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