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 } 658