1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
20da6c28aaSamw  */
21148c5f43SAlan Wright 
22da6c28aaSamw /*
23c5866007SKeyur Desai  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
245831d79bSGordon Ross  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
25*97264293SGordon Ross  * Copyright 2022 RackTop Systems, Inc.
26da6c28aaSamw  */
27da6c28aaSamw 
28da6c28aaSamw /*
29da6c28aaSamw  * Server Service RPC (SRVSVC) server-side interface definition.
30da6c28aaSamw  * The server service provides a remote administration interface.
31da6c28aaSamw  *
32da6c28aaSamw  * This service uses NERR/Win32 error codes rather than NT status
33da6c28aaSamw  * values.
34da6c28aaSamw  */
35da6c28aaSamw 
36da6c28aaSamw #include <sys/errno.h>
37bbf6f00cSJordan Brown #include <sys/tzfile.h>
38da6c28aaSamw #include <unistd.h>
39da6c28aaSamw #include <netdb.h>
40da6c28aaSamw #include <strings.h>
41da6c28aaSamw #include <time.h>
42da6c28aaSamw #include <thread.h>
43da6c28aaSamw #include <ctype.h>
44da6c28aaSamw #include <stdlib.h>
45da6c28aaSamw #include <string.h>
46da6c28aaSamw #include <sys/types.h>
47da6c28aaSamw #include <sys/socket.h>
48da6c28aaSamw #include <netinet/in.h>
49da6c28aaSamw #include <arpa/inet.h>
50b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <libshare.h>
51e3f2c991SKeyur Desai #include <libnvpair.h>
52c5866007SKeyur Desai #include <sys/idmap.h>
53c5866007SKeyur Desai #include <pwd.h>
54c5866007SKeyur Desai #include <nss_dbdefs.h>
55da6c28aaSamw #include <smbsrv/libsmb.h>
56da6c28aaSamw #include <smbsrv/libmlsvc.h>
57da6c28aaSamw #include <smbsrv/nmpipes.h>
58bbf6f00cSJordan Brown #include <smbsrv/smb.h>
59da6c28aaSamw #include <smbsrv/netrauth.h>
60da6c28aaSamw #include <smbsrv/ndl/srvsvc.ndl>
6129bd2886SAlan Wright #include "mlsvc.h"
62da6c28aaSamw 
6389dc44ceSjose borrego /*
6489dc44ceSjose borrego  * Qualifier types for NetConnectEnum.
6589dc44ceSjose borrego  */
6689dc44ceSjose borrego #define	SRVSVC_CONNECT_ENUM_NULL	0
6789dc44ceSjose borrego #define	SRVSVC_CONNECT_ENUM_SHARE	1
6889dc44ceSjose borrego #define	SRVSVC_CONNECT_ENUM_WKSTN	2
6989dc44ceSjose borrego 
701fcced4cSJordan Brown #define	SMB_SRVSVC_MAXBUFLEN		(8 * 1024 * 1024)
711fcced4cSJordan Brown #define	SMB_SRVSVC_MAXPREFLEN		((uint32_t)(-1))
7219d41fccSamw 
7329bd2886SAlan Wright typedef struct srvsvc_sd {
7429bd2886SAlan Wright 	uint8_t *sd_buf;
7529bd2886SAlan Wright 	uint32_t sd_size;
7629bd2886SAlan Wright } srvsvc_sd_t;
7729bd2886SAlan Wright 
7829bd2886SAlan Wright typedef struct srvsvc_netshare_setinfo {
7929bd2886SAlan Wright 	char *nss_netname;
8029bd2886SAlan Wright 	char *nss_comment;
8129bd2886SAlan Wright 	char *nss_path;
8229bd2886SAlan Wright 	uint32_t nss_type;
8329bd2886SAlan Wright 	srvsvc_sd_t nss_sd;
8429bd2886SAlan Wright } srvsvc_netshare_setinfo_t;
8529bd2886SAlan Wright 
8629bd2886SAlan Wright typedef union srvsvc_netshare_getinfo {
8729bd2886SAlan Wright 	struct mslm_NetShareInfo_0 nsg_info0;
8829bd2886SAlan Wright 	struct mslm_NetShareInfo_1 nsg_info1;
8929bd2886SAlan Wright 	struct mslm_NetShareInfo_2 nsg_info2;
9029bd2886SAlan Wright 	struct mslm_NetShareInfo_501 nsg_info501;
9129bd2886SAlan Wright 	struct mslm_NetShareInfo_502 nsg_info502;
9229bd2886SAlan Wright 	struct mslm_NetShareInfo_503 nsg_info503;
9329bd2886SAlan Wright 	struct mslm_NetShareInfo_1004 nsg_info1004;
9429bd2886SAlan Wright 	struct mslm_NetShareInfo_1005 nsg_info1005;
9529bd2886SAlan Wright 	struct mslm_NetShareInfo_1006 nsg_info1006;
9629bd2886SAlan Wright 	struct mslm_NetShareInfo_1501 nsg_info1501;
9729bd2886SAlan Wright } srvsvc_netshare_getinfo_t;
9829bd2886SAlan Wright 
991fcced4cSJordan Brown typedef struct mslm_infonres srvsvc_infonres_t;
1001fcced4cSJordan Brown typedef struct mslm_NetConnectEnum srvsvc_NetConnectEnum_t;
1011fcced4cSJordan Brown 
1021fcced4cSJordan Brown static uint32_t srvsvc_netconnectenum_level0(ndr_xa_t *, smb_svcenum_t *,
1031fcced4cSJordan Brown     srvsvc_NetConnectEnum_t *);
1041fcced4cSJordan Brown static uint32_t srvsvc_netconnectenum_level1(ndr_xa_t *, smb_svcenum_t *,
1051fcced4cSJordan Brown     srvsvc_NetConnectEnum_t *);
1061fcced4cSJordan Brown static uint32_t srvsvc_netconnectenum_common(ndr_xa_t *,
1071fcced4cSJordan Brown     srvsvc_NetConnectInfo_t *, smb_netsvc_t *, smb_svcenum_t *);
1081fcced4cSJordan Brown 
1091fcced4cSJordan Brown static DWORD srvsvc_NetFileEnum2(ndr_xa_t *, struct mslm_NetFileEnum *,
1101fcced4cSJordan Brown     smb_svcenum_t *se);
1111fcced4cSJordan Brown static DWORD srvsvc_NetFileEnum3(ndr_xa_t *, struct mslm_NetFileEnum *,
1121fcced4cSJordan Brown     smb_svcenum_t *se);
1131fcced4cSJordan Brown 
1141fcced4cSJordan Brown static uint32_t srvsvc_NetSessionEnumCommon(ndr_xa_t *, srvsvc_infonres_t *,
1151fcced4cSJordan Brown     smb_netsvc_t *, smb_svcenum_t *);
1161fcced4cSJordan Brown 
1171fcced4cSJordan Brown static DWORD mlsvc_NetShareEnumLevel0(ndr_xa_t *, srvsvc_infonres_t *,
1181fcced4cSJordan Brown     smb_svcenum_t *, int);
1191fcced4cSJordan Brown static DWORD mlsvc_NetShareEnumLevel1(ndr_xa_t *, srvsvc_infonres_t *,
1201fcced4cSJordan Brown     smb_svcenum_t *, int);
1211fcced4cSJordan Brown static DWORD mlsvc_NetShareEnumLevel2(ndr_xa_t *, srvsvc_infonres_t *,
1221fcced4cSJordan Brown     smb_svcenum_t *, int);
1231fcced4cSJordan Brown static DWORD mlsvc_NetShareEnumLevel501(ndr_xa_t *, srvsvc_infonres_t *,
1241fcced4cSJordan Brown     smb_svcenum_t *, int);
1251fcced4cSJordan Brown static DWORD mlsvc_NetShareEnumLevel502(ndr_xa_t *, srvsvc_infonres_t *,
1261fcced4cSJordan Brown     smb_svcenum_t *, int);
1271fcced4cSJordan Brown static DWORD mlsvc_NetShareEnumCommon(ndr_xa_t *, smb_svcenum_t *,
1281fcced4cSJordan Brown     smb_share_t *, void *);
1291fcced4cSJordan Brown static boolean_t srvsvc_add_autohome(ndr_xa_t *, smb_svcenum_t *, void *);
1308d7e4166Sjose borrego static char *srvsvc_share_mkpath(ndr_xa_t *, char *);
13129bd2886SAlan Wright static uint32_t srvsvc_share_getsd(ndr_xa_t *, smb_share_t *, srvsvc_sd_t *);
132*97264293SGordon Ross static boolean_t srvsvc_share_access(ndr_xa_t *, smb_share_t *);
13319d41fccSamw 
13489dc44ceSjose borrego static int srvsvc_netconnect_qualifier(const char *);
1351fcced4cSJordan Brown static void srvsvc_estimate_limit(smb_svcenum_t *, uint32_t);
1361fcced4cSJordan Brown static uint32_t srvsvc_open_sessions(void);
1371fcced4cSJordan Brown static uint32_t srvsvc_open_connections(uint32_t, const char *);
1381fcced4cSJordan Brown static uint32_t srvsvc_open_files(void);
139da6c28aaSamw 
14029bd2886SAlan Wright static uint32_t srvsvc_modify_share(smb_share_t *,
14129bd2886SAlan Wright     srvsvc_netshare_setinfo_t *);
14229bd2886SAlan Wright static uint32_t srvsvc_modify_transient_share(smb_share_t *,
14329bd2886SAlan Wright     srvsvc_netshare_setinfo_t *);
14429bd2886SAlan Wright static uint32_t srvsvc_update_share_flags(smb_share_t *, uint32_t);
145e3f2c991SKeyur Desai static uint32_t srvsvc_get_share_flags(smb_share_t *);
14629bd2886SAlan Wright 
147b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t srvsvc_sa_add(char *, char *, char *);
148b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t srvsvc_sa_delete(char *);
14929bd2886SAlan Wright static uint32_t srvsvc_sa_modify(smb_share_t *, srvsvc_netshare_setinfo_t *);
150e3f2c991SKeyur Desai static uint32_t srvsvc_sa_setprop(smb_share_t *, nvlist_t *);
151b89a8333Snatalie li - Sun Microsystems - Irvine United States 
152da6c28aaSamw static char empty_string[1];
153da6c28aaSamw 
1548d7e4166Sjose borrego static ndr_stub_table_t srvsvc_stub_table[];
155da6c28aaSamw 
1568d7e4166Sjose borrego static ndr_service_t srvsvc_service = {
157da6c28aaSamw 	"SRVSVC",			/* name */
158da6c28aaSamw 	"Server services",		/* desc */
159da6c28aaSamw 	"\\srvsvc",			/* endpoint */
160da6c28aaSamw 	PIPE_NTSVCS,			/* sec_addr_port */
1618d7e4166Sjose borrego 	"4b324fc8-1670-01d3-1278-5a47bf6ee188", 3,	/* abstract */
1628d7e4166Sjose borrego 	NDR_TRANSFER_SYNTAX_UUID,		2,	/* transfer */
163da6c28aaSamw 	0,				/* no bind_instance_size */
164da6c28aaSamw 	0,				/* no bind_req() */
165da6c28aaSamw 	0,				/* no unbind_and_close() */
166da6c28aaSamw 	0,				/* use generic_call_stub() */
167da6c28aaSamw 	&TYPEINFO(srvsvc_interface),	/* interface ti */
168da6c28aaSamw 	srvsvc_stub_table		/* stub_table */
169da6c28aaSamw };
170da6c28aaSamw 
171da6c28aaSamw /*
172da6c28aaSamw  * srvsvc_initialize
173da6c28aaSamw  *
174da6c28aaSamw  * This function registers the SRVSVC RPC interface with the RPC runtime
175da6c28aaSamw  * library. It must be called in order to use either the client side
176da6c28aaSamw  * or the server side functions.
177da6c28aaSamw  */
178da6c28aaSamw void
srvsvc_initialize(void)179da6c28aaSamw srvsvc_initialize(void)
180da6c28aaSamw {
1818d7e4166Sjose borrego 	(void) ndr_svc_register(&srvsvc_service);
182da6c28aaSamw }
183da6c28aaSamw 
1849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
1859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Turn "dfsroot" property on/off for the specified
1869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * share and save it.
1879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If the requested value is the same as what is already
1899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * set then no change is required and the function returns.
1909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
1919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t
srvsvc_shr_setdfsroot(smb_share_t * si,boolean_t on)1929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States srvsvc_shr_setdfsroot(smb_share_t *si, boolean_t on)
1939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char *dfs = NULL;
1959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nvlist_t *nvl;
1969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t nerr;
1979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (on && ((si->shr_flags & SMB_SHRF_DFSROOT) == 0)) {
1999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		si->shr_flags |= SMB_SHRF_DFSROOT;
2009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dfs = "true";
2019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	} else if (!on && (si->shr_flags & SMB_SHRF_DFSROOT)) {
2029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		si->shr_flags &= ~SMB_SHRF_DFSROOT;
2039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dfs = "false";
2049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (dfs == NULL)
2079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (ERROR_SUCCESS);
2089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
2109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
2119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (nvlist_add_string(nvl, SHOPT_DFSROOT, dfs) != 0) {
2139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		nvlist_free(nvl);
2149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
2159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nerr = srvsvc_sa_setprop(si, nvl);
2189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nvlist_free(nvl);
2199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (nerr != NERR_Success)
2219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (nerr);
2229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (smb_shr_modify(si));
2249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
226da6c28aaSamw /*
227da6c28aaSamw  * srvsvc_s_NetConnectEnum
228da6c28aaSamw  *
22989dc44ceSjose borrego  * List tree connections made to a share on this server or all tree
23089dc44ceSjose borrego  * connections established from a specific client.  Administrator,
23189dc44ceSjose borrego  * Server Operator, Print Operator or Power User group membership
23289dc44ceSjose borrego  * is required to use this interface.
23389dc44ceSjose borrego  *
23489dc44ceSjose borrego  * There are three information levels:  0, 1, and 50.  We don't support
23589dc44ceSjose borrego  * level 50, which is only used by Windows 9x clients.
236da6c28aaSamw  *
23789dc44ceSjose borrego  * It seems Server Manger (srvmgr) only sends workstation as the qualifier
23889dc44ceSjose borrego  * and the Computer Management Interface on Windows 2000 doesn't request
23989dc44ceSjose borrego  * a list of connections.
24089dc44ceSjose borrego  *
24189dc44ceSjose borrego  * Return Values:
24289dc44ceSjose borrego  * ERROR_SUCCESS            Success
24389dc44ceSjose borrego  * ERROR_ACCESS_DENIED      Caller does not have access to this call.
24489dc44ceSjose borrego  * ERROR_INVALID_PARAMETER  One of the parameters is invalid.
24589dc44ceSjose borrego  * ERROR_INVALID_LEVEL      Unknown information level specified.
24689dc44ceSjose borrego  * ERROR_MORE_DATA          Partial date returned, more entries available.
24789dc44ceSjose borrego  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
24889dc44ceSjose borrego  * NERR_NetNameNotFound     The share qualifier cannot be found.
24989dc44ceSjose borrego  * NERR_BufTooSmall         The supplied buffer is too small.
250da6c28aaSamw  */
251da6c28aaSamw static int
srvsvc_s_NetConnectEnum(void * arg,ndr_xa_t * mxa)2528d7e4166Sjose borrego srvsvc_s_NetConnectEnum(void *arg, ndr_xa_t *mxa)
253da6c28aaSamw {
2541fcced4cSJordan Brown 	srvsvc_NetConnectEnum_t		*param = arg;
2551fcced4cSJordan Brown 	smb_netsvc_t			*ns;
2561fcced4cSJordan Brown 	smb_svcenum_t			se;
2571fcced4cSJordan Brown 	char				*qualifier;
2581fcced4cSJordan Brown 	int				qualtype;
2591fcced4cSJordan Brown 	DWORD				status = ERROR_SUCCESS;
26089dc44ceSjose borrego 
26189dc44ceSjose borrego 	if (!ndr_is_poweruser(mxa)) {
2621fcced4cSJordan Brown 		status = ERROR_ACCESS_DENIED;
2631fcced4cSJordan Brown 		goto srvsvc_netconnectenum_error;
26489dc44ceSjose borrego 	}
26589dc44ceSjose borrego 
26689dc44ceSjose borrego 	qualifier = (char *)param->qualifier;
26789dc44ceSjose borrego 	qualtype = srvsvc_netconnect_qualifier(qualifier);
26889dc44ceSjose borrego 	if (qualtype == SRVSVC_CONNECT_ENUM_NULL) {
2691fcced4cSJordan Brown 		status = NERR_NetNameNotFound;
2701fcced4cSJordan Brown 		goto srvsvc_netconnectenum_error;
2711fcced4cSJordan Brown 	}
2721fcced4cSJordan Brown 
2731fcced4cSJordan Brown 	param->total_entries = srvsvc_open_connections(qualtype, qualifier);
2741fcced4cSJordan Brown 	if (param->total_entries == 0) {
2751fcced4cSJordan Brown 		bzero(param, sizeof (srvsvc_NetConnectEnum_t));
2761fcced4cSJordan Brown 		param->status = ERROR_SUCCESS;
27789dc44ceSjose borrego 		return (NDR_DRC_OK);
27889dc44ceSjose borrego 	}
279da6c28aaSamw 
2801fcced4cSJordan Brown 	bzero(&se, sizeof (smb_svcenum_t));
2811fcced4cSJordan Brown 	se.se_type = SMB_SVCENUM_TYPE_TREE;
2821fcced4cSJordan Brown 	se.se_level = param->info.level;
2831fcced4cSJordan Brown 	se.se_ntotal = param->total_entries;
2841fcced4cSJordan Brown 	se.se_nlimit = se.se_ntotal;
285da6c28aaSamw 
2861fcced4cSJordan Brown 	if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN ||
2871fcced4cSJordan Brown 	    param->pref_max_len > SMB_SRVSVC_MAXBUFLEN)
2881fcced4cSJordan Brown 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
2891fcced4cSJordan Brown 	else
2901fcced4cSJordan Brown 		se.se_prefmaxlen = param->pref_max_len;
291da6c28aaSamw 
2921fcced4cSJordan Brown 	if (param->resume_handle) {
2931fcced4cSJordan Brown 		se.se_resume = *param->resume_handle;
2941fcced4cSJordan Brown 		se.se_nskip = se.se_resume;
2951fcced4cSJordan Brown 		*param->resume_handle = 0;
2961fcced4cSJordan Brown 	}
297da6c28aaSamw 
2981fcced4cSJordan Brown 	switch (param->info.level) {
2991fcced4cSJordan Brown 	case 0:
3001fcced4cSJordan Brown 		status = srvsvc_netconnectenum_level0(mxa, &se, param);
301da6c28aaSamw 		break;
302da6c28aaSamw 	case 1:
3031fcced4cSJordan Brown 		status = srvsvc_netconnectenum_level1(mxa, &se, param);
30489dc44ceSjose borrego 		break;
30589dc44ceSjose borrego 	case 50:
30689dc44ceSjose borrego 		status = ERROR_NOT_SUPPORTED;
307da6c28aaSamw 		break;
308da6c28aaSamw 	default:
30989dc44ceSjose borrego 		status = ERROR_INVALID_LEVEL;
310da6c28aaSamw 		break;
311da6c28aaSamw 	}
312da6c28aaSamw 
313da6c28aaSamw 	if (status != ERROR_SUCCESS)
3141fcced4cSJordan Brown 		goto srvsvc_netconnectenum_error;
3151fcced4cSJordan Brown 
3161fcced4cSJordan Brown 	if ((ns = smb_kmod_enum_init(&se)) == NULL) {
3171fcced4cSJordan Brown 		status = ERROR_NOT_ENOUGH_MEMORY;
3181fcced4cSJordan Brown 		goto srvsvc_netconnectenum_error;
3191fcced4cSJordan Brown 	}
3201fcced4cSJordan Brown 
3211fcced4cSJordan Brown 	status = srvsvc_netconnectenum_common(mxa, &param->info, ns, &se);
3221fcced4cSJordan Brown 	smb_kmod_enum_fini(ns);
3231fcced4cSJordan Brown 
3241fcced4cSJordan Brown 	if (status != ERROR_SUCCESS)
3251fcced4cSJordan Brown 		goto srvsvc_netconnectenum_error;
3261fcced4cSJordan Brown 
3271fcced4cSJordan Brown 	if (param->resume_handle &&
3281fcced4cSJordan Brown 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
3291fcced4cSJordan Brown 		if (se.se_resume < param->total_entries) {
3301fcced4cSJordan Brown 			*param->resume_handle = se.se_resume;
3311fcced4cSJordan Brown 			status = ERROR_MORE_DATA;
3321fcced4cSJordan Brown 		}
3331fcced4cSJordan Brown 	}
334da6c28aaSamw 
335da6c28aaSamw 	param->status = status;
3368d7e4166Sjose borrego 	return (NDR_DRC_OK);
3371fcced4cSJordan Brown 
3381fcced4cSJordan Brown srvsvc_netconnectenum_error:
3391fcced4cSJordan Brown 	bzero(param, sizeof (srvsvc_NetConnectEnum_t));
3401fcced4cSJordan Brown 	param->status = status;
3411fcced4cSJordan Brown 	return (NDR_DRC_OK);
342da6c28aaSamw }
343da6c28aaSamw 
3441fcced4cSJordan Brown /*
3451fcced4cSJordan Brown  * Allocate memory and estimate the number of objects that can
3461fcced4cSJordan Brown  * be returned for NetConnectEnum level 0.
3471fcced4cSJordan Brown  */
3481fcced4cSJordan Brown static uint32_t
srvsvc_netconnectenum_level0(ndr_xa_t * mxa,smb_svcenum_t * se,srvsvc_NetConnectEnum_t * param)3491fcced4cSJordan Brown srvsvc_netconnectenum_level0(ndr_xa_t *mxa, smb_svcenum_t *se,
3501fcced4cSJordan Brown     srvsvc_NetConnectEnum_t *param)
35189dc44ceSjose borrego {
3521fcced4cSJordan Brown 	srvsvc_NetConnectInfo0_t	*info0;
3531fcced4cSJordan Brown 	srvsvc_NetConnectInfoBuf0_t	*ci0;
35489dc44ceSjose borrego 
3551fcced4cSJordan Brown 	if ((info0 = NDR_NEW(mxa, srvsvc_NetConnectInfo0_t)) == NULL)
35689dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
35789dc44ceSjose borrego 
3581fcced4cSJordan Brown 	bzero(info0, sizeof (srvsvc_NetConnectInfo0_t));
3591fcced4cSJordan Brown 	param->info.ru.info0 = info0;
3601fcced4cSJordan Brown 
3611fcced4cSJordan Brown 	srvsvc_estimate_limit(se, sizeof (srvsvc_NetConnectInfoBuf0_t));
3621fcced4cSJordan Brown 	if (se->se_nlimit == 0)
3631fcced4cSJordan Brown 		return (NERR_BufTooSmall);
3641fcced4cSJordan Brown 
3651fcced4cSJordan Brown 	do {
3661fcced4cSJordan Brown 		ci0 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf0_t, se->se_nlimit);
3671fcced4cSJordan Brown 		if (ci0 == NULL)
3681fcced4cSJordan Brown 			se->se_nlimit >>= 1;
3691fcced4cSJordan Brown 	} while ((se->se_nlimit > 0) && (ci0 == NULL));
3701fcced4cSJordan Brown 
3711fcced4cSJordan Brown 	if (ci0 == NULL)
3721fcced4cSJordan Brown 		return (ERROR_NOT_ENOUGH_MEMORY);
37389dc44ceSjose borrego 
37489dc44ceSjose borrego 	info0->ci0 = ci0;
3751fcced4cSJordan Brown 	info0->entries_read = 0;
37689dc44ceSjose borrego 	return (ERROR_SUCCESS);
37789dc44ceSjose borrego }
37889dc44ceSjose borrego 
3791fcced4cSJordan Brown /*
3801fcced4cSJordan Brown  * Allocate memory and estimate the number of objects that can
3811fcced4cSJordan Brown  * be returned for NetConnectEnum level 1.
3821fcced4cSJordan Brown  */
3831fcced4cSJordan Brown static uint32_t
srvsvc_netconnectenum_level1(ndr_xa_t * mxa,smb_svcenum_t * se,srvsvc_NetConnectEnum_t * param)3841fcced4cSJordan Brown srvsvc_netconnectenum_level1(ndr_xa_t *mxa, smb_svcenum_t *se,
3851fcced4cSJordan Brown     srvsvc_NetConnectEnum_t *param)
38689dc44ceSjose borrego {
3871fcced4cSJordan Brown 	srvsvc_NetConnectInfo1_t	*info1;
3881fcced4cSJordan Brown 	srvsvc_NetConnectInfoBuf1_t	*ci1;
38989dc44ceSjose borrego 
3901fcced4cSJordan Brown 	if ((info1 = NDR_NEW(mxa, srvsvc_NetConnectInfo1_t)) == NULL)
39189dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
39289dc44ceSjose borrego 
3931fcced4cSJordan Brown 	bzero(info1, sizeof (srvsvc_NetConnectInfo1_t));
3941fcced4cSJordan Brown 	param->info.ru.info1 = info1;
3951fcced4cSJordan Brown 
3961fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
3971fcced4cSJordan Brown 	    sizeof (srvsvc_NetConnectInfoBuf1_t) + MAXNAMELEN);
3981fcced4cSJordan Brown 	if (se->se_nlimit == 0)
3991fcced4cSJordan Brown 		return (NERR_BufTooSmall);
4001fcced4cSJordan Brown 
4011fcced4cSJordan Brown 	do {
4021fcced4cSJordan Brown 		ci1 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf1_t, se->se_nlimit);
4031fcced4cSJordan Brown 		if (ci1 == NULL)
4041fcced4cSJordan Brown 			se->se_nlimit >>= 1;
4051fcced4cSJordan Brown 	} while ((se->se_nlimit > 0) && (ci1 == NULL));
4061fcced4cSJordan Brown 
4071fcced4cSJordan Brown 	if (ci1 == NULL)
4081fcced4cSJordan Brown 		return (ERROR_NOT_ENOUGH_MEMORY);
40989dc44ceSjose borrego 
41089dc44ceSjose borrego 	info1->ci1 = ci1;
4111fcced4cSJordan Brown 	info1->entries_read = 0;
4121fcced4cSJordan Brown 	return (ERROR_SUCCESS);
4131fcced4cSJordan Brown }
4141fcced4cSJordan Brown 
4151fcced4cSJordan Brown /*
4161fcced4cSJordan Brown  * Request a list of connections from the kernel and set up
4171fcced4cSJordan Brown  * the connection information to be returned to the client.
4181fcced4cSJordan Brown  */
4191fcced4cSJordan Brown static uint32_t
srvsvc_netconnectenum_common(ndr_xa_t * mxa,srvsvc_NetConnectInfo_t * info,smb_netsvc_t * ns,smb_svcenum_t * se)4201fcced4cSJordan Brown srvsvc_netconnectenum_common(ndr_xa_t *mxa, srvsvc_NetConnectInfo_t *info,
4211fcced4cSJordan Brown     smb_netsvc_t *ns, smb_svcenum_t *se)
4221fcced4cSJordan Brown {
4231fcced4cSJordan Brown 	srvsvc_NetConnectInfo0_t	*info0;
4241fcced4cSJordan Brown 	srvsvc_NetConnectInfo1_t	*info1;
4251fcced4cSJordan Brown 	srvsvc_NetConnectInfoBuf0_t	*ci0;
4261fcced4cSJordan Brown 	srvsvc_NetConnectInfoBuf1_t	*ci1;
4271fcced4cSJordan Brown 	smb_netsvcitem_t		*item;
4281fcced4cSJordan Brown 	smb_netconnectinfo_t		*tree;
4291fcced4cSJordan Brown 
4301fcced4cSJordan Brown 	if (smb_kmod_enum(ns) != 0)
4311fcced4cSJordan Brown 		return (ERROR_INTERNAL_ERROR);
4321fcced4cSJordan Brown 
4331fcced4cSJordan Brown 	info0 = info->ru.info0;
4341fcced4cSJordan Brown 	ci0 = info0->ci0;
4351fcced4cSJordan Brown 
4361fcced4cSJordan Brown 	info1 = info->ru.info1;
4371fcced4cSJordan Brown 	ci1 = info1->ci1;
4381fcced4cSJordan Brown 
4391fcced4cSJordan Brown 	item = list_head(&ns->ns_list);
4401fcced4cSJordan Brown 	while (item != NULL) {
4411fcced4cSJordan Brown 		tree = &item->nsi_un.nsi_tree;
4421fcced4cSJordan Brown 
4431fcced4cSJordan Brown 		switch (se->se_level) {
4441fcced4cSJordan Brown 		case 0:
4451fcced4cSJordan Brown 			ci0->coni0_id = tree->ci_id;
4461fcced4cSJordan Brown 			++ci0;
4471fcced4cSJordan Brown 			++info0->entries_read;
4481fcced4cSJordan Brown 			break;
4491fcced4cSJordan Brown 		case 1:
4501fcced4cSJordan Brown 			ci1->coni1_id = tree->ci_id;
4511fcced4cSJordan Brown 			ci1->coni1_type = tree->ci_type;
4521fcced4cSJordan Brown 			ci1->coni1_num_opens = tree->ci_numopens;
4531fcced4cSJordan Brown 			ci1->coni1_num_users = tree->ci_numusers;
4541fcced4cSJordan Brown 			ci1->coni1_time = tree->ci_time;
4551fcced4cSJordan Brown 			ci1->coni1_username = (uint8_t *)
4561fcced4cSJordan Brown 			    NDR_STRDUP(mxa, tree->ci_username);
4571fcced4cSJordan Brown 			ci1->coni1_netname = (uint8_t *)
4581fcced4cSJordan Brown 			    NDR_STRDUP(mxa, tree->ci_share);
4591fcced4cSJordan Brown 			++ci1;
4601fcced4cSJordan Brown 			++info1->entries_read;
4611fcced4cSJordan Brown 			break;
4621fcced4cSJordan Brown 		default:
4631fcced4cSJordan Brown 			return (ERROR_INVALID_LEVEL);
4641fcced4cSJordan Brown 		}
4651fcced4cSJordan Brown 
4661fcced4cSJordan Brown 		++se->se_resume;
4671fcced4cSJordan Brown 		item = list_next(&ns->ns_list, item);
4681fcced4cSJordan Brown 	}
4691fcced4cSJordan Brown 
47089dc44ceSjose borrego 	return (ERROR_SUCCESS);
47189dc44ceSjose borrego }
47289dc44ceSjose borrego 
47389dc44ceSjose borrego /*
47489dc44ceSjose borrego  * srvsvc_netconnect_qualifier
47589dc44ceSjose borrego  *
47689dc44ceSjose borrego  * The qualifier is a string that specifies a share name or computer name
47789dc44ceSjose borrego  * for the connections of interest.  If it is a share name then all the
47889dc44ceSjose borrego  * connections made to that share name are listed.  If it is a computer
47989dc44ceSjose borrego  * name (it starts with two backslash characters), then NetConnectEnum
48089dc44ceSjose borrego  * lists all connections made from that computer to the specified server.
48189dc44ceSjose borrego  */
48289dc44ceSjose borrego static int
srvsvc_netconnect_qualifier(const char * qualifier)48389dc44ceSjose borrego srvsvc_netconnect_qualifier(const char *qualifier)
48489dc44ceSjose borrego {
48589dc44ceSjose borrego 	if (qualifier == NULL || *qualifier == '\0')
48689dc44ceSjose borrego 		return (SRVSVC_CONNECT_ENUM_NULL);
48789dc44ceSjose borrego 
48889dc44ceSjose borrego 	if (strlen(qualifier) > MAXHOSTNAMELEN)
48989dc44ceSjose borrego 		return (SRVSVC_CONNECT_ENUM_NULL);
49089dc44ceSjose borrego 
49189dc44ceSjose borrego 	if (qualifier[0] == '\\' && qualifier[1] == '\\') {
49289dc44ceSjose borrego 		return (SRVSVC_CONNECT_ENUM_WKSTN);
49389dc44ceSjose borrego 	} else {
49489dc44ceSjose borrego 		if (!smb_shr_exists((char *)qualifier))
49589dc44ceSjose borrego 			return (SRVSVC_CONNECT_ENUM_NULL);
49689dc44ceSjose borrego 
49789dc44ceSjose borrego 		return (SRVSVC_CONNECT_ENUM_SHARE);
49889dc44ceSjose borrego 	}
49989dc44ceSjose borrego }
50089dc44ceSjose borrego 
5011fcced4cSJordan Brown static uint32_t
srvsvc_open_sessions(void)5021fcced4cSJordan Brown srvsvc_open_sessions(void)
5031fcced4cSJordan Brown {
5041fcced4cSJordan Brown 	smb_opennum_t	opennum;
5051fcced4cSJordan Brown 
5061fcced4cSJordan Brown 	bzero(&opennum, sizeof (smb_opennum_t));
5071fcced4cSJordan Brown 	if (smb_kmod_get_open_num(&opennum) != 0)
5081fcced4cSJordan Brown 		return (0);
5091fcced4cSJordan Brown 
5101fcced4cSJordan Brown 	return (opennum.open_users);
5111fcced4cSJordan Brown }
5121fcced4cSJordan Brown 
5131fcced4cSJordan Brown static uint32_t
srvsvc_open_connections(uint32_t qualtype,const char * qualifier)5141fcced4cSJordan Brown srvsvc_open_connections(uint32_t qualtype, const char *qualifier)
5151fcced4cSJordan Brown {
5161fcced4cSJordan Brown 	smb_opennum_t	opennum;
5171fcced4cSJordan Brown 
5181fcced4cSJordan Brown 	bzero(&opennum, sizeof (smb_opennum_t));
5191fcced4cSJordan Brown 	opennum.qualtype = qualtype;
5201fcced4cSJordan Brown 	(void) strlcpy(opennum.qualifier, qualifier, MAXNAMELEN);
5211fcced4cSJordan Brown 
5221fcced4cSJordan Brown 	if (smb_kmod_get_open_num(&opennum) != 0)
5231fcced4cSJordan Brown 		return (0);
5241fcced4cSJordan Brown 
5251fcced4cSJordan Brown 	return (opennum.open_trees);
5261fcced4cSJordan Brown }
5271fcced4cSJordan Brown 
5281fcced4cSJordan Brown static uint32_t
srvsvc_open_files(void)5291fcced4cSJordan Brown srvsvc_open_files(void)
5301fcced4cSJordan Brown {
5311fcced4cSJordan Brown 	smb_opennum_t	opennum;
5321fcced4cSJordan Brown 
5331fcced4cSJordan Brown 	bzero(&opennum, sizeof (smb_opennum_t));
5341fcced4cSJordan Brown 	if (smb_kmod_get_open_num(&opennum) != 0)
5351fcced4cSJordan Brown 		return (0);
5361fcced4cSJordan Brown 
5371fcced4cSJordan Brown 	return (opennum.open_files);
5381fcced4cSJordan Brown }
5391fcced4cSJordan Brown 
540da6c28aaSamw /*
541da6c28aaSamw  * srvsvc_s_NetFileEnum
542da6c28aaSamw  *
5433db3f65cSamw  * Return information on open files or named pipes. Only members of the
5443db3f65cSamw  * Administrators or Server Operators local groups are allowed to make
5453db3f65cSamw  * this call. Currently, we only support Administrators.
5463db3f65cSamw  *
5473db3f65cSamw  * If basepath is null, all open resources are enumerated. If basepath
5483db3f65cSamw  * is non-null, only resources that have basepath as a prefix should
5493db3f65cSamw  * be returned.
5503db3f65cSamw  *
5513db3f65cSamw  * If username is specified (non-null), only files opened by username
5523db3f65cSamw  * should be returned.
5533db3f65cSamw  *
5543db3f65cSamw  * Notes:
5553db3f65cSamw  * 1. We don't validate the servername because we would have to check
5563db3f65cSamw  * all primary IPs and the ROI seems unlikely to be worth it.
5573db3f65cSamw  * 2. Both basepath and username are currently ignored because both
5583db3f65cSamw  * Server Manger (NT 4.0) and CMI (Windows 2000) always set them to null.
5593db3f65cSamw  *
5603db3f65cSamw  * The level of information requested may be one of:
5613db3f65cSamw  *
5623db3f65cSamw  *  2   Return the file identification number.
5633db3f65cSamw  *      This level is not supported on Windows Me/98/95.
5643db3f65cSamw  *
5653db3f65cSamw  *  3   Return information about the file.
5663db3f65cSamw  *      This level is not supported on Windows Me/98/95.
5673db3f65cSamw  *
5683db3f65cSamw  *  50  Windows Me/98/95:  Return information about the file.
5693db3f65cSamw  *
5703db3f65cSamw  * Note:
5713db3f65cSamw  * If pref_max_len is unlimited and resume_handle is null, the client
5723db3f65cSamw  * expects to receive all data in a single call.
5733db3f65cSamw  * If we are unable to do fit all data in a single response, we would
5743db3f65cSamw  * normally return ERROR_MORE_DATA with a partial list.
5753db3f65cSamw  *
5763db3f65cSamw  * Unfortunately, when both of these conditions occur, Server Manager
5773db3f65cSamw  * pops up an error box with the message "more data available" and
5783db3f65cSamw  * doesn't display any of the returned data. In this case, it is
5793db3f65cSamw  * probably better to return ERROR_SUCCESS with the partial list.
5803db3f65cSamw  * Windows 2000 doesn't have this problem because it always sends a
5813db3f65cSamw  * non-null resume_handle.
5823db3f65cSamw  *
5833db3f65cSamw  * Return Values:
5843db3f65cSamw  * ERROR_SUCCESS            Success
5853db3f65cSamw  * ERROR_ACCESS_DENIED      Caller does not have access to this call.
5863db3f65cSamw  * ERROR_INVALID_PARAMETER  One of the parameters is invalid.
5873db3f65cSamw  * ERROR_INVALID_LEVEL      Unknown information level specified.
5883db3f65cSamw  * ERROR_MORE_DATA          Partial date returned, more entries available.
5893db3f65cSamw  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
5903db3f65cSamw  * NERR_BufTooSmall         The supplied buffer is too small.
591da6c28aaSamw  */
592da6c28aaSamw static int
srvsvc_s_NetFileEnum(void * arg,ndr_xa_t * mxa)5938d7e4166Sjose borrego srvsvc_s_NetFileEnum(void *arg, ndr_xa_t *mxa)
594da6c28aaSamw {
5951fcced4cSJordan Brown 	struct mslm_NetFileEnum	*param = arg;
5961fcced4cSJordan Brown 	smb_svcenum_t		se;
5971fcced4cSJordan Brown 	DWORD			status;
598da6c28aaSamw 
5993db3f65cSamw 	if (!ndr_is_admin(mxa)) {
60019d41fccSamw 		bzero(param, sizeof (struct mslm_NetFileEnum));
60119d41fccSamw 		param->status = ERROR_ACCESS_DENIED;
6028d7e4166Sjose borrego 		return (NDR_DRC_OK);
60319d41fccSamw 	}
60419d41fccSamw 
6051fcced4cSJordan Brown 	if ((param->total_entries = srvsvc_open_files()) == 0) {
6061fcced4cSJordan Brown 		bzero(param, sizeof (struct mslm_NetFileEnum));
6071fcced4cSJordan Brown 		param->status = ERROR_SUCCESS;
6081fcced4cSJordan Brown 		return (NDR_DRC_OK);
6091fcced4cSJordan Brown 	}
6101fcced4cSJordan Brown 
6111fcced4cSJordan Brown 	bzero(&se, sizeof (smb_svcenum_t));
6121fcced4cSJordan Brown 	se.se_type = SMB_SVCENUM_TYPE_FILE;
6131fcced4cSJordan Brown 	se.se_level = param->info.switch_value;
6141fcced4cSJordan Brown 	se.se_ntotal = param->total_entries;
6151fcced4cSJordan Brown 	se.se_nlimit = se.se_ntotal;
6161fcced4cSJordan Brown 
6171fcced4cSJordan Brown 	if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN ||
6181fcced4cSJordan Brown 	    param->pref_max_len > SMB_SRVSVC_MAXBUFLEN)
6191fcced4cSJordan Brown 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
6201fcced4cSJordan Brown 	else
6211fcced4cSJordan Brown 		se.se_prefmaxlen = param->pref_max_len;
6221fcced4cSJordan Brown 
6231fcced4cSJordan Brown 	if (param->resume_handle) {
6241fcced4cSJordan Brown 		se.se_resume = *param->resume_handle;
6251fcced4cSJordan Brown 		se.se_nskip = se.se_resume;
6261fcced4cSJordan Brown 		*param->resume_handle = 0;
6271fcced4cSJordan Brown 	}
6281fcced4cSJordan Brown 
6293db3f65cSamw 	switch (param->info.switch_value) {
6303db3f65cSamw 	case 2:
6311fcced4cSJordan Brown 		status = srvsvc_NetFileEnum2(mxa, param, &se);
6323db3f65cSamw 		break;
6333db3f65cSamw 
6343db3f65cSamw 	case 3:
6351fcced4cSJordan Brown 		status = srvsvc_NetFileEnum3(mxa, param, &se);
6363db3f65cSamw 		break;
6373db3f65cSamw 
6383db3f65cSamw 	case 50:
6393db3f65cSamw 		status = ERROR_NOT_SUPPORTED;
6403db3f65cSamw 		break;
6413db3f65cSamw 
6423db3f65cSamw 	default:
6433db3f65cSamw 		status = ERROR_INVALID_LEVEL;
6443db3f65cSamw 		break;
645da6c28aaSamw 	}
646da6c28aaSamw 
6473db3f65cSamw 	if (status != ERROR_SUCCESS) {
648da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetFileEnum));
6493db3f65cSamw 		param->status = status;
6508d7e4166Sjose borrego 		return (NDR_DRC_OK);
651da6c28aaSamw 	}
652da6c28aaSamw 
6531fcced4cSJordan Brown 	if (param->resume_handle &&
6541fcced4cSJordan Brown 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
6551fcced4cSJordan Brown 		if (se.se_resume < param->total_entries) {
6561fcced4cSJordan Brown 			*param->resume_handle = se.se_resume;
6571fcced4cSJordan Brown 			status = ERROR_MORE_DATA;
6581fcced4cSJordan Brown 		}
6591fcced4cSJordan Brown 	}
6603db3f65cSamw 
6611fcced4cSJordan Brown 	param->status = status;
6628d7e4166Sjose borrego 	return (NDR_DRC_OK);
6633db3f65cSamw }
6643db3f65cSamw 
6653db3f65cSamw /*
6663db3f65cSamw  * Build level 2 file information.
6673db3f65cSamw  *
6681fcced4cSJordan Brown  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
6691fcced4cSJordan Brown  * So we use the uniqid here.
6701fcced4cSJordan Brown  *
6713db3f65cSamw  * On success, the caller expects that the info2, fi2 and entries_read
6723db3f65cSamw  * fields have been set up.
6733db3f65cSamw  */
6743db3f65cSamw static DWORD
srvsvc_NetFileEnum2(ndr_xa_t * mxa,struct mslm_NetFileEnum * param,smb_svcenum_t * se)6751fcced4cSJordan Brown srvsvc_NetFileEnum2(ndr_xa_t *mxa, struct mslm_NetFileEnum *param,
6761fcced4cSJordan Brown     smb_svcenum_t *se)
6773db3f65cSamw {
6781fcced4cSJordan Brown 	struct mslm_NetFileInfoBuf2	*fi2;
6791fcced4cSJordan Brown 	smb_netsvc_t			*ns;
6801fcced4cSJordan Brown 	smb_netsvcitem_t		*item;
6811fcced4cSJordan Brown 	smb_netfileinfo_t		*ofile;
6821fcced4cSJordan Brown 	uint32_t			entries_read = 0;
6833db3f65cSamw 
6848d7e4166Sjose borrego 	param->info.ru.info2 = NDR_NEW(mxa, struct mslm_NetFileInfo2);
68529bd2886SAlan Wright 	if (param->info.ru.info2 == NULL)
6863db3f65cSamw 		return (ERROR_NOT_ENOUGH_MEMORY);
6873db3f65cSamw 
6881fcced4cSJordan Brown 	srvsvc_estimate_limit(se, sizeof (struct mslm_NetFileInfoBuf2));
6891fcced4cSJordan Brown 	if (se->se_nlimit == 0)
6901fcced4cSJordan Brown 		return (NERR_BufTooSmall);
6911fcced4cSJordan Brown 
6921fcced4cSJordan Brown 	do {
6931fcced4cSJordan Brown 		fi2 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf2, se->se_nlimit);
6941fcced4cSJordan Brown 		if (fi2 == NULL)
6951fcced4cSJordan Brown 			se->se_nlimit >>= 1;
6961fcced4cSJordan Brown 	} while ((se->se_nlimit > 0) && (fi2 == NULL));
6971fcced4cSJordan Brown 
69889dc44ceSjose borrego 	if (fi2 == NULL)
69989dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
70089dc44ceSjose borrego 
7013db3f65cSamw 	param->info.ru.info2->fi2 = fi2;
70289dc44ceSjose borrego 
7031fcced4cSJordan Brown 	if ((ns = smb_kmod_enum_init(se)) == NULL)
7041fcced4cSJordan Brown 		return (ERROR_NOT_ENOUGH_MEMORY);
7051fcced4cSJordan Brown 
7061fcced4cSJordan Brown 	if (smb_kmod_enum(ns) != 0) {
7071fcced4cSJordan Brown 		smb_kmod_enum_fini(ns);
7081fcced4cSJordan Brown 		return (ERROR_INTERNAL_ERROR);
7091fcced4cSJordan Brown 	}
71089dc44ceSjose borrego 
7111fcced4cSJordan Brown 	item = list_head(&ns->ns_list);
7121fcced4cSJordan Brown 	while (item != NULL) {
7131fcced4cSJordan Brown 		ofile = &item->nsi_un.nsi_ofile;
7141fcced4cSJordan Brown 		fi2->fi2_id = ofile->fi_uniqid;
71589dc44ceSjose borrego 
71689dc44ceSjose borrego 		++entries_read;
71789dc44ceSjose borrego 		++fi2;
7181fcced4cSJordan Brown 		item = list_next(&ns->ns_list, item);
71989dc44ceSjose borrego 	}
72089dc44ceSjose borrego 
7211fcced4cSJordan Brown 	se->se_resume += entries_read;
72289dc44ceSjose borrego 	param->info.ru.info2->entries_read = entries_read;
7231fcced4cSJordan Brown 	smb_kmod_enum_fini(ns);
7243db3f65cSamw 	return (ERROR_SUCCESS);
7253db3f65cSamw }
7263db3f65cSamw 
7273db3f65cSamw /*
7283db3f65cSamw  * Build level 3 file information.
7293db3f65cSamw  *
7301fcced4cSJordan Brown  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
7311fcced4cSJordan Brown  * So we use the uniqid here.
7321fcced4cSJordan Brown  *
7333db3f65cSamw  * On success, the caller expects that the info3, fi3 and entries_read
7343db3f65cSamw  * fields have been set up.
7353db3f65cSamw  */
7363db3f65cSamw static DWORD
srvsvc_NetFileEnum3(ndr_xa_t * mxa,struct mslm_NetFileEnum * param,smb_svcenum_t * se)7371fcced4cSJordan Brown srvsvc_NetFileEnum3(ndr_xa_t *mxa, struct mslm_NetFileEnum *param,
7381fcced4cSJordan Brown     smb_svcenum_t *se)
7393db3f65cSamw {
7401fcced4cSJordan Brown 	struct mslm_NetFileInfoBuf3	*fi3;
7411fcced4cSJordan Brown 	smb_netsvc_t			*ns;
7421fcced4cSJordan Brown 	smb_netsvcitem_t		*item;
7431fcced4cSJordan Brown 	smb_netfileinfo_t		*ofile;
7441fcced4cSJordan Brown 	uint32_t			entries_read = 0;
745da6c28aaSamw 
7468d7e4166Sjose borrego 	param->info.ru.info3 = NDR_NEW(mxa, struct mslm_NetFileInfo3);
7473db3f65cSamw 	if (param->info.ru.info3 == NULL)
7483db3f65cSamw 		return (ERROR_NOT_ENOUGH_MEMORY);
749da6c28aaSamw 
7501fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
7511fcced4cSJordan Brown 	    sizeof (struct mslm_NetFileInfoBuf3) + MAXNAMELEN);
7521fcced4cSJordan Brown 	if (se->se_nlimit == 0)
7531fcced4cSJordan Brown 		return (NERR_BufTooSmall);
7541fcced4cSJordan Brown 
7551fcced4cSJordan Brown 	do {
7561fcced4cSJordan Brown 		fi3 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf3, se->se_nlimit);
7571fcced4cSJordan Brown 		if (fi3 == NULL)
7581fcced4cSJordan Brown 			se->se_nlimit >>= 1;
7591fcced4cSJordan Brown 	} while ((se->se_nlimit > 0) && (fi3 == NULL));
7601fcced4cSJordan Brown 
76189dc44ceSjose borrego 	if (fi3 == NULL)
76289dc44ceSjose borrego 		return (ERROR_NOT_ENOUGH_MEMORY);
76389dc44ceSjose borrego 
764da6c28aaSamw 	param->info.ru.info3->fi3 = fi3;
76589dc44ceSjose borrego 
7661fcced4cSJordan Brown 	if ((ns = smb_kmod_enum_init(se)) == NULL)
7671fcced4cSJordan Brown 		return (ERROR_NOT_ENOUGH_MEMORY);
7681fcced4cSJordan Brown 
7691fcced4cSJordan Brown 	if (smb_kmod_enum(ns) != 0) {
7701fcced4cSJordan Brown 		smb_kmod_enum_fini(ns);
7711fcced4cSJordan Brown 		return (ERROR_INTERNAL_ERROR);
7721fcced4cSJordan Brown 	}
77389dc44ceSjose borrego 
7741fcced4cSJordan Brown 	item = list_head(&ns->ns_list);
7751fcced4cSJordan Brown 	while (item != NULL) {
7761fcced4cSJordan Brown 		ofile = &item->nsi_un.nsi_ofile;
7771fcced4cSJordan Brown 		fi3->fi3_id = ofile->fi_uniqid;
7781fcced4cSJordan Brown 		fi3->fi3_permissions = ofile->fi_permissions;
7791fcced4cSJordan Brown 		fi3->fi3_num_locks = ofile->fi_numlocks;
78089dc44ceSjose borrego 		fi3->fi3_pathname = (uint8_t *)
7811fcced4cSJordan Brown 		    NDR_STRDUP(mxa, ofile->fi_path);
78289dc44ceSjose borrego 		fi3->fi3_username = (uint8_t *)
7831fcced4cSJordan Brown 		    NDR_STRDUP(mxa, ofile->fi_username);
78489dc44ceSjose borrego 
78589dc44ceSjose borrego 		++entries_read;
78689dc44ceSjose borrego 		++fi3;
7871fcced4cSJordan Brown 		item = list_next(&ns->ns_list, item);
78889dc44ceSjose borrego 	}
78989dc44ceSjose borrego 
7901fcced4cSJordan Brown 	se->se_resume += entries_read;
79189dc44ceSjose borrego 	param->info.ru.info3->entries_read = entries_read;
79289dc44ceSjose borrego 	param->total_entries = entries_read;
7939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_kmod_enum_fini(ns);
7943db3f65cSamw 	return (ERROR_SUCCESS);
795da6c28aaSamw }
796da6c28aaSamw 
797da6c28aaSamw /*
798da6c28aaSamw  * srvsvc_s_NetFileClose
799da6c28aaSamw  *
8003db3f65cSamw  * NetFileClose forces a file to close. This function can be used when
8011fcced4cSJordan Brown  * an error prevents closure by other means.  Use NetFileClose with
8023db3f65cSamw  * caution because it does not flush data, cached on a client, to the
8033db3f65cSamw  * file before closing the file.
8043db3f65cSamw  *
8051fcced4cSJordan Brown  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
8061fcced4cSJordan Brown  * So we use the uniqid here.
8071fcced4cSJordan Brown  *
8083db3f65cSamw  * Return Values
8093db3f65cSamw  * ERROR_SUCCESS            Operation succeeded.
8103db3f65cSamw  * ERROR_ACCESS_DENIED      Operation denied.
8113db3f65cSamw  * NERR_FileIdNotFound      No open file with the specified id.
8123db3f65cSamw  *
8131fcced4cSJordan Brown  * Note: MSDN suggests ERROR_FILE_NOT_FOUND for NetFileClose but network
8141fcced4cSJordan Brown  * captures using NT show NERR_FileIdNotFound, which is consistent with
8151fcced4cSJordan Brown  * the NetFileClose2 page on MSDN.
816da6c28aaSamw  */
817da6c28aaSamw static int
srvsvc_s_NetFileClose(void * arg,ndr_xa_t * mxa)8188d7e4166Sjose borrego srvsvc_s_NetFileClose(void *arg, ndr_xa_t *mxa)
819da6c28aaSamw {
8201fcced4cSJordan Brown 	static struct {
8211fcced4cSJordan Brown 		int errnum;
8221fcced4cSJordan Brown 		int nerr;
8231fcced4cSJordan Brown 	} errmap[] = {
8241fcced4cSJordan Brown 		0,	ERROR_SUCCESS,
8251fcced4cSJordan Brown 		EACCES,	ERROR_ACCESS_DENIED,
8261fcced4cSJordan Brown 		EPERM,	ERROR_ACCESS_DENIED,
8271fcced4cSJordan Brown 		EINVAL,	ERROR_INVALID_PARAMETER,
8281fcced4cSJordan Brown 		ENOMEM,	ERROR_NOT_ENOUGH_MEMORY,
8291fcced4cSJordan Brown 		ENOENT,	NERR_FileIdNotFound
8301fcced4cSJordan Brown 	};
8311fcced4cSJordan Brown 
832da6c28aaSamw 	struct mslm_NetFileClose *param = arg;
8331fcced4cSJordan Brown 	int		i;
8341fcced4cSJordan Brown 	int		rc;
835da6c28aaSamw 
8363db3f65cSamw 	if (!ndr_is_admin(mxa)) {
8373db3f65cSamw 		param->status = ERROR_ACCESS_DENIED;
8388d7e4166Sjose borrego 		return (NDR_DRC_OK);
8393db3f65cSamw 	}
8403db3f65cSamw 
8411fcced4cSJordan Brown 	rc = smb_kmod_file_close(param->file_id);
8421fcced4cSJordan Brown 
8431fcced4cSJordan Brown 	for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) {
8441fcced4cSJordan Brown 		if (rc == errmap[i].errnum) {
8451fcced4cSJordan Brown 			param->status = errmap[i].nerr;
8461fcced4cSJordan Brown 			return (NDR_DRC_OK);
8471fcced4cSJordan Brown 		}
8481fcced4cSJordan Brown 	}
8491fcced4cSJordan Brown 
8501fcced4cSJordan Brown 	param->status = ERROR_INTERNAL_ERROR;
8518d7e4166Sjose borrego 	return (NDR_DRC_OK);
852da6c28aaSamw }
853da6c28aaSamw 
854da6c28aaSamw /*
855da6c28aaSamw  * srvsvc_s_NetShareGetInfo
856da6c28aaSamw  *
857da6c28aaSamw  * Returns Win32 error codes.
858da6c28aaSamw  */
859da6c28aaSamw static int
srvsvc_s_NetShareGetInfo(void * arg,ndr_xa_t * mxa)8608d7e4166Sjose borrego srvsvc_s_NetShareGetInfo(void *arg, ndr_xa_t *mxa)
861da6c28aaSamw {
862da6c28aaSamw 	struct mlsm_NetShareGetInfo *param = arg;
863eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_0 *info0;
864eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_1 *info1;
865eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_2 *info2;
866eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_501 *info501;
867eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_502 *info502;
86829bd2886SAlan Wright 	struct mslm_NetShareInfo_503 *info503;
869eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_1004 *info1004;
870eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_1005 *info1005;
871eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_1006 *info1006;
87229bd2886SAlan Wright 	struct mslm_NetShareInfo_1501 *info1501;
87329bd2886SAlan Wright 	srvsvc_netshare_getinfo_t *info;
87429bd2886SAlan Wright 	uint8_t *netname;
87529bd2886SAlan Wright 	uint8_t *comment;
8763db3f65cSamw 	smb_share_t si;
87729bd2886SAlan Wright 	srvsvc_sd_t sd;
878da6c28aaSamw 	DWORD status;
879da6c28aaSamw 
8803db3f65cSamw 	status = smb_shr_get((char *)param->netname, &si);
881da6c28aaSamw 	if (status != NERR_Success) {
882c8ec8eeaSjose borrego 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
883c8ec8eeaSjose borrego 		param->status = status;
8848d7e4166Sjose borrego 		return (NDR_DRC_OK);
885da6c28aaSamw 	}
886da6c28aaSamw 
887*97264293SGordon Ross 	if ((si.shr_flags & SMB_SHRF_ABE) != 0 &&
888*97264293SGordon Ross 	    !srvsvc_share_access(mxa, &si)) {
889*97264293SGordon Ross 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
890*97264293SGordon Ross 		param->status = ERROR_ACCESS_DENIED;
891*97264293SGordon Ross 		return (NDR_DRC_OK);
892*97264293SGordon Ross 	}
893*97264293SGordon Ross 
89429bd2886SAlan Wright 	netname = (uint8_t *)NDR_STRDUP(mxa, si.shr_name);
89529bd2886SAlan Wright 	comment = (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt);
89629bd2886SAlan Wright 	info = NDR_NEW(mxa, srvsvc_netshare_getinfo_t);
8973db3f65cSamw 
89829bd2886SAlan Wright 	if (netname == NULL || comment == NULL || info == NULL) {
89929bd2886SAlan Wright 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
90029bd2886SAlan Wright 		param->status = ERROR_NOT_ENOUGH_MEMORY;
90129bd2886SAlan Wright 		return (NDR_DRC_OK);
90229bd2886SAlan Wright 	}
903da6c28aaSamw 
90429bd2886SAlan Wright 	switch (param->level) {
90529bd2886SAlan Wright 	case 0:
90629bd2886SAlan Wright 		info0 = &info->nsg_info0;
90729bd2886SAlan Wright 		info0->shi0_netname = netname;
908da6c28aaSamw 		param->result.ru.info0 = info0;
909da6c28aaSamw 		break;
910da6c28aaSamw 
911da6c28aaSamw 	case 1:
91229bd2886SAlan Wright 		info1 = &info->nsg_info1;
91329bd2886SAlan Wright 		info1->shi1_netname = netname;
91429bd2886SAlan Wright 		info1->shi1_comment = comment;
9153db3f65cSamw 		info1->shi1_type = si.shr_type;
916da6c28aaSamw 		param->result.ru.info1 = info1;
917da6c28aaSamw 		break;
918da6c28aaSamw 
919da6c28aaSamw 	case 2:
92029bd2886SAlan Wright 		info2 = &info->nsg_info2;
92129bd2886SAlan Wright 		info2->shi2_netname = netname;
92229bd2886SAlan Wright 		info2->shi2_comment = comment;
923da6c28aaSamw 		info2->shi2_path =
92489dc44ceSjose borrego 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
925da6c28aaSamw 		info2->shi2_passwd = 0;
9263db3f65cSamw 		info2->shi2_type = si.shr_type;
927da6c28aaSamw 		info2->shi2_permissions = 0;
928da6c28aaSamw 		info2->shi2_max_uses = SHI_USES_UNLIMITED;
929da6c28aaSamw 		info2->shi2_current_uses = 0;
930da6c28aaSamw 		param->result.ru.info2 = info2;
931da6c28aaSamw 		break;
932da6c28aaSamw 
93329bd2886SAlan Wright 	case 501:
93429bd2886SAlan Wright 		info501 = &info->nsg_info501;
93529bd2886SAlan Wright 		info501->shi501_netname = netname;
93629bd2886SAlan Wright 		info501->shi501_comment = comment;
93729bd2886SAlan Wright 		info501->shi501_type = si.shr_type;
938e3f2c991SKeyur Desai 		info501->shi501_flags = srvsvc_get_share_flags(&si);
93929bd2886SAlan Wright 		param->result.ru.info501 = info501;
94029bd2886SAlan Wright 		break;
94129bd2886SAlan Wright 
94229bd2886SAlan Wright 	case 502:
94329bd2886SAlan Wright 		info502 = &info->nsg_info502;
94429bd2886SAlan Wright 		info502->shi502_netname = netname;
94529bd2886SAlan Wright 		info502->shi502_comment = comment;
94629bd2886SAlan Wright 		info502->shi502_path =
94729bd2886SAlan Wright 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
94829bd2886SAlan Wright 		info502->shi502_passwd = 0;
94929bd2886SAlan Wright 		info502->shi502_type = si.shr_type;
95029bd2886SAlan Wright 		info502->shi502_permissions = 0;
95129bd2886SAlan Wright 		info502->shi502_max_uses = SHI_USES_UNLIMITED;
95229bd2886SAlan Wright 		info502->shi502_current_uses = 0;
95329bd2886SAlan Wright 
95429bd2886SAlan Wright 		status = srvsvc_share_getsd(mxa, &si, &sd);
95529bd2886SAlan Wright 		if (status == ERROR_SUCCESS) {
95629bd2886SAlan Wright 			info502->shi502_reserved = sd.sd_size;
95729bd2886SAlan Wright 			info502->shi502_security_descriptor = sd.sd_buf;
95829bd2886SAlan Wright 		} else {
95929bd2886SAlan Wright 			info502->shi502_reserved = 0;
96029bd2886SAlan Wright 			info502->shi502_security_descriptor = NULL;
9618d7e4166Sjose borrego 		}
9628d7e4166Sjose borrego 
96329bd2886SAlan Wright 		param->result.ru.info502 = info502;
9648d7e4166Sjose borrego 		break;
9658d7e4166Sjose borrego 
96629bd2886SAlan Wright 	case 503:
96729bd2886SAlan Wright 		info503 = &info->nsg_info503;
96829bd2886SAlan Wright 		info503->shi503_netname = netname;
96929bd2886SAlan Wright 		info503->shi503_comment = comment;
97029bd2886SAlan Wright 		info503->shi503_path =
97129bd2886SAlan Wright 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
97229bd2886SAlan Wright 		info503->shi503_passwd = NULL;
97329bd2886SAlan Wright 		info503->shi503_type = si.shr_type;
97429bd2886SAlan Wright 		info503->shi503_permissions = 0;
97529bd2886SAlan Wright 		info503->shi503_max_uses = SHI_USES_UNLIMITED;
97629bd2886SAlan Wright 		info503->shi503_current_uses = 0;
97729bd2886SAlan Wright 		info503->shi503_servername = NULL;
97829bd2886SAlan Wright 
97929bd2886SAlan Wright 		status = srvsvc_share_getsd(mxa, &si, &sd);
98029bd2886SAlan Wright 		if (status == ERROR_SUCCESS) {
98129bd2886SAlan Wright 			info503->shi503_reserved = sd.sd_size;
98229bd2886SAlan Wright 			info503->shi503_security_descriptor = sd.sd_buf;
98329bd2886SAlan Wright 		} else {
98429bd2886SAlan Wright 			info503->shi503_reserved = 0;
98529bd2886SAlan Wright 			info503->shi503_security_descriptor = NULL;
986da6c28aaSamw 		}
9878d7e4166Sjose borrego 
98829bd2886SAlan Wright 		param->result.ru.info503 = info503;
98929bd2886SAlan Wright 		break;
99029bd2886SAlan Wright 
99129bd2886SAlan Wright 	case 1004:
99229bd2886SAlan Wright 		info1004 = &info->nsg_info1004;
99329bd2886SAlan Wright 		info1004->shi1004_comment = comment;
99429bd2886SAlan Wright 		param->result.ru.info1004 = info1004;
99529bd2886SAlan Wright 		break;
99629bd2886SAlan Wright 
99729bd2886SAlan Wright 	case 1005:
99829bd2886SAlan Wright 		info1005 = &info->nsg_info1005;
999e3f2c991SKeyur Desai 		info1005->shi1005_flags = srvsvc_get_share_flags(&si);
1000da6c28aaSamw 		param->result.ru.info1005 = info1005;
1001da6c28aaSamw 		break;
1002da6c28aaSamw 
10038d7e4166Sjose borrego 	case 1006:
100429bd2886SAlan Wright 		info1006 = &info->nsg_info1006;
10058d7e4166Sjose borrego 		info1006->shi1006_max_uses = SHI_USES_UNLIMITED;
10068d7e4166Sjose borrego 		param->result.ru.info1006 = info1006;
10078d7e4166Sjose borrego 		break;
10088d7e4166Sjose borrego 
100929bd2886SAlan Wright 	case 1501:
101029bd2886SAlan Wright 		info1501 = &info->nsg_info1501;
10113db3f65cSamw 
101229bd2886SAlan Wright 		status = srvsvc_share_getsd(mxa, &si, &sd);
101329bd2886SAlan Wright 		if (status == ERROR_SUCCESS) {
10145831d79bSGordon Ross 			info1501->shi1501_reserved = sd.sd_size;
10155831d79bSGordon Ross 			info1501->shi1501_security_descriptor = sd.sd_buf;
101629bd2886SAlan Wright 		} else {
10175831d79bSGordon Ross 			info1501->shi1501_reserved = 0;
10185831d79bSGordon Ross 			info1501->shi1501_security_descriptor = NULL;
10193db3f65cSamw 		}
10203db3f65cSamw 
102129bd2886SAlan Wright 		param->result.ru.info1501 = info1501;
1022da6c28aaSamw 		break;
1023da6c28aaSamw 
1024da6c28aaSamw 	default:
1025da6c28aaSamw 		status = ERROR_ACCESS_DENIED;
1026da6c28aaSamw 		break;
1027da6c28aaSamw 	}
1028da6c28aaSamw 
1029da6c28aaSamw 	if (status != ERROR_SUCCESS)
1030da6c28aaSamw 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
1031da6c28aaSamw 	else
1032da6c28aaSamw 		param->result.switch_value = param->level;
1033da6c28aaSamw 
1034da6c28aaSamw 	param->status = status;
10358d7e4166Sjose borrego 	return (NDR_DRC_OK);
1036da6c28aaSamw }
1037da6c28aaSamw 
103829bd2886SAlan Wright static uint32_t
srvsvc_share_getsd(ndr_xa_t * mxa,smb_share_t * si,srvsvc_sd_t * sd)103929bd2886SAlan Wright srvsvc_share_getsd(ndr_xa_t *mxa, smb_share_t *si, srvsvc_sd_t *sd)
104029bd2886SAlan Wright {
104129bd2886SAlan Wright 	uint32_t status;
104229bd2886SAlan Wright 
104329bd2886SAlan Wright 	status = srvsvc_sd_get(si, NULL, &sd->sd_size);
104429bd2886SAlan Wright 	if (status != ERROR_SUCCESS) {
104529bd2886SAlan Wright 		if (status == ERROR_PATH_NOT_FOUND) {
104629bd2886SAlan Wright 			bzero(sd, sizeof (srvsvc_sd_t));
104729bd2886SAlan Wright 			status = ERROR_SUCCESS;
104829bd2886SAlan Wright 		}
104929bd2886SAlan Wright 
105029bd2886SAlan Wright 		return (status);
105129bd2886SAlan Wright 	}
105229bd2886SAlan Wright 
105329bd2886SAlan Wright 	if ((sd->sd_buf = NDR_MALLOC(mxa, sd->sd_size)) == NULL)
105429bd2886SAlan Wright 		return (ERROR_NOT_ENOUGH_MEMORY);
105529bd2886SAlan Wright 
105629bd2886SAlan Wright 	status = srvsvc_sd_get(si, sd->sd_buf, NULL);
105729bd2886SAlan Wright 	if (status == ERROR_PATH_NOT_FOUND) {
105829bd2886SAlan Wright 		bzero(sd, sizeof (srvsvc_sd_t));
105929bd2886SAlan Wright 		status = ERROR_SUCCESS;
106029bd2886SAlan Wright 	}
106129bd2886SAlan Wright 
106229bd2886SAlan Wright 	return (status);
106329bd2886SAlan Wright }
1064da6c28aaSamw 
1065da6c28aaSamw /*
1066da6c28aaSamw  * srvsvc_s_NetShareSetInfo
1067da6c28aaSamw  *
1068da6c28aaSamw  * This call is made by SrvMgr to set share information.
106929bd2886SAlan Wright  * Only power users groups can manage shares.
107029bd2886SAlan Wright  *
107129bd2886SAlan Wright  * To avoid misleading errors, we don't report an error
107229bd2886SAlan Wright  * when a FS doesn't support ACLs on shares.
1073da6c28aaSamw  *
1074da6c28aaSamw  * Returns Win32 error codes.
1075da6c28aaSamw  */
1076da6c28aaSamw static int
srvsvc_s_NetShareSetInfo(void * arg,ndr_xa_t * mxa)10778d7e4166Sjose borrego srvsvc_s_NetShareSetInfo(void *arg, ndr_xa_t *mxa)
1078da6c28aaSamw {
1079da6c28aaSamw 	struct mlsm_NetShareSetInfo *param = arg;
108029bd2886SAlan Wright 	struct mslm_NetShareInfo_0 *info0;
108129bd2886SAlan Wright 	struct mslm_NetShareInfo_1 *info1;
108229bd2886SAlan Wright 	struct mslm_NetShareInfo_2 *info2;
108329bd2886SAlan Wright 	struct mslm_NetShareInfo_501 *info501;
108429bd2886SAlan Wright 	struct mslm_NetShareInfo_502 *info502;
108529bd2886SAlan Wright 	struct mslm_NetShareInfo_503 *info503;
108629bd2886SAlan Wright 	struct mslm_NetShareInfo_1004 *info1004;
108729bd2886SAlan Wright 	struct mslm_NetShareInfo_1005 *info1005;
108829bd2886SAlan Wright 	struct mslm_NetShareInfo_1501 *info1501;
108929bd2886SAlan Wright 	static DWORD parm_err = 0;
109029bd2886SAlan Wright 	srvsvc_netshare_setinfo_t info;
109129bd2886SAlan Wright 	smb_share_t si;
109229bd2886SAlan Wright 	uint8_t *sdbuf;
109329bd2886SAlan Wright 	int32_t native_os;
109429bd2886SAlan Wright 	DWORD status;
109529bd2886SAlan Wright 
109629bd2886SAlan Wright 	native_os = ndr_native_os(mxa);
1097da6c28aaSamw 
109829bd2886SAlan Wright 	if (!ndr_is_poweruser(mxa)) {
109929bd2886SAlan Wright 		status = ERROR_ACCESS_DENIED;
110029bd2886SAlan Wright 		goto netsharesetinfo_exit;
110129bd2886SAlan Wright 	}
1102da6c28aaSamw 
110329bd2886SAlan Wright 	if (smb_shr_get((char *)param->netname, &si) != NERR_Success) {
110429bd2886SAlan Wright 		status = ERROR_INVALID_NETNAME;
110529bd2886SAlan Wright 		goto netsharesetinfo_exit;
110629bd2886SAlan Wright 	}
110729bd2886SAlan Wright 
110829bd2886SAlan Wright 	if (param->result.ru.nullptr == NULL) {
110929bd2886SAlan Wright 		status = ERROR_INVALID_PARAMETER;
111029bd2886SAlan Wright 		goto netsharesetinfo_exit;
111129bd2886SAlan Wright 	}
111229bd2886SAlan Wright 
111329bd2886SAlan Wright 	bzero(&info, sizeof (srvsvc_netshare_setinfo_t));
111429bd2886SAlan Wright 
111529bd2886SAlan Wright 	switch (param->level) {
111629bd2886SAlan Wright 	case 0:
111729bd2886SAlan Wright 		info0 = (struct mslm_NetShareInfo_0 *)param->result.ru.info0;
111829bd2886SAlan Wright 		info.nss_netname = (char *)info0->shi0_netname;
111929bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
112029bd2886SAlan Wright 		break;
112129bd2886SAlan Wright 
112229bd2886SAlan Wright 	case 1:
112329bd2886SAlan Wright 		info1 = (struct mslm_NetShareInfo_1 *)param->result.ru.info1;
112429bd2886SAlan Wright 		info.nss_netname = (char *)info1->shi1_netname;
112529bd2886SAlan Wright 		info.nss_comment = (char *)info1->shi1_comment;
112629bd2886SAlan Wright 		info.nss_type = info1->shi1_type;
112729bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
112829bd2886SAlan Wright 		break;
112929bd2886SAlan Wright 
113029bd2886SAlan Wright 	case 2:
113129bd2886SAlan Wright 		info2 = (struct mslm_NetShareInfo_2 *)param->result.ru.info2;
113229bd2886SAlan Wright 		info.nss_netname = (char *)info2->shi2_netname;
113329bd2886SAlan Wright 		info.nss_comment = (char *)info2->shi2_comment;
113429bd2886SAlan Wright 		info.nss_path = (char *)info2->shi2_path;
113529bd2886SAlan Wright 		info.nss_type = info2->shi2_type;
113629bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
113729bd2886SAlan Wright 		break;
113829bd2886SAlan Wright 
113929bd2886SAlan Wright 	case 501:
114029bd2886SAlan Wright 		info501 = (struct mslm_NetShareInfo_501 *)
114129bd2886SAlan Wright 		    param->result.ru.info501;
114229bd2886SAlan Wright 		info.nss_netname = (char *)info501->shi501_netname;
114329bd2886SAlan Wright 		info.nss_comment = (char *)info501->shi501_comment;
114429bd2886SAlan Wright 		info.nss_type = info501->shi501_type;
114529bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
1146e3f2c991SKeyur Desai 		if (status == ERROR_SUCCESS)
1147e3f2c991SKeyur Desai 			status = srvsvc_update_share_flags(&si,
1148e3f2c991SKeyur Desai 			    info501->shi501_flags);
114929bd2886SAlan Wright 		break;
115029bd2886SAlan Wright 
115129bd2886SAlan Wright 	case 502:
115229bd2886SAlan Wright 		info502 = (struct mslm_NetShareInfo_502 *)
115329bd2886SAlan Wright 		    param->result.ru.info502;
115429bd2886SAlan Wright 		info.nss_netname = (char *)info502->shi502_netname;
115529bd2886SAlan Wright 		info.nss_comment = (char *)info502->shi502_comment;
115629bd2886SAlan Wright 		info.nss_path = (char *)info502->shi502_path;
115729bd2886SAlan Wright 		info.nss_type = info502->shi502_type;
115829bd2886SAlan Wright 		info.nss_sd.sd_buf = info502->shi502_security_descriptor;
115929bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
116029bd2886SAlan Wright 		break;
116129bd2886SAlan Wright 
116229bd2886SAlan Wright 	case 503:
116329bd2886SAlan Wright 		info503 = (struct mslm_NetShareInfo_503 *)
116429bd2886SAlan Wright 		    param->result.ru.info503;
116529bd2886SAlan Wright 		info.nss_netname = (char *)info503->shi503_netname;
116629bd2886SAlan Wright 		info.nss_comment = (char *)info503->shi503_comment;
116729bd2886SAlan Wright 		info.nss_path = (char *)info503->shi503_path;
116829bd2886SAlan Wright 		info.nss_type = info503->shi503_type;
116929bd2886SAlan Wright 		info.nss_sd.sd_buf = info503->shi503_security_descriptor;
117029bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
117129bd2886SAlan Wright 		break;
117229bd2886SAlan Wright 
117329bd2886SAlan Wright 	case 1004:
117429bd2886SAlan Wright 		info1004 = (struct mslm_NetShareInfo_1004 *)
117529bd2886SAlan Wright 		    param->result.ru.info1004;
117629bd2886SAlan Wright 		info.nss_comment = (char *)info1004->shi1004_comment;
117729bd2886SAlan Wright 		status = srvsvc_modify_share(&si, &info);
117829bd2886SAlan Wright 		break;
117929bd2886SAlan Wright 
118029bd2886SAlan Wright 	case 1005:
118129bd2886SAlan Wright 		info1005 = (struct mslm_NetShareInfo_1005 *)
118229bd2886SAlan Wright 		    param->result.ru.info1005;
118329bd2886SAlan Wright 		status = srvsvc_update_share_flags(&si,
118429bd2886SAlan Wright 		    info1005->shi1005_flags);
118529bd2886SAlan Wright 		break;
118629bd2886SAlan Wright 
118729bd2886SAlan Wright 	case 1006:
118829bd2886SAlan Wright 		/*
118929bd2886SAlan Wright 		 * We don't limit the maximum number of concurrent
119029bd2886SAlan Wright 		 * connections to a share.
119129bd2886SAlan Wright 		 */
119229bd2886SAlan Wright 		status = ERROR_SUCCESS;
119329bd2886SAlan Wright 		break;
119429bd2886SAlan Wright 
119529bd2886SAlan Wright 	case 1501:
119629bd2886SAlan Wright 		info1501 = (struct mslm_NetShareInfo_1501 *)
119729bd2886SAlan Wright 		    param->result.ru.info1501;
119829bd2886SAlan Wright 		sdbuf = info1501->shi1501_security_descriptor;
119929bd2886SAlan Wright 		status = ERROR_SUCCESS;
120029bd2886SAlan Wright 
120129bd2886SAlan Wright 		if (sdbuf != NULL) {
120229bd2886SAlan Wright 			status = srvsvc_sd_set(&si, sdbuf);
120329bd2886SAlan Wright 			if (status == ERROR_PATH_NOT_FOUND)
120429bd2886SAlan Wright 				status = ERROR_SUCCESS;
120529bd2886SAlan Wright 		}
120629bd2886SAlan Wright 		break;
1207da6c28aaSamw 
120829bd2886SAlan Wright 	default:
120929bd2886SAlan Wright 		status = ERROR_ACCESS_DENIED;
121029bd2886SAlan Wright 		break;
121129bd2886SAlan Wright 	}
121229bd2886SAlan Wright 
121329bd2886SAlan Wright netsharesetinfo_exit:
121429bd2886SAlan Wright 	if (status != ERROR_SUCCESS)
121529bd2886SAlan Wright 		bzero(param, sizeof (struct mlsm_NetShareSetInfo));
121629bd2886SAlan Wright 
121729bd2886SAlan Wright 	param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
121829bd2886SAlan Wright 	param->status = status;
12198d7e4166Sjose borrego 	return (NDR_DRC_OK);
1220da6c28aaSamw }
1221da6c28aaSamw 
122229bd2886SAlan Wright static uint32_t
srvsvc_modify_share(smb_share_t * si,srvsvc_netshare_setinfo_t * info)122329bd2886SAlan Wright srvsvc_modify_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
122429bd2886SAlan Wright {
122529bd2886SAlan Wright 	uint32_t nerr = NERR_Success;
122629bd2886SAlan Wright 
122729bd2886SAlan Wright 	if (si->shr_flags & SMB_SHRF_TRANS)
122829bd2886SAlan Wright 		return (srvsvc_modify_transient_share(si, info));
122929bd2886SAlan Wright 
123029bd2886SAlan Wright 	if (info->nss_sd.sd_buf != NULL) {
123129bd2886SAlan Wright 		nerr = srvsvc_sd_set(si, info->nss_sd.sd_buf);
123229bd2886SAlan Wright 		if (nerr == ERROR_PATH_NOT_FOUND)
123329bd2886SAlan Wright 			nerr = NERR_Success;
123429bd2886SAlan Wright 	}
123529bd2886SAlan Wright 
123629bd2886SAlan Wright 	if ((nerr = srvsvc_sa_modify(si, info)) == NERR_Success)
123729bd2886SAlan Wright 		nerr = smb_shr_modify(si);
123829bd2886SAlan Wright 
123929bd2886SAlan Wright 	return (nerr);
124029bd2886SAlan Wright }
124129bd2886SAlan Wright 
124229bd2886SAlan Wright /*
124329bd2886SAlan Wright  * Update transient shares.  This includes autohome shares.
124429bd2886SAlan Wright  */
124529bd2886SAlan Wright static uint32_t
srvsvc_modify_transient_share(smb_share_t * si,srvsvc_netshare_setinfo_t * info)124629bd2886SAlan Wright srvsvc_modify_transient_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
124729bd2886SAlan Wright {
124829bd2886SAlan Wright 	uint32_t nerr;
124929bd2886SAlan Wright 
125029bd2886SAlan Wright 	if (info->nss_netname != NULL && info->nss_netname[0] != '\0' &&
1251bbf6f00cSJordan Brown 	    smb_strcasecmp(info->nss_netname, si->shr_name, 0) != 0) {
125229bd2886SAlan Wright 		nerr = smb_shr_rename(si->shr_name, info->nss_netname);
125329bd2886SAlan Wright 		if (nerr != NERR_Success)
125429bd2886SAlan Wright 			return (nerr);
125529bd2886SAlan Wright 
125629bd2886SAlan Wright 		(void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN);
125729bd2886SAlan Wright 	}
125829bd2886SAlan Wright 
125929bd2886SAlan Wright 	if ((info->nss_comment != NULL) &&
126029bd2886SAlan Wright 	    (strcmp(info->nss_comment, si->shr_cmnt) != 0)) {
126129bd2886SAlan Wright 		(void) strlcpy(si->shr_cmnt, info->nss_comment,
126229bd2886SAlan Wright 		    SMB_SHARE_CMNT_MAX);
126329bd2886SAlan Wright 
126429bd2886SAlan Wright 		if ((nerr = smb_shr_modify(si)) != NERR_Success)
126529bd2886SAlan Wright 			return (nerr);
126629bd2886SAlan Wright 	}
126729bd2886SAlan Wright 
126829bd2886SAlan Wright 	return (NERR_Success);
126929bd2886SAlan Wright }
127029bd2886SAlan Wright 
1271e3f2c991SKeyur Desai /*
1272e3f2c991SKeyur Desai  * srvsvc_update_share_flags
1273e3f2c991SKeyur Desai  *
1274e3f2c991SKeyur Desai  * This function updates flags for shares.
1275e3f2c991SKeyur Desai  * Flags for Persistent shares are updated in both libshare and the local cache.
1276e3f2c991SKeyur Desai  * Flags for Transient shares are updated only in the local cache.
1277e3f2c991SKeyur Desai  */
127829bd2886SAlan Wright static uint32_t
srvsvc_update_share_flags(smb_share_t * si,uint32_t shi_flags)127929bd2886SAlan Wright srvsvc_update_share_flags(smb_share_t *si, uint32_t shi_flags)
128029bd2886SAlan Wright {
128129bd2886SAlan Wright 	uint32_t nerr = NERR_Success;
1282e3f2c991SKeyur Desai 	uint32_t flag = 0;
1283e3f2c991SKeyur Desai 	char *csc_value;
1284e3f2c991SKeyur Desai 	char *abe_value = "false";
1285e3f2c991SKeyur Desai 	nvlist_t *nvl;
1286e3f2c991SKeyur Desai 	int err = 0;
1287e3f2c991SKeyur Desai 
1288e3f2c991SKeyur Desai 	if (shi_flags & SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM) {
1289e3f2c991SKeyur Desai 		flag = SMB_SHRF_ABE;
1290e3f2c991SKeyur Desai 		abe_value = "true";
1291e3f2c991SKeyur Desai 	}
1292e3f2c991SKeyur Desai 
1293e3f2c991SKeyur Desai 	si->shr_flags &= ~SMB_SHRF_ABE;
1294e3f2c991SKeyur Desai 	si->shr_flags |= flag;
129529bd2886SAlan Wright 
129629bd2886SAlan Wright 	switch ((shi_flags & CSC_MASK)) {
129729bd2886SAlan Wright 	case CSC_CACHE_AUTO_REINT:
1298e3f2c991SKeyur Desai 		flag = SMB_SHRF_CSC_AUTO;
129929bd2886SAlan Wright 		break;
130029bd2886SAlan Wright 	case CSC_CACHE_VDO:
1301e3f2c991SKeyur Desai 		flag = SMB_SHRF_CSC_VDO;
130229bd2886SAlan Wright 		break;
130329bd2886SAlan Wright 	case CSC_CACHE_NONE:
1304e3f2c991SKeyur Desai 		flag = SMB_SHRF_CSC_DISABLED;
130529bd2886SAlan Wright 		break;
130629bd2886SAlan Wright 	case CSC_CACHE_MANUAL_REINT:
1307e3f2c991SKeyur Desai 		flag = SMB_SHRF_CSC_MANUAL;
130829bd2886SAlan Wright 		break;
130929bd2886SAlan Wright 	default:
1310e3f2c991SKeyur Desai 		return (NERR_InternalError);
131129bd2886SAlan Wright 	}
131229bd2886SAlan Wright 
131329bd2886SAlan Wright 	si->shr_flags &= ~SMB_SHRF_CSC_MASK;
1314e3f2c991SKeyur Desai 	si->shr_flags |= flag;
131529bd2886SAlan Wright 
131629bd2886SAlan Wright 	if ((si->shr_flags & SMB_SHRF_TRANS) == 0) {
1317e3f2c991SKeyur Desai 		csc_value = smb_shr_sa_csc_name(si);
1318e3f2c991SKeyur Desai 
1319e3f2c991SKeyur Desai 		if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
1320e3f2c991SKeyur Desai 			return (NERR_InternalError);
1321e3f2c991SKeyur Desai 
1322e3f2c991SKeyur Desai 		err |= nvlist_add_string(nvl, SHOPT_CSC, csc_value);
1323e3f2c991SKeyur Desai 		err |= nvlist_add_string(nvl, SHOPT_ABE, abe_value);
1324e3f2c991SKeyur Desai 		if (err) {
1325e3f2c991SKeyur Desai 			nvlist_free(nvl);
1326e3f2c991SKeyur Desai 			return (NERR_InternalError);
1327e3f2c991SKeyur Desai 		}
1328e3f2c991SKeyur Desai 
1329e3f2c991SKeyur Desai 		nerr = srvsvc_sa_setprop(si, nvl);
1330e3f2c991SKeyur Desai 		nvlist_free(nvl);
1331e3f2c991SKeyur Desai 
1332e3f2c991SKeyur Desai 		if (nerr != NERR_Success)
133329bd2886SAlan Wright 			return (nerr);
133429bd2886SAlan Wright 	}
133529bd2886SAlan Wright 
133629bd2886SAlan Wright 	return (smb_shr_modify(si));
133729bd2886SAlan Wright }
133829bd2886SAlan Wright 
1339e3f2c991SKeyur Desai static uint32_t
srvsvc_get_share_flags(smb_share_t * si)1340e3f2c991SKeyur Desai srvsvc_get_share_flags(smb_share_t *si)
1341e3f2c991SKeyur Desai {
1342e3f2c991SKeyur Desai 	uint32_t flags = 0;
1343cb174861Sjoyce mcintosh 	boolean_t shortnames = B_TRUE;
1344e3f2c991SKeyur Desai 
1345e3f2c991SKeyur Desai 	switch (si->shr_flags & SMB_SHRF_CSC_MASK) {
1346e3f2c991SKeyur Desai 	case SMB_SHRF_CSC_DISABLED:
1347e3f2c991SKeyur Desai 		flags |= CSC_CACHE_NONE;
1348e3f2c991SKeyur Desai 		break;
1349e3f2c991SKeyur Desai 	case SMB_SHRF_CSC_AUTO:
1350e3f2c991SKeyur Desai 		flags |= CSC_CACHE_AUTO_REINT;
1351e3f2c991SKeyur Desai 		break;
1352e3f2c991SKeyur Desai 	case SMB_SHRF_CSC_VDO:
1353e3f2c991SKeyur Desai 		flags |= CSC_CACHE_VDO;
1354e3f2c991SKeyur Desai 		break;
1355e3f2c991SKeyur Desai 	case SMB_SHRF_CSC_MANUAL:
1356e3f2c991SKeyur Desai 	default:
1357e3f2c991SKeyur Desai 		/*
1358e3f2c991SKeyur Desai 		 * Default to CSC_CACHE_MANUAL_REINT.
1359e3f2c991SKeyur Desai 		 */
1360e3f2c991SKeyur Desai 		break;
1361e3f2c991SKeyur Desai 	}
1362e3f2c991SKeyur Desai 
1363e3f2c991SKeyur Desai 	if (si->shr_flags & SMB_SHRF_ABE)
1364e3f2c991SKeyur Desai 		flags |= SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM;
1365e3f2c991SKeyur Desai 
1366cb174861Sjoyce mcintosh 	/* if 'smb' zfs property: shortnames=disabled */
1367cb174861Sjoyce mcintosh 	if ((smb_kmod_shareinfo(si->shr_name, &shortnames) == 0) &&
1368cb174861Sjoyce mcintosh 	    (shortnames == B_FALSE)) {
1369cb174861Sjoyce mcintosh 		flags |= SHI1005_FLAGS_ALLOW_NAMESPACE_CACHING;
1370cb174861Sjoyce mcintosh 	}
1371cb174861Sjoyce mcintosh 
1372e3f2c991SKeyur Desai 	return (flags);
1373e3f2c991SKeyur Desai }
1374e3f2c991SKeyur Desai 
1375da6c28aaSamw /*
1376da6c28aaSamw  * srvsvc_s_NetSessionEnum
1377da6c28aaSamw  *
137889dc44ceSjose borrego  * Level 1 request is made by (Server Manager (srvmgr) on NT Server when
137989dc44ceSjose borrego  * the user info icon is selected.
1380da6c28aaSamw  *
138189dc44ceSjose borrego  * On success, the return value is NERR_Success.
138289dc44ceSjose borrego  * On error, the return value can be one of the following error codes:
1383da6c28aaSamw  *
1384da6c28aaSamw  * ERROR_ACCESS_DENIED      The user does not have access to the requested
1385da6c28aaSamw  *                          information.
138689dc44ceSjose borrego  * ERROR_INVALID_LEVEL      The value specified for the level is invalid.
1387da6c28aaSamw  * ERROR_INVALID_PARAMETER  The specified parameter is invalid.
138889dc44ceSjose borrego  * ERROR_MORE_DATA          More entries are available. Specify a large
1389da6c28aaSamw  *                          enough buffer to receive all entries.
1390da6c28aaSamw  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
139189dc44ceSjose borrego  * NERR_ClientNameNotFound  A session does not exist with the computer name.
1392da6c28aaSamw  * NERR_InvalidComputer     The computer name is invalid.
1393da6c28aaSamw  * NERR_UserNotFound        The user name could not be found.
1394da6c28aaSamw  */
1395da6c28aaSamw static int
srvsvc_s_NetSessionEnum(void * arg,ndr_xa_t * mxa)13968d7e4166Sjose borrego srvsvc_s_NetSessionEnum(void *arg, ndr_xa_t *mxa)
1397da6c28aaSamw {
13981fcced4cSJordan Brown 	struct mslm_NetSessionEnum	*param = arg;
13991fcced4cSJordan Brown 	srvsvc_infonres_t		*info;
14001fcced4cSJordan Brown 	smb_netsvc_t			*ns;
14011fcced4cSJordan Brown 	smb_svcenum_t			se;
14021fcced4cSJordan Brown 	DWORD				status = ERROR_SUCCESS;
1403da6c28aaSamw 
14041fcced4cSJordan Brown 	if (!ndr_is_admin(mxa)) {
14051fcced4cSJordan Brown 		status = ERROR_ACCESS_DENIED;
14061fcced4cSJordan Brown 		goto srvsvc_netsessionenum_error;
1407da6c28aaSamw 	}
1408da6c28aaSamw 
14091fcced4cSJordan Brown 	if ((info = NDR_NEW(mxa, srvsvc_infonres_t)) == NULL) {
14101fcced4cSJordan Brown 		status = ERROR_NOT_ENOUGH_MEMORY;
14111fcced4cSJordan Brown 		goto srvsvc_netsessionenum_error;
14121fcced4cSJordan Brown 	}
14131fcced4cSJordan Brown 
14141fcced4cSJordan Brown 	info->entriesread = 0;
14151fcced4cSJordan Brown 	info->entries = NULL;
1416da6c28aaSamw 	param->result.level = param->level;
14171fcced4cSJordan Brown 	param->result.bufptr.p = info;
1418da6c28aaSamw 
14191fcced4cSJordan Brown 	if ((param->total_entries = srvsvc_open_sessions()) == 0) {
14201fcced4cSJordan Brown 		param->resume_handle = NULL;
14211fcced4cSJordan Brown 		param->status = ERROR_SUCCESS;
142289dc44ceSjose borrego 		return (NDR_DRC_OK);
14231fcced4cSJordan Brown 	}
14241fcced4cSJordan Brown 
14251fcced4cSJordan Brown 	bzero(&se, sizeof (smb_svcenum_t));
14261fcced4cSJordan Brown 	se.se_type = SMB_SVCENUM_TYPE_USER;
14271fcced4cSJordan Brown 	se.se_level = param->level;
14281fcced4cSJordan Brown 	se.se_ntotal = param->total_entries;
14291fcced4cSJordan Brown 	se.se_nlimit = se.se_ntotal;
14301fcced4cSJordan Brown 
14311fcced4cSJordan Brown 	if (param->resume_handle) {
14321fcced4cSJordan Brown 		se.se_resume = *param->resume_handle;
14331fcced4cSJordan Brown 		se.se_nskip = se.se_resume;
14341fcced4cSJordan Brown 		*param->resume_handle = 0;
14351fcced4cSJordan Brown 	}
1436da6c28aaSamw 
1437da6c28aaSamw 	switch (param->level) {
1438da6c28aaSamw 	case 0:
14391fcced4cSJordan Brown 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_0,
14401fcced4cSJordan Brown 		    se.se_nlimit);
1441da6c28aaSamw 		break;
1442da6c28aaSamw 	case 1:
14431fcced4cSJordan Brown 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_1,
14441fcced4cSJordan Brown 		    se.se_nlimit);
1445da6c28aaSamw 		break;
144629bd2886SAlan Wright 	case 2:
14471fcced4cSJordan Brown 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_2,
14481fcced4cSJordan Brown 		    se.se_nlimit);
144929bd2886SAlan Wright 		break;
145029bd2886SAlan Wright 	case 10:
14511fcced4cSJordan Brown 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_10,
14521fcced4cSJordan Brown 		    se.se_nlimit);
145329bd2886SAlan Wright 		break;
145429bd2886SAlan Wright 	case 502:
14551fcced4cSJordan Brown 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_502,
14561fcced4cSJordan Brown 		    se.se_nlimit);
145729bd2886SAlan Wright 		break;
1458da6c28aaSamw 	default:
1459da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetSessionEnum));
14601fcced4cSJordan Brown 		param->status = ERROR_INVALID_LEVEL;
14618d7e4166Sjose borrego 		return (NDR_DRC_OK);
1462da6c28aaSamw 	}
1463da6c28aaSamw 
14641fcced4cSJordan Brown 	if (info->entries == NULL) {
14651fcced4cSJordan Brown 		status = ERROR_NOT_ENOUGH_MEMORY;
14661fcced4cSJordan Brown 		goto srvsvc_netsessionenum_error;
146789dc44ceSjose borrego 	}
146889dc44ceSjose borrego 
14691fcced4cSJordan Brown 	if ((ns = smb_kmod_enum_init(&se)) == NULL) {
14701fcced4cSJordan Brown 		status = ERROR_NOT_ENOUGH_MEMORY;
14711fcced4cSJordan Brown 		goto srvsvc_netsessionenum_error;
1472da6c28aaSamw 	}
1473da6c28aaSamw 
14741fcced4cSJordan Brown 	status = srvsvc_NetSessionEnumCommon(mxa, info, ns, &se);
14751fcced4cSJordan Brown 	smb_kmod_enum_fini(ns);
1476da6c28aaSamw 
14771fcced4cSJordan Brown 	if (status != ERROR_SUCCESS)
14781fcced4cSJordan Brown 		goto srvsvc_netsessionenum_error;
147989dc44ceSjose borrego 
14801fcced4cSJordan Brown 	if (param->resume_handle &&
14811fcced4cSJordan Brown 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
14821fcced4cSJordan Brown 		if (se.se_resume < param->total_entries) {
14831fcced4cSJordan Brown 			*param->resume_handle = se.se_resume;
14841fcced4cSJordan Brown 			status = ERROR_MORE_DATA;
148589dc44ceSjose borrego 		}
148629bd2886SAlan Wright 	}
148729bd2886SAlan Wright 
14881fcced4cSJordan Brown 	param->total_entries = info->entriesread;
14891fcced4cSJordan Brown 	param->status = status;
14901fcced4cSJordan Brown 	return (NDR_DRC_OK);
149129bd2886SAlan Wright 
14921fcced4cSJordan Brown srvsvc_netsessionenum_error:
14931fcced4cSJordan Brown 	bzero(param, sizeof (struct mslm_NetSessionEnum));
14941fcced4cSJordan Brown 	param->status = status;
14951fcced4cSJordan Brown 	return (NDR_DRC_OK);
149629bd2886SAlan Wright }
149729bd2886SAlan Wright 
14981fcced4cSJordan Brown static uint32_t
srvsvc_NetSessionEnumCommon(ndr_xa_t * mxa,srvsvc_infonres_t * info,smb_netsvc_t * ns,smb_svcenum_t * se)14991fcced4cSJordan Brown srvsvc_NetSessionEnumCommon(ndr_xa_t *mxa, srvsvc_infonres_t *info,
15001fcced4cSJordan Brown     smb_netsvc_t *ns, smb_svcenum_t *se)
150129bd2886SAlan Wright {
15021fcced4cSJordan Brown 	struct mslm_SESSION_INFO_0	*info0 = info->entries;
15031fcced4cSJordan Brown 	struct mslm_SESSION_INFO_1	*info1 = info->entries;
15041fcced4cSJordan Brown 	struct mslm_SESSION_INFO_2	*info2 = info->entries;
15051fcced4cSJordan Brown 	struct mslm_SESSION_INFO_10	*info10 = info->entries;
15061fcced4cSJordan Brown 	struct mslm_SESSION_INFO_502	*info502 = info->entries;
15071fcced4cSJordan Brown 	smb_netsvcitem_t		*item;
15081fcced4cSJordan Brown 	smb_netuserinfo_t		*user;
15091fcced4cSJordan Brown 	char				*workstation;
15101fcced4cSJordan Brown 	char				account[MAXNAMELEN];
15111fcced4cSJordan Brown 	char				ipaddr_buf[INET6_ADDRSTRLEN];
15121fcced4cSJordan Brown 	uint32_t			logon_time;
15131fcced4cSJordan Brown 	uint32_t			flags;
15141fcced4cSJordan Brown 	uint32_t			entries_read = 0;
15151fcced4cSJordan Brown 
15161fcced4cSJordan Brown 	if (smb_kmod_enum(ns) != 0)
15171fcced4cSJordan Brown 		return (ERROR_INTERNAL_ERROR);
15181fcced4cSJordan Brown 
15191fcced4cSJordan Brown 	item = list_head(&ns->ns_list);
15201fcced4cSJordan Brown 	while (item != NULL) {
15211fcced4cSJordan Brown 		user = &item->nsi_un.nsi_user;
15221fcced4cSJordan Brown 
15231fcced4cSJordan Brown 		workstation = user->ui_workstation;
152429bd2886SAlan Wright 		if (workstation == NULL || *workstation == '\0') {
15251fcced4cSJordan Brown 			(void) smb_inet_ntop(&user->ui_ipaddr, ipaddr_buf,
15261fcced4cSJordan Brown 			    SMB_IPSTRLEN(user->ui_ipaddr.a_family));
152729bd2886SAlan Wright 			workstation = ipaddr_buf;
152829bd2886SAlan Wright 		}
152929bd2886SAlan Wright 
153029bd2886SAlan Wright 		(void) snprintf(account, MAXNAMELEN, "%s\\%s",
15311fcced4cSJordan Brown 		    user->ui_domain, user->ui_account);
153229bd2886SAlan Wright 
15331fcced4cSJordan Brown 		logon_time = time(0) - user->ui_logon_time;
15341fcced4cSJordan Brown 		flags = (user->ui_flags & SMB_ATF_GUEST) ? SESS_GUEST : 0;
153529bd2886SAlan Wright 
15361fcced4cSJordan Brown 		switch (se->se_level) {
15371fcced4cSJordan Brown 		case 0:
15381fcced4cSJordan Brown 			info0->sesi0_cname = NDR_STRDUP(mxa, workstation);
15391fcced4cSJordan Brown 			if (info0->sesi0_cname == NULL)
15401fcced4cSJordan Brown 				return (ERROR_NOT_ENOUGH_MEMORY);
15411fcced4cSJordan Brown 			++info0;
15421fcced4cSJordan Brown 			break;
154329bd2886SAlan Wright 
15441fcced4cSJordan Brown 		case 1:
15451fcced4cSJordan Brown 			info1->sesi1_cname = NDR_STRDUP(mxa, workstation);
15461fcced4cSJordan Brown 			info1->sesi1_uname = NDR_STRDUP(mxa, account);
154729bd2886SAlan Wright 
15481fcced4cSJordan Brown 			if (info1->sesi1_cname == NULL ||
15491fcced4cSJordan Brown 			    info1->sesi1_uname == NULL)
15501fcced4cSJordan Brown 				return (ERROR_NOT_ENOUGH_MEMORY);
155129bd2886SAlan Wright 
15521fcced4cSJordan Brown 			info1->sesi1_nopens = user->ui_numopens;
15531fcced4cSJordan Brown 			info1->sesi1_time = logon_time;
15541fcced4cSJordan Brown 			info1->sesi1_itime = 0;
15551fcced4cSJordan Brown 			info1->sesi1_uflags = flags;
15561fcced4cSJordan Brown 			++info1;
15571fcced4cSJordan Brown 			break;
155829bd2886SAlan Wright 
15591fcced4cSJordan Brown 		case 2:
15601fcced4cSJordan Brown 			info2->sesi2_cname = NDR_STRDUP(mxa, workstation);
15611fcced4cSJordan Brown 			info2->sesi2_uname = NDR_STRDUP(mxa, account);
156229bd2886SAlan Wright 
15631fcced4cSJordan Brown 			if (info2->sesi2_cname == NULL ||
15641fcced4cSJordan Brown 			    info2->sesi2_uname == NULL)
15651fcced4cSJordan Brown 				return (ERROR_NOT_ENOUGH_MEMORY);
156629bd2886SAlan Wright 
15671fcced4cSJordan Brown 			info2->sesi2_nopens = user->ui_numopens;
15681fcced4cSJordan Brown 			info2->sesi2_time = logon_time;
15691fcced4cSJordan Brown 			info2->sesi2_itime = 0;
15701fcced4cSJordan Brown 			info2->sesi2_uflags = flags;
15711fcced4cSJordan Brown 			info2->sesi2_cltype_name = (uint8_t *)"";
15721fcced4cSJordan Brown 			++info2;
15731fcced4cSJordan Brown 			break;
157429bd2886SAlan Wright 
15751fcced4cSJordan Brown 		case 10:
15761fcced4cSJordan Brown 			info10->sesi10_cname = NDR_STRDUP(mxa, workstation);
15771fcced4cSJordan Brown 			info10->sesi10_uname = NDR_STRDUP(mxa, account);
157829bd2886SAlan Wright 
15791fcced4cSJordan Brown 			if (info10->sesi10_cname == NULL ||
15801fcced4cSJordan Brown 			    info10->sesi10_uname == NULL)
15811fcced4cSJordan Brown 				return (ERROR_NOT_ENOUGH_MEMORY);
15821fcced4cSJordan Brown 
15831fcced4cSJordan Brown 			info10->sesi10_time = logon_time;
15841fcced4cSJordan Brown 			info10->sesi10_itime = 0;
15851fcced4cSJordan Brown 			++info10;
15861fcced4cSJordan Brown 			break;
158729bd2886SAlan Wright 
15881fcced4cSJordan Brown 		case 502:
15891fcced4cSJordan Brown 			info502->sesi502_cname = NDR_STRDUP(mxa, workstation);
15901fcced4cSJordan Brown 			info502->sesi502_uname = NDR_STRDUP(mxa, account);
15911fcced4cSJordan Brown 
15921fcced4cSJordan Brown 			if (info502->sesi502_cname == NULL ||
15931fcced4cSJordan Brown 			    info502->sesi502_uname == NULL)
15941fcced4cSJordan Brown 				return (ERROR_NOT_ENOUGH_MEMORY);
15951fcced4cSJordan Brown 
15961fcced4cSJordan Brown 			info502->sesi502_nopens = user->ui_numopens;
15971fcced4cSJordan Brown 			info502->sesi502_time = logon_time;
15981fcced4cSJordan Brown 			info502->sesi502_itime = 0;
15991fcced4cSJordan Brown 			info502->sesi502_uflags = flags;
16001fcced4cSJordan Brown 			info502->sesi502_cltype_name = (uint8_t *)"";
16011fcced4cSJordan Brown 			info502->sesi502_transport = (uint8_t *)"";
16021fcced4cSJordan Brown 			++info502;
16031fcced4cSJordan Brown 			break;
160429bd2886SAlan Wright 
16051fcced4cSJordan Brown 		default:
16061fcced4cSJordan Brown 			return (ERROR_INVALID_LEVEL);
160729bd2886SAlan Wright 		}
160829bd2886SAlan Wright 
16091fcced4cSJordan Brown 		++entries_read;
16101fcced4cSJordan Brown 		item = list_next(&ns->ns_list, item);
161129bd2886SAlan Wright 	}
161229bd2886SAlan Wright 
16131fcced4cSJordan Brown 	info->entriesread = entries_read;
161429bd2886SAlan Wright 	return (ERROR_SUCCESS);
161529bd2886SAlan Wright }
161629bd2886SAlan Wright 
1617da6c28aaSamw /*
1618da6c28aaSamw  * srvsvc_s_NetSessionDel
1619da6c28aaSamw  *
1620da6c28aaSamw  * Ends a network session between a server and a workstation.
1621da6c28aaSamw  * On NT only members of the Administrators or Account Operators
1622da6c28aaSamw  * local groups are permitted to use NetSessionDel.
1623da6c28aaSamw  *
16241fcced4cSJordan Brown  * If unc_clientname is NULL, all sessions associated with the
16251fcced4cSJordan Brown  * specified user will be disconnected.
16261fcced4cSJordan Brown  *
16271fcced4cSJordan Brown  * If username is NULL, all sessions from the specified client
16281fcced4cSJordan Brown  * will be disconnected.
16291fcced4cSJordan Brown  *
1630da6c28aaSamw  * Return Values
16311fcced4cSJordan Brown  * On success, the return value is NERR_Success/ERROR_SUCCESS.
16321fcced4cSJordan Brown  * On failure, the return value can be one of the following errors:
1633da6c28aaSamw  *
16345831d79bSGordon Ross  * ERROR_ACCESS_DENIED		The user does not have access to the
16355831d79bSGordon Ross  *				requested information.
1636da6c28aaSamw  * ERROR_INVALID_PARAMETER	The specified parameter is invalid.
1637da6c28aaSamw  * ERROR_NOT_ENOUGH_MEMORY	Insufficient memory is available.
1638da6c28aaSamw  * NERR_ClientNameNotFound	A session does not exist with that
16391fcced4cSJordan Brown  *				computer name.
1640da6c28aaSamw  */
1641da6c28aaSamw static int
srvsvc_s_NetSessionDel(void * arg,ndr_xa_t * mxa)16428d7e4166Sjose borrego srvsvc_s_NetSessionDel(void *arg, ndr_xa_t *mxa)
1643da6c28aaSamw {
16441fcced4cSJordan Brown 	static struct {
16451fcced4cSJordan Brown 		int errnum;
16461fcced4cSJordan Brown 		int nerr;
16471fcced4cSJordan Brown 	} errmap[] = {
16481fcced4cSJordan Brown 		0,	ERROR_SUCCESS,
16491fcced4cSJordan Brown 		EACCES,	ERROR_ACCESS_DENIED,
16501fcced4cSJordan Brown 		EPERM,	ERROR_ACCESS_DENIED,
16511fcced4cSJordan Brown 		EINVAL,	ERROR_INVALID_PARAMETER,
16521fcced4cSJordan Brown 		ENOMEM,	ERROR_NOT_ENOUGH_MEMORY,
16531fcced4cSJordan Brown 		ENOENT,	NERR_ClientNameNotFound
16541fcced4cSJordan Brown 	};
16551fcced4cSJordan Brown 
1656da6c28aaSamw 	struct mslm_NetSessionDel *param = arg;
16571fcced4cSJordan Brown 	int	i;
16581fcced4cSJordan Brown 	int	rc;
1659da6c28aaSamw 
16601fcced4cSJordan Brown 	if (!ndr_is_admin(mxa)) {
1661da6c28aaSamw 		param->status = ERROR_ACCESS_DENIED;
16628d7e4166Sjose borrego 		return (NDR_DRC_OK);
1663da6c28aaSamw 	}
1664da6c28aaSamw 
16651fcced4cSJordan Brown 	rc = smb_kmod_session_close((char *)param->unc_clientname,
16661fcced4cSJordan Brown 	    (char *)param->username);
16671fcced4cSJordan Brown 
16681fcced4cSJordan Brown 	for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) {
16691fcced4cSJordan Brown 		if (rc == errmap[i].errnum) {
16701fcced4cSJordan Brown 			param->status = errmap[i].nerr;
16711fcced4cSJordan Brown 			return (NDR_DRC_OK);
16721fcced4cSJordan Brown 		}
16731fcced4cSJordan Brown 	}
16741fcced4cSJordan Brown 
16751fcced4cSJordan Brown 	param->status = ERROR_INTERNAL_ERROR;
16768d7e4166Sjose borrego 	return (NDR_DRC_OK);
1677da6c28aaSamw }
1678da6c28aaSamw 
1679da6c28aaSamw static int
srvsvc_s_NetServerGetInfo(void * arg,ndr_xa_t * mxa)16808d7e4166Sjose borrego srvsvc_s_NetServerGetInfo(void *arg, ndr_xa_t *mxa)
1681da6c28aaSamw {
1682da6c28aaSamw 	struct mslm_NetServerGetInfo *param = arg;
1683da6c28aaSamw 	struct mslm_SERVER_INFO_100 *info100;
1684da6c28aaSamw 	struct mslm_SERVER_INFO_101 *info101;
1685da6c28aaSamw 	struct mslm_SERVER_INFO_102 *info102;
168629bd2886SAlan Wright 	struct mslm_SERVER_INFO_502 *info502;
168729bd2886SAlan Wright 	struct mslm_SERVER_INFO_503 *info503;
1688dc20a302Sas 	char sys_comment[SMB_PI_MAX_COMMENT];
1689b89a8333Snatalie li - Sun Microsystems - Irvine United States 	char hostname[NETBIOS_NAME_SZ];
16909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_version_t version;
1691da6c28aaSamw 
1692b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_getnetbiosname(hostname, sizeof (hostname)) != 0) {
1693da6c28aaSamw netservergetinfo_no_memory:
1694da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetServerGetInfo));
1695da6c28aaSamw 		return (ERROR_NOT_ENOUGH_MEMORY);
1696da6c28aaSamw 	}
1697da6c28aaSamw 
1698dc20a302Sas 	(void) smb_config_getstr(SMB_CI_SYS_CMNT, sys_comment,
1699dc20a302Sas 	    sizeof (sys_comment));
1700dc20a302Sas 	if (*sys_comment == '\0')
1701dc20a302Sas 		(void) strcpy(sys_comment, " ");
1702da6c28aaSamw 
17039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_config_get_version(&version);
17049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1705da6c28aaSamw 	switch (param->level) {
1706da6c28aaSamw 	case 100:
17078d7e4166Sjose borrego 		info100 = NDR_NEW(mxa, struct mslm_SERVER_INFO_100);
170889dc44ceSjose borrego 		if (info100 == NULL)
1709da6c28aaSamw 			goto netservergetinfo_no_memory;
1710da6c28aaSamw 
1711da6c28aaSamw 		bzero(info100, sizeof (struct mslm_SERVER_INFO_100));
1712da6c28aaSamw 		info100->sv100_platform_id = SV_PLATFORM_ID_NT;
171389dc44ceSjose borrego 		info100->sv100_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
171489dc44ceSjose borrego 		if (info100->sv100_name == NULL)
1715da6c28aaSamw 			goto netservergetinfo_no_memory;
1716da6c28aaSamw 
1717da6c28aaSamw 		param->result.bufptr.bufptr100 = info100;
1718da6c28aaSamw 		break;
1719da6c28aaSamw 
1720da6c28aaSamw 	case 101:
17218d7e4166Sjose borrego 		info101 = NDR_NEW(mxa, struct mslm_SERVER_INFO_101);
172289dc44ceSjose borrego 		if (info101 == NULL)
1723da6c28aaSamw 			goto netservergetinfo_no_memory;
1724da6c28aaSamw 
1725da6c28aaSamw 		bzero(info101, sizeof (struct mslm_SERVER_INFO_101));
1726da6c28aaSamw 		info101->sv101_platform_id = SV_PLATFORM_ID_NT;
17279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		info101->sv101_version_major = version.sv_major;
17289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		info101->sv101_version_minor = version.sv_minor;
1729fe1c642dSBill Krier 		info101->sv101_type = SV_TYPE_DEFAULT;
173089dc44ceSjose borrego 		info101->sv101_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
1731da6c28aaSamw 		info101->sv101_comment
173289dc44ceSjose borrego 		    = (uint8_t *)NDR_STRDUP(mxa, sys_comment);
1733da6c28aaSamw 
173489dc44ceSjose borrego 		if (info101->sv101_name == NULL ||
173589dc44ceSjose borrego 		    info101->sv101_comment == NULL)
1736da6c28aaSamw 			goto netservergetinfo_no_memory;
1737da6c28aaSamw 
1738da6c28aaSamw 		param->result.bufptr.bufptr101 = info101;
1739da6c28aaSamw 		break;
1740da6c28aaSamw 
1741da6c28aaSamw 	case 102:
17428d7e4166Sjose borrego 		info102 = NDR_NEW(mxa, struct mslm_SERVER_INFO_102);
174389dc44ceSjose borrego 		if (info102 == NULL)
1744da6c28aaSamw 			goto netservergetinfo_no_memory;
1745da6c28aaSamw 
1746da6c28aaSamw 		bzero(info102, sizeof (struct mslm_SERVER_INFO_102));
1747da6c28aaSamw 		info102->sv102_platform_id = SV_PLATFORM_ID_NT;
17489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		info102->sv102_version_major = version.sv_major;
17499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		info102->sv102_version_minor = version.sv_minor;
1750fe1c642dSBill Krier 		info102->sv102_type = SV_TYPE_DEFAULT;
175189dc44ceSjose borrego 		info102->sv102_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
1752da6c28aaSamw 		info102->sv102_comment
175389dc44ceSjose borrego 		    = (uint8_t *)NDR_STRDUP(mxa, sys_comment);
1754da6c28aaSamw 
1755da6c28aaSamw 		/*
1756da6c28aaSamw 		 * The following level 102 fields are defaulted to zero
1757da6c28aaSamw 		 * by virtue of the call to bzero above.
1758da6c28aaSamw 		 *
1759da6c28aaSamw 		 * sv102_users
1760da6c28aaSamw 		 * sv102_disc
1761da6c28aaSamw 		 * sv102_hidden
1762da6c28aaSamw 		 * sv102_announce
1763da6c28aaSamw 		 * sv102_anndelta
1764da6c28aaSamw 		 * sv102_licenses
1765da6c28aaSamw 		 * sv102_userpath
1766da6c28aaSamw 		 */
176789dc44ceSjose borrego 		if (info102->sv102_name == NULL ||
176889dc44ceSjose borrego 		    info102->sv102_comment == NULL)
1769da6c28aaSamw 			goto netservergetinfo_no_memory;
1770da6c28aaSamw 
1771da6c28aaSamw 		param->result.bufptr.bufptr102 = info102;
1772da6c28aaSamw 		break;
1773da6c28aaSamw 
177429bd2886SAlan Wright 	case 502:
177529bd2886SAlan Wright 		info502 = NDR_NEW(mxa, struct mslm_SERVER_INFO_502);
177629bd2886SAlan Wright 		if (info502 == NULL)
177729bd2886SAlan Wright 			goto netservergetinfo_no_memory;
177829bd2886SAlan Wright 
177929bd2886SAlan Wright 		bzero(info502, sizeof (struct mslm_SERVER_INFO_502));
178029bd2886SAlan Wright 		param->result.bufptr.bufptr502 = info502;
178129bd2886SAlan Wright #ifdef SRVSVC_SATISFY_SMBTORTURE
178229bd2886SAlan Wright 		break;
178329bd2886SAlan Wright #else
178429bd2886SAlan Wright 		param->result.level = param->level;
178529bd2886SAlan Wright 		param->status = ERROR_ACCESS_DENIED;
178629bd2886SAlan Wright 		return (NDR_DRC_OK);
178729bd2886SAlan Wright #endif /* SRVSVC_SATISFY_SMBTORTURE */
178829bd2886SAlan Wright 
178929bd2886SAlan Wright 	case 503:
179029bd2886SAlan Wright 		info503 = NDR_NEW(mxa, struct mslm_SERVER_INFO_503);
179129bd2886SAlan Wright 		if (info503 == NULL)
179229bd2886SAlan Wright 			goto netservergetinfo_no_memory;
179329bd2886SAlan Wright 
179429bd2886SAlan Wright 		bzero(info503, sizeof (struct mslm_SERVER_INFO_503));
179529bd2886SAlan Wright 		param->result.bufptr.bufptr503 = info503;
179629bd2886SAlan Wright #ifdef SRVSVC_SATISFY_SMBTORTURE
179729bd2886SAlan Wright 		break;
179829bd2886SAlan Wright #else
179929bd2886SAlan Wright 		param->result.level = param->level;
180029bd2886SAlan Wright 		param->status = ERROR_ACCESS_DENIED;
180129bd2886SAlan Wright 		return (NDR_DRC_OK);
180229bd2886SAlan Wright #endif /* SRVSVC_SATISFY_SMBTORTURE */
180329bd2886SAlan Wright 
1804da6c28aaSamw 	default:
1805da6c28aaSamw 		bzero(&param->result,
1806da6c28aaSamw 		    sizeof (struct mslm_NetServerGetInfo_result));
1807da6c28aaSamw 		param->status = ERROR_ACCESS_DENIED;
18088d7e4166Sjose borrego 		return (NDR_DRC_OK);
1809da6c28aaSamw 	}
1810da6c28aaSamw 
1811da6c28aaSamw 	param->result.level = param->level;
181229bd2886SAlan Wright 	param->status = ERROR_SUCCESS;
18138d7e4166Sjose borrego 	return (NDR_DRC_OK);
1814da6c28aaSamw }
1815da6c28aaSamw 
1816da6c28aaSamw /*
1817da6c28aaSamw  * NetRemoteTOD
1818da6c28aaSamw  *
1819da6c28aaSamw  * Returns information about the time of day on this server.
1820da6c28aaSamw  *
1821da6c28aaSamw  * typedef struct _TIME_OF_DAY_INFO {
1822da6c28aaSamw  *	DWORD tod_elapsedt;  // seconds since 00:00:00 January 1 1970 GMT
1823da6c28aaSamw  *	DWORD tod_msecs;     // arbitrary milliseconds (since reset)
1824da6c28aaSamw  *	DWORD tod_hours;     // current hour [0-23]
1825da6c28aaSamw  *	DWORD tod_mins;      // current minute [0-59]
1826da6c28aaSamw  *	DWORD tod_secs;      // current second [0-59]
1827da6c28aaSamw  *	DWORD tod_hunds;     // current hundredth (0.01) second [0-99]
1828da6c28aaSamw  *	LONG tod_timezone;   // time zone of the server
1829da6c28aaSamw  *	DWORD tod_tinterval; // clock tick time interval
1830da6c28aaSamw  *	DWORD tod_day;       // day of the month [1-31]
1831da6c28aaSamw  *	DWORD tod_month;     // month of the year [1-12]
1832da6c28aaSamw  *	DWORD tod_year;      // current year
183389dc44ceSjose borrego  *	DWORD tod_weekday;   // day of the week since Sunday [0-6]
1834da6c28aaSamw  * } TIME_OF_DAY_INFO;
1835da6c28aaSamw  *
1836da6c28aaSamw  * The time zone of the server is calculated in minutes from Greenwich
1837da6c28aaSamw  * Mean Time (GMT). For time zones west of Greenwich, the value is
1838da6c28aaSamw  * positive; for time zones east of Greenwich, the value is negative.
1839da6c28aaSamw  * A value of -1 indicates that the time zone is undefined.
1840da6c28aaSamw  *
1841bbf6f00cSJordan Brown  * Determine offset from GMT. If daylight saving time use altzone,
1842bbf6f00cSJordan Brown  * otherwise use timezone.
1843bbf6f00cSJordan Brown  *
1844da6c28aaSamw  * The clock tick value represents a resolution of one ten-thousandth
1845da6c28aaSamw  * (0.0001) second.
1846da6c28aaSamw  */
1847da6c28aaSamw static int
srvsvc_s_NetRemoteTOD(void * arg,ndr_xa_t * mxa)18488d7e4166Sjose borrego srvsvc_s_NetRemoteTOD(void *arg, ndr_xa_t *mxa)
1849da6c28aaSamw {
1850da6c28aaSamw 	struct mslm_NetRemoteTOD *param = arg;
1851da6c28aaSamw 	struct mslm_TIME_OF_DAY_INFO *tod;
1852da6c28aaSamw 	struct timeval		time_val;
1853da6c28aaSamw 	struct tm		tm;
1854bbf6f00cSJordan Brown 	time_t			gmtoff;
1855bbf6f00cSJordan Brown 
1856da6c28aaSamw 
1857da6c28aaSamw 	(void) gettimeofday(&time_val, 0);
1858da6c28aaSamw 	(void) gmtime_r(&time_val.tv_sec, &tm);
1859da6c28aaSamw 
18608d7e4166Sjose borrego 	tod = NDR_NEW(mxa, struct mslm_TIME_OF_DAY_INFO);
1861da6c28aaSamw 	if (tod == NULL) {
1862da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetRemoteTOD));
1863da6c28aaSamw 		return (ERROR_NOT_ENOUGH_MEMORY);
1864da6c28aaSamw 	}
1865da6c28aaSamw 
1866bbf6f00cSJordan Brown 	bzero(tod, sizeof (struct mslm_TIME_OF_DAY_INFO));
1867bbf6f00cSJordan Brown 
1868da6c28aaSamw 	tod->tod_elapsedt = time_val.tv_sec;
1869da6c28aaSamw 	tod->tod_msecs = time_val.tv_usec;
1870da6c28aaSamw 	tod->tod_hours = tm.tm_hour;
1871da6c28aaSamw 	tod->tod_mins = tm.tm_min;
1872da6c28aaSamw 	tod->tod_secs = tm.tm_sec;
1873da6c28aaSamw 	tod->tod_hunds = 0;
1874da6c28aaSamw 	tod->tod_tinterval = 1000;
1875da6c28aaSamw 	tod->tod_day = tm.tm_mday;
1876da6c28aaSamw 	tod->tod_month = tm.tm_mon+1;
1877da6c28aaSamw 	tod->tod_year = tm.tm_year+1900;
1878da6c28aaSamw 	tod->tod_weekday = tm.tm_wday;
1879da6c28aaSamw 
1880da6c28aaSamw 	(void) localtime_r(&time_val.tv_sec, &tm);
1881bbf6f00cSJordan Brown 	gmtoff = (tm.tm_isdst) ? altzone : timezone;
1882bbf6f00cSJordan Brown 	tod->tod_timezone = gmtoff / SECSPERMIN;
1883da6c28aaSamw 
1884da6c28aaSamw 	param->bufptr = tod;
1885da6c28aaSamw 	param->status = ERROR_SUCCESS;
18868d7e4166Sjose borrego 	return (NDR_DRC_OK);
1887da6c28aaSamw }
1888da6c28aaSamw 
1889da6c28aaSamw /*
1890da6c28aaSamw  * srvsvc_s_NetNameValidate
1891da6c28aaSamw  *
1892da6c28aaSamw  * Perform name validation.
1893da6c28aaSamw  *
1894da6c28aaSamw  * Returns Win32 error codes.
1895da6c28aaSamw  */
1896da6c28aaSamw /*ARGSUSED*/
1897da6c28aaSamw static int
srvsvc_s_NetNameValidate(void * arg,ndr_xa_t * mxa)18988d7e4166Sjose borrego srvsvc_s_NetNameValidate(void *arg, ndr_xa_t *mxa)
1899da6c28aaSamw {
1900da6c28aaSamw 	struct mslm_NetNameValidate *param = arg;
19013db3f65cSamw 	char *name;
1902fe1c642dSBill Krier 	int maxlen;
19033db3f65cSamw 	int len;
19043db3f65cSamw 
19053db3f65cSamw 	if ((name = (char *)param->pathname) == NULL) {
19063db3f65cSamw 		param->status = ERROR_INVALID_PARAMETER;
19078d7e4166Sjose borrego 		return (NDR_DRC_OK);
19083db3f65cSamw 	}
19093db3f65cSamw 
1910da6c28aaSamw 	switch (param->type) {
19113db3f65cSamw 	case NAMETYPE_SHARE:
1912fe1c642dSBill Krier 		len = strlen(name);
1913fe1c642dSBill Krier 		maxlen = (param->flags & NAMEFLAG_LM2) ?
1914fe1c642dSBill Krier 		    SMB_SHARE_OEMNAME_MAX : SMB_SHARE_NTNAME_MAX;
1915fe1c642dSBill Krier 
1916fe1c642dSBill Krier 		if (len > maxlen) {
19173db3f65cSamw 			param->status = ERROR_INVALID_NAME;
1918fe1c642dSBill Krier 			return (NDR_DRC_OK);
1919fe1c642dSBill Krier 		}
1920fe1c642dSBill Krier 
1921fe1c642dSBill Krier 		param->status = smb_name_validate_share(name);
19223db3f65cSamw 		break;
19233db3f65cSamw 
19243db3f65cSamw 	case NAMETYPE_USER:
19253db3f65cSamw 	case NAMETYPE_GROUP:
1926fe1c642dSBill Krier 		param->status = smb_name_validate_account(name);
1927fe1c642dSBill Krier 		break;
1928fe1c642dSBill Krier 
1929fe1c642dSBill Krier 	case NAMETYPE_DOMAIN:	/* NetBIOS domain name */
1930fe1c642dSBill Krier 		param->status = smb_name_validate_nbdomain(name);
1931fe1c642dSBill Krier 		break;
1932fe1c642dSBill Krier 
1933fe1c642dSBill Krier 	case NAMETYPE_WORKGROUP:
1934fe1c642dSBill Krier 		param->status = smb_name_validate_workgroup(name);
1935fe1c642dSBill Krier 		break;
1936fe1c642dSBill Krier 
1937fe1c642dSBill Krier 	case NAMETYPE_PASSWORD:
19383db3f65cSamw 	case NAMETYPE_COMPUTER:
19393db3f65cSamw 	case NAMETYPE_EVENT:
19403db3f65cSamw 	case NAMETYPE_SERVICE:
19413db3f65cSamw 	case NAMETYPE_NET:
19423db3f65cSamw 	case NAMETYPE_MESSAGE:
19433db3f65cSamw 	case NAMETYPE_MESSAGEDEST:
19443db3f65cSamw 	case NAMETYPE_SHAREPASSWORD:
19453db3f65cSamw 		param->status = ERROR_NOT_SUPPORTED;
1946da6c28aaSamw 		break;
1947da6c28aaSamw 
1948da6c28aaSamw 	default:
19493db3f65cSamw 		param->status = ERROR_INVALID_PARAMETER;
1950da6c28aaSamw 		break;
1951da6c28aaSamw 	}
1952da6c28aaSamw 
19538d7e4166Sjose borrego 	return (NDR_DRC_OK);
1954da6c28aaSamw }
1955da6c28aaSamw 
1956da6c28aaSamw /*
1957da6c28aaSamw  * srvsvc_s_NetShareAdd
1958da6c28aaSamw  *
195929bd2886SAlan Wright  * Add a new share. Only power users groups can manage shares.
1960da6c28aaSamw  *
1961da6c28aaSamw  * This interface is used by the rmtshare command from the NT resource
1962da6c28aaSamw  * kit. Rmtshare allows a client to add or remove shares on a server
1963da6c28aaSamw  * from the client's command line.
1964da6c28aaSamw  *
1965da6c28aaSamw  * Returns Win32 error codes.
1966da6c28aaSamw  */
1967da6c28aaSamw static int
srvsvc_s_NetShareAdd(void * arg,ndr_xa_t * mxa)19688d7e4166Sjose borrego srvsvc_s_NetShareAdd(void *arg, ndr_xa_t *mxa)
1969da6c28aaSamw {
1970da6c28aaSamw 	static DWORD parm_err = 0;
1971da6c28aaSamw 	DWORD parm_stat;
1972da6c28aaSamw 	struct mslm_NetShareAdd *param = arg;
1973eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_2 *info2;
197429bd2886SAlan Wright 	struct mslm_NetShareInfo_502 *info502;
1975da6c28aaSamw 	char realpath[MAXPATHLEN];
19763db3f65cSamw 	int32_t native_os;
197729bd2886SAlan Wright 	uint8_t *sdbuf = NULL;
197829bd2886SAlan Wright 	uint32_t status;
197929bd2886SAlan Wright 	smb_share_t si;
1980da6c28aaSamw 
19813db3f65cSamw 	native_os = ndr_native_os(mxa);
1982da6c28aaSamw 
19833db3f65cSamw 	if (!ndr_is_poweruser(mxa)) {
1984da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetShareAdd));
1985da6c28aaSamw 		param->status = ERROR_ACCESS_DENIED;
19868d7e4166Sjose borrego 		return (NDR_DRC_OK);
1987da6c28aaSamw 	}
1988da6c28aaSamw 
1989da6c28aaSamw 	switch (param->level) {
1990da6c28aaSamw 	case 2:
199129bd2886SAlan Wright 		info2 = (struct mslm_NetShareInfo_2 *)param->info.un.info2;
1992da6c28aaSamw 		break;
1993da6c28aaSamw 
1994da6c28aaSamw 	case 502:
199529bd2886SAlan Wright 		info502 = (struct mslm_NetShareInfo_502 *)
199629bd2886SAlan Wright 		    param->info.un.info502;
199729bd2886SAlan Wright 		sdbuf = info502->shi502_security_descriptor;
199829bd2886SAlan Wright 		info2 = (struct mslm_NetShareInfo_2 *)info502;
1999da6c28aaSamw 		break;
2000da6c28aaSamw 
2001da6c28aaSamw 	default:
2002da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetShareAdd));
2003da6c28aaSamw 		param->status = ERROR_ACCESS_DENIED;
20048d7e4166Sjose borrego 		return (NDR_DRC_OK);
2005da6c28aaSamw 	}
2006da6c28aaSamw 
200789dc44ceSjose borrego 	if (info2->shi2_netname == NULL || info2->shi2_path == NULL) {
2008da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetShareAdd));
2009da6c28aaSamw 		param->status = NERR_NetNameNotFound;
20108d7e4166Sjose borrego 		return (NDR_DRC_OK);
2011da6c28aaSamw 	}
2012da6c28aaSamw 
20133db3f65cSamw 	if (smb_shr_is_restricted((char *)info2->shi2_netname)) {
2014da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetShareAdd));
2015da6c28aaSamw 		param->status = ERROR_ACCESS_DENIED;
20168d7e4166Sjose borrego 		return (NDR_DRC_OK);
2017da6c28aaSamw 	}
2018da6c28aaSamw 
2019eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (info2->shi2_comment == NULL)
2020eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		info2->shi2_comment = (uint8_t *)"";
2021da6c28aaSamw 
2022da6c28aaSamw 	/*
2023da6c28aaSamw 	 * Derive the real path which will be stored in the
20243db3f65cSamw 	 * directory field of the smb_share_t structure
2025da6c28aaSamw 	 * from the path field in this RPC request.
2026da6c28aaSamw 	 */
20273db3f65cSamw 	parm_stat = smb_shr_get_realpath((const char *)info2->shi2_path,
2028da6c28aaSamw 	    realpath, MAXPATHLEN);
2029da6c28aaSamw 
2030da6c28aaSamw 	if (parm_stat != NERR_Success) {
2031da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetShareAdd));
2032da6c28aaSamw 		param->status = parm_stat;
2033da6c28aaSamw 		param->parm_err
20343db3f65cSamw 		    = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
20358d7e4166Sjose borrego 		return (NDR_DRC_OK);
2036da6c28aaSamw 	}
2037da6c28aaSamw 
2038b89a8333Snatalie li - Sun Microsystems - Irvine United States 	param->status = srvsvc_sa_add((char *)info2->shi2_netname, realpath,
2039eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    (char *)info2->shi2_comment);
204089dc44ceSjose borrego 	if (param->status == NERR_Success) {
204129bd2886SAlan Wright 		status = smb_shr_get((char *)info2->shi2_netname, &si);
204229bd2886SAlan Wright 
204329bd2886SAlan Wright 		if ((sdbuf != NULL) && (status == NERR_Success))
204429bd2886SAlan Wright 			(void) srvsvc_sd_set(&si, sdbuf);
204589dc44ceSjose borrego 	}
20463db3f65cSamw 	param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
20478d7e4166Sjose borrego 	return (NDR_DRC_OK);
2048da6c28aaSamw }
2049da6c28aaSamw 
205019d41fccSamw /*
20511fcced4cSJordan Brown  * srvsvc_estimate_limit
205219d41fccSamw  *
205319d41fccSamw  * Estimate the number of objects that will fit in prefmaxlen.
20541fcced4cSJordan Brown  * nlimit is adjusted here.
205519d41fccSamw  */
20561fcced4cSJordan Brown static void
srvsvc_estimate_limit(smb_svcenum_t * se,uint32_t obj_size)20571fcced4cSJordan Brown srvsvc_estimate_limit(smb_svcenum_t *se, uint32_t obj_size)
205819d41fccSamw {
205919d41fccSamw 	DWORD max_cnt;
206019d41fccSamw 
20611fcced4cSJordan Brown 	if (obj_size == 0) {
20621fcced4cSJordan Brown 		se->se_nlimit = 0;
20631fcced4cSJordan Brown 		return;
20641fcced4cSJordan Brown 	}
206519d41fccSamw 
20661fcced4cSJordan Brown 	if ((max_cnt = (se->se_prefmaxlen / obj_size)) == 0) {
20671fcced4cSJordan Brown 		se->se_nlimit = 0;
20681fcced4cSJordan Brown 		return;
20691fcced4cSJordan Brown 	}
207019d41fccSamw 
20711fcced4cSJordan Brown 	if (se->se_ntotal > max_cnt)
20721fcced4cSJordan Brown 		se->se_nlimit = max_cnt;
20731fcced4cSJordan Brown 	else
20741fcced4cSJordan Brown 		se->se_nlimit = se->se_ntotal;
207519d41fccSamw }
207619d41fccSamw 
2077da6c28aaSamw /*
2078da6c28aaSamw  * srvsvc_s_NetShareEnum
2079da6c28aaSamw  *
208019d41fccSamw  * Enumerate all shares (see also NetShareEnumSticky).
208119d41fccSamw  *
2082da6c28aaSamw  * Request for various levels of information about our shares.
208319d41fccSamw  * Level 0: share names.
208419d41fccSamw  * Level 1: share name, share type and comment field.
2085da6c28aaSamw  * Level 2: everything that we know about the shares.
2086e3f2c991SKeyur Desai  * Level 501: level 1 + flags.
208719d41fccSamw  * Level 502: level 2 + security descriptor.
2088da6c28aaSamw  */
2089da6c28aaSamw static int
srvsvc_s_NetShareEnum(void * arg,ndr_xa_t * mxa)20908d7e4166Sjose borrego srvsvc_s_NetShareEnum(void *arg, ndr_xa_t *mxa)
2091da6c28aaSamw {
2092da6c28aaSamw 	struct mslm_NetShareEnum *param = arg;
20931fcced4cSJordan Brown 	srvsvc_infonres_t *infonres;
20941fcced4cSJordan Brown 	smb_svcenum_t se;
2095da6c28aaSamw 	DWORD status;
2096da6c28aaSamw 
20971fcced4cSJordan Brown 	infonres = NDR_NEW(mxa, srvsvc_infonres_t);
209819d41fccSamw 	if (infonres == NULL) {
2099da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetShareEnum));
2100da6c28aaSamw 		param->status = ERROR_NOT_ENOUGH_MEMORY;
21018d7e4166Sjose borrego 		return (NDR_DRC_OK);
2102da6c28aaSamw 	}
2103da6c28aaSamw 
2104da6c28aaSamw 	infonres->entriesread = 0;
210519d41fccSamw 	infonres->entries = NULL;
2106da6c28aaSamw 	param->result.level = param->level;
2107da6c28aaSamw 	param->result.bufptr.p = infonres;
2108da6c28aaSamw 
21091fcced4cSJordan Brown 	bzero(&se, sizeof (smb_svcenum_t));
21101fcced4cSJordan Brown 	se.se_type = SMB_SVCENUM_TYPE_SHARE;
211119d41fccSamw 	se.se_level = param->level;
21121fcced4cSJordan Brown 	se.se_ntotal = smb_shr_count();
21131fcced4cSJordan Brown 	se.se_nlimit = se.se_ntotal;
211419d41fccSamw 
211519d41fccSamw 	if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN ||
211619d41fccSamw 	    param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN)
211719d41fccSamw 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
211819d41fccSamw 	else
211919d41fccSamw 		se.se_prefmaxlen = param->prefmaxlen;
212019d41fccSamw 
212119d41fccSamw 	if (param->resume_handle) {
21221fcced4cSJordan Brown 		se.se_resume = *param->resume_handle;
21231fcced4cSJordan Brown 		se.se_nskip = se.se_resume;
21241fcced4cSJordan Brown 		*param->resume_handle = 0;
212519d41fccSamw 	}
2126da6c28aaSamw 
2127da6c28aaSamw 	switch (param->level) {
2128da6c28aaSamw 	case 0:
212919d41fccSamw 		status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 0);
2130da6c28aaSamw 		break;
2131da6c28aaSamw 
2132da6c28aaSamw 	case 1:
213319d41fccSamw 		status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 0);
2134da6c28aaSamw 		break;
2135da6c28aaSamw 
2136da6c28aaSamw 	case 2:
213719d41fccSamw 		status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 0);
213819d41fccSamw 		break;
213919d41fccSamw 
214019d41fccSamw 	case 501:
214119d41fccSamw 		status = mlsvc_NetShareEnumLevel501(mxa, infonres, &se, 0);
2142da6c28aaSamw 		break;
2143da6c28aaSamw 
2144da6c28aaSamw 	case 502:
214519d41fccSamw 		status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 0);
2146da6c28aaSamw 		break;
2147da6c28aaSamw 
2148da6c28aaSamw 	default:
214929bd2886SAlan Wright 		status = ERROR_INVALID_LEVEL;
2150da6c28aaSamw 		break;
2151da6c28aaSamw 	}
2152da6c28aaSamw 
2153da6c28aaSamw 	if (status != 0) {
2154da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetShareEnum));
2155da6c28aaSamw 		param->status = status;
21568d7e4166Sjose borrego 		return (NDR_DRC_OK);
2157da6c28aaSamw 	}
2158da6c28aaSamw 
21591fcced4cSJordan Brown 	if (se.se_nlimit == 0) {
216019d41fccSamw 		param->status = ERROR_SUCCESS;
21618d7e4166Sjose borrego 		return (NDR_DRC_OK);
216219d41fccSamw 	}
216319d41fccSamw 
216419d41fccSamw 	if (param->resume_handle &&
216519d41fccSamw 	    param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) {
21661fcced4cSJordan Brown 		if (se.se_resume < se.se_ntotal) {
21671fcced4cSJordan Brown 			*param->resume_handle = se.se_resume;
216819d41fccSamw 			status = ERROR_MORE_DATA;
216919d41fccSamw 		}
217019d41fccSamw 	}
217119d41fccSamw 
21721fcced4cSJordan Brown 	param->totalentries = se.se_ntotal;
2173da6c28aaSamw 	param->status = status;
21748d7e4166Sjose borrego 	return (NDR_DRC_OK);
2175da6c28aaSamw }
2176da6c28aaSamw 
2177da6c28aaSamw /*
2178da6c28aaSamw  * srvsvc_s_NetShareEnumSticky
2179da6c28aaSamw  *
218019d41fccSamw  * Enumerate sticky shares: all shares except those marked STYPE_SPECIAL.
218119d41fccSamw  * Except for excluding STYPE_SPECIAL shares, NetShareEnumSticky is the
218219d41fccSamw  * same as NetShareEnum.
218319d41fccSamw  *
2184da6c28aaSamw  * Request for various levels of information about our shares.
218519d41fccSamw  * Level 0: share names.
218619d41fccSamw  * Level 1: share name, share type and comment field.
2187da6c28aaSamw  * Level 2: everything that we know about the shares.
218819d41fccSamw  * Level 501: not valid for this request.
218919d41fccSamw  * Level 502: level 2 + security descriptor.
2190da6c28aaSamw  *
219119d41fccSamw  * We set n_skip to resume_handle, which is used to find the appropriate
219219d41fccSamw  * place to resume.  The resume_handle is similar to the readdir cookie.
2193da6c28aaSamw  */
2194da6c28aaSamw static int
srvsvc_s_NetShareEnumSticky(void * arg,ndr_xa_t * mxa)21958d7e4166Sjose borrego srvsvc_s_NetShareEnumSticky(void *arg, ndr_xa_t *mxa)
2196da6c28aaSamw {
2197da6c28aaSamw 	struct mslm_NetShareEnum *param = arg;
21981fcced4cSJordan Brown 	srvsvc_infonres_t *infonres;
21991fcced4cSJordan Brown 	smb_svcenum_t se;
2200da6c28aaSamw 	DWORD status;
2201da6c28aaSamw 
22021fcced4cSJordan Brown 	infonres = NDR_NEW(mxa, srvsvc_infonres_t);
220319d41fccSamw 	if (infonres == NULL) {
2204da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetShareEnum));
2205da6c28aaSamw 		param->status = ERROR_NOT_ENOUGH_MEMORY;
22068d7e4166Sjose borrego 		return (NDR_DRC_OK);
2207da6c28aaSamw 	}
2208da6c28aaSamw 
2209da6c28aaSamw 	infonres->entriesread = 0;
221019d41fccSamw 	infonres->entries = NULL;
2211da6c28aaSamw 	param->result.level = param->level;
2212da6c28aaSamw 	param->result.bufptr.p = infonres;
2213da6c28aaSamw 
22141fcced4cSJordan Brown 	bzero(&se, sizeof (smb_svcenum_t));
22151fcced4cSJordan Brown 	se.se_type = SMB_SVCENUM_TYPE_SHARE;
221619d41fccSamw 	se.se_level = param->level;
22171fcced4cSJordan Brown 	se.se_ntotal = smb_shr_count();
22181fcced4cSJordan Brown 	se.se_nlimit = se.se_ntotal;
2219da6c28aaSamw 
222019d41fccSamw 	if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN ||
222119d41fccSamw 	    param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN)
222219d41fccSamw 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
2223da6c28aaSamw 	else
222419d41fccSamw 		se.se_prefmaxlen = param->prefmaxlen;
222519d41fccSamw 
222619d41fccSamw 	if (param->resume_handle) {
22271fcced4cSJordan Brown 		se.se_resume = *param->resume_handle;
22281fcced4cSJordan Brown 		se.se_nskip = se.se_resume;
22291fcced4cSJordan Brown 		*param->resume_handle = 0;
223019d41fccSamw 	}
2231da6c28aaSamw 
2232da6c28aaSamw 	switch (param->level) {
2233da6c28aaSamw 	case 0:
223419d41fccSamw 		status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 1);
2235da6c28aaSamw 		break;
2236da6c28aaSamw 
2237da6c28aaSamw 	case 1:
223819d41fccSamw 		status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 1);
2239da6c28aaSamw 		break;
2240da6c28aaSamw 
2241da6c28aaSamw 	case 2:
224219d41fccSamw 		status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 1);
2243da6c28aaSamw 		break;
2244da6c28aaSamw 
2245da6c28aaSamw 	case 502:
224619d41fccSamw 		status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 1);
2247da6c28aaSamw 		break;
2248da6c28aaSamw 
224929bd2886SAlan Wright 	case 501:
2250da6c28aaSamw 	default:
225119d41fccSamw 		status = ERROR_INVALID_LEVEL;
2252da6c28aaSamw 		break;
2253da6c28aaSamw 	}
2254da6c28aaSamw 
225519d41fccSamw 	if (status != ERROR_SUCCESS) {
2256da6c28aaSamw 		bzero(param, sizeof (struct mslm_NetShareEnum));
2257da6c28aaSamw 		param->status = status;
22588d7e4166Sjose borrego 		return (NDR_DRC_OK);
2259da6c28aaSamw 	}
2260da6c28aaSamw 
22611fcced4cSJordan Brown 	if (se.se_nlimit == 0) {
226219d41fccSamw 		param->status = ERROR_SUCCESS;
22638d7e4166Sjose borrego 		return (NDR_DRC_OK);
226419d41fccSamw 	}
226519d41fccSamw 
226619d41fccSamw 	if (param->resume_handle &&
226719d41fccSamw 	    param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) {
22681fcced4cSJordan Brown 		if (se.se_resume < se.se_ntotal) {
22691fcced4cSJordan Brown 			*param->resume_handle = se.se_resume;
227019d41fccSamw 			status = ERROR_MORE_DATA;
227119d41fccSamw 		}
227219d41fccSamw 	}
227319d41fccSamw 
22741fcced4cSJordan Brown 	param->totalentries = se.se_ntotal;
2275da6c28aaSamw 	param->status = status;
22768d7e4166Sjose borrego 	return (NDR_DRC_OK);
2277da6c28aaSamw }
2278da6c28aaSamw 
2279da6c28aaSamw /*
228019d41fccSamw  * NetShareEnum Level 0
2281da6c28aaSamw  */
2282da6c28aaSamw static DWORD
mlsvc_NetShareEnumLevel0(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)22831fcced4cSJordan Brown mlsvc_NetShareEnumLevel0(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
22841fcced4cSJordan Brown     smb_svcenum_t *se, int sticky)
2285da6c28aaSamw {
2286eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_0 *info0;
22873db3f65cSamw 	smb_shriter_t iterator;
22883db3f65cSamw 	smb_share_t *si;
2289da6c28aaSamw 	DWORD status;
2290da6c28aaSamw 
22911fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
22921fcced4cSJordan Brown 	    sizeof (struct mslm_NetShareInfo_0) + MAXNAMELEN);
22931fcced4cSJordan Brown 	if (se->se_nlimit == 0)
229419d41fccSamw 		return (ERROR_SUCCESS);
229519d41fccSamw 
22961fcced4cSJordan Brown 	info0 = NDR_NEWN(mxa, struct mslm_NetShareInfo_0, se->se_nlimit);
229719d41fccSamw 	if (info0 == NULL)
229819d41fccSamw 		return (ERROR_NOT_ENOUGH_MEMORY);
2299da6c28aaSamw 
2300c8ec8eeaSjose borrego 	smb_shr_iterinit(&iterator);
230119d41fccSamw 
23021fcced4cSJordan Brown 	se->se_nitems = 0;
23033db3f65cSamw 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
23041fcced4cSJordan Brown 		if (se->se_nskip > 0) {
23051fcced4cSJordan Brown 			--se->se_nskip;
230619d41fccSamw 			continue;
230719d41fccSamw 		}
230819d41fccSamw 
23091fcced4cSJordan Brown 		++se->se_resume;
2310da6c28aaSamw 
2311*97264293SGordon Ross 		if ((si->shr_flags & SMB_SHRF_ABE) != 0 &&
2312*97264293SGordon Ross 		    !srvsvc_share_access(mxa, si))
2313*97264293SGordon Ross 			continue;
2314*97264293SGordon Ross 
2315c8ec8eeaSjose borrego 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
2316da6c28aaSamw 			continue;
2317da6c28aaSamw 
2318c8ec8eeaSjose borrego 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
2319da6c28aaSamw 			continue;
2320da6c28aaSamw 
23211fcced4cSJordan Brown 		if (se->se_nitems >= se->se_nlimit) {
23221fcced4cSJordan Brown 			se->se_nitems = se->se_nlimit;
232319d41fccSamw 			break;
232419d41fccSamw 		}
2325da6c28aaSamw 
232619d41fccSamw 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info0);
2327da6c28aaSamw 		if (status != ERROR_SUCCESS)
2328da6c28aaSamw 			break;
2329da6c28aaSamw 
23301fcced4cSJordan Brown 		++se->se_nitems;
2331da6c28aaSamw 	}
2332da6c28aaSamw 
23331fcced4cSJordan Brown 	if (se->se_nitems < se->se_nlimit) {
233419d41fccSamw 		if (srvsvc_add_autohome(mxa, se, (void *)info0))
23351fcced4cSJordan Brown 			++se->se_nitems;
233619d41fccSamw 	}
2337da6c28aaSamw 
23381fcced4cSJordan Brown 	infonres->entriesread = se->se_nitems;
2339da6c28aaSamw 	infonres->entries = info0;
2340da6c28aaSamw 	return (ERROR_SUCCESS);
2341da6c28aaSamw }
2342da6c28aaSamw 
2343da6c28aaSamw /*
234419d41fccSamw  * NetShareEnum Level 1
2345da6c28aaSamw  */
2346da6c28aaSamw static DWORD
mlsvc_NetShareEnumLevel1(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)23471fcced4cSJordan Brown mlsvc_NetShareEnumLevel1(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
23481fcced4cSJordan Brown     smb_svcenum_t *se, int sticky)
2349da6c28aaSamw {
2350eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_1 *info1;
23513db3f65cSamw 	smb_shriter_t iterator;
23523db3f65cSamw 	smb_share_t *si;
235319d41fccSamw 	DWORD status;
2354da6c28aaSamw 
23551fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
23561fcced4cSJordan Brown 	    sizeof (struct mslm_NetShareInfo_1) + MAXNAMELEN);
23571fcced4cSJordan Brown 	if (se->se_nlimit == 0)
235819d41fccSamw 		return (ERROR_SUCCESS);
235919d41fccSamw 
23601fcced4cSJordan Brown 	info1 = NDR_NEWN(mxa, struct mslm_NetShareInfo_1, se->se_nlimit);
236119d41fccSamw 	if (info1 == NULL)
2362da6c28aaSamw 		return (ERROR_NOT_ENOUGH_MEMORY);
2363da6c28aaSamw 
2364c8ec8eeaSjose borrego 	smb_shr_iterinit(&iterator);
2365da6c28aaSamw 
23661fcced4cSJordan Brown 	se->se_nitems = 0;
23673db3f65cSamw 	while ((si = smb_shr_iterate(&iterator)) != 0) {
23681fcced4cSJordan Brown 		if (se->se_nskip > 0) {
23691fcced4cSJordan Brown 			--se->se_nskip;
237019d41fccSamw 			continue;
237119d41fccSamw 		}
237219d41fccSamw 
23731fcced4cSJordan Brown 		++se->se_resume;
237419d41fccSamw 
2375*97264293SGordon Ross 		if ((si->shr_flags & SMB_SHRF_ABE) != 0 &&
2376*97264293SGordon Ross 		    !srvsvc_share_access(mxa, si))
2377*97264293SGordon Ross 			continue;
2378*97264293SGordon Ross 
2379c8ec8eeaSjose borrego 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
2380da6c28aaSamw 			continue;
2381da6c28aaSamw 
2382c8ec8eeaSjose borrego 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
2383da6c28aaSamw 			continue;
2384da6c28aaSamw 
23851fcced4cSJordan Brown 		if (se->se_nitems >= se->se_nlimit) {
23861fcced4cSJordan Brown 			se->se_nitems = se->se_nlimit;
2387da6c28aaSamw 			break;
238819d41fccSamw 		}
238919d41fccSamw 
239019d41fccSamw 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info1);
239119d41fccSamw 		if (status != ERROR_SUCCESS)
239219d41fccSamw 			break;
239319d41fccSamw 
23941fcced4cSJordan Brown 		++se->se_nitems;
2395da6c28aaSamw 	}
2396da6c28aaSamw 
23971fcced4cSJordan Brown 	if (se->se_nitems < se->se_nlimit) {
239819d41fccSamw 		if (srvsvc_add_autohome(mxa, se, (void *)info1))
23991fcced4cSJordan Brown 			++se->se_nitems;
240019d41fccSamw 	}
2401da6c28aaSamw 
24021fcced4cSJordan Brown 	infonres->entriesread = se->se_nitems;
2403da6c28aaSamw 	infonres->entries = info1;
2404da6c28aaSamw 	return (ERROR_SUCCESS);
2405da6c28aaSamw }
2406da6c28aaSamw 
2407da6c28aaSamw /*
240819d41fccSamw  * NetShareEnum Level 2
2409da6c28aaSamw  */
2410da6c28aaSamw static DWORD
mlsvc_NetShareEnumLevel2(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)24111fcced4cSJordan Brown mlsvc_NetShareEnumLevel2(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
24121fcced4cSJordan Brown     smb_svcenum_t *se, int sticky)
2413da6c28aaSamw {
2414eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_2 *info2;
24153db3f65cSamw 	smb_shriter_t iterator;
24163db3f65cSamw 	smb_share_t *si;
241719d41fccSamw 	DWORD status;
2418da6c28aaSamw 
24191fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
24201fcced4cSJordan Brown 	    sizeof (struct mslm_NetShareInfo_2) + MAXNAMELEN);
24211fcced4cSJordan Brown 	if (se->se_nlimit == 0)
242219d41fccSamw 		return (ERROR_SUCCESS);
242319d41fccSamw 
24241fcced4cSJordan Brown 	info2 = NDR_NEWN(mxa, struct mslm_NetShareInfo_2, se->se_nlimit);
242589dc44ceSjose borrego 	if (info2 == NULL)
2426da6c28aaSamw 		return (ERROR_NOT_ENOUGH_MEMORY);
2427da6c28aaSamw 
2428c8ec8eeaSjose borrego 	smb_shr_iterinit(&iterator);
2429da6c28aaSamw 
24301fcced4cSJordan Brown 	se->se_nitems = 0;
24313db3f65cSamw 	while ((si = smb_shr_iterate(&iterator)) != 0) {
24321fcced4cSJordan Brown 		if (se->se_nskip > 0) {
24331fcced4cSJordan Brown 			--se->se_nskip;
243419d41fccSamw 			continue;
243519d41fccSamw 		}
243619d41fccSamw 
24371fcced4cSJordan Brown 		++se->se_resume;
243819d41fccSamw 
2439*97264293SGordon Ross 		if ((si->shr_flags & SMB_SHRF_ABE) != 0 &&
2440*97264293SGordon Ross 		    !srvsvc_share_access(mxa, si))
2441*97264293SGordon Ross 			continue;
2442*97264293SGordon Ross 
2443c8ec8eeaSjose borrego 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
2444da6c28aaSamw 			continue;
2445da6c28aaSamw 
2446c8ec8eeaSjose borrego 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
2447da6c28aaSamw 			continue;
2448da6c28aaSamw 
24491fcced4cSJordan Brown 		if (se->se_nitems >= se->se_nlimit) {
24501fcced4cSJordan Brown 			se->se_nitems = se->se_nlimit;
245119d41fccSamw 			break;
245219d41fccSamw 		}
245319d41fccSamw 
245419d41fccSamw 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info2);
245519d41fccSamw 		if (status != ERROR_SUCCESS)
2456da6c28aaSamw 			break;
245719d41fccSamw 
24581fcced4cSJordan Brown 		++se->se_nitems;
2459da6c28aaSamw 	}
2460da6c28aaSamw 
24611fcced4cSJordan Brown 	if (se->se_nitems < se->se_nlimit) {
246219d41fccSamw 		if (srvsvc_add_autohome(mxa, se, (void *)info2))
24631fcced4cSJordan Brown 			++se->se_nitems;
246419d41fccSamw 	}
2465da6c28aaSamw 
24661fcced4cSJordan Brown 	infonres->entriesread = se->se_nitems;
2467da6c28aaSamw 	infonres->entries = info2;
2468da6c28aaSamw 	return (ERROR_SUCCESS);
2469da6c28aaSamw }
2470da6c28aaSamw 
2471da6c28aaSamw /*
247219d41fccSamw  * NetShareEnum Level 501
2473da6c28aaSamw  */
2474da6c28aaSamw static DWORD
mlsvc_NetShareEnumLevel501(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)24751fcced4cSJordan Brown mlsvc_NetShareEnumLevel501(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
24761fcced4cSJordan Brown     smb_svcenum_t *se, int sticky)
2477da6c28aaSamw {
2478eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_501 *info501;
24793db3f65cSamw 	smb_shriter_t iterator;
24803db3f65cSamw 	smb_share_t *si;
248119d41fccSamw 	DWORD status;
2482da6c28aaSamw 
24831fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
24841fcced4cSJordan Brown 	    sizeof (struct mslm_NetShareInfo_501) + MAXNAMELEN);
24851fcced4cSJordan Brown 	if (se->se_nlimit == 0)
248619d41fccSamw 		return (ERROR_SUCCESS);
2487da6c28aaSamw 
2488eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	info501 = NDR_NEWN(mxa, struct mslm_NetShareInfo_501,
24891fcced4cSJordan Brown 	    se->se_nlimit);
249019d41fccSamw 	if (info501 == NULL)
2491da6c28aaSamw 		return (ERROR_NOT_ENOUGH_MEMORY);
2492da6c28aaSamw 
2493c8ec8eeaSjose borrego 	smb_shr_iterinit(&iterator);
2494da6c28aaSamw 
24951fcced4cSJordan Brown 	se->se_nitems = 0;
24963db3f65cSamw 	while ((si = smb_shr_iterate(&iterator)) != 0) {
24971fcced4cSJordan Brown 		if (se->se_nskip > 0) {
24981fcced4cSJordan Brown 			--se->se_nskip;
249919d41fccSamw 			continue;
250019d41fccSamw 		}
250119d41fccSamw 
25021fcced4cSJordan Brown 		++se->se_resume;
250319d41fccSamw 
2504*97264293SGordon Ross 		if ((si->shr_flags & SMB_SHRF_ABE) != 0 &&
2505*97264293SGordon Ross 		    !srvsvc_share_access(mxa, si))
2506*97264293SGordon Ross 			continue;
2507*97264293SGordon Ross 
2508c8ec8eeaSjose borrego 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
2509da6c28aaSamw 			continue;
2510da6c28aaSamw 
2511c8ec8eeaSjose borrego 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
2512da6c28aaSamw 			continue;
2513da6c28aaSamw 
25141fcced4cSJordan Brown 		if (se->se_nitems >= se->se_nlimit) {
25151fcced4cSJordan Brown 			se->se_nitems = se->se_nlimit;
251619d41fccSamw 			break;
251719d41fccSamw 		}
251819d41fccSamw 
251919d41fccSamw 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info501);
252019d41fccSamw 		if (status != ERROR_SUCCESS)
2521da6c28aaSamw 			break;
252219d41fccSamw 
25231fcced4cSJordan Brown 		++se->se_nitems;
2524da6c28aaSamw 	}
2525da6c28aaSamw 
25261fcced4cSJordan Brown 	if (se->se_nitems < se->se_nlimit) {
252719d41fccSamw 		if (srvsvc_add_autohome(mxa, se, (void *)info501))
25281fcced4cSJordan Brown 			++se->se_nitems;
252919d41fccSamw 	}
2530da6c28aaSamw 
25311fcced4cSJordan Brown 	infonres->entriesread = se->se_nitems;
253219d41fccSamw 	infonres->entries = info501;
253319d41fccSamw 	return (ERROR_SUCCESS);
253419d41fccSamw }
253519d41fccSamw 
253619d41fccSamw /*
253719d41fccSamw  * NetShareEnum Level 502
253819d41fccSamw  */
253919d41fccSamw static DWORD
mlsvc_NetShareEnumLevel502(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)25401fcced4cSJordan Brown mlsvc_NetShareEnumLevel502(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
25411fcced4cSJordan Brown     smb_svcenum_t *se, int sticky)
254219d41fccSamw {
2543eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_502 *info502;
25443db3f65cSamw 	smb_shriter_t iterator;
25453db3f65cSamw 	smb_share_t *si;
254619d41fccSamw 	DWORD status;
254719d41fccSamw 
25481fcced4cSJordan Brown 	srvsvc_estimate_limit(se,
25491fcced4cSJordan Brown 	    sizeof (struct mslm_NetShareInfo_502) + MAXNAMELEN);
25501fcced4cSJordan Brown 	if (se->se_nlimit == 0)
255119d41fccSamw 		return (ERROR_SUCCESS);
255219d41fccSamw 
2553eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	info502 = NDR_NEWN(mxa, struct mslm_NetShareInfo_502,
25541fcced4cSJordan Brown 	    se->se_nlimit);
255519d41fccSamw 	if (info502 == NULL)
255619d41fccSamw 		return (ERROR_NOT_ENOUGH_MEMORY);
255719d41fccSamw 
2558c8ec8eeaSjose borrego 	smb_shr_iterinit(&iterator);
255919d41fccSamw 
25601fcced4cSJordan Brown 	se->se_nitems = 0;
25613db3f65cSamw 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
25621fcced4cSJordan Brown 		if (se->se_nskip > 0) {
25631fcced4cSJordan Brown 			--se->se_nskip;
256419d41fccSamw 			continue;
256519d41fccSamw 		}
256619d41fccSamw 
25671fcced4cSJordan Brown 		++se->se_resume;
256819d41fccSamw 
2569*97264293SGordon Ross 		if ((si->shr_flags & SMB_SHRF_ABE) != 0 &&
2570*97264293SGordon Ross 		    !srvsvc_share_access(mxa, si))
2571*97264293SGordon Ross 			continue;
2572*97264293SGordon Ross 
2573c8ec8eeaSjose borrego 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
257419d41fccSamw 			continue;
257519d41fccSamw 
2576c8ec8eeaSjose borrego 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
257719d41fccSamw 			continue;
257819d41fccSamw 
25791fcced4cSJordan Brown 		if (se->se_nitems >= se->se_nlimit) {
25801fcced4cSJordan Brown 			se->se_nitems = se->se_nlimit;
258119d41fccSamw 			break;
258219d41fccSamw 		}
258319d41fccSamw 
258419d41fccSamw 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info502);
258519d41fccSamw 		if (status != ERROR_SUCCESS)
258619d41fccSamw 			break;
258719d41fccSamw 
25881fcced4cSJordan Brown 		++se->se_nitems;
258919d41fccSamw 	}
259019d41fccSamw 
25911fcced4cSJordan Brown 	if (se->se_nitems < se->se_nlimit) {
259219d41fccSamw 		if (srvsvc_add_autohome(mxa, se, (void *)info502))
25931fcced4cSJordan Brown 			++se->se_nitems;
259419d41fccSamw 	}
259519d41fccSamw 
25961fcced4cSJordan Brown 	infonres->entriesread = se->se_nitems;
2597da6c28aaSamw 	infonres->entries = info502;
2598da6c28aaSamw 	return (ERROR_SUCCESS);
2599da6c28aaSamw }
2600da6c28aaSamw 
2601da6c28aaSamw /*
2602da6c28aaSamw  * mlsvc_NetShareEnumCommon
2603da6c28aaSamw  *
260419d41fccSamw  * Build the levels 0, 1, 2, 501 and 502 share information. This function
2605da6c28aaSamw  * is called by the various NetShareEnum levels for each share. If
2606da6c28aaSamw  * we cannot build the share data for some reason, we return an error
2607da6c28aaSamw  * but the actual value of the error is not important to the caller.
2608da6c28aaSamw  * The caller just needs to know not to include this info in the RPC
2609da6c28aaSamw  * response.
2610da6c28aaSamw  *
2611da6c28aaSamw  * Returns:
2612da6c28aaSamw  *	ERROR_SUCCESS
2613da6c28aaSamw  *	ERROR_NOT_ENOUGH_MEMORY
2614da6c28aaSamw  *	ERROR_INVALID_LEVEL
2615da6c28aaSamw  */
2616da6c28aaSamw static DWORD
mlsvc_NetShareEnumCommon(ndr_xa_t * mxa,smb_svcenum_t * se,smb_share_t * si,void * infop)26171fcced4cSJordan Brown mlsvc_NetShareEnumCommon(ndr_xa_t *mxa, smb_svcenum_t *se,
26183db3f65cSamw     smb_share_t *si, void *infop)
2619da6c28aaSamw {
2620eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_0 *info0;
2621eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_1 *info1;
2622eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_2 *info2;
2623eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_501 *info501;
2624eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	struct mslm_NetShareInfo_502 *info502;
262529bd2886SAlan Wright 	srvsvc_sd_t sd;
262629bd2886SAlan Wright 	uint8_t *netname;
262729bd2886SAlan Wright 	uint8_t *comment;
262829bd2886SAlan Wright 	uint8_t *passwd;
262929bd2886SAlan Wright 	uint8_t *path;
26301fcced4cSJordan Brown 	int i = se->se_nitems;
2631da6c28aaSamw 
263229bd2886SAlan Wright 	netname = (uint8_t *)NDR_STRDUP(mxa, si->shr_name);
263329bd2886SAlan Wright 	comment = (uint8_t *)NDR_STRDUP(mxa, si->shr_cmnt);
263429bd2886SAlan Wright 	passwd = (uint8_t *)NDR_STRDUP(mxa, empty_string);
263529bd2886SAlan Wright 	path = (uint8_t *)srvsvc_share_mkpath(mxa, si->shr_path);
263629bd2886SAlan Wright 
263729bd2886SAlan Wright 	if (!netname || !comment || !passwd || !path)
263829bd2886SAlan Wright 		return (ERROR_NOT_ENOUGH_MEMORY);
263929bd2886SAlan Wright 
264019d41fccSamw 	switch (se->se_level) {
2641da6c28aaSamw 	case 0:
2642eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		info0 = (struct mslm_NetShareInfo_0 *)infop;
264329bd2886SAlan Wright 		info0[i].shi0_netname = netname;
2644da6c28aaSamw 		break;
2645da6c28aaSamw 
2646da6c28aaSamw 	case 1:
2647eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		info1 = (struct mslm_NetShareInfo_1 *)infop;
264829bd2886SAlan Wright 		info1[i].shi1_netname = netname;
264929bd2886SAlan Wright 		info1[i].shi1_comment = comment;
26503db3f65cSamw 		info1[i].shi1_type = si->shr_type;
2651da6c28aaSamw 		break;
2652da6c28aaSamw 
2653da6c28aaSamw 	case 2:
2654eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		info2 = (struct mslm_NetShareInfo_2 *)infop;
265529bd2886SAlan Wright 		info2[i].shi2_netname = netname;
265629bd2886SAlan Wright 		info2[i].shi2_comment = comment;
265729bd2886SAlan Wright 		info2[i].shi2_path = path;
26583db3f65cSamw 		info2[i].shi2_type = si->shr_type;
2659da6c28aaSamw 		info2[i].shi2_permissions = 0;
2660da6c28aaSamw 		info2[i].shi2_max_uses = SHI_USES_UNLIMITED;
2661da6c28aaSamw 		info2[i].shi2_current_uses = 0;
266229bd2886SAlan Wright 		info2[i].shi2_passwd = passwd;
2663da6c28aaSamw 		break;
2664da6c28aaSamw 
266519d41fccSamw 	case 501:
2666eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		info501 = (struct mslm_NetShareInfo_501 *)infop;
266729bd2886SAlan Wright 		info501[i].shi501_netname = netname;
266829bd2886SAlan Wright 		info501[i].shi501_comment = comment;
26693db3f65cSamw 		info501[i].shi501_type = si->shr_type;
2670e3f2c991SKeyur Desai 		info501[i].shi501_flags = srvsvc_get_share_flags(si);
267119d41fccSamw 		break;
267219d41fccSamw 
2673da6c28aaSamw 	case 502:
2674eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		info502 = (struct mslm_NetShareInfo_502 *)infop;
267529bd2886SAlan Wright 		info502[i].shi502_netname = netname;
267629bd2886SAlan Wright 		info502[i].shi502_comment = comment;
267729bd2886SAlan Wright 		info502[i].shi502_path = path;
26783db3f65cSamw 		info502[i].shi502_type = si->shr_type;
2679da6c28aaSamw 		info502[i].shi502_permissions = 0;
2680da6c28aaSamw 		info502[i].shi502_max_uses = SHI_USES_UNLIMITED;
2681da6c28aaSamw 		info502[i].shi502_current_uses = 0;
268229bd2886SAlan Wright 		info502[i].shi502_passwd = passwd;
2683da6c28aaSamw 
268429bd2886SAlan Wright 		if (srvsvc_share_getsd(mxa, si, &sd) == ERROR_SUCCESS) {
268529bd2886SAlan Wright 			info502[i].shi502_reserved = sd.sd_size;
268629bd2886SAlan Wright 			info502[i].shi502_security_descriptor = sd.sd_buf;
268729bd2886SAlan Wright 		} else {
268829bd2886SAlan Wright 			info502[i].shi502_reserved = 0;
268929bd2886SAlan Wright 			info502[i].shi502_security_descriptor = NULL;
269029bd2886SAlan Wright 		}
2691da6c28aaSamw 
2692da6c28aaSamw 		break;
2693da6c28aaSamw 
2694da6c28aaSamw 	default:
2695da6c28aaSamw 		return (ERROR_INVALID_LEVEL);
2696da6c28aaSamw 	}
2697da6c28aaSamw 
2698da6c28aaSamw 	return (ERROR_SUCCESS);
2699da6c28aaSamw }
2700da6c28aaSamw 
2701*97264293SGordon Ross /*
2702*97264293SGordon Ross  * srvsvc_share_access()
2703*97264293SGordon Ross  * Return TRUE if the client has access to this share.
2704*97264293SGordon Ross  * Called for shares with the ABE flag.
2705*97264293SGordon Ross  *
2706*97264293SGordon Ross  * Similar to: smb_kshare_hostaccess()
2707*97264293SGordon Ross  */
2708*97264293SGordon Ross static boolean_t
srvsvc_share_access(ndr_xa_t * xa,smb_share_t * si)2709*97264293SGordon Ross srvsvc_share_access(ndr_xa_t *xa, smb_share_t *si)
2710*97264293SGordon Ross {
2711*97264293SGordon Ross 	smb_netuserinfo_t *ui;
2712*97264293SGordon Ross 	uint32_t host_access;
2713*97264293SGordon Ross 
2714*97264293SGordon Ross 	if (xa->pipe == NULL || xa->pipe->np_user == NULL)
2715*97264293SGordon Ross 		return (B_FALSE);
2716*97264293SGordon Ross 	ui = xa->pipe->np_user;
2717*97264293SGordon Ross 
2718*97264293SGordon Ross 	/*
2719*97264293SGordon Ross 	 * Administrators see all shares
2720*97264293SGordon Ross 	 */
2721*97264293SGordon Ross 	if (ndr_is_admin(xa))
2722*97264293SGordon Ross 		return (B_TRUE);
2723*97264293SGordon Ross 
2724*97264293SGordon Ross 	/*
2725*97264293SGordon Ross 	 * Check host-based access
2726*97264293SGordon Ross 	 */
2727*97264293SGordon Ross 	if ((si->shr_flags & SMB_SHRF_ACC_ALL) != SMB_SHRF_ACC_OPEN) {
2728*97264293SGordon Ross 		host_access = smb_shr_hostaccess(
2729*97264293SGordon Ross 		    &ui->ui_ipaddr,
2730*97264293SGordon Ross 		    si->shr_access_none,
2731*97264293SGordon Ross 		    si->shr_access_ro,
2732*97264293SGordon Ross 		    si->shr_access_rw,
2733*97264293SGordon Ross 		    si->shr_flags & SMB_SHRF_ACC_ALL);
2734*97264293SGordon Ross 		if (host_access == SMB_SHRF_ACC_NONE)
2735*97264293SGordon Ross 			return (B_FALSE);
2736*97264293SGordon Ross 	}
2737*97264293SGordon Ross 
2738*97264293SGordon Ross 	/*
2739*97264293SGordon Ross 	 * Check share root ACL
2740*97264293SGordon Ross 	 */
2741*97264293SGordon Ross 	if (smb_kmod_shareaccess(ui, si) != 0)
2742*97264293SGordon Ross 		return (B_FALSE);
2743*97264293SGordon Ross 
2744*97264293SGordon Ross 	return (B_TRUE);
2745*97264293SGordon Ross }
2746*97264293SGordon Ross 
274719d41fccSamw /*
274819d41fccSamw  * srvsvc_add_autohome
274919d41fccSamw  *
275019d41fccSamw  * Add the autohome share for the user. The share must not be a permanent
275119d41fccSamw  * share to avoid duplicates.
275219d41fccSamw  */
275319d41fccSamw static boolean_t
srvsvc_add_autohome(ndr_xa_t * mxa,smb_svcenum_t * se,void * infop)27541fcced4cSJordan Brown srvsvc_add_autohome(ndr_xa_t *mxa, smb_svcenum_t *se, void *infop)
275519d41fccSamw {
275668b2bbf2SGordon Ross 	smb_netuserinfo_t *user = mxa->pipe->np_user;
2757c5866007SKeyur Desai 	char *username;
27583db3f65cSamw 	smb_share_t si;
275919d41fccSamw 	DWORD status;
2760c5866007SKeyur Desai 	struct passwd pw;
2761c5866007SKeyur Desai 	char buf[NSS_LINELEN_PASSWD];
2762c5866007SKeyur Desai 
2763c5866007SKeyur Desai 	if (IDMAP_ID_IS_EPHEMERAL(user->ui_posix_uid)) {
2764c5866007SKeyur Desai 		username = user->ui_account;
2765c5866007SKeyur Desai 	} else {
2766c5866007SKeyur Desai 		if (getpwuid_r(user->ui_posix_uid, &pw, buf, sizeof (buf)) ==
2767c5866007SKeyur Desai 		    NULL)
2768c5866007SKeyur Desai 			return (B_FALSE);
2769c5866007SKeyur Desai 
2770c5866007SKeyur Desai 		username = pw.pw_name;
2771c5866007SKeyur Desai 	}
277219d41fccSamw 
27733db3f65cSamw 	if (smb_shr_get(username, &si) != NERR_Success)
277419d41fccSamw 		return (B_FALSE);
277519d41fccSamw 
27763db3f65cSamw 	if ((si.shr_flags & SMB_SHRF_AUTOHOME) == 0)
277719d41fccSamw 		return (B_FALSE);
277819d41fccSamw 
277919d41fccSamw 	status = mlsvc_NetShareEnumCommon(mxa, se, &si, infop);
278019d41fccSamw 	return (status == ERROR_SUCCESS);
278119d41fccSamw }
278219d41fccSamw 
278319d41fccSamw /*
278419d41fccSamw  * srvsvc_share_mkpath
278519d41fccSamw  *
278619d41fccSamw  * Create the share path required by the share enum calls. The path
278719d41fccSamw  * is created in a heap buffer ready for use by the caller.
278819d41fccSamw  *
278919d41fccSamw  * Some Windows over-the-wire backup applications do not work unless a
279019d41fccSamw  * drive letter is present in the share path.  We don't care about the
279119d41fccSamw  * drive letter since the path is fully qualified with the volume name.
279219d41fccSamw  *
279319d41fccSamw  * Windows clients seem to be mostly okay with forward slashes in
279419d41fccSamw  * share paths but they cannot handle one immediately after the drive
279519d41fccSamw  * letter, i.e. B:/.  For consistency we convert all the slashes in
279619d41fccSamw  * the path.
279719d41fccSamw  *
279819d41fccSamw  * Returns a pointer to a heap buffer containing the share path, which
279919d41fccSamw  * could be a null pointer if the heap allocation fails.
280019d41fccSamw  */
280119d41fccSamw static char *
srvsvc_share_mkpath(ndr_xa_t * mxa,char * path)28028d7e4166Sjose borrego srvsvc_share_mkpath(ndr_xa_t *mxa, char *path)
280319d41fccSamw {
280419d41fccSamw 	char tmpbuf[MAXPATHLEN];
280519d41fccSamw 	char *p;
2806c5866007SKeyur Desai 	char drive_letter;
280719d41fccSamw 
280889dc44ceSjose borrego 	if (strlen(path) == 0)
280989dc44ceSjose borrego 		return (NDR_STRDUP(mxa, path));
281089dc44ceSjose borrego 
2811c5866007SKeyur Desai 	drive_letter = smb_shr_drive_letter(path);
2812c5866007SKeyur Desai 	if (drive_letter != '\0') {
2813c5866007SKeyur Desai 		(void) snprintf(tmpbuf, MAXPATHLEN, "%c:\\", drive_letter);
2814c5866007SKeyur Desai 		return (NDR_STRDUP(mxa, tmpbuf));
2815c5866007SKeyur Desai 	}
2816c5866007SKeyur Desai 
281719d41fccSamw 	/*
281819d41fccSamw 	 * Strip the volume name from the path (/vol1/home -> /home).
281919d41fccSamw 	 */
282019d41fccSamw 	p = path;
282119d41fccSamw 	p += strspn(p, "/");
282219d41fccSamw 	p += strcspn(p, "/");
282319d41fccSamw 	p += strspn(p, "/");
282419d41fccSamw 	(void) snprintf(tmpbuf, MAXPATHLEN, "%c:/%s", 'B', p);
282519d41fccSamw 	(void) strsubst(tmpbuf, '/', '\\');
282619d41fccSamw 
28278d7e4166Sjose borrego 	return (NDR_STRDUP(mxa, tmpbuf));
282819d41fccSamw }
282919d41fccSamw 
283029bd2886SAlan Wright static int
srvsvc_s_NetShareCheck(void * arg,ndr_xa_t * mxa)283129bd2886SAlan Wright srvsvc_s_NetShareCheck(void *arg, ndr_xa_t *mxa)
283229bd2886SAlan Wright {
283329bd2886SAlan Wright 	struct mslm_NetShareCheck *param = arg;
283429bd2886SAlan Wright 	smb_shriter_t iterator;
283529bd2886SAlan Wright 	smb_share_t *si;
283629bd2886SAlan Wright 	char *path;
283729bd2886SAlan Wright 
283829bd2886SAlan Wright 	if (param->path == NULL) {
283929bd2886SAlan Wright 		param->stype = STYPE_DISKTREE;
284029bd2886SAlan Wright 		param->status = NERR_NetNameNotFound;
284129bd2886SAlan Wright 		return (NDR_DRC_OK);
284229bd2886SAlan Wright 	}
284329bd2886SAlan Wright 
284429bd2886SAlan Wright 	(void) strsubst((char *)param->path, '/', '\\');
284529bd2886SAlan Wright 
284629bd2886SAlan Wright 	smb_shr_iterinit(&iterator);
284729bd2886SAlan Wright 
284829bd2886SAlan Wright 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
284929bd2886SAlan Wright 		path = srvsvc_share_mkpath(mxa, si->shr_path);
2850*97264293SGordon Ross 
2851*97264293SGordon Ross 		if ((si->shr_flags & SMB_SHRF_ABE) != 0 &&
2852*97264293SGordon Ross 		    !srvsvc_share_access(mxa, si))
2853*97264293SGordon Ross 			continue;
285429bd2886SAlan Wright 
2855bbf6f00cSJordan Brown 		if (smb_strcasecmp(path, (char *)param->path, 0) == 0) {
285629bd2886SAlan Wright 			param->stype = (si->shr_type & STYPE_MASK);
285729bd2886SAlan Wright 			param->status = NERR_Success;
285829bd2886SAlan Wright 			return (NDR_DRC_OK);
285929bd2886SAlan Wright 		}
286029bd2886SAlan Wright 	}
286129bd2886SAlan Wright 
286229bd2886SAlan Wright 	param->stype = STYPE_DISKTREE;
286329bd2886SAlan Wright 	param->status = NERR_NetNameNotFound;
286429bd2886SAlan Wright 	return (NDR_DRC_OK);
286529bd2886SAlan Wright }
286629bd2886SAlan Wright 
2867da6c28aaSamw /*
28681fcced4cSJordan Brown  * Delete a share.  Only members of the Administrators, Server Operators
28691fcced4cSJordan Brown  * or Power Users local groups are allowed to delete shares.
2870da6c28aaSamw  *
2871da6c28aaSamw  * This interface is used by the rmtshare command from the NT resource
2872da6c28aaSamw  * kit. Rmtshare allows a client to add or remove shares on a server
2873da6c28aaSamw  * from the client's command line.
2874da6c28aaSamw  *
2875da6c28aaSamw  * Returns Win32 error codes.
2876da6c28aaSamw  */
2877da6c28aaSamw static int
srvsvc_s_NetShareDel(void * arg,ndr_xa_t * mxa)28788d7e4166Sjose borrego srvsvc_s_NetShareDel(void *arg, ndr_xa_t *mxa)
2879da6c28aaSamw {
2880da6c28aaSamw 	struct mslm_NetShareDel *param = arg;
28819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_share_t si;
2882da6c28aaSamw 
28833db3f65cSamw 	if (!ndr_is_poweruser(mxa) ||
28843db3f65cSamw 	    smb_shr_is_restricted((char *)param->netname)) {
2885da6c28aaSamw 		param->status = ERROR_ACCESS_DENIED;
28868d7e4166Sjose borrego 		return (NDR_DRC_OK);
2887da6c28aaSamw 	}
2888da6c28aaSamw 
28899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_shr_get((char *)param->netname, &si) == NERR_Success) {
28909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (si.shr_flags & SMB_SHRF_DFSROOT) {
28919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			param->status = NERR_IsDfsShare;
28929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (NDR_DRC_OK);
28939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
28949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
28959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2896b89a8333Snatalie li - Sun Microsystems - Irvine United States 	param->status = srvsvc_sa_delete((char *)param->netname);
28978d7e4166Sjose borrego 	return (NDR_DRC_OK);
2898da6c28aaSamw }
2899da6c28aaSamw 
2900da6c28aaSamw /*
2901da6c28aaSamw  * srvsvc_s_NetGetFileSecurity
2902da6c28aaSamw  *
2903da6c28aaSamw  * Get security descriptor of the requested file/folder
2904da6c28aaSamw  *
2905da6c28aaSamw  * Right now, just returns ERROR_ACCESS_DENIED, because we cannot
29068d7e4166Sjose borrego  * get the requested SD here in RPC code.
2907da6c28aaSamw  */
2908da6c28aaSamw /*ARGSUSED*/
2909da6c28aaSamw static int
srvsvc_s_NetGetFileSecurity(void * arg,ndr_xa_t * mxa)29108d7e4166Sjose borrego srvsvc_s_NetGetFileSecurity(void *arg, ndr_xa_t *mxa)
2911da6c28aaSamw {
2912da6c28aaSamw 	struct mslm_NetGetFileSecurity *param = arg;
2913da6c28aaSamw 
2914da6c28aaSamw 	param->length = 0;
2915da6c28aaSamw 	param->status = ERROR_ACCESS_DENIED;
29168d7e4166Sjose borrego 	return (NDR_DRC_OK);
2917da6c28aaSamw }
2918da6c28aaSamw 
2919da6c28aaSamw /*
2920da6c28aaSamw  * srvsvc_s_NetSetFileSecurity
2921da6c28aaSamw  *
2922da6c28aaSamw  * Set the given security descriptor for the requested file/folder
2923da6c28aaSamw  *
2924da6c28aaSamw  * Right now, just returns ERROR_ACCESS_DENIED, because we cannot
29258d7e4166Sjose borrego  * set the requested SD here in RPC code.
2926da6c28aaSamw  */
2927da6c28aaSamw /*ARGSUSED*/
2928da6c28aaSamw static int
srvsvc_s_NetSetFileSecurity(void * arg,ndr_xa_t * mxa)29298d7e4166Sjose borrego srvsvc_s_NetSetFileSecurity(void *arg, ndr_xa_t *mxa)
2930da6c28aaSamw {
2931da6c28aaSamw 	struct mslm_NetSetFileSecurity *param = arg;
2932da6c28aaSamw 
2933da6c28aaSamw 	param->status = ERROR_ACCESS_DENIED;
29348d7e4166Sjose borrego 	return (NDR_DRC_OK);
2935da6c28aaSamw }
2936da6c28aaSamw 
2937b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
2938b89a8333Snatalie li - Sun Microsystems - Irvine United States  * If the default "smb" share group exists then return the group
2939b89a8333Snatalie li - Sun Microsystems - Irvine United States  * handle, otherwise create the group and return the handle.
2940b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
2941b89a8333Snatalie li - Sun Microsystems - Irvine United States  * All shares created via the srvsvc will be added to the "smb"
2942b89a8333Snatalie li - Sun Microsystems - Irvine United States  * group.
2943b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
2944b89a8333Snatalie li - Sun Microsystems - Irvine United States static sa_group_t
srvsvc_sa_get_smbgrp(sa_handle_t handle)2945b89a8333Snatalie li - Sun Microsystems - Irvine United States srvsvc_sa_get_smbgrp(sa_handle_t handle)
2946b89a8333Snatalie li - Sun Microsystems - Irvine United States {
2947b89a8333Snatalie li - Sun Microsystems - Irvine United States 	sa_group_t group = NULL;
2948b89a8333Snatalie li - Sun Microsystems - Irvine United States 	int err;
2949b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2950b89a8333Snatalie li - Sun Microsystems - Irvine United States 	group = sa_get_group(handle, SMB_DEFAULT_SHARE_GROUP);
2951b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (group != NULL)
2952b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (group);
2953b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2954b89a8333Snatalie li - Sun Microsystems - Irvine United States 	group = sa_create_group(handle, SMB_DEFAULT_SHARE_GROUP, &err);
2955b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (group == NULL)
2956b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NULL);
2957b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2958b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (sa_create_optionset(group, SMB_DEFAULT_SHARE_GROUP) == NULL) {
2959b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) sa_remove_group(group);
2960b89a8333Snatalie li - Sun Microsystems - Irvine United States 		group = NULL;
2961b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
2962b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2963b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (group);
2964b89a8333Snatalie li - Sun Microsystems - Irvine United States }
2965b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2966b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
2967b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Stores the given share in sharemgr
2968b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
2969b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t
srvsvc_sa_add(char * sharename,char * path,char * cmnt)2970b89a8333Snatalie li - Sun Microsystems - Irvine United States srvsvc_sa_add(char *sharename, char *path, char *cmnt)
2971b89a8333Snatalie li - Sun Microsystems - Irvine United States {
2972b89a8333Snatalie li - Sun Microsystems - Irvine United States 	sa_handle_t handle;
2973b89a8333Snatalie li - Sun Microsystems - Irvine United States 	sa_share_t share;
2974b89a8333Snatalie li - Sun Microsystems - Irvine United States 	sa_group_t group;
2975b89a8333Snatalie li - Sun Microsystems - Irvine United States 	sa_resource_t resource;
2976b89a8333Snatalie li - Sun Microsystems - Irvine United States 	boolean_t new_share = B_FALSE;
2977b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t status = NERR_Success;
2978b89a8333Snatalie li - Sun Microsystems - Irvine United States 	int err;
2979b89a8333Snatalie li - Sun Microsystems - Irvine United States 
298089dc44ceSjose borrego 	if ((handle = smb_shr_sa_enter()) == NULL)
2981b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
2982b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2983b89a8333Snatalie li - Sun Microsystems - Irvine United States 	share = sa_find_share(handle, path);
2984b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (share == NULL) {
2985b89a8333Snatalie li - Sun Microsystems - Irvine United States 		group = srvsvc_sa_get_smbgrp(handle);
2986b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (group == NULL) {
298789dc44ceSjose borrego 			smb_shr_sa_exit();
2988b89a8333Snatalie li - Sun Microsystems - Irvine United States 			return (NERR_InternalError);
2989b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
2990b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2991b89a8333Snatalie li - Sun Microsystems - Irvine United States 		share = sa_add_share(group, path, SA_SHARE_PERMANENT, &err);
2992b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (share == NULL) {
299389dc44ceSjose borrego 			smb_shr_sa_exit();
2994b89a8333Snatalie li - Sun Microsystems - Irvine United States 			return (NERR_InternalError);
2995b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
2996b89a8333Snatalie li - Sun Microsystems - Irvine United States 		new_share = B_TRUE;
2997b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
2998b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2999b89a8333Snatalie li - Sun Microsystems - Irvine United States 	resource = sa_get_share_resource(share, sharename);
3000b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (resource == NULL) {
3001b89a8333Snatalie li - Sun Microsystems - Irvine United States 		resource = sa_add_resource(share, sharename,
3002b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    SA_SHARE_PERMANENT, &err);
3003b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (resource == NULL) {
3004b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (new_share)
3005b89a8333Snatalie li - Sun Microsystems - Irvine United States 				(void) sa_remove_share(share);
300689dc44ceSjose borrego 			smb_shr_sa_exit();
3007b89a8333Snatalie li - Sun Microsystems - Irvine United States 			return (NERR_InternalError);
3008b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
3009b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
3010b89a8333Snatalie li - Sun Microsystems - Irvine United States 
301189dc44ceSjose borrego 	(void) sa_set_resource_description(resource, cmnt);
3012b89a8333Snatalie li - Sun Microsystems - Irvine United States 
301389dc44ceSjose borrego 	smb_shr_sa_exit();
3014b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (status);
3015b89a8333Snatalie li - Sun Microsystems - Irvine United States }
3016b89a8333Snatalie li - Sun Microsystems - Irvine United States 
3017b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
3018b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Removes the share from sharemgr
3019b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
3020b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t
srvsvc_sa_delete(char * sharename)3021b89a8333Snatalie li - Sun Microsystems - Irvine United States srvsvc_sa_delete(char *sharename)
3022b89a8333Snatalie li - Sun Microsystems - Irvine United States {
3023b89a8333Snatalie li - Sun Microsystems - Irvine United States 	sa_handle_t handle;
3024b89a8333Snatalie li - Sun Microsystems - Irvine United States 	sa_resource_t resource;
3025b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t status;
3026b89a8333Snatalie li - Sun Microsystems - Irvine United States 
302789dc44ceSjose borrego 	if ((handle = smb_shr_sa_enter()) == NULL)
3028b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
3029b89a8333Snatalie li - Sun Microsystems - Irvine United States 
3030b89a8333Snatalie li - Sun Microsystems - Irvine United States 	status = NERR_InternalError;
3031b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((resource = sa_find_resource(handle, sharename)) != NULL) {
3032b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (sa_remove_resource(resource) == SA_OK)
3033b89a8333Snatalie li - Sun Microsystems - Irvine United States 			status = NERR_Success;
3034b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
3035b89a8333Snatalie li - Sun Microsystems - Irvine United States 
303689dc44ceSjose borrego 	smb_shr_sa_exit();
3037b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (status);
3038b89a8333Snatalie li - Sun Microsystems - Irvine United States }
3039b89a8333Snatalie li - Sun Microsystems - Irvine United States 
304029bd2886SAlan Wright /*
304129bd2886SAlan Wright  * Update the share information.
304229bd2886SAlan Wright  */
304329bd2886SAlan Wright static uint32_t
srvsvc_sa_modify(smb_share_t * si,srvsvc_netshare_setinfo_t * info)304429bd2886SAlan Wright srvsvc_sa_modify(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
304529bd2886SAlan Wright {
304629bd2886SAlan Wright 	sa_handle_t handle;
304729bd2886SAlan Wright 	sa_share_t share;
304829bd2886SAlan Wright 	sa_resource_t resource;
3049148c5f43SAlan Wright 	boolean_t renamed = B_FALSE, is_zfs = B_FALSE;
3050148c5f43SAlan Wright 	nvlist_t *nvl;
305129bd2886SAlan Wright 	uint32_t nerr = NERR_Success;
305229bd2886SAlan Wright 
305329bd2886SAlan Wright 	if ((handle = smb_shr_sa_enter()) == NULL)
305429bd2886SAlan Wright 		return (NERR_InternalError);
305529bd2886SAlan Wright 
305629bd2886SAlan Wright 	if ((share = sa_find_share(handle, si->shr_path)) == NULL) {
305729bd2886SAlan Wright 		smb_shr_sa_exit();
305829bd2886SAlan Wright 		return (NERR_InternalError);
305929bd2886SAlan Wright 	}
306029bd2886SAlan Wright 
306129bd2886SAlan Wright 	if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) {
306229bd2886SAlan Wright 		smb_shr_sa_exit();
306329bd2886SAlan Wright 		return (NERR_InternalError);
306429bd2886SAlan Wright 	}
306529bd2886SAlan Wright 
3066148c5f43SAlan Wright 	if (sa_group_is_zfs(sa_get_parent_group(share))) {
3067148c5f43SAlan Wright 		is_zfs = B_TRUE;
3068148c5f43SAlan Wright 		if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
3069148c5f43SAlan Wright 			smb_shr_sa_exit();
3070148c5f43SAlan Wright 			return (NERR_InternalError);
3071148c5f43SAlan Wright 		}
3072148c5f43SAlan Wright 	}
3073148c5f43SAlan Wright 
307429bd2886SAlan Wright 	if (info->nss_netname != NULL && info->nss_netname[0] != '\0' &&
3075bbf6f00cSJordan Brown 	    smb_strcasecmp(info->nss_netname, si->shr_name, 0) != 0) {
3076148c5f43SAlan Wright 		if (is_zfs)
3077148c5f43SAlan Wright 			(void) nvlist_add_string(nvl, SHOPT_NAME,
3078148c5f43SAlan Wright 			    info->nss_netname);
3079148c5f43SAlan Wright 		else
3080148c5f43SAlan Wright 			(void) sa_set_resource_attr(resource, SHOPT_NAME,
3081148c5f43SAlan Wright 			    info->nss_netname);
308229bd2886SAlan Wright 		renamed = B_TRUE;
308329bd2886SAlan Wright 	}
308429bd2886SAlan Wright 
308529bd2886SAlan Wright 	if ((info->nss_comment != NULL) &&
308629bd2886SAlan Wright 	    (strcmp(info->nss_comment, si->shr_cmnt) != 0)) {
3087148c5f43SAlan Wright 		if (is_zfs)
3088148c5f43SAlan Wright 			(void) nvlist_add_string(nvl, SHOPT_DESCRIPTION,
3089148c5f43SAlan Wright 			    info->nss_comment);
3090148c5f43SAlan Wright 		else
3091148c5f43SAlan Wright 			(void) sa_set_resource_description(resource,
3092148c5f43SAlan Wright 			    info->nss_comment);
309329bd2886SAlan Wright 		(void) strlcpy(si->shr_cmnt, info->nss_comment,
309429bd2886SAlan Wright 		    SMB_SHARE_CMNT_MAX);
309529bd2886SAlan Wright 	}
309629bd2886SAlan Wright 
3097148c5f43SAlan Wright 	if (is_zfs) {
3098148c5f43SAlan Wright 		if (sa_zfs_setprop(handle, si->shr_path, nvl) != 0) {
3099148c5f43SAlan Wright 			smb_shr_sa_exit();
3100148c5f43SAlan Wright 			nvlist_free(nvl);
3101148c5f43SAlan Wright 			return (NERR_InternalError);
3102148c5f43SAlan Wright 		}
3103148c5f43SAlan Wright 		nvlist_free(nvl);
3104148c5f43SAlan Wright 	}
310529bd2886SAlan Wright 	smb_shr_sa_exit();
310629bd2886SAlan Wright 
310729bd2886SAlan Wright 	if (renamed) {
310829bd2886SAlan Wright 		nerr = smb_shr_rename(si->shr_name, info->nss_netname);
310929bd2886SAlan Wright 		if (nerr != NERR_Success)
311029bd2886SAlan Wright 			return (nerr);
311129bd2886SAlan Wright 
311229bd2886SAlan Wright 		(void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN);
311329bd2886SAlan Wright 	}
311429bd2886SAlan Wright 
311529bd2886SAlan Wright 	return (nerr);
311629bd2886SAlan Wright }
311729bd2886SAlan Wright 
311829bd2886SAlan Wright /*
3119148c5f43SAlan Wright  * Sets the share properties.
3120e3f2c991SKeyur Desai  *
3121148c5f43SAlan Wright  * This method sets share properties. If its a ZFS share, then properties
3122148c5f43SAlan Wright  * are set by calling the sa_zfs_setprop method. Else the optionset properties
3123148c5f43SAlan Wright  * of the share resource are set.The properties to be set are given as a list
3124148c5f43SAlan Wright  * of name-value pair.
312529bd2886SAlan Wright  */
312629bd2886SAlan Wright static uint32_t
srvsvc_sa_setprop(smb_share_t * si,nvlist_t * nvl)3127e3f2c991SKeyur Desai srvsvc_sa_setprop(smb_share_t *si, nvlist_t *nvl)
312829bd2886SAlan Wright {
312929bd2886SAlan Wright 	sa_handle_t handle;
313029bd2886SAlan Wright 	sa_share_t share;
313129bd2886SAlan Wright 	sa_resource_t resource;
3132e3f2c991SKeyur Desai 	sa_property_t prop;
3133e3f2c991SKeyur Desai 	sa_optionset_t opts;
3134e3f2c991SKeyur Desai 	uint32_t nerr = NERR_Success;
3135e3f2c991SKeyur Desai 	nvpair_t *cur;
3136e3f2c991SKeyur Desai 	int err = 0;
3137e3f2c991SKeyur Desai 	char *name, *val;
313829bd2886SAlan Wright 
31399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((handle = sa_init(SA_INIT_SHARE_API)) == NULL)
314029bd2886SAlan Wright 		return (NERR_InternalError);
314129bd2886SAlan Wright 
314229bd2886SAlan Wright 	if ((share = sa_find_share(handle, si->shr_path)) == NULL) {
31439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sa_fini(handle);
314429bd2886SAlan Wright 		return (NERR_InternalError);
314529bd2886SAlan Wright 	}
314629bd2886SAlan Wright 
314729bd2886SAlan Wright 	if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) {
31489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sa_fini(handle);
314929bd2886SAlan Wright 		return (NERR_InternalError);
315029bd2886SAlan Wright 	}
315129bd2886SAlan Wright 
3152148c5f43SAlan Wright 	if (sa_group_is_zfs(sa_get_parent_group(share))) {
3153148c5f43SAlan Wright 		if (sa_zfs_setprop(handle, si->shr_path, nvl) != 0)
3154148c5f43SAlan Wright 			nerr = NERR_InternalError;
3155148c5f43SAlan Wright 		sa_fini(handle);
3156148c5f43SAlan Wright 		return (nerr);
3157148c5f43SAlan Wright 	}
3158148c5f43SAlan Wright 
3159e3f2c991SKeyur Desai 	if ((opts = sa_get_optionset(resource, SMB_PROTOCOL_NAME)) == NULL) {
3160e3f2c991SKeyur Desai 		opts = sa_create_optionset(resource, SMB_PROTOCOL_NAME);
3161e3f2c991SKeyur Desai 		if (opts == NULL) {
31629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			sa_fini(handle);
3163e3f2c991SKeyur Desai 			return (NERR_InternalError);
3164e3f2c991SKeyur Desai 		}
3165e3f2c991SKeyur Desai 	}
3166e3f2c991SKeyur Desai 
3167e3f2c991SKeyur Desai 	cur = nvlist_next_nvpair(nvl, NULL);
3168e3f2c991SKeyur Desai 	while (cur != NULL) {
3169e3f2c991SKeyur Desai 		name = nvpair_name(cur);
3170e3f2c991SKeyur Desai 		err = nvpair_value_string(cur, &val);
3171e3f2c991SKeyur Desai 		if ((err != 0) || (name == NULL) || (val == NULL)) {
3172e3f2c991SKeyur Desai 			nerr = NERR_InternalError;
3173e3f2c991SKeyur Desai 			break;
3174e3f2c991SKeyur Desai 		}
3175e3f2c991SKeyur Desai 
3176e3f2c991SKeyur Desai 		prop = NULL;
3177e3f2c991SKeyur Desai 		if ((prop = sa_get_property(opts, name)) == NULL) {
3178e3f2c991SKeyur Desai 			prop = sa_create_property(name, val);
3179e3f2c991SKeyur Desai 			if (prop != NULL) {
3180e3f2c991SKeyur Desai 				nerr = sa_valid_property(handle, opts,
3181e3f2c991SKeyur Desai 				    SMB_PROTOCOL_NAME, prop);
3182e3f2c991SKeyur Desai 				if (nerr != NERR_Success) {
3183e3f2c991SKeyur Desai 					(void) sa_remove_property(prop);
3184e3f2c991SKeyur Desai 					break;
3185e3f2c991SKeyur Desai 				}
3186e3f2c991SKeyur Desai 			}
3187e3f2c991SKeyur Desai 			nerr = sa_add_property(opts, prop);
3188e3f2c991SKeyur Desai 			if (nerr != NERR_Success)
3189e3f2c991SKeyur Desai 				break;
3190e3f2c991SKeyur Desai 		} else {
3191e3f2c991SKeyur Desai 			nerr = sa_update_property(prop, val);
3192e3f2c991SKeyur Desai 			if (nerr != NERR_Success)
3193e3f2c991SKeyur Desai 				break;
3194e3f2c991SKeyur Desai 		}
3195e3f2c991SKeyur Desai 
3196e3f2c991SKeyur Desai 		cur = nvlist_next_nvpair(nvl, cur);
319729bd2886SAlan Wright 	}
319829bd2886SAlan Wright 
3199e3f2c991SKeyur Desai 	if (nerr == NERR_Success)
3200e3f2c991SKeyur Desai 		nerr = sa_commit_properties(opts, 0);
3201e3f2c991SKeyur Desai 
32029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sa_fini(handle);
3203e3f2c991SKeyur Desai 	return (nerr);
320429bd2886SAlan Wright }
320529bd2886SAlan Wright 
32068d7e4166Sjose borrego static ndr_stub_table_t srvsvc_stub_table[] = {
3207da6c28aaSamw 	{ srvsvc_s_NetConnectEnum,	SRVSVC_OPNUM_NetConnectEnum },
3208da6c28aaSamw 	{ srvsvc_s_NetFileEnum,		SRVSVC_OPNUM_NetFileEnum },
3209da6c28aaSamw 	{ srvsvc_s_NetFileClose,	SRVSVC_OPNUM_NetFileClose },
3210da6c28aaSamw 	{ srvsvc_s_NetShareGetInfo,	SRVSVC_OPNUM_NetShareGetInfo },
3211da6c28aaSamw 	{ srvsvc_s_NetShareSetInfo,	SRVSVC_OPNUM_NetShareSetInfo },
3212da6c28aaSamw 	{ srvsvc_s_NetSessionEnum,	SRVSVC_OPNUM_NetSessionEnum },
3213da6c28aaSamw 	{ srvsvc_s_NetSessionDel,	SRVSVC_OPNUM_NetSessionDel },
3214da6c28aaSamw 	{ srvsvc_s_NetServerGetInfo,	SRVSVC_OPNUM_NetServerGetInfo },
3215da6c28aaSamw 	{ srvsvc_s_NetRemoteTOD,	SRVSVC_OPNUM_NetRemoteTOD },
3216da6c28aaSamw 	{ srvsvc_s_NetNameValidate,	SRVSVC_OPNUM_NetNameValidate },
3217da6c28aaSamw 	{ srvsvc_s_NetShareAdd,		SRVSVC_OPNUM_NetShareAdd },
3218da6c28aaSamw 	{ srvsvc_s_NetShareDel,		SRVSVC_OPNUM_NetShareDel },
3219da6c28aaSamw 	{ srvsvc_s_NetShareEnum,	SRVSVC_OPNUM_NetShareEnum },
3220da6c28aaSamw 	{ srvsvc_s_NetShareEnumSticky,	SRVSVC_OPNUM_NetShareEnumSticky },
322129bd2886SAlan Wright 	{ srvsvc_s_NetShareCheck,	SRVSVC_OPNUM_NetShareCheck },
3222da6c28aaSamw 	{ srvsvc_s_NetGetFileSecurity,	SRVSVC_OPNUM_NetGetFileSecurity },
3223da6c28aaSamw 	{ srvsvc_s_NetSetFileSecurity,	SRVSVC_OPNUM_NetSetFileSecurity },
3224da6c28aaSamw 	{0}
3225da6c28aaSamw };
3226