da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Client NDR RPC interface.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright#include <sys/types.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <sys/errno.h>
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross#include <sys/fcntl.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <sys/tzfile.h>
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright#include <time.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <strings.h>
8d7e41661dc4633488e93b13363137523ce59977jose borrego#include <assert.h>
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross#include <errno.h>
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright#include <thread.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <unistd.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <syslog.h>
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright#include <synch.h>
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross#include <netsmb/smbfs_api.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/libsmb.h>
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross#include <smbsrv/libsmbns.h>
8d7e41661dc4633488e93b13363137523ce59977jose borrego#include <smbsrv/libmlrpc.h>
8d7e41661dc4633488e93b13363137523ce59977jose borrego#include <smbsrv/libmlsvc.h>
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier#include <smbsrv/ndl/srvsvc.ndl>
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross#include <libsmbrdr.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <mlsvc.h>
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borregostatic int ndr_xa_init(ndr_client_t *, ndr_xa_t *);
8d7e41661dc4633488e93b13363137523ce59977jose borregostatic int ndr_xa_exchange(ndr_client_t *, ndr_xa_t *);
8d7e41661dc4633488e93b13363137523ce59977jose borregostatic int ndr_xa_read(ndr_client_t *, ndr_xa_t *);
8d7e41661dc4633488e93b13363137523ce59977jose borregostatic void ndr_xa_preserve(ndr_client_t *, ndr_xa_t *);
8d7e41661dc4633488e93b13363137523ce59977jose borregostatic void ndr_xa_destruct(ndr_client_t *, ndr_xa_t *);
8d7e41661dc4633488e93b13363137523ce59977jose borregostatic void ndr_xa_release(ndr_client_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * This call must be made to initialize an RPC client structure and bind
8d7e41661dc4633488e93b13363137523ce59977jose borrego * to the remote service before any RPCs can be exchanged with that service.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
8d7e41661dc4633488e93b13363137523ce59977jose borrego * The mlsvc_handle_t is a wrapper that is used to associate an RPC handle
8d7e41661dc4633488e93b13363137523ce59977jose borrego * with the client context for an instance of the interface. The handle
8d7e41661dc4633488e93b13363137523ce59977jose borrego * is zeroed to ensure that it doesn't look like a valid handle -
8d7e41661dc4633488e93b13363137523ce59977jose borrego * handle content is provided by the remove service.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
8d7e41661dc4633488e93b13363137523ce59977jose borrego * The client points to this top-level handle so that we know when to
8d7e41661dc4633488e93b13363137523ce59977jose borrego * unbind and teardown the connection. As each handle is initialized it
8d7e41661dc4633488e93b13363137523ce59977jose borrego * will inherit a reference to the client context.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross *
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * Returns 0 or an NT_STATUS:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * NT_STATUS_BAD_NETWORK_PATH (get server addr)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * NT_STATUS_NETWORK_ACCESS_DENIED (connect, auth)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * NT_STATUS_BAD_NETWORK_NAME (tcon, open)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * NT_STATUS_ACCESS_DENIED (open pipe)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * NT_STATUS_INVALID_PARAMETER (rpc bind)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross *
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * NT_STATUS_INTERNAL_ERROR (bad args etc)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * NT_STATUS_NO_MEMORY
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon RossDWORD
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain,
8d7e41661dc4633488e93b13363137523ce59977jose borrego char *username, const char *service)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross struct smb_ctx *ctx = NULL;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross ndr_client_t *clnt = NULL;
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_service_t *svc;
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright srvsvc_server_info_t svinfo;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross DWORD status;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross int fd = -1;
8d7e41661dc4633488e93b13363137523ce59977jose borrego int rc;
8d7e41661dc4633488e93b13363137523ce59977jose borrego
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (handle == NULL || server == NULL || server[0] == '\0' ||
8d7e41661dc4633488e93b13363137523ce59977jose borrego domain == NULL || username == NULL)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (NT_STATUS_INTERNAL_ERROR);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /* In case the service was not registered... */
8d7e41661dc4633488e93b13363137523ce59977jose borrego if ((svc = ndr_svc_lookup_name(service)) == NULL)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (NT_STATUS_INTERNAL_ERROR);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright /*
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright * Set the default based on the assumption that most
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * servers will be Windows 2000 or later. This used to
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * try to get the actual server version, but that RPC
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * is not necessarily allowed anymore, so don't bother.
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright */
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier bzero(&svinfo, sizeof (srvsvc_server_info_t));
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier svinfo.sv_platform_id = SV_PLATFORM_ID_NT;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier svinfo.sv_version_major = 5;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier svinfo.sv_version_minor = 0;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier svinfo.sv_type = SV_TYPE_DEFAULT;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier svinfo.sv_os = NATIVE_OS_WIN2000;
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross /*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Some callers pass this when they want a NULL session.
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Todo: have callers pass an empty string for that.
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross if (strcmp(username, MLSVC_ANON_USER) == 0)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross username = "";
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross /*
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross * Setup smbfs library handle, authenticate, connect to
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross * the IPC$ share. This will reuse an existing connection
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross * if the driver already has one for this combination of
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * server, user, domain. It may return any of:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * NT_STATUS_BAD_NETWORK_PATH (get server addr)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * NT_STATUS_NETWORK_ACCESS_DENIED (connect, auth)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * NT_STATUS_BAD_NETWORK_NAME (tcon)
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross status = smbrdr_ctx_new(&ctx, server, domain, username);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (status != NT_STATUS_SUCCESS) {
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross syslog(LOG_ERR, "ndr_rpc_bind: smbrdr_ctx_new"
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross "(Srv=%s Dom=%s User=%s), %s (0x%x)",
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross server, domain, username,
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross xlate_nt_status(status), status);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /* Tell the DC Locator this DC failed. */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross smb_ddiscover_bad_dc(server);
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross goto errout;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross }
8d7e41661dc4633488e93b13363137523ce59977jose borrego
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross /*
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross * Open the named pipe.
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross */
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross fd = smb_fh_open(ctx, svc->endpoint, O_RDWR);
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross if (fd < 0) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross rc = errno;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross syslog(LOG_DEBUG, "ndr_rpc_bind: "
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "smb_fh_open (%s) err=%d",
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross svc->endpoint, rc);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross switch (rc) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross case EACCES:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross status = NT_STATUS_ACCESS_DENIED;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross break;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross default:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross status = NT_STATUS_BAD_NETWORK_NAME;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross break;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross goto errout;
8d7e41661dc4633488e93b13363137523ce59977jose borrego }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross /*
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross * Setup the RPC client handle.
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if ((clnt = malloc(sizeof (ndr_client_t))) == NULL) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross status = NT_STATUS_NO_MEMORY;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross goto errout;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
8d7e41661dc4633488e93b13363137523ce59977jose borrego bzero(clnt, sizeof (ndr_client_t));
8d7e41661dc4633488e93b13363137523ce59977jose borrego
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross clnt->handle = &handle->handle;
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->xa_init = ndr_xa_init;
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->xa_exchange = ndr_xa_exchange;
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->xa_read = ndr_xa_read;
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->xa_preserve = ndr_xa_preserve;
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->xa_destruct = ndr_xa_destruct;
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->xa_release = ndr_xa_release;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross clnt->xa_private = ctx;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross clnt->xa_fd = fd;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross ndr_svc_binding_pool_init(&clnt->binding_list,
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross clnt->binding_pool, NDR_N_BINDING_POOL);
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if ((clnt->heap = ndr_heap_create()) == NULL) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross status = NT_STATUS_NO_MEMORY;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross goto errout;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
8d7e41661dc4633488e93b13363137523ce59977jose borrego
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross /*
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross * Fill in the caller's handle.
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross */
8d7e41661dc4633488e93b13363137523ce59977jose borrego bzero(&handle->handle, sizeof (ndr_hdid_t));
8d7e41661dc4633488e93b13363137523ce59977jose borrego handle->clnt = clnt;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier bcopy(&svinfo, &handle->svinfo, sizeof (srvsvc_server_info_t));
8d7e41661dc4633488e93b13363137523ce59977jose borrego
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross /*
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross * Do the OtW RPC bind.
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross */
8d7e41661dc4633488e93b13363137523ce59977jose borrego rc = ndr_clnt_bind(clnt, service, &clnt->binding);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross switch (rc) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross case NDR_DRC_FAULT_OUT_OF_MEMORY:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross status = NT_STATUS_NO_MEMORY;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross break;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross case NDR_DRC_FAULT_API_SERVICE_INVALID: /* not registered */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross status = NT_STATUS_INTERNAL_ERROR;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross break;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross default:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (NDR_DRC_IS_FAULT(rc)) {
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross status = NT_STATUS_INVALID_PARAMETER;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross break;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross }
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /* FALLTHROUGH */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross case NDR_DRC_OK:
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (NT_STATUS_SUCCESS);
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross }
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross syslog(LOG_DEBUG, "ndr_rpc_bind: "
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross "ndr_clnt_bind, %s (0x%x)",
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross xlate_nt_status(status), status);
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Rosserrout:
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross handle->clnt = NULL;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross if (clnt != NULL) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_heap_destroy(clnt->heap);
8d7e41661dc4633488e93b13363137523ce59977jose borrego free(clnt);
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross }
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross if (ctx != NULL) {
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross if (fd != -1)
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross (void) smb_fh_close(fd);
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross smbrdr_ctx_free(ctx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Unbind and close the pipe to an RPC service.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
8d7e41661dc4633488e93b13363137523ce59977jose borrego * If the heap has been preserved we need to go through an xa release.
8d7e41661dc4633488e93b13363137523ce59977jose borrego * The heap is preserved during an RPC call because that's where data
8d7e41661dc4633488e93b13363137523ce59977jose borrego * returned from the server is stored.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Otherwise we destroy the heap directly.
8d7e41661dc4633488e93b13363137523ce59977jose borrego */
8d7e41661dc4633488e93b13363137523ce59977jose borregovoid
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_rpc_unbind(mlsvc_handle_t *handle)
8d7e41661dc4633488e93b13363137523ce59977jose borrego{
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_client_t *clnt = handle->clnt;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross struct smb_ctx *ctx = clnt->xa_private;
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (clnt->heap_preserved)
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_clnt_free_heap(clnt);
8d7e41661dc4633488e93b13363137523ce59977jose borrego else
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_heap_destroy(clnt->heap);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross (void) smb_fh_close(clnt->xa_fd);
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross smbrdr_ctx_free(ctx);
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross free(clnt);
8d7e41661dc4633488e93b13363137523ce59977jose borrego bzero(handle, sizeof (mlsvc_handle_t));
8d7e41661dc4633488e93b13363137523ce59977jose borrego}
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Call the RPC function identified by opnum. The remote service is
8d7e41661dc4633488e93b13363137523ce59977jose borrego * identified by the handle, which should have been initialized by
8d7e41661dc4633488e93b13363137523ce59977jose borrego * ndr_rpc_bind.
8d7e41661dc4633488e93b13363137523ce59977jose borrego *
8d7e41661dc4633488e93b13363137523ce59977jose borrego * If the RPC call is successful (returns 0), the caller must call
8d7e41661dc4633488e93b13363137523ce59977jose borrego * ndr_rpc_release to release the heap. Otherwise, we release the
8d7e41661dc4633488e93b13363137523ce59977jose borrego * heap here.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_rpc_call(mlsvc_handle_t *handle, int opnum, void *params)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_client_t *clnt = handle->clnt;
8d7e41661dc4633488e93b13363137523ce59977jose borrego int rc;
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (ndr_rpc_get_heap(handle) == NULL)
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego rc = ndr_clnt_call(clnt->binding, opnum, params);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier /*
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier * Always clear the nonull flag to ensure
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier * it is not applied to subsequent calls.
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier */
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier clnt->nonull = B_FALSE;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (NDR_DRC_IS_FAULT(rc)) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_rpc_release(handle);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
8d7e41661dc4633488e93b13363137523ce59977jose borrego }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier * Outgoing strings should not be null terminated.
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier */
fe1c642d06e14b412cd83ae2179303186ab08972Bill Kriervoid
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krierndr_rpc_set_nonull(mlsvc_handle_t *handle)
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier{
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier handle->clnt->nonull = B_TRUE;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier}
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier/*
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier * Return a reference to the server info.
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier */
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krierconst srvsvc_server_info_t *
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krierndr_rpc_server_info(mlsvc_handle_t *handle)
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier{
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier return (&handle->svinfo);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier}
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier/*
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier * Return the RPC server OS level.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wrightuint32_t
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_rpc_server_os(mlsvc_handle_t *handle)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier return (handle->svinfo.sv_os);
8d7e41661dc4633488e93b13363137523ce59977jose borrego}
8d7e41661dc4633488e93b13363137523ce59977jose borrego
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai/*
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * Get the session key from a bound RPC client handle.
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai *
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * The key returned is the 16-byte "user session key"
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * established by the underlying authentication protocol
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * (either Kerberos or NTLM). This key is needed for
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * SAM RPC calls such as SamrSetInformationUser, etc.
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * See [MS-SAMR] sections: 2.2.3.3, 2.2.7.21, 2.2.7.25.
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai *
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * Returns zero (success) or an errno.
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai */
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desaiint
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desaindr_rpc_get_ssnkey(mlsvc_handle_t *handle,
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai unsigned char *ssn_key, size_t len)
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai{
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai ndr_client_t *clnt = handle->clnt;
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai int rc;
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai if (clnt == NULL)
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai return (EINVAL);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross rc = smb_fh_getssnkey(clnt->xa_fd, ssn_key, len);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai return (rc);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai}
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
8d7e41661dc4633488e93b13363137523ce59977jose borregovoid *
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_rpc_malloc(mlsvc_handle_t *handle, size_t size)
8d7e41661dc4633488e93b13363137523ce59977jose borrego{
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_heap_t *heap;
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego if ((heap = ndr_rpc_get_heap(handle)) == NULL)
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (NULL);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (ndr_heap_malloc(heap, size));
8d7e41661dc4633488e93b13363137523ce59977jose borrego}
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_heap_t *
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_rpc_get_heap(mlsvc_handle_t *handle)
8d7e41661dc4633488e93b13363137523ce59977jose borrego{
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_client_t *clnt = handle->clnt;
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (clnt->heap == NULL)
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->heap = ndr_heap_create();
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (clnt->heap);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Must be called by RPC clients to free the heap after a successful RPC
8d7e41661dc4633488e93b13363137523ce59977jose borrego * call, i.e. ndr_rpc_call returned 0. The caller should take a copy
8d7e41661dc4633488e93b13363137523ce59977jose borrego * of any data returned by the RPC prior to calling this function because
8d7e41661dc4633488e93b13363137523ce59977jose borrego * returned data is in the heap.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_rpc_release(mlsvc_handle_t *handle)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_client_t *clnt = handle->clnt;
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (clnt->heap_preserved)
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_clnt_free_heap(clnt);
8d7e41661dc4633488e93b13363137523ce59977jose borrego else
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_heap_destroy(clnt->heap);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->heap = NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Returns true if the handle is null.
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Otherwise returns false.
8d7e41661dc4633488e93b13363137523ce59977jose borrego */
8d7e41661dc4633488e93b13363137523ce59977jose borregoboolean_t
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_is_null_handle(mlsvc_handle_t *handle)
8d7e41661dc4633488e93b13363137523ce59977jose borrego{
8d7e41661dc4633488e93b13363137523ce59977jose borrego static ndr_hdid_t zero_handle;
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (handle == NULL || handle->clnt == NULL)
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (B_TRUE);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (!memcmp(&handle->handle, &zero_handle, sizeof (ndr_hdid_t)))
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (B_TRUE);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (B_FALSE);
8d7e41661dc4633488e93b13363137523ce59977jose borrego}
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Returns true if the handle is the top level bind handle.
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Otherwise returns false.
8d7e41661dc4633488e93b13363137523ce59977jose borrego */
8d7e41661dc4633488e93b13363137523ce59977jose borregoboolean_t
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_is_bind_handle(mlsvc_handle_t *handle)
8d7e41661dc4633488e93b13363137523ce59977jose borrego{
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (handle->clnt->handle == &handle->handle);
8d7e41661dc4633488e93b13363137523ce59977jose borrego}
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Pass the client reference from parent to child.
8d7e41661dc4633488e93b13363137523ce59977jose borrego */
8d7e41661dc4633488e93b13363137523ce59977jose borregovoid
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_inherit_handle(mlsvc_handle_t *child, mlsvc_handle_t *parent)
8d7e41661dc4633488e93b13363137523ce59977jose borrego{
8d7e41661dc4633488e93b13363137523ce59977jose borrego child->clnt = parent->clnt;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier bcopy(&parent->svinfo, &child->svinfo, sizeof (srvsvc_server_info_t));
8d7e41661dc4633488e93b13363137523ce59977jose borrego}
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borregovoid
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_rpc_status(mlsvc_handle_t *handle, int opnum, DWORD status)
8d7e41661dc4633488e93b13363137523ce59977jose borrego{
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_service_t *svc;
8d7e41661dc4633488e93b13363137523ce59977jose borrego char *name = "NDR RPC";
8d7e41661dc4633488e93b13363137523ce59977jose borrego char *s = "unknown";
8d7e41661dc4633488e93b13363137523ce59977jose borrego
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright switch (NT_SC_SEVERITY(status)) {
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright case NT_STATUS_SEVERITY_SUCCESS:
8d7e41661dc4633488e93b13363137523ce59977jose borrego s = "success";
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright break;
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright case NT_STATUS_SEVERITY_INFORMATIONAL:
8d7e41661dc4633488e93b13363137523ce59977jose borrego s = "info";
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright break;
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright case NT_STATUS_SEVERITY_WARNING:
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright s = "warning";
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright break;
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright case NT_STATUS_SEVERITY_ERROR:
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright s = "error";
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright break;
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright }
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (handle) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego svc = handle->clnt->binding->service;
8d7e41661dc4633488e93b13363137523ce59977jose borrego name = svc->name;
8d7e41661dc4633488e93b13363137523ce59977jose borrego }
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego smb_tracef("%s[0x%02x]: %s: %s (0x%08x)",
8d7e41661dc4633488e93b13363137523ce59977jose borrego name, opnum, s, xlate_nt_status(status), status);
8d7e41661dc4633488e93b13363137523ce59977jose borrego}
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * The following functions provide the client callback interface.
8d7e41661dc4633488e93b13363137523ce59977jose borrego * If the caller hasn't provided a heap, create one here.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_xa_init(ndr_client_t *clnt, ndr_xa_t *mxa)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier ndr_stream_t *recv_nds = &mxa->recv_nds;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier ndr_stream_t *send_nds = &mxa->send_nds;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier ndr_heap_t *heap = clnt->heap;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier int rc;
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (heap == NULL) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego if ((heap = ndr_heap_create()) == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->heap = heap;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mxa->heap = heap;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier rc = nds_initialize(send_nds, 0, NDR_MODE_CALL_SEND, heap);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier if (rc == 0)
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier rc = nds_initialize(recv_nds, NDR_PDU_SIZE_HINT_DEFAULT,
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier NDR_MODE_RETURN_RECV, heap);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier if (rc != 0) {
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier nds_destruct(&mxa->recv_nds);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier nds_destruct(&mxa->send_nds);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier ndr_heap_destroy(mxa->heap);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier mxa->heap = NULL;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier clnt->heap = NULL;
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier return (-1);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier }
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier if (clnt->nonull)
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier NDS_SETF(send_nds, NDS_F_NONULL);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This is the entry pointy for an RPC client call exchange with
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * a server, which will result in an smbrdr SmbTransact request.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SmbTransact should return the number of bytes received, which
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * we record as the PDU size, or a negative error code.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_xa_exchange(ndr_client_t *clnt, ndr_xa_t *mxa)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_stream_t *recv_nds = &mxa->recv_nds;
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_stream_t *send_nds = &mxa->send_nds;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross int err, more, nbytes;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross nbytes = recv_nds->pdu_max_size;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross err = smb_fh_xactnp(clnt->xa_fd,
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross send_nds->pdu_size, (char *)send_nds->pdu_base_offset,
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross &nbytes, (char *)recv_nds->pdu_base_offset, &more);
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross if (err) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego recv_nds->pdu_size = 0;
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (-1);
8d7e41661dc4633488e93b13363137523ce59977jose borrego }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego recv_nds->pdu_size = nbytes;
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This entry point will be invoked if the xa-exchange response contained
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * only the first fragment of a multi-fragment response. The RPC client
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * code will then make repeated xa-read requests to obtain the remaining
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fragments, which will result in smbrdr SmbReadX requests.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SmbReadX should return the number of bytes received, in which case we
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * expand the PDU size to include the received data, or a negative error
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * code.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_xa_read(ndr_client_t *clnt, ndr_xa_t *mxa)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_stream_t *nds = &mxa->recv_nds;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int len;
8d7e41661dc4633488e93b13363137523ce59977jose borrego int nbytes;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego if ((len = (nds->pdu_max_size - nds->pdu_size)) < 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross nbytes = smb_fh_read(clnt->xa_fd, 0, len,
ed9aabc708901eb85fb058aacbd851c0fd958a16Gordon Ross (char *)nds->pdu_base_offset + nds->pdu_size);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (nbytes < 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego nds->pdu_size += nbytes;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (nds->pdu_size > nds->pdu_max_size) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego nds->pdu_size = nds->pdu_max_size;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (nbytes);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Preserve the heap so that the client application has access to data
8d7e41661dc4633488e93b13363137523ce59977jose borrego * returned from the server after an RPC call.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
8d7e41661dc4633488e93b13363137523ce59977jose borregostatic void
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_xa_preserve(ndr_client_t *clnt, ndr_xa_t *mxa)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
8d7e41661dc4633488e93b13363137523ce59977jose borrego assert(clnt->heap == mxa->heap);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->heap_preserved = B_TRUE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mxa->heap = NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Dispose of the transaction streams. If the heap has not been
8d7e41661dc4633488e93b13363137523ce59977jose borrego * preserved, we can destroy it here.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
8d7e41661dc4633488e93b13363137523ce59977jose borregostatic void
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_xa_destruct(ndr_client_t *clnt, ndr_xa_t *mxa)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
8d7e41661dc4633488e93b13363137523ce59977jose borrego nds_destruct(&mxa->recv_nds);
8d7e41661dc4633488e93b13363137523ce59977jose borrego nds_destruct(&mxa->send_nds);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (!clnt->heap_preserved) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_heap_destroy(mxa->heap);
8d7e41661dc4633488e93b13363137523ce59977jose borrego mxa->heap = NULL;
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->heap = NULL;
8d7e41661dc4633488e93b13363137523ce59977jose borrego }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Dispose of a preserved heap.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
8d7e41661dc4633488e93b13363137523ce59977jose borregondr_xa_release(ndr_client_t *clnt)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (clnt->heap_preserved) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_heap_destroy(clnt->heap);
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->heap = NULL;
8d7e41661dc4633488e93b13363137523ce59977jose borrego clnt->heap_preserved = B_FALSE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States/*
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * Compare the time here with the remote time on the server
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * and report clock skew.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesvoid
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesndr_srvsvc_timecheck(char *server, char *domain)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States char hostname[MAXHOSTNAMELEN];
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States struct timeval dc_tv;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States struct tm dc_tm;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States struct tm *tm;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States time_t tnow;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States time_t tdiff;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States int priority;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (srvsvc_net_remote_tod(server, domain, &dc_tv, &dc_tm) < 0) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States syslog(LOG_DEBUG, "srvsvc_net_remote_tod failed");
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States tnow = time(NULL);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (tnow > dc_tv.tv_sec)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States tdiff = (tnow - dc_tv.tv_sec) / SECSPERMIN;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States else
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States tdiff = (dc_tv.tv_sec - tnow) / SECSPERMIN;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (tdiff != 0) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States (void) strlcpy(hostname, "localhost", MAXHOSTNAMELEN);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States (void) gethostname(hostname, MAXHOSTNAMELEN);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States priority = (tdiff > 2) ? LOG_NOTICE : LOG_DEBUG;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States syslog(priority, "DC [%s] clock skew detected: %u minutes",
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States server, tdiff);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States tm = gmtime(&dc_tv.tv_sec);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States syslog(priority, "%-8s UTC: %s", server, asctime(tm));
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States tm = gmtime(&tnow);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States syslog(priority, "%-8s UTC: %s", hostname, asctime(tm));
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}