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