3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * CDDL HEADER START
3db3f65c6274eb042354801a308c8e9bc4994553amw *
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 *
3db3f65c6274eb042354801a308c8e9bc4994553amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3db3f65c6274eb042354801a308c8e9bc4994553amw * or http://www.opensolaris.org/os/licensing.
3db3f65c6274eb042354801a308c8e9bc4994553amw * See the License for the specific language governing permissions
3db3f65c6274eb042354801a308c8e9bc4994553amw * and limitations under the License.
3db3f65c6274eb042354801a308c8e9bc4994553amw *
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 *
3db3f65c6274eb042354801a308c8e9bc4994553amw * CDDL HEADER END
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
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 */
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * This module provides the interface to NDR RPC.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw#include <sys/stat.h>
3db3f65c6274eb042354801a308c8e9bc4994553amw#include <sys/uio.h>
3db3f65c6274eb042354801a308c8e9bc4994553amw#include <sys/ksynch.h>
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross#include <sys/stropts.h>
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross#include <sys/socket.h>
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross#include <sys/filio.h>
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <smbsrv/smb_kproto.h>
3db3f65c6274eb042354801a308c8e9bc4994553amw#include <smbsrv/smb_xdr.h>
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#include <smbsrv/winioctl.h>
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic uint32_t smb_opipe_transceive(smb_request_t *, smb_fsctl_t *);
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross/*
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Allocate a new opipe and return it, or NULL, in which case
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * the caller will report "internal error".
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rossstatic smb_opipe_t *
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rosssmb_opipe_alloc(smb_request_t *sr)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_server_t *sv = sr->sr_server;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_opipe_t *opipe;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ksocket_t sock;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (ksocket_socket(&sock, AF_UNIX, SOCK_STREAM, 0,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross KSOCKET_SLEEP, sr->user_cr) != 0)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross return (NULL);
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;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross opipe->p_refcnt = 1;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross opipe->p_socket = sock;
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/*
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.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross */
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 /*
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * This is called in the error path when opening,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * in which case we close the socket here.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (opipe->p_socket != NULL)
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
8622ec4569457733001d4982ef7f5b44427069beGordon Ross kmem_cache_free(smb_cache_opipe, opipe);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Helper for open: build pipe name and connect.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rossstatic int
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rosssmb_opipe_connect(smb_request_t *sr, smb_opipe_t *opipe)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross struct sockaddr_un saddr;
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright smb_arg_open_t *op = &sr->sr_open;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross const char *name;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross int rc;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross name = op->fqi.fq_path.pn_path;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross name += strspn(name, "\\");
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (smb_strcasecmp(name, "PIPE", 4) == 0) {
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross name += 4;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross name += strspn(name, "\\");
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross }
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross (void) strlcpy(opipe->p_name, name, SMB_OPIPE_MAXNAME);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross (void) smb_strlwr(opipe->p_name);
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross bzero(&saddr, sizeof (saddr));
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross saddr.sun_family = AF_UNIX;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross (void) snprintf(saddr.sun_path, sizeof (saddr.sun_path),
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross "%s/%s", SMB_PIPE_DIR, opipe->p_name);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross rc = ksocket_connect(opipe->p_socket, (struct sockaddr *)&saddr,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross sizeof (saddr), sr->user_cr);
b7301bf5522d8b9141fe432333ded586218327f2Gordon Ross
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross return (rc);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross}
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross/*
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Helper for open: encode and send the user info.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross *
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 Ross */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rossstatic void
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rosssmb_opipe_send_userinfo(smb_request_t *sr, smb_opipe_t *opipe,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_error_t *errp)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross{
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross XDR xdrs;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_netuserinfo_t nui;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_pipehdr_t phdr;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross char *buf;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross uint32_t buflen;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross uint32_t status;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross size_t iocnt = 0;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross int rc;
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross /*
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Any errors building the XDR message etc.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross errp->status = NT_STATUS_INTERNAL_ERROR;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_user_netinfo_init(sr->uid_user, &nui);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross phdr.ph_magic = SMB_PIPE_HDR_MAGIC;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross phdr.ph_uilen = xdr_sizeof(smb_netuserinfo_xdr, &nui);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross buflen = sizeof (phdr) + phdr.ph_uilen;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross buf = kmem_alloc(buflen, KM_SLEEP);
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross bcopy(&phdr, buf, sizeof (phdr));
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross xdrmem_create(&xdrs, buf + sizeof (phdr),
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross buflen - (sizeof (phdr)), XDR_ENCODE);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (!smb_netuserinfo_xdr(&xdrs, &nui))
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross goto out;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross /*
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 */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross errp->status = NT_STATUS_PIPE_NOT_AVAILABLE;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross rc = ksocket_send(opipe->p_socket, buf, buflen, 0,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross &iocnt, sr->user_cr);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (rc == 0 && iocnt != buflen)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross rc = EIO;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (rc != 0)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross goto out;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross rc = ksocket_recv(opipe->p_socket, &status, sizeof (status), 0,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross &iocnt, sr->user_cr);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (rc != 0 || iocnt != sizeof (status))
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross goto out;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw /*
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.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross errp->status = status;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rossout:
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross xdr_destroy(&xdrs);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross kmem_free(buf, buflen);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_user_netinfo_fini(&nui);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * smb_opipe_open
3db3f65c6274eb042354801a308c8e9bc4994553amw *
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.
3db3f65c6274eb042354801a308c8e9bc4994553amw *
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Returns 0 on success, Otherwise an NT status code.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rossint
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rosssmb_opipe_open(smb_request_t *sr, uint32_t uniqid)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_arg_open_t *op = &sr->sr_open;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_ofile_t *ofile;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_opipe_t *opipe;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_error_t err;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross opipe = smb_opipe_alloc(sr);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (opipe == NULL)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross return (NT_STATUS_INTERNAL_ERROR);
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (smb_opipe_connect(sr, opipe) != 0) {
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_opipe_dealloc(opipe);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_opipe_send_userinfo(sr, opipe, &err);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (err.status != 0) {
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_opipe_dealloc(opipe);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross return (err.status);
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross /*
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 */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross op->create_options = 0;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross op->pipe = opipe;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ofile = smb_ofile_open(sr, NULL, op,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross SMB_FTYPE_MESG_PIPE, uniqid, &err);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross op->pipe = NULL;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (ofile == NULL) {
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_opipe_dealloc(opipe);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross return (err.status);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross }
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross /* An "up" pointer, for debug. */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross opipe->p_ofile = ofile;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross op->dsize = 0x01000;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross op->dattr = FILE_ATTRIBUTE_NORMAL;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross op->ftype = SMB_FTYPE_MESG_PIPE;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross op->action_taken = SMB_OACT_LOCK | SMB_OACT_OPENED; /* 0x8001 */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross op->devstate = SMB_PIPE_READMODE_MESSAGE
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross | SMB_PIPE_TYPE_MESSAGE
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross | SMB_PIPE_UNLIMITED_INSTANCES; /* 0x05ff */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross op->fileid = ofile->f_fid;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross sr->smb_fid = ofile->f_fid;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross sr->fid_ofile = ofile;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross return (NT_STATUS_SUCCESS);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_opipe_close
3db3f65c6274eb042354801a308c8e9bc4994553amw *
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Called by smb_ofile_close for pipes.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross *
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * Note: ksocket_close may block while waiting for
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * any I/O threads with a hold to get out.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwvoid
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_opipe_close(smb_ofile_t *of)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_opipe_t *opipe;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ksocket_t sock;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ASSERT(of->f_state == SMB_OFILE_STATE_CLOSING);
3db3f65c6274eb042354801a308c8e9bc4994553amw ASSERT(of->f_ftype == SMB_FTYPE_MESG_PIPE);
3db3f65c6274eb042354801a308c8e9bc4994553amw opipe = of->f_pipe;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_OPIPE_VALID(opipe);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross mutex_enter(&opipe->p_mutex);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross sock = opipe->p_socket;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross opipe->p_socket = NULL;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross mutex_exit(&opipe->p_mutex);
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross (void) ksocket_shutdown(sock, SHUT_RDWR, of->f_cr);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross (void) ksocket_close(sock, of->f_cr);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_opipe_write
3db3f65c6274eb042354801a308c8e9bc4994553amw *
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 *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Returns 0 on success or an errno on failure.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwint
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_opipe_write(smb_request_t *sr, struct uio *uio)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross struct nmsghdr msghdr;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_ofile_t *ofile;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_opipe_t *opipe;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ksocket_t sock;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross size_t sent = 0;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross int rc = 0;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ofile = sr->fid_ofile;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross opipe = ofile->f_pipe;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_OPIPE_VALID(opipe);
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross mutex_enter(&opipe->p_mutex);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross sock = opipe->p_socket;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (sock != NULL)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ksocket_hold(sock);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross mutex_exit(&opipe->p_mutex);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (sock == NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (EBADF);
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross bzero(&msghdr, sizeof (msghdr));
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross msghdr.msg_iov = uio->uio_iov;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross msghdr.msg_iovlen = uio->uio_iovcnt;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross /*
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * This should block until we've sent it all,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * or given up due to errors (pipe closed).
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross while (uio->uio_resid > 0) {
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross rc = ksocket_sendmsg(sock, &msghdr, 0, &sent, ofile->f_cr);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (rc != 0)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross break;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross uio->uio_resid -= sent;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross }
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ksocket_rele(sock);
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross return (rc);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_opipe_read
3db3f65c6274eb042354801a308c8e9bc4994553amw *
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.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwint
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_opipe_read(smb_request_t *sr, struct uio *uio)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross struct nmsghdr msghdr;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross smb_ofile_t *ofile;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_opipe_t *opipe;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ksocket_t sock;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross size_t recvcnt = 0;
3db3f65c6274eb042354801a308c8e9bc4994553amw int rc;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ofile = sr->fid_ofile;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross opipe = ofile->f_pipe;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_OPIPE_VALID(opipe);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross mutex_enter(&opipe->p_mutex);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross sock = opipe->p_socket;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (sock != NULL)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ksocket_hold(sock);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross mutex_exit(&opipe->p_mutex);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (sock == NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (EBADF);
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross bzero(&msghdr, sizeof (msghdr));
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross msghdr.msg_iov = uio->uio_iov;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross msghdr.msg_iovlen = uio->uio_iovcnt;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross /*
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 */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross rc = ksocket_recvmsg(sock, &msghdr, 0,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross &recvcnt, ofile->f_cr);
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (rc != 0)
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross goto out;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (recvcnt == 0) {
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross /* Other side closed. */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross rc = EPIPE;
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross goto out;
3db3f65c6274eb042354801a308c8e9bc4994553amw }
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross uio->uio_resid -= recvcnt;
3db3f65c6274eb042354801a308c8e9bc4994553amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rossout:
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross ksocket_rele(sock);
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}
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Rossint
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb_opipe_ioctl(smb_request_t *sr, int cmd, void *arg, int *rvalp)
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross{
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross smb_ofile_t *ofile;
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross smb_opipe_t *opipe;
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross ksocket_t sock;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross int rc;
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross ofile = sr->fid_ofile;
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE);
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross opipe = ofile->f_pipe;
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross SMB_OPIPE_VALID(opipe);
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross mutex_enter(&opipe->p_mutex);
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross sock = opipe->p_socket;
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross if (sock != NULL)
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross ksocket_hold(sock);
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross mutex_exit(&opipe->p_mutex);
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross if (sock == NULL)
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross return (EBADF);
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = ksocket_ioctl(sock, cmd, (intptr_t)arg, rvalp, ofile->f_cr);
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross ksocket_rele(sock);
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross return (rc);
bce01b59de50fe66a0267f4aa23e1d6e60d973d9Gordon Ross}
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross/*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Get the smb_attr_t for a named pipe.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Caller has already cleared to zero.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossint
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb_opipe_getattr(smb_ofile_t *of, smb_attr_t *ap)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross{
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (of->f_pipe == NULL)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (EINVAL);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross ap->sa_vattr.va_type = VFIFO;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross ap->sa_vattr.va_nlink = 1;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross ap->sa_dosattr = FILE_ATTRIBUTE_NORMAL;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross ap->sa_allocsz = 0x1000LL;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (0);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross}
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossint
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb_opipe_getname(smb_ofile_t *of, char *buf, size_t buflen)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross{
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_opipe_t *opipe;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((opipe = of->f_pipe) == NULL)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (EINVAL);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross (void) snprintf(buf, buflen, "\\%s", opipe->p_name);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (0);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross}
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross/*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Handler for smb2_ioctl
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross/* ARGSUSED */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossuint32_t
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb_opipe_fsctl(smb_request_t *sr, smb_fsctl_t *fsctl)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross{
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t status;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross switch (fsctl->CtlCode) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case FSCTL_PIPE_TRANSCEIVE:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = smb_opipe_transceive(sr, fsctl);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case FSCTL_PIPE_PEEK:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case FSCTL_PIPE_WAIT:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* XXX todo */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_NOT_SUPPORTED;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross default:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross ASSERT(!"CtlCode");
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_INTERNAL_ERROR;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (status);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross}
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic uint32_t
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb_opipe_transceive(smb_request_t *sr, smb_fsctl_t *fsctl)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross{
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_vdb_t vdb;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_ofile_t *ofile;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross struct mbuf *mb;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t status;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross int len, rc;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
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 */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross ofile = sr->fid_ofile;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (ofile->f_ftype != SMB_FTYPE_MESG_PIPE)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (NT_STATUS_INVALID_HANDLE);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_mbc_decodef(fsctl->in_mbc, "#B",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross fsctl->InputCount, &vdb);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc != 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* Not enough data sent. */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (NT_STATUS_INVALID_PARAMETER);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_opipe_write(sr, &vdb.vdb_uio);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc != 0)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (smb_errno2status(rc));
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross vdb.vdb_tag = 0;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross vdb.vdb_uio.uio_iov = &vdb.vdb_iovec[0];
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross vdb.vdb_uio.uio_iovcnt = MAX_IOVEC;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross vdb.vdb_uio.uio_segflg = UIO_SYSSPACE;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross vdb.vdb_uio.uio_extflg = UIO_COPY_DEFAULT;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross vdb.vdb_uio.uio_loffset = (offset_t)0;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross vdb.vdb_uio.uio_resid = fsctl->MaxOutputResp;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross mb = smb_mbuf_allocate(&vdb.vdb_uio);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_opipe_read(sr, &vdb.vdb_uio);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc != 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross m_freem(mb);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (smb_errno2status(rc));
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross len = fsctl->MaxOutputResp - vdb.vdb_uio.uio_resid;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_mbuf_trim(mb, len);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross MBC_ATTACH_MBUF(fsctl->out_mbc, mb);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
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 */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_SUCCESS;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (fsctl->MaxOutputResp < SMB_PIPE_MAX_MSGSIZE &&
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross vdb.vdb_uio.uio_resid == 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross int nread = 0, trval;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_opipe_ioctl(sr, FIONREAD, &nread, &trval);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc == 0 && nread != 0)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_BUFFER_OVERFLOW;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (status);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross}