1 /*
2  *  sock.c
3  *
4  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5  *  Copyright (C) 1997 by Volker Lendecke
6  *
7  *  Please add a note about your changes to smbfs in the ChangeLog file.
8  */
9 
10 #include <linux/sched.h>
11 #include <linux/errno.h>
12 #include <linux/socket.h>
13 #include <linux/fcntl.h>
14 #include <linux/file.h>
15 #include <linux/poll.h>
16 #include <linux/in.h>
17 #include <linux/net.h>
18 #include <linux/mm.h>
19 #include <linux/netdevice.h>
20 #include <linux/smp_lock.h>
21 #include <net/scm.h>
22 #include <net/ip.h>
23 
24 #include <linux/smb_fs.h>
25 #include <linux/smb.h>
26 #include <linux/smbno.h>
27 
28 #include <asm/uaccess.h>
29 
30 #include "smb_debug.h"
31 #include "proto.h"
32 
33 
34 static int
_recvfrom(struct socket * socket,unsigned char * ubuf,int size,unsigned flags)35 _recvfrom(struct socket *socket, unsigned char *ubuf, int size,
36 	  unsigned flags)
37 {
38 	struct iovec iov;
39 	struct msghdr msg;
40 	struct scm_cookie scm;
41 
42 	msg.msg_name = NULL;
43 	msg.msg_namelen = 0;
44 	msg.msg_iov = &iov;
45 	msg.msg_iovlen = 1;
46 	msg.msg_control = NULL;
47 	iov.iov_base = ubuf;
48 	iov.iov_len = size;
49 
50 	memset(&scm, 0,sizeof(scm));
51 	size=socket->ops->recvmsg(socket, &msg, size, flags, &scm);
52 	if(size>=0)
53 		scm_recv(socket,&msg,&scm,flags);
54 	return size;
55 }
56 
57 static int
_send(struct socket * socket,const void * buff,int len)58 _send(struct socket *socket, const void *buff, int len)
59 {
60 	struct iovec iov;
61 	struct msghdr msg;
62 	struct scm_cookie scm;
63 	int err;
64 
65 	msg.msg_name = NULL;
66 	msg.msg_namelen = 0;
67 	msg.msg_iov = &iov;
68 	msg.msg_iovlen = 1;
69 	msg.msg_control = NULL;
70 	msg.msg_controllen = 0;
71 
72 	iov.iov_base = (void *)buff;
73 	iov.iov_len = len;
74 
75 	msg.msg_flags = 0;
76 
77 	err = scm_send(socket, &msg, &scm);
78         if (err >= 0)
79 	{
80 		err = socket->ops->sendmsg(socket, &msg, len, &scm);
81 		scm_destroy(&scm);
82 	}
83 	return err;
84 }
85 
86 struct data_callback {
87 	struct tq_struct cb;
88 	struct sock *sk;
89 };
90 /*
91  * N.B. What happens if we're in here when the socket closes??
92  */
93 static void
found_data(struct sock * sk)94 found_data(struct sock *sk)
95 {
96 	/*
97 	 * FIXME: copied from sock_def_readable, it should be a call to
98 	 * server->data_ready()	-- manfreds@colorfullife.com
99 	 */
100 	read_lock(&sk->callback_lock);
101 	if(!sk->dead) {
102 		wake_up_interruptible(sk->sleep);
103 		sock_wake_async(sk->socket,1,POLL_IN);
104 	}
105 	read_unlock(&sk->callback_lock);
106 }
107 
108 static void
smb_data_callback(void * ptr)109 smb_data_callback(void* ptr)
110 {
111 	struct data_callback* job=ptr;
112 	struct socket *socket = job->sk->socket;
113 	unsigned char peek_buf[4];
114 	int result = 0;
115 	mm_segment_t fs;
116 	int count = 100;   /* this is a lot, we should have some data waiting */
117 	int found = 0;
118 
119 	fs = get_fs();
120 	set_fs(get_ds());
121 
122 	lock_kernel();
123 	while (count-- > 0) {
124 		peek_buf[0] = 0;
125 
126 		result = -EIO;
127 		if (job->sk->dead) {
128 			PARANOIA("sock dead!\n");
129 			break;
130 		}
131 
132 		result = _recvfrom(socket, (void *) peek_buf, 1,
133 				   MSG_PEEK | MSG_DONTWAIT);
134 		if (result < 0)
135 			break;
136 		if (peek_buf[0] != 0x85)
137 			break;
138 
139 		/* got SESSION KEEP ALIVE */
140 		result = _recvfrom(socket, (void *) peek_buf, 4,
141 				   MSG_DONTWAIT);
142 
143 		DEBUG1("got SESSION KEEPALIVE\n");
144 
145 		if (result < 0)
146 			break;
147 		found = 1;
148 	}
149 	unlock_kernel();
150 	set_fs(fs);
151 
152 	DEBUG1("found=%d, count=%d, result=%d\n", found, count, result);
153 	if (found)
154 		found_data(job->sk);
155 	smb_kfree(ptr);
156 }
157 
158 static void
smb_data_ready(struct sock * sk,int len)159 smb_data_ready(struct sock *sk, int len)
160 {
161 	struct data_callback* job;
162 	job = smb_kmalloc(sizeof(struct data_callback),GFP_ATOMIC);
163 	if(job == 0) {
164 		printk("smb_data_ready: lost SESSION KEEPALIVE due to OOM.\n");
165 		found_data(sk);
166 		return;
167 	}
168 	INIT_LIST_HEAD(&job->cb.list);
169 	job->cb.sync = 0;
170 	job->cb.routine = smb_data_callback;
171 	job->cb.data = job;
172 	job->sk = sk;
173 	schedule_task(&job->cb);
174 }
175 
176 int
smb_valid_socket(struct inode * inode)177 smb_valid_socket(struct inode * inode)
178 {
179 	return (inode && S_ISSOCK(inode->i_mode) &&
180 		inode->u.socket_i.type == SOCK_STREAM);
181 }
182 
183 static struct socket *
server_sock(struct smb_sb_info * server)184 server_sock(struct smb_sb_info *server)
185 {
186 	struct file *file;
187 
188 	if (server && (file = server->sock_file))
189 	{
190 #ifdef SMBFS_PARANOIA
191 		if (!smb_valid_socket(file->f_dentry->d_inode))
192 			PARANOIA("bad socket!\n");
193 #endif
194 		return &file->f_dentry->d_inode->u.socket_i;
195 	}
196 	return NULL;
197 }
198 
199 int
smb_catch_keepalive(struct smb_sb_info * server)200 smb_catch_keepalive(struct smb_sb_info *server)
201 {
202 	struct socket *socket;
203 	struct sock *sk;
204 	void *data_ready;
205 	int error;
206 
207 	error = -EINVAL;
208 	socket = server_sock(server);
209 	if (!socket)
210 	{
211 		printk(KERN_DEBUG "smb_catch_keepalive: did not get valid server!\n");
212 		server->data_ready = NULL;
213 		goto out;
214 	}
215 
216 	sk = socket->sk;
217 	if (sk == NULL)
218 	{
219 		DEBUG1("sk == NULL");
220 		server->data_ready = NULL;
221 		goto out;
222 	}
223 	DEBUG1("sk->d_r = %x, server->d_r = %x\n",
224 		 (unsigned int) (sk->data_ready),
225 		 (unsigned int) (server->data_ready));
226 
227 	/*
228 	 * Install the callback atomically to avoid races ...
229 	 */
230 	data_ready = xchg(&sk->data_ready, smb_data_ready);
231 	if (data_ready != smb_data_ready) {
232 		server->data_ready = data_ready;
233 		error = 0;
234 	} else
235 		printk(KERN_ERR "smb_catch_keepalive: already done\n");
236 out:
237 	return error;
238 }
239 
240 int
smb_dont_catch_keepalive(struct smb_sb_info * server)241 smb_dont_catch_keepalive(struct smb_sb_info *server)
242 {
243 	struct socket *socket;
244 	struct sock *sk;
245 	void * data_ready;
246 	int error;
247 
248 	error = -EINVAL;
249 	socket = server_sock(server);
250 	if (!socket)
251 	{
252 		printk(KERN_DEBUG "smb_dont_catch_keepalive: did not get valid server!\n");
253 		goto out;
254 	}
255 
256 	sk = socket->sk;
257 	if (sk == NULL)
258 	{
259 		DEBUG1("sk == NULL");
260 		goto out;
261 	}
262 
263 	/* Is this really an error?? */
264 	if (server->data_ready == NULL)
265 	{
266 		printk(KERN_DEBUG "smb_dont_catch_keepalive: "
267 		       "server->data_ready == NULL\n");
268 		goto out;
269 	}
270 	DEBUG1("smb_dont_catch_keepalive: sk->d_r = %x, server->d_r = %x\n",
271 	       (unsigned int) (sk->data_ready),
272 	       (unsigned int) (server->data_ready));
273 
274 	/*
275 	 * Restore the original callback atomically to avoid races ...
276 	 */
277 	data_ready = xchg(&sk->data_ready, server->data_ready);
278 	server->data_ready = NULL;
279 	if (data_ready != smb_data_ready)
280 	{
281 		printk(KERN_ERR "smb_dont_catch_keepalive: "
282 		       "sk->data_ready != smb_data_ready\n");
283 	}
284 	error = 0;
285 out:
286 	return error;
287 }
288 
289 /*
290  * Called with the server locked.
291  */
292 void
smb_close_socket(struct smb_sb_info * server)293 smb_close_socket(struct smb_sb_info *server)
294 {
295 	struct file * file = server->sock_file;
296 
297 	if (file)
298 	{
299 		VERBOSE("closing socket %p\n", server_sock(server));
300 #ifdef SMBFS_PARANOIA
301 		if (server_sock(server)->sk->data_ready == smb_data_ready)
302 			PARANOIA("still catching keepalives!\n");
303 #endif
304 		server->sock_file = NULL;
305 		fput(file);
306 	}
307 }
308 
309 /*
310  * Poll the server->socket to allow receives to time out.
311  * returns 0 when ok to continue, <0 on errors.
312  */
313 static int
smb_receive_poll(struct smb_sb_info * server)314 smb_receive_poll(struct smb_sb_info *server)
315 {
316 	struct file *file = server->sock_file;
317 	poll_table wait_table;
318 	int result = 0;
319 	int timeout = server->mnt->timeo * HZ;
320 	int mask;
321 
322 	for (;;) {
323 		poll_initwait(&wait_table);
324                 set_current_state(TASK_INTERRUPTIBLE);
325 
326 		mask = file->f_op->poll(file, &wait_table);
327 		if (mask & POLLIN) {
328 			poll_freewait(&wait_table);
329 			current->state = TASK_RUNNING;
330 			break;
331 		}
332 
333 		timeout = schedule_timeout(timeout);
334 		poll_freewait(&wait_table);
335                 set_current_state(TASK_RUNNING);
336 
337 		if (wait_table.error) {
338 			result = wait_table.error;
339 			break;
340 		}
341 
342 		if (signal_pending(current)) {
343 			/* we got a signal (which?) tell the caller to
344 			   try again (on all signals?). */
345 			DEBUG1("got signal_pending()\n");
346 			result = -ERESTARTSYS;
347 			break;
348 		}
349 		if (!timeout) {
350 			printk(KERN_WARNING "SMB server not responding\n");
351 			result = -EIO;
352 			break;
353 		}
354 	}
355 	return result;
356 }
357 
358 static int
smb_send_raw(struct socket * socket,unsigned char * source,int length)359 smb_send_raw(struct socket *socket, unsigned char *source, int length)
360 {
361 	int result;
362 	int already_sent = 0;
363 
364 	while (already_sent < length)
365 	{
366 		result = _send(socket,
367 			       (void *) (source + already_sent),
368 			       length - already_sent);
369 
370 		if (result == 0)
371 		{
372 			return -EIO;
373 		}
374 		if (result < 0)
375 		{
376 			DEBUG1("smb_send_raw: sendto error = %d\n", -result);
377 			return result;
378 		}
379 		already_sent += result;
380 	}
381 	return already_sent;
382 }
383 
384 static int
smb_receive_raw(struct smb_sb_info * server,unsigned char * target,int length)385 smb_receive_raw(struct smb_sb_info *server, unsigned char *target, int length)
386 {
387 	int result;
388 	int already_read = 0;
389 	struct socket *socket = server_sock(server);
390 
391 	while (already_read < length)
392 	{
393 		result = smb_receive_poll(server);
394 		if (result < 0) {
395 			DEBUG1("poll error = %d\n", -result);
396 			return result;
397 		}
398 		result = _recvfrom(socket,
399 				   (void *) (target + already_read),
400 				   length - already_read, 0);
401 
402 		if (result == 0)
403 		{
404 			return -EIO;
405 		}
406 		if (result < 0)
407 		{
408 			DEBUG1("recvfrom error = %d\n", -result);
409 			return result;
410 		}
411 		already_read += result;
412 	}
413 	return already_read;
414 }
415 
416 static int
smb_get_length(struct smb_sb_info * server,unsigned char * header)417 smb_get_length(struct smb_sb_info *server, unsigned char *header)
418 {
419 	int result;
420 	unsigned char peek_buf[4];
421 	mm_segment_t fs;
422 
423       re_recv:
424 	fs = get_fs();
425 	set_fs(get_ds());
426 	result = smb_receive_raw(server, peek_buf, 4);
427 	set_fs(fs);
428 
429 	if (result < 0)
430 	{
431 		PARANOIA("recv error = %d\n", -result);
432 		return result;
433 	}
434 	switch (peek_buf[0])
435 	{
436 	case 0x00:
437 	case 0x82:
438 		break;
439 
440 	case 0x85:
441 		DEBUG1("Got SESSION KEEP ALIVE\n");
442 		goto re_recv;
443 
444 	default:
445 		PARANOIA("Invalid NBT packet, code=%x\n", peek_buf[0]);
446 		return -EIO;
447 	}
448 
449 	if (header != NULL)
450 	{
451 		memcpy(header, peek_buf, 4);
452 	}
453 	/* The length in the RFC NB header is the raw data length */
454 	return smb_len(peek_buf);
455 }
456 
457 /*
458  * Since we allocate memory in increments of PAGE_SIZE,
459  * round up the packet length to the next multiple.
460  */
461 int
smb_round_length(int len)462 smb_round_length(int len)
463 {
464 	return (len + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
465 }
466 
467 /*
468  * smb_receive
469  * fs points to the correct segment
470  */
471 static int
smb_receive(struct smb_sb_info * server)472 smb_receive(struct smb_sb_info *server)
473 {
474 	unsigned char * packet = server->packet;
475 	int len, result;
476 	unsigned char peek_buf[4];
477 
478 	result = smb_get_length(server, peek_buf);
479 	if (result < 0)
480 		goto out;
481 	len = result;
482 	/*
483 	 * Some servers do not respect our max_xmit and send
484 	 * larger packets.  Try to allocate a new packet,
485 	 * but don't free the old one unless we succeed.
486 	 */
487 	if (len + 4 > server->packet_size)
488 	{
489 		int new_len = smb_round_length(len + 4);
490 
491 		result = -ENOMEM;
492 		packet = smb_vmalloc(new_len);
493 		if (packet == NULL)
494 			goto out;
495 		smb_vfree(server->packet);
496 		server->packet = packet;
497 		server->packet_size = new_len;
498 	}
499 	memcpy(packet, peek_buf, 4);
500 	result = smb_receive_raw(server, packet + 4, len);
501 	if (result < 0)
502 	{
503 		VERBOSE("receive error: %d\n", result);
504 		goto out;
505 	}
506 	server->rcls = *(packet + smb_rcls);
507 	server->err  = WVAL(packet, smb_err);
508 
509 #ifdef SMBFS_DEBUG_VERBOSE
510 	if (server->rcls != 0)
511 		VERBOSE("rcls=%d, err=%d\n", server->rcls, server->err);
512 #endif
513 out:
514 	return result;
515 }
516 
517 /*
518  * This routine checks first for "fast track" processing, as most
519  * packets won't need to be copied. Otherwise, it allocates a new
520  * packet to hold the incoming data.
521  *
522  * Note that the final server packet must be the larger of the two;
523  * server packets aren't allowed to shrink.
524  */
525 static int
smb_receive_trans2(struct smb_sb_info * server,int * ldata,unsigned char ** data,int * lparm,unsigned char ** parm)526 smb_receive_trans2(struct smb_sb_info *server,
527 		   int *ldata, unsigned char **data,
528 		   int *lparm, unsigned char **parm)
529 {
530 	unsigned char *inbuf, *base, *rcv_buf = NULL;
531 	unsigned int parm_disp, parm_offset, parm_count, parm_tot, parm_len = 0;
532 	unsigned int data_disp, data_offset, data_count, data_tot, data_len = 0;
533 	unsigned int total_p = 0, total_d = 0, buf_len = 0;
534 	int result;
535 
536 	while (1) {
537 		result = smb_receive(server);
538 		if (result < 0)
539 			goto out;
540 		inbuf = server->packet;
541 		if (server->rcls != 0) {
542 			*parm = *data = inbuf;
543 			*ldata = *lparm = 0;
544 			goto out;
545 		}
546 		/*
547 		 * Extract the control data from the packet.
548 		 */
549 		data_tot    = WVAL(inbuf, smb_tdrcnt);
550 		parm_tot    = WVAL(inbuf, smb_tprcnt);
551 		parm_disp   = WVAL(inbuf, smb_prdisp);
552 		parm_offset = WVAL(inbuf, smb_proff);
553 		parm_count  = WVAL(inbuf, smb_prcnt);
554 		data_disp   = WVAL(inbuf, smb_drdisp);
555 		data_offset = WVAL(inbuf, smb_droff);
556 		data_count  = WVAL(inbuf, smb_drcnt);
557 		base = smb_base(inbuf);
558 
559 		/*
560 		 * Assume success and increment lengths.
561 		 */
562 		parm_len += parm_count;
563 		data_len += data_count;
564 
565 		if (!rcv_buf) {
566 			/*
567 			 * Check for fast track processing ... just this packet.
568 			 */
569 			if (parm_count == parm_tot && data_count == data_tot) {
570 				VERBOSE("fast track, parm=%u %u %u, data=%u %u %u\n",
571 					parm_disp, parm_offset, parm_count,
572 					data_disp, data_offset, data_count);
573 				*parm  = base + parm_offset;
574 				if (*parm - inbuf + parm_tot > server->packet_size)
575 					goto out_bad_parm;
576 				*data  = base + data_offset;
577 				if (*data - inbuf + data_tot > server->packet_size)
578 					goto out_bad_data;
579 				goto success;
580 			}
581 
582 			/*
583 			 * Save the total parameter and data length.
584 			 */
585 			total_d = data_tot;
586 			total_p = parm_tot;
587 
588 			buf_len = total_d + total_p;
589 			if (server->packet_size > buf_len)
590 				buf_len = server->packet_size;
591 			buf_len = smb_round_length(buf_len);
592 			if (buf_len > SMB_MAX_PACKET_SIZE)
593 				goto out_too_long;
594 
595 			rcv_buf = smb_vmalloc(buf_len);
596 			if (!rcv_buf)
597 				goto out_no_mem;
598 			memset(rcv_buf, 0, buf_len);
599 
600 			*parm = rcv_buf;
601 			*data = rcv_buf + total_p;
602 		} else if (data_tot > total_d || parm_tot > total_p)
603 			goto out_data_grew;
604 
605 		if (parm_disp + parm_count > total_p)
606 			goto out_bad_parm;
607 		if (parm_offset + parm_count > server->packet_size)
608 			goto out_bad_parm;
609 		if (data_disp + data_count > total_d)
610 			goto out_bad_data;
611 		if (data_offset + data_count > server->packet_size)
612 			goto out_bad_data;
613 		memcpy(*parm + parm_disp, base + parm_offset, parm_count);
614 		memcpy(*data + data_disp, base + data_offset, data_count);
615 
616 		PARANOIA("copied, parm=%u of %u, data=%u of %u\n",
617 			 parm_len, parm_tot, data_len, data_tot);
618 
619 		/*
620 		 * Check whether we've received all of the data. Note that
621 		 * we use the packet totals -- total lengths might shrink!
622 		 */
623 		if (data_len >= data_tot && parm_len >= parm_tot) {
624 			data_len = data_tot;
625 			parm_len = parm_tot;
626 			break;
627 		}
628 	}
629 
630 	/*
631 	 * Install the new packet.  Note that it's possible, though
632 	 * unlikely, that the new packet could be smaller than the
633 	 * old one, in which case we just copy the data.
634 	 */
635 	inbuf = server->packet;
636 	if (buf_len >= server->packet_size) {
637 		server->packet_size = buf_len;
638 		server->packet = rcv_buf;
639 		rcv_buf = inbuf;
640 	} else {
641 		if (parm_len + data_len > buf_len)
642 			goto out_data_grew;
643 
644 		PARANOIA("copying data, old size=%d, new size=%u\n",
645 			 server->packet_size, buf_len);
646 		memcpy(inbuf, rcv_buf, parm_len + data_len);
647 	}
648 
649 success:
650 	*ldata = data_len;
651 	*lparm = parm_len;
652 out:
653 	if (rcv_buf)
654 		smb_vfree(rcv_buf);
655 	return result;
656 
657 out_no_mem:
658 	PARANOIA("couldn't allocate data area\n");
659 	result = -ENOMEM;
660 	goto out;
661 out_too_long:
662 	printk(KERN_ERR "smb_receive_trans2: data/param too long, data=%d, parm=%d\n",
663 		data_tot, parm_tot);
664 	goto out_error;
665 out_data_grew:
666 	printk(KERN_ERR "smb_receive_trans2: data/params grew!\n");
667 	goto out_error;
668 out_bad_parm:
669 	printk(KERN_ERR "smb_receive_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n",
670 		parm_disp, parm_count, parm_tot);
671 	goto out_error;
672 out_bad_data:
673 	printk(KERN_ERR "smb_receive_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n",
674 		data_disp, data_count, data_tot);
675 out_error:
676 	result = -EIO;
677 	goto out;
678 }
679 
680 /*
681  * Called with the server locked
682  */
683 int
smb_request(struct smb_sb_info * server)684 smb_request(struct smb_sb_info *server)
685 {
686 	unsigned long flags, sigpipe;
687 	mm_segment_t fs;
688 	sigset_t old_set;
689 	int len, result;
690 	unsigned char *buffer;
691 
692 	result = -EBADF;
693 	buffer = server->packet;
694 	if (!buffer)
695 		goto bad_no_packet;
696 
697 	result = -EIO;
698 	if (server->state != CONN_VALID)
699 		goto bad_no_conn;
700 
701 	if ((result = smb_dont_catch_keepalive(server)) != 0)
702 		goto bad_conn;
703 
704 	len = smb_len(buffer) + 4;
705 	DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]);
706 
707 	spin_lock_irqsave(&current->sigmask_lock, flags);
708 	sigpipe = sigismember(&current->pending.signal, SIGPIPE);
709 	old_set = current->blocked;
710 	siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
711 	recalc_sigpending(current);
712 	spin_unlock_irqrestore(&current->sigmask_lock, flags);
713 
714 	fs = get_fs();
715 	set_fs(get_ds());
716 
717 	result = smb_send_raw(server_sock(server), (void *) buffer, len);
718 	if (result > 0)
719 	{
720 		result = smb_receive(server);
721 	}
722 
723 	/* read/write errors are handled by errno */
724 	spin_lock_irqsave(&current->sigmask_lock, flags);
725 	if (result == -EPIPE && !sigpipe)
726 		sigdelset(&current->pending.signal, SIGPIPE);
727 	current->blocked = old_set;
728 	recalc_sigpending(current);
729 	spin_unlock_irqrestore(&current->sigmask_lock, flags);
730 
731 	set_fs(fs);
732 
733 	if (result >= 0)
734 	{
735 		int result2 = smb_catch_keepalive(server);
736 		if (result2 < 0)
737 		{
738 			printk(KERN_ERR "smb_request: catch keepalive failed\n");
739 			result = result2;
740 		}
741 	}
742 	if (result < 0)
743 		goto bad_conn;
744 	/*
745 	 * Check for fatal server errors ...
746 	 */
747 	if (server->rcls) {
748 		int error = smb_errno(server);
749 		if (error == -EBADSLT) {
750 			printk(KERN_ERR "smb_request: tree ID invalid\n");
751 			result = error;
752 			goto bad_conn;
753 		}
754 	}
755 
756 out:
757 	DEBUG1("result = %d\n", result);
758 	return result;
759 
760 bad_conn:
761 	PARANOIA("result %d, setting invalid\n", result);
762 	server->state = CONN_INVALID;
763 	smb_invalidate_inodes(server);
764 	goto out;
765 bad_no_packet:
766 	printk(KERN_ERR "smb_request: no packet!\n");
767 	goto out;
768 bad_no_conn:
769 	printk(KERN_ERR "smb_request: connection %d not valid!\n",
770 	       server->state);
771 	goto out;
772 }
773 
774 #define ROUND_UP(x) (((x)+3) & ~3)
775 static int
smb_send_trans2(struct smb_sb_info * server,__u16 trans2_command,int ldata,unsigned char * data,int lparam,unsigned char * param)776 smb_send_trans2(struct smb_sb_info *server, __u16 trans2_command,
777 		int ldata, unsigned char *data,
778 		int lparam, unsigned char *param)
779 {
780 	struct socket *sock = server_sock(server);
781 	struct scm_cookie scm;
782 	int err;
783 	int mparam, mdata;
784 
785 	/* I know the following is very ugly, but I want to build the
786 	   smb packet as efficiently as possible. */
787 
788 	const int smb_parameters = 15;
789 	const int oparam =
790 		ROUND_UP(SMB_HEADER_LEN + 2 * smb_parameters + 2 + 3);
791 	const int odata =
792 		ROUND_UP(oparam + lparam);
793 	const int bcc =
794 		odata + ldata - (SMB_HEADER_LEN + 2 * smb_parameters + 2);
795 	const int packet_length =
796 		SMB_HEADER_LEN + 2 * smb_parameters + bcc + 2;
797 
798 	unsigned char padding[4] =
799 	{0,};
800 	char *p;
801 
802 	struct iovec iov[4];
803 	struct msghdr msg;
804 
805 	/* FIXME! this test needs to include SMB overhead too, I think ... */
806 	if ((bcc + oparam) > server->opt.max_xmit)
807 		return -ENOMEM;
808 	p = smb_setup_header(server, SMBtrans2, smb_parameters, bcc);
809 
810 	/*
811 	 * max parameters + max data + max setup == max_xmit to make NT4 happy
812 	 * and not abort the transfer or split into multiple responses.
813 	 *
814 	 * -100 is to make room for headers, which OS/2 seems to include in the
815 	 * size calculation while NT4 does not?
816 	 */
817 	mparam = SMB_TRANS2_MAX_PARAM;
818 	mdata = server->opt.max_xmit - mparam - 100;
819 	if (mdata < 1024) {
820 		mdata = 1024;
821 		mparam = 20;
822 	}
823 
824 	WSET(server->packet, smb_tpscnt, lparam);
825 	WSET(server->packet, smb_tdscnt, ldata);
826 	WSET(server->packet, smb_mprcnt, mparam);
827 	WSET(server->packet, smb_mdrcnt, mdata);
828 	WSET(server->packet, smb_msrcnt, 0);    /* max setup always 0 ? */
829 	WSET(server->packet, smb_flags, 0);
830 	DSET(server->packet, smb_timeout, 0);
831 	WSET(server->packet, smb_pscnt, lparam);
832 	WSET(server->packet, smb_psoff, oparam - 4);
833 	WSET(server->packet, smb_dscnt, ldata);
834 	WSET(server->packet, smb_dsoff, odata - 4);
835 	WSET(server->packet, smb_suwcnt, 1);
836 	WSET(server->packet, smb_setup0, trans2_command);
837 	*p++ = 0;		/* null smb_name for trans2 */
838 	*p++ = 'D';		/* this was added because OS/2 does it */
839 	*p++ = ' ';
840 
841 
842 	msg.msg_name = NULL;
843 	msg.msg_namelen = 0;
844 	msg.msg_control = NULL;
845 	msg.msg_controllen = 0;
846 	msg.msg_iov = iov;
847 	msg.msg_iovlen = 4;
848 	msg.msg_flags = 0;
849 
850 	iov[0].iov_base = (void *) server->packet;
851 	iov[0].iov_len = oparam;
852 	iov[1].iov_base = (param == NULL) ? padding : param;
853 	iov[1].iov_len = lparam;
854 	iov[2].iov_base = padding;
855 	iov[2].iov_len = odata - oparam - lparam;
856 	iov[3].iov_base = (data == NULL) ? padding : data;
857 	iov[3].iov_len = ldata;
858 
859 	err = scm_send(sock, &msg, &scm);
860         if (err >= 0) {
861 		err = sock->ops->sendmsg(sock, &msg, packet_length, &scm);
862 		scm_destroy(&scm);
863 	}
864 	return err;
865 }
866 
867 /*
868  * This is not really a trans2 request, we assume that you only have
869  * one packet to send.
870  */
871 int
smb_trans2_request(struct smb_sb_info * server,__u16 trans2_command,int ldata,unsigned char * data,int lparam,unsigned char * param,int * lrdata,unsigned char ** rdata,int * lrparam,unsigned char ** rparam)872 smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
873 		   int ldata, unsigned char *data,
874 		   int lparam, unsigned char *param,
875 		   int *lrdata, unsigned char **rdata,
876 		   int *lrparam, unsigned char **rparam)
877 {
878 	sigset_t old_set;
879 	unsigned long flags, sigpipe;
880 	mm_segment_t fs;
881 	int result;
882 
883 	DEBUG1("com=%d, ld=%d, lp=%d\n", trans2_command, ldata, lparam);
884 
885 	/*
886 	 * These are initialized in smb_request_ok, but not here??
887 	 */
888 	server->rcls = 0;
889 	server->err = 0;
890 
891 	result = -EIO;
892 	if (server->state != CONN_VALID)
893 		goto out;
894 
895 	if ((result = smb_dont_catch_keepalive(server)) != 0)
896 		goto bad_conn;
897 
898 	spin_lock_irqsave(&current->sigmask_lock, flags);
899 	sigpipe = sigismember(&current->pending.signal, SIGPIPE);
900 	old_set = current->blocked;
901 	siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
902 	recalc_sigpending(current);
903 	spin_unlock_irqrestore(&current->sigmask_lock, flags);
904 
905 	fs = get_fs();
906 	set_fs(get_ds());
907 
908 	result = smb_send_trans2(server, trans2_command,
909 				 ldata, data, lparam, param);
910 	if (result >= 0)
911 	{
912 		result = smb_receive_trans2(server,
913 					    lrdata, rdata, lrparam, rparam);
914 	}
915 
916 	/* read/write errors are handled by errno */
917 	spin_lock_irqsave(&current->sigmask_lock, flags);
918 	if (result == -EPIPE && !sigpipe)
919 		sigdelset(&current->pending.signal, SIGPIPE);
920 	current->blocked = old_set;
921 	recalc_sigpending(current);
922 	spin_unlock_irqrestore(&current->sigmask_lock, flags);
923 
924 	set_fs(fs);
925 
926 	if (result >= 0)
927 	{
928 		int result2 = smb_catch_keepalive(server);
929 		if (result2 < 0)
930 		{
931 			result = result2;
932 		}
933 	}
934 	if (result < 0)
935 		goto bad_conn;
936 	/*
937 	 * Check for fatal server errors ...
938 	 */
939 	if (server->rcls) {
940 		int error = smb_errno(server);
941 		if (error == -EBADSLT) {
942 			printk(KERN_ERR "smb_request: tree ID invalid\n");
943 			result = error;
944 			goto bad_conn;
945 		}
946 	}
947 
948 out:
949 	return result;
950 
951 bad_conn:
952 	PARANOIA("result=%d, setting invalid\n", result);
953 	server->state = CONN_INVALID;
954 	smb_invalidate_inodes(server);
955 	goto out;
956 }
957