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 * Helper for open: build pipe name and connect. 101 */ 102 static int 103 smb_opipe_connect(smb_request_t *sr, smb_opipe_t *opipe) 104 { 105 struct sockaddr_un saddr; 106 smb_arg_open_t *op = &sr->sr_open; 107 const char *name; 108 int rc; 109 110 name = op->fqi.fq_path.pn_path; 111 name += strspn(name, "\\"); 112 if (smb_strcasecmp(name, "PIPE", 4) == 0) { 113 name += 4; 114 name += strspn(name, "\\"); 115 } 116 (void) strlcpy(opipe->p_name, name, SMB_OPIPE_MAXNAME); 117 (void) smb_strlwr(opipe->p_name); 118 119 bzero(&saddr, sizeof (saddr)); 120 saddr.sun_family = AF_UNIX; 121 (void) snprintf(saddr.sun_path, sizeof (saddr.sun_path), 122 "%s/%s", SMB_PIPE_DIR, opipe->p_name); 123 rc = ksocket_connect(opipe->p_socket, (struct sockaddr *)&saddr, 124 sizeof (saddr), sr->user_cr); 125 126 return (rc); 127 } 128 129 /* 130 * Helper for open: encode and send the user info. 131 * 132 * We send information about this client + user to the 133 * pipe service so it can use it for access checks. 134 * The service MAY deny the open based on this info, 135 * (i.e. anonymous session trying to open a pipe that 136 * requires authentication) in which case we will read 137 * an error status from the service and return that. 138 */ 139 static void 140 smb_opipe_send_userinfo(smb_request_t *sr, smb_opipe_t *opipe, 141 smb_error_t *errp) 142 { 143 XDR xdrs; 144 smb_netuserinfo_t nui; 145 smb_pipehdr_t phdr; 146 char *buf; 147 uint32_t buflen; 148 uint32_t status; 149 size_t iocnt = 0; 150 int rc; 151 152 /* 153 * Any errors building the XDR message etc. 154 */ 155 errp->status = NT_STATUS_INTERNAL_ERROR; 156 157 smb_user_netinfo_init(sr->uid_user, &nui); 158 phdr.ph_magic = SMB_PIPE_HDR_MAGIC; 159 phdr.ph_uilen = xdr_sizeof(smb_netuserinfo_xdr, &nui); 160 161 buflen = sizeof (phdr) + phdr.ph_uilen; 162 buf = kmem_alloc(buflen, KM_SLEEP); 163 164 bcopy(&phdr, buf, sizeof (phdr)); 165 xdrmem_create(&xdrs, buf + sizeof (phdr), 166 buflen - (sizeof (phdr)), XDR_ENCODE); 167 if (!smb_netuserinfo_xdr(&xdrs, &nui)) 168 goto out; 169 170 /* 171 * If we fail sending the netuserinfo or recv'ing the 172 * status reponse, we have probably run into the limit 173 * on the number of open pipes. That's this status: 174 */ 175 errp->status = NT_STATUS_PIPE_NOT_AVAILABLE; 176 177 rc = ksocket_send(opipe->p_socket, buf, buflen, 0, 178 &iocnt, sr->user_cr); 179 if (rc == 0 && iocnt != buflen) 180 rc = EIO; 181 if (rc != 0) 182 goto out; 183 184 rc = ksocket_recv(opipe->p_socket, &status, sizeof (status), 0, 185 &iocnt, sr->user_cr); 186 if (rc != 0 || iocnt != sizeof (status)) 187 goto out; 188 189 /* 190 * Return the status we read from the pipe service, 191 * normally NT_STATUS_SUCCESS, but could be something 192 * else like NT_STATUS_ACCESS_DENIED. 193 */ 194 errp->status = status; 195 196 out: 197 xdr_destroy(&xdrs); 198 kmem_free(buf, buflen); 199 smb_user_netinfo_fini(&nui); 200 } 201 202 /* 203 * smb_opipe_open 204 * 205 * Open an RPC named pipe. This routine should be called if 206 * a file open is requested on a share of type STYPE_IPC. 207 * If we recognize the pipe, we setup a new ofile. 208 * 209 * Returns 0 on success, Otherwise an NT status code. 210 */ 211 int 212 smb_opipe_open(smb_request_t *sr, uint32_t uniqid) 213 { 214 smb_arg_open_t *op = &sr->sr_open; 215 smb_attr_t *ap = &op->fqi.fq_fattr; 216 smb_ofile_t *ofile; 217 smb_opipe_t *opipe; 218 smb_error_t err; 219 220 opipe = smb_opipe_alloc(sr); 221 if (opipe == NULL) 222 return (NT_STATUS_INTERNAL_ERROR); 223 224 if (smb_opipe_connect(sr, opipe) != 0) { 225 smb_opipe_dealloc(opipe); 226 return (NT_STATUS_OBJECT_NAME_NOT_FOUND); 227 } 228 229 smb_opipe_send_userinfo(sr, opipe, &err); 230 if (err.status != 0) { 231 smb_opipe_dealloc(opipe); 232 return (err.status); 233 } 234 235 /* 236 * Note: If smb_ofile_open succeeds, the new ofile is 237 * in the FID lists can can be used by I/O requests. 238 */ 239 op->create_options = 0; 240 op->pipe = opipe; 241 ofile = smb_ofile_open(sr, NULL, op, 242 SMB_FTYPE_MESG_PIPE, uniqid, &err); 243 op->pipe = NULL; 244 if (ofile == NULL) { 245 smb_opipe_dealloc(opipe); 246 return (err.status); 247 } 248 249 /* An "up" pointer, for debug. */ 250 opipe->p_ofile = ofile; 251 252 /* 253 * Caller expects attributes in op->fqi 254 */ 255 (void) smb_opipe_getattr(ofile, &op->fqi.fq_fattr); 256 257 op->dsize = 0; 258 op->dattr = ap->sa_dosattr; 259 op->fileid = ap->sa_vattr.va_nodeid; 260 op->ftype = SMB_FTYPE_MESG_PIPE; 261 op->action_taken = SMB_OACT_OPLOCK | SMB_OACT_OPENED; 262 op->devstate = SMB_PIPE_READMODE_MESSAGE 263 | SMB_PIPE_TYPE_MESSAGE 264 | SMB_PIPE_UNLIMITED_INSTANCES; /* 0x05ff */ 265 266 sr->smb_fid = ofile->f_fid; 267 sr->fid_ofile = ofile; 268 269 return (NT_STATUS_SUCCESS); 270 } 271 272 /* 273 * smb_opipe_close 274 * 275 * Called by smb_ofile_close for pipes. 276 * 277 * Note: ksocket_close may block while waiting for 278 * any I/O threads with a hold to get out. 279 */ 280 void 281 smb_opipe_close(smb_ofile_t *of) 282 { 283 smb_opipe_t *opipe; 284 ksocket_t sock; 285 286 ASSERT(of->f_state == SMB_OFILE_STATE_CLOSING); 287 ASSERT(of->f_ftype == SMB_FTYPE_MESG_PIPE); 288 opipe = of->f_pipe; 289 SMB_OPIPE_VALID(opipe); 290 291 mutex_enter(&opipe->p_mutex); 292 sock = opipe->p_socket; 293 opipe->p_socket = NULL; 294 mutex_exit(&opipe->p_mutex); 295 296 (void) ksocket_shutdown(sock, SHUT_RDWR, of->f_cr); 297 (void) ksocket_close(sock, of->f_cr); 298 } 299 300 /* 301 * smb_opipe_write 302 * 303 * Write RPC request data to the pipe. The client should call smb_opipe_read 304 * to complete the exchange and obtain the RPC response. 305 * 306 * Returns 0 on success or an errno on failure. 307 */ 308 int 309 smb_opipe_write(smb_request_t *sr, struct uio *uio) 310 { 311 struct nmsghdr msghdr; 312 smb_ofile_t *ofile; 313 smb_opipe_t *opipe; 314 ksocket_t sock; 315 size_t sent = 0; 316 int rc = 0; 317 318 ofile = sr->fid_ofile; 319 ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE); 320 opipe = ofile->f_pipe; 321 SMB_OPIPE_VALID(opipe); 322 323 mutex_enter(&opipe->p_mutex); 324 sock = opipe->p_socket; 325 if (sock != NULL) 326 ksocket_hold(sock); 327 mutex_exit(&opipe->p_mutex); 328 if (sock == NULL) 329 return (EBADF); 330 331 bzero(&msghdr, sizeof (msghdr)); 332 msghdr.msg_iov = uio->uio_iov; 333 msghdr.msg_iovlen = uio->uio_iovcnt; 334 335 /* 336 * This should block until we've sent it all, 337 * or given up due to errors (pipe closed). 338 */ 339 while (uio->uio_resid > 0) { 340 rc = ksocket_sendmsg(sock, &msghdr, 0, &sent, ofile->f_cr); 341 if (rc != 0) 342 break; 343 uio->uio_resid -= sent; 344 } 345 346 ksocket_rele(sock); 347 348 return (rc); 349 } 350 351 /* 352 * smb_opipe_read 353 * 354 * This interface may be called from smb_opipe_transact (write, read) 355 * or from smb_read / smb2_read to get the rest of an RPC response. 356 * The response data (and length) are returned via the uio. 357 */ 358 int 359 smb_opipe_read(smb_request_t *sr, struct uio *uio) 360 { 361 struct nmsghdr msghdr; 362 smb_ofile_t *ofile; 363 smb_opipe_t *opipe; 364 ksocket_t sock; 365 size_t recvcnt = 0; 366 int rc; 367 368 ofile = sr->fid_ofile; 369 ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE); 370 opipe = ofile->f_pipe; 371 SMB_OPIPE_VALID(opipe); 372 373 mutex_enter(&opipe->p_mutex); 374 sock = opipe->p_socket; 375 if (sock != NULL) 376 ksocket_hold(sock); 377 mutex_exit(&opipe->p_mutex); 378 if (sock == NULL) 379 return (EBADF); 380 381 bzero(&msghdr, sizeof (msghdr)); 382 msghdr.msg_iov = uio->uio_iov; 383 msghdr.msg_iovlen = uio->uio_iovcnt; 384 385 /* 386 * This should block only if there's no data. 387 * A single call to recvmsg does just that. 388 * (Intentionaly no recv loop here.) 389 */ 390 rc = ksocket_recvmsg(sock, &msghdr, 0, 391 &recvcnt, ofile->f_cr); 392 if (rc != 0) 393 goto out; 394 395 if (recvcnt == 0) { 396 /* Other side closed. */ 397 rc = EPIPE; 398 goto out; 399 } 400 uio->uio_resid -= recvcnt; 401 402 out: 403 ksocket_rele(sock); 404 405 return (rc); 406 } 407 408 int 409 smb_opipe_ioctl(smb_request_t *sr, int cmd, void *arg, int *rvalp) 410 { 411 smb_ofile_t *ofile; 412 smb_opipe_t *opipe; 413 ksocket_t sock; 414 int rc; 415 416 ofile = sr->fid_ofile; 417 ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE); 418 opipe = ofile->f_pipe; 419 SMB_OPIPE_VALID(opipe); 420 421 mutex_enter(&opipe->p_mutex); 422 sock = opipe->p_socket; 423 if (sock != NULL) 424 ksocket_hold(sock); 425 mutex_exit(&opipe->p_mutex); 426 if (sock == NULL) 427 return (EBADF); 428 429 rc = ksocket_ioctl(sock, cmd, (intptr_t)arg, rvalp, ofile->f_cr); 430 431 ksocket_rele(sock); 432 433 return (rc); 434 } 435 436 /* 437 * Get the smb_attr_t for a named pipe. 438 * Caller has already cleared to zero. 439 */ 440 int 441 smb_opipe_getattr(smb_ofile_t *of, smb_attr_t *ap) 442 { 443 444 if (of->f_pipe == NULL) 445 return (EINVAL); 446 447 ap->sa_vattr.va_type = VFIFO; 448 ap->sa_vattr.va_nlink = 1; 449 ap->sa_vattr.va_nodeid = (uintptr_t)of->f_pipe; 450 ap->sa_dosattr = FILE_ATTRIBUTE_NORMAL; 451 ap->sa_allocsz = SMB_PIPE_MAX_MSGSIZE; 452 453 return (0); 454 } 455 456 int 457 smb_opipe_getname(smb_ofile_t *of, char *buf, size_t buflen) 458 { 459 smb_opipe_t *opipe; 460 461 if ((opipe = of->f_pipe) == NULL) 462 return (EINVAL); 463 464 (void) snprintf(buf, buflen, "\\%s", opipe->p_name); 465 return (0); 466 } 467 468 /* 469 * Handler for smb2_ioctl 470 */ 471 /* ARGSUSED */ 472 uint32_t 473 smb_opipe_fsctl(smb_request_t *sr, smb_fsctl_t *fsctl) 474 { 475 uint32_t status; 476 477 switch (fsctl->CtlCode) { 478 case FSCTL_PIPE_TRANSCEIVE: 479 status = smb_opipe_transceive(sr, fsctl); 480 break; 481 482 case FSCTL_PIPE_PEEK: 483 case FSCTL_PIPE_WAIT: 484 /* XXX todo */ 485 status = NT_STATUS_NOT_SUPPORTED; 486 break; 487 488 default: 489 ASSERT(!"CtlCode"); 490 status = NT_STATUS_INTERNAL_ERROR; 491 break; 492 } 493 494 return (status); 495 } 496 497 static uint32_t 498 smb_opipe_transceive(smb_request_t *sr, smb_fsctl_t *fsctl) 499 { 500 smb_vdb_t vdb; 501 smb_ofile_t *ofile; 502 struct mbuf *mb; 503 uint32_t status; 504 int len, rc; 505 506 /* 507 * Caller checked that this is the IPC$ share, 508 * and that this call has a valid open handle. 509 * Just check the type. 510 */ 511 ofile = sr->fid_ofile; 512 if (ofile->f_ftype != SMB_FTYPE_MESG_PIPE) 513 return (NT_STATUS_INVALID_HANDLE); 514 515 rc = smb_mbc_decodef(fsctl->in_mbc, "#B", 516 fsctl->InputCount, &vdb); 517 if (rc != 0) { 518 /* Not enough data sent. */ 519 return (NT_STATUS_INVALID_PARAMETER); 520 } 521 522 rc = smb_opipe_write(sr, &vdb.vdb_uio); 523 if (rc != 0) 524 return (smb_errno2status(rc)); 525 526 vdb.vdb_tag = 0; 527 vdb.vdb_uio.uio_iov = &vdb.vdb_iovec[0]; 528 vdb.vdb_uio.uio_iovcnt = MAX_IOVEC; 529 vdb.vdb_uio.uio_segflg = UIO_SYSSPACE; 530 vdb.vdb_uio.uio_extflg = UIO_COPY_DEFAULT; 531 vdb.vdb_uio.uio_loffset = (offset_t)0; 532 vdb.vdb_uio.uio_resid = fsctl->MaxOutputResp; 533 mb = smb_mbuf_allocate(&vdb.vdb_uio); 534 535 rc = smb_opipe_read(sr, &vdb.vdb_uio); 536 if (rc != 0) { 537 m_freem(mb); 538 return (smb_errno2status(rc)); 539 } 540 541 len = fsctl->MaxOutputResp - vdb.vdb_uio.uio_resid; 542 smb_mbuf_trim(mb, len); 543 MBC_ATTACH_MBUF(fsctl->out_mbc, mb); 544 545 /* 546 * If the output buffer holds a partial pipe message, 547 * we're supposed to return NT_STATUS_BUFFER_OVERFLOW. 548 * As we don't have message boundary markers, the best 549 * we can do is return that status when we have ALL of: 550 * Output buffer was < SMB_PIPE_MAX_MSGSIZE 551 * We filled the output buffer (resid==0) 552 * There's more data (ioctl FIONREAD) 553 */ 554 status = NT_STATUS_SUCCESS; 555 if (fsctl->MaxOutputResp < SMB_PIPE_MAX_MSGSIZE && 556 vdb.vdb_uio.uio_resid == 0) { 557 int nread = 0, trval; 558 rc = smb_opipe_ioctl(sr, FIONREAD, &nread, &trval); 559 if (rc == 0 && nread != 0) 560 status = NT_STATUS_BUFFER_OVERFLOW; 561 } 562 563 return (status); 564 } 565