smb_opipe.c revision 68b2bbf26c7040fea4281dcb58b81e7627e46f34
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.
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 const char *name;
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. */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * If we filled the user's buffer,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * find out if there's more data.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross rc2 = ksocket_ioctl(sock, FIONREAD, (intptr_t)&nread,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (rc);