xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_opipe.c (revision b210fede5519ffcaa92e5409d891c77b945d73bb)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
24  */
25 
26 /*
27  * This module provides the interface to NDR RPC.
28  */
29 
30 #include <sys/stat.h>
31 #include <sys/uio.h>
32 #include <sys/ksynch.h>
33 #include <sys/stropts.h>
34 #include <sys/socket.h>
35 #include <sys/filio.h>
36 #include <smbsrv/smb_kproto.h>
37 #include <smbsrv/smb_xdr.h>
38 #include <smb/winioctl.h>
39 
40 static uint32_t smb_opipe_transceive(smb_request_t *, smb_fsctl_t *);
41 
42 /*
43  * Allocate a new opipe and return it, or NULL, in which case
44  * the caller will report "internal error".
45  */
46 static smb_opipe_t *
47 smb_opipe_alloc(smb_request_t *sr)
48 {
49 	smb_server_t	*sv = sr->sr_server;
50 	smb_opipe_t	*opipe;
51 	ksocket_t	sock;
52 
53 	if (ksocket_socket(&sock, AF_UNIX, SOCK_STREAM, 0,
54 	    KSOCKET_SLEEP, sr->user_cr) != 0)
55 		return (NULL);
56 
57 	opipe = kmem_cache_alloc(smb_cache_opipe, KM_SLEEP);
58 
59 	bzero(opipe, sizeof (smb_opipe_t));
60 	mutex_init(&opipe->p_mutex, NULL, MUTEX_DEFAULT, NULL);
61 	cv_init(&opipe->p_cv, NULL, CV_DEFAULT, NULL);
62 	opipe->p_magic = SMB_OPIPE_MAGIC;
63 	opipe->p_server = sv;
64 	opipe->p_refcnt = 1;
65 	opipe->p_socket = sock;
66 
67 	return (opipe);
68 }
69 
70 /*
71  * Destroy an opipe.  This is normally called from smb_ofile_delete
72  * when the ofile has no more references and is about to be free'd.
73  * This is also called here in error handling code paths, before
74  * the opipe is installed under an ofile.
75  */
76 void
77 smb_opipe_dealloc(smb_opipe_t *opipe)
78 {
79 	smb_server_t *sv;
80 
81 	SMB_OPIPE_VALID(opipe);
82 	sv = opipe->p_server;
83 	SMB_SERVER_VALID(sv);
84 
85 	/*
86 	 * This is called in the error path when opening,
87 	 * in which case we close the socket here.
88 	 */
89 	if (opipe->p_socket != NULL)
90 		(void) ksocket_close(opipe->p_socket, zone_kcred());
91 
92 	opipe->p_magic = (uint32_t)~SMB_OPIPE_MAGIC;
93 	cv_destroy(&opipe->p_cv);
94 	mutex_destroy(&opipe->p_mutex);
95 
96 	kmem_cache_free(smb_cache_opipe, opipe);
97 }
98 
99 /*
100  * Unblock a request that might be blocked reading some
101  * pipe (AF_UNIX socket).  We don't have an easy way to
102  * interrupt just the thread servicing this request, so
103  * we shutdown(3socket) the socket, waking all readers.
104  * That's a bit heavy-handed, making the socket unusable
105  * after this, so we do this only when disconnecting a
106  * session (i.e. stopping the SMB service), and not when
107  * handling an SMB2_cancel or SMB_nt_cancel request.
108  */
109 static void
110 smb_opipe_cancel(smb_request_t *sr)
111 {
112 	ksocket_t so;
113 
114 	if (sr->session->s_state == SMB_SESSION_STATE_DISCONNECTED &&
115 	    (so = sr->cancel_arg2) != NULL) {
116 		(void) ksocket_shutdown(so, SHUT_RDWR, sr->user_cr);
117 	}
118 }
119 
120 /*
121  * Helper for open: build pipe name and connect.
122  */
123 static int
124 smb_opipe_connect(smb_request_t *sr, smb_opipe_t *opipe)
125 {
126 	struct sockaddr_un saddr;
127 	smb_arg_open_t	*op = &sr->sr_open;
128 	const char *name;
129 	int rc;
130 
131 	name = op->fqi.fq_path.pn_path;
132 	name += strspn(name, "\\");
133 	if (smb_strcasecmp(name, "PIPE", 4) == 0) {
134 		name += 4;
135 		name += strspn(name, "\\");
136 	}
137 	(void) strlcpy(opipe->p_name, name, SMB_OPIPE_MAXNAME);
138 	(void) smb_strlwr(opipe->p_name);
139 
140 	bzero(&saddr, sizeof (saddr));
141 	saddr.sun_family = AF_UNIX;
142 	(void) snprintf(saddr.sun_path, sizeof (saddr.sun_path),
143 	    "%s/%s", SMB_PIPE_DIR, opipe->p_name);
144 	rc = ksocket_connect(opipe->p_socket, (struct sockaddr *)&saddr,
145 	    sizeof (saddr), sr->user_cr);
146 
147 	return (rc);
148 }
149 
150 /*
151  * Helper for open: encode and send the user info.
152  *
153  * We send information about this client + user to the
154  * pipe service so it can use it for access checks.
155  * The service MAY deny the open based on this info,
156  * (i.e. anonymous session trying to open a pipe that
157  * requires authentication) in which case we will read
158  * an error status from the service and return that.
159  */
160 static void
161 smb_opipe_send_userinfo(smb_request_t *sr, smb_opipe_t *opipe,
162     smb_error_t *errp)
163 {
164 	XDR xdrs;
165 	smb_netuserinfo_t nui;
166 	smb_pipehdr_t phdr;
167 	char *buf;
168 	uint32_t buflen;
169 	uint32_t status;
170 	size_t iocnt = 0;
171 	int rc;
172 
173 	/*
174 	 * Any errors building the XDR message etc.
175 	 */
176 	errp->status = NT_STATUS_INTERNAL_ERROR;
177 
178 	smb_user_netinfo_init(sr->uid_user, &nui);
179 	phdr.ph_magic = SMB_PIPE_HDR_MAGIC;
180 	phdr.ph_uilen = xdr_sizeof(smb_netuserinfo_xdr, &nui);
181 
182 	buflen = sizeof (phdr) + phdr.ph_uilen;
183 	buf = kmem_alloc(buflen, KM_SLEEP);
184 
185 	bcopy(&phdr, buf, sizeof (phdr));
186 	xdrmem_create(&xdrs, buf + sizeof (phdr),
187 	    buflen - (sizeof (phdr)), XDR_ENCODE);
188 	if (!smb_netuserinfo_xdr(&xdrs, &nui))
189 		goto out;
190 
191 	mutex_enter(&sr->sr_mutex);
192 	if (sr->sr_state != SMB_REQ_STATE_ACTIVE) {
193 		mutex_exit(&sr->sr_mutex);
194 		errp->status = NT_STATUS_CANCELLED;
195 		goto out;
196 	}
197 	sr->sr_state = SMB_REQ_STATE_WAITING_PIPE;
198 	sr->cancel_method = smb_opipe_cancel;
199 	sr->cancel_arg2 = opipe->p_socket;
200 	mutex_exit(&sr->sr_mutex);
201 
202 	rc = ksocket_send(opipe->p_socket, buf, buflen, 0,
203 	    &iocnt, sr->user_cr);
204 	if (rc == 0 && iocnt != buflen)
205 		rc = EIO;
206 	if (rc == 0)
207 		rc = ksocket_recv(opipe->p_socket, &status, sizeof (status),
208 		    0, &iocnt, sr->user_cr);
209 	if (rc == 0 && iocnt != sizeof (status))
210 		rc = EIO;
211 
212 	mutex_enter(&sr->sr_mutex);
213 	sr->cancel_method = NULL;
214 	sr->cancel_arg2 = NULL;
215 	switch (sr->sr_state) {
216 	case SMB_REQ_STATE_WAITING_PIPE:
217 		sr->sr_state = SMB_REQ_STATE_ACTIVE;
218 		break;
219 	case SMB_REQ_STATE_CANCEL_PENDING:
220 		sr->sr_state = SMB_REQ_STATE_CANCELLED;
221 		rc = EINTR;
222 		break;
223 	default:
224 		/* keep rc from above */
225 		break;
226 	}
227 	mutex_exit(&sr->sr_mutex);
228 
229 
230 	/*
231 	 * Return the status we read from the pipe service,
232 	 * normally NT_STATUS_SUCCESS, but could be something
233 	 * else like NT_STATUS_ACCESS_DENIED.
234 	 */
235 	switch (rc) {
236 	case 0:
237 		errp->status = status;
238 		break;
239 	case EINTR:
240 		errp->status = NT_STATUS_CANCELLED;
241 		break;
242 	/*
243 	 * If we fail sending the netuserinfo or recv'ing the
244 	 * status reponse, we have probably run into the limit
245 	 * on the number of open pipes.  That's this status:
246 	 */
247 	default:
248 		errp->status = NT_STATUS_PIPE_NOT_AVAILABLE;
249 		break;
250 	}
251 
252 out:
253 	xdr_destroy(&xdrs);
254 	kmem_free(buf, buflen);
255 	smb_user_netinfo_fini(&nui);
256 }
257 
258 /*
259  * smb_opipe_open
260  *
261  * Open an RPC named pipe. This routine should be called if
262  * a file open is requested on a share of type STYPE_IPC.
263  * If we recognize the pipe, we setup a new ofile.
264  *
265  * Returns 0 on success, Otherwise an NT status code.
266  */
267 int
268 smb_opipe_open(smb_request_t *sr, uint32_t uniqid)
269 {
270 	smb_arg_open_t	*op = &sr->sr_open;
271 	smb_attr_t *ap = &op->fqi.fq_fattr;
272 	smb_ofile_t *ofile;
273 	smb_opipe_t *opipe;
274 	smb_error_t err;
275 
276 	opipe = smb_opipe_alloc(sr);
277 	if (opipe == NULL)
278 		return (NT_STATUS_INTERNAL_ERROR);
279 
280 	if (smb_opipe_connect(sr, opipe) != 0) {
281 		smb_opipe_dealloc(opipe);
282 		return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
283 	}
284 
285 	smb_opipe_send_userinfo(sr, opipe, &err);
286 	if (err.status != 0) {
287 		smb_opipe_dealloc(opipe);
288 		return (err.status);
289 	}
290 
291 	/*
292 	 * Note: If smb_ofile_open succeeds, the new ofile is
293 	 * in the FID lists can can be used by I/O requests.
294 	 */
295 	op->create_options = 0;
296 	op->pipe = opipe;
297 	ofile = smb_ofile_open(sr, NULL, op,
298 	    SMB_FTYPE_MESG_PIPE, uniqid, &err);
299 	op->pipe = NULL;
300 	if (ofile == NULL) {
301 		smb_opipe_dealloc(opipe);
302 		return (err.status);
303 	}
304 
305 	/* An "up" pointer, for debug. */
306 	opipe->p_ofile = ofile;
307 
308 	/*
309 	 * Caller expects attributes in op->fqi
310 	 */
311 	(void) smb_opipe_getattr(ofile, &op->fqi.fq_fattr);
312 
313 	op->dsize = 0;
314 	op->dattr = ap->sa_dosattr;
315 	op->fileid = ap->sa_vattr.va_nodeid;
316 	op->ftype = SMB_FTYPE_MESG_PIPE;
317 	op->action_taken = SMB_OACT_OPLOCK | SMB_OACT_OPENED;
318 	op->devstate = SMB_PIPE_READMODE_MESSAGE
319 	    | SMB_PIPE_TYPE_MESSAGE
320 	    | SMB_PIPE_UNLIMITED_INSTANCES; /* 0x05ff */
321 
322 	sr->smb_fid = ofile->f_fid;
323 	sr->fid_ofile = ofile;
324 
325 	return (NT_STATUS_SUCCESS);
326 }
327 
328 /*
329  * smb_opipe_close
330  *
331  * Called by smb_ofile_close for pipes.
332  *
333  * Note: ksocket_close may block while waiting for
334  * any I/O threads with a hold to get out.
335  */
336 void
337 smb_opipe_close(smb_ofile_t *of)
338 {
339 	smb_opipe_t *opipe;
340 	ksocket_t sock;
341 
342 	ASSERT(of->f_state == SMB_OFILE_STATE_CLOSING);
343 	ASSERT(of->f_ftype == SMB_FTYPE_MESG_PIPE);
344 	opipe = of->f_pipe;
345 	SMB_OPIPE_VALID(opipe);
346 
347 	mutex_enter(&opipe->p_mutex);
348 	sock = opipe->p_socket;
349 	opipe->p_socket = NULL;
350 	mutex_exit(&opipe->p_mutex);
351 
352 	(void) ksocket_shutdown(sock, SHUT_RDWR, of->f_cr);
353 	(void) ksocket_close(sock, of->f_cr);
354 }
355 
356 /*
357  * smb_opipe_write
358  *
359  * Write RPC request data to the pipe.  The client should call smb_opipe_read
360  * to complete the exchange and obtain the RPC response.
361  *
362  * Returns 0 on success or an errno on failure.
363  */
364 int
365 smb_opipe_write(smb_request_t *sr, struct uio *uio)
366 {
367 	struct nmsghdr msghdr;
368 	smb_ofile_t *ofile;
369 	smb_opipe_t *opipe;
370 	ksocket_t sock;
371 	size_t sent = 0;
372 	int rc = 0;
373 
374 	ofile = sr->fid_ofile;
375 	ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE);
376 	opipe = ofile->f_pipe;
377 	SMB_OPIPE_VALID(opipe);
378 
379 	mutex_enter(&opipe->p_mutex);
380 	sock = opipe->p_socket;
381 	if (sock != NULL)
382 		ksocket_hold(sock);
383 	mutex_exit(&opipe->p_mutex);
384 	if (sock == NULL)
385 		return (EBADF);
386 
387 	bzero(&msghdr, sizeof (msghdr));
388 	msghdr.msg_iov = uio->uio_iov;
389 	msghdr.msg_iovlen = uio->uio_iovcnt;
390 
391 	/*
392 	 * This should block until we've sent it all,
393 	 * or given up due to errors (pipe closed).
394 	 */
395 	while (uio->uio_resid > 0) {
396 		rc = ksocket_sendmsg(sock, &msghdr, 0, &sent, ofile->f_cr);
397 		if (rc != 0)
398 			break;
399 		uio->uio_resid -= sent;
400 	}
401 
402 	ksocket_rele(sock);
403 
404 	return (rc);
405 }
406 
407 /*
408  * smb_opipe_read
409  *
410  * This interface may be called from smb_opipe_transact (write, read)
411  * or from smb_read / smb2_read to get the rest of an RPC response.
412  * The response data (and length) are returned via the uio.
413  */
414 int
415 smb_opipe_read(smb_request_t *sr, struct uio *uio)
416 {
417 	struct nmsghdr msghdr;
418 	smb_ofile_t *ofile;
419 	smb_opipe_t *opipe;
420 	ksocket_t sock;
421 	size_t recvcnt = 0;
422 	int rc;
423 
424 	ofile = sr->fid_ofile;
425 	ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE);
426 	opipe = ofile->f_pipe;
427 	SMB_OPIPE_VALID(opipe);
428 
429 	mutex_enter(&opipe->p_mutex);
430 	sock = opipe->p_socket;
431 	if (sock != NULL)
432 		ksocket_hold(sock);
433 	mutex_exit(&opipe->p_mutex);
434 	if (sock == NULL)
435 		return (EBADF);
436 
437 	mutex_enter(&sr->sr_mutex);
438 	if (sr->sr_state != SMB_REQ_STATE_ACTIVE) {
439 		mutex_exit(&sr->sr_mutex);
440 		rc = EINTR;
441 		goto out;
442 	}
443 	sr->sr_state = SMB_REQ_STATE_WAITING_PIPE;
444 	sr->cancel_method = smb_opipe_cancel;
445 	sr->cancel_arg2 = sock;
446 	mutex_exit(&sr->sr_mutex);
447 
448 	/*
449 	 * This should block only if there's no data.
450 	 * A single call to recvmsg does just that.
451 	 * (Intentionaly no recv loop here.)
452 	 */
453 	bzero(&msghdr, sizeof (msghdr));
454 	msghdr.msg_iov = uio->uio_iov;
455 	msghdr.msg_iovlen = uio->uio_iovcnt;
456 	rc = ksocket_recvmsg(sock, &msghdr, 0,
457 	    &recvcnt, ofile->f_cr);
458 
459 	mutex_enter(&sr->sr_mutex);
460 	sr->cancel_method = NULL;
461 	sr->cancel_arg2 = NULL;
462 	switch (sr->sr_state) {
463 	case SMB_REQ_STATE_WAITING_PIPE:
464 		sr->sr_state = SMB_REQ_STATE_ACTIVE;
465 		break;
466 	case SMB_REQ_STATE_CANCEL_PENDING:
467 		sr->sr_state = SMB_REQ_STATE_CANCELLED;
468 		rc = EINTR;
469 		break;
470 	default:
471 		/* keep rc from above */
472 		break;
473 	}
474 	mutex_exit(&sr->sr_mutex);
475 
476 	if (rc != 0)
477 		goto out;
478 
479 	if (recvcnt == 0) {
480 		/* Other side closed. */
481 		rc = EPIPE;
482 		goto out;
483 	}
484 	uio->uio_resid -= recvcnt;
485 
486 out:
487 	ksocket_rele(sock);
488 
489 	return (rc);
490 }
491 
492 int
493 smb_opipe_ioctl(smb_request_t *sr, int cmd, void *arg, int *rvalp)
494 {
495 	smb_ofile_t *ofile;
496 	smb_opipe_t *opipe;
497 	ksocket_t sock;
498 	int rc;
499 
500 	ofile = sr->fid_ofile;
501 	ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE);
502 	opipe = ofile->f_pipe;
503 	SMB_OPIPE_VALID(opipe);
504 
505 	mutex_enter(&opipe->p_mutex);
506 	sock = opipe->p_socket;
507 	if (sock != NULL)
508 		ksocket_hold(sock);
509 	mutex_exit(&opipe->p_mutex);
510 	if (sock == NULL)
511 		return (EBADF);
512 
513 	rc = ksocket_ioctl(sock, cmd, (intptr_t)arg, rvalp, ofile->f_cr);
514 
515 	ksocket_rele(sock);
516 
517 	return (rc);
518 }
519 
520 /*
521  * Get the smb_attr_t for a named pipe.
522  * Caller has already cleared to zero.
523  */
524 int
525 smb_opipe_getattr(smb_ofile_t *of, smb_attr_t *ap)
526 {
527 
528 	if (of->f_pipe == NULL)
529 		return (EINVAL);
530 
531 	ap->sa_vattr.va_type = VFIFO;
532 	ap->sa_vattr.va_nlink = 1;
533 	ap->sa_vattr.va_nodeid = (uintptr_t)of->f_pipe;
534 	ap->sa_dosattr = FILE_ATTRIBUTE_NORMAL;
535 	ap->sa_allocsz = SMB_PIPE_MAX_MSGSIZE;
536 
537 	return (0);
538 }
539 
540 int
541 smb_opipe_getname(smb_ofile_t *of, char *buf, size_t buflen)
542 {
543 	smb_opipe_t *opipe;
544 
545 	if ((opipe = of->f_pipe) == NULL)
546 		return (EINVAL);
547 
548 	(void) snprintf(buf, buflen, "\\%s", opipe->p_name);
549 	return (0);
550 }
551 
552 /*
553  * Handler for smb2_ioctl
554  */
555 /* ARGSUSED */
556 uint32_t
557 smb_opipe_fsctl(smb_request_t *sr, smb_fsctl_t *fsctl)
558 {
559 	uint32_t status;
560 
561 	switch (fsctl->CtlCode) {
562 	case FSCTL_PIPE_TRANSCEIVE:
563 		status = smb_opipe_transceive(sr, fsctl);
564 		break;
565 
566 	case FSCTL_PIPE_PEEK:
567 	case FSCTL_PIPE_WAIT:
568 		/* XXX todo */
569 		status = NT_STATUS_NOT_SUPPORTED;
570 		break;
571 
572 	default:
573 		ASSERT(!"CtlCode");
574 		status = NT_STATUS_INTERNAL_ERROR;
575 		break;
576 	}
577 
578 	return (status);
579 }
580 
581 static uint32_t
582 smb_opipe_transceive(smb_request_t *sr, smb_fsctl_t *fsctl)
583 {
584 	smb_vdb_t	vdb;
585 	smb_ofile_t	*ofile;
586 	struct mbuf	*mb;
587 	uint32_t	status;
588 	int		len, rc;
589 
590 	/*
591 	 * Caller checked that this is the IPC$ share,
592 	 * and that this call has a valid open handle.
593 	 * Just check the type.
594 	 */
595 	ofile = sr->fid_ofile;
596 	if (ofile->f_ftype != SMB_FTYPE_MESG_PIPE)
597 		return (NT_STATUS_INVALID_HANDLE);
598 
599 	rc = smb_mbc_decodef(fsctl->in_mbc, "#B",
600 	    fsctl->InputCount, &vdb);
601 	if (rc != 0) {
602 		/* Not enough data sent. */
603 		return (NT_STATUS_INVALID_PARAMETER);
604 	}
605 
606 	rc = smb_opipe_write(sr, &vdb.vdb_uio);
607 	if (rc != 0)
608 		return (smb_errno2status(rc));
609 
610 	vdb.vdb_tag = 0;
611 	vdb.vdb_uio.uio_iov = &vdb.vdb_iovec[0];
612 	vdb.vdb_uio.uio_iovcnt = MAX_IOVEC;
613 	vdb.vdb_uio.uio_segflg = UIO_SYSSPACE;
614 	vdb.vdb_uio.uio_extflg = UIO_COPY_DEFAULT;
615 	vdb.vdb_uio.uio_loffset = (offset_t)0;
616 	vdb.vdb_uio.uio_resid = fsctl->MaxOutputResp;
617 	mb = smb_mbuf_allocate(&vdb.vdb_uio);
618 
619 	rc = smb_opipe_read(sr, &vdb.vdb_uio);
620 	if (rc != 0) {
621 		m_freem(mb);
622 		return (smb_errno2status(rc));
623 	}
624 
625 	len = fsctl->MaxOutputResp - vdb.vdb_uio.uio_resid;
626 	smb_mbuf_trim(mb, len);
627 	MBC_ATTACH_MBUF(fsctl->out_mbc, mb);
628 
629 	/*
630 	 * If the output buffer holds a partial pipe message,
631 	 * we're supposed to return NT_STATUS_BUFFER_OVERFLOW.
632 	 * As we don't have message boundary markers, the best
633 	 * we can do is return that status when we have ALL of:
634 	 *	Output buffer was < SMB_PIPE_MAX_MSGSIZE
635 	 *	We filled the output buffer (resid==0)
636 	 *	There's more data (ioctl FIONREAD)
637 	 */
638 	status = NT_STATUS_SUCCESS;
639 	if (fsctl->MaxOutputResp < SMB_PIPE_MAX_MSGSIZE &&
640 	    vdb.vdb_uio.uio_resid == 0) {
641 		int nread = 0, trval;
642 		rc = smb_opipe_ioctl(sr, FIONREAD, &nread, &trval);
643 		if (rc == 0 && nread != 0)
644 			status = NT_STATUS_BUFFER_OVERFLOW;
645 	}
646 
647 	return (status);
648 }
649