3db3f65c6274eb042354801a308c8e9bc4994553amw * CDDL HEADER START
3db3f65c6274eb042354801a308c8e9bc4994553amw * The contents of this file are subject to the terms of the
3db3f65c6274eb042354801a308c8e9bc4994553amw * Common Development and Distribution License (the "License").
3db3f65c6274eb042354801a308c8e9bc4994553amw * You may not use this file except in compliance with the License.
3db3f65c6274eb042354801a308c8e9bc4994553amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3db3f65c6274eb042354801a308c8e9bc4994553amw * See the License for the specific language governing permissions
3db3f65c6274eb042354801a308c8e9bc4994553amw * and limitations under the License.
3db3f65c6274eb042354801a308c8e9bc4994553amw * When distributing Covered Code, include this CDDL HEADER in each
3db3f65c6274eb042354801a308c8e9bc4994553amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
3db3f65c6274eb042354801a308c8e9bc4994553amw * If applicable, add the following below this CDDL HEADER, with the
3db3f65c6274eb042354801a308c8e9bc4994553amw * fields enclosed by brackets "[]" replaced with your own identifying
3db3f65c6274eb042354801a308c8e9bc4994553amw * information: Portions Copyright [yyyy] [name of copyright owner]
3db3f65c6274eb042354801a308c8e9bc4994553amw * CDDL HEADER END
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
3db3f65c6274eb042354801a308c8e9bc4994553amw * This module provides the interface to NDR RPC.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic uint32_t smb_opipe_transceive(smb_request_t *, smb_fsctl_t *);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Allocate a new opipe and return it, or NULL, in which case
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * the caller will report "internal error".
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_opipe_t *opipe;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (ksocket_socket(&sock, AF_UNIX, SOCK_STREAM, 0,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
8622ec4569457733001d4982ef7f5b44427069beGordon Ross opipe = kmem_cache_alloc(smb_cache_opipe, KM_SLEEP);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States bzero(opipe, sizeof (smb_opipe_t));
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States mutex_init(&opipe->p_mutex, NULL, MUTEX_DEFAULT, NULL);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States cv_init(&opipe->p_cv, NULL, CV_DEFAULT, NULL);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States opipe->p_magic = SMB_OPIPE_MAGIC;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States opipe->p_server = sv;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (opipe);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Destroy an opipe. This is normally called from smb_ofile_delete
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * when the ofile has no more references and is about to be free'd.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * This is also called here in error handling code paths, before
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * the opipe is installed under an ofile.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesvoid
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_opipe_dealloc(smb_opipe_t *opipe)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_server_t *sv;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_OPIPE_VALID(opipe);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States sv = opipe->p_server;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * This is called in the error path when opening,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * in which case we close the socket here.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross (void) ksocket_close(opipe->p_socket, zone_kcred());
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States opipe->p_magic = (uint32_t)~SMB_OPIPE_MAGIC;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States cv_destroy(&opipe->p_cv);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States mutex_destroy(&opipe->p_mutex);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Helper for open: build pipe name and connect.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rosssmb_opipe_connect(smb_request_t *sr, smb_opipe_t *opipe)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross (void) strlcpy(opipe->p_name, name, SMB_OPIPE_MAXNAME);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross (void) snprintf(saddr.sun_path, sizeof (saddr.sun_path),
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross rc = ksocket_connect(opipe->p_socket, (struct sockaddr *)&saddr,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Helper for open: encode and send the user info.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * We send information about this client + user to the
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * pipe service so it can use it for access checks.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * The service MAY deny the open based on this info,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * (i.e. anonymous session trying to open a pipe that
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * requires authentication) in which case we will read
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * an error status from the service and return that.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rosssmb_opipe_send_userinfo(smb_request_t *sr, smb_opipe_t *opipe,
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Any errors building the XDR message etc.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross phdr.ph_uilen = xdr_sizeof(smb_netuserinfo_xdr, &nui);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * If we fail sending the netuserinfo or recv'ing the
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * status reponse, we have probably run into the limit
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * on the number of open pipes. That's this status:
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross rc = ksocket_send(opipe->p_socket, buf, buflen, 0,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross rc = ksocket_recv(opipe->p_socket, &status, sizeof (status), 0,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Return the status we read from the pipe service,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * normally NT_STATUS_SUCCESS, but could be something
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * else like NT_STATUS_ACCESS_DENIED.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * smb_opipe_open
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Open an RPC named pipe. This routine should be called if
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * a file open is requested on a share of type STYPE_IPC.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * If we recognize the pipe, we setup a new ofile.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Returns 0 on success, Otherwise an NT status code.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rosssmb_opipe_open(smb_request_t *sr, uint32_t uniqid)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Note: If smb_ofile_open succeeds, the new ofile is
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * in the FID lists can can be used by I/O requests.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross /* An "up" pointer, for debug. */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross op->action_taken = SMB_OACT_LOCK | SMB_OACT_OPENED; /* 0x8001 */
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_opipe_close
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Called by smb_ofile_close for pipes.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Note: ksocket_close may block while waiting for
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * any I/O threads with a hold to get out.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_OPIPE_VALID(opipe);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross (void) ksocket_shutdown(sock, SHUT_RDWR, of->f_cr);
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_opipe_write
3db3f65c6274eb042354801a308c8e9bc4994553amw * Write RPC request data to the pipe. The client should call smb_opipe_read
3db3f65c6274eb042354801a308c8e9bc4994553amw * to complete the exchange and obtain the RPC response.
3db3f65c6274eb042354801a308c8e9bc4994553amw * Returns 0 on success or an errno on failure.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_OPIPE_VALID(opipe);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * This should block until we've sent it all,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * or given up due to errors (pipe closed).
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross rc = ksocket_sendmsg(sock, &msghdr, 0, &sent, ofile->f_cr);
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_opipe_read
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * This interface may be called from smb_opipe_transact (write, read)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * or from smb_read / smb2_read to get the rest of an RPC response.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * The response data (and length) are returned via the uio.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_OPIPE_VALID(opipe);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * This should block only if there's no data.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * A single call to recvmsg does just that.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * (Intentionaly no recv loop here.)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross /* Other side closed. */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (rc);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb_opipe_ioctl(smb_request_t *sr, int cmd, void *arg, int *rvalp)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = ksocket_ioctl(sock, cmd, (intptr_t)arg, rvalp, ofile->f_cr);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Get the smb_attr_t for a named pipe.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Caller has already cleared to zero.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb_opipe_getattr(smb_ofile_t *of, smb_attr_t *ap)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb_opipe_getname(smb_ofile_t *of, char *buf, size_t buflen)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross (void) snprintf(buf, buflen, "\\%s", opipe->p_name);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Handler for smb2_ioctl
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross/* ARGSUSED */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb_opipe_fsctl(smb_request_t *sr, smb_fsctl_t *fsctl)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* XXX todo */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb_opipe_transceive(smb_request_t *sr, smb_fsctl_t *fsctl)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Caller checked that this is the IPC$ share,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * and that this call has a valid open handle.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Just check the type.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* Not enough data sent. */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross len = fsctl->MaxOutputResp - vdb.vdb_uio.uio_resid;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * If the output buffer holds a partial pipe message,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * we're supposed to return NT_STATUS_BUFFER_OVERFLOW.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * As we don't have message boundary markers, the best
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * we can do is return that status when we have ALL of:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Output buffer was < SMB_PIPE_MAX_MSGSIZE
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * We filled the output buffer (resid==0)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * There's more data (ioctl FIONREAD)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (fsctl->MaxOutputResp < SMB_PIPE_MAX_MSGSIZE &&