xref: /titanic_41/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c (revision cf115f3609b69ef25a8b5a1c0a4a5afa19271fa8)
189dc44ceSjose borrego /*
289dc44ceSjose borrego  * CDDL HEADER START
389dc44ceSjose borrego  *
489dc44ceSjose borrego  * The contents of this file are subject to the terms of the
589dc44ceSjose borrego  * Common Development and Distribution License (the "License").
689dc44ceSjose borrego  * You may not use this file except in compliance with the License.
789dc44ceSjose borrego  *
889dc44ceSjose borrego  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
989dc44ceSjose borrego  * or http://www.opensolaris.org/os/licensing.
1089dc44ceSjose borrego  * See the License for the specific language governing permissions
1189dc44ceSjose borrego  * and limitations under the License.
1289dc44ceSjose borrego  *
1389dc44ceSjose borrego  * When distributing Covered Code, include this CDDL HEADER in each
1489dc44ceSjose borrego  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1589dc44ceSjose borrego  * If applicable, add the following below this CDDL HEADER, with the
1689dc44ceSjose borrego  * fields enclosed by brackets "[]" replaced with your own identifying
1789dc44ceSjose borrego  * information: Portions Copyright [yyyy] [name of copyright owner]
1889dc44ceSjose borrego  *
1989dc44ceSjose borrego  * CDDL HEADER END
2089dc44ceSjose borrego  */
21148c5f43SAlan Wright 
2289dc44ceSjose borrego /*
23c5866007SKeyur Desai  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24*cf115f36SGordon Ross  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
2589dc44ceSjose borrego  */
2689dc44ceSjose borrego 
2789dc44ceSjose borrego /*
2889dc44ceSjose borrego  * Server Service RPC (SRVSVC) server-side interface definition.
2989dc44ceSjose borrego  * The server service provides a remote administration interface.
3089dc44ceSjose borrego  *
3189dc44ceSjose borrego  * This service uses NERR/Win32 error codes rather than NT status
3289dc44ceSjose borrego  * values.
3389dc44ceSjose borrego  */
3489dc44ceSjose borrego 
3589dc44ceSjose borrego #include <sys/errno.h>
36bbf6f00cSJordan Brown #include <sys/tzfile.h>
3789dc44ceSjose borrego #include <unistd.h>
3889dc44ceSjose borrego #include <netdb.h>
3989dc44ceSjose borrego #include <strings.h>
4089dc44ceSjose borrego #include <time.h>
4189dc44ceSjose borrego #include <thread.h>
4289dc44ceSjose borrego #include <ctype.h>
4389dc44ceSjose borrego #include <stdlib.h>
4489dc44ceSjose borrego #include <string.h>
4589dc44ceSjose borrego #include <sys/types.h>
4689dc44ceSjose borrego #include <sys/socket.h>
4789dc44ceSjose borrego #include <netinet/in.h>
4889dc44ceSjose borrego #include <arpa/inet.h>
4989dc44ceSjose borrego #include <libshare.h>
50e3f2c991SKeyur Desai #include <libnvpair.h>
51c5866007SKeyur Desai #include <sys/idmap.h>
52c5866007SKeyur Desai #include <pwd.h>
53c5866007SKeyur Desai #include <nss_dbdefs.h>
5489dc44ceSjose borrego #include <smbsrv/libsmb.h>
5589dc44ceSjose borrego #include <smbsrv/libmlsvc.h>
5689dc44ceSjose borrego #include <smbsrv/nmpipes.h>
57bbf6f00cSJordan Brown #include <smbsrv/smb.h>
5889dc44ceSjose borrego #include <smbsrv/netrauth.h>
5989dc44ceSjose borrego #include <smbsrv/ndl/srvsvc.ndl>
6029bd2886SAlan Wright #include "mlsvc.h"
6189dc44ceSjose borrego 
6289dc44ceSjose borrego /*
6389dc44ceSjose borrego  * Qualifier types for NetConnectEnum.
6489dc44ceSjose borrego  */
6589dc44ceSjose borrego #define	SRVSVC_CONNECT_ENUM_NULL	0
6689dc44ceSjose borrego #define	SRVSVC_CONNECT_ENUM_SHARE	1
6789dc44ceSjose borrego #define	SRVSVC_CONNECT_ENUM_WKSTN	2
6889dc44ceSjose borrego 
6989dc44ceSjose borrego #define	SMB_SRVSVC_MAXBUFLEN		(8 * 1024 * 1024)
7089dc44ceSjose borrego #define	SMB_SRVSVC_MAXPREFLEN		((uint32_t)(-1))
7189dc44ceSjose borrego 
7229bd2886SAlan Wright typedef struct srvsvc_sd {
7329bd2886SAlan Wright 	uint8_t *sd_buf;
7429bd2886SAlan Wright 	uint32_t sd_size;
7529bd2886SAlan Wright } srvsvc_sd_t;
7629bd2886SAlan Wright 
7729bd2886SAlan Wright typedef struct srvsvc_netshare_setinfo {
7829bd2886SAlan Wright 	char *nss_netname;
7929bd2886SAlan Wright 	char *nss_comment;
8029bd2886SAlan Wright 	char *nss_path;
8129bd2886SAlan Wright 	uint32_t nss_type;
8229bd2886SAlan Wright 	srvsvc_sd_t nss_sd;
8329bd2886SAlan Wright } srvsvc_netshare_setinfo_t;
8429bd2886SAlan Wright 
8529bd2886SAlan Wright typedef union srvsvc_netshare_getinfo {
8629bd2886SAlan Wright 	struct mslm_NetShareInfo_0 nsg_info0;
8729bd2886SAlan Wright 	struct mslm_NetShareInfo_1 nsg_info1;
8829bd2886SAlan Wright 	struct mslm_NetShareInfo_2 nsg_info2;
8929bd2886SAlan Wright 	struct mslm_NetShareInfo_501 nsg_info501;
9029bd2886SAlan Wright 	struct mslm_NetShareInfo_502 nsg_info502;
9129bd2886SAlan Wright 	struct mslm_NetShareInfo_503 nsg_info503;
9229bd2886SAlan Wright 	struct mslm_NetShareInfo_1004 nsg_info1004;
9329bd2886SAlan Wright 	struct mslm_NetShareInfo_1005 nsg_info1005;
9429bd2886SAlan Wright 	struct mslm_NetShareInfo_1006 nsg_info1006;
9529bd2886SAlan Wright 	struct mslm_NetShareInfo_1501 nsg_info1501;
9629bd2886SAlan Wright } srvsvc_netshare_getinfo_t;
9729bd2886SAlan Wright 
981fcced4cSJordan Brown typedef struct mslm_infonres srvsvc_infonres_t;
991fcced4cSJordan Brown typedef struct mslm_NetConnectEnum srvsvc_NetConnectEnum_t;
10089dc44ceSjose borrego 
1011fcced4cSJordan Brown static uint32_t srvsvc_netconnectenum_level0(ndr_xa_t *, smb_svcenum_t *,
1021fcced4cSJordan Brown     srvsvc_NetConnectEnum_t *);
1031fcced4cSJordan Brown static uint32_t srvsvc_netconnectenum_level1(ndr_xa_t *, smb_svcenum_t *,
1041fcced4cSJordan Brown     srvsvc_NetConnectEnum_t *);
1051fcced4cSJordan Brown static uint32_t srvsvc_netconnectenum_common(ndr_xa_t *,
1061fcced4cSJordan Brown     srvsvc_NetConnectInfo_t *, smb_netsvc_t *, smb_svcenum_t *);
10789dc44ceSjose borrego 
1081fcced4cSJordan Brown static DWORD srvsvc_NetFileEnum2(ndr_xa_t *, struct mslm_NetFileEnum *,
1091fcced4cSJordan Brown     smb_svcenum_t *se);
1101fcced4cSJordan Brown static DWORD srvsvc_NetFileEnum3(ndr_xa_t *, struct mslm_NetFileEnum *,
1111fcced4cSJordan Brown     smb_svcenum_t *se);
11289dc44ceSjose borrego 
1131fcced4cSJordan Brown static uint32_t srvsvc_NetSessionEnumCommon(ndr_xa_t *, srvsvc_infonres_t *,
1141fcced4cSJordan Brown     smb_netsvc_t *, smb_svcenum_t *);
1151fcced4cSJordan Brown 
1161fcced4cSJordan Brown static DWORD mlsvc_NetShareEnumLevel0(ndr_xa_t *, srvsvc_infonres_t *,
1171fcced4cSJordan Brown     smb_svcenum_t *, int);
1181fcced4cSJordan Brown static DWORD mlsvc_NetShareEnumLevel1(ndr_xa_t *, srvsvc_infonres_t *,
1191fcced4cSJordan Brown     smb_svcenum_t *, int);
1201fcced4cSJordan Brown static DWORD mlsvc_NetShareEnumLevel2(ndr_xa_t *, srvsvc_infonres_t *,
1211fcced4cSJordan Brown     smb_svcenum_t *, int);
1221fcced4cSJordan Brown static DWORD mlsvc_NetShareEnumLevel501(ndr_xa_t *, srvsvc_infonres_t *,
1231fcced4cSJordan Brown     smb_svcenum_t *, int);
1241fcced4cSJordan Brown static DWORD mlsvc_NetShareEnumLevel502(ndr_xa_t *, srvsvc_infonres_t *,
1251fcced4cSJordan Brown     smb_svcenum_t *, int);
1261fcced4cSJordan Brown static DWORD mlsvc_NetShareEnumCommon(ndr_xa_t *, smb_svcenum_t *,
1271fcced4cSJordan Brown     smb_share_t *, void *);
1281fcced4cSJordan Brown static boolean_t srvsvc_add_autohome(ndr_xa_t *, smb_svcenum_t *, void *);
12989dc44ceSjose borrego static char *srvsvc_share_mkpath(ndr_xa_t *, char *);
13029bd2886SAlan Wright static uint32_t srvsvc_share_getsd(ndr_xa_t *, smb_share_t *, srvsvc_sd_t *);
13189dc44ceSjose borrego 
13289dc44ceSjose borrego static int srvsvc_netconnect_qualifier(const char *);
1331fcced4cSJordan Brown static void srvsvc_estimate_limit(smb_svcenum_t *, uint32_t);
1341fcced4cSJordan Brown static uint32_t srvsvc_open_sessions(void);
1351fcced4cSJordan Brown static uint32_t srvsvc_open_connections(uint32_t, const char *);
1361fcced4cSJordan Brown static uint32_t srvsvc_open_files(void);
13789dc44ceSjose borrego 
13829bd2886SAlan Wright static uint32_t srvsvc_modify_share(smb_share_t *,
13929bd2886SAlan Wright     srvsvc_netshare_setinfo_t *);
14029bd2886SAlan Wright static uint32_t srvsvc_modify_transient_share(smb_share_t *,
14129bd2886SAlan Wright     srvsvc_netshare_setinfo_t *);
14229bd2886SAlan Wright static uint32_t srvsvc_update_share_flags(smb_share_t *, uint32_t);
143e3f2c991SKeyur Desai static uint32_t srvsvc_get_share_flags(smb_share_t *);
14429bd2886SAlan Wright 
14589dc44ceSjose borrego static uint32_t srvsvc_sa_add(char *, char *, char *);
14689dc44ceSjose borrego static uint32_t srvsvc_sa_delete(char *);
14729bd2886SAlan Wright static uint32_t srvsvc_sa_modify(smb_share_t *, srvsvc_netshare_setinfo_t *);
148e3f2c991SKeyur Desai static uint32_t srvsvc_sa_setprop(smb_share_t *, nvlist_t *);
14989dc44ceSjose borrego 
15089dc44ceSjose borrego static char empty_string[1];
15189dc44ceSjose borrego 
15289dc44ceSjose borrego static ndr_stub_table_t srvsvc_stub_table[];
15389dc44ceSjose borrego 
15489dc44ceSjose borrego static ndr_service_t srvsvc_service = {
15589dc44ceSjose borrego 	"SRVSVC",			/* name */
15689dc44ceSjose borrego 	"Server services",		/* desc */
15789dc44ceSjose borrego 	"\\srvsvc",			/* endpoint */
15889dc44ceSjose borrego 	PIPE_NTSVCS,			/* sec_addr_port */
15989dc44ceSjose borrego 	"4b324fc8-1670-01d3-1278-5a47bf6ee188", 3,	/* abstract */
16089dc44ceSjose borrego 	NDR_TRANSFER_SYNTAX_UUID,		2,	/* transfer */
16189dc44ceSjose borrego 	0,				/* no bind_instance_size */
16289dc44ceSjose borrego 	0,				/* no bind_req() */
16389dc44ceSjose borrego 	0,				/* no unbind_and_close() */
16489dc44ceSjose borrego 	0,				/* use generic_call_stub() */
16589dc44ceSjose borrego 	&TYPEINFO(srvsvc_interface),	/* interface ti */
16689dc44ceSjose borrego 	srvsvc_stub_table		/* stub_table */
16789dc44ceSjose borrego };
16889dc44ceSjose borrego 
16989dc44ceSjose borrego /*
17089dc44ceSjose borrego  * srvsvc_initialize
17189dc44ceSjose borrego  *
17289dc44ceSjose borrego  * This function registers the SRVSVC RPC interface with the RPC runtime
17389dc44ceSjose borrego  * library. It must be called in order to use either the client side
17489dc44ceSjose borrego  * or the server side functions.
17589dc44ceSjose borrego  */
17689dc44ceSjose borrego void
srvsvc_initialize(void)17789dc44ceSjose borrego srvsvc_initialize(void)
17889dc44ceSjose borrego {
17989dc44ceSjose borrego 	(void) ndr_svc_register(&srvsvc_service);
18089dc44ceSjose borrego }
18189dc44ceSjose borrego 
18289dc44ceSjose borrego /*
1839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Turn "dfsroot" property on/off for the specified
1849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * share and save it.
1859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If the requested value is the same as what is already
1879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * set then no change is required and the function returns.
1889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
1899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t
srvsvc_shr_setdfsroot(smb_share_t * si,boolean_t on)1909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States srvsvc_shr_setdfsroot(smb_share_t *si, boolean_t on)
1919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char *dfs = NULL;
1939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nvlist_t *nvl;
1949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t nerr;
1959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (on && ((si->shr_flags & SMB_SHRF_DFSROOT) == 0)) {
1979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		si->shr_flags |= SMB_SHRF_DFSROOT;
1989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dfs = "true";
1999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	} else if (!on && (si->shr_flags & SMB_SHRF_DFSROOT)) {
2009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		si->shr_flags &= ~SMB_SHRF_DFSROOT;
2019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dfs = "false";
2029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (dfs == NULL)
2059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (ERROR_SUCCESS);
2069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
2089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
2099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (nvlist_add_string(nvl, SHOPT_DFSROOT, dfs) != 0) {
2119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		nvlist_free(nvl);
2129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
2139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nerr = srvsvc_sa_setprop(si, nvl);
2169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nvlist_free(nvl);
2179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (nerr != NERR_Success)
2199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (nerr);
2209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (smb_shr_modify(si));
2229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
22589dc44ceSjose borrego  * srvsvc_s_NetConnectEnum
22689dc44ceSjose borrego  *
22789dc44ceSjose borrego  * List tree connections made to a share on this server or all tree
22889dc44ceSjose borrego  * connections established from a specific client.  Administrator,
22989dc44ceSjose borrego  * Server Operator, Print Operator or Power User group membership
23089dc44ceSjose borrego  * is required to use this interface.
23189dc44ceSjose borrego  *
23289dc44ceSjose borrego  * There are three information levels:  0, 1, and 50.  We don't support
23389dc44ceSjose borrego  * level 50, which is only used by Windows 9x clients.
23489dc44ceSjose borrego  *
23589dc44ceSjose borrego  * It seems Server Manger (srvmgr) only sends workstation as the qualifier
23689dc44ceSjose borrego  * and the Computer Management Interface on Windows 2000 doesn't request
23789dc44ceSjose borrego  * a list of connections.
23889dc44ceSjose borrego  *
23989dc44ceSjose borrego  * Return Values:
24089dc44ceSjose borrego  * ERROR_SUCCESS            Success
24189dc44ceSjose borrego  * ERROR_ACCESS_DENIED      Caller does not have access to this call.
24289dc44ceSjose borrego  * ERROR_INVALID_PARAMETER  One of the parameters is invalid.
24389dc44ceSjose borrego  * ERROR_INVALID_LEVEL      Unknown information level specified.
24489dc44ceSjose borrego  * ERROR_MORE_DATA          Partial date returned, more entries available.
24589dc44ceSjose borrego  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
24689dc44ceSjose borrego  * NERR_NetNameNotFound     The share qualifier cannot be found.
24789dc44ceSjose borrego  * NERR_BufTooSmall         The supplied buffer is too small.
24889dc44ceSjose borrego  */
24989dc44ceSjose borrego static int
srvsvc_s_NetConnectEnum(void * arg,ndr_xa_t * mxa)25089dc44ceSjose borrego srvsvc_s_NetConnectEnum(void *arg, ndr_xa_t *mxa)
25189dc44ceSjose borrego {
2521fcced4cSJordan Brown 	srvsvc_NetConnectEnum_t		*param = arg;
2531fcced4cSJordan Brown 	smb_netsvc_t			*ns;
2541fcced4cSJordan Brown 	smb_svcenum_t			se;
25589dc44ceSjose borrego 	char				*qualifier;
25689dc44ceSjose borrego 	int				qualtype;
25789dc44ceSjose borrego 	DWORD				status = ERROR_SUCCESS;
25889dc44ceSjose borrego 
25989dc44ceSjose borrego 	if (!ndr_is_poweruser(mxa)) {
2601fcced4cSJordan Brown 		status = ERROR_ACCESS_DENIED;
2611fcced4cSJordan Brown 		goto srvsvc_netconnectenum_error;
26289dc44ceSjose borrego 	}
26389dc44ceSjose borrego 
26489dc44ceSjose borrego 	qualifier = (char *)param->qualifier;
26589dc44ceSjose borrego 	qualtype = srvsvc_netconnect_qualifier(qualifier);
26689dc44ceSjose borrego 	if (qualtype == SRVSVC_CONNECT_ENUM_NULL) {
2671fcced4cSJordan Brown 		status = NERR_NetNameNotFound;
2681fcced4cSJordan Brown 		goto srvsvc_netconnectenum_error;
2691fcced4cSJordan Brown 	}
2701fcced4cSJordan Brown 
2711fcced4cSJordan Brown 	param->total_entries = srvsvc_open_connections(qualtype, qualifier);
2721fcced4cSJordan Brown 	if (param->total_entries == 0) {
2731fcced4cSJordan Brown 		bzero(param, sizeof (srvsvc_NetConnectEnum_t));
2741fcced4cSJordan Brown 		param->status = ERROR_SUCCESS;
27589dc44ceSjose borrego 		return (NDR_DRC_OK);
27689dc44ceSjose borrego 	}
27789dc44ceSjose borrego 
2781fcced4cSJordan Brown 	bzero(&se, sizeof (smb_svcenum_t));
2791fcced4cSJordan Brown 	se.se_type = SMB_SVCENUM_TYPE_TREE;
2801fcced4cSJordan Brown 	se.se_level = param->info.level;
2811fcced4cSJordan Brown 	se.se_ntotal = param->total_entries;
2821fcced4cSJordan Brown 	se.se_nlimit = se.se_ntotal;
2831fcced4cSJordan Brown 
2841fcced4cSJordan Brown 	if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN ||
2851fcced4cSJordan Brown 	    param->pref_max_len > SMB_SRVSVC_MAXBUFLEN)
2861fcced4cSJordan Brown 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
2871fcced4cSJordan Brown 	else
2881fcced4cSJordan Brown 		se.se_prefmaxlen = param->pref_max_len;
2891fcced4cSJordan Brown 
2901fcced4cSJordan Brown 	if (param->resume_handle) {
2911fcced4cSJordan Brown 		se.se_resume = *param->resume_handle;
2921fcced4cSJordan Brown 		se.se_nskip = se.se_resume;
2931fcced4cSJordan Brown 		*param->resume_handle = 0;
2941fcced4cSJordan Brown 	}
2951fcced4cSJordan Brown 
29689dc44ceSjose borrego 	switch (param->info.level) {
29789dc44ceSjose borrego 	case 0:
2981fcced4cSJordan Brown 		status = srvsvc_netconnectenum_level0(mxa, &se, param);
29989dc44ceSjose borrego 		break;
30089dc44ceSjose borrego 	case 1:
3011fcced4cSJordan Brown 		status = srvsvc_netconnectenum_level1(mxa, &se, param);
30289dc44ceSjose borrego 		break;
30389dc44ceSjose borrego 	case 50:
30489dc44ceSjose borrego 		status = ERROR_NOT_SUPPORTED;
30589dc44ceSjose borrego 		break;
30689dc44ceSjose borrego 	default:
30789dc44ceSjose borrego 		status = ERROR_INVALID_LEVEL;
30889dc44ceSjose borrego 		break;
30989dc44ceSjose borrego 	}
31089dc44ceSjose borrego 
31189dc44ceSjose borrego 	if (status != ERROR_SUCCESS)
3121fcced4cSJordan Brown 		goto srvsvc_netconnectenum_error;
31389dc44ceSjose borrego 
3141fcced4cSJordan Brown 	if ((ns = smb_kmod_enum_init(&se)) == NULL) {
3151fcced4cSJordan Brown 		status = ERROR_NOT_ENOUGH_MEMORY;
3161fcced4cSJordan Brown 		goto srvsvc_netconnectenum_error;
3171fcced4cSJordan Brown 	}
3181fcced4cSJordan Brown 
3191fcced4cSJordan Brown 	status = srvsvc_netconnectenum_common(mxa, &param->info, ns, &se);
3201fcced4cSJordan Brown 	smb_kmod_enum_fini(ns);
3211fcced4cSJordan Brown 
3221fcced4cSJordan Brown 	if (status != ERROR_SUCCESS)
3231fcced4cSJordan Brown 		goto srvsvc_netconnectenum_error;
3241fcced4cSJordan Brown 
3251fcced4cSJordan Brown 	if (param->resume_handle &&
3261fcced4cSJordan Brown 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
3271fcced4cSJordan Brown 		if (se.se_resume < param->total_entries) {
3281fcced4cSJordan Brown 			*param->resume_handle = se.se_resume;
3291fcced4cSJordan Brown 			status = ERROR_MORE_DATA;
3301fcced4cSJordan Brown 		}
3311fcced4cSJordan Brown 	}
3321fcced4cSJordan Brown 
3331fcced4cSJordan Brown 	param->status = status;
3341fcced4cSJordan Brown 	return (NDR_DRC_OK);
3351fcced4cSJordan Brown 
3361fcced4cSJordan Brown srvsvc_netconnectenum_error:
3371fcced4cSJordan Brown 	bzero(param, sizeof (srvsvc_NetConnectEnum_t));
33889dc44ceSjose borrego 	param->status = status;
33989dc44ceSjose borrego 	return (NDR_DRC_OK);
34089dc44ceSjose borrego }
34189dc44ceSjose borrego 
3421fcced4cSJordan Brown /*
3431fcced4cSJordan Brown  * Allocate memory and estimate the number of objects that can
3441fcced4cSJordan Brown  * be returned for NetConnectEnum level 0.
3451fcced4cSJordan Brown  */
3461fcced4cSJordan Brown static uint32_t
srvsvc_netconnectenum_level0(ndr_xa_t * mxa,smb_svcenum_t * se,srvsvc_NetConnectEnum_t * param)3471fcced4cSJordan Brown srvsvc_netconnectenum_level0(ndr_xa_t *mxa, smb_svcenum_t *se,
3481fcced4cSJordan Brown     srvsvc_NetConnectEnum_t *param)
34989dc44ceSjose borrego {
3501fcced4cSJordan Brown 	srvsvc_NetConnectInfo0_t	*info0;
35189dc44ceSjose borrego 	srvsvc_NetConnectInfoBuf0_t	*ci0;
35289dc44ceSjose borrego 
3531fcced4cSJordan Brown 	if ((info0 = NDR_NEW(mxa, srvsvc_NetConnectInfo0_t)) == NULL)
3541fcced4cSJordan Brown 		return (ERROR_NOT_ENOUGH_MEMORY);
3551fcced4cSJordan Brown 
3561fcced4cSJordan Brown 	bzero(info0, sizeof (srvsvc_NetConnectInfo0_t));
3571fcced4cSJordan Brown 	param->info.ru.info0 = info0;
3581fcced4cSJordan Brown 
3591fcced4cSJordan Brown 	srvsvc_estimate_limit(se, sizeof (srvsvc_NetConnectInfoBuf0_t));
3601fcced4cSJordan Brown 	if (se->se_nlimit == 0)
3611fcced4cSJordan Brown 		return (NERR_BufTooSmall);
3621fcced4cSJordan Brown 
3631fcced4cSJordan Brown 	do {
3641fcced4cSJordan Brown 		ci0 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf0_t, se->se_nlimit);
3651fcced4cSJordan Brown 		if (ci0 == NULL)
3661fcced4cSJordan Brown 			se->se_nlimit >>= 1;
3671fcced4cSJordan Brown 	} while ((se->se_nlimit > 0) && (ci0 == NULL));
3681fcced4cSJordan Brown 
36989dc44ceSjose borrego 	if (ci0 == NULL)
37089dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
37189dc44ceSjose borrego 
37289dc44ceSjose borrego 	info0->ci0 = ci0;
3731fcced4cSJordan Brown 	info0->entries_read = 0;
37489dc44ceSjose borrego 	return (ERROR_SUCCESS);
37589dc44ceSjose borrego }
37689dc44ceSjose borrego 
3771fcced4cSJordan Brown /*
3781fcced4cSJordan Brown  * Allocate memory and estimate the number of objects that can
3791fcced4cSJordan Brown  * be returned for NetConnectEnum level 1.
3801fcced4cSJordan Brown  */
3811fcced4cSJordan Brown static uint32_t
srvsvc_netconnectenum_level1(ndr_xa_t * mxa,smb_svcenum_t * se,srvsvc_NetConnectEnum_t * param)3821fcced4cSJordan Brown srvsvc_netconnectenum_level1(ndr_xa_t *mxa, smb_svcenum_t *se,
3831fcced4cSJordan Brown     srvsvc_NetConnectEnum_t *param)
38489dc44ceSjose borrego {
3851fcced4cSJordan Brown 	srvsvc_NetConnectInfo1_t	*info1;
38689dc44ceSjose borrego 	srvsvc_NetConnectInfoBuf1_t	*ci1;
38789dc44ceSjose borrego 
3881fcced4cSJordan Brown 	if ((info1 = NDR_NEW(mxa, srvsvc_NetConnectInfo1_t)) == NULL)
3891fcced4cSJordan Brown 		return (ERROR_NOT_ENOUGH_MEMORY);
3901fcced4cSJordan Brown 
3911fcced4cSJordan Brown 	bzero(info1, sizeof (srvsvc_NetConnectInfo1_t));
3921fcced4cSJordan Brown 	param->info.ru.info1 = info1;
3931fcced4cSJordan Brown 
3941fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
3951fcced4cSJordan Brown 	    sizeof (srvsvc_NetConnectInfoBuf1_t) + MAXNAMELEN);
3961fcced4cSJordan Brown 	if (se->se_nlimit == 0)
3971fcced4cSJordan Brown 		return (NERR_BufTooSmall);
3981fcced4cSJordan Brown 
3991fcced4cSJordan Brown 	do {
4001fcced4cSJordan Brown 		ci1 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf1_t, se->se_nlimit);
4011fcced4cSJordan Brown 		if (ci1 == NULL)
4021fcced4cSJordan Brown 			se->se_nlimit >>= 1;
4031fcced4cSJordan Brown 	} while ((se->se_nlimit > 0) && (ci1 == NULL));
4041fcced4cSJordan Brown 
40589dc44ceSjose borrego 	if (ci1 == NULL)
40689dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
40789dc44ceSjose borrego 
40889dc44ceSjose borrego 	info1->ci1 = ci1;
4091fcced4cSJordan Brown 	info1->entries_read = 0;
4101fcced4cSJordan Brown 	return (ERROR_SUCCESS);
4111fcced4cSJordan Brown }
4121fcced4cSJordan Brown 
4131fcced4cSJordan Brown /*
4141fcced4cSJordan Brown  * Request a list of connections from the kernel and set up
4151fcced4cSJordan Brown  * the connection information to be returned to the client.
4161fcced4cSJordan Brown  */
4171fcced4cSJordan Brown static uint32_t
srvsvc_netconnectenum_common(ndr_xa_t * mxa,srvsvc_NetConnectInfo_t * info,smb_netsvc_t * ns,smb_svcenum_t * se)4181fcced4cSJordan Brown srvsvc_netconnectenum_common(ndr_xa_t *mxa, srvsvc_NetConnectInfo_t *info,
4191fcced4cSJordan Brown     smb_netsvc_t *ns, smb_svcenum_t *se)
4201fcced4cSJordan Brown {
4211fcced4cSJordan Brown 	srvsvc_NetConnectInfo0_t	*info0;
4221fcced4cSJordan Brown 	srvsvc_NetConnectInfo1_t	*info1;
4231fcced4cSJordan Brown 	srvsvc_NetConnectInfoBuf0_t	*ci0;
4241fcced4cSJordan Brown 	srvsvc_NetConnectInfoBuf1_t	*ci1;
4251fcced4cSJordan Brown 	smb_netsvcitem_t		*item;
4261fcced4cSJordan Brown 	smb_netconnectinfo_t		*tree;
4271fcced4cSJordan Brown 
4281fcced4cSJordan Brown 	if (smb_kmod_enum(ns) != 0)
4291fcced4cSJordan Brown 		return (ERROR_INTERNAL_ERROR);
4301fcced4cSJordan Brown 
4311fcced4cSJordan Brown 	info0 = info->ru.info0;
4321fcced4cSJordan Brown 	ci0 = info0->ci0;
4331fcced4cSJordan Brown 
4341fcced4cSJordan Brown 	info1 = info->ru.info1;
4351fcced4cSJordan Brown 	ci1 = info1->ci1;
4361fcced4cSJordan Brown 
4371fcced4cSJordan Brown 	item = list_head(&ns->ns_list);
4381fcced4cSJordan Brown 	while (item != NULL) {
4391fcced4cSJordan Brown 		tree = &item->nsi_un.nsi_tree;
4401fcced4cSJordan Brown 
4411fcced4cSJordan Brown 		switch (se->se_level) {
4421fcced4cSJordan Brown 		case 0:
4431fcced4cSJordan Brown 			ci0->coni0_id = tree->ci_id;
4441fcced4cSJordan Brown 			++ci0;
4451fcced4cSJordan Brown 			++info0->entries_read;
4461fcced4cSJordan Brown 			break;
4471fcced4cSJordan Brown 		case 1:
4481fcced4cSJordan Brown 			ci1->coni1_id = tree->ci_id;
4491fcced4cSJordan Brown 			ci1->coni1_type = tree->ci_type;
4501fcced4cSJordan Brown 			ci1->coni1_num_opens = tree->ci_numopens;
4511fcced4cSJordan Brown 			ci1->coni1_num_users = tree->ci_numusers;
4521fcced4cSJordan Brown 			ci1->coni1_time = tree->ci_time;
4531fcced4cSJordan Brown 			ci1->coni1_username = (uint8_t *)
4541fcced4cSJordan Brown 			    NDR_STRDUP(mxa, tree->ci_username);
4551fcced4cSJordan Brown 			ci1->coni1_netname = (uint8_t *)
4561fcced4cSJordan Brown 			    NDR_STRDUP(mxa, tree->ci_share);
4571fcced4cSJordan Brown 			++ci1;
4581fcced4cSJordan Brown 			++info1->entries_read;
4591fcced4cSJordan Brown 			break;
4601fcced4cSJordan Brown 		default:
4611fcced4cSJordan Brown 			return (ERROR_INVALID_LEVEL);
4621fcced4cSJordan Brown 		}
4631fcced4cSJordan Brown 
4641fcced4cSJordan Brown 		++se->se_resume;
4651fcced4cSJordan Brown 		item = list_next(&ns->ns_list, item);
4661fcced4cSJordan Brown 	}
4671fcced4cSJordan Brown 
46889dc44ceSjose borrego 	return (ERROR_SUCCESS);
46989dc44ceSjose borrego }
47089dc44ceSjose borrego 
47189dc44ceSjose borrego /*
47289dc44ceSjose borrego  * srvsvc_netconnect_qualifier
47389dc44ceSjose borrego  *
47489dc44ceSjose borrego  * The qualifier is a string that specifies a share name or computer name
47589dc44ceSjose borrego  * for the connections of interest.  If it is a share name then all the
47689dc44ceSjose borrego  * connections made to that share name are listed.  If it is a computer
47789dc44ceSjose borrego  * name (it starts with two backslash characters), then NetConnectEnum
47889dc44ceSjose borrego  * lists all connections made from that computer to the specified server.
47989dc44ceSjose borrego  */
48089dc44ceSjose borrego static int
srvsvc_netconnect_qualifier(const char * qualifier)48189dc44ceSjose borrego srvsvc_netconnect_qualifier(const char *qualifier)
48289dc44ceSjose borrego {
48389dc44ceSjose borrego 	if (qualifier == NULL || *qualifier == '\0')
48489dc44ceSjose borrego 		return (SRVSVC_CONNECT_ENUM_NULL);
48589dc44ceSjose borrego 
48689dc44ceSjose borrego 	if (strlen(qualifier) > MAXHOSTNAMELEN)
48789dc44ceSjose borrego 		return (SRVSVC_CONNECT_ENUM_NULL);
48889dc44ceSjose borrego 
48989dc44ceSjose borrego 	if (qualifier[0] == '\\' && qualifier[1] == '\\') {
49089dc44ceSjose borrego 		return (SRVSVC_CONNECT_ENUM_WKSTN);
49189dc44ceSjose borrego 	} else {
49289dc44ceSjose borrego 		if (!smb_shr_exists((char *)qualifier))
49389dc44ceSjose borrego 			return (SRVSVC_CONNECT_ENUM_NULL);
49489dc44ceSjose borrego 
49589dc44ceSjose borrego 		return (SRVSVC_CONNECT_ENUM_SHARE);
49689dc44ceSjose borrego 	}
49789dc44ceSjose borrego }
49889dc44ceSjose borrego 
4991fcced4cSJordan Brown static uint32_t
srvsvc_open_sessions(void)5001fcced4cSJordan Brown srvsvc_open_sessions(void)
5011fcced4cSJordan Brown {
5021fcced4cSJordan Brown 	smb_opennum_t	opennum;
5031fcced4cSJordan Brown 
5041fcced4cSJordan Brown 	bzero(&opennum, sizeof (smb_opennum_t));
5051fcced4cSJordan Brown 	if (smb_kmod_get_open_num(&opennum) != 0)
5061fcced4cSJordan Brown 		return (0);
5071fcced4cSJordan Brown 
5081fcced4cSJordan Brown 	return (opennum.open_users);
5091fcced4cSJordan Brown }
5101fcced4cSJordan Brown 
5111fcced4cSJordan Brown static uint32_t
srvsvc_open_connections(uint32_t qualtype,const char * qualifier)5121fcced4cSJordan Brown srvsvc_open_connections(uint32_t qualtype, const char *qualifier)
5131fcced4cSJordan Brown {
5141fcced4cSJordan Brown 	smb_opennum_t	opennum;
5151fcced4cSJordan Brown 
5161fcced4cSJordan Brown 	bzero(&opennum, sizeof (smb_opennum_t));
5171fcced4cSJordan Brown 	opennum.qualtype = qualtype;
5181fcced4cSJordan Brown 	(void) strlcpy(opennum.qualifier, qualifier, MAXNAMELEN);
5191fcced4cSJordan Brown 
5201fcced4cSJordan Brown 	if (smb_kmod_get_open_num(&opennum) != 0)
5211fcced4cSJordan Brown 		return (0);
5221fcced4cSJordan Brown 
5231fcced4cSJordan Brown 	return (opennum.open_trees);
5241fcced4cSJordan Brown }
5251fcced4cSJordan Brown 
5261fcced4cSJordan Brown static uint32_t
srvsvc_open_files(void)5271fcced4cSJordan Brown srvsvc_open_files(void)
5281fcced4cSJordan Brown {
5291fcced4cSJordan Brown 	smb_opennum_t	opennum;
5301fcced4cSJordan Brown 
5311fcced4cSJordan Brown 	bzero(&opennum, sizeof (smb_opennum_t));
5321fcced4cSJordan Brown 	if (smb_kmod_get_open_num(&opennum) != 0)
5331fcced4cSJordan Brown 		return (0);
5341fcced4cSJordan Brown 
5351fcced4cSJordan Brown 	return (opennum.open_files);
5361fcced4cSJordan Brown }
5371fcced4cSJordan Brown 
53889dc44ceSjose borrego /*
53989dc44ceSjose borrego  * srvsvc_s_NetFileEnum
54089dc44ceSjose borrego  *
54189dc44ceSjose borrego  * Return information on open files or named pipes. Only members of the
54289dc44ceSjose borrego  * Administrators or Server Operators local groups are allowed to make
54389dc44ceSjose borrego  * this call. Currently, we only support Administrators.
54489dc44ceSjose borrego  *
54589dc44ceSjose borrego  * If basepath is null, all open resources are enumerated. If basepath
54689dc44ceSjose borrego  * is non-null, only resources that have basepath as a prefix should
54789dc44ceSjose borrego  * be returned.
54889dc44ceSjose borrego  *
54989dc44ceSjose borrego  * If username is specified (non-null), only files opened by username
55089dc44ceSjose borrego  * should be returned.
55189dc44ceSjose borrego  *
55289dc44ceSjose borrego  * Notes:
55389dc44ceSjose borrego  * 1. We don't validate the servername because we would have to check
55489dc44ceSjose borrego  * all primary IPs and the ROI seems unlikely to be worth it.
55589dc44ceSjose borrego  * 2. Both basepath and username are currently ignored because both
55689dc44ceSjose borrego  * Server Manger (NT 4.0) and CMI (Windows 2000) always set them to null.
55789dc44ceSjose borrego  *
55889dc44ceSjose borrego  * The level of information requested may be one of:
55989dc44ceSjose borrego  *
56089dc44ceSjose borrego  *  2   Return the file identification number.
56189dc44ceSjose borrego  *      This level is not supported on Windows Me/98/95.
56289dc44ceSjose borrego  *
56389dc44ceSjose borrego  *  3   Return information about the file.
56489dc44ceSjose borrego  *      This level is not supported on Windows Me/98/95.
56589dc44ceSjose borrego  *
56689dc44ceSjose borrego  *  50  Windows Me/98/95:  Return information about the file.
56789dc44ceSjose borrego  *
56889dc44ceSjose borrego  * Note:
56989dc44ceSjose borrego  * If pref_max_len is unlimited and resume_handle is null, the client
57089dc44ceSjose borrego  * expects to receive all data in a single call.
57189dc44ceSjose borrego  * If we are unable to do fit all data in a single response, we would
57289dc44ceSjose borrego  * normally return ERROR_MORE_DATA with a partial list.
57389dc44ceSjose borrego  *
57489dc44ceSjose borrego  * Unfortunately, when both of these conditions occur, Server Manager
57589dc44ceSjose borrego  * pops up an error box with the message "more data available" and
57689dc44ceSjose borrego  * doesn't display any of the returned data. In this case, it is
57789dc44ceSjose borrego  * probably better to return ERROR_SUCCESS with the partial list.
57889dc44ceSjose borrego  * Windows 2000 doesn't have this problem because it always sends a
57989dc44ceSjose borrego  * non-null resume_handle.
58089dc44ceSjose borrego  *
58189dc44ceSjose borrego  * Return Values:
58289dc44ceSjose borrego  * ERROR_SUCCESS            Success
58389dc44ceSjose borrego  * ERROR_ACCESS_DENIED      Caller does not have access to this call.
58489dc44ceSjose borrego  * ERROR_INVALID_PARAMETER  One of the parameters is invalid.
58589dc44ceSjose borrego  * ERROR_INVALID_LEVEL      Unknown information level specified.
58689dc44ceSjose borrego  * ERROR_MORE_DATA          Partial date returned, more entries available.
58789dc44ceSjose borrego  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
58889dc44ceSjose borrego  * NERR_BufTooSmall         The supplied buffer is too small.
58989dc44ceSjose borrego  */
59089dc44ceSjose borrego static int
srvsvc_s_NetFileEnum(void * arg,ndr_xa_t * mxa)59189dc44ceSjose borrego srvsvc_s_NetFileEnum(void *arg, ndr_xa_t *mxa)
59289dc44ceSjose borrego {
59389dc44ceSjose borrego 	struct mslm_NetFileEnum	*param = arg;
5941fcced4cSJordan Brown 	smb_svcenum_t		se;
59589dc44ceSjose borrego 	DWORD			status;
59689dc44ceSjose borrego 
59789dc44ceSjose borrego 	if (!ndr_is_admin(mxa)) {
59889dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetFileEnum));
59989dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
60089dc44ceSjose borrego 		return (NDR_DRC_OK);
60189dc44ceSjose borrego 	}
60289dc44ceSjose borrego 
6031fcced4cSJordan Brown 	if ((param->total_entries = srvsvc_open_files()) == 0) {
6041fcced4cSJordan Brown 		bzero(param, sizeof (struct mslm_NetFileEnum));
6051fcced4cSJordan Brown 		param->status = ERROR_SUCCESS;
6061fcced4cSJordan Brown 		return (NDR_DRC_OK);
6071fcced4cSJordan Brown 	}
6081fcced4cSJordan Brown 
6091fcced4cSJordan Brown 	bzero(&se, sizeof (smb_svcenum_t));
6101fcced4cSJordan Brown 	se.se_type = SMB_SVCENUM_TYPE_FILE;
6111fcced4cSJordan Brown 	se.se_level = param->info.switch_value;
6121fcced4cSJordan Brown 	se.se_ntotal = param->total_entries;
6131fcced4cSJordan Brown 	se.se_nlimit = se.se_ntotal;
6141fcced4cSJordan Brown 
6151fcced4cSJordan Brown 	if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN ||
6161fcced4cSJordan Brown 	    param->pref_max_len > SMB_SRVSVC_MAXBUFLEN)
6171fcced4cSJordan Brown 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
6181fcced4cSJordan Brown 	else
6191fcced4cSJordan Brown 		se.se_prefmaxlen = param->pref_max_len;
6201fcced4cSJordan Brown 
6211fcced4cSJordan Brown 	if (param->resume_handle) {
6221fcced4cSJordan Brown 		se.se_resume = *param->resume_handle;
6231fcced4cSJordan Brown 		se.se_nskip = se.se_resume;
6241fcced4cSJordan Brown 		*param->resume_handle = 0;
6251fcced4cSJordan Brown 	}
6261fcced4cSJordan Brown 
62789dc44ceSjose borrego 	switch (param->info.switch_value) {
62889dc44ceSjose borrego 	case 2:
6291fcced4cSJordan Brown 		status = srvsvc_NetFileEnum2(mxa, param, &se);
63089dc44ceSjose borrego 		break;
63189dc44ceSjose borrego 
63289dc44ceSjose borrego 	case 3:
6331fcced4cSJordan Brown 		status = srvsvc_NetFileEnum3(mxa, param, &se);
63489dc44ceSjose borrego 		break;
63589dc44ceSjose borrego 
63689dc44ceSjose borrego 	case 50:
63789dc44ceSjose borrego 		status = ERROR_NOT_SUPPORTED;
63889dc44ceSjose borrego 		break;
63989dc44ceSjose borrego 
64089dc44ceSjose borrego 	default:
64189dc44ceSjose borrego 		status = ERROR_INVALID_LEVEL;
64289dc44ceSjose borrego 		break;
64389dc44ceSjose borrego 	}
64489dc44ceSjose borrego 
64589dc44ceSjose borrego 	if (status != ERROR_SUCCESS) {
64689dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetFileEnum));
64789dc44ceSjose borrego 		param->status = status;
64889dc44ceSjose borrego 		return (NDR_DRC_OK);
64989dc44ceSjose borrego 	}
65089dc44ceSjose borrego 
6511fcced4cSJordan Brown 	if (param->resume_handle &&
6521fcced4cSJordan Brown 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
6531fcced4cSJordan Brown 		if (se.se_resume < param->total_entries) {
6541fcced4cSJordan Brown 			*param->resume_handle = se.se_resume;
6551fcced4cSJordan Brown 			status = ERROR_MORE_DATA;
6561fcced4cSJordan Brown 		}
6571fcced4cSJordan Brown 	}
65889dc44ceSjose borrego 
6591fcced4cSJordan Brown 	param->status = status;
66089dc44ceSjose borrego 	return (NDR_DRC_OK);
66189dc44ceSjose borrego }
66289dc44ceSjose borrego 
66389dc44ceSjose borrego /*
66489dc44ceSjose borrego  * Build level 2 file information.
66589dc44ceSjose borrego  *
6661fcced4cSJordan Brown  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
6671fcced4cSJordan Brown  * So we use the uniqid here.
6681fcced4cSJordan Brown  *
66989dc44ceSjose borrego  * On success, the caller expects that the info2, fi2 and entries_read
67089dc44ceSjose borrego  * fields have been set up.
67189dc44ceSjose borrego  */
67289dc44ceSjose borrego static DWORD
srvsvc_NetFileEnum2(ndr_xa_t * mxa,struct mslm_NetFileEnum * param,smb_svcenum_t * se)6731fcced4cSJordan Brown srvsvc_NetFileEnum2(ndr_xa_t *mxa, struct mslm_NetFileEnum *param,
6741fcced4cSJordan Brown     smb_svcenum_t *se)
67589dc44ceSjose borrego {
67689dc44ceSjose borrego 	struct mslm_NetFileInfoBuf2	*fi2;
6771fcced4cSJordan Brown 	smb_netsvc_t			*ns;
6781fcced4cSJordan Brown 	smb_netsvcitem_t		*item;
6791fcced4cSJordan Brown 	smb_netfileinfo_t		*ofile;
68089dc44ceSjose borrego 	uint32_t			entries_read = 0;
68189dc44ceSjose borrego 
68289dc44ceSjose borrego 	param->info.ru.info2 = NDR_NEW(mxa, struct mslm_NetFileInfo2);
68329bd2886SAlan Wright 	if (param->info.ru.info2 == NULL)
68489dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
68589dc44ceSjose borrego 
6861fcced4cSJordan Brown 	srvsvc_estimate_limit(se, sizeof (struct mslm_NetFileInfoBuf2));
6871fcced4cSJordan Brown 	if (se->se_nlimit == 0)
6881fcced4cSJordan Brown 		return (NERR_BufTooSmall);
6891fcced4cSJordan Brown 
6901fcced4cSJordan Brown 	do {
6911fcced4cSJordan Brown 		fi2 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf2, se->se_nlimit);
6921fcced4cSJordan Brown 		if (fi2 == NULL)
6931fcced4cSJordan Brown 			se->se_nlimit >>= 1;
6941fcced4cSJordan Brown 	} while ((se->se_nlimit > 0) && (fi2 == NULL));
6951fcced4cSJordan Brown 
69689dc44ceSjose borrego 	if (fi2 == NULL)
69789dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
69889dc44ceSjose borrego 
69989dc44ceSjose borrego 	param->info.ru.info2->fi2 = fi2;
70089dc44ceSjose borrego 
7011fcced4cSJordan Brown 	if ((ns = smb_kmod_enum_init(se)) == NULL)
7021fcced4cSJordan Brown 		return (ERROR_NOT_ENOUGH_MEMORY);
70389dc44ceSjose borrego 
7041fcced4cSJordan Brown 	if (smb_kmod_enum(ns) != 0) {
7051fcced4cSJordan Brown 		smb_kmod_enum_fini(ns);
7061fcced4cSJordan Brown 		return (ERROR_INTERNAL_ERROR);
7071fcced4cSJordan Brown 	}
7081fcced4cSJordan Brown 
7091fcced4cSJordan Brown 	item = list_head(&ns->ns_list);
7101fcced4cSJordan Brown 	while (item != NULL) {
7111fcced4cSJordan Brown 		ofile = &item->nsi_un.nsi_ofile;
7121fcced4cSJordan Brown 		fi2->fi2_id = ofile->fi_uniqid;
71389dc44ceSjose borrego 
71489dc44ceSjose borrego 		++entries_read;
71589dc44ceSjose borrego 		++fi2;
7161fcced4cSJordan Brown 		item = list_next(&ns->ns_list, item);
71789dc44ceSjose borrego 	}
71889dc44ceSjose borrego 
7191fcced4cSJordan Brown 	se->se_resume += entries_read;
72089dc44ceSjose borrego 	param->info.ru.info2->entries_read = entries_read;
7211fcced4cSJordan Brown 	smb_kmod_enum_fini(ns);
72289dc44ceSjose borrego 	return (ERROR_SUCCESS);
72389dc44ceSjose borrego }
72489dc44ceSjose borrego 
72589dc44ceSjose borrego /*
72689dc44ceSjose borrego  * Build level 3 file information.
72789dc44ceSjose borrego  *
7281fcced4cSJordan Brown  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
7291fcced4cSJordan Brown  * So we use the uniqid here.
7301fcced4cSJordan Brown  *
73189dc44ceSjose borrego  * On success, the caller expects that the info3, fi3 and entries_read
73289dc44ceSjose borrego  * fields have been set up.
73389dc44ceSjose borrego  */
73489dc44ceSjose borrego static DWORD
srvsvc_NetFileEnum3(ndr_xa_t * mxa,struct mslm_NetFileEnum * param,smb_svcenum_t * se)7351fcced4cSJordan Brown srvsvc_NetFileEnum3(ndr_xa_t *mxa, struct mslm_NetFileEnum *param,
7361fcced4cSJordan Brown     smb_svcenum_t *se)
73789dc44ceSjose borrego {
73889dc44ceSjose borrego 	struct mslm_NetFileInfoBuf3	*fi3;
7391fcced4cSJordan Brown 	smb_netsvc_t			*ns;
7401fcced4cSJordan Brown 	smb_netsvcitem_t		*item;
7411fcced4cSJordan Brown 	smb_netfileinfo_t		*ofile;
74289dc44ceSjose borrego 	uint32_t			entries_read = 0;
74389dc44ceSjose borrego 
74489dc44ceSjose borrego 	param->info.ru.info3 = NDR_NEW(mxa, struct mslm_NetFileInfo3);
74589dc44ceSjose borrego 	if (param->info.ru.info3 == NULL)
74689dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
74789dc44ceSjose borrego 
7481fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
7491fcced4cSJordan Brown 	    sizeof (struct mslm_NetFileInfoBuf3) + MAXNAMELEN);
7501fcced4cSJordan Brown 	if (se->se_nlimit == 0)
7511fcced4cSJordan Brown 		return (NERR_BufTooSmall);
7521fcced4cSJordan Brown 
7531fcced4cSJordan Brown 	do {
7541fcced4cSJordan Brown 		fi3 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf3, se->se_nlimit);
7551fcced4cSJordan Brown 		if (fi3 == NULL)
7561fcced4cSJordan Brown 			se->se_nlimit >>= 1;
7571fcced4cSJordan Brown 	} while ((se->se_nlimit > 0) && (fi3 == NULL));
7581fcced4cSJordan Brown 
75989dc44ceSjose borrego 	if (fi3 == NULL)
76089dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
76189dc44ceSjose borrego 
76289dc44ceSjose borrego 	param->info.ru.info3->fi3 = fi3;
76389dc44ceSjose borrego 
7641fcced4cSJordan Brown 	if ((ns = smb_kmod_enum_init(se)) == NULL)
7651fcced4cSJordan Brown 		return (ERROR_NOT_ENOUGH_MEMORY);
76689dc44ceSjose borrego 
7671fcced4cSJordan Brown 	if (smb_kmod_enum(ns) != 0) {
7681fcced4cSJordan Brown 		smb_kmod_enum_fini(ns);
7691fcced4cSJordan Brown 		return (ERROR_INTERNAL_ERROR);
7701fcced4cSJordan Brown 	}
7711fcced4cSJordan Brown 
7721fcced4cSJordan Brown 	item = list_head(&ns->ns_list);
7731fcced4cSJordan Brown 	while (item != NULL) {
7741fcced4cSJordan Brown 		ofile = &item->nsi_un.nsi_ofile;
7751fcced4cSJordan Brown 		fi3->fi3_id = ofile->fi_uniqid;
7761fcced4cSJordan Brown 		fi3->fi3_permissions = ofile->fi_permissions;
7771fcced4cSJordan Brown 		fi3->fi3_num_locks = ofile->fi_numlocks;
77889dc44ceSjose borrego 		fi3->fi3_pathname = (uint8_t *)
7791fcced4cSJordan Brown 		    NDR_STRDUP(mxa, ofile->fi_path);
78089dc44ceSjose borrego 		fi3->fi3_username = (uint8_t *)
7811fcced4cSJordan Brown 		    NDR_STRDUP(mxa, ofile->fi_username);
78289dc44ceSjose borrego 
78389dc44ceSjose borrego 		++entries_read;
78489dc44ceSjose borrego 		++fi3;
7851fcced4cSJordan Brown 		item = list_next(&ns->ns_list, item);
78689dc44ceSjose borrego 	}
78789dc44ceSjose borrego 
7881fcced4cSJordan Brown 	se->se_resume += entries_read;
78989dc44ceSjose borrego 	param->info.ru.info3->entries_read = entries_read;
79089dc44ceSjose borrego 	param->total_entries = entries_read;
7919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_kmod_enum_fini(ns);
79289dc44ceSjose borrego 	return (ERROR_SUCCESS);
79389dc44ceSjose borrego }
79489dc44ceSjose borrego 
79589dc44ceSjose borrego /*
79689dc44ceSjose borrego  * srvsvc_s_NetFileClose
79789dc44ceSjose borrego  *
79889dc44ceSjose borrego  * NetFileClose forces a file to close. This function can be used when
7991fcced4cSJordan Brown  * an error prevents closure by other means.  Use NetFileClose with
80089dc44ceSjose borrego  * caution because it does not flush data, cached on a client, to the
80189dc44ceSjose borrego  * file before closing the file.
80289dc44ceSjose borrego  *
8031fcced4cSJordan Brown  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
8041fcced4cSJordan Brown  * So we use the uniqid here.
8051fcced4cSJordan Brown  *
80689dc44ceSjose borrego  * Return Values
80789dc44ceSjose borrego  * ERROR_SUCCESS            Operation succeeded.
80889dc44ceSjose borrego  * ERROR_ACCESS_DENIED      Operation denied.
80989dc44ceSjose borrego  * NERR_FileIdNotFound      No open file with the specified id.
81089dc44ceSjose borrego  *
8111fcced4cSJordan Brown  * Note: MSDN suggests ERROR_FILE_NOT_FOUND for NetFileClose but network
8121fcced4cSJordan Brown  * captures using NT show NERR_FileIdNotFound, which is consistent with
8131fcced4cSJordan Brown  * the NetFileClose2 page on MSDN.
81489dc44ceSjose borrego  */
81589dc44ceSjose borrego static int
srvsvc_s_NetFileClose(void * arg,ndr_xa_t * mxa)81689dc44ceSjose borrego srvsvc_s_NetFileClose(void *arg, ndr_xa_t *mxa)
81789dc44ceSjose borrego {
8181fcced4cSJordan Brown 	static struct {
8191fcced4cSJordan Brown 		int errnum;
8201fcced4cSJordan Brown 		int nerr;
8211fcced4cSJordan Brown 	} errmap[] = {
8221fcced4cSJordan Brown 		0,	ERROR_SUCCESS,
8231fcced4cSJordan Brown 		EACCES,	ERROR_ACCESS_DENIED,
8241fcced4cSJordan Brown 		EPERM,	ERROR_ACCESS_DENIED,
8251fcced4cSJordan Brown 		EINVAL,	ERROR_INVALID_PARAMETER,
8261fcced4cSJordan Brown 		ENOMEM,	ERROR_NOT_ENOUGH_MEMORY,
8271fcced4cSJordan Brown 		ENOENT,	NERR_FileIdNotFound
8281fcced4cSJordan Brown 	};
8291fcced4cSJordan Brown 
83089dc44ceSjose borrego 	struct mslm_NetFileClose *param = arg;
8311fcced4cSJordan Brown 	int		i;
8321fcced4cSJordan Brown 	int		rc;
83389dc44ceSjose borrego 
83489dc44ceSjose borrego 	if (!ndr_is_admin(mxa)) {
83589dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
83689dc44ceSjose borrego 		return (NDR_DRC_OK);
83789dc44ceSjose borrego 	}
83889dc44ceSjose borrego 
8391fcced4cSJordan Brown 	rc = smb_kmod_file_close(param->file_id);
8401fcced4cSJordan Brown 
8411fcced4cSJordan Brown 	for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) {
8421fcced4cSJordan Brown 		if (rc == errmap[i].errnum) {
8431fcced4cSJordan Brown 			param->status = errmap[i].nerr;
8441fcced4cSJordan Brown 			return (NDR_DRC_OK);
8451fcced4cSJordan Brown 		}
8461fcced4cSJordan Brown 	}
8471fcced4cSJordan Brown 
8481fcced4cSJordan Brown 	param->status = ERROR_INTERNAL_ERROR;
84989dc44ceSjose borrego 	return (NDR_DRC_OK);
85089dc44ceSjose borrego }
85189dc44ceSjose borrego 
85289dc44ceSjose borrego /*
85389dc44ceSjose borrego  * srvsvc_s_NetShareGetInfo
85489dc44ceSjose borrego  *
85589dc44ceSjose borrego  * Returns Win32 error codes.
85689dc44ceSjose borrego  */
85789dc44ceSjose borrego static int
srvsvc_s_NetShareGetInfo(void * arg,ndr_xa_t * mxa)85889dc44ceSjose borrego srvsvc_s_NetShareGetInfo(void *arg, ndr_xa_t *mxa)
85989dc44ceSjose borrego {
86089dc44ceSjose borrego 	struct mlsm_NetShareGetInfo *param = arg;
861eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_0 *info0;
862eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_1 *info1;
863eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_2 *info2;
864eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_501 *info501;
865eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_502 *info502;
86629bd2886SAlan Wright 	struct mslm_NetShareInfo_503 *info503;
867eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_1004 *info1004;
868eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_1005 *info1005;
869eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_1006 *info1006;
87029bd2886SAlan Wright 	struct mslm_NetShareInfo_1501 *info1501;
87129bd2886SAlan Wright 	srvsvc_netshare_getinfo_t *info;
87229bd2886SAlan Wright 	uint8_t *netname;
87329bd2886SAlan Wright 	uint8_t *comment;
87489dc44ceSjose borrego 	smb_share_t si;
87529bd2886SAlan Wright 	srvsvc_sd_t sd;
87689dc44ceSjose borrego 	DWORD status;
87789dc44ceSjose borrego 
87889dc44ceSjose borrego 	status = smb_shr_get((char *)param->netname, &si);
87989dc44ceSjose borrego 	if (status != NERR_Success) {
88089dc44ceSjose borrego 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
88189dc44ceSjose borrego 		param->status = status;
88289dc44ceSjose borrego 		return (NDR_DRC_OK);
88389dc44ceSjose borrego 	}
88489dc44ceSjose borrego 
88529bd2886SAlan Wright 	netname = (uint8_t *)NDR_STRDUP(mxa, si.shr_name);
88629bd2886SAlan Wright 	comment = (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt);
88729bd2886SAlan Wright 	info = NDR_NEW(mxa, srvsvc_netshare_getinfo_t);
88829bd2886SAlan Wright 
88929bd2886SAlan Wright 	if (netname == NULL || comment == NULL || info == NULL) {
89029bd2886SAlan Wright 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
89129bd2886SAlan Wright 		param->status = ERROR_NOT_ENOUGH_MEMORY;
89229bd2886SAlan Wright 		return (NDR_DRC_OK);
89329bd2886SAlan Wright 	}
89429bd2886SAlan Wright 
89589dc44ceSjose borrego 	switch (param->level) {
89689dc44ceSjose borrego 	case 0:
89729bd2886SAlan Wright 		info0 = &info->nsg_info0;
89829bd2886SAlan Wright 		info0->shi0_netname = netname;
89989dc44ceSjose borrego 		param->result.ru.info0 = info0;
90089dc44ceSjose borrego 		break;
90189dc44ceSjose borrego 
90289dc44ceSjose borrego 	case 1:
90329bd2886SAlan Wright 		info1 = &info->nsg_info1;
90429bd2886SAlan Wright 		info1->shi1_netname = netname;
90529bd2886SAlan Wright 		info1->shi1_comment = comment;
90689dc44ceSjose borrego 		info1->shi1_type = si.shr_type;
90789dc44ceSjose borrego 		param->result.ru.info1 = info1;
90889dc44ceSjose borrego 		break;
90989dc44ceSjose borrego 
91089dc44ceSjose borrego 	case 2:
91129bd2886SAlan Wright 		info2 = &info->nsg_info2;
91229bd2886SAlan Wright 		info2->shi2_netname = netname;
91329bd2886SAlan Wright 		info2->shi2_comment = comment;
91489dc44ceSjose borrego 		info2->shi2_path =
91589dc44ceSjose borrego 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
91689dc44ceSjose borrego 		info2->shi2_passwd = 0;
91789dc44ceSjose borrego 		info2->shi2_type = si.shr_type;
91889dc44ceSjose borrego 		info2->shi2_permissions = 0;
91989dc44ceSjose borrego 		info2->shi2_max_uses = SHI_USES_UNLIMITED;
92089dc44ceSjose borrego 		info2->shi2_current_uses = 0;
92189dc44ceSjose borrego 		param->result.ru.info2 = info2;
92289dc44ceSjose borrego 		break;
92389dc44ceSjose borrego 
92429bd2886SAlan Wright 	case 501:
92529bd2886SAlan Wright 		info501 = &info->nsg_info501;
92629bd2886SAlan Wright 		info501->shi501_netname = netname;
92729bd2886SAlan Wright 		info501->shi501_comment = comment;
92829bd2886SAlan Wright 		info501->shi501_type = si.shr_type;
929e3f2c991SKeyur Desai 		info501->shi501_flags = srvsvc_get_share_flags(&si);
93029bd2886SAlan Wright 		param->result.ru.info501 = info501;
93189dc44ceSjose borrego 		break;
93229bd2886SAlan Wright 
93329bd2886SAlan Wright 	case 502:
93429bd2886SAlan Wright 		info502 = &info->nsg_info502;
93529bd2886SAlan Wright 		info502->shi502_netname = netname;
93629bd2886SAlan Wright 		info502->shi502_comment = comment;
93729bd2886SAlan Wright 		info502->shi502_path =
93829bd2886SAlan Wright 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
93929bd2886SAlan Wright 		info502->shi502_passwd = 0;
94029bd2886SAlan Wright 		info502->shi502_type = si.shr_type;
94129bd2886SAlan Wright 		info502->shi502_permissions = 0;
94229bd2886SAlan Wright 		info502->shi502_max_uses = SHI_USES_UNLIMITED;
94329bd2886SAlan Wright 		info502->shi502_current_uses = 0;
94429bd2886SAlan Wright 
94529bd2886SAlan Wright 		status = srvsvc_share_getsd(mxa, &si, &sd);
94629bd2886SAlan Wright 		if (status == ERROR_SUCCESS) {
94729bd2886SAlan Wright 			info502->shi502_reserved = sd.sd_size;
94829bd2886SAlan Wright 			info502->shi502_security_descriptor = sd.sd_buf;
94929bd2886SAlan Wright 		} else {
95029bd2886SAlan Wright 			info502->shi502_reserved = 0;
95129bd2886SAlan Wright 			info502->shi502_security_descriptor = NULL;
95289dc44ceSjose borrego 		}
95389dc44ceSjose borrego 
95429bd2886SAlan Wright 		param->result.ru.info502 = info502;
95529bd2886SAlan Wright 		break;
95629bd2886SAlan Wright 
95729bd2886SAlan Wright 	case 503:
95829bd2886SAlan Wright 		info503 = &info->nsg_info503;
95929bd2886SAlan Wright 		info503->shi503_netname = netname;
96029bd2886SAlan Wright 		info503->shi503_comment = comment;
96129bd2886SAlan Wright 		info503->shi503_path =
96229bd2886SAlan Wright 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
96329bd2886SAlan Wright 		info503->shi503_passwd = NULL;
96429bd2886SAlan Wright 		info503->shi503_type = si.shr_type;
96529bd2886SAlan Wright 		info503->shi503_permissions = 0;
96629bd2886SAlan Wright 		info503->shi503_max_uses = SHI_USES_UNLIMITED;
96729bd2886SAlan Wright 		info503->shi503_current_uses = 0;
96829bd2886SAlan Wright 		info503->shi503_servername = NULL;
96929bd2886SAlan Wright 
97029bd2886SAlan Wright 		status = srvsvc_share_getsd(mxa, &si, &sd);
97129bd2886SAlan Wright 		if (status == ERROR_SUCCESS) {
97229bd2886SAlan Wright 			info503->shi503_reserved = sd.sd_size;
97329bd2886SAlan Wright 			info503->shi503_security_descriptor = sd.sd_buf;
97429bd2886SAlan Wright 		} else {
97529bd2886SAlan Wright 			info503->shi503_reserved = 0;
97629bd2886SAlan Wright 			info503->shi503_security_descriptor = NULL;
97729bd2886SAlan Wright 		}
97829bd2886SAlan Wright 
97929bd2886SAlan Wright 		param->result.ru.info503 = info503;
98029bd2886SAlan Wright 		break;
98129bd2886SAlan Wright 
98229bd2886SAlan Wright 	case 1004:
98329bd2886SAlan Wright 		info1004 = &info->nsg_info1004;
98429bd2886SAlan Wright 		info1004->shi1004_comment = comment;
98529bd2886SAlan Wright 		param->result.ru.info1004 = info1004;
98689dc44ceSjose borrego 		break;
98789dc44ceSjose borrego 
98889dc44ceSjose borrego 	case 1005:
98929bd2886SAlan Wright 		info1005 = &info->nsg_info1005;
990e3f2c991SKeyur Desai 		info1005->shi1005_flags = srvsvc_get_share_flags(&si);
99189dc44ceSjose borrego 		param->result.ru.info1005 = info1005;
99289dc44ceSjose borrego 		break;
99389dc44ceSjose borrego 
99489dc44ceSjose borrego 	case 1006:
99529bd2886SAlan Wright 		info1006 = &info->nsg_info1006;
99689dc44ceSjose borrego 		info1006->shi1006_max_uses = SHI_USES_UNLIMITED;
99789dc44ceSjose borrego 		param->result.ru.info1006 = info1006;
99889dc44ceSjose borrego 		break;
99989dc44ceSjose borrego 
100029bd2886SAlan Wright 	case 1501:
100129bd2886SAlan Wright 		info1501 = &info->nsg_info1501;
100229bd2886SAlan Wright 
100329bd2886SAlan Wright 		status = srvsvc_share_getsd(mxa, &si, &sd);
100429bd2886SAlan Wright 		if (status == ERROR_SUCCESS) {
100529bd2886SAlan Wright 			info503->shi503_reserved = sd.sd_size;
100629bd2886SAlan Wright 			info503->shi503_security_descriptor = sd.sd_buf;
100729bd2886SAlan Wright 		} else {
100829bd2886SAlan Wright 			info503->shi503_reserved = 0;
100929bd2886SAlan Wright 			info503->shi503_security_descriptor = NULL;
101089dc44ceSjose borrego 		}
101189dc44ceSjose borrego 
101229bd2886SAlan Wright 		param->result.ru.info1501 = info1501;
101389dc44ceSjose borrego 		break;
101489dc44ceSjose borrego 
101589dc44ceSjose borrego 	default:
101689dc44ceSjose borrego 		status = ERROR_ACCESS_DENIED;
101789dc44ceSjose borrego 		break;
101889dc44ceSjose borrego 	}
101989dc44ceSjose borrego 
102089dc44ceSjose borrego 	if (status != ERROR_SUCCESS)
102189dc44ceSjose borrego 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
102289dc44ceSjose borrego 	else
102389dc44ceSjose borrego 		param->result.switch_value = param->level;
102489dc44ceSjose borrego 
102589dc44ceSjose borrego 	param->status = status;
102689dc44ceSjose borrego 	return (NDR_DRC_OK);
102789dc44ceSjose borrego }
102889dc44ceSjose borrego 
102929bd2886SAlan Wright static uint32_t
srvsvc_share_getsd(ndr_xa_t * mxa,smb_share_t * si,srvsvc_sd_t * sd)103029bd2886SAlan Wright srvsvc_share_getsd(ndr_xa_t *mxa, smb_share_t *si, srvsvc_sd_t *sd)
103129bd2886SAlan Wright {
103229bd2886SAlan Wright 	uint32_t status;
103329bd2886SAlan Wright 
103429bd2886SAlan Wright 	status = srvsvc_sd_get(si, NULL, &sd->sd_size);
103529bd2886SAlan Wright 	if (status != ERROR_SUCCESS) {
103629bd2886SAlan Wright 		if (status == ERROR_PATH_NOT_FOUND) {
103729bd2886SAlan Wright 			bzero(sd, sizeof (srvsvc_sd_t));
103829bd2886SAlan Wright 			status = ERROR_SUCCESS;
103929bd2886SAlan Wright 		}
104029bd2886SAlan Wright 
104129bd2886SAlan Wright 		return (status);
104229bd2886SAlan Wright 	}
104329bd2886SAlan Wright 
104429bd2886SAlan Wright 	if ((sd->sd_buf = NDR_MALLOC(mxa, sd->sd_size)) == NULL)
104529bd2886SAlan Wright 		return (ERROR_NOT_ENOUGH_MEMORY);
104629bd2886SAlan Wright 
104729bd2886SAlan Wright 	status = srvsvc_sd_get(si, sd->sd_buf, NULL);
104829bd2886SAlan Wright 	if (status == ERROR_PATH_NOT_FOUND) {
104929bd2886SAlan Wright 		bzero(sd, sizeof (srvsvc_sd_t));
105029bd2886SAlan Wright 		status = ERROR_SUCCESS;
105129bd2886SAlan Wright 	}
105229bd2886SAlan Wright 
105329bd2886SAlan Wright 	return (status);
105429bd2886SAlan Wright }
105589dc44ceSjose borrego 
105689dc44ceSjose borrego /*
105789dc44ceSjose borrego  * srvsvc_s_NetShareSetInfo
105889dc44ceSjose borrego  *
105989dc44ceSjose borrego  * This call is made by SrvMgr to set share information.
106029bd2886SAlan Wright  * Only power users groups can manage shares.
106129bd2886SAlan Wright  *
106229bd2886SAlan Wright  * To avoid misleading errors, we don't report an error
106329bd2886SAlan Wright  * when a FS doesn't support ACLs on shares.
106489dc44ceSjose borrego  *
106589dc44ceSjose borrego  * Returns Win32 error codes.
106689dc44ceSjose borrego  */
106789dc44ceSjose borrego static int
srvsvc_s_NetShareSetInfo(void * arg,ndr_xa_t * mxa)106889dc44ceSjose borrego srvsvc_s_NetShareSetInfo(void *arg, ndr_xa_t *mxa)
106989dc44ceSjose borrego {
107089dc44ceSjose borrego 	struct mlsm_NetShareSetInfo *param = arg;
107129bd2886SAlan Wright 	struct mslm_NetShareInfo_0 *info0;
107229bd2886SAlan Wright 	struct mslm_NetShareInfo_1 *info1;
107329bd2886SAlan Wright 	struct mslm_NetShareInfo_2 *info2;
107429bd2886SAlan Wright 	struct mslm_NetShareInfo_501 *info501;
107529bd2886SAlan Wright 	struct mslm_NetShareInfo_502 *info502;
107629bd2886SAlan Wright 	struct mslm_NetShareInfo_503 *info503;
107729bd2886SAlan Wright 	struct mslm_NetShareInfo_1004 *info1004;
107829bd2886SAlan Wright 	struct mslm_NetShareInfo_1005 *info1005;
107929bd2886SAlan Wright 	struct mslm_NetShareInfo_1501 *info1501;
108029bd2886SAlan Wright 	static DWORD parm_err = 0;
108129bd2886SAlan Wright 	srvsvc_netshare_setinfo_t info;
108229bd2886SAlan Wright 	smb_share_t si;
108329bd2886SAlan Wright 	uint8_t *sdbuf;
108429bd2886SAlan Wright 	int32_t native_os;
108529bd2886SAlan Wright 	DWORD status;
108689dc44ceSjose borrego 
108729bd2886SAlan Wright 	native_os = ndr_native_os(mxa);
108889dc44ceSjose borrego 
108929bd2886SAlan Wright 	if (!ndr_is_poweruser(mxa)) {
109029bd2886SAlan Wright 		status = ERROR_ACCESS_DENIED;
109129bd2886SAlan Wright 		goto netsharesetinfo_exit;
109229bd2886SAlan Wright 	}
109389dc44ceSjose borrego 
109429bd2886SAlan Wright 	if (smb_shr_get((char *)param->netname, &si) != NERR_Success) {
109529bd2886SAlan Wright 		status = ERROR_INVALID_NETNAME;
109629bd2886SAlan Wright 		goto netsharesetinfo_exit;
109729bd2886SAlan Wright 	}
109829bd2886SAlan Wright 
109929bd2886SAlan Wright 	if (param->result.ru.nullptr == NULL) {
110029bd2886SAlan Wright 		status = ERROR_INVALID_PARAMETER;
110129bd2886SAlan Wright 		goto netsharesetinfo_exit;
110229bd2886SAlan Wright 	}
110329bd2886SAlan Wright 
110429bd2886SAlan Wright 	bzero(&info, sizeof (srvsvc_netshare_setinfo_t));
110529bd2886SAlan Wright 
110629bd2886SAlan Wright 	switch (param->level) {
110729bd2886SAlan Wright 	case 0:
110829bd2886SAlan Wright 		info0 = (struct mslm_NetShareInfo_0 *)param->result.ru.info0;
110929bd2886SAlan Wright 		info.nss_netname = (char *)info0->shi0_netname;
111029bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
111129bd2886SAlan Wright 		break;
111229bd2886SAlan Wright 
111329bd2886SAlan Wright 	case 1:
111429bd2886SAlan Wright 		info1 = (struct mslm_NetShareInfo_1 *)param->result.ru.info1;
111529bd2886SAlan Wright 		info.nss_netname = (char *)info1->shi1_netname;
111629bd2886SAlan Wright 		info.nss_comment = (char *)info1->shi1_comment;
111729bd2886SAlan Wright 		info.nss_type = info1->shi1_type;
111829bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
111929bd2886SAlan Wright 		break;
112029bd2886SAlan Wright 
112129bd2886SAlan Wright 	case 2:
112229bd2886SAlan Wright 		info2 = (struct mslm_NetShareInfo_2 *)param->result.ru.info2;
112329bd2886SAlan Wright 		info.nss_netname = (char *)info2->shi2_netname;
112429bd2886SAlan Wright 		info.nss_comment = (char *)info2->shi2_comment;
112529bd2886SAlan Wright 		info.nss_path = (char *)info2->shi2_path;
112629bd2886SAlan Wright 		info.nss_type = info2->shi2_type;
112729bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
112829bd2886SAlan Wright 		break;
112929bd2886SAlan Wright 
113029bd2886SAlan Wright 	case 501:
113129bd2886SAlan Wright 		info501 = (struct mslm_NetShareInfo_501 *)
113229bd2886SAlan Wright 		    param->result.ru.info501;
113329bd2886SAlan Wright 		info.nss_netname = (char *)info501->shi501_netname;
113429bd2886SAlan Wright 		info.nss_comment = (char *)info501->shi501_comment;
113529bd2886SAlan Wright 		info.nss_type = info501->shi501_type;
113629bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
1137e3f2c991SKeyur Desai 		if (status == ERROR_SUCCESS)
1138e3f2c991SKeyur Desai 			status = srvsvc_update_share_flags(&si,
1139e3f2c991SKeyur Desai 			    info501->shi501_flags);
114029bd2886SAlan Wright 		break;
114129bd2886SAlan Wright 
114229bd2886SAlan Wright 	case 502:
114329bd2886SAlan Wright 		info502 = (struct mslm_NetShareInfo_502 *)
114429bd2886SAlan Wright 		    param->result.ru.info502;
114529bd2886SAlan Wright 		info.nss_netname = (char *)info502->shi502_netname;
114629bd2886SAlan Wright 		info.nss_comment = (char *)info502->shi502_comment;
114729bd2886SAlan Wright 		info.nss_path = (char *)info502->shi502_path;
114829bd2886SAlan Wright 		info.nss_type = info502->shi502_type;
114929bd2886SAlan Wright 		info.nss_sd.sd_buf = info502->shi502_security_descriptor;
115029bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
115129bd2886SAlan Wright 		break;
115229bd2886SAlan Wright 
115329bd2886SAlan Wright 	case 503:
115429bd2886SAlan Wright 		info503 = (struct mslm_NetShareInfo_503 *)
115529bd2886SAlan Wright 		    param->result.ru.info503;
115629bd2886SAlan Wright 		info.nss_netname = (char *)info503->shi503_netname;
115729bd2886SAlan Wright 		info.nss_comment = (char *)info503->shi503_comment;
115829bd2886SAlan Wright 		info.nss_path = (char *)info503->shi503_path;
115929bd2886SAlan Wright 		info.nss_type = info503->shi503_type;
116029bd2886SAlan Wright 		info.nss_sd.sd_buf = info503->shi503_security_descriptor;
116129bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
116229bd2886SAlan Wright 		break;
116329bd2886SAlan Wright 
116429bd2886SAlan Wright 	case 1004:
116529bd2886SAlan Wright 		info1004 = (struct mslm_NetShareInfo_1004 *)
116629bd2886SAlan Wright 		    param->result.ru.info1004;
116729bd2886SAlan Wright 		info.nss_comment = (char *)info1004->shi1004_comment;
116829bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
116929bd2886SAlan Wright 		break;
117029bd2886SAlan Wright 
117129bd2886SAlan Wright 	case 1005:
117229bd2886SAlan Wright 		info1005 = (struct mslm_NetShareInfo_1005 *)
117329bd2886SAlan Wright 		    param->result.ru.info1005;
117429bd2886SAlan Wright 		status = srvsvc_update_share_flags(&si,
117529bd2886SAlan Wright 		    info1005->shi1005_flags);
117629bd2886SAlan Wright 		break;
117729bd2886SAlan Wright 
117829bd2886SAlan Wright 	case 1006:
117929bd2886SAlan Wright 		/*
118029bd2886SAlan Wright 		 * We don't limit the maximum number of concurrent
118129bd2886SAlan Wright 		 * connections to a share.
118229bd2886SAlan Wright 		 */
118329bd2886SAlan Wright 		status = ERROR_SUCCESS;
118429bd2886SAlan Wright 		break;
118529bd2886SAlan Wright 
118629bd2886SAlan Wright 	case 1501:
118729bd2886SAlan Wright 		info1501 = (struct mslm_NetShareInfo_1501 *)
118829bd2886SAlan Wright 		    param->result.ru.info1501;
118929bd2886SAlan Wright 		sdbuf = info1501->shi1501_security_descriptor;
119029bd2886SAlan Wright 		status = ERROR_SUCCESS;
119129bd2886SAlan Wright 
119229bd2886SAlan Wright 		if (sdbuf != NULL) {
119329bd2886SAlan Wright 			status = srvsvc_sd_set(&si, sdbuf);
119429bd2886SAlan Wright 			if (status == ERROR_PATH_NOT_FOUND)
119529bd2886SAlan Wright 				status = ERROR_SUCCESS;
119629bd2886SAlan Wright 		}
119729bd2886SAlan Wright 		break;
119829bd2886SAlan Wright 
119929bd2886SAlan Wright 	default:
120029bd2886SAlan Wright 		status = ERROR_ACCESS_DENIED;
120129bd2886SAlan Wright 		break;
120229bd2886SAlan Wright 	}
120329bd2886SAlan Wright 
120429bd2886SAlan Wright netsharesetinfo_exit:
120529bd2886SAlan Wright 	if (status != ERROR_SUCCESS)
120629bd2886SAlan Wright 		bzero(param, sizeof (struct mlsm_NetShareSetInfo));
120729bd2886SAlan Wright 
120829bd2886SAlan Wright 	param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
120929bd2886SAlan Wright 	param->status = status;
121089dc44ceSjose borrego 	return (NDR_DRC_OK);
121189dc44ceSjose borrego }
121289dc44ceSjose borrego 
121329bd2886SAlan Wright static uint32_t
srvsvc_modify_share(smb_share_t * si,srvsvc_netshare_setinfo_t * info)121429bd2886SAlan Wright srvsvc_modify_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
121529bd2886SAlan Wright {
121629bd2886SAlan Wright 	uint32_t nerr = NERR_Success;
121729bd2886SAlan Wright 
121829bd2886SAlan Wright 	if (si->shr_flags & SMB_SHRF_TRANS)
121929bd2886SAlan Wright 		return (srvsvc_modify_transient_share(si, info));
122029bd2886SAlan Wright 
122129bd2886SAlan Wright 	if (info->nss_sd.sd_buf != NULL) {
122229bd2886SAlan Wright 		nerr = srvsvc_sd_set(si, info->nss_sd.sd_buf);
122329bd2886SAlan Wright 		if (nerr == ERROR_PATH_NOT_FOUND)
122429bd2886SAlan Wright 			nerr = NERR_Success;
122529bd2886SAlan Wright 	}
122629bd2886SAlan Wright 
122729bd2886SAlan Wright 	if ((nerr = srvsvc_sa_modify(si, info)) == NERR_Success)
122829bd2886SAlan Wright 		nerr = smb_shr_modify(si);
122929bd2886SAlan Wright 
123029bd2886SAlan Wright 	return (nerr);
123129bd2886SAlan Wright }
123229bd2886SAlan Wright 
123329bd2886SAlan Wright /*
123429bd2886SAlan Wright  * Update transient shares.  This includes autohome shares.
123529bd2886SAlan Wright  */
123629bd2886SAlan Wright static uint32_t
srvsvc_modify_transient_share(smb_share_t * si,srvsvc_netshare_setinfo_t * info)123729bd2886SAlan Wright srvsvc_modify_transient_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
123829bd2886SAlan Wright {
123929bd2886SAlan Wright 	uint32_t nerr;
124029bd2886SAlan Wright 
124129bd2886SAlan Wright 	if (info->nss_netname != NULL && info->nss_netname[0] != '\0' &&
1242bbf6f00cSJordan Brown 	    smb_strcasecmp(info->nss_netname, si->shr_name, 0) != 0) {
124329bd2886SAlan Wright 		nerr = smb_shr_rename(si->shr_name, info->nss_netname);
124429bd2886SAlan Wright 		if (nerr != NERR_Success)
124529bd2886SAlan Wright 			return (nerr);
124629bd2886SAlan Wright 
124729bd2886SAlan Wright 		(void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN);
124829bd2886SAlan Wright 	}
124929bd2886SAlan Wright 
125029bd2886SAlan Wright 	if ((info->nss_comment != NULL) &&
125129bd2886SAlan Wright 	    (strcmp(info->nss_comment, si->shr_cmnt) != 0)) {
125229bd2886SAlan Wright 		(void) strlcpy(si->shr_cmnt, info->nss_comment,
125329bd2886SAlan Wright 		    SMB_SHARE_CMNT_MAX);
125429bd2886SAlan Wright 
125529bd2886SAlan Wright 		if ((nerr = smb_shr_modify(si)) != NERR_Success)
125629bd2886SAlan Wright 			return (nerr);
125729bd2886SAlan Wright 	}
125829bd2886SAlan Wright 
125929bd2886SAlan Wright 	return (NERR_Success);
126029bd2886SAlan Wright }
126129bd2886SAlan Wright 
1262e3f2c991SKeyur Desai /*
1263e3f2c991SKeyur Desai  * srvsvc_update_share_flags
1264e3f2c991SKeyur Desai  *
1265e3f2c991SKeyur Desai  * This function updates flags for shares.
1266e3f2c991SKeyur Desai  * Flags for Persistent shares are updated in both libshare and the local cache.
1267e3f2c991SKeyur Desai  * Flags for Transient shares are updated only in the local cache.
1268e3f2c991SKeyur Desai  */
126929bd2886SAlan Wright static uint32_t
srvsvc_update_share_flags(smb_share_t * si,uint32_t shi_flags)127029bd2886SAlan Wright srvsvc_update_share_flags(smb_share_t *si, uint32_t shi_flags)
127129bd2886SAlan Wright {
127229bd2886SAlan Wright 	uint32_t nerr = NERR_Success;
1273e3f2c991SKeyur Desai 	uint32_t flag = 0;
1274e3f2c991SKeyur Desai 	char *csc_value;
1275e3f2c991SKeyur Desai 	char *abe_value = "false";
1276e3f2c991SKeyur Desai 	nvlist_t *nvl;
1277e3f2c991SKeyur Desai 	int err = 0;
1278e3f2c991SKeyur Desai 
1279e3f2c991SKeyur Desai 	if (shi_flags & SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM) {
1280e3f2c991SKeyur Desai 		flag = SMB_SHRF_ABE;
1281e3f2c991SKeyur Desai 		abe_value = "true";
1282e3f2c991SKeyur Desai 	}
1283e3f2c991SKeyur Desai 
1284e3f2c991SKeyur Desai 	si->shr_flags &= ~SMB_SHRF_ABE;
1285e3f2c991SKeyur Desai 	si->shr_flags |= flag;
128629bd2886SAlan Wright 
128729bd2886SAlan Wright 	switch ((shi_flags & CSC_MASK)) {
128829bd2886SAlan Wright 	case CSC_CACHE_AUTO_REINT:
1289e3f2c991SKeyur Desai 		flag = SMB_SHRF_CSC_AUTO;
129029bd2886SAlan Wright 		break;
129129bd2886SAlan Wright 	case CSC_CACHE_VDO:
1292e3f2c991SKeyur Desai 		flag = SMB_SHRF_CSC_VDO;
129329bd2886SAlan Wright 		break;
129429bd2886SAlan Wright 	case CSC_CACHE_NONE:
1295e3f2c991SKeyur Desai 		flag = SMB_SHRF_CSC_DISABLED;
129629bd2886SAlan Wright 		break;
129729bd2886SAlan Wright 	case CSC_CACHE_MANUAL_REINT:
1298e3f2c991SKeyur Desai 		flag = SMB_SHRF_CSC_MANUAL;
129929bd2886SAlan Wright 		break;
130029bd2886SAlan Wright 	default:
1301e3f2c991SKeyur Desai 		return (NERR_InternalError);
130229bd2886SAlan Wright 	}
130329bd2886SAlan Wright 
130429bd2886SAlan Wright 	si->shr_flags &= ~SMB_SHRF_CSC_MASK;
1305e3f2c991SKeyur Desai 	si->shr_flags |= flag;
130629bd2886SAlan Wright 
130729bd2886SAlan Wright 	if ((si->shr_flags & SMB_SHRF_TRANS) == 0) {
1308e3f2c991SKeyur Desai 		csc_value = smb_shr_sa_csc_name(si);
1309e3f2c991SKeyur Desai 
1310e3f2c991SKeyur Desai 		if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
1311e3f2c991SKeyur Desai 			return (NERR_InternalError);
1312e3f2c991SKeyur Desai 
1313e3f2c991SKeyur Desai 		err |= nvlist_add_string(nvl, SHOPT_CSC, csc_value);
1314e3f2c991SKeyur Desai 		err |= nvlist_add_string(nvl, SHOPT_ABE, abe_value);
1315e3f2c991SKeyur Desai 		if (err) {
1316e3f2c991SKeyur Desai 			nvlist_free(nvl);
1317e3f2c991SKeyur Desai 			return (NERR_InternalError);
1318e3f2c991SKeyur Desai 		}
1319e3f2c991SKeyur Desai 
1320e3f2c991SKeyur Desai 		nerr = srvsvc_sa_setprop(si, nvl);
1321e3f2c991SKeyur Desai 		nvlist_free(nvl);
1322e3f2c991SKeyur Desai 
1323e3f2c991SKeyur Desai 		if (nerr != NERR_Success)
132429bd2886SAlan Wright 			return (nerr);
132529bd2886SAlan Wright 	}
132629bd2886SAlan Wright 
132729bd2886SAlan Wright 	return (smb_shr_modify(si));
132829bd2886SAlan Wright }
132929bd2886SAlan Wright 
1330e3f2c991SKeyur Desai static uint32_t
srvsvc_get_share_flags(smb_share_t * si)1331e3f2c991SKeyur Desai srvsvc_get_share_flags(smb_share_t *si)
1332e3f2c991SKeyur Desai {
1333e3f2c991SKeyur Desai 	uint32_t flags = 0;
1334cb174861Sjoyce mcintosh 	boolean_t shortnames = B_TRUE;
1335e3f2c991SKeyur Desai 
1336e3f2c991SKeyur Desai 	switch (si->shr_flags & SMB_SHRF_CSC_MASK) {
1337e3f2c991SKeyur Desai 	case SMB_SHRF_CSC_DISABLED:
1338e3f2c991SKeyur Desai 		flags |= CSC_CACHE_NONE;
1339e3f2c991SKeyur Desai 		break;
1340e3f2c991SKeyur Desai 	case SMB_SHRF_CSC_AUTO:
1341e3f2c991SKeyur Desai 		flags |= CSC_CACHE_AUTO_REINT;
1342e3f2c991SKeyur Desai 		break;
1343e3f2c991SKeyur Desai 	case SMB_SHRF_CSC_VDO:
1344e3f2c991SKeyur Desai 		flags |= CSC_CACHE_VDO;
1345e3f2c991SKeyur Desai 		break;
1346e3f2c991SKeyur Desai 	case SMB_SHRF_CSC_MANUAL:
1347e3f2c991SKeyur Desai 	default:
1348e3f2c991SKeyur Desai 		/*
1349e3f2c991SKeyur Desai 		 * Default to CSC_CACHE_MANUAL_REINT.
1350e3f2c991SKeyur Desai 		 */
1351e3f2c991SKeyur Desai 		break;
1352e3f2c991SKeyur Desai 	}
1353e3f2c991SKeyur Desai 
1354e3f2c991SKeyur Desai 	if (si->shr_flags & SMB_SHRF_ABE)
1355e3f2c991SKeyur Desai 		flags |= SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM;
1356e3f2c991SKeyur Desai 
1357cb174861Sjoyce mcintosh 	/* if 'smb' zfs property: shortnames=disabled */
1358cb174861Sjoyce mcintosh 	if ((smb_kmod_shareinfo(si->shr_name, &shortnames) == 0) &&
1359cb174861Sjoyce mcintosh 	    (shortnames == B_FALSE)) {
1360cb174861Sjoyce mcintosh 		flags |= SHI1005_FLAGS_ALLOW_NAMESPACE_CACHING;
1361cb174861Sjoyce mcintosh 	}
1362cb174861Sjoyce mcintosh 
1363e3f2c991SKeyur Desai 	return (flags);
1364e3f2c991SKeyur Desai }
1365e3f2c991SKeyur Desai 
136689dc44ceSjose borrego /*
136789dc44ceSjose borrego  * srvsvc_s_NetSessionEnum
136889dc44ceSjose borrego  *
136989dc44ceSjose borrego  * Level 1 request is made by (Server Manager (srvmgr) on NT Server when
137089dc44ceSjose borrego  * the user info icon is selected.
137189dc44ceSjose borrego  *
137289dc44ceSjose borrego  * On success, the return value is NERR_Success.
137389dc44ceSjose borrego  * On error, the return value can be one of the following error codes:
137489dc44ceSjose borrego  *
137589dc44ceSjose borrego  * ERROR_ACCESS_DENIED      The user does not have access to the requested
137689dc44ceSjose borrego  *                          information.
137789dc44ceSjose borrego  * ERROR_INVALID_LEVEL      The value specified for the level is invalid.
137889dc44ceSjose borrego  * ERROR_INVALID_PARAMETER  The specified parameter is invalid.
137989dc44ceSjose borrego  * ERROR_MORE_DATA          More entries are available. Specify a large
138089dc44ceSjose borrego  *                          enough buffer to receive all entries.
138189dc44ceSjose borrego  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
138289dc44ceSjose borrego  * NERR_ClientNameNotFound  A session does not exist with the computer name.
138389dc44ceSjose borrego  * NERR_InvalidComputer     The computer name is invalid.
138489dc44ceSjose borrego  * NERR_UserNotFound        The user name could not be found.
138589dc44ceSjose borrego  */
138689dc44ceSjose borrego static int
srvsvc_s_NetSessionEnum(void * arg,ndr_xa_t * mxa)138789dc44ceSjose borrego srvsvc_s_NetSessionEnum(void *arg, ndr_xa_t *mxa)
138889dc44ceSjose borrego {
138989dc44ceSjose borrego 	struct mslm_NetSessionEnum	*param = arg;
13901fcced4cSJordan Brown 	srvsvc_infonres_t		*info;
13911fcced4cSJordan Brown 	smb_netsvc_t			*ns;
13921fcced4cSJordan Brown 	smb_svcenum_t			se;
13931fcced4cSJordan Brown 	DWORD				status = ERROR_SUCCESS;
139489dc44ceSjose borrego 
13951fcced4cSJordan Brown 	if (!ndr_is_admin(mxa)) {
13961fcced4cSJordan Brown 		status = ERROR_ACCESS_DENIED;
13971fcced4cSJordan Brown 		goto srvsvc_netsessionenum_error;
13981fcced4cSJordan Brown 	}
13991fcced4cSJordan Brown 
14001fcced4cSJordan Brown 	if ((info = NDR_NEW(mxa, srvsvc_infonres_t)) == NULL) {
14011fcced4cSJordan Brown 		status = ERROR_NOT_ENOUGH_MEMORY;
14021fcced4cSJordan Brown 		goto srvsvc_netsessionenum_error;
14031fcced4cSJordan Brown 	}
14041fcced4cSJordan Brown 
14051fcced4cSJordan Brown 	info->entriesread = 0;
14061fcced4cSJordan Brown 	info->entries = NULL;
14071fcced4cSJordan Brown 	param->result.level = param->level;
14081fcced4cSJordan Brown 	param->result.bufptr.p = info;
14091fcced4cSJordan Brown 
14101fcced4cSJordan Brown 	if ((param->total_entries = srvsvc_open_sessions()) == 0) {
14111fcced4cSJordan Brown 		param->resume_handle = NULL;
14121fcced4cSJordan Brown 		param->status = ERROR_SUCCESS;
141389dc44ceSjose borrego 		return (NDR_DRC_OK);
141489dc44ceSjose borrego 	}
141589dc44ceSjose borrego 
14161fcced4cSJordan Brown 	bzero(&se, sizeof (smb_svcenum_t));
14171fcced4cSJordan Brown 	se.se_type = SMB_SVCENUM_TYPE_USER;
14181fcced4cSJordan Brown 	se.se_level = param->level;
14191fcced4cSJordan Brown 	se.se_ntotal = param->total_entries;
14201fcced4cSJordan Brown 	se.se_nlimit = se.se_ntotal;
142189dc44ceSjose borrego 
14221fcced4cSJordan Brown 	if (param->resume_handle) {
14231fcced4cSJordan Brown 		se.se_resume = *param->resume_handle;
14241fcced4cSJordan Brown 		se.se_nskip = se.se_resume;
14251fcced4cSJordan Brown 		*param->resume_handle = 0;
14261fcced4cSJordan Brown 	}
142789dc44ceSjose borrego 
142889dc44ceSjose borrego 	switch (param->level) {
142989dc44ceSjose borrego 	case 0:
14301fcced4cSJordan Brown 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_0,
14311fcced4cSJordan Brown 		    se.se_nlimit);
143289dc44ceSjose borrego 		break;
143389dc44ceSjose borrego 	case 1:
14341fcced4cSJordan Brown 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_1,
14351fcced4cSJordan Brown 		    se.se_nlimit);
143689dc44ceSjose borrego 		break;
143729bd2886SAlan Wright 	case 2:
14381fcced4cSJordan Brown 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_2,
14391fcced4cSJordan Brown 		    se.se_nlimit);
144029bd2886SAlan Wright 		break;
144129bd2886SAlan Wright 	case 10:
14421fcced4cSJordan Brown 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_10,
14431fcced4cSJordan Brown 		    se.se_nlimit);
144429bd2886SAlan Wright 		break;
144529bd2886SAlan Wright 	case 502:
14461fcced4cSJordan Brown 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_502,
14471fcced4cSJordan Brown 		    se.se_nlimit);
144829bd2886SAlan Wright 		break;
144989dc44ceSjose borrego 	default:
14501fcced4cSJordan Brown 		bzero(param, sizeof (struct mslm_NetSessionEnum));
14511fcced4cSJordan Brown 		param->status = ERROR_INVALID_LEVEL;
14521fcced4cSJordan Brown 		return (NDR_DRC_OK);
145389dc44ceSjose borrego 	}
145489dc44ceSjose borrego 
14551fcced4cSJordan Brown 	if (info->entries == NULL) {
14561fcced4cSJordan Brown 		status = ERROR_NOT_ENOUGH_MEMORY;
14571fcced4cSJordan Brown 		goto srvsvc_netsessionenum_error;
14581fcced4cSJordan Brown 	}
14591fcced4cSJordan Brown 
14601fcced4cSJordan Brown 	if ((ns = smb_kmod_enum_init(&se)) == NULL) {
14611fcced4cSJordan Brown 		status = ERROR_NOT_ENOUGH_MEMORY;
14621fcced4cSJordan Brown 		goto srvsvc_netsessionenum_error;
14631fcced4cSJordan Brown 	}
14641fcced4cSJordan Brown 
14651fcced4cSJordan Brown 	status = srvsvc_NetSessionEnumCommon(mxa, info, ns, &se);
14661fcced4cSJordan Brown 	smb_kmod_enum_fini(ns);
14671fcced4cSJordan Brown 
14681fcced4cSJordan Brown 	if (status != ERROR_SUCCESS)
14691fcced4cSJordan Brown 		goto srvsvc_netsessionenum_error;
14701fcced4cSJordan Brown 
14711fcced4cSJordan Brown 	if (param->resume_handle &&
14721fcced4cSJordan Brown 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
14731fcced4cSJordan Brown 		if (se.se_resume < param->total_entries) {
14741fcced4cSJordan Brown 			*param->resume_handle = se.se_resume;
14751fcced4cSJordan Brown 			status = ERROR_MORE_DATA;
14761fcced4cSJordan Brown 		}
14771fcced4cSJordan Brown 	}
14781fcced4cSJordan Brown 
14791fcced4cSJordan Brown 	param->total_entries = info->entriesread;
14801fcced4cSJordan Brown 	param->status = status;
14811fcced4cSJordan Brown 	return (NDR_DRC_OK);
14821fcced4cSJordan Brown 
14831fcced4cSJordan Brown srvsvc_netsessionenum_error:
148489dc44ceSjose borrego 	bzero(param, sizeof (struct mslm_NetSessionEnum));
148589dc44ceSjose borrego 	param->status = status;
148689dc44ceSjose borrego 	return (NDR_DRC_OK);
148789dc44ceSjose borrego }
148889dc44ceSjose borrego 
14891fcced4cSJordan Brown static uint32_t
srvsvc_NetSessionEnumCommon(ndr_xa_t * mxa,srvsvc_infonres_t * info,smb_netsvc_t * ns,smb_svcenum_t * se)14901fcced4cSJordan Brown srvsvc_NetSessionEnumCommon(ndr_xa_t *mxa, srvsvc_infonres_t *info,
14911fcced4cSJordan Brown     smb_netsvc_t *ns, smb_svcenum_t *se)
149289dc44ceSjose borrego {
14931fcced4cSJordan Brown 	struct mslm_SESSION_INFO_0	*info0 = info->entries;
14941fcced4cSJordan Brown 	struct mslm_SESSION_INFO_1	*info1 = info->entries;
14951fcced4cSJordan Brown 	struct mslm_SESSION_INFO_2	*info2 = info->entries;
14961fcced4cSJordan Brown 	struct mslm_SESSION_INFO_10	*info10 = info->entries;
14971fcced4cSJordan Brown 	struct mslm_SESSION_INFO_502	*info502 = info->entries;
14981fcced4cSJordan Brown 	smb_netsvcitem_t		*item;
14991fcced4cSJordan Brown 	smb_netuserinfo_t		*user;
150089dc44ceSjose borrego 	char				*workstation;
150189dc44ceSjose borrego 	char				account[MAXNAMELEN];
15027f667e74Sjose borrego 	char				ipaddr_buf[INET6_ADDRSTRLEN];
15031fcced4cSJordan Brown 	uint32_t			logon_time;
15041fcced4cSJordan Brown 	uint32_t			flags;
15051fcced4cSJordan Brown 	uint32_t			entries_read = 0;
150689dc44ceSjose borrego 
15071fcced4cSJordan Brown 	if (smb_kmod_enum(ns) != 0)
15081fcced4cSJordan Brown 		return (ERROR_INTERNAL_ERROR);
150989dc44ceSjose borrego 
15101fcced4cSJordan Brown 	item = list_head(&ns->ns_list);
15111fcced4cSJordan Brown 	while (item != NULL) {
15121fcced4cSJordan Brown 		user = &item->nsi_un.nsi_user;
151389dc44ceSjose borrego 
15141fcced4cSJordan Brown 		workstation = user->ui_workstation;
151589dc44ceSjose borrego 		if (workstation == NULL || *workstation == '\0') {
15161fcced4cSJordan Brown 			(void) smb_inet_ntop(&user->ui_ipaddr, ipaddr_buf,
15171fcced4cSJordan Brown 			    SMB_IPSTRLEN(user->ui_ipaddr.a_family));
151889dc44ceSjose borrego 			workstation = ipaddr_buf;
151989dc44ceSjose borrego 		}
152089dc44ceSjose borrego 
152189dc44ceSjose borrego 		(void) snprintf(account, MAXNAMELEN, "%s\\%s",
15221fcced4cSJordan Brown 		    user->ui_domain, user->ui_account);
152389dc44ceSjose borrego 
15241fcced4cSJordan Brown 		logon_time = time(0) - user->ui_logon_time;
15251fcced4cSJordan Brown 		flags = (user->ui_flags & SMB_ATF_GUEST) ? SESS_GUEST : 0;
152689dc44ceSjose borrego 
15271fcced4cSJordan Brown 		switch (se->se_level) {
15281fcced4cSJordan Brown 		case 0:
15291fcced4cSJordan Brown 			info0->sesi0_cname = NDR_STRDUP(mxa, workstation);
15301fcced4cSJordan Brown 			if (info0->sesi0_cname == NULL)
153189dc44ceSjose borrego 				return (ERROR_NOT_ENOUGH_MEMORY);
15321fcced4cSJordan Brown 			++info0;
15331fcced4cSJordan Brown 			break;
153489dc44ceSjose borrego 
15351fcced4cSJordan Brown 		case 1:
15361fcced4cSJordan Brown 			info1->sesi1_cname = NDR_STRDUP(mxa, workstation);
15371fcced4cSJordan Brown 			info1->sesi1_uname = NDR_STRDUP(mxa, account);
153889dc44ceSjose borrego 
15391fcced4cSJordan Brown 			if (info1->sesi1_cname == NULL ||
15401fcced4cSJordan Brown 			    info1->sesi1_uname == NULL)
154129bd2886SAlan Wright 				return (ERROR_NOT_ENOUGH_MEMORY);
154229bd2886SAlan Wright 
15431fcced4cSJordan Brown 			info1->sesi1_nopens = user->ui_numopens;
15441fcced4cSJordan Brown 			info1->sesi1_time = logon_time;
15451fcced4cSJordan Brown 			info1->sesi1_itime = 0;
15461fcced4cSJordan Brown 			info1->sesi1_uflags = flags;
15471fcced4cSJordan Brown 			++info1;
15481fcced4cSJordan Brown 			break;
154929bd2886SAlan Wright 
15501fcced4cSJordan Brown 		case 2:
15511fcced4cSJordan Brown 			info2->sesi2_cname = NDR_STRDUP(mxa, workstation);
15521fcced4cSJordan Brown 			info2->sesi2_uname = NDR_STRDUP(mxa, account);
155329bd2886SAlan Wright 
15541fcced4cSJordan Brown 			if (info2->sesi2_cname == NULL ||
15551fcced4cSJordan Brown 			    info2->sesi2_uname == NULL)
155629bd2886SAlan Wright 				return (ERROR_NOT_ENOUGH_MEMORY);
155729bd2886SAlan Wright 
15581fcced4cSJordan Brown 			info2->sesi2_nopens = user->ui_numopens;
15591fcced4cSJordan Brown 			info2->sesi2_time = logon_time;
15601fcced4cSJordan Brown 			info2->sesi2_itime = 0;
15611fcced4cSJordan Brown 			info2->sesi2_uflags = flags;
15621fcced4cSJordan Brown 			info2->sesi2_cltype_name = (uint8_t *)"";
15631fcced4cSJordan Brown 			++info2;
15641fcced4cSJordan Brown 			break;
156529bd2886SAlan Wright 
15661fcced4cSJordan Brown 		case 10:
15671fcced4cSJordan Brown 			info10->sesi10_cname = NDR_STRDUP(mxa, workstation);
15681fcced4cSJordan Brown 			info10->sesi10_uname = NDR_STRDUP(mxa, account);
156929bd2886SAlan Wright 
15701fcced4cSJordan Brown 			if (info10->sesi10_cname == NULL ||
15711fcced4cSJordan Brown 			    info10->sesi10_uname == NULL)
157229bd2886SAlan Wright 				return (ERROR_NOT_ENOUGH_MEMORY);
157329bd2886SAlan Wright 
15741fcced4cSJordan Brown 			info10->sesi10_time = logon_time;
15751fcced4cSJordan Brown 			info10->sesi10_itime = 0;
15761fcced4cSJordan Brown 			++info10;
15771fcced4cSJordan Brown 			break;
15781fcced4cSJordan Brown 
15791fcced4cSJordan Brown 		case 502:
15801fcced4cSJordan Brown 			info502->sesi502_cname = NDR_STRDUP(mxa, workstation);
15811fcced4cSJordan Brown 			info502->sesi502_uname = NDR_STRDUP(mxa, account);
15821fcced4cSJordan Brown 
15831fcced4cSJordan Brown 			if (info502->sesi502_cname == NULL ||
15841fcced4cSJordan Brown 			    info502->sesi502_uname == NULL)
158529bd2886SAlan Wright 				return (ERROR_NOT_ENOUGH_MEMORY);
15861fcced4cSJordan Brown 
15871fcced4cSJordan Brown 			info502->sesi502_nopens = user->ui_numopens;
15881fcced4cSJordan Brown 			info502->sesi502_time = logon_time;
15891fcced4cSJordan Brown 			info502->sesi502_itime = 0;
15901fcced4cSJordan Brown 			info502->sesi502_uflags = flags;
15911fcced4cSJordan Brown 			info502->sesi502_cltype_name = (uint8_t *)"";
15921fcced4cSJordan Brown 			info502->sesi502_transport = (uint8_t *)"";
15931fcced4cSJordan Brown 			++info502;
15941fcced4cSJordan Brown 			break;
15951fcced4cSJordan Brown 
15961fcced4cSJordan Brown 		default:
15971fcced4cSJordan Brown 			return (ERROR_INVALID_LEVEL);
159829bd2886SAlan Wright 		}
159929bd2886SAlan Wright 
16001fcced4cSJordan Brown 		++entries_read;
16011fcced4cSJordan Brown 		item = list_next(&ns->ns_list, item);
160229bd2886SAlan Wright 	}
160329bd2886SAlan Wright 
16041fcced4cSJordan Brown 	info->entriesread = entries_read;
160529bd2886SAlan Wright 	return (ERROR_SUCCESS);
160629bd2886SAlan Wright }
160729bd2886SAlan Wright 
160829bd2886SAlan Wright /*
160989dc44ceSjose borrego  * srvsvc_s_NetSessionDel
161089dc44ceSjose borrego  *
161189dc44ceSjose borrego  * Ends a network session between a server and a workstation.
161289dc44ceSjose borrego  * On NT only members of the Administrators or Account Operators
161389dc44ceSjose borrego  * local groups are permitted to use NetSessionDel.
161489dc44ceSjose borrego  *
16151fcced4cSJordan Brown  * If unc_clientname is NULL, all sessions associated with the
16161fcced4cSJordan Brown  * specified user will be disconnected.
16171fcced4cSJordan Brown  *
16181fcced4cSJordan Brown  * If username is NULL, all sessions from the specified client
16191fcced4cSJordan Brown  * will be disconnected.
16201fcced4cSJordan Brown  *
162189dc44ceSjose borrego  * Return Values
16221fcced4cSJordan Brown  * On success, the return value is NERR_Success/ERROR_SUCCESS.
16231fcced4cSJordan Brown  * On failure, the return value can be one of the following errors:
162489dc44ceSjose borrego  *
162589dc44ceSjose borrego  * ERROR_ACCESS_DENIED 		The user does not have access to the
162689dc44ceSjose borrego  * 				requested information.
162789dc44ceSjose borrego  * ERROR_INVALID_PARAMETER	The specified parameter is invalid.
162889dc44ceSjose borrego  * ERROR_NOT_ENOUGH_MEMORY	Insufficient memory is available.
162989dc44ceSjose borrego  * NERR_ClientNameNotFound	A session does not exist with that
163089dc44ceSjose borrego  *				computer name.
163189dc44ceSjose borrego  */
163289dc44ceSjose borrego static int
srvsvc_s_NetSessionDel(void * arg,ndr_xa_t * mxa)163389dc44ceSjose borrego srvsvc_s_NetSessionDel(void *arg, ndr_xa_t *mxa)
163489dc44ceSjose borrego {
16351fcced4cSJordan Brown 	static struct {
16361fcced4cSJordan Brown 		int errnum;
16371fcced4cSJordan Brown 		int nerr;
16381fcced4cSJordan Brown 	} errmap[] = {
16391fcced4cSJordan Brown 		0,	ERROR_SUCCESS,
16401fcced4cSJordan Brown 		EACCES,	ERROR_ACCESS_DENIED,
16411fcced4cSJordan Brown 		EPERM,	ERROR_ACCESS_DENIED,
16421fcced4cSJordan Brown 		EINVAL,	ERROR_INVALID_PARAMETER,
16431fcced4cSJordan Brown 		ENOMEM,	ERROR_NOT_ENOUGH_MEMORY,
16441fcced4cSJordan Brown 		ENOENT,	NERR_ClientNameNotFound
16451fcced4cSJordan Brown 	};
164689dc44ceSjose borrego 
16471fcced4cSJordan Brown 	struct mslm_NetSessionDel *param = arg;
16481fcced4cSJordan Brown 	int	i;
16491fcced4cSJordan Brown 	int	rc;
16501fcced4cSJordan Brown 
16511fcced4cSJordan Brown 	if (!ndr_is_admin(mxa)) {
165289dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
165389dc44ceSjose borrego 		return (NDR_DRC_OK);
165489dc44ceSjose borrego 	}
165589dc44ceSjose borrego 
16561fcced4cSJordan Brown 	rc = smb_kmod_session_close((char *)param->unc_clientname,
16571fcced4cSJordan Brown 	    (char *)param->username);
16581fcced4cSJordan Brown 
16591fcced4cSJordan Brown 	for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) {
16601fcced4cSJordan Brown 		if (rc == errmap[i].errnum) {
16611fcced4cSJordan Brown 			param->status = errmap[i].nerr;
16621fcced4cSJordan Brown 			return (NDR_DRC_OK);
16631fcced4cSJordan Brown 		}
16641fcced4cSJordan Brown 	}
16651fcced4cSJordan Brown 
16661fcced4cSJordan Brown 	param->status = ERROR_INTERNAL_ERROR;
166789dc44ceSjose borrego 	return (NDR_DRC_OK);
166889dc44ceSjose borrego }
166989dc44ceSjose borrego 
167089dc44ceSjose borrego static int
srvsvc_s_NetServerGetInfo(void * arg,ndr_xa_t * mxa)167189dc44ceSjose borrego srvsvc_s_NetServerGetInfo(void *arg, ndr_xa_t *mxa)
167289dc44ceSjose borrego {
167389dc44ceSjose borrego 	struct mslm_NetServerGetInfo *param = arg;
167489dc44ceSjose borrego 	struct mslm_SERVER_INFO_100 *info100;
167589dc44ceSjose borrego 	struct mslm_SERVER_INFO_101 *info101;
167689dc44ceSjose borrego 	struct mslm_SERVER_INFO_102 *info102;
167729bd2886SAlan Wright 	struct mslm_SERVER_INFO_502 *info502;
167829bd2886SAlan Wright 	struct mslm_SERVER_INFO_503 *info503;
167989dc44ceSjose borrego 	char sys_comment[SMB_PI_MAX_COMMENT];
168089dc44ceSjose borrego 	char hostname[NETBIOS_NAME_SZ];
16819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_version_t version;
168289dc44ceSjose borrego 
168389dc44ceSjose borrego 	if (smb_getnetbiosname(hostname, sizeof (hostname)) != 0) {
168489dc44ceSjose borrego netservergetinfo_no_memory:
168589dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetServerGetInfo));
168689dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
168789dc44ceSjose borrego 	}
168889dc44ceSjose borrego 
168989dc44ceSjose borrego 	(void) smb_config_getstr(SMB_CI_SYS_CMNT, sys_comment,
169089dc44ceSjose borrego 	    sizeof (sys_comment));
169189dc44ceSjose borrego 	if (*sys_comment == '\0')
169289dc44ceSjose borrego 		(void) strcpy(sys_comment, " ");
169389dc44ceSjose borrego 
16949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_config_get_version(&version);
16959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
169689dc44ceSjose borrego 	switch (param->level) {
169789dc44ceSjose borrego 	case 100:
169889dc44ceSjose borrego 		info100 = NDR_NEW(mxa, struct mslm_SERVER_INFO_100);
169989dc44ceSjose borrego 		if (info100 == NULL)
170089dc44ceSjose borrego 			goto netservergetinfo_no_memory;
170189dc44ceSjose borrego 
170289dc44ceSjose borrego 		bzero(info100, sizeof (struct mslm_SERVER_INFO_100));
170389dc44ceSjose borrego 		info100->sv100_platform_id = SV_PLATFORM_ID_NT;
170489dc44ceSjose borrego 		info100->sv100_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
170589dc44ceSjose borrego 		if (info100->sv100_name == NULL)
170689dc44ceSjose borrego 			goto netservergetinfo_no_memory;
170789dc44ceSjose borrego 
170889dc44ceSjose borrego 		param->result.bufptr.bufptr100 = info100;
170989dc44ceSjose borrego 		break;
171089dc44ceSjose borrego 
171189dc44ceSjose borrego 	case 101:
171289dc44ceSjose borrego 		info101 = NDR_NEW(mxa, struct mslm_SERVER_INFO_101);
171389dc44ceSjose borrego 		if (info101 == NULL)
171489dc44ceSjose borrego 			goto netservergetinfo_no_memory;
171589dc44ceSjose borrego 
171689dc44ceSjose borrego 		bzero(info101, sizeof (struct mslm_SERVER_INFO_101));
171789dc44ceSjose borrego 		info101->sv101_platform_id = SV_PLATFORM_ID_NT;
17189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		info101->sv101_version_major = version.sv_major;
17199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		info101->sv101_version_minor = version.sv_minor;
1720fe1c642dSBill Krier 		info101->sv101_type = SV_TYPE_DEFAULT;
172189dc44ceSjose borrego 		info101->sv101_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
172289dc44ceSjose borrego 		info101->sv101_comment
172389dc44ceSjose borrego 		    = (uint8_t *)NDR_STRDUP(mxa, sys_comment);
172489dc44ceSjose borrego 
172589dc44ceSjose borrego 		if (info101->sv101_name == NULL ||
172689dc44ceSjose borrego 		    info101->sv101_comment == NULL)
172789dc44ceSjose borrego 			goto netservergetinfo_no_memory;
172889dc44ceSjose borrego 
172989dc44ceSjose borrego 		param->result.bufptr.bufptr101 = info101;
173089dc44ceSjose borrego 		break;
173189dc44ceSjose borrego 
173289dc44ceSjose borrego 	case 102:
173389dc44ceSjose borrego 		info102 = NDR_NEW(mxa, struct mslm_SERVER_INFO_102);
173489dc44ceSjose borrego 		if (info102 == NULL)
173589dc44ceSjose borrego 			goto netservergetinfo_no_memory;
173689dc44ceSjose borrego 
173789dc44ceSjose borrego 		bzero(info102, sizeof (struct mslm_SERVER_INFO_102));
173889dc44ceSjose borrego 		info102->sv102_platform_id = SV_PLATFORM_ID_NT;
17399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		info102->sv102_version_major = version.sv_major;
17409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		info102->sv102_version_minor = version.sv_minor;
1741fe1c642dSBill Krier 		info102->sv102_type = SV_TYPE_DEFAULT;
174289dc44ceSjose borrego 		info102->sv102_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
174389dc44ceSjose borrego 		info102->sv102_comment
174489dc44ceSjose borrego 		    = (uint8_t *)NDR_STRDUP(mxa, sys_comment);
174589dc44ceSjose borrego 
174689dc44ceSjose borrego 		/*
174789dc44ceSjose borrego 		 * The following level 102 fields are defaulted to zero
174889dc44ceSjose borrego 		 * by virtue of the call to bzero above.
174989dc44ceSjose borrego 		 *
175089dc44ceSjose borrego 		 * sv102_users
175189dc44ceSjose borrego 		 * sv102_disc
175289dc44ceSjose borrego 		 * sv102_hidden
175389dc44ceSjose borrego 		 * sv102_announce
175489dc44ceSjose borrego 		 * sv102_anndelta
175589dc44ceSjose borrego 		 * sv102_licenses
175689dc44ceSjose borrego 		 * sv102_userpath
175789dc44ceSjose borrego 		 */
175889dc44ceSjose borrego 		if (info102->sv102_name == NULL ||
175989dc44ceSjose borrego 		    info102->sv102_comment == NULL)
176089dc44ceSjose borrego 			goto netservergetinfo_no_memory;
176189dc44ceSjose borrego 
176289dc44ceSjose borrego 		param->result.bufptr.bufptr102 = info102;
176389dc44ceSjose borrego 		break;
176489dc44ceSjose borrego 
176529bd2886SAlan Wright 	case 502:
176629bd2886SAlan Wright 		info502 = NDR_NEW(mxa, struct mslm_SERVER_INFO_502);
176729bd2886SAlan Wright 		if (info502 == NULL)
176829bd2886SAlan Wright 			goto netservergetinfo_no_memory;
176929bd2886SAlan Wright 
177029bd2886SAlan Wright 		bzero(info502, sizeof (struct mslm_SERVER_INFO_502));
177129bd2886SAlan Wright 		param->result.bufptr.bufptr502 = info502;
177229bd2886SAlan Wright #ifdef SRVSVC_SATISFY_SMBTORTURE
177329bd2886SAlan Wright 		break;
177429bd2886SAlan Wright #else
177529bd2886SAlan Wright 		param->result.level = param->level;
177629bd2886SAlan Wright 		param->status = ERROR_ACCESS_DENIED;
177729bd2886SAlan Wright 		return (NDR_DRC_OK);
177829bd2886SAlan Wright #endif /* SRVSVC_SATISFY_SMBTORTURE */
177929bd2886SAlan Wright 
178029bd2886SAlan Wright 	case 503:
178129bd2886SAlan Wright 		info503 = NDR_NEW(mxa, struct mslm_SERVER_INFO_503);
178229bd2886SAlan Wright 		if (info503 == NULL)
178329bd2886SAlan Wright 			goto netservergetinfo_no_memory;
178429bd2886SAlan Wright 
178529bd2886SAlan Wright 		bzero(info503, sizeof (struct mslm_SERVER_INFO_503));
178629bd2886SAlan Wright 		param->result.bufptr.bufptr503 = info503;
178729bd2886SAlan Wright #ifdef SRVSVC_SATISFY_SMBTORTURE
178829bd2886SAlan Wright 		break;
178929bd2886SAlan Wright #else
179029bd2886SAlan Wright 		param->result.level = param->level;
179129bd2886SAlan Wright 		param->status = ERROR_ACCESS_DENIED;
179229bd2886SAlan Wright 		return (NDR_DRC_OK);
179329bd2886SAlan Wright #endif /* SRVSVC_SATISFY_SMBTORTURE */
179429bd2886SAlan Wright 
179589dc44ceSjose borrego 	default:
179689dc44ceSjose borrego 		bzero(&param->result,
179789dc44ceSjose borrego 		    sizeof (struct mslm_NetServerGetInfo_result));
179889dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
179989dc44ceSjose borrego 		return (NDR_DRC_OK);
180089dc44ceSjose borrego 	}
180189dc44ceSjose borrego 
180289dc44ceSjose borrego 	param->result.level = param->level;
180329bd2886SAlan Wright 	param->status = ERROR_SUCCESS;
180489dc44ceSjose borrego 	return (NDR_DRC_OK);
180589dc44ceSjose borrego }
180689dc44ceSjose borrego 
180789dc44ceSjose borrego /*
180889dc44ceSjose borrego  * NetRemoteTOD
180989dc44ceSjose borrego  *
181089dc44ceSjose borrego  * Returns information about the time of day on this server.
181189dc44ceSjose borrego  *
181289dc44ceSjose borrego  * typedef struct _TIME_OF_DAY_INFO {
181389dc44ceSjose borrego  *	DWORD tod_elapsedt;  // seconds since 00:00:00 January 1 1970 GMT
181489dc44ceSjose borrego  *	DWORD tod_msecs;     // arbitrary milliseconds (since reset)
181589dc44ceSjose borrego  *	DWORD tod_hours;     // current hour [0-23]
181689dc44ceSjose borrego  *	DWORD tod_mins;      // current minute [0-59]
181789dc44ceSjose borrego  *	DWORD tod_secs;      // current second [0-59]
181889dc44ceSjose borrego  *	DWORD tod_hunds;     // current hundredth (0.01) second [0-99]
181989dc44ceSjose borrego  *	LONG tod_timezone;   // time zone of the server
182089dc44ceSjose borrego  *	DWORD tod_tinterval; // clock tick time interval
182189dc44ceSjose borrego  *	DWORD tod_day;       // day of the month [1-31]
182289dc44ceSjose borrego  *	DWORD tod_month;     // month of the year [1-12]
182389dc44ceSjose borrego  *	DWORD tod_year;      // current year
182489dc44ceSjose borrego  *	DWORD tod_weekday;   // day of the week since Sunday [0-6]
182589dc44ceSjose borrego  * } TIME_OF_DAY_INFO;
182689dc44ceSjose borrego  *
182789dc44ceSjose borrego  * The time zone of the server is calculated in minutes from Greenwich
182889dc44ceSjose borrego  * Mean Time (GMT). For time zones west of Greenwich, the value is
182989dc44ceSjose borrego  * positive; for time zones east of Greenwich, the value is negative.
183089dc44ceSjose borrego  * A value of -1 indicates that the time zone is undefined.
183189dc44ceSjose borrego  *
1832bbf6f00cSJordan Brown  * Determine offset from GMT. If daylight saving time use altzone,
1833bbf6f00cSJordan Brown  * otherwise use timezone.
1834bbf6f00cSJordan Brown  *
183589dc44ceSjose borrego  * The clock tick value represents a resolution of one ten-thousandth
183689dc44ceSjose borrego  * (0.0001) second.
183789dc44ceSjose borrego  */
183889dc44ceSjose borrego static int
srvsvc_s_NetRemoteTOD(void * arg,ndr_xa_t * mxa)183989dc44ceSjose borrego srvsvc_s_NetRemoteTOD(void *arg, ndr_xa_t *mxa)
184089dc44ceSjose borrego {
184189dc44ceSjose borrego 	struct mslm_NetRemoteTOD *param = arg;
184289dc44ceSjose borrego 	struct mslm_TIME_OF_DAY_INFO *tod;
184389dc44ceSjose borrego 	struct timeval		time_val;
184489dc44ceSjose borrego 	struct tm		tm;
1845bbf6f00cSJordan Brown 	time_t			gmtoff;
1846bbf6f00cSJordan Brown 
184789dc44ceSjose borrego 
184889dc44ceSjose borrego 	(void) gettimeofday(&time_val, 0);
184989dc44ceSjose borrego 	(void) gmtime_r(&time_val.tv_sec, &tm);
185089dc44ceSjose borrego 
185189dc44ceSjose borrego 	tod = NDR_NEW(mxa, struct mslm_TIME_OF_DAY_INFO);
185289dc44ceSjose borrego 	if (tod == NULL) {
185389dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetRemoteTOD));
185489dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
185589dc44ceSjose borrego 	}
185689dc44ceSjose borrego 
1857bbf6f00cSJordan Brown 	bzero(tod, sizeof (struct mslm_TIME_OF_DAY_INFO));
1858bbf6f00cSJordan Brown 
185989dc44ceSjose borrego 	tod->tod_elapsedt = time_val.tv_sec;
186089dc44ceSjose borrego 	tod->tod_msecs = time_val.tv_usec;
186189dc44ceSjose borrego 	tod->tod_hours = tm.tm_hour;
186289dc44ceSjose borrego 	tod->tod_mins = tm.tm_min;
186389dc44ceSjose borrego 	tod->tod_secs = tm.tm_sec;
186489dc44ceSjose borrego 	tod->tod_hunds = 0;
186589dc44ceSjose borrego 	tod->tod_tinterval = 1000;
186689dc44ceSjose borrego 	tod->tod_day = tm.tm_mday;
186789dc44ceSjose borrego 	tod->tod_month = tm.tm_mon+1;
186889dc44ceSjose borrego 	tod->tod_year = tm.tm_year+1900;
186989dc44ceSjose borrego 	tod->tod_weekday = tm.tm_wday;
187089dc44ceSjose borrego 
187189dc44ceSjose borrego 	(void) localtime_r(&time_val.tv_sec, &tm);
1872bbf6f00cSJordan Brown 	gmtoff = (tm.tm_isdst) ? altzone : timezone;
1873bbf6f00cSJordan Brown 	tod->tod_timezone = gmtoff / SECSPERMIN;
187489dc44ceSjose borrego 
187589dc44ceSjose borrego 	param->bufptr = tod;
187689dc44ceSjose borrego 	param->status = ERROR_SUCCESS;
187789dc44ceSjose borrego 	return (NDR_DRC_OK);
187889dc44ceSjose borrego }
187989dc44ceSjose borrego 
188089dc44ceSjose borrego /*
188189dc44ceSjose borrego  * srvsvc_s_NetNameValidate
188289dc44ceSjose borrego  *
188389dc44ceSjose borrego  * Perform name validation.
188489dc44ceSjose borrego  *
188589dc44ceSjose borrego  * Returns Win32 error codes.
188689dc44ceSjose borrego  */
188789dc44ceSjose borrego /*ARGSUSED*/
188889dc44ceSjose borrego static int
srvsvc_s_NetNameValidate(void * arg,ndr_xa_t * mxa)188989dc44ceSjose borrego srvsvc_s_NetNameValidate(void *arg, ndr_xa_t *mxa)
189089dc44ceSjose borrego {
189189dc44ceSjose borrego 	struct mslm_NetNameValidate *param = arg;
189289dc44ceSjose borrego 	char *name;
1893fe1c642dSBill Krier 	int maxlen;
189489dc44ceSjose borrego 	int len;
189589dc44ceSjose borrego 
189689dc44ceSjose borrego 	if ((name = (char *)param->pathname) == NULL) {
189789dc44ceSjose borrego 		param->status = ERROR_INVALID_PARAMETER;
189889dc44ceSjose borrego 		return (NDR_DRC_OK);
189989dc44ceSjose borrego 	}
190089dc44ceSjose borrego 
1901fe1c642dSBill Krier 	switch (param->type) {
1902fe1c642dSBill Krier 	case NAMETYPE_SHARE:
190389dc44ceSjose borrego 		len = strlen(name);
1904fe1c642dSBill Krier 		maxlen = (param->flags & NAMEFLAG_LM2) ?
1905fe1c642dSBill Krier 		    SMB_SHARE_OEMNAME_MAX : SMB_SHARE_NTNAME_MAX;
190689dc44ceSjose borrego 
1907fe1c642dSBill Krier 		if (len > maxlen) {
190889dc44ceSjose borrego 			param->status = ERROR_INVALID_NAME;
190989dc44ceSjose borrego 			return (NDR_DRC_OK);
191089dc44ceSjose borrego 		}
191189dc44ceSjose borrego 
1912fe1c642dSBill Krier 		param->status = smb_name_validate_share(name);
191389dc44ceSjose borrego 		break;
191489dc44ceSjose borrego 
191589dc44ceSjose borrego 	case NAMETYPE_USER:
191689dc44ceSjose borrego 	case NAMETYPE_GROUP:
1917fe1c642dSBill Krier 		param->status = smb_name_validate_account(name);
1918fe1c642dSBill Krier 		break;
1919fe1c642dSBill Krier 
1920fe1c642dSBill Krier 	case NAMETYPE_DOMAIN:	/* NetBIOS domain name */
1921fe1c642dSBill Krier 		param->status = smb_name_validate_nbdomain(name);
1922fe1c642dSBill Krier 		break;
1923fe1c642dSBill Krier 
1924fe1c642dSBill Krier 	case NAMETYPE_WORKGROUP:
1925fe1c642dSBill Krier 		param->status = smb_name_validate_workgroup(name);
1926fe1c642dSBill Krier 		break;
1927fe1c642dSBill Krier 
1928fe1c642dSBill Krier 	case NAMETYPE_PASSWORD:
192989dc44ceSjose borrego 	case NAMETYPE_COMPUTER:
193089dc44ceSjose borrego 	case NAMETYPE_EVENT:
193189dc44ceSjose borrego 	case NAMETYPE_SERVICE:
193289dc44ceSjose borrego 	case NAMETYPE_NET:
193389dc44ceSjose borrego 	case NAMETYPE_MESSAGE:
193489dc44ceSjose borrego 	case NAMETYPE_MESSAGEDEST:
193589dc44ceSjose borrego 	case NAMETYPE_SHAREPASSWORD:
193689dc44ceSjose borrego 		param->status = ERROR_NOT_SUPPORTED;
193789dc44ceSjose borrego 		break;
193889dc44ceSjose borrego 
193989dc44ceSjose borrego 	default:
194089dc44ceSjose borrego 		param->status = ERROR_INVALID_PARAMETER;
194189dc44ceSjose borrego 		break;
194289dc44ceSjose borrego 	}
194389dc44ceSjose borrego 
194489dc44ceSjose borrego 	return (NDR_DRC_OK);
194589dc44ceSjose borrego }
194689dc44ceSjose borrego 
194789dc44ceSjose borrego /*
194889dc44ceSjose borrego  * srvsvc_s_NetShareAdd
194989dc44ceSjose borrego  *
195029bd2886SAlan Wright  * Add a new share. Only power users groups can manage shares.
195189dc44ceSjose borrego  *
195289dc44ceSjose borrego  * This interface is used by the rmtshare command from the NT resource
195389dc44ceSjose borrego  * kit. Rmtshare allows a client to add or remove shares on a server
195489dc44ceSjose borrego  * from the client's command line.
195589dc44ceSjose borrego  *
195689dc44ceSjose borrego  * Returns Win32 error codes.
195789dc44ceSjose borrego  */
195889dc44ceSjose borrego static int
srvsvc_s_NetShareAdd(void * arg,ndr_xa_t * mxa)195989dc44ceSjose borrego srvsvc_s_NetShareAdd(void *arg, ndr_xa_t *mxa)
196089dc44ceSjose borrego {
196189dc44ceSjose borrego 	static DWORD parm_err = 0;
196289dc44ceSjose borrego 	DWORD parm_stat;
196389dc44ceSjose borrego 	struct mslm_NetShareAdd *param = arg;
1964eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_2 *info2;
196529bd2886SAlan Wright 	struct mslm_NetShareInfo_502 *info502;
196689dc44ceSjose borrego 	char realpath[MAXPATHLEN];
196789dc44ceSjose borrego 	int32_t native_os;
196829bd2886SAlan Wright 	uint8_t *sdbuf = NULL;
196929bd2886SAlan Wright 	uint32_t status;
197029bd2886SAlan Wright 	smb_share_t si;
197189dc44ceSjose borrego 
197289dc44ceSjose borrego 	native_os = ndr_native_os(mxa);
197389dc44ceSjose borrego 
197489dc44ceSjose borrego 	if (!ndr_is_poweruser(mxa)) {
197589dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetShareAdd));
197689dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
197789dc44ceSjose borrego 		return (NDR_DRC_OK);
197889dc44ceSjose borrego 	}
197989dc44ceSjose borrego 
198089dc44ceSjose borrego 	switch (param->level) {
198189dc44ceSjose borrego 	case 2:
198229bd2886SAlan Wright 		info2 = (struct mslm_NetShareInfo_2 *)param->info.un.info2;
198389dc44ceSjose borrego 		break;
198489dc44ceSjose borrego 
198589dc44ceSjose borrego 	case 502:
198629bd2886SAlan Wright 		info502 = (struct mslm_NetShareInfo_502 *)
198729bd2886SAlan Wright 		    param->info.un.info502;
198829bd2886SAlan Wright 		sdbuf = info502->shi502_security_descriptor;
198929bd2886SAlan Wright 		info2 = (struct mslm_NetShareInfo_2 *)info502;
199089dc44ceSjose borrego 		break;
199189dc44ceSjose borrego 
199289dc44ceSjose borrego 	default:
199389dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetShareAdd));
199489dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
199589dc44ceSjose borrego 		return (NDR_DRC_OK);
199689dc44ceSjose borrego 	}
199789dc44ceSjose borrego 
199889dc44ceSjose borrego 	if (info2->shi2_netname == NULL || info2->shi2_path == NULL) {
199989dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetShareAdd));
200089dc44ceSjose borrego 		param->status = NERR_NetNameNotFound;
200189dc44ceSjose borrego 		return (NDR_DRC_OK);
200289dc44ceSjose borrego 	}
200389dc44ceSjose borrego 
200489dc44ceSjose borrego 	if (smb_shr_is_restricted((char *)info2->shi2_netname)) {
200589dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetShareAdd));
200689dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
200789dc44ceSjose borrego 		return (NDR_DRC_OK);
200889dc44ceSjose borrego 	}
200989dc44ceSjose borrego 
2010eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (info2->shi2_comment == NULL)
2011eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		info2->shi2_comment = (uint8_t *)"";
201289dc44ceSjose borrego 
201389dc44ceSjose borrego 	/*
201489dc44ceSjose borrego 	 * Derive the real path which will be stored in the
201589dc44ceSjose borrego 	 * directory field of the smb_share_t structure
201689dc44ceSjose borrego 	 * from the path field in this RPC request.
201789dc44ceSjose borrego 	 */
201889dc44ceSjose borrego 	parm_stat = smb_shr_get_realpath((const char *)info2->shi2_path,
201989dc44ceSjose borrego 	    realpath, MAXPATHLEN);
202089dc44ceSjose borrego 
202189dc44ceSjose borrego 	if (parm_stat != NERR_Success) {
202289dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetShareAdd));
202389dc44ceSjose borrego 		param->status = parm_stat;
202489dc44ceSjose borrego 		param->parm_err
202589dc44ceSjose borrego 		    = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
202689dc44ceSjose borrego 		return (NDR_DRC_OK);
202789dc44ceSjose borrego 	}
202889dc44ceSjose borrego 
202989dc44ceSjose borrego 	param->status = srvsvc_sa_add((char *)info2->shi2_netname, realpath,
2030eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    (char *)info2->shi2_comment);
203189dc44ceSjose borrego 	if (param->status == NERR_Success) {
203229bd2886SAlan Wright 		status = smb_shr_get((char *)info2->shi2_netname, &si);
203329bd2886SAlan Wright 
203429bd2886SAlan Wright 		if ((sdbuf != NULL) && (status == NERR_Success))
203529bd2886SAlan Wright 			(void) srvsvc_sd_set(&si, sdbuf);
203689dc44ceSjose borrego 	}
203789dc44ceSjose borrego 	param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
203889dc44ceSjose borrego 	return (NDR_DRC_OK);
203989dc44ceSjose borrego }
204089dc44ceSjose borrego 
204189dc44ceSjose borrego /*
20421fcced4cSJordan Brown  * srvsvc_estimate_limit
204389dc44ceSjose borrego  *
204489dc44ceSjose borrego  * Estimate the number of objects that will fit in prefmaxlen.
20451fcced4cSJordan Brown  * nlimit is adjusted here.
204689dc44ceSjose borrego  */
20471fcced4cSJordan Brown static void
srvsvc_estimate_limit(smb_svcenum_t * se,uint32_t obj_size)20481fcced4cSJordan Brown srvsvc_estimate_limit(smb_svcenum_t *se, uint32_t obj_size)
204989dc44ceSjose borrego {
205089dc44ceSjose borrego 	DWORD max_cnt;
205189dc44ceSjose borrego 
20521fcced4cSJordan Brown 	if (obj_size == 0) {
20531fcced4cSJordan Brown 		se->se_nlimit = 0;
20541fcced4cSJordan Brown 		return;
20551fcced4cSJordan Brown 	}
205689dc44ceSjose borrego 
20571fcced4cSJordan Brown 	if ((max_cnt = (se->se_prefmaxlen / obj_size)) == 0) {
20581fcced4cSJordan Brown 		se->se_nlimit = 0;
20591fcced4cSJordan Brown 		return;
20601fcced4cSJordan Brown 	}
206189dc44ceSjose borrego 
20621fcced4cSJordan Brown 	if (se->se_ntotal > max_cnt)
20631fcced4cSJordan Brown 		se->se_nlimit = max_cnt;
20641fcced4cSJordan Brown 	else
20651fcced4cSJordan Brown 		se->se_nlimit = se->se_ntotal;
206689dc44ceSjose borrego }
206789dc44ceSjose borrego 
206889dc44ceSjose borrego /*
206989dc44ceSjose borrego  * srvsvc_s_NetShareEnum
207089dc44ceSjose borrego  *
207189dc44ceSjose borrego  * Enumerate all shares (see also NetShareEnumSticky).
207289dc44ceSjose borrego  *
207389dc44ceSjose borrego  * Request for various levels of information about our shares.
207489dc44ceSjose borrego  * Level 0: share names.
207589dc44ceSjose borrego  * Level 1: share name, share type and comment field.
207689dc44ceSjose borrego  * Level 2: everything that we know about the shares.
2077e3f2c991SKeyur Desai  * Level 501: level 1 + flags.
207889dc44ceSjose borrego  * Level 502: level 2 + security descriptor.
207989dc44ceSjose borrego  */
208089dc44ceSjose borrego static int
srvsvc_s_NetShareEnum(void * arg,ndr_xa_t * mxa)208189dc44ceSjose borrego srvsvc_s_NetShareEnum(void *arg, ndr_xa_t *mxa)
208289dc44ceSjose borrego {
208389dc44ceSjose borrego 	struct mslm_NetShareEnum *param = arg;
20841fcced4cSJordan Brown 	srvsvc_infonres_t *infonres;
20851fcced4cSJordan Brown 	smb_svcenum_t se;
208689dc44ceSjose borrego 	DWORD status;
208789dc44ceSjose borrego 
20881fcced4cSJordan Brown 	infonres = NDR_NEW(mxa, srvsvc_infonres_t);
208989dc44ceSjose borrego 	if (infonres == NULL) {
209089dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetShareEnum));
209189dc44ceSjose borrego 		param->status = ERROR_NOT_ENOUGH_MEMORY;
209289dc44ceSjose borrego 		return (NDR_DRC_OK);
209389dc44ceSjose borrego 	}
209489dc44ceSjose borrego 
209589dc44ceSjose borrego 	infonres->entriesread = 0;
209689dc44ceSjose borrego 	infonres->entries = NULL;
209789dc44ceSjose borrego 	param->result.level = param->level;
209889dc44ceSjose borrego 	param->result.bufptr.p = infonres;
209989dc44ceSjose borrego 
21001fcced4cSJordan Brown 	bzero(&se, sizeof (smb_svcenum_t));
21011fcced4cSJordan Brown 	se.se_type = SMB_SVCENUM_TYPE_SHARE;
210289dc44ceSjose borrego 	se.se_level = param->level;
21031fcced4cSJordan Brown 	se.se_ntotal = smb_shr_count();
21041fcced4cSJordan Brown 	se.se_nlimit = se.se_ntotal;
210589dc44ceSjose borrego 
210689dc44ceSjose borrego 	if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN ||
210789dc44ceSjose borrego 	    param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN)
210889dc44ceSjose borrego 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
210989dc44ceSjose borrego 	else
211089dc44ceSjose borrego 		se.se_prefmaxlen = param->prefmaxlen;
211189dc44ceSjose borrego 
211289dc44ceSjose borrego 	if (param->resume_handle) {
21131fcced4cSJordan Brown 		se.se_resume = *param->resume_handle;
21141fcced4cSJordan Brown 		se.se_nskip = se.se_resume;
21151fcced4cSJordan Brown 		*param->resume_handle = 0;
211689dc44ceSjose borrego 	}
211789dc44ceSjose borrego 
211889dc44ceSjose borrego 	switch (param->level) {
211989dc44ceSjose borrego 	case 0:
212089dc44ceSjose borrego 		status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 0);
212189dc44ceSjose borrego 		break;
212289dc44ceSjose borrego 
212389dc44ceSjose borrego 	case 1:
212489dc44ceSjose borrego 		status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 0);
212589dc44ceSjose borrego 		break;
212689dc44ceSjose borrego 
212789dc44ceSjose borrego 	case 2:
212889dc44ceSjose borrego 		status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 0);
212989dc44ceSjose borrego 		break;
213089dc44ceSjose borrego 
213189dc44ceSjose borrego 	case 501:
213289dc44ceSjose borrego 		status = mlsvc_NetShareEnumLevel501(mxa, infonres, &se, 0);
213389dc44ceSjose borrego 		break;
213489dc44ceSjose borrego 
213589dc44ceSjose borrego 	case 502:
213689dc44ceSjose borrego 		status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 0);
213789dc44ceSjose borrego 		break;
213889dc44ceSjose borrego 
213989dc44ceSjose borrego 	default:
214029bd2886SAlan Wright 		status = ERROR_INVALID_LEVEL;
214189dc44ceSjose borrego 		break;
214289dc44ceSjose borrego 	}
214389dc44ceSjose borrego 
214489dc44ceSjose borrego 	if (status != 0) {
214589dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetShareEnum));
214689dc44ceSjose borrego 		param->status = status;
214789dc44ceSjose borrego 		return (NDR_DRC_OK);
214889dc44ceSjose borrego 	}
214989dc44ceSjose borrego 
21501fcced4cSJordan Brown 	if (se.se_nlimit == 0) {
215189dc44ceSjose borrego 		param->status = ERROR_SUCCESS;
215289dc44ceSjose borrego 		return (NDR_DRC_OK);
215389dc44ceSjose borrego 	}
215489dc44ceSjose borrego 
215589dc44ceSjose borrego 	if (param->resume_handle &&
215689dc44ceSjose borrego 	    param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) {
21571fcced4cSJordan Brown 		if (se.se_resume < se.se_ntotal) {
21581fcced4cSJordan Brown 			*param->resume_handle = se.se_resume;
215989dc44ceSjose borrego 			status = ERROR_MORE_DATA;
216089dc44ceSjose borrego 		}
216189dc44ceSjose borrego 	}
216289dc44ceSjose borrego 
21631fcced4cSJordan Brown 	param->totalentries = se.se_ntotal;
216489dc44ceSjose borrego 	param->status = status;
216589dc44ceSjose borrego 	return (NDR_DRC_OK);
216689dc44ceSjose borrego }
216789dc44ceSjose borrego 
216889dc44ceSjose borrego /*
216989dc44ceSjose borrego  * srvsvc_s_NetShareEnumSticky
217089dc44ceSjose borrego  *
217189dc44ceSjose borrego  * Enumerate sticky shares: all shares except those marked STYPE_SPECIAL.
217289dc44ceSjose borrego  * Except for excluding STYPE_SPECIAL shares, NetShareEnumSticky is the
217389dc44ceSjose borrego  * same as NetShareEnum.
217489dc44ceSjose borrego  *
217589dc44ceSjose borrego  * Request for various levels of information about our shares.
217689dc44ceSjose borrego  * Level 0: share names.
217789dc44ceSjose borrego  * Level 1: share name, share type and comment field.
217889dc44ceSjose borrego  * Level 2: everything that we know about the shares.
217989dc44ceSjose borrego  * Level 501: not valid for this request.
218089dc44ceSjose borrego  * Level 502: level 2 + security descriptor.
218189dc44ceSjose borrego  *
218289dc44ceSjose borrego  * We set n_skip to resume_handle, which is used to find the appropriate
218389dc44ceSjose borrego  * place to resume.  The resume_handle is similar to the readdir cookie.
218489dc44ceSjose borrego  */
218589dc44ceSjose borrego static int
srvsvc_s_NetShareEnumSticky(void * arg,ndr_xa_t * mxa)218689dc44ceSjose borrego srvsvc_s_NetShareEnumSticky(void *arg, ndr_xa_t *mxa)
218789dc44ceSjose borrego {
218889dc44ceSjose borrego 	struct mslm_NetShareEnum *param = arg;
21891fcced4cSJordan Brown 	srvsvc_infonres_t *infonres;
21901fcced4cSJordan Brown 	smb_svcenum_t se;
219189dc44ceSjose borrego 	DWORD status;
219289dc44ceSjose borrego 
21931fcced4cSJordan Brown 	infonres = NDR_NEW(mxa, srvsvc_infonres_t);
219489dc44ceSjose borrego 	if (infonres == NULL) {
219589dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetShareEnum));
219689dc44ceSjose borrego 		param->status = ERROR_NOT_ENOUGH_MEMORY;
219789dc44ceSjose borrego 		return (NDR_DRC_OK);
219889dc44ceSjose borrego 	}
219989dc44ceSjose borrego 
220089dc44ceSjose borrego 	infonres->entriesread = 0;
220189dc44ceSjose borrego 	infonres->entries = NULL;
220289dc44ceSjose borrego 	param->result.level = param->level;
220389dc44ceSjose borrego 	param->result.bufptr.p = infonres;
220489dc44ceSjose borrego 
22051fcced4cSJordan Brown 	bzero(&se, sizeof (smb_svcenum_t));
22061fcced4cSJordan Brown 	se.se_type = SMB_SVCENUM_TYPE_SHARE;
220789dc44ceSjose borrego 	se.se_level = param->level;
22081fcced4cSJordan Brown 	se.se_ntotal = smb_shr_count();
22091fcced4cSJordan Brown 	se.se_nlimit = se.se_ntotal;
221089dc44ceSjose borrego 
221189dc44ceSjose borrego 	if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN ||
221289dc44ceSjose borrego 	    param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN)
221389dc44ceSjose borrego 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
221489dc44ceSjose borrego 	else
221589dc44ceSjose borrego 		se.se_prefmaxlen = param->prefmaxlen;
221689dc44ceSjose borrego 
221789dc44ceSjose borrego 	if (param->resume_handle) {
22181fcced4cSJordan Brown 		se.se_resume = *param->resume_handle;
22191fcced4cSJordan Brown 		se.se_nskip = se.se_resume;
22201fcced4cSJordan Brown 		*param->resume_handle = 0;
222189dc44ceSjose borrego 	}
222289dc44ceSjose borrego 
222389dc44ceSjose borrego 	switch (param->level) {
222489dc44ceSjose borrego 	case 0:
222589dc44ceSjose borrego 		status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 1);
222689dc44ceSjose borrego 		break;
222789dc44ceSjose borrego 
222889dc44ceSjose borrego 	case 1:
222989dc44ceSjose borrego 		status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 1);
223089dc44ceSjose borrego 		break;
223189dc44ceSjose borrego 
223289dc44ceSjose borrego 	case 2:
223389dc44ceSjose borrego 		status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 1);
223489dc44ceSjose borrego 		break;
223589dc44ceSjose borrego 
223689dc44ceSjose borrego 	case 502:
223789dc44ceSjose borrego 		status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 1);
223889dc44ceSjose borrego 		break;
223989dc44ceSjose borrego 
224029bd2886SAlan Wright 	case 501:
224189dc44ceSjose borrego 	default:
224289dc44ceSjose borrego 		status = ERROR_INVALID_LEVEL;
224389dc44ceSjose borrego 		break;
224489dc44ceSjose borrego 	}
224589dc44ceSjose borrego 
224689dc44ceSjose borrego 	if (status != ERROR_SUCCESS) {
224789dc44ceSjose borrego 		bzero(param, sizeof (struct mslm_NetShareEnum));
224889dc44ceSjose borrego 		param->status = status;
224989dc44ceSjose borrego 		return (NDR_DRC_OK);
225089dc44ceSjose borrego 	}
225189dc44ceSjose borrego 
22521fcced4cSJordan Brown 	if (se.se_nlimit == 0) {
225389dc44ceSjose borrego 		param->status = ERROR_SUCCESS;
225489dc44ceSjose borrego 		return (NDR_DRC_OK);
225589dc44ceSjose borrego 	}
225689dc44ceSjose borrego 
225789dc44ceSjose borrego 	if (param->resume_handle &&
225889dc44ceSjose borrego 	    param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) {
22591fcced4cSJordan Brown 		if (se.se_resume < se.se_ntotal) {
22601fcced4cSJordan Brown 			*param->resume_handle = se.se_resume;
226189dc44ceSjose borrego 			status = ERROR_MORE_DATA;
226289dc44ceSjose borrego 		}
226389dc44ceSjose borrego 	}
226489dc44ceSjose borrego 
22651fcced4cSJordan Brown 	param->totalentries = se.se_ntotal;
226689dc44ceSjose borrego 	param->status = status;
226789dc44ceSjose borrego 	return (NDR_DRC_OK);
226889dc44ceSjose borrego }
226989dc44ceSjose borrego 
227089dc44ceSjose borrego /*
227189dc44ceSjose borrego  * NetShareEnum Level 0
227289dc44ceSjose borrego  */
227389dc44ceSjose borrego static DWORD
mlsvc_NetShareEnumLevel0(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)22741fcced4cSJordan Brown mlsvc_NetShareEnumLevel0(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
22751fcced4cSJordan Brown     smb_svcenum_t *se, int sticky)
227689dc44ceSjose borrego {
2277eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_0 *info0;
227889dc44ceSjose borrego 	smb_shriter_t iterator;
227989dc44ceSjose borrego 	smb_share_t *si;
228089dc44ceSjose borrego 	DWORD status;
228189dc44ceSjose borrego 
22821fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
22831fcced4cSJordan Brown 	    sizeof (struct mslm_NetShareInfo_0) + MAXNAMELEN);
22841fcced4cSJordan Brown 	if (se->se_nlimit == 0)
228589dc44ceSjose borrego 		return (ERROR_SUCCESS);
228689dc44ceSjose borrego 
22871fcced4cSJordan Brown 	info0 = NDR_NEWN(mxa, struct mslm_NetShareInfo_0, se->se_nlimit);
228889dc44ceSjose borrego 	if (info0 == NULL)
228989dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
229089dc44ceSjose borrego 
229189dc44ceSjose borrego 	smb_shr_iterinit(&iterator);
229289dc44ceSjose borrego 
22931fcced4cSJordan Brown 	se->se_nitems = 0;
229489dc44ceSjose borrego 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
22951fcced4cSJordan Brown 		if (se->se_nskip > 0) {
22961fcced4cSJordan Brown 			--se->se_nskip;
229789dc44ceSjose borrego 			continue;
229889dc44ceSjose borrego 		}
229989dc44ceSjose borrego 
23001fcced4cSJordan Brown 		++se->se_resume;
230189dc44ceSjose borrego 
230289dc44ceSjose borrego 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
230389dc44ceSjose borrego 			continue;
230489dc44ceSjose borrego 
230589dc44ceSjose borrego 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
230689dc44ceSjose borrego 			continue;
230789dc44ceSjose borrego 
23081fcced4cSJordan Brown 		if (se->se_nitems >= se->se_nlimit) {
23091fcced4cSJordan Brown 			se->se_nitems = se->se_nlimit;
231089dc44ceSjose borrego 			break;
231189dc44ceSjose borrego 		}
231289dc44ceSjose borrego 
231389dc44ceSjose borrego 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info0);
231489dc44ceSjose borrego 		if (status != ERROR_SUCCESS)
231589dc44ceSjose borrego 			break;
231689dc44ceSjose borrego 
23171fcced4cSJordan Brown 		++se->se_nitems;
231889dc44ceSjose borrego 	}
231989dc44ceSjose borrego 
23201fcced4cSJordan Brown 	if (se->se_nitems < se->se_nlimit) {
232189dc44ceSjose borrego 		if (srvsvc_add_autohome(mxa, se, (void *)info0))
23221fcced4cSJordan Brown 			++se->se_nitems;
232389dc44ceSjose borrego 	}
232489dc44ceSjose borrego 
23251fcced4cSJordan Brown 	infonres->entriesread = se->se_nitems;
232689dc44ceSjose borrego 	infonres->entries = info0;
232789dc44ceSjose borrego 	return (ERROR_SUCCESS);
232889dc44ceSjose borrego }
232989dc44ceSjose borrego 
233089dc44ceSjose borrego /*
233189dc44ceSjose borrego  * NetShareEnum Level 1
233289dc44ceSjose borrego  */
233389dc44ceSjose borrego static DWORD
mlsvc_NetShareEnumLevel1(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)23341fcced4cSJordan Brown mlsvc_NetShareEnumLevel1(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
23351fcced4cSJordan Brown     smb_svcenum_t *se, int sticky)
233689dc44ceSjose borrego {
2337eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_1 *info1;
233889dc44ceSjose borrego 	smb_shriter_t iterator;
233989dc44ceSjose borrego 	smb_share_t *si;
234089dc44ceSjose borrego 	DWORD status;
234189dc44ceSjose borrego 
23421fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
23431fcced4cSJordan Brown 	    sizeof (struct mslm_NetShareInfo_1) + MAXNAMELEN);
23441fcced4cSJordan Brown 	if (se->se_nlimit == 0)
234589dc44ceSjose borrego 		return (ERROR_SUCCESS);
234689dc44ceSjose borrego 
23471fcced4cSJordan Brown 	info1 = NDR_NEWN(mxa, struct mslm_NetShareInfo_1, se->se_nlimit);
234889dc44ceSjose borrego 	if (info1 == NULL)
234989dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
235089dc44ceSjose borrego 
235189dc44ceSjose borrego 	smb_shr_iterinit(&iterator);
235289dc44ceSjose borrego 
23531fcced4cSJordan Brown 	se->se_nitems = 0;
235489dc44ceSjose borrego 	while ((si = smb_shr_iterate(&iterator)) != 0) {
23551fcced4cSJordan Brown 		if (se->se_nskip > 0) {
23561fcced4cSJordan Brown 			--se->se_nskip;
235789dc44ceSjose borrego 			continue;
235889dc44ceSjose borrego 		}
235989dc44ceSjose borrego 
23601fcced4cSJordan Brown 		++se->se_resume;
236189dc44ceSjose borrego 
236289dc44ceSjose borrego 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
236389dc44ceSjose borrego 			continue;
236489dc44ceSjose borrego 
236589dc44ceSjose borrego 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
236689dc44ceSjose borrego 			continue;
236789dc44ceSjose borrego 
23681fcced4cSJordan Brown 		if (se->se_nitems >= se->se_nlimit) {
23691fcced4cSJordan Brown 			se->se_nitems = se->se_nlimit;
237089dc44ceSjose borrego 			break;
237189dc44ceSjose borrego 		}
237289dc44ceSjose borrego 
237389dc44ceSjose borrego 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info1);
237489dc44ceSjose borrego 		if (status != ERROR_SUCCESS)
237589dc44ceSjose borrego 			break;
237689dc44ceSjose borrego 
23771fcced4cSJordan Brown 		++se->se_nitems;
237889dc44ceSjose borrego 	}
237989dc44ceSjose borrego 
23801fcced4cSJordan Brown 	if (se->se_nitems < se->se_nlimit) {
238189dc44ceSjose borrego 		if (srvsvc_add_autohome(mxa, se, (void *)info1))
23821fcced4cSJordan Brown 			++se->se_nitems;
238389dc44ceSjose borrego 	}
238489dc44ceSjose borrego 
23851fcced4cSJordan Brown 	infonres->entriesread = se->se_nitems;
238689dc44ceSjose borrego 	infonres->entries = info1;
238789dc44ceSjose borrego 	return (ERROR_SUCCESS);
238889dc44ceSjose borrego }
238989dc44ceSjose borrego 
239089dc44ceSjose borrego /*
239189dc44ceSjose borrego  * NetShareEnum Level 2
239289dc44ceSjose borrego  */
239389dc44ceSjose borrego static DWORD
mlsvc_NetShareEnumLevel2(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)23941fcced4cSJordan Brown mlsvc_NetShareEnumLevel2(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
23951fcced4cSJordan Brown     smb_svcenum_t *se, int sticky)
239689dc44ceSjose borrego {
2397eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_2 *info2;
239889dc44ceSjose borrego 	smb_shriter_t iterator;
239989dc44ceSjose borrego 	smb_share_t *si;
240089dc44ceSjose borrego 	DWORD status;
240189dc44ceSjose borrego 
24021fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
24031fcced4cSJordan Brown 	    sizeof (struct mslm_NetShareInfo_2) + MAXNAMELEN);
24041fcced4cSJordan Brown 	if (se->se_nlimit == 0)
240589dc44ceSjose borrego 		return (ERROR_SUCCESS);
240689dc44ceSjose borrego 
24071fcced4cSJordan Brown 	info2 = NDR_NEWN(mxa, struct mslm_NetShareInfo_2, se->se_nlimit);
240889dc44ceSjose borrego 	if (info2 == NULL)
240989dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
241089dc44ceSjose borrego 
241189dc44ceSjose borrego 	smb_shr_iterinit(&iterator);
241289dc44ceSjose borrego 
24131fcced4cSJordan Brown 	se->se_nitems = 0;
241489dc44ceSjose borrego 	while ((si = smb_shr_iterate(&iterator)) != 0) {
24151fcced4cSJordan Brown 		if (se->se_nskip > 0) {
24161fcced4cSJordan Brown 			--se->se_nskip;
241789dc44ceSjose borrego 			continue;
241889dc44ceSjose borrego 		}
241989dc44ceSjose borrego 
24201fcced4cSJordan Brown 		++se->se_resume;
242189dc44ceSjose borrego 
242289dc44ceSjose borrego 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
242389dc44ceSjose borrego 			continue;
242489dc44ceSjose borrego 
242589dc44ceSjose borrego 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
242689dc44ceSjose borrego 			continue;
242789dc44ceSjose borrego 
24281fcced4cSJordan Brown 		if (se->se_nitems >= se->se_nlimit) {
24291fcced4cSJordan Brown 			se->se_nitems = se->se_nlimit;
243089dc44ceSjose borrego 			break;
243189dc44ceSjose borrego 		}
243289dc44ceSjose borrego 
243389dc44ceSjose borrego 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info2);
243489dc44ceSjose borrego 		if (status != ERROR_SUCCESS)
243589dc44ceSjose borrego 			break;
243689dc44ceSjose borrego 
24371fcced4cSJordan Brown 		++se->se_nitems;
243889dc44ceSjose borrego 	}
243989dc44ceSjose borrego 
24401fcced4cSJordan Brown 	if (se->se_nitems < se->se_nlimit) {
244189dc44ceSjose borrego 		if (srvsvc_add_autohome(mxa, se, (void *)info2))
24421fcced4cSJordan Brown 			++se->se_nitems;
244389dc44ceSjose borrego 	}
244489dc44ceSjose borrego 
24451fcced4cSJordan Brown 	infonres->entriesread = se->se_nitems;
244689dc44ceSjose borrego 	infonres->entries = info2;
244789dc44ceSjose borrego 	return (ERROR_SUCCESS);
244889dc44ceSjose borrego }
244989dc44ceSjose borrego 
245089dc44ceSjose borrego /*
245189dc44ceSjose borrego  * NetShareEnum Level 501
245289dc44ceSjose borrego  */
245389dc44ceSjose borrego static DWORD
mlsvc_NetShareEnumLevel501(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)24541fcced4cSJordan Brown mlsvc_NetShareEnumLevel501(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
24551fcced4cSJordan Brown     smb_svcenum_t *se, int sticky)
245689dc44ceSjose borrego {
2457eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_501 *info501;
245889dc44ceSjose borrego 	smb_shriter_t iterator;
245989dc44ceSjose borrego 	smb_share_t *si;
246089dc44ceSjose borrego 	DWORD status;
246189dc44ceSjose borrego 
24621fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
24631fcced4cSJordan Brown 	    sizeof (struct mslm_NetShareInfo_501) + MAXNAMELEN);
24641fcced4cSJordan Brown 	if (se->se_nlimit == 0)
246589dc44ceSjose borrego 		return (ERROR_SUCCESS);
246689dc44ceSjose borrego 
2467eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	info501 = NDR_NEWN(mxa, struct mslm_NetShareInfo_501,
24681fcced4cSJordan Brown 	    se->se_nlimit);
246989dc44ceSjose borrego 	if (info501 == NULL)
247089dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
247189dc44ceSjose borrego 
247289dc44ceSjose borrego 	smb_shr_iterinit(&iterator);
247389dc44ceSjose borrego 
24741fcced4cSJordan Brown 	se->se_nitems = 0;
247589dc44ceSjose borrego 	while ((si = smb_shr_iterate(&iterator)) != 0) {
24761fcced4cSJordan Brown 		if (se->se_nskip > 0) {
24771fcced4cSJordan Brown 			--se->se_nskip;
247889dc44ceSjose borrego 			continue;
247989dc44ceSjose borrego 		}
248089dc44ceSjose borrego 
24811fcced4cSJordan Brown 		++se->se_resume;
248289dc44ceSjose borrego 
248389dc44ceSjose borrego 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
248489dc44ceSjose borrego 			continue;
248589dc44ceSjose borrego 
248689dc44ceSjose borrego 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
248789dc44ceSjose borrego 			continue;
248889dc44ceSjose borrego 
24891fcced4cSJordan Brown 		if (se->se_nitems >= se->se_nlimit) {
24901fcced4cSJordan Brown 			se->se_nitems = se->se_nlimit;
249189dc44ceSjose borrego 			break;
249289dc44ceSjose borrego 		}
249389dc44ceSjose borrego 
249489dc44ceSjose borrego 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info501);
249589dc44ceSjose borrego 		if (status != ERROR_SUCCESS)
249689dc44ceSjose borrego 			break;
249789dc44ceSjose borrego 
24981fcced4cSJordan Brown 		++se->se_nitems;
249989dc44ceSjose borrego 	}
250089dc44ceSjose borrego 
25011fcced4cSJordan Brown 	if (se->se_nitems < se->se_nlimit) {
250289dc44ceSjose borrego 		if (srvsvc_add_autohome(mxa, se, (void *)info501))
25031fcced4cSJordan Brown 			++se->se_nitems;
250489dc44ceSjose borrego 	}
250589dc44ceSjose borrego 
25061fcced4cSJordan Brown 	infonres->entriesread = se->se_nitems;
250789dc44ceSjose borrego 	infonres->entries = info501;
250889dc44ceSjose borrego 	return (ERROR_SUCCESS);
250989dc44ceSjose borrego }
251089dc44ceSjose borrego 
251189dc44ceSjose borrego /*
251289dc44ceSjose borrego  * NetShareEnum Level 502
251389dc44ceSjose borrego  */
251489dc44ceSjose borrego static DWORD
mlsvc_NetShareEnumLevel502(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)25151fcced4cSJordan Brown mlsvc_NetShareEnumLevel502(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
25161fcced4cSJordan Brown     smb_svcenum_t *se, int sticky)
251789dc44ceSjose borrego {
2518eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_502 *info502;
251989dc44ceSjose borrego 	smb_shriter_t iterator;
252089dc44ceSjose borrego 	smb_share_t *si;
252189dc44ceSjose borrego 	DWORD status;
252289dc44ceSjose borrego 
25231fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
25241fcced4cSJordan Brown 	    sizeof (struct mslm_NetShareInfo_502) + MAXNAMELEN);
25251fcced4cSJordan Brown 	if (se->se_nlimit == 0)
252689dc44ceSjose borrego 		return (ERROR_SUCCESS);
252789dc44ceSjose borrego 
2528eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	info502 = NDR_NEWN(mxa, struct mslm_NetShareInfo_502,
25291fcced4cSJordan Brown 	    se->se_nlimit);
253089dc44ceSjose borrego 	if (info502 == NULL)
253189dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
253289dc44ceSjose borrego 
253389dc44ceSjose borrego 	smb_shr_iterinit(&iterator);
253489dc44ceSjose borrego 
25351fcced4cSJordan Brown 	se->se_nitems = 0;
253689dc44ceSjose borrego 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
25371fcced4cSJordan Brown 		if (se->se_nskip > 0) {
25381fcced4cSJordan Brown 			--se->se_nskip;
253989dc44ceSjose borrego 			continue;
254089dc44ceSjose borrego 		}
254189dc44ceSjose borrego 
25421fcced4cSJordan Brown 		++se->se_resume;
254389dc44ceSjose borrego 
254489dc44ceSjose borrego 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
254589dc44ceSjose borrego 			continue;
254689dc44ceSjose borrego 
254789dc44ceSjose borrego 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
254889dc44ceSjose borrego 			continue;
254989dc44ceSjose borrego 
25501fcced4cSJordan Brown 		if (se->se_nitems >= se->se_nlimit) {
25511fcced4cSJordan Brown 			se->se_nitems = se->se_nlimit;
255289dc44ceSjose borrego 			break;
255389dc44ceSjose borrego 		}
255489dc44ceSjose borrego 
255589dc44ceSjose borrego 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info502);
255689dc44ceSjose borrego 		if (status != ERROR_SUCCESS)
255789dc44ceSjose borrego 			break;
255889dc44ceSjose borrego 
25591fcced4cSJordan Brown 		++se->se_nitems;
256089dc44ceSjose borrego 	}
256189dc44ceSjose borrego 
25621fcced4cSJordan Brown 	if (se->se_nitems < se->se_nlimit) {
256389dc44ceSjose borrego 		if (srvsvc_add_autohome(mxa, se, (void *)info502))
25641fcced4cSJordan Brown 			++se->se_nitems;
256589dc44ceSjose borrego 	}
256689dc44ceSjose borrego 
25671fcced4cSJordan Brown 	infonres->entriesread = se->se_nitems;
256889dc44ceSjose borrego 	infonres->entries = info502;
256989dc44ceSjose borrego 	return (ERROR_SUCCESS);
257089dc44ceSjose borrego }
257189dc44ceSjose borrego 
257289dc44ceSjose borrego /*
257389dc44ceSjose borrego  * mlsvc_NetShareEnumCommon
257489dc44ceSjose borrego  *
257589dc44ceSjose borrego  * Build the levels 0, 1, 2, 501 and 502 share information. This function
257689dc44ceSjose borrego  * is called by the various NetShareEnum levels for each share. If
257789dc44ceSjose borrego  * we cannot build the share data for some reason, we return an error
257889dc44ceSjose borrego  * but the actual value of the error is not important to the caller.
257989dc44ceSjose borrego  * The caller just needs to know not to include this info in the RPC
258089dc44ceSjose borrego  * response.
258189dc44ceSjose borrego  *
258289dc44ceSjose borrego  * Returns:
258389dc44ceSjose borrego  *	ERROR_SUCCESS
258489dc44ceSjose borrego  *	ERROR_NOT_ENOUGH_MEMORY
258589dc44ceSjose borrego  *	ERROR_INVALID_LEVEL
258689dc44ceSjose borrego  */
258789dc44ceSjose borrego static DWORD
mlsvc_NetShareEnumCommon(ndr_xa_t * mxa,smb_svcenum_t * se,smb_share_t * si,void * infop)25881fcced4cSJordan Brown mlsvc_NetShareEnumCommon(ndr_xa_t *mxa, smb_svcenum_t *se,
258989dc44ceSjose borrego     smb_share_t *si, void *infop)
259089dc44ceSjose borrego {
2591eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_0 *info0;
2592eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_1 *info1;
2593eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_2 *info2;
2594eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_501 *info501;
2595eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_502 *info502;
259629bd2886SAlan Wright 	srvsvc_sd_t sd;
259729bd2886SAlan Wright 	uint8_t *netname;
259829bd2886SAlan Wright 	uint8_t *comment;
259929bd2886SAlan Wright 	uint8_t *passwd;
260029bd2886SAlan Wright 	uint8_t *path;
26011fcced4cSJordan Brown 	int i = se->se_nitems;
260289dc44ceSjose borrego 
260329bd2886SAlan Wright 	netname = (uint8_t *)NDR_STRDUP(mxa, si->shr_name);
260429bd2886SAlan Wright 	comment = (uint8_t *)NDR_STRDUP(mxa, si->shr_cmnt);
260529bd2886SAlan Wright 	passwd = (uint8_t *)NDR_STRDUP(mxa, empty_string);
260629bd2886SAlan Wright 	path = (uint8_t *)srvsvc_share_mkpath(mxa, si->shr_path);
260729bd2886SAlan Wright 
260829bd2886SAlan Wright 	if (!netname || !comment || !passwd || !path)
260929bd2886SAlan Wright 		return (ERROR_NOT_ENOUGH_MEMORY);
261029bd2886SAlan Wright 
261189dc44ceSjose borrego 	switch (se->se_level) {
261289dc44ceSjose borrego 	case 0:
2613eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		info0 = (struct mslm_NetShareInfo_0 *)infop;
261429bd2886SAlan Wright 		info0[i].shi0_netname = netname;
261589dc44ceSjose borrego 		break;
261689dc44ceSjose borrego 
261789dc44ceSjose borrego 	case 1:
2618eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		info1 = (struct mslm_NetShareInfo_1 *)infop;
261929bd2886SAlan Wright 		info1[i].shi1_netname = netname;
262029bd2886SAlan Wright 		info1[i].shi1_comment = comment;
262189dc44ceSjose borrego 		info1[i].shi1_type = si->shr_type;
262289dc44ceSjose borrego 		break;
262389dc44ceSjose borrego 
262489dc44ceSjose borrego 	case 2:
2625eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		info2 = (struct mslm_NetShareInfo_2 *)infop;
262629bd2886SAlan Wright 		info2[i].shi2_netname = netname;
262729bd2886SAlan Wright 		info2[i].shi2_comment = comment;
262829bd2886SAlan Wright 		info2[i].shi2_path = path;
262989dc44ceSjose borrego 		info2[i].shi2_type = si->shr_type;
263089dc44ceSjose borrego 		info2[i].shi2_permissions = 0;
263189dc44ceSjose borrego 		info2[i].shi2_max_uses = SHI_USES_UNLIMITED;
263289dc44ceSjose borrego 		info2[i].shi2_current_uses = 0;
263329bd2886SAlan Wright 		info2[i].shi2_passwd = passwd;
263489dc44ceSjose borrego 		break;
263589dc44ceSjose borrego 
263689dc44ceSjose borrego 	case 501:
2637eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		info501 = (struct mslm_NetShareInfo_501 *)infop;
263829bd2886SAlan Wright 		info501[i].shi501_netname = netname;
263929bd2886SAlan Wright 		info501[i].shi501_comment = comment;
264089dc44ceSjose borrego 		info501[i].shi501_type = si->shr_type;
2641e3f2c991SKeyur Desai 		info501[i].shi501_flags = srvsvc_get_share_flags(si);
264289dc44ceSjose borrego 		break;
264389dc44ceSjose borrego 
264489dc44ceSjose borrego 	case 502:
2645eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		info502 = (struct mslm_NetShareInfo_502 *)infop;
264629bd2886SAlan Wright 		info502[i].shi502_netname = netname;
264729bd2886SAlan Wright 		info502[i].shi502_comment = comment;
264829bd2886SAlan Wright 		info502[i].shi502_path = path;
264989dc44ceSjose borrego 		info502[i].shi502_type = si->shr_type;
265089dc44ceSjose borrego 		info502[i].shi502_permissions = 0;
265189dc44ceSjose borrego 		info502[i].shi502_max_uses = SHI_USES_UNLIMITED;
265289dc44ceSjose borrego 		info502[i].shi502_current_uses = 0;
265329bd2886SAlan Wright 		info502[i].shi502_passwd = passwd;
265489dc44ceSjose borrego 
265529bd2886SAlan Wright 		if (srvsvc_share_getsd(mxa, si, &sd) == ERROR_SUCCESS) {
265629bd2886SAlan Wright 			info502[i].shi502_reserved = sd.sd_size;
265729bd2886SAlan Wright 			info502[i].shi502_security_descriptor = sd.sd_buf;
265829bd2886SAlan Wright 		} else {
265989dc44ceSjose borrego 			info502[i].shi502_reserved = 0;
266029bd2886SAlan Wright 			info502[i].shi502_security_descriptor = NULL;
266129bd2886SAlan Wright 		}
266289dc44ceSjose borrego 
266389dc44ceSjose borrego 		break;
266489dc44ceSjose borrego 
266589dc44ceSjose borrego 	default:
266689dc44ceSjose borrego 		return (ERROR_INVALID_LEVEL);
266789dc44ceSjose borrego 	}
266889dc44ceSjose borrego 
266989dc44ceSjose borrego 	return (ERROR_SUCCESS);
267089dc44ceSjose borrego }
267189dc44ceSjose borrego 
267289dc44ceSjose borrego /*
267389dc44ceSjose borrego  * srvsvc_add_autohome
267489dc44ceSjose borrego  *
267589dc44ceSjose borrego  * Add the autohome share for the user. The share must not be a permanent
267689dc44ceSjose borrego  * share to avoid duplicates.
267789dc44ceSjose borrego  */
267889dc44ceSjose borrego static boolean_t
srvsvc_add_autohome(ndr_xa_t * mxa,smb_svcenum_t * se,void * infop)26791fcced4cSJordan Brown srvsvc_add_autohome(ndr_xa_t *mxa, smb_svcenum_t *se, void *infop)
268089dc44ceSjose borrego {
2681*cf115f36SGordon Ross 	smb_netuserinfo_t *user = mxa->pipe->np_user;
2682c5866007SKeyur Desai 	char *username;
268389dc44ceSjose borrego 	smb_share_t si;
268489dc44ceSjose borrego 	DWORD status;
2685c5866007SKeyur Desai 	struct passwd pw;
2686c5866007SKeyur Desai 	char buf[NSS_LINELEN_PASSWD];
2687c5866007SKeyur Desai 
2688c5866007SKeyur Desai 	if (IDMAP_ID_IS_EPHEMERAL(user->ui_posix_uid)) {
2689c5866007SKeyur Desai 		username = user->ui_account;
2690c5866007SKeyur Desai 	} else {
2691c5866007SKeyur Desai 		if (getpwuid_r(user->ui_posix_uid, &pw, buf, sizeof (buf)) ==
2692c5866007SKeyur Desai 		    NULL)
2693c5866007SKeyur Desai 			return (B_FALSE);
2694c5866007SKeyur Desai 
2695c5866007SKeyur Desai 		username = pw.pw_name;
2696c5866007SKeyur Desai 	}
269789dc44ceSjose borrego 
269889dc44ceSjose borrego 	if (smb_shr_get(username, &si) != NERR_Success)
269989dc44ceSjose borrego 		return (B_FALSE);
270089dc44ceSjose borrego 
270189dc44ceSjose borrego 	if ((si.shr_flags & SMB_SHRF_AUTOHOME) == 0)
270289dc44ceSjose borrego 		return (B_FALSE);
270389dc44ceSjose borrego 
270489dc44ceSjose borrego 	status = mlsvc_NetShareEnumCommon(mxa, se, &si, infop);
270589dc44ceSjose borrego 	return (status == ERROR_SUCCESS);
270689dc44ceSjose borrego }
270789dc44ceSjose borrego 
270889dc44ceSjose borrego /*
270989dc44ceSjose borrego  * srvsvc_share_mkpath
271089dc44ceSjose borrego  *
271189dc44ceSjose borrego  * Create the share path required by the share enum calls. The path
271289dc44ceSjose borrego  * is created in a heap buffer ready for use by the caller.
271389dc44ceSjose borrego  *
271489dc44ceSjose borrego  * Some Windows over-the-wire backup applications do not work unless a
271589dc44ceSjose borrego  * drive letter is present in the share path.  We don't care about the
271689dc44ceSjose borrego  * drive letter since the path is fully qualified with the volume name.
271789dc44ceSjose borrego  *
271889dc44ceSjose borrego  * Windows clients seem to be mostly okay with forward slashes in
271989dc44ceSjose borrego  * share paths but they cannot handle one immediately after the drive
272089dc44ceSjose borrego  * letter, i.e. B:/.  For consistency we convert all the slashes in
272189dc44ceSjose borrego  * the path.
272289dc44ceSjose borrego  *
272389dc44ceSjose borrego  * Returns a pointer to a heap buffer containing the share path, which
272489dc44ceSjose borrego  * could be a null pointer if the heap allocation fails.
272589dc44ceSjose borrego  */
272689dc44ceSjose borrego static char *
srvsvc_share_mkpath(ndr_xa_t * mxa,char * path)272789dc44ceSjose borrego srvsvc_share_mkpath(ndr_xa_t *mxa, char *path)
272889dc44ceSjose borrego {
272989dc44ceSjose borrego 	char tmpbuf[MAXPATHLEN];
273089dc44ceSjose borrego 	char *p;
2731c5866007SKeyur Desai 	char drive_letter;
273289dc44ceSjose borrego 
273389dc44ceSjose borrego 	if (strlen(path) == 0)
273489dc44ceSjose borrego 		return (NDR_STRDUP(mxa, path));
273589dc44ceSjose borrego 
2736c5866007SKeyur Desai 	drive_letter = smb_shr_drive_letter(path);
2737c5866007SKeyur Desai 	if (drive_letter != '\0') {
2738c5866007SKeyur Desai 		(void) snprintf(tmpbuf, MAXPATHLEN, "%c:\\", drive_letter);
2739c5866007SKeyur Desai 		return (NDR_STRDUP(mxa, tmpbuf));
2740c5866007SKeyur Desai 	}
2741c5866007SKeyur Desai 
274289dc44ceSjose borrego 	/*
274389dc44ceSjose borrego 	 * Strip the volume name from the path (/vol1/home -> /home).
274489dc44ceSjose borrego 	 */
274589dc44ceSjose borrego 	p = path;
274689dc44ceSjose borrego 	p += strspn(p, "/");
274789dc44ceSjose borrego 	p += strcspn(p, "/");
274889dc44ceSjose borrego 	p += strspn(p, "/");
274989dc44ceSjose borrego 	(void) snprintf(tmpbuf, MAXPATHLEN, "%c:/%s", 'B', p);
275089dc44ceSjose borrego 	(void) strsubst(tmpbuf, '/', '\\');
275189dc44ceSjose borrego 
275289dc44ceSjose borrego 	return (NDR_STRDUP(mxa, tmpbuf));
275389dc44ceSjose borrego }
275489dc44ceSjose borrego 
275529bd2886SAlan Wright static int
srvsvc_s_NetShareCheck(void * arg,ndr_xa_t * mxa)275629bd2886SAlan Wright srvsvc_s_NetShareCheck(void *arg, ndr_xa_t *mxa)
275729bd2886SAlan Wright {
275829bd2886SAlan Wright 	struct mslm_NetShareCheck *param = arg;
275929bd2886SAlan Wright 	smb_shriter_t iterator;
276029bd2886SAlan Wright 	smb_share_t *si;
276129bd2886SAlan Wright 	char *path;
276229bd2886SAlan Wright 
276329bd2886SAlan Wright 	if (param->path == NULL) {
276429bd2886SAlan Wright 		param->stype = STYPE_DISKTREE;
276529bd2886SAlan Wright 		param->status = NERR_NetNameNotFound;
276629bd2886SAlan Wright 		return (NDR_DRC_OK);
276729bd2886SAlan Wright 	}
276829bd2886SAlan Wright 
276929bd2886SAlan Wright 	(void) strsubst((char *)param->path, '/', '\\');
277029bd2886SAlan Wright 
277129bd2886SAlan Wright 	smb_shr_iterinit(&iterator);
277229bd2886SAlan Wright 
277329bd2886SAlan Wright 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
277429bd2886SAlan Wright 		path = srvsvc_share_mkpath(mxa, si->shr_path);
277529bd2886SAlan Wright 
2776bbf6f00cSJordan Brown 		if (smb_strcasecmp(path, (char *)param->path, 0) == 0) {
277729bd2886SAlan Wright 			param->stype = (si->shr_type & STYPE_MASK);
277829bd2886SAlan Wright 			param->status = NERR_Success;
277929bd2886SAlan Wright 			return (NDR_DRC_OK);
278029bd2886SAlan Wright 		}
278129bd2886SAlan Wright 	}
278229bd2886SAlan Wright 
278329bd2886SAlan Wright 	param->stype = STYPE_DISKTREE;
278429bd2886SAlan Wright 	param->status = NERR_NetNameNotFound;
278529bd2886SAlan Wright 	return (NDR_DRC_OK);
278629bd2886SAlan Wright }
278729bd2886SAlan Wright 
278889dc44ceSjose borrego /*
27891fcced4cSJordan Brown  * Delete a share.  Only members of the Administrators, Server Operators
27901fcced4cSJordan Brown  * or Power Users local groups are allowed to delete shares.
279189dc44ceSjose borrego  *
279289dc44ceSjose borrego  * This interface is used by the rmtshare command from the NT resource
279389dc44ceSjose borrego  * kit. Rmtshare allows a client to add or remove shares on a server
279489dc44ceSjose borrego  * from the client's command line.
279589dc44ceSjose borrego  *
279689dc44ceSjose borrego  * Returns Win32 error codes.
279789dc44ceSjose borrego  */
279889dc44ceSjose borrego static int
srvsvc_s_NetShareDel(void * arg,ndr_xa_t * mxa)279989dc44ceSjose borrego srvsvc_s_NetShareDel(void *arg, ndr_xa_t *mxa)
280089dc44ceSjose borrego {
280189dc44ceSjose borrego 	struct mslm_NetShareDel *param = arg;
28029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_share_t si;
280389dc44ceSjose borrego 
280489dc44ceSjose borrego 	if (!ndr_is_poweruser(mxa) ||
280589dc44ceSjose borrego 	    smb_shr_is_restricted((char *)param->netname)) {
280689dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
280789dc44ceSjose borrego 		return (NDR_DRC_OK);
280889dc44ceSjose borrego 	}
280989dc44ceSjose borrego 
28109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_shr_get((char *)param->netname, &si) == NERR_Success) {
28119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (si.shr_flags & SMB_SHRF_DFSROOT) {
28129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			param->status = NERR_IsDfsShare;
28139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (NDR_DRC_OK);
28149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
28159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
28169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
281789dc44ceSjose borrego 	param->status = srvsvc_sa_delete((char *)param->netname);
281889dc44ceSjose borrego 	return (NDR_DRC_OK);
281989dc44ceSjose borrego }
282089dc44ceSjose borrego 
282189dc44ceSjose borrego /*
282289dc44ceSjose borrego  * srvsvc_s_NetGetFileSecurity
282389dc44ceSjose borrego  *
282489dc44ceSjose borrego  * Get security descriptor of the requested file/folder
282589dc44ceSjose borrego  *
282689dc44ceSjose borrego  * Right now, just returns ERROR_ACCESS_DENIED, because we cannot
282789dc44ceSjose borrego  * get the requested SD here in RPC code.
282889dc44ceSjose borrego  */
282989dc44ceSjose borrego /*ARGSUSED*/
283089dc44ceSjose borrego static int
srvsvc_s_NetGetFileSecurity(void * arg,ndr_xa_t * mxa)283189dc44ceSjose borrego srvsvc_s_NetGetFileSecurity(void *arg, ndr_xa_t *mxa)
283289dc44ceSjose borrego {
283389dc44ceSjose borrego 	struct mslm_NetGetFileSecurity *param = arg;
283489dc44ceSjose borrego 
283589dc44ceSjose borrego 	param->length = 0;
283689dc44ceSjose borrego 	param->status = ERROR_ACCESS_DENIED;
283789dc44ceSjose borrego 	return (NDR_DRC_OK);
283889dc44ceSjose borrego }
283989dc44ceSjose borrego 
284089dc44ceSjose borrego /*
284189dc44ceSjose borrego  * srvsvc_s_NetSetFileSecurity
284289dc44ceSjose borrego  *
284389dc44ceSjose borrego  * Set the given security descriptor for the requested file/folder
284489dc44ceSjose borrego  *
284589dc44ceSjose borrego  * Right now, just returns ERROR_ACCESS_DENIED, because we cannot
284689dc44ceSjose borrego  * set the requested SD here in RPC code.
284789dc44ceSjose borrego  */
284889dc44ceSjose borrego /*ARGSUSED*/
284989dc44ceSjose borrego static int
srvsvc_s_NetSetFileSecurity(void * arg,ndr_xa_t * mxa)285089dc44ceSjose borrego srvsvc_s_NetSetFileSecurity(void *arg, ndr_xa_t *mxa)
285189dc44ceSjose borrego {
285289dc44ceSjose borrego 	struct mslm_NetSetFileSecurity *param = arg;
285389dc44ceSjose borrego 
285489dc44ceSjose borrego 	param->status = ERROR_ACCESS_DENIED;
285589dc44ceSjose borrego 	return (NDR_DRC_OK);
285689dc44ceSjose borrego }
285789dc44ceSjose borrego 
285889dc44ceSjose borrego /*
285989dc44ceSjose borrego  * If the default "smb" share group exists then return the group
286089dc44ceSjose borrego  * handle, otherwise create the group and return the handle.
286189dc44ceSjose borrego  *
286289dc44ceSjose borrego  * All shares created via the srvsvc will be added to the "smb"
286389dc44ceSjose borrego  * group.
286489dc44ceSjose borrego  */
286589dc44ceSjose borrego static sa_group_t
srvsvc_sa_get_smbgrp(sa_handle_t handle)286689dc44ceSjose borrego srvsvc_sa_get_smbgrp(sa_handle_t handle)
286789dc44ceSjose borrego {
286889dc44ceSjose borrego 	sa_group_t group = NULL;
286989dc44ceSjose borrego 	int err;
287089dc44ceSjose borrego 
287189dc44ceSjose borrego 	group = sa_get_group(handle, SMB_DEFAULT_SHARE_GROUP);
287289dc44ceSjose borrego 	if (group != NULL)
287389dc44ceSjose borrego 		return (group);
287489dc44ceSjose borrego 
287589dc44ceSjose borrego 	group = sa_create_group(handle, SMB_DEFAULT_SHARE_GROUP, &err);
287689dc44ceSjose borrego 	if (group == NULL)
287789dc44ceSjose borrego 		return (NULL);
287889dc44ceSjose borrego 
287989dc44ceSjose borrego 	if (sa_create_optionset(group, SMB_DEFAULT_SHARE_GROUP) == NULL) {
288089dc44ceSjose borrego 		(void) sa_remove_group(group);
288189dc44ceSjose borrego 		group = NULL;
288289dc44ceSjose borrego 	}
288389dc44ceSjose borrego 
288489dc44ceSjose borrego 	return (group);
288589dc44ceSjose borrego }
288689dc44ceSjose borrego 
288789dc44ceSjose borrego /*
288889dc44ceSjose borrego  * Stores the given share in sharemgr
288989dc44ceSjose borrego  */
289089dc44ceSjose borrego static uint32_t
srvsvc_sa_add(char * sharename,char * path,char * cmnt)289189dc44ceSjose borrego srvsvc_sa_add(char *sharename, char *path, char *cmnt)
289289dc44ceSjose borrego {
289389dc44ceSjose borrego 	sa_handle_t handle;
289489dc44ceSjose borrego 	sa_share_t share;
289589dc44ceSjose borrego 	sa_group_t group;
289689dc44ceSjose borrego 	sa_resource_t resource;
289789dc44ceSjose borrego 	boolean_t new_share = B_FALSE;
289889dc44ceSjose borrego 	uint32_t status = NERR_Success;
289989dc44ceSjose borrego 	int err;
290089dc44ceSjose borrego 
290189dc44ceSjose borrego 	if ((handle = smb_shr_sa_enter()) == NULL)
290289dc44ceSjose borrego 		return (NERR_InternalError);
290389dc44ceSjose borrego 
290489dc44ceSjose borrego 	share = sa_find_share(handle, path);
290589dc44ceSjose borrego 	if (share == NULL) {
290689dc44ceSjose borrego 		group = srvsvc_sa_get_smbgrp(handle);
290789dc44ceSjose borrego 		if (group == NULL) {
290889dc44ceSjose borrego 			smb_shr_sa_exit();
290989dc44ceSjose borrego 			return (NERR_InternalError);
291089dc44ceSjose borrego 		}
291189dc44ceSjose borrego 
291289dc44ceSjose borrego 		share = sa_add_share(group, path, SA_SHARE_PERMANENT, &err);
291389dc44ceSjose borrego 		if (share == NULL) {
291489dc44ceSjose borrego 			smb_shr_sa_exit();
291589dc44ceSjose borrego 			return (NERR_InternalError);
291689dc44ceSjose borrego 		}
291789dc44ceSjose borrego 		new_share = B_TRUE;
291889dc44ceSjose borrego 	}
291989dc44ceSjose borrego 
292089dc44ceSjose borrego 	resource = sa_get_share_resource(share, sharename);
292189dc44ceSjose borrego 	if (resource == NULL) {
292289dc44ceSjose borrego 		resource = sa_add_resource(share, sharename,
292389dc44ceSjose borrego 		    SA_SHARE_PERMANENT, &err);
292489dc44ceSjose borrego 		if (resource == NULL) {
292589dc44ceSjose borrego 			if (new_share)
292689dc44ceSjose borrego 				(void) sa_remove_share(share);
292789dc44ceSjose borrego 			smb_shr_sa_exit();
292889dc44ceSjose borrego 			return (NERR_InternalError);
292989dc44ceSjose borrego 		}
293089dc44ceSjose borrego 	}
293189dc44ceSjose borrego 
293289dc44ceSjose borrego 	(void) sa_set_resource_description(resource, cmnt);
293389dc44ceSjose borrego 
293489dc44ceSjose borrego 	smb_shr_sa_exit();
293589dc44ceSjose borrego 	return (status);
293689dc44ceSjose borrego }
293789dc44ceSjose borrego 
293889dc44ceSjose borrego /*
293989dc44ceSjose borrego  * Removes the share from sharemgr
294089dc44ceSjose borrego  */
294189dc44ceSjose borrego static uint32_t
srvsvc_sa_delete(char * sharename)294289dc44ceSjose borrego srvsvc_sa_delete(char *sharename)
294389dc44ceSjose borrego {
294489dc44ceSjose borrego 	sa_handle_t handle;
294589dc44ceSjose borrego 	sa_resource_t resource;
294689dc44ceSjose borrego 	uint32_t status;
294789dc44ceSjose borrego 
294889dc44ceSjose borrego 	if ((handle = smb_shr_sa_enter()) == NULL)
294989dc44ceSjose borrego 		return (NERR_InternalError);
295089dc44ceSjose borrego 
295189dc44ceSjose borrego 	status = NERR_InternalError;
295289dc44ceSjose borrego 	if ((resource = sa_find_resource(handle, sharename)) != NULL) {
295389dc44ceSjose borrego 		if (sa_remove_resource(resource) == SA_OK)
295489dc44ceSjose borrego 			status = NERR_Success;
295589dc44ceSjose borrego 	}
295689dc44ceSjose borrego 
295789dc44ceSjose borrego 	smb_shr_sa_exit();
295889dc44ceSjose borrego 	return (status);
295989dc44ceSjose borrego }
296089dc44ceSjose borrego 
296129bd2886SAlan Wright /*
296229bd2886SAlan Wright  * Update the share information.
296329bd2886SAlan Wright  */
296429bd2886SAlan Wright static uint32_t
srvsvc_sa_modify(smb_share_t * si,srvsvc_netshare_setinfo_t * info)296529bd2886SAlan Wright srvsvc_sa_modify(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
296629bd2886SAlan Wright {
296729bd2886SAlan Wright 	sa_handle_t handle;
296829bd2886SAlan Wright 	sa_share_t share;
296929bd2886SAlan Wright 	sa_resource_t resource;
2970148c5f43SAlan Wright 	boolean_t renamed = B_FALSE, is_zfs = B_FALSE;
2971148c5f43SAlan Wright 	nvlist_t *nvl;
297229bd2886SAlan Wright 	uint32_t nerr = NERR_Success;
297329bd2886SAlan Wright 
297429bd2886SAlan Wright 	if ((handle = smb_shr_sa_enter()) == NULL)
297529bd2886SAlan Wright 		return (NERR_InternalError);
297629bd2886SAlan Wright 
297729bd2886SAlan Wright 	if ((share = sa_find_share(handle, si->shr_path)) == NULL) {
297829bd2886SAlan Wright 		smb_shr_sa_exit();
297929bd2886SAlan Wright 		return (NERR_InternalError);
298029bd2886SAlan Wright 	}
298129bd2886SAlan Wright 
298229bd2886SAlan Wright 	if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) {
298329bd2886SAlan Wright 		smb_shr_sa_exit();
298429bd2886SAlan Wright 		return (NERR_InternalError);
298529bd2886SAlan Wright 	}
298629bd2886SAlan Wright 
2987148c5f43SAlan Wright 	if (sa_group_is_zfs(sa_get_parent_group(share))) {
2988148c5f43SAlan Wright 		is_zfs = B_TRUE;
2989148c5f43SAlan Wright 		if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
2990148c5f43SAlan Wright 			smb_shr_sa_exit();
2991148c5f43SAlan Wright 			return (NERR_InternalError);
2992148c5f43SAlan Wright 		}
2993148c5f43SAlan Wright 	}
2994148c5f43SAlan Wright 
299529bd2886SAlan Wright 	if (info->nss_netname != NULL && info->nss_netname[0] != '\0' &&
2996bbf6f00cSJordan Brown 	    smb_strcasecmp(info->nss_netname, si->shr_name, 0) != 0) {
2997148c5f43SAlan Wright 		if (is_zfs)
2998148c5f43SAlan Wright 			(void) nvlist_add_string(nvl, SHOPT_NAME,
2999148c5f43SAlan Wright 			    info->nss_netname);
3000148c5f43SAlan Wright 		else
300129bd2886SAlan Wright 			(void) sa_set_resource_attr(resource, SHOPT_NAME,
300229bd2886SAlan Wright 			    info->nss_netname);
300329bd2886SAlan Wright 		renamed = B_TRUE;
300429bd2886SAlan Wright 	}
300529bd2886SAlan Wright 
300629bd2886SAlan Wright 	if ((info->nss_comment != NULL) &&
300729bd2886SAlan Wright 	    (strcmp(info->nss_comment, si->shr_cmnt) != 0)) {
3008148c5f43SAlan Wright 		if (is_zfs)
3009148c5f43SAlan Wright 			(void) nvlist_add_string(nvl, SHOPT_DESCRIPTION,
3010148c5f43SAlan Wright 			    info->nss_comment);
3011148c5f43SAlan Wright 		else
3012148c5f43SAlan Wright 			(void) sa_set_resource_description(resource,
3013148c5f43SAlan Wright 			    info->nss_comment);
301429bd2886SAlan Wright 		(void) strlcpy(si->shr_cmnt, info->nss_comment,
301529bd2886SAlan Wright 		    SMB_SHARE_CMNT_MAX);
301629bd2886SAlan Wright 	}
301729bd2886SAlan Wright 
3018148c5f43SAlan Wright 	if (is_zfs) {
3019148c5f43SAlan Wright 		if (sa_zfs_setprop(handle, si->shr_path, nvl) != 0) {
3020148c5f43SAlan Wright 			smb_shr_sa_exit();
3021148c5f43SAlan Wright 			nvlist_free(nvl);
3022148c5f43SAlan Wright 			return (NERR_InternalError);
3023148c5f43SAlan Wright 		}
3024148c5f43SAlan Wright 		nvlist_free(nvl);
3025148c5f43SAlan Wright 	}
302629bd2886SAlan Wright 	smb_shr_sa_exit();
302729bd2886SAlan Wright 
302829bd2886SAlan Wright 	if (renamed) {
302929bd2886SAlan Wright 		nerr = smb_shr_rename(si->shr_name, info->nss_netname);
303029bd2886SAlan Wright 		if (nerr != NERR_Success)
303129bd2886SAlan Wright 			return (nerr);
303229bd2886SAlan Wright 
303329bd2886SAlan Wright 		(void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN);
303429bd2886SAlan Wright 	}
303529bd2886SAlan Wright 
303629bd2886SAlan Wright 	return (nerr);
303729bd2886SAlan Wright }
303829bd2886SAlan Wright 
303929bd2886SAlan Wright /*
3040148c5f43SAlan Wright  * Sets the share properties.
3041e3f2c991SKeyur Desai  *
3042148c5f43SAlan Wright  * This method sets share properties. If its a ZFS share, then properties
3043148c5f43SAlan Wright  * are set by calling the sa_zfs_setprop method. Else the optionset properties
3044148c5f43SAlan Wright  * of the share resource are set.The properties to be set are given as a list
3045148c5f43SAlan Wright  * of name-value pair.
304629bd2886SAlan Wright  */
304729bd2886SAlan Wright static uint32_t
srvsvc_sa_setprop(smb_share_t * si,nvlist_t * nvl)3048e3f2c991SKeyur Desai srvsvc_sa_setprop(smb_share_t *si, nvlist_t *nvl)
304929bd2886SAlan Wright {
305029bd2886SAlan Wright 	sa_handle_t handle;
305129bd2886SAlan Wright 	sa_share_t share;
305229bd2886SAlan Wright 	sa_resource_t resource;
3053e3f2c991SKeyur Desai 	sa_property_t prop;
3054e3f2c991SKeyur Desai 	sa_optionset_t opts;
3055e3f2c991SKeyur Desai 	uint32_t nerr = NERR_Success;
3056e3f2c991SKeyur Desai 	nvpair_t *cur;
3057e3f2c991SKeyur Desai 	int err = 0;
3058e3f2c991SKeyur Desai 	char *name, *val;
305929bd2886SAlan Wright 
30609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((handle = sa_init(SA_INIT_SHARE_API)) == NULL)
306129bd2886SAlan Wright 		return (NERR_InternalError);
306229bd2886SAlan Wright 
306329bd2886SAlan Wright 	if ((share = sa_find_share(handle, si->shr_path)) == NULL) {
30649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sa_fini(handle);
306529bd2886SAlan Wright 		return (NERR_InternalError);
306629bd2886SAlan Wright 	}
306729bd2886SAlan Wright 
306829bd2886SAlan Wright 	if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) {
30699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sa_fini(handle);
307029bd2886SAlan Wright 		return (NERR_InternalError);
307129bd2886SAlan Wright 	}
307229bd2886SAlan Wright 
3073148c5f43SAlan Wright 	if (sa_group_is_zfs(sa_get_parent_group(share))) {
3074148c5f43SAlan Wright 		if (sa_zfs_setprop(handle, si->shr_path, nvl) != 0)
3075148c5f43SAlan Wright 			nerr = NERR_InternalError;
3076148c5f43SAlan Wright 		sa_fini(handle);
3077148c5f43SAlan Wright 		return (nerr);
3078148c5f43SAlan Wright 	}
3079148c5f43SAlan Wright 
3080e3f2c991SKeyur Desai 	if ((opts = sa_get_optionset(resource, SMB_PROTOCOL_NAME)) == NULL) {
3081e3f2c991SKeyur Desai 		opts = sa_create_optionset(resource, SMB_PROTOCOL_NAME);
3082e3f2c991SKeyur Desai 		if (opts == NULL) {
30839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			sa_fini(handle);
308429bd2886SAlan Wright 			return (NERR_InternalError);
308529bd2886SAlan Wright 		}
308629bd2886SAlan Wright 	}
308729bd2886SAlan Wright 
3088e3f2c991SKeyur Desai 	cur = nvlist_next_nvpair(nvl, NULL);
3089e3f2c991SKeyur Desai 	while (cur != NULL) {
3090e3f2c991SKeyur Desai 		name = nvpair_name(cur);
3091e3f2c991SKeyur Desai 		err = nvpair_value_string(cur, &val);
3092e3f2c991SKeyur Desai 		if ((err != 0) || (name == NULL) || (val == NULL)) {
3093e3f2c991SKeyur Desai 			nerr = NERR_InternalError;
3094e3f2c991SKeyur Desai 			break;
3095e3f2c991SKeyur Desai 		}
3096e3f2c991SKeyur Desai 
3097e3f2c991SKeyur Desai 		prop = NULL;
3098e3f2c991SKeyur Desai 		if ((prop = sa_get_property(opts, name)) == NULL) {
3099e3f2c991SKeyur Desai 			prop = sa_create_property(name, val);
3100e3f2c991SKeyur Desai 			if (prop != NULL) {
3101e3f2c991SKeyur Desai 				nerr = sa_valid_property(handle, opts,
3102e3f2c991SKeyur Desai 				    SMB_PROTOCOL_NAME, prop);
3103e3f2c991SKeyur Desai 				if (nerr != NERR_Success) {
3104e3f2c991SKeyur Desai 					(void) sa_remove_property(prop);
3105e3f2c991SKeyur Desai 					break;
3106e3f2c991SKeyur Desai 				}
3107e3f2c991SKeyur Desai 			}
3108e3f2c991SKeyur Desai 			nerr = sa_add_property(opts, prop);
3109e3f2c991SKeyur Desai 			if (nerr != NERR_Success)
3110e3f2c991SKeyur Desai 				break;
3111e3f2c991SKeyur Desai 		} else {
3112e3f2c991SKeyur Desai 			nerr = sa_update_property(prop, val);
3113e3f2c991SKeyur Desai 			if (nerr != NERR_Success)
3114e3f2c991SKeyur Desai 				break;
3115e3f2c991SKeyur Desai 		}
3116e3f2c991SKeyur Desai 
3117e3f2c991SKeyur Desai 		cur = nvlist_next_nvpair(nvl, cur);
3118e3f2c991SKeyur Desai 	}
3119e3f2c991SKeyur Desai 
3120e3f2c991SKeyur Desai 	if (nerr == NERR_Success)
3121e3f2c991SKeyur Desai 		nerr = sa_commit_properties(opts, 0);
3122e3f2c991SKeyur Desai 
31239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sa_fini(handle);
3124e3f2c991SKeyur Desai 	return (nerr);
3125e3f2c991SKeyur Desai }
3126e3f2c991SKeyur Desai 
312789dc44ceSjose borrego static ndr_stub_table_t srvsvc_stub_table[] = {
312889dc44ceSjose borrego 	{ srvsvc_s_NetConnectEnum,	SRVSVC_OPNUM_NetConnectEnum },
312989dc44ceSjose borrego 	{ srvsvc_s_NetFileEnum,		SRVSVC_OPNUM_NetFileEnum },
313089dc44ceSjose borrego 	{ srvsvc_s_NetFileClose,	SRVSVC_OPNUM_NetFileClose },
313189dc44ceSjose borrego 	{ srvsvc_s_NetShareGetInfo,	SRVSVC_OPNUM_NetShareGetInfo },
313289dc44ceSjose borrego 	{ srvsvc_s_NetShareSetInfo,	SRVSVC_OPNUM_NetShareSetInfo },
313389dc44ceSjose borrego 	{ srvsvc_s_NetSessionEnum,	SRVSVC_OPNUM_NetSessionEnum },
313489dc44ceSjose borrego 	{ srvsvc_s_NetSessionDel,	SRVSVC_OPNUM_NetSessionDel },
313589dc44ceSjose borrego 	{ srvsvc_s_NetServerGetInfo,	SRVSVC_OPNUM_NetServerGetInfo },
313689dc44ceSjose borrego 	{ srvsvc_s_NetRemoteTOD,	SRVSVC_OPNUM_NetRemoteTOD },
313789dc44ceSjose borrego 	{ srvsvc_s_NetNameValidate,	SRVSVC_OPNUM_NetNameValidate },
313889dc44ceSjose borrego 	{ srvsvc_s_NetShareAdd,		SRVSVC_OPNUM_NetShareAdd },
313989dc44ceSjose borrego 	{ srvsvc_s_NetShareDel,		SRVSVC_OPNUM_NetShareDel },
314089dc44ceSjose borrego 	{ srvsvc_s_NetShareEnum,	SRVSVC_OPNUM_NetShareEnum },
314189dc44ceSjose borrego 	{ srvsvc_s_NetShareEnumSticky,	SRVSVC_OPNUM_NetShareEnumSticky },
314229bd2886SAlan Wright 	{ srvsvc_s_NetShareCheck,	SRVSVC_OPNUM_NetShareCheck },
314389dc44ceSjose borrego 	{ srvsvc_s_NetGetFileSecurity,	SRVSVC_OPNUM_NetGetFileSecurity },
314489dc44ceSjose borrego 	{ srvsvc_s_NetSetFileSecurity,	SRVSVC_OPNUM_NetSetFileSecurity },
314589dc44ceSjose borrego 	{0}
314689dc44ceSjose borrego };
3147