xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c (revision 10122:96eda55bfd54)
18474SJose.Borrego@Sun.COM /*
28474SJose.Borrego@Sun.COM  * CDDL HEADER START
38474SJose.Borrego@Sun.COM  *
48474SJose.Borrego@Sun.COM  * The contents of this file are subject to the terms of the
58474SJose.Borrego@Sun.COM  * Common Development and Distribution License (the "License").
68474SJose.Borrego@Sun.COM  * You may not use this file except in compliance with the License.
78474SJose.Borrego@Sun.COM  *
88474SJose.Borrego@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98474SJose.Borrego@Sun.COM  * or http://www.opensolaris.org/os/licensing.
108474SJose.Borrego@Sun.COM  * See the License for the specific language governing permissions
118474SJose.Borrego@Sun.COM  * and limitations under the License.
128474SJose.Borrego@Sun.COM  *
138474SJose.Borrego@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
148474SJose.Borrego@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158474SJose.Borrego@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
168474SJose.Borrego@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
178474SJose.Borrego@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
188474SJose.Borrego@Sun.COM  *
198474SJose.Borrego@Sun.COM  * CDDL HEADER END
208474SJose.Borrego@Sun.COM  */
218474SJose.Borrego@Sun.COM /*
228474SJose.Borrego@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
238474SJose.Borrego@Sun.COM  * Use is subject to license terms.
248474SJose.Borrego@Sun.COM  */
258474SJose.Borrego@Sun.COM 
268474SJose.Borrego@Sun.COM /*
278474SJose.Borrego@Sun.COM  * Server Service RPC (SRVSVC) server-side interface definition.
288474SJose.Borrego@Sun.COM  * The server service provides a remote administration interface.
298474SJose.Borrego@Sun.COM  *
308474SJose.Borrego@Sun.COM  * This service uses NERR/Win32 error codes rather than NT status
318474SJose.Borrego@Sun.COM  * values.
328474SJose.Borrego@Sun.COM  */
338474SJose.Borrego@Sun.COM 
348474SJose.Borrego@Sun.COM #include <sys/errno.h>
358474SJose.Borrego@Sun.COM #include <unistd.h>
368474SJose.Borrego@Sun.COM #include <netdb.h>
378474SJose.Borrego@Sun.COM #include <strings.h>
388474SJose.Borrego@Sun.COM #include <time.h>
398474SJose.Borrego@Sun.COM #include <thread.h>
408474SJose.Borrego@Sun.COM #include <ctype.h>
418474SJose.Borrego@Sun.COM #include <stdlib.h>
428474SJose.Borrego@Sun.COM #include <string.h>
438474SJose.Borrego@Sun.COM #include <sys/types.h>
448474SJose.Borrego@Sun.COM #include <sys/socket.h>
458474SJose.Borrego@Sun.COM #include <netinet/in.h>
468474SJose.Borrego@Sun.COM #include <arpa/inet.h>
478474SJose.Borrego@Sun.COM #include <libshare.h>
488474SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h>
498474SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h>
508474SJose.Borrego@Sun.COM #include <smbsrv/lmerr.h>
518474SJose.Borrego@Sun.COM #include <smbsrv/nterror.h>
528474SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h>
538474SJose.Borrego@Sun.COM #include <smbsrv/cifs.h>
548474SJose.Borrego@Sun.COM #include <smbsrv/netrauth.h>
558474SJose.Borrego@Sun.COM #include <smbsrv/ndl/srvsvc.ndl>
568474SJose.Borrego@Sun.COM #include <smbsrv/smb_common_door.h>
579832Samw@Sun.COM #include "mlsvc.h"
588474SJose.Borrego@Sun.COM 
598474SJose.Borrego@Sun.COM #define	SV_TYPE_SENT_BY_ME (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | SV_TYPE_NT)
608474SJose.Borrego@Sun.COM 
618474SJose.Borrego@Sun.COM /*
628474SJose.Borrego@Sun.COM  * Qualifier types for NetConnectEnum.
638474SJose.Borrego@Sun.COM  */
648474SJose.Borrego@Sun.COM #define	SRVSVC_CONNECT_ENUM_NULL	0
658474SJose.Borrego@Sun.COM #define	SRVSVC_CONNECT_ENUM_SHARE	1
668474SJose.Borrego@Sun.COM #define	SRVSVC_CONNECT_ENUM_WKSTN	2
678474SJose.Borrego@Sun.COM 
68*10122SJordan.Brown@Sun.COM #define	SMB_SRVSVC_MAXBUFLEN		(8 * 1024 * 1024)
69*10122SJordan.Brown@Sun.COM #define	SMB_SRVSVC_MAXPREFLEN		((uint32_t)(-1))
708474SJose.Borrego@Sun.COM 
719832Samw@Sun.COM typedef struct srvsvc_sd {
729832Samw@Sun.COM 	uint8_t *sd_buf;
739832Samw@Sun.COM 	uint32_t sd_size;
749832Samw@Sun.COM } srvsvc_sd_t;
759832Samw@Sun.COM 
769832Samw@Sun.COM typedef struct srvsvc_netshare_setinfo {
779832Samw@Sun.COM 	char *nss_netname;
789832Samw@Sun.COM 	char *nss_comment;
799832Samw@Sun.COM 	char *nss_path;
809832Samw@Sun.COM 	uint32_t nss_type;
819832Samw@Sun.COM 	srvsvc_sd_t nss_sd;
829832Samw@Sun.COM } srvsvc_netshare_setinfo_t;
839832Samw@Sun.COM 
849832Samw@Sun.COM typedef union srvsvc_netshare_getinfo {
859832Samw@Sun.COM 	struct mslm_NetShareInfo_0 nsg_info0;
869832Samw@Sun.COM 	struct mslm_NetShareInfo_1 nsg_info1;
879832Samw@Sun.COM 	struct mslm_NetShareInfo_2 nsg_info2;
889832Samw@Sun.COM 	struct mslm_NetShareInfo_501 nsg_info501;
899832Samw@Sun.COM 	struct mslm_NetShareInfo_502 nsg_info502;
909832Samw@Sun.COM 	struct mslm_NetShareInfo_503 nsg_info503;
919832Samw@Sun.COM 	struct mslm_NetShareInfo_1004 nsg_info1004;
929832Samw@Sun.COM 	struct mslm_NetShareInfo_1005 nsg_info1005;
939832Samw@Sun.COM 	struct mslm_NetShareInfo_1006 nsg_info1006;
949832Samw@Sun.COM 	struct mslm_NetShareInfo_1501 nsg_info1501;
959832Samw@Sun.COM } srvsvc_netshare_getinfo_t;
969832Samw@Sun.COM 
97*10122SJordan.Brown@Sun.COM typedef struct mslm_infonres srvsvc_infonres_t;
98*10122SJordan.Brown@Sun.COM typedef struct mslm_NetConnectEnum srvsvc_NetConnectEnum_t;
99*10122SJordan.Brown@Sun.COM 
100*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_level0(ndr_xa_t *, smb_svcenum_t *,
101*10122SJordan.Brown@Sun.COM     srvsvc_NetConnectEnum_t *);
102*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_level1(ndr_xa_t *, smb_svcenum_t *,
103*10122SJordan.Brown@Sun.COM     srvsvc_NetConnectEnum_t *);
104*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_common(ndr_xa_t *,
105*10122SJordan.Brown@Sun.COM     srvsvc_NetConnectInfo_t *, smb_netsvc_t *, smb_svcenum_t *);
106*10122SJordan.Brown@Sun.COM 
107*10122SJordan.Brown@Sun.COM static DWORD srvsvc_NetFileEnum2(ndr_xa_t *, struct mslm_NetFileEnum *,
108*10122SJordan.Brown@Sun.COM     smb_svcenum_t *se);
109*10122SJordan.Brown@Sun.COM static DWORD srvsvc_NetFileEnum3(ndr_xa_t *, struct mslm_NetFileEnum *,
110*10122SJordan.Brown@Sun.COM     smb_svcenum_t *se);
111*10122SJordan.Brown@Sun.COM 
112*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_NetSessionEnumCommon(ndr_xa_t *, srvsvc_infonres_t *,
113*10122SJordan.Brown@Sun.COM     smb_netsvc_t *, smb_svcenum_t *);
114*10122SJordan.Brown@Sun.COM 
115*10122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel0(ndr_xa_t *, srvsvc_infonres_t *,
116*10122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
117*10122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel1(ndr_xa_t *, srvsvc_infonres_t *,
118*10122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
119*10122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel2(ndr_xa_t *, srvsvc_infonres_t *,
120*10122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
121*10122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel501(ndr_xa_t *, srvsvc_infonres_t *,
122*10122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
123*10122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel502(ndr_xa_t *, srvsvc_infonres_t *,
124*10122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
125*10122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumCommon(ndr_xa_t *, smb_svcenum_t *,
126*10122SJordan.Brown@Sun.COM     smb_share_t *, void *);
127*10122SJordan.Brown@Sun.COM static boolean_t srvsvc_add_autohome(ndr_xa_t *, smb_svcenum_t *, void *);
1288474SJose.Borrego@Sun.COM static char *srvsvc_share_mkpath(ndr_xa_t *, char *);
1299832Samw@Sun.COM static uint32_t srvsvc_share_getsd(ndr_xa_t *, smb_share_t *, srvsvc_sd_t *);
1308474SJose.Borrego@Sun.COM 
1318474SJose.Borrego@Sun.COM static int srvsvc_netconnect_qualifier(const char *);
132*10122SJordan.Brown@Sun.COM static void srvsvc_estimate_limit(smb_svcenum_t *, uint32_t);
133*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_sessions(void);
134*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_connections(uint32_t, const char *);
135*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_files(void);
1368474SJose.Borrego@Sun.COM 
1379832Samw@Sun.COM static uint32_t srvsvc_modify_share(smb_share_t *,
1389832Samw@Sun.COM     srvsvc_netshare_setinfo_t *);
1399832Samw@Sun.COM static uint32_t srvsvc_modify_transient_share(smb_share_t *,
1409832Samw@Sun.COM     srvsvc_netshare_setinfo_t *);
1419832Samw@Sun.COM static uint32_t srvsvc_update_share_flags(smb_share_t *, uint32_t);
1429832Samw@Sun.COM 
1438474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_add(char *, char *, char *);
1448474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_delete(char *);
1459832Samw@Sun.COM static uint32_t srvsvc_sa_modify(smb_share_t *, srvsvc_netshare_setinfo_t *);
1469832Samw@Sun.COM static uint32_t srvsvc_sa_setattr(smb_share_t *);
1478474SJose.Borrego@Sun.COM 
1488474SJose.Borrego@Sun.COM static char empty_string[1];
1498474SJose.Borrego@Sun.COM 
1508474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[];
1518474SJose.Borrego@Sun.COM 
1528474SJose.Borrego@Sun.COM static ndr_service_t srvsvc_service = {
1538474SJose.Borrego@Sun.COM 	"SRVSVC",			/* name */
1548474SJose.Borrego@Sun.COM 	"Server services",		/* desc */
1558474SJose.Borrego@Sun.COM 	"\\srvsvc",			/* endpoint */
1568474SJose.Borrego@Sun.COM 	PIPE_NTSVCS,			/* sec_addr_port */
1578474SJose.Borrego@Sun.COM 	"4b324fc8-1670-01d3-1278-5a47bf6ee188", 3,	/* abstract */
1588474SJose.Borrego@Sun.COM 	NDR_TRANSFER_SYNTAX_UUID,		2,	/* transfer */
1598474SJose.Borrego@Sun.COM 	0,				/* no bind_instance_size */
1608474SJose.Borrego@Sun.COM 	0,				/* no bind_req() */
1618474SJose.Borrego@Sun.COM 	0,				/* no unbind_and_close() */
1628474SJose.Borrego@Sun.COM 	0,				/* use generic_call_stub() */
1638474SJose.Borrego@Sun.COM 	&TYPEINFO(srvsvc_interface),	/* interface ti */
1648474SJose.Borrego@Sun.COM 	srvsvc_stub_table		/* stub_table */
1658474SJose.Borrego@Sun.COM };
1668474SJose.Borrego@Sun.COM 
1678474SJose.Borrego@Sun.COM /*
1688474SJose.Borrego@Sun.COM  * srvsvc_initialize
1698474SJose.Borrego@Sun.COM  *
1708474SJose.Borrego@Sun.COM  * This function registers the SRVSVC RPC interface with the RPC runtime
1718474SJose.Borrego@Sun.COM  * library. It must be called in order to use either the client side
1728474SJose.Borrego@Sun.COM  * or the server side functions.
1738474SJose.Borrego@Sun.COM  */
1748474SJose.Borrego@Sun.COM void
1758474SJose.Borrego@Sun.COM srvsvc_initialize(void)
1768474SJose.Borrego@Sun.COM {
1778474SJose.Borrego@Sun.COM 	(void) ndr_svc_register(&srvsvc_service);
1788474SJose.Borrego@Sun.COM }
1798474SJose.Borrego@Sun.COM 
1808474SJose.Borrego@Sun.COM /*
1818474SJose.Borrego@Sun.COM  * srvsvc_s_NetConnectEnum
1828474SJose.Borrego@Sun.COM  *
1838474SJose.Borrego@Sun.COM  * List tree connections made to a share on this server or all tree
1848474SJose.Borrego@Sun.COM  * connections established from a specific client.  Administrator,
1858474SJose.Borrego@Sun.COM  * Server Operator, Print Operator or Power User group membership
1868474SJose.Borrego@Sun.COM  * is required to use this interface.
1878474SJose.Borrego@Sun.COM  *
1888474SJose.Borrego@Sun.COM  * There are three information levels:  0, 1, and 50.  We don't support
1898474SJose.Borrego@Sun.COM  * level 50, which is only used by Windows 9x clients.
1908474SJose.Borrego@Sun.COM  *
1918474SJose.Borrego@Sun.COM  * It seems Server Manger (srvmgr) only sends workstation as the qualifier
1928474SJose.Borrego@Sun.COM  * and the Computer Management Interface on Windows 2000 doesn't request
1938474SJose.Borrego@Sun.COM  * a list of connections.
1948474SJose.Borrego@Sun.COM  *
1958474SJose.Borrego@Sun.COM  * Return Values:
1968474SJose.Borrego@Sun.COM  * ERROR_SUCCESS            Success
1978474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED      Caller does not have access to this call.
1988474SJose.Borrego@Sun.COM  * ERROR_INVALID_PARAMETER  One of the parameters is invalid.
1998474SJose.Borrego@Sun.COM  * ERROR_INVALID_LEVEL      Unknown information level specified.
2008474SJose.Borrego@Sun.COM  * ERROR_MORE_DATA          Partial date returned, more entries available.
2018474SJose.Borrego@Sun.COM  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
2028474SJose.Borrego@Sun.COM  * NERR_NetNameNotFound     The share qualifier cannot be found.
2038474SJose.Borrego@Sun.COM  * NERR_BufTooSmall         The supplied buffer is too small.
2048474SJose.Borrego@Sun.COM  */
2058474SJose.Borrego@Sun.COM static int
2068474SJose.Borrego@Sun.COM srvsvc_s_NetConnectEnum(void *arg, ndr_xa_t *mxa)
2078474SJose.Borrego@Sun.COM {
208*10122SJordan.Brown@Sun.COM 	srvsvc_NetConnectEnum_t		*param = arg;
209*10122SJordan.Brown@Sun.COM 	smb_netsvc_t			*ns;
210*10122SJordan.Brown@Sun.COM 	smb_svcenum_t			se;
211*10122SJordan.Brown@Sun.COM 	char				*qualifier;
212*10122SJordan.Brown@Sun.COM 	int				qualtype;
213*10122SJordan.Brown@Sun.COM 	DWORD				status = ERROR_SUCCESS;
2148474SJose.Borrego@Sun.COM 
2158474SJose.Borrego@Sun.COM 	if (!ndr_is_poweruser(mxa)) {
216*10122SJordan.Brown@Sun.COM 		status = ERROR_ACCESS_DENIED;
217*10122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
2188474SJose.Borrego@Sun.COM 	}
2198474SJose.Borrego@Sun.COM 
2208474SJose.Borrego@Sun.COM 	qualifier = (char *)param->qualifier;
2218474SJose.Borrego@Sun.COM 	qualtype = srvsvc_netconnect_qualifier(qualifier);
2228474SJose.Borrego@Sun.COM 	if (qualtype == SRVSVC_CONNECT_ENUM_NULL) {
223*10122SJordan.Brown@Sun.COM 		status = NERR_NetNameNotFound;
224*10122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
225*10122SJordan.Brown@Sun.COM 	}
226*10122SJordan.Brown@Sun.COM 
227*10122SJordan.Brown@Sun.COM 	param->total_entries = srvsvc_open_connections(qualtype, qualifier);
228*10122SJordan.Brown@Sun.COM 	if (param->total_entries == 0) {
229*10122SJordan.Brown@Sun.COM 		bzero(param, sizeof (srvsvc_NetConnectEnum_t));
230*10122SJordan.Brown@Sun.COM 		param->status = ERROR_SUCCESS;
2318474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
2328474SJose.Borrego@Sun.COM 	}
2338474SJose.Borrego@Sun.COM 
234*10122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
235*10122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_TREE;
236*10122SJordan.Brown@Sun.COM 	se.se_level = param->info.level;
237*10122SJordan.Brown@Sun.COM 	se.se_ntotal = param->total_entries;
238*10122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
239*10122SJordan.Brown@Sun.COM 
240*10122SJordan.Brown@Sun.COM 	if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN ||
241*10122SJordan.Brown@Sun.COM 	    param->pref_max_len > SMB_SRVSVC_MAXBUFLEN)
242*10122SJordan.Brown@Sun.COM 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
243*10122SJordan.Brown@Sun.COM 	else
244*10122SJordan.Brown@Sun.COM 		se.se_prefmaxlen = param->pref_max_len;
245*10122SJordan.Brown@Sun.COM 
246*10122SJordan.Brown@Sun.COM 	if (param->resume_handle) {
247*10122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
248*10122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
249*10122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
250*10122SJordan.Brown@Sun.COM 	}
251*10122SJordan.Brown@Sun.COM 
2528474SJose.Borrego@Sun.COM 	switch (param->info.level) {
2538474SJose.Borrego@Sun.COM 	case 0:
254*10122SJordan.Brown@Sun.COM 		status = srvsvc_netconnectenum_level0(mxa, &se, param);
2558474SJose.Borrego@Sun.COM 		break;
2568474SJose.Borrego@Sun.COM 	case 1:
257*10122SJordan.Brown@Sun.COM 		status = srvsvc_netconnectenum_level1(mxa, &se, param);
2588474SJose.Borrego@Sun.COM 		break;
2598474SJose.Borrego@Sun.COM 	case 50:
2608474SJose.Borrego@Sun.COM 		status = ERROR_NOT_SUPPORTED;
2618474SJose.Borrego@Sun.COM 		break;
2628474SJose.Borrego@Sun.COM 	default:
2638474SJose.Borrego@Sun.COM 		status = ERROR_INVALID_LEVEL;
2648474SJose.Borrego@Sun.COM 		break;
2658474SJose.Borrego@Sun.COM 	}
2668474SJose.Borrego@Sun.COM 
2678474SJose.Borrego@Sun.COM 	if (status != ERROR_SUCCESS)
268*10122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
269*10122SJordan.Brown@Sun.COM 
270*10122SJordan.Brown@Sun.COM 	if ((ns = smb_kmod_enum_init(&se)) == NULL) {
271*10122SJordan.Brown@Sun.COM 		status = ERROR_NOT_ENOUGH_MEMORY;
272*10122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
273*10122SJordan.Brown@Sun.COM 	}
274*10122SJordan.Brown@Sun.COM 
275*10122SJordan.Brown@Sun.COM 	status = srvsvc_netconnectenum_common(mxa, &param->info, ns, &se);
276*10122SJordan.Brown@Sun.COM 	smb_kmod_enum_fini(ns);
277*10122SJordan.Brown@Sun.COM 
278*10122SJordan.Brown@Sun.COM 	if (status != ERROR_SUCCESS)
279*10122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
280*10122SJordan.Brown@Sun.COM 
281*10122SJordan.Brown@Sun.COM 	if (param->resume_handle &&
282*10122SJordan.Brown@Sun.COM 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
283*10122SJordan.Brown@Sun.COM 		if (se.se_resume < param->total_entries) {
284*10122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
285*10122SJordan.Brown@Sun.COM 			status = ERROR_MORE_DATA;
286*10122SJordan.Brown@Sun.COM 		}
287*10122SJordan.Brown@Sun.COM 	}
288*10122SJordan.Brown@Sun.COM 
289*10122SJordan.Brown@Sun.COM 	param->status = status;
290*10122SJordan.Brown@Sun.COM 	return (NDR_DRC_OK);
291*10122SJordan.Brown@Sun.COM 
292*10122SJordan.Brown@Sun.COM srvsvc_netconnectenum_error:
293*10122SJordan.Brown@Sun.COM 	bzero(param, sizeof (srvsvc_NetConnectEnum_t));
2948474SJose.Borrego@Sun.COM 	param->status = status;
2958474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
2968474SJose.Borrego@Sun.COM }
2978474SJose.Borrego@Sun.COM 
298*10122SJordan.Brown@Sun.COM /*
299*10122SJordan.Brown@Sun.COM  * Allocate memory and estimate the number of objects that can
300*10122SJordan.Brown@Sun.COM  * be returned for NetConnectEnum level 0.
301*10122SJordan.Brown@Sun.COM  */
302*10122SJordan.Brown@Sun.COM static uint32_t
303*10122SJordan.Brown@Sun.COM srvsvc_netconnectenum_level0(ndr_xa_t *mxa, smb_svcenum_t *se,
304*10122SJordan.Brown@Sun.COM     srvsvc_NetConnectEnum_t *param)
3058474SJose.Borrego@Sun.COM {
306*10122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfo0_t	*info0;
307*10122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfoBuf0_t	*ci0;
308*10122SJordan.Brown@Sun.COM 
309*10122SJordan.Brown@Sun.COM 	if ((info0 = NDR_NEW(mxa, srvsvc_NetConnectInfo0_t)) == NULL)
310*10122SJordan.Brown@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
311*10122SJordan.Brown@Sun.COM 
312*10122SJordan.Brown@Sun.COM 	bzero(info0, sizeof (srvsvc_NetConnectInfo0_t));
313*10122SJordan.Brown@Sun.COM 	param->info.ru.info0 = info0;
314*10122SJordan.Brown@Sun.COM 
315*10122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se, sizeof (srvsvc_NetConnectInfoBuf0_t));
316*10122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
317*10122SJordan.Brown@Sun.COM 		return (NERR_BufTooSmall);
318*10122SJordan.Brown@Sun.COM 
319*10122SJordan.Brown@Sun.COM 	do {
320*10122SJordan.Brown@Sun.COM 		ci0 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf0_t, se->se_nlimit);
321*10122SJordan.Brown@Sun.COM 		if (ci0 == NULL)
322*10122SJordan.Brown@Sun.COM 			se->se_nlimit >>= 1;
323*10122SJordan.Brown@Sun.COM 	} while ((se->se_nlimit > 0) && (ci0 == NULL));
324*10122SJordan.Brown@Sun.COM 
3258474SJose.Borrego@Sun.COM 	if (ci0 == NULL)
3268474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
3278474SJose.Borrego@Sun.COM 
3288474SJose.Borrego@Sun.COM 	info0->ci0 = ci0;
329*10122SJordan.Brown@Sun.COM 	info0->entries_read = 0;
3308474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
3318474SJose.Borrego@Sun.COM }
3328474SJose.Borrego@Sun.COM 
333*10122SJordan.Brown@Sun.COM /*
334*10122SJordan.Brown@Sun.COM  * Allocate memory and estimate the number of objects that can
335*10122SJordan.Brown@Sun.COM  * be returned for NetConnectEnum level 1.
336*10122SJordan.Brown@Sun.COM  */
337*10122SJordan.Brown@Sun.COM static uint32_t
338*10122SJordan.Brown@Sun.COM srvsvc_netconnectenum_level1(ndr_xa_t *mxa, smb_svcenum_t *se,
339*10122SJordan.Brown@Sun.COM     srvsvc_NetConnectEnum_t *param)
3408474SJose.Borrego@Sun.COM {
341*10122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfo1_t	*info1;
342*10122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfoBuf1_t	*ci1;
343*10122SJordan.Brown@Sun.COM 
344*10122SJordan.Brown@Sun.COM 	if ((info1 = NDR_NEW(mxa, srvsvc_NetConnectInfo1_t)) == NULL)
345*10122SJordan.Brown@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
346*10122SJordan.Brown@Sun.COM 
347*10122SJordan.Brown@Sun.COM 	bzero(info1, sizeof (srvsvc_NetConnectInfo1_t));
348*10122SJordan.Brown@Sun.COM 	param->info.ru.info1 = info1;
349*10122SJordan.Brown@Sun.COM 
350*10122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
351*10122SJordan.Brown@Sun.COM 	    sizeof (srvsvc_NetConnectInfoBuf1_t) + MAXNAMELEN);
352*10122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
353*10122SJordan.Brown@Sun.COM 		return (NERR_BufTooSmall);
354*10122SJordan.Brown@Sun.COM 
355*10122SJordan.Brown@Sun.COM 	do {
356*10122SJordan.Brown@Sun.COM 		ci1 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf1_t, se->se_nlimit);
357*10122SJordan.Brown@Sun.COM 		if (ci1 == NULL)
358*10122SJordan.Brown@Sun.COM 			se->se_nlimit >>= 1;
359*10122SJordan.Brown@Sun.COM 	} while ((se->se_nlimit > 0) && (ci1 == NULL));
360*10122SJordan.Brown@Sun.COM 
3618474SJose.Borrego@Sun.COM 	if (ci1 == NULL)
3628474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
3638474SJose.Borrego@Sun.COM 
3648474SJose.Borrego@Sun.COM 	info1->ci1 = ci1;
365*10122SJordan.Brown@Sun.COM 	info1->entries_read = 0;
366*10122SJordan.Brown@Sun.COM 	return (ERROR_SUCCESS);
367*10122SJordan.Brown@Sun.COM }
368*10122SJordan.Brown@Sun.COM 
369*10122SJordan.Brown@Sun.COM /*
370*10122SJordan.Brown@Sun.COM  * Request a list of connections from the kernel and set up
371*10122SJordan.Brown@Sun.COM  * the connection information to be returned to the client.
372*10122SJordan.Brown@Sun.COM  */
373*10122SJordan.Brown@Sun.COM static uint32_t
374*10122SJordan.Brown@Sun.COM srvsvc_netconnectenum_common(ndr_xa_t *mxa, srvsvc_NetConnectInfo_t *info,
375*10122SJordan.Brown@Sun.COM     smb_netsvc_t *ns, smb_svcenum_t *se)
376*10122SJordan.Brown@Sun.COM {
377*10122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfo0_t	*info0;
378*10122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfo1_t	*info1;
379*10122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfoBuf0_t	*ci0;
380*10122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfoBuf1_t	*ci1;
381*10122SJordan.Brown@Sun.COM 	smb_netsvcitem_t		*item;
382*10122SJordan.Brown@Sun.COM 	smb_netconnectinfo_t		*tree;
383*10122SJordan.Brown@Sun.COM 
384*10122SJordan.Brown@Sun.COM 	if (smb_kmod_enum(ns) != 0)
385*10122SJordan.Brown@Sun.COM 		return (ERROR_INTERNAL_ERROR);
386*10122SJordan.Brown@Sun.COM 
387*10122SJordan.Brown@Sun.COM 	info0 = info->ru.info0;
388*10122SJordan.Brown@Sun.COM 	ci0 = info0->ci0;
389*10122SJordan.Brown@Sun.COM 
390*10122SJordan.Brown@Sun.COM 	info1 = info->ru.info1;
391*10122SJordan.Brown@Sun.COM 	ci1 = info1->ci1;
392*10122SJordan.Brown@Sun.COM 
393*10122SJordan.Brown@Sun.COM 	item = list_head(&ns->ns_list);
394*10122SJordan.Brown@Sun.COM 	while (item != NULL) {
395*10122SJordan.Brown@Sun.COM 		tree = &item->nsi_un.nsi_tree;
396*10122SJordan.Brown@Sun.COM 
397*10122SJordan.Brown@Sun.COM 		switch (se->se_level) {
398*10122SJordan.Brown@Sun.COM 		case 0:
399*10122SJordan.Brown@Sun.COM 			ci0->coni0_id = tree->ci_id;
400*10122SJordan.Brown@Sun.COM 			++ci0;
401*10122SJordan.Brown@Sun.COM 			++info0->entries_read;
402*10122SJordan.Brown@Sun.COM 			break;
403*10122SJordan.Brown@Sun.COM 		case 1:
404*10122SJordan.Brown@Sun.COM 			ci1->coni1_id = tree->ci_id;
405*10122SJordan.Brown@Sun.COM 			ci1->coni1_type = tree->ci_type;
406*10122SJordan.Brown@Sun.COM 			ci1->coni1_num_opens = tree->ci_numopens;
407*10122SJordan.Brown@Sun.COM 			ci1->coni1_num_users = tree->ci_numusers;
408*10122SJordan.Brown@Sun.COM 			ci1->coni1_time = tree->ci_time;
409*10122SJordan.Brown@Sun.COM 			ci1->coni1_username = (uint8_t *)
410*10122SJordan.Brown@Sun.COM 			    NDR_STRDUP(mxa, tree->ci_username);
411*10122SJordan.Brown@Sun.COM 			ci1->coni1_netname = (uint8_t *)
412*10122SJordan.Brown@Sun.COM 			    NDR_STRDUP(mxa, tree->ci_share);
413*10122SJordan.Brown@Sun.COM 			++ci1;
414*10122SJordan.Brown@Sun.COM 			++info1->entries_read;
415*10122SJordan.Brown@Sun.COM 			break;
416*10122SJordan.Brown@Sun.COM 		default:
417*10122SJordan.Brown@Sun.COM 			return (ERROR_INVALID_LEVEL);
418*10122SJordan.Brown@Sun.COM 		}
419*10122SJordan.Brown@Sun.COM 
420*10122SJordan.Brown@Sun.COM 		++se->se_resume;
421*10122SJordan.Brown@Sun.COM 		item = list_next(&ns->ns_list, item);
422*10122SJordan.Brown@Sun.COM 	}
423*10122SJordan.Brown@Sun.COM 
4248474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
4258474SJose.Borrego@Sun.COM }
4268474SJose.Borrego@Sun.COM 
4278474SJose.Borrego@Sun.COM /*
4288474SJose.Borrego@Sun.COM  * srvsvc_netconnect_qualifier
4298474SJose.Borrego@Sun.COM  *
4308474SJose.Borrego@Sun.COM  * The qualifier is a string that specifies a share name or computer name
4318474SJose.Borrego@Sun.COM  * for the connections of interest.  If it is a share name then all the
4328474SJose.Borrego@Sun.COM  * connections made to that share name are listed.  If it is a computer
4338474SJose.Borrego@Sun.COM  * name (it starts with two backslash characters), then NetConnectEnum
4348474SJose.Borrego@Sun.COM  * lists all connections made from that computer to the specified server.
4358474SJose.Borrego@Sun.COM  */
4368474SJose.Borrego@Sun.COM static int
4378474SJose.Borrego@Sun.COM srvsvc_netconnect_qualifier(const char *qualifier)
4388474SJose.Borrego@Sun.COM {
4398474SJose.Borrego@Sun.COM 	if (qualifier == NULL || *qualifier == '\0')
4408474SJose.Borrego@Sun.COM 		return (SRVSVC_CONNECT_ENUM_NULL);
4418474SJose.Borrego@Sun.COM 
4428474SJose.Borrego@Sun.COM 	if (strlen(qualifier) > MAXHOSTNAMELEN)
4438474SJose.Borrego@Sun.COM 		return (SRVSVC_CONNECT_ENUM_NULL);
4448474SJose.Borrego@Sun.COM 
4458474SJose.Borrego@Sun.COM 	if (qualifier[0] == '\\' && qualifier[1] == '\\') {
4468474SJose.Borrego@Sun.COM 		return (SRVSVC_CONNECT_ENUM_WKSTN);
4478474SJose.Borrego@Sun.COM 	} else {
4488474SJose.Borrego@Sun.COM 		if (!smb_shr_exists((char *)qualifier))
4498474SJose.Borrego@Sun.COM 			return (SRVSVC_CONNECT_ENUM_NULL);
4508474SJose.Borrego@Sun.COM 
4518474SJose.Borrego@Sun.COM 		return (SRVSVC_CONNECT_ENUM_SHARE);
4528474SJose.Borrego@Sun.COM 	}
4538474SJose.Borrego@Sun.COM }
4548474SJose.Borrego@Sun.COM 
455*10122SJordan.Brown@Sun.COM static uint32_t
456*10122SJordan.Brown@Sun.COM srvsvc_open_sessions(void)
457*10122SJordan.Brown@Sun.COM {
458*10122SJordan.Brown@Sun.COM 	smb_opennum_t	opennum;
459*10122SJordan.Brown@Sun.COM 
460*10122SJordan.Brown@Sun.COM 	bzero(&opennum, sizeof (smb_opennum_t));
461*10122SJordan.Brown@Sun.COM 	if (smb_kmod_get_open_num(&opennum) != 0)
462*10122SJordan.Brown@Sun.COM 		return (0);
463*10122SJordan.Brown@Sun.COM 
464*10122SJordan.Brown@Sun.COM 	return (opennum.open_users);
465*10122SJordan.Brown@Sun.COM }
466*10122SJordan.Brown@Sun.COM 
467*10122SJordan.Brown@Sun.COM static uint32_t
468*10122SJordan.Brown@Sun.COM srvsvc_open_connections(uint32_t qualtype, const char *qualifier)
469*10122SJordan.Brown@Sun.COM {
470*10122SJordan.Brown@Sun.COM 	smb_opennum_t	opennum;
471*10122SJordan.Brown@Sun.COM 
472*10122SJordan.Brown@Sun.COM 	bzero(&opennum, sizeof (smb_opennum_t));
473*10122SJordan.Brown@Sun.COM 	opennum.qualtype = qualtype;
474*10122SJordan.Brown@Sun.COM 	(void) strlcpy(opennum.qualifier, qualifier, MAXNAMELEN);
475*10122SJordan.Brown@Sun.COM 
476*10122SJordan.Brown@Sun.COM 	if (smb_kmod_get_open_num(&opennum) != 0)
477*10122SJordan.Brown@Sun.COM 		return (0);
478*10122SJordan.Brown@Sun.COM 
479*10122SJordan.Brown@Sun.COM 	return (opennum.open_trees);
480*10122SJordan.Brown@Sun.COM }
481*10122SJordan.Brown@Sun.COM 
482*10122SJordan.Brown@Sun.COM static uint32_t
483*10122SJordan.Brown@Sun.COM srvsvc_open_files(void)
484*10122SJordan.Brown@Sun.COM {
485*10122SJordan.Brown@Sun.COM 	smb_opennum_t	opennum;
486*10122SJordan.Brown@Sun.COM 
487*10122SJordan.Brown@Sun.COM 	bzero(&opennum, sizeof (smb_opennum_t));
488*10122SJordan.Brown@Sun.COM 	if (smb_kmod_get_open_num(&opennum) != 0)
489*10122SJordan.Brown@Sun.COM 		return (0);
490*10122SJordan.Brown@Sun.COM 
491*10122SJordan.Brown@Sun.COM 	return (opennum.open_files);
492*10122SJordan.Brown@Sun.COM }
493*10122SJordan.Brown@Sun.COM 
4948474SJose.Borrego@Sun.COM /*
4958474SJose.Borrego@Sun.COM  * srvsvc_s_NetFileEnum
4968474SJose.Borrego@Sun.COM  *
4978474SJose.Borrego@Sun.COM  * Return information on open files or named pipes. Only members of the
4988474SJose.Borrego@Sun.COM  * Administrators or Server Operators local groups are allowed to make
4998474SJose.Borrego@Sun.COM  * this call. Currently, we only support Administrators.
5008474SJose.Borrego@Sun.COM  *
5018474SJose.Borrego@Sun.COM  * If basepath is null, all open resources are enumerated. If basepath
5028474SJose.Borrego@Sun.COM  * is non-null, only resources that have basepath as a prefix should
5038474SJose.Borrego@Sun.COM  * be returned.
5048474SJose.Borrego@Sun.COM  *
5058474SJose.Borrego@Sun.COM  * If username is specified (non-null), only files opened by username
5068474SJose.Borrego@Sun.COM  * should be returned.
5078474SJose.Borrego@Sun.COM  *
5088474SJose.Borrego@Sun.COM  * Notes:
5098474SJose.Borrego@Sun.COM  * 1. We don't validate the servername because we would have to check
5108474SJose.Borrego@Sun.COM  * all primary IPs and the ROI seems unlikely to be worth it.
5118474SJose.Borrego@Sun.COM  * 2. Both basepath and username are currently ignored because both
5128474SJose.Borrego@Sun.COM  * Server Manger (NT 4.0) and CMI (Windows 2000) always set them to null.
5138474SJose.Borrego@Sun.COM  *
5148474SJose.Borrego@Sun.COM  * The level of information requested may be one of:
5158474SJose.Borrego@Sun.COM  *
5168474SJose.Borrego@Sun.COM  *  2   Return the file identification number.
5178474SJose.Borrego@Sun.COM  *      This level is not supported on Windows Me/98/95.
5188474SJose.Borrego@Sun.COM  *
5198474SJose.Borrego@Sun.COM  *  3   Return information about the file.
5208474SJose.Borrego@Sun.COM  *      This level is not supported on Windows Me/98/95.
5218474SJose.Borrego@Sun.COM  *
5228474SJose.Borrego@Sun.COM  *  50  Windows Me/98/95:  Return information about the file.
5238474SJose.Borrego@Sun.COM  *
5248474SJose.Borrego@Sun.COM  * Note:
5258474SJose.Borrego@Sun.COM  * If pref_max_len is unlimited and resume_handle is null, the client
5268474SJose.Borrego@Sun.COM  * expects to receive all data in a single call.
5278474SJose.Borrego@Sun.COM  * If we are unable to do fit all data in a single response, we would
5288474SJose.Borrego@Sun.COM  * normally return ERROR_MORE_DATA with a partial list.
5298474SJose.Borrego@Sun.COM  *
5308474SJose.Borrego@Sun.COM  * Unfortunately, when both of these conditions occur, Server Manager
5318474SJose.Borrego@Sun.COM  * pops up an error box with the message "more data available" and
5328474SJose.Borrego@Sun.COM  * doesn't display any of the returned data. In this case, it is
5338474SJose.Borrego@Sun.COM  * probably better to return ERROR_SUCCESS with the partial list.
5348474SJose.Borrego@Sun.COM  * Windows 2000 doesn't have this problem because it always sends a
5358474SJose.Borrego@Sun.COM  * non-null resume_handle.
5368474SJose.Borrego@Sun.COM  *
5378474SJose.Borrego@Sun.COM  * Return Values:
5388474SJose.Borrego@Sun.COM  * ERROR_SUCCESS            Success
5398474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED      Caller does not have access to this call.
5408474SJose.Borrego@Sun.COM  * ERROR_INVALID_PARAMETER  One of the parameters is invalid.
5418474SJose.Borrego@Sun.COM  * ERROR_INVALID_LEVEL      Unknown information level specified.
5428474SJose.Borrego@Sun.COM  * ERROR_MORE_DATA          Partial date returned, more entries available.
5438474SJose.Borrego@Sun.COM  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
5448474SJose.Borrego@Sun.COM  * NERR_BufTooSmall         The supplied buffer is too small.
5458474SJose.Borrego@Sun.COM  */
5468474SJose.Borrego@Sun.COM static int
5478474SJose.Borrego@Sun.COM srvsvc_s_NetFileEnum(void *arg, ndr_xa_t *mxa)
5488474SJose.Borrego@Sun.COM {
549*10122SJordan.Brown@Sun.COM 	struct mslm_NetFileEnum	*param = arg;
550*10122SJordan.Brown@Sun.COM 	smb_svcenum_t		se;
551*10122SJordan.Brown@Sun.COM 	DWORD			status;
5528474SJose.Borrego@Sun.COM 
5538474SJose.Borrego@Sun.COM 	if (!ndr_is_admin(mxa)) {
5548474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetFileEnum));
5558474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
5568474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
5578474SJose.Borrego@Sun.COM 	}
5588474SJose.Borrego@Sun.COM 
559*10122SJordan.Brown@Sun.COM 	if ((param->total_entries = srvsvc_open_files()) == 0) {
560*10122SJordan.Brown@Sun.COM 		bzero(param, sizeof (struct mslm_NetFileEnum));
561*10122SJordan.Brown@Sun.COM 		param->status = ERROR_SUCCESS;
562*10122SJordan.Brown@Sun.COM 		return (NDR_DRC_OK);
563*10122SJordan.Brown@Sun.COM 	}
564*10122SJordan.Brown@Sun.COM 
565*10122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
566*10122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_FILE;
567*10122SJordan.Brown@Sun.COM 	se.se_level = param->info.switch_value;
568*10122SJordan.Brown@Sun.COM 	se.se_ntotal = param->total_entries;
569*10122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
570*10122SJordan.Brown@Sun.COM 
571*10122SJordan.Brown@Sun.COM 	if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN ||
572*10122SJordan.Brown@Sun.COM 	    param->pref_max_len > SMB_SRVSVC_MAXBUFLEN)
573*10122SJordan.Brown@Sun.COM 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
574*10122SJordan.Brown@Sun.COM 	else
575*10122SJordan.Brown@Sun.COM 		se.se_prefmaxlen = param->pref_max_len;
576*10122SJordan.Brown@Sun.COM 
577*10122SJordan.Brown@Sun.COM 	if (param->resume_handle) {
578*10122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
579*10122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
580*10122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
581*10122SJordan.Brown@Sun.COM 	}
582*10122SJordan.Brown@Sun.COM 
5838474SJose.Borrego@Sun.COM 	switch (param->info.switch_value) {
5848474SJose.Borrego@Sun.COM 	case 2:
585*10122SJordan.Brown@Sun.COM 		status = srvsvc_NetFileEnum2(mxa, param, &se);
5868474SJose.Borrego@Sun.COM 		break;
5878474SJose.Borrego@Sun.COM 
5888474SJose.Borrego@Sun.COM 	case 3:
589*10122SJordan.Brown@Sun.COM 		status = srvsvc_NetFileEnum3(mxa, param, &se);
5908474SJose.Borrego@Sun.COM 		break;
5918474SJose.Borrego@Sun.COM 
5928474SJose.Borrego@Sun.COM 	case 50:
5938474SJose.Borrego@Sun.COM 		status = ERROR_NOT_SUPPORTED;
5948474SJose.Borrego@Sun.COM 		break;
5958474SJose.Borrego@Sun.COM 
5968474SJose.Borrego@Sun.COM 	default:
5978474SJose.Borrego@Sun.COM 		status = ERROR_INVALID_LEVEL;
5988474SJose.Borrego@Sun.COM 		break;
5998474SJose.Borrego@Sun.COM 	}
6008474SJose.Borrego@Sun.COM 
6018474SJose.Borrego@Sun.COM 	if (status != ERROR_SUCCESS) {
6028474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetFileEnum));
6038474SJose.Borrego@Sun.COM 		param->status = status;
6048474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
6058474SJose.Borrego@Sun.COM 	}
6068474SJose.Borrego@Sun.COM 
607*10122SJordan.Brown@Sun.COM 	if (param->resume_handle &&
608*10122SJordan.Brown@Sun.COM 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
609*10122SJordan.Brown@Sun.COM 		if (se.se_resume < param->total_entries) {
610*10122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
611*10122SJordan.Brown@Sun.COM 			status = ERROR_MORE_DATA;
612*10122SJordan.Brown@Sun.COM 		}
613*10122SJordan.Brown@Sun.COM 	}
614*10122SJordan.Brown@Sun.COM 
615*10122SJordan.Brown@Sun.COM 	param->status = status;
6168474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
6178474SJose.Borrego@Sun.COM }
6188474SJose.Borrego@Sun.COM 
6198474SJose.Borrego@Sun.COM /*
6208474SJose.Borrego@Sun.COM  * Build level 2 file information.
6218474SJose.Borrego@Sun.COM  *
622*10122SJordan.Brown@Sun.COM  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
623*10122SJordan.Brown@Sun.COM  * So we use the uniqid here.
624*10122SJordan.Brown@Sun.COM  *
6258474SJose.Borrego@Sun.COM  * On success, the caller expects that the info2, fi2 and entries_read
6268474SJose.Borrego@Sun.COM  * fields have been set up.
6278474SJose.Borrego@Sun.COM  */
6288474SJose.Borrego@Sun.COM static DWORD
629*10122SJordan.Brown@Sun.COM srvsvc_NetFileEnum2(ndr_xa_t *mxa, struct mslm_NetFileEnum *param,
630*10122SJordan.Brown@Sun.COM     smb_svcenum_t *se)
6318474SJose.Borrego@Sun.COM {
632*10122SJordan.Brown@Sun.COM 	struct mslm_NetFileInfoBuf2	*fi2;
633*10122SJordan.Brown@Sun.COM 	smb_netsvc_t			*ns;
634*10122SJordan.Brown@Sun.COM 	smb_netsvcitem_t		*item;
635*10122SJordan.Brown@Sun.COM 	smb_netfileinfo_t		*ofile;
636*10122SJordan.Brown@Sun.COM 	uint32_t			entries_read = 0;
6378474SJose.Borrego@Sun.COM 
6388474SJose.Borrego@Sun.COM 	param->info.ru.info2 = NDR_NEW(mxa, struct mslm_NetFileInfo2);
6399832Samw@Sun.COM 	if (param->info.ru.info2 == NULL)
6408474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
6418474SJose.Borrego@Sun.COM 
642*10122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se, sizeof (struct mslm_NetFileInfoBuf2));
643*10122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
644*10122SJordan.Brown@Sun.COM 		return (NERR_BufTooSmall);
645*10122SJordan.Brown@Sun.COM 
646*10122SJordan.Brown@Sun.COM 	do {
647*10122SJordan.Brown@Sun.COM 		fi2 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf2, se->se_nlimit);
648*10122SJordan.Brown@Sun.COM 		if (fi2 == NULL)
649*10122SJordan.Brown@Sun.COM 			se->se_nlimit >>= 1;
650*10122SJordan.Brown@Sun.COM 	} while ((se->se_nlimit > 0) && (fi2 == NULL));
651*10122SJordan.Brown@Sun.COM 
6528474SJose.Borrego@Sun.COM 	if (fi2 == NULL)
6538474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
6548474SJose.Borrego@Sun.COM 
6558474SJose.Borrego@Sun.COM 	param->info.ru.info2->fi2 = fi2;
6568474SJose.Borrego@Sun.COM 
657*10122SJordan.Brown@Sun.COM 	if ((ns = smb_kmod_enum_init(se)) == NULL)
658*10122SJordan.Brown@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
659*10122SJordan.Brown@Sun.COM 
660*10122SJordan.Brown@Sun.COM 	if (smb_kmod_enum(ns) != 0) {
661*10122SJordan.Brown@Sun.COM 		smb_kmod_enum_fini(ns);
662*10122SJordan.Brown@Sun.COM 		return (ERROR_INTERNAL_ERROR);
663*10122SJordan.Brown@Sun.COM 	}
664*10122SJordan.Brown@Sun.COM 
665*10122SJordan.Brown@Sun.COM 	item = list_head(&ns->ns_list);
666*10122SJordan.Brown@Sun.COM 	while (item != NULL) {
667*10122SJordan.Brown@Sun.COM 		ofile = &item->nsi_un.nsi_ofile;
668*10122SJordan.Brown@Sun.COM 		fi2->fi2_id = ofile->fi_uniqid;
6698474SJose.Borrego@Sun.COM 
6708474SJose.Borrego@Sun.COM 		++entries_read;
6718474SJose.Borrego@Sun.COM 		++fi2;
672*10122SJordan.Brown@Sun.COM 		item = list_next(&ns->ns_list, item);
6738474SJose.Borrego@Sun.COM 	}
6748474SJose.Borrego@Sun.COM 
675*10122SJordan.Brown@Sun.COM 	se->se_resume += entries_read;
6768474SJose.Borrego@Sun.COM 	param->info.ru.info2->entries_read = entries_read;
677*10122SJordan.Brown@Sun.COM 	smb_kmod_enum_fini(ns);
6788474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
6798474SJose.Borrego@Sun.COM }
6808474SJose.Borrego@Sun.COM 
6818474SJose.Borrego@Sun.COM /*
6828474SJose.Borrego@Sun.COM  * Build level 3 file information.
6838474SJose.Borrego@Sun.COM  *
684*10122SJordan.Brown@Sun.COM  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
685*10122SJordan.Brown@Sun.COM  * So we use the uniqid here.
686*10122SJordan.Brown@Sun.COM  *
6878474SJose.Borrego@Sun.COM  * On success, the caller expects that the info3, fi3 and entries_read
6888474SJose.Borrego@Sun.COM  * fields have been set up.
6898474SJose.Borrego@Sun.COM  */
6908474SJose.Borrego@Sun.COM static DWORD
691*10122SJordan.Brown@Sun.COM srvsvc_NetFileEnum3(ndr_xa_t *mxa, struct mslm_NetFileEnum *param,
692*10122SJordan.Brown@Sun.COM     smb_svcenum_t *se)
6938474SJose.Borrego@Sun.COM {
694*10122SJordan.Brown@Sun.COM 	struct mslm_NetFileInfoBuf3	*fi3;
695*10122SJordan.Brown@Sun.COM 	smb_netsvc_t			*ns;
696*10122SJordan.Brown@Sun.COM 	smb_netsvcitem_t		*item;
697*10122SJordan.Brown@Sun.COM 	smb_netfileinfo_t		*ofile;
698*10122SJordan.Brown@Sun.COM 	uint32_t			entries_read = 0;
6998474SJose.Borrego@Sun.COM 
7008474SJose.Borrego@Sun.COM 	param->info.ru.info3 = NDR_NEW(mxa, struct mslm_NetFileInfo3);
7018474SJose.Borrego@Sun.COM 	if (param->info.ru.info3 == NULL)
7028474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
7038474SJose.Borrego@Sun.COM 
704*10122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
705*10122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetFileInfoBuf3) + MAXNAMELEN);
706*10122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
707*10122SJordan.Brown@Sun.COM 		return (NERR_BufTooSmall);
708*10122SJordan.Brown@Sun.COM 
709*10122SJordan.Brown@Sun.COM 	do {
710*10122SJordan.Brown@Sun.COM 		fi3 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf3, se->se_nlimit);
711*10122SJordan.Brown@Sun.COM 		if (fi3 == NULL)
712*10122SJordan.Brown@Sun.COM 			se->se_nlimit >>= 1;
713*10122SJordan.Brown@Sun.COM 	} while ((se->se_nlimit > 0) && (fi3 == NULL));
714*10122SJordan.Brown@Sun.COM 
7158474SJose.Borrego@Sun.COM 	if (fi3 == NULL)
7168474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
7178474SJose.Borrego@Sun.COM 
7188474SJose.Borrego@Sun.COM 	param->info.ru.info3->fi3 = fi3;
7198474SJose.Borrego@Sun.COM 
720*10122SJordan.Brown@Sun.COM 	if ((ns = smb_kmod_enum_init(se)) == NULL)
721*10122SJordan.Brown@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
722*10122SJordan.Brown@Sun.COM 
723*10122SJordan.Brown@Sun.COM 	if (smb_kmod_enum(ns) != 0) {
724*10122SJordan.Brown@Sun.COM 		smb_kmod_enum_fini(ns);
725*10122SJordan.Brown@Sun.COM 		return (ERROR_INTERNAL_ERROR);
726*10122SJordan.Brown@Sun.COM 	}
727*10122SJordan.Brown@Sun.COM 
728*10122SJordan.Brown@Sun.COM 	item = list_head(&ns->ns_list);
729*10122SJordan.Brown@Sun.COM 	while (item != NULL) {
730*10122SJordan.Brown@Sun.COM 		ofile = &item->nsi_un.nsi_ofile;
731*10122SJordan.Brown@Sun.COM 		fi3->fi3_id = ofile->fi_uniqid;
732*10122SJordan.Brown@Sun.COM 		fi3->fi3_permissions = ofile->fi_permissions;
733*10122SJordan.Brown@Sun.COM 		fi3->fi3_num_locks = ofile->fi_numlocks;
7348474SJose.Borrego@Sun.COM 		fi3->fi3_pathname = (uint8_t *)
735*10122SJordan.Brown@Sun.COM 		    NDR_STRDUP(mxa, ofile->fi_path);
7368474SJose.Borrego@Sun.COM 		fi3->fi3_username = (uint8_t *)
737*10122SJordan.Brown@Sun.COM 		    NDR_STRDUP(mxa, ofile->fi_username);
7388474SJose.Borrego@Sun.COM 
7398474SJose.Borrego@Sun.COM 		++entries_read;
7408474SJose.Borrego@Sun.COM 		++fi3;
741*10122SJordan.Brown@Sun.COM 		item = list_next(&ns->ns_list, item);
7428474SJose.Borrego@Sun.COM 	}
7438474SJose.Borrego@Sun.COM 
744*10122SJordan.Brown@Sun.COM 	se->se_resume += entries_read;
7458474SJose.Borrego@Sun.COM 	param->info.ru.info3->entries_read = entries_read;
7468474SJose.Borrego@Sun.COM 	param->total_entries = entries_read;
7478474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
7488474SJose.Borrego@Sun.COM }
7498474SJose.Borrego@Sun.COM 
7508474SJose.Borrego@Sun.COM /*
7518474SJose.Borrego@Sun.COM  * srvsvc_s_NetFileClose
7528474SJose.Borrego@Sun.COM  *
7538474SJose.Borrego@Sun.COM  * NetFileClose forces a file to close. This function can be used when
754*10122SJordan.Brown@Sun.COM  * an error prevents closure by other means.  Use NetFileClose with
7558474SJose.Borrego@Sun.COM  * caution because it does not flush data, cached on a client, to the
7568474SJose.Borrego@Sun.COM  * file before closing the file.
7578474SJose.Borrego@Sun.COM  *
758*10122SJordan.Brown@Sun.COM  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
759*10122SJordan.Brown@Sun.COM  * So we use the uniqid here.
760*10122SJordan.Brown@Sun.COM  *
7618474SJose.Borrego@Sun.COM  * Return Values
7628474SJose.Borrego@Sun.COM  * ERROR_SUCCESS            Operation succeeded.
7638474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED      Operation denied.
7648474SJose.Borrego@Sun.COM  * NERR_FileIdNotFound      No open file with the specified id.
7658474SJose.Borrego@Sun.COM  *
766*10122SJordan.Brown@Sun.COM  * Note: MSDN suggests ERROR_FILE_NOT_FOUND for NetFileClose but network
767*10122SJordan.Brown@Sun.COM  * captures using NT show NERR_FileIdNotFound, which is consistent with
768*10122SJordan.Brown@Sun.COM  * the NetFileClose2 page on MSDN.
7698474SJose.Borrego@Sun.COM  */
7708474SJose.Borrego@Sun.COM static int
7718474SJose.Borrego@Sun.COM srvsvc_s_NetFileClose(void *arg, ndr_xa_t *mxa)
7728474SJose.Borrego@Sun.COM {
773*10122SJordan.Brown@Sun.COM 	static struct {
774*10122SJordan.Brown@Sun.COM 		int errnum;
775*10122SJordan.Brown@Sun.COM 		int nerr;
776*10122SJordan.Brown@Sun.COM 	} errmap[] = {
777*10122SJordan.Brown@Sun.COM 		0,	ERROR_SUCCESS,
778*10122SJordan.Brown@Sun.COM 		EACCES,	ERROR_ACCESS_DENIED,
779*10122SJordan.Brown@Sun.COM 		EPERM,	ERROR_ACCESS_DENIED,
780*10122SJordan.Brown@Sun.COM 		EINVAL,	ERROR_INVALID_PARAMETER,
781*10122SJordan.Brown@Sun.COM 		ENOMEM,	ERROR_NOT_ENOUGH_MEMORY,
782*10122SJordan.Brown@Sun.COM 		ENOENT,	NERR_FileIdNotFound
783*10122SJordan.Brown@Sun.COM 	};
784*10122SJordan.Brown@Sun.COM 
7858474SJose.Borrego@Sun.COM 	struct mslm_NetFileClose *param = arg;
786*10122SJordan.Brown@Sun.COM 	int		i;
787*10122SJordan.Brown@Sun.COM 	int		rc;
7888474SJose.Borrego@Sun.COM 
7898474SJose.Borrego@Sun.COM 	if (!ndr_is_admin(mxa)) {
7908474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
7918474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
7928474SJose.Borrego@Sun.COM 	}
7938474SJose.Borrego@Sun.COM 
794*10122SJordan.Brown@Sun.COM 	rc = smb_kmod_file_close(param->file_id);
795*10122SJordan.Brown@Sun.COM 
796*10122SJordan.Brown@Sun.COM 	for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) {
797*10122SJordan.Brown@Sun.COM 		if (rc == errmap[i].errnum) {
798*10122SJordan.Brown@Sun.COM 			param->status = errmap[i].nerr;
799*10122SJordan.Brown@Sun.COM 			return (NDR_DRC_OK);
800*10122SJordan.Brown@Sun.COM 		}
801*10122SJordan.Brown@Sun.COM 	}
802*10122SJordan.Brown@Sun.COM 
803*10122SJordan.Brown@Sun.COM 	param->status = ERROR_INTERNAL_ERROR;
8048474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
8058474SJose.Borrego@Sun.COM }
8068474SJose.Borrego@Sun.COM 
8078474SJose.Borrego@Sun.COM /*
8088474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareGetInfo
8098474SJose.Borrego@Sun.COM  *
8108474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
8118474SJose.Borrego@Sun.COM  */
8128474SJose.Borrego@Sun.COM static int
8138474SJose.Borrego@Sun.COM srvsvc_s_NetShareGetInfo(void *arg, ndr_xa_t *mxa)
8148474SJose.Borrego@Sun.COM {
8158474SJose.Borrego@Sun.COM 	struct mlsm_NetShareGetInfo *param = arg;
8169343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_0 *info0;
8179343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1 *info1;
8189343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
8199343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_501 *info501;
8209343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
8219832Samw@Sun.COM 	struct mslm_NetShareInfo_503 *info503;
8229343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1004 *info1004;
8239343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1005 *info1005;
8249343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1006 *info1006;
8259832Samw@Sun.COM 	struct mslm_NetShareInfo_1501 *info1501;
8269832Samw@Sun.COM 	srvsvc_netshare_getinfo_t *info;
8279832Samw@Sun.COM 	uint8_t *netname;
8289832Samw@Sun.COM 	uint8_t *comment;
8298474SJose.Borrego@Sun.COM 	smb_share_t si;
8309832Samw@Sun.COM 	srvsvc_sd_t sd;
8318474SJose.Borrego@Sun.COM 	DWORD status;
8328474SJose.Borrego@Sun.COM 
8338474SJose.Borrego@Sun.COM 	status = smb_shr_get((char *)param->netname, &si);
8348474SJose.Borrego@Sun.COM 	if (status != NERR_Success) {
8358474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
8368474SJose.Borrego@Sun.COM 		param->status = status;
8378474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
8388474SJose.Borrego@Sun.COM 	}
8398474SJose.Borrego@Sun.COM 
8409832Samw@Sun.COM 	netname = (uint8_t *)NDR_STRDUP(mxa, si.shr_name);
8419832Samw@Sun.COM 	comment = (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt);
8429832Samw@Sun.COM 	info = NDR_NEW(mxa, srvsvc_netshare_getinfo_t);
8439832Samw@Sun.COM 
8449832Samw@Sun.COM 	if (netname == NULL || comment == NULL || info == NULL) {
8459832Samw@Sun.COM 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
8469832Samw@Sun.COM 		param->status = ERROR_NOT_ENOUGH_MEMORY;
8479832Samw@Sun.COM 		return (NDR_DRC_OK);
8489832Samw@Sun.COM 	}
8499832Samw@Sun.COM 
8508474SJose.Borrego@Sun.COM 	switch (param->level) {
8518474SJose.Borrego@Sun.COM 	case 0:
8529832Samw@Sun.COM 		info0 = &info->nsg_info0;
8539832Samw@Sun.COM 		info0->shi0_netname = netname;
8548474SJose.Borrego@Sun.COM 		param->result.ru.info0 = info0;
8558474SJose.Borrego@Sun.COM 		break;
8568474SJose.Borrego@Sun.COM 
8578474SJose.Borrego@Sun.COM 	case 1:
8589832Samw@Sun.COM 		info1 = &info->nsg_info1;
8599832Samw@Sun.COM 		info1->shi1_netname = netname;
8609832Samw@Sun.COM 		info1->shi1_comment = comment;
8618474SJose.Borrego@Sun.COM 		info1->shi1_type = si.shr_type;
8628474SJose.Borrego@Sun.COM 		param->result.ru.info1 = info1;
8638474SJose.Borrego@Sun.COM 		break;
8648474SJose.Borrego@Sun.COM 
8658474SJose.Borrego@Sun.COM 	case 2:
8669832Samw@Sun.COM 		info2 = &info->nsg_info2;
8679832Samw@Sun.COM 		info2->shi2_netname = netname;
8689832Samw@Sun.COM 		info2->shi2_comment = comment;
8698474SJose.Borrego@Sun.COM 		info2->shi2_path =
8708474SJose.Borrego@Sun.COM 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
8718474SJose.Borrego@Sun.COM 		info2->shi2_passwd = 0;
8728474SJose.Borrego@Sun.COM 		info2->shi2_type = si.shr_type;
8738474SJose.Borrego@Sun.COM 		info2->shi2_permissions = 0;
8748474SJose.Borrego@Sun.COM 		info2->shi2_max_uses = SHI_USES_UNLIMITED;
8758474SJose.Borrego@Sun.COM 		info2->shi2_current_uses = 0;
8768474SJose.Borrego@Sun.COM 		param->result.ru.info2 = info2;
8778474SJose.Borrego@Sun.COM 		break;
8788474SJose.Borrego@Sun.COM 
8799832Samw@Sun.COM 	case 501:
8809832Samw@Sun.COM 		info501 = &info->nsg_info501;
8819832Samw@Sun.COM 		info501->shi501_netname = netname;
8829832Samw@Sun.COM 		info501->shi501_comment = comment;
8839832Samw@Sun.COM 		info501->shi501_type = si.shr_type;
8849832Samw@Sun.COM 		info501->shi501_reserved = 0;
8859832Samw@Sun.COM 		param->result.ru.info501 = info501;
8869832Samw@Sun.COM 		break;
8879832Samw@Sun.COM 
8889832Samw@Sun.COM 	case 502:
8899832Samw@Sun.COM 		info502 = &info->nsg_info502;
8909832Samw@Sun.COM 		info502->shi502_netname = netname;
8919832Samw@Sun.COM 		info502->shi502_comment = comment;
8929832Samw@Sun.COM 		info502->shi502_path =
8939832Samw@Sun.COM 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
8949832Samw@Sun.COM 		info502->shi502_passwd = 0;
8959832Samw@Sun.COM 		info502->shi502_type = si.shr_type;
8969832Samw@Sun.COM 		info502->shi502_permissions = 0;
8979832Samw@Sun.COM 		info502->shi502_max_uses = SHI_USES_UNLIMITED;
8989832Samw@Sun.COM 		info502->shi502_current_uses = 0;
8999832Samw@Sun.COM 
9009832Samw@Sun.COM 		status = srvsvc_share_getsd(mxa, &si, &sd);
9019832Samw@Sun.COM 		if (status == ERROR_SUCCESS) {
9029832Samw@Sun.COM 			info502->shi502_reserved = sd.sd_size;
9039832Samw@Sun.COM 			info502->shi502_security_descriptor = sd.sd_buf;
9049832Samw@Sun.COM 		} else {
9059832Samw@Sun.COM 			info502->shi502_reserved = 0;
9069832Samw@Sun.COM 			info502->shi502_security_descriptor = NULL;
9078474SJose.Borrego@Sun.COM 		}
9088474SJose.Borrego@Sun.COM 
9099832Samw@Sun.COM 		param->result.ru.info502 = info502;
9109832Samw@Sun.COM 		break;
9119832Samw@Sun.COM 
9129832Samw@Sun.COM 	case 503:
9139832Samw@Sun.COM 		info503 = &info->nsg_info503;
9149832Samw@Sun.COM 		info503->shi503_netname = netname;
9159832Samw@Sun.COM 		info503->shi503_comment = comment;
9169832Samw@Sun.COM 		info503->shi503_path =
9179832Samw@Sun.COM 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
9189832Samw@Sun.COM 		info503->shi503_passwd = NULL;
9199832Samw@Sun.COM 		info503->shi503_type = si.shr_type;
9209832Samw@Sun.COM 		info503->shi503_permissions = 0;
9219832Samw@Sun.COM 		info503->shi503_max_uses = SHI_USES_UNLIMITED;
9229832Samw@Sun.COM 		info503->shi503_current_uses = 0;
9239832Samw@Sun.COM 		info503->shi503_servername = NULL;
9249832Samw@Sun.COM 
9259832Samw@Sun.COM 		status = srvsvc_share_getsd(mxa, &si, &sd);
9269832Samw@Sun.COM 		if (status == ERROR_SUCCESS) {
9279832Samw@Sun.COM 			info503->shi503_reserved = sd.sd_size;
9289832Samw@Sun.COM 			info503->shi503_security_descriptor = sd.sd_buf;
9299832Samw@Sun.COM 		} else {
9309832Samw@Sun.COM 			info503->shi503_reserved = 0;
9319832Samw@Sun.COM 			info503->shi503_security_descriptor = NULL;
9329832Samw@Sun.COM 		}
9339832Samw@Sun.COM 
9349832Samw@Sun.COM 		param->result.ru.info503 = info503;
9359832Samw@Sun.COM 		break;
9369832Samw@Sun.COM 
9379832Samw@Sun.COM 	case 1004:
9389832Samw@Sun.COM 		info1004 = &info->nsg_info1004;
9399832Samw@Sun.COM 		info1004->shi1004_comment = comment;
9409832Samw@Sun.COM 		param->result.ru.info1004 = info1004;
9418474SJose.Borrego@Sun.COM 		break;
9428474SJose.Borrego@Sun.COM 
9438474SJose.Borrego@Sun.COM 	case 1005:
9449832Samw@Sun.COM 		info1005 = &info->nsg_info1005;
9458474SJose.Borrego@Sun.COM 		info1005->shi1005_flags = 0;
9468474SJose.Borrego@Sun.COM 
9478474SJose.Borrego@Sun.COM 		switch (si.shr_flags & SMB_SHRF_CSC_MASK) {
9488474SJose.Borrego@Sun.COM 		case SMB_SHRF_CSC_DISABLED:
9498474SJose.Borrego@Sun.COM 			info1005->shi1005_flags |= CSC_CACHE_NONE;
9508474SJose.Borrego@Sun.COM 			break;
9518474SJose.Borrego@Sun.COM 		case SMB_SHRF_CSC_AUTO:
9528474SJose.Borrego@Sun.COM 			info1005->shi1005_flags |= CSC_CACHE_AUTO_REINT;
9538474SJose.Borrego@Sun.COM 			break;
9548474SJose.Borrego@Sun.COM 		case SMB_SHRF_CSC_VDO:
9558474SJose.Borrego@Sun.COM 			info1005->shi1005_flags |= CSC_CACHE_VDO;
9568474SJose.Borrego@Sun.COM 			break;
9578474SJose.Borrego@Sun.COM 		case SMB_SHRF_CSC_MANUAL:
9588474SJose.Borrego@Sun.COM 		default:
9598474SJose.Borrego@Sun.COM 			/*
9608474SJose.Borrego@Sun.COM 			 * Default to CSC_CACHE_MANUAL_REINT.
9618474SJose.Borrego@Sun.COM 			 */
9628474SJose.Borrego@Sun.COM 			break;
9638474SJose.Borrego@Sun.COM 		}
9648474SJose.Borrego@Sun.COM 
9658474SJose.Borrego@Sun.COM 		param->result.ru.info1005 = info1005;
9668474SJose.Borrego@Sun.COM 		break;
9678474SJose.Borrego@Sun.COM 
9688474SJose.Borrego@Sun.COM 	case 1006:
9699832Samw@Sun.COM 		info1006 = &info->nsg_info1006;
9708474SJose.Borrego@Sun.COM 		info1006->shi1006_max_uses = SHI_USES_UNLIMITED;
9718474SJose.Borrego@Sun.COM 		param->result.ru.info1006 = info1006;
9728474SJose.Borrego@Sun.COM 		break;
9738474SJose.Borrego@Sun.COM 
9749832Samw@Sun.COM 	case 1501:
9759832Samw@Sun.COM 		info1501 = &info->nsg_info1501;
9769832Samw@Sun.COM 
9779832Samw@Sun.COM 		status = srvsvc_share_getsd(mxa, &si, &sd);
9789832Samw@Sun.COM 		if (status == ERROR_SUCCESS) {
9799832Samw@Sun.COM 			info503->shi503_reserved = sd.sd_size;
9809832Samw@Sun.COM 			info503->shi503_security_descriptor = sd.sd_buf;
9819832Samw@Sun.COM 		} else {
9829832Samw@Sun.COM 			info503->shi503_reserved = 0;
9839832Samw@Sun.COM 			info503->shi503_security_descriptor = NULL;
9848474SJose.Borrego@Sun.COM 		}
9858474SJose.Borrego@Sun.COM 
9869832Samw@Sun.COM 		param->result.ru.info1501 = info1501;
9878474SJose.Borrego@Sun.COM 		break;
9888474SJose.Borrego@Sun.COM 
9898474SJose.Borrego@Sun.COM 	default:
9908474SJose.Borrego@Sun.COM 		status = ERROR_ACCESS_DENIED;
9918474SJose.Borrego@Sun.COM 		break;
9928474SJose.Borrego@Sun.COM 	}
9938474SJose.Borrego@Sun.COM 
9948474SJose.Borrego@Sun.COM 	if (status != ERROR_SUCCESS)
9958474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
9968474SJose.Borrego@Sun.COM 	else
9978474SJose.Borrego@Sun.COM 		param->result.switch_value = param->level;
9988474SJose.Borrego@Sun.COM 
9998474SJose.Borrego@Sun.COM 	param->status = status;
10008474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
10018474SJose.Borrego@Sun.COM }
10028474SJose.Borrego@Sun.COM 
10039832Samw@Sun.COM static uint32_t
10049832Samw@Sun.COM srvsvc_share_getsd(ndr_xa_t *mxa, smb_share_t *si, srvsvc_sd_t *sd)
10059832Samw@Sun.COM {
10069832Samw@Sun.COM 	uint32_t status;
10079832Samw@Sun.COM 
10089832Samw@Sun.COM 	status = srvsvc_sd_get(si, NULL, &sd->sd_size);
10099832Samw@Sun.COM 	if (status != ERROR_SUCCESS) {
10109832Samw@Sun.COM 		if (status == ERROR_PATH_NOT_FOUND) {
10119832Samw@Sun.COM 			bzero(sd, sizeof (srvsvc_sd_t));
10129832Samw@Sun.COM 			status = ERROR_SUCCESS;
10139832Samw@Sun.COM 		}
10149832Samw@Sun.COM 
10159832Samw@Sun.COM 		return (status);
10169832Samw@Sun.COM 	}
10179832Samw@Sun.COM 
10189832Samw@Sun.COM 	if ((sd->sd_buf = NDR_MALLOC(mxa, sd->sd_size)) == NULL)
10199832Samw@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
10209832Samw@Sun.COM 
10219832Samw@Sun.COM 	status = srvsvc_sd_get(si, sd->sd_buf, NULL);
10229832Samw@Sun.COM 	if (status == ERROR_PATH_NOT_FOUND) {
10239832Samw@Sun.COM 		bzero(sd, sizeof (srvsvc_sd_t));
10249832Samw@Sun.COM 		status = ERROR_SUCCESS;
10259832Samw@Sun.COM 	}
10269832Samw@Sun.COM 
10279832Samw@Sun.COM 	return (status);
10289832Samw@Sun.COM }
10298474SJose.Borrego@Sun.COM 
10308474SJose.Borrego@Sun.COM /*
10318474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareSetInfo
10328474SJose.Borrego@Sun.COM  *
10338474SJose.Borrego@Sun.COM  * This call is made by SrvMgr to set share information.
10349832Samw@Sun.COM  * Only power users groups can manage shares.
10359832Samw@Sun.COM  *
10369832Samw@Sun.COM  * To avoid misleading errors, we don't report an error
10379832Samw@Sun.COM  * when a FS doesn't support ACLs on shares.
10388474SJose.Borrego@Sun.COM  *
10398474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
10408474SJose.Borrego@Sun.COM  */
10418474SJose.Borrego@Sun.COM static int
10428474SJose.Borrego@Sun.COM srvsvc_s_NetShareSetInfo(void *arg, ndr_xa_t *mxa)
10438474SJose.Borrego@Sun.COM {
10448474SJose.Borrego@Sun.COM 	struct mlsm_NetShareSetInfo *param = arg;
10459832Samw@Sun.COM 	struct mslm_NetShareInfo_0 *info0;
10469832Samw@Sun.COM 	struct mslm_NetShareInfo_1 *info1;
10479832Samw@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
10489832Samw@Sun.COM 	struct mslm_NetShareInfo_501 *info501;
10499832Samw@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
10509832Samw@Sun.COM 	struct mslm_NetShareInfo_503 *info503;
10519832Samw@Sun.COM 	struct mslm_NetShareInfo_1004 *info1004;
10529832Samw@Sun.COM 	struct mslm_NetShareInfo_1005 *info1005;
10539832Samw@Sun.COM 	struct mslm_NetShareInfo_1501 *info1501;
10549832Samw@Sun.COM 	static DWORD parm_err = 0;
10559832Samw@Sun.COM 	srvsvc_netshare_setinfo_t info;
10569832Samw@Sun.COM 	smb_share_t si;
10579832Samw@Sun.COM 	uint8_t *sdbuf;
10589832Samw@Sun.COM 	int32_t native_os;
10599832Samw@Sun.COM 	DWORD status;
10609832Samw@Sun.COM 
10619832Samw@Sun.COM 	native_os = ndr_native_os(mxa);
10629832Samw@Sun.COM 
10639832Samw@Sun.COM 	if (!ndr_is_poweruser(mxa)) {
10649832Samw@Sun.COM 		status = ERROR_ACCESS_DENIED;
10659832Samw@Sun.COM 		goto netsharesetinfo_exit;
10669832Samw@Sun.COM 	}
10679832Samw@Sun.COM 
10689832Samw@Sun.COM 	if (smb_shr_get((char *)param->netname, &si) != NERR_Success) {
10699832Samw@Sun.COM 		status = ERROR_INVALID_NETNAME;
10709832Samw@Sun.COM 		goto netsharesetinfo_exit;
10719832Samw@Sun.COM 	}
10729832Samw@Sun.COM 
10739832Samw@Sun.COM 	if (param->result.ru.nullptr == NULL) {
10749832Samw@Sun.COM 		status = ERROR_INVALID_PARAMETER;
10759832Samw@Sun.COM 		goto netsharesetinfo_exit;
10769832Samw@Sun.COM 	}
10779832Samw@Sun.COM 
10789832Samw@Sun.COM 	bzero(&info, sizeof (srvsvc_netshare_setinfo_t));
10799832Samw@Sun.COM 
10809832Samw@Sun.COM 	switch (param->level) {
10819832Samw@Sun.COM 	case 0:
10829832Samw@Sun.COM 		info0 = (struct mslm_NetShareInfo_0 *)param->result.ru.info0;
10839832Samw@Sun.COM 		info.nss_netname = (char *)info0->shi0_netname;
10849832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
10859832Samw@Sun.COM 		break;
10869832Samw@Sun.COM 
10879832Samw@Sun.COM 	case 1:
10889832Samw@Sun.COM 		info1 = (struct mslm_NetShareInfo_1 *)param->result.ru.info1;
10899832Samw@Sun.COM 		info.nss_netname = (char *)info1->shi1_netname;
10909832Samw@Sun.COM 		info.nss_comment = (char *)info1->shi1_comment;
10919832Samw@Sun.COM 		info.nss_type = info1->shi1_type;
10929832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
10939832Samw@Sun.COM 		break;
10949832Samw@Sun.COM 
10959832Samw@Sun.COM 	case 2:
10969832Samw@Sun.COM 		info2 = (struct mslm_NetShareInfo_2 *)param->result.ru.info2;
10979832Samw@Sun.COM 		info.nss_netname = (char *)info2->shi2_netname;
10989832Samw@Sun.COM 		info.nss_comment = (char *)info2->shi2_comment;
10999832Samw@Sun.COM 		info.nss_path = (char *)info2->shi2_path;
11009832Samw@Sun.COM 		info.nss_type = info2->shi2_type;
11019832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11029832Samw@Sun.COM 		break;
11039832Samw@Sun.COM 
11049832Samw@Sun.COM 	case 501:
11059832Samw@Sun.COM 		info501 = (struct mslm_NetShareInfo_501 *)
11069832Samw@Sun.COM 		    param->result.ru.info501;
11079832Samw@Sun.COM 		info.nss_netname = (char *)info501->shi501_netname;
11089832Samw@Sun.COM 		info.nss_comment = (char *)info501->shi501_comment;
11099832Samw@Sun.COM 		info.nss_type = info501->shi501_type;
11109832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11119832Samw@Sun.COM 		break;
11129832Samw@Sun.COM 
11139832Samw@Sun.COM 	case 502:
11149832Samw@Sun.COM 		info502 = (struct mslm_NetShareInfo_502 *)
11159832Samw@Sun.COM 		    param->result.ru.info502;
11169832Samw@Sun.COM 		info.nss_netname = (char *)info502->shi502_netname;
11179832Samw@Sun.COM 		info.nss_comment = (char *)info502->shi502_comment;
11189832Samw@Sun.COM 		info.nss_path = (char *)info502->shi502_path;
11199832Samw@Sun.COM 		info.nss_type = info502->shi502_type;
11209832Samw@Sun.COM 		info.nss_sd.sd_buf = info502->shi502_security_descriptor;
11219832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11229832Samw@Sun.COM 		break;
11239832Samw@Sun.COM 
11249832Samw@Sun.COM 	case 503:
11259832Samw@Sun.COM 		info503 = (struct mslm_NetShareInfo_503 *)
11269832Samw@Sun.COM 		    param->result.ru.info503;
11279832Samw@Sun.COM 		info.nss_netname = (char *)info503->shi503_netname;
11289832Samw@Sun.COM 		info.nss_comment = (char *)info503->shi503_comment;
11299832Samw@Sun.COM 		info.nss_path = (char *)info503->shi503_path;
11309832Samw@Sun.COM 		info.nss_type = info503->shi503_type;
11319832Samw@Sun.COM 		info.nss_sd.sd_buf = info503->shi503_security_descriptor;
11329832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11339832Samw@Sun.COM 		break;
11349832Samw@Sun.COM 
11359832Samw@Sun.COM 	case 1004:
11369832Samw@Sun.COM 		info1004 = (struct mslm_NetShareInfo_1004 *)
11379832Samw@Sun.COM 		    param->result.ru.info1004;
11389832Samw@Sun.COM 		info.nss_comment = (char *)info1004->shi1004_comment;
11399832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11409832Samw@Sun.COM 		break;
11419832Samw@Sun.COM 
11429832Samw@Sun.COM 	case 1005:
11439832Samw@Sun.COM 		info1005 = (struct mslm_NetShareInfo_1005 *)
11449832Samw@Sun.COM 		    param->result.ru.info1005;
11459832Samw@Sun.COM 		status = srvsvc_update_share_flags(&si,
11469832Samw@Sun.COM 		    info1005->shi1005_flags);
11479832Samw@Sun.COM 		break;
11489832Samw@Sun.COM 
11499832Samw@Sun.COM 	case 1006:
11509832Samw@Sun.COM 		/*
11519832Samw@Sun.COM 		 * We don't limit the maximum number of concurrent
11529832Samw@Sun.COM 		 * connections to a share.
11539832Samw@Sun.COM 		 */
11549832Samw@Sun.COM 		status = ERROR_SUCCESS;
11559832Samw@Sun.COM 		break;
11569832Samw@Sun.COM 
11579832Samw@Sun.COM 	case 1501:
11589832Samw@Sun.COM 		info1501 = (struct mslm_NetShareInfo_1501 *)
11599832Samw@Sun.COM 		    param->result.ru.info1501;
11609832Samw@Sun.COM 		sdbuf = info1501->shi1501_security_descriptor;
11619832Samw@Sun.COM 		status = ERROR_SUCCESS;
11629832Samw@Sun.COM 
11639832Samw@Sun.COM 		if (sdbuf != NULL) {
11649832Samw@Sun.COM 			status = srvsvc_sd_set(&si, sdbuf);
11659832Samw@Sun.COM 			if (status == ERROR_PATH_NOT_FOUND)
11669832Samw@Sun.COM 				status = ERROR_SUCCESS;
11679832Samw@Sun.COM 		}
11689832Samw@Sun.COM 		break;
11699832Samw@Sun.COM 
11709832Samw@Sun.COM 	default:
11719832Samw@Sun.COM 		status = ERROR_ACCESS_DENIED;
11729832Samw@Sun.COM 		break;
11739832Samw@Sun.COM 	}
11749832Samw@Sun.COM 
11759832Samw@Sun.COM netsharesetinfo_exit:
11769832Samw@Sun.COM 	if (status != ERROR_SUCCESS)
11779832Samw@Sun.COM 		bzero(param, sizeof (struct mlsm_NetShareSetInfo));
11789832Samw@Sun.COM 
11799832Samw@Sun.COM 	param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
11809832Samw@Sun.COM 	param->status = status;
11818474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
11828474SJose.Borrego@Sun.COM }
11838474SJose.Borrego@Sun.COM 
11849832Samw@Sun.COM static uint32_t
11859832Samw@Sun.COM srvsvc_modify_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
11869832Samw@Sun.COM {
11879832Samw@Sun.COM 	uint32_t nerr = NERR_Success;
11889832Samw@Sun.COM 
11899832Samw@Sun.COM 	if (si->shr_flags & SMB_SHRF_TRANS)
11909832Samw@Sun.COM 		return (srvsvc_modify_transient_share(si, info));
11919832Samw@Sun.COM 
11929832Samw@Sun.COM 	if (info->nss_sd.sd_buf != NULL) {
11939832Samw@Sun.COM 		nerr = srvsvc_sd_set(si, info->nss_sd.sd_buf);
11949832Samw@Sun.COM 		if (nerr == ERROR_PATH_NOT_FOUND)
11959832Samw@Sun.COM 			nerr = NERR_Success;
11969832Samw@Sun.COM 	}
11979832Samw@Sun.COM 
11989832Samw@Sun.COM 	if ((nerr = srvsvc_sa_modify(si, info)) == NERR_Success)
11999832Samw@Sun.COM 		nerr = smb_shr_modify(si);
12009832Samw@Sun.COM 
12019832Samw@Sun.COM 	return (nerr);
12029832Samw@Sun.COM }
12039832Samw@Sun.COM 
12049832Samw@Sun.COM /*
12059832Samw@Sun.COM  * Update transient shares.  This includes autohome shares.
12069832Samw@Sun.COM  */
12079832Samw@Sun.COM static uint32_t
12089832Samw@Sun.COM srvsvc_modify_transient_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
12099832Samw@Sun.COM {
12109832Samw@Sun.COM 	uint32_t nerr;
12119832Samw@Sun.COM 
12129832Samw@Sun.COM 	if (info->nss_netname != NULL && info->nss_netname[0] != '\0' &&
12139832Samw@Sun.COM 	    utf8_strcasecmp(info->nss_netname, si->shr_name) != 0) {
12149832Samw@Sun.COM 		nerr = smb_shr_rename(si->shr_name, info->nss_netname);
12159832Samw@Sun.COM 		if (nerr != NERR_Success)
12169832Samw@Sun.COM 			return (nerr);
12179832Samw@Sun.COM 
12189832Samw@Sun.COM 		(void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN);
12199832Samw@Sun.COM 	}
12209832Samw@Sun.COM 
12219832Samw@Sun.COM 	if ((info->nss_comment != NULL) &&
12229832Samw@Sun.COM 	    (strcmp(info->nss_comment, si->shr_cmnt) != 0)) {
12239832Samw@Sun.COM 		(void) strlcpy(si->shr_cmnt, info->nss_comment,
12249832Samw@Sun.COM 		    SMB_SHARE_CMNT_MAX);
12259832Samw@Sun.COM 
12269832Samw@Sun.COM 		if ((nerr = smb_shr_modify(si)) != NERR_Success)
12279832Samw@Sun.COM 			return (nerr);
12289832Samw@Sun.COM 	}
12299832Samw@Sun.COM 
12309832Samw@Sun.COM 	return (NERR_Success);
12319832Samw@Sun.COM }
12329832Samw@Sun.COM 
12339832Samw@Sun.COM static uint32_t
12349832Samw@Sun.COM srvsvc_update_share_flags(smb_share_t *si, uint32_t shi_flags)
12359832Samw@Sun.COM {
12369832Samw@Sun.COM 	uint32_t cscflg = 0;
12379832Samw@Sun.COM 	uint32_t nerr = NERR_Success;
12389832Samw@Sun.COM 
12399832Samw@Sun.COM 	switch ((shi_flags & CSC_MASK)) {
12409832Samw@Sun.COM 	case CSC_CACHE_AUTO_REINT:
12419832Samw@Sun.COM 		cscflg = SMB_SHRF_CSC_AUTO;
12429832Samw@Sun.COM 		break;
12439832Samw@Sun.COM 	case CSC_CACHE_VDO:
12449832Samw@Sun.COM 		cscflg = SMB_SHRF_CSC_VDO;
12459832Samw@Sun.COM 		break;
12469832Samw@Sun.COM 	case CSC_CACHE_NONE:
12479832Samw@Sun.COM 		cscflg = SMB_SHRF_CSC_DISABLED;
12489832Samw@Sun.COM 		break;
12499832Samw@Sun.COM 	case CSC_CACHE_MANUAL_REINT:
12509832Samw@Sun.COM 		cscflg = SMB_SHRF_CSC_MANUAL;
12519832Samw@Sun.COM 		break;
12529832Samw@Sun.COM 	default:
12539832Samw@Sun.COM 		return (NERR_Success);
12549832Samw@Sun.COM 	}
12559832Samw@Sun.COM 
12569832Samw@Sun.COM 	if (cscflg == (si->shr_flags & SMB_SHRF_CSC_MASK))
12579832Samw@Sun.COM 		return (NERR_Success);
12589832Samw@Sun.COM 
12599832Samw@Sun.COM 	si->shr_flags &= ~SMB_SHRF_CSC_MASK;
12609832Samw@Sun.COM 	si->shr_flags |= cscflg;
12619832Samw@Sun.COM 
12629832Samw@Sun.COM 	if ((si->shr_flags & SMB_SHRF_TRANS) == 0) {
12639832Samw@Sun.COM 		if ((nerr = srvsvc_sa_setattr(si)) != NERR_Success)
12649832Samw@Sun.COM 			return (nerr);
12659832Samw@Sun.COM 	}
12669832Samw@Sun.COM 
12679832Samw@Sun.COM 	return (smb_shr_modify(si));
12689832Samw@Sun.COM }
12699832Samw@Sun.COM 
12708474SJose.Borrego@Sun.COM /*
12718474SJose.Borrego@Sun.COM  * srvsvc_s_NetSessionEnum
12728474SJose.Borrego@Sun.COM  *
12738474SJose.Borrego@Sun.COM  * Level 1 request is made by (Server Manager (srvmgr) on NT Server when
12748474SJose.Borrego@Sun.COM  * the user info icon is selected.
12758474SJose.Borrego@Sun.COM  *
12768474SJose.Borrego@Sun.COM  * On success, the return value is NERR_Success.
12778474SJose.Borrego@Sun.COM  * On error, the return value can be one of the following error codes:
12788474SJose.Borrego@Sun.COM  *
12798474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED      The user does not have access to the requested
12808474SJose.Borrego@Sun.COM  *                          information.
12818474SJose.Borrego@Sun.COM  * ERROR_INVALID_LEVEL      The value specified for the level is invalid.
12828474SJose.Borrego@Sun.COM  * ERROR_INVALID_PARAMETER  The specified parameter is invalid.
12838474SJose.Borrego@Sun.COM  * ERROR_MORE_DATA          More entries are available. Specify a large
12848474SJose.Borrego@Sun.COM  *                          enough buffer to receive all entries.
12858474SJose.Borrego@Sun.COM  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
12868474SJose.Borrego@Sun.COM  * NERR_ClientNameNotFound  A session does not exist with the computer name.
12878474SJose.Borrego@Sun.COM  * NERR_InvalidComputer     The computer name is invalid.
12888474SJose.Borrego@Sun.COM  * NERR_UserNotFound        The user name could not be found.
12898474SJose.Borrego@Sun.COM  */
12908474SJose.Borrego@Sun.COM static int
12918474SJose.Borrego@Sun.COM srvsvc_s_NetSessionEnum(void *arg, ndr_xa_t *mxa)
12928474SJose.Borrego@Sun.COM {
1293*10122SJordan.Brown@Sun.COM 	struct mslm_NetSessionEnum	*param = arg;
1294*10122SJordan.Brown@Sun.COM 	srvsvc_infonres_t		*info;
1295*10122SJordan.Brown@Sun.COM 	smb_netsvc_t			*ns;
1296*10122SJordan.Brown@Sun.COM 	smb_svcenum_t			se;
1297*10122SJordan.Brown@Sun.COM 	DWORD				status = ERROR_SUCCESS;
1298*10122SJordan.Brown@Sun.COM 
1299*10122SJordan.Brown@Sun.COM 	if (!ndr_is_admin(mxa)) {
1300*10122SJordan.Brown@Sun.COM 		status = ERROR_ACCESS_DENIED;
1301*10122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
1302*10122SJordan.Brown@Sun.COM 	}
1303*10122SJordan.Brown@Sun.COM 
1304*10122SJordan.Brown@Sun.COM 	if ((info = NDR_NEW(mxa, srvsvc_infonres_t)) == NULL) {
1305*10122SJordan.Brown@Sun.COM 		status = ERROR_NOT_ENOUGH_MEMORY;
1306*10122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
1307*10122SJordan.Brown@Sun.COM 	}
1308*10122SJordan.Brown@Sun.COM 
1309*10122SJordan.Brown@Sun.COM 	info->entriesread = 0;
1310*10122SJordan.Brown@Sun.COM 	info->entries = NULL;
1311*10122SJordan.Brown@Sun.COM 	param->result.level = param->level;
1312*10122SJordan.Brown@Sun.COM 	param->result.bufptr.p = info;
1313*10122SJordan.Brown@Sun.COM 
1314*10122SJordan.Brown@Sun.COM 	if ((param->total_entries = srvsvc_open_sessions()) == 0) {
1315*10122SJordan.Brown@Sun.COM 		param->resume_handle = NULL;
1316*10122SJordan.Brown@Sun.COM 		param->status = ERROR_SUCCESS;
13178474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
13188474SJose.Borrego@Sun.COM 	}
13198474SJose.Borrego@Sun.COM 
1320*10122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
1321*10122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_USER;
1322*10122SJordan.Brown@Sun.COM 	se.se_level = param->level;
1323*10122SJordan.Brown@Sun.COM 	se.se_ntotal = param->total_entries;
1324*10122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
1325*10122SJordan.Brown@Sun.COM 
1326*10122SJordan.Brown@Sun.COM 	if (param->resume_handle) {
1327*10122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
1328*10122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
1329*10122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
1330*10122SJordan.Brown@Sun.COM 	}
13318474SJose.Borrego@Sun.COM 
13328474SJose.Borrego@Sun.COM 	switch (param->level) {
13338474SJose.Borrego@Sun.COM 	case 0:
1334*10122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_0,
1335*10122SJordan.Brown@Sun.COM 		    se.se_nlimit);
13368474SJose.Borrego@Sun.COM 		break;
1337*10122SJordan.Brown@Sun.COM 	case 1:
1338*10122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_1,
1339*10122SJordan.Brown@Sun.COM 		    se.se_nlimit);
13409832Samw@Sun.COM 		break;
1341*10122SJordan.Brown@Sun.COM 	case 2:
1342*10122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_2,
1343*10122SJordan.Brown@Sun.COM 		    se.se_nlimit);
13449832Samw@Sun.COM 		break;
1345*10122SJordan.Brown@Sun.COM 	case 10:
1346*10122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_10,
1347*10122SJordan.Brown@Sun.COM 		    se.se_nlimit);
1348*10122SJordan.Brown@Sun.COM 		break;
13499832Samw@Sun.COM 	case 502:
1350*10122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_502,
1351*10122SJordan.Brown@Sun.COM 		    se.se_nlimit);
13529832Samw@Sun.COM 		break;
13538474SJose.Borrego@Sun.COM 	default:
13548474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetSessionEnum));
1355*10122SJordan.Brown@Sun.COM 		param->status = ERROR_INVALID_LEVEL;
13568474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
13578474SJose.Borrego@Sun.COM 	}
13588474SJose.Borrego@Sun.COM 
1359*10122SJordan.Brown@Sun.COM 	if (info->entries == NULL) {
1360*10122SJordan.Brown@Sun.COM 		status = ERROR_NOT_ENOUGH_MEMORY;
1361*10122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
1362*10122SJordan.Brown@Sun.COM 	}
1363*10122SJordan.Brown@Sun.COM 
1364*10122SJordan.Brown@Sun.COM 	if ((ns = smb_kmod_enum_init(&se)) == NULL) {
1365*10122SJordan.Brown@Sun.COM 		status = ERROR_NOT_ENOUGH_MEMORY;
1366*10122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
1367*10122SJordan.Brown@Sun.COM 	}
1368*10122SJordan.Brown@Sun.COM 
1369*10122SJordan.Brown@Sun.COM 	status = srvsvc_NetSessionEnumCommon(mxa, info, ns, &se);
1370*10122SJordan.Brown@Sun.COM 	smb_kmod_enum_fini(ns);
1371*10122SJordan.Brown@Sun.COM 
1372*10122SJordan.Brown@Sun.COM 	if (status != ERROR_SUCCESS)
1373*10122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
1374*10122SJordan.Brown@Sun.COM 
1375*10122SJordan.Brown@Sun.COM 	if (param->resume_handle &&
1376*10122SJordan.Brown@Sun.COM 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
1377*10122SJordan.Brown@Sun.COM 		if (se.se_resume < param->total_entries) {
1378*10122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
1379*10122SJordan.Brown@Sun.COM 			status = ERROR_MORE_DATA;
1380*10122SJordan.Brown@Sun.COM 		}
1381*10122SJordan.Brown@Sun.COM 	}
1382*10122SJordan.Brown@Sun.COM 
1383*10122SJordan.Brown@Sun.COM 	param->total_entries = info->entriesread;
1384*10122SJordan.Brown@Sun.COM 	param->status = status;
1385*10122SJordan.Brown@Sun.COM 	return (NDR_DRC_OK);
1386*10122SJordan.Brown@Sun.COM 
1387*10122SJordan.Brown@Sun.COM srvsvc_netsessionenum_error:
1388*10122SJordan.Brown@Sun.COM 	bzero(param, sizeof (struct mslm_NetSessionEnum));
13898474SJose.Borrego@Sun.COM 	param->status = status;
13908474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
13918474SJose.Borrego@Sun.COM }
13928474SJose.Borrego@Sun.COM 
1393*10122SJordan.Brown@Sun.COM static uint32_t
1394*10122SJordan.Brown@Sun.COM srvsvc_NetSessionEnumCommon(ndr_xa_t *mxa, srvsvc_infonres_t *info,
1395*10122SJordan.Brown@Sun.COM     smb_netsvc_t *ns, smb_svcenum_t *se)
13968474SJose.Borrego@Sun.COM {
1397*10122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_0	*info0 = info->entries;
1398*10122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_1	*info1 = info->entries;
1399*10122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_2	*info2 = info->entries;
1400*10122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_10	*info10 = info->entries;
1401*10122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_502	*info502 = info->entries;
1402*10122SJordan.Brown@Sun.COM 	smb_netsvcitem_t		*item;
1403*10122SJordan.Brown@Sun.COM 	smb_netuserinfo_t		*user;
1404*10122SJordan.Brown@Sun.COM 	char				*workstation;
1405*10122SJordan.Brown@Sun.COM 	char				account[MAXNAMELEN];
1406*10122SJordan.Brown@Sun.COM 	char				ipaddr_buf[INET6_ADDRSTRLEN];
1407*10122SJordan.Brown@Sun.COM 	uint32_t			logon_time;
1408*10122SJordan.Brown@Sun.COM 	uint32_t			flags;
1409*10122SJordan.Brown@Sun.COM 	uint32_t			entries_read = 0;
1410*10122SJordan.Brown@Sun.COM 
1411*10122SJordan.Brown@Sun.COM 	if (smb_kmod_enum(ns) != 0)
1412*10122SJordan.Brown@Sun.COM 		return (ERROR_INTERNAL_ERROR);
1413*10122SJordan.Brown@Sun.COM 
1414*10122SJordan.Brown@Sun.COM 	item = list_head(&ns->ns_list);
1415*10122SJordan.Brown@Sun.COM 	while (item != NULL) {
1416*10122SJordan.Brown@Sun.COM 		user = &item->nsi_un.nsi_user;
1417*10122SJordan.Brown@Sun.COM 
1418*10122SJordan.Brown@Sun.COM 		workstation = user->ui_workstation;
14198474SJose.Borrego@Sun.COM 		if (workstation == NULL || *workstation == '\0') {
1420*10122SJordan.Brown@Sun.COM 			(void) smb_inet_ntop(&user->ui_ipaddr, ipaddr_buf,
1421*10122SJordan.Brown@Sun.COM 			    SMB_IPSTRLEN(user->ui_ipaddr.a_family));
14228474SJose.Borrego@Sun.COM 			workstation = ipaddr_buf;
14238474SJose.Borrego@Sun.COM 		}
14248474SJose.Borrego@Sun.COM 
14258474SJose.Borrego@Sun.COM 		(void) snprintf(account, MAXNAMELEN, "%s\\%s",
1426*10122SJordan.Brown@Sun.COM 		    user->ui_domain, user->ui_account);
1427*10122SJordan.Brown@Sun.COM 
1428*10122SJordan.Brown@Sun.COM 		logon_time = time(0) - user->ui_logon_time;
1429*10122SJordan.Brown@Sun.COM 		flags = (user->ui_flags & SMB_ATF_GUEST) ? SESS_GUEST : 0;
1430*10122SJordan.Brown@Sun.COM 
1431*10122SJordan.Brown@Sun.COM 		switch (se->se_level) {
1432*10122SJordan.Brown@Sun.COM 		case 0:
1433*10122SJordan.Brown@Sun.COM 			info0->sesi0_cname = NDR_STRDUP(mxa, workstation);
1434*10122SJordan.Brown@Sun.COM 			if (info0->sesi0_cname == NULL)
1435*10122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
1436*10122SJordan.Brown@Sun.COM 			++info0;
1437*10122SJordan.Brown@Sun.COM 			break;
1438*10122SJordan.Brown@Sun.COM 
1439*10122SJordan.Brown@Sun.COM 		case 1:
1440*10122SJordan.Brown@Sun.COM 			info1->sesi1_cname = NDR_STRDUP(mxa, workstation);
1441*10122SJordan.Brown@Sun.COM 			info1->sesi1_uname = NDR_STRDUP(mxa, account);
1442*10122SJordan.Brown@Sun.COM 
1443*10122SJordan.Brown@Sun.COM 			if (info1->sesi1_cname == NULL ||
1444*10122SJordan.Brown@Sun.COM 			    info1->sesi1_uname == NULL)
1445*10122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
1446*10122SJordan.Brown@Sun.COM 
1447*10122SJordan.Brown@Sun.COM 			info1->sesi1_nopens = user->ui_numopens;
1448*10122SJordan.Brown@Sun.COM 			info1->sesi1_time = logon_time;
1449*10122SJordan.Brown@Sun.COM 			info1->sesi1_itime = 0;
1450*10122SJordan.Brown@Sun.COM 			info1->sesi1_uflags = flags;
1451*10122SJordan.Brown@Sun.COM 			++info1;
1452*10122SJordan.Brown@Sun.COM 			break;
1453*10122SJordan.Brown@Sun.COM 
1454*10122SJordan.Brown@Sun.COM 		case 2:
1455*10122SJordan.Brown@Sun.COM 			info2->sesi2_cname = NDR_STRDUP(mxa, workstation);
1456*10122SJordan.Brown@Sun.COM 			info2->sesi2_uname = NDR_STRDUP(mxa, account);
1457*10122SJordan.Brown@Sun.COM 
1458*10122SJordan.Brown@Sun.COM 			if (info2->sesi2_cname == NULL ||
1459*10122SJordan.Brown@Sun.COM 			    info2->sesi2_uname == NULL)
1460*10122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
1461*10122SJordan.Brown@Sun.COM 
1462*10122SJordan.Brown@Sun.COM 			info2->sesi2_nopens = user->ui_numopens;
1463*10122SJordan.Brown@Sun.COM 			info2->sesi2_time = logon_time;
1464*10122SJordan.Brown@Sun.COM 			info2->sesi2_itime = 0;
1465*10122SJordan.Brown@Sun.COM 			info2->sesi2_uflags = flags;
1466*10122SJordan.Brown@Sun.COM 			info2->sesi2_cltype_name = (uint8_t *)"";
1467*10122SJordan.Brown@Sun.COM 			++info2;
1468*10122SJordan.Brown@Sun.COM 			break;
1469*10122SJordan.Brown@Sun.COM 
1470*10122SJordan.Brown@Sun.COM 		case 10:
1471*10122SJordan.Brown@Sun.COM 			info10->sesi10_cname = NDR_STRDUP(mxa, workstation);
1472*10122SJordan.Brown@Sun.COM 			info10->sesi10_uname = NDR_STRDUP(mxa, account);
1473*10122SJordan.Brown@Sun.COM 
1474*10122SJordan.Brown@Sun.COM 			if (info10->sesi10_cname == NULL ||
1475*10122SJordan.Brown@Sun.COM 			    info10->sesi10_uname == NULL)
1476*10122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
1477*10122SJordan.Brown@Sun.COM 
1478*10122SJordan.Brown@Sun.COM 			info10->sesi10_time = logon_time;
1479*10122SJordan.Brown@Sun.COM 			info10->sesi10_itime = 0;
1480*10122SJordan.Brown@Sun.COM 			++info10;
1481*10122SJordan.Brown@Sun.COM 			break;
1482*10122SJordan.Brown@Sun.COM 
1483*10122SJordan.Brown@Sun.COM 		case 502:
1484*10122SJordan.Brown@Sun.COM 			info502->sesi502_cname = NDR_STRDUP(mxa, workstation);
1485*10122SJordan.Brown@Sun.COM 			info502->sesi502_uname = NDR_STRDUP(mxa, account);
1486*10122SJordan.Brown@Sun.COM 
1487*10122SJordan.Brown@Sun.COM 			if (info502->sesi502_cname == NULL ||
1488*10122SJordan.Brown@Sun.COM 			    info502->sesi502_uname == NULL)
1489*10122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
1490*10122SJordan.Brown@Sun.COM 
1491*10122SJordan.Brown@Sun.COM 			info502->sesi502_nopens = user->ui_numopens;
1492*10122SJordan.Brown@Sun.COM 			info502->sesi502_time = logon_time;
1493*10122SJordan.Brown@Sun.COM 			info502->sesi502_itime = 0;
1494*10122SJordan.Brown@Sun.COM 			info502->sesi502_uflags = flags;
1495*10122SJordan.Brown@Sun.COM 			info502->sesi502_cltype_name = (uint8_t *)"";
1496*10122SJordan.Brown@Sun.COM 			info502->sesi502_transport = (uint8_t *)"";
1497*10122SJordan.Brown@Sun.COM 			++info502;
1498*10122SJordan.Brown@Sun.COM 			break;
1499*10122SJordan.Brown@Sun.COM 
1500*10122SJordan.Brown@Sun.COM 		default:
1501*10122SJordan.Brown@Sun.COM 			return (ERROR_INVALID_LEVEL);
15028474SJose.Borrego@Sun.COM 		}
15038474SJose.Borrego@Sun.COM 
1504*10122SJordan.Brown@Sun.COM 		++entries_read;
1505*10122SJordan.Brown@Sun.COM 		item = list_next(&ns->ns_list, item);
15069832Samw@Sun.COM 	}
15079832Samw@Sun.COM 
1508*10122SJordan.Brown@Sun.COM 	info->entriesread = entries_read;
15099832Samw@Sun.COM 	return (ERROR_SUCCESS);
15109832Samw@Sun.COM }
15119832Samw@Sun.COM 
15129832Samw@Sun.COM /*
15138474SJose.Borrego@Sun.COM  * srvsvc_s_NetSessionDel
15148474SJose.Borrego@Sun.COM  *
15158474SJose.Borrego@Sun.COM  * Ends a network session between a server and a workstation.
15168474SJose.Borrego@Sun.COM  * On NT only members of the Administrators or Account Operators
15178474SJose.Borrego@Sun.COM  * local groups are permitted to use NetSessionDel.
15188474SJose.Borrego@Sun.COM  *
1519*10122SJordan.Brown@Sun.COM  * If unc_clientname is NULL, all sessions associated with the
1520*10122SJordan.Brown@Sun.COM  * specified user will be disconnected.
1521*10122SJordan.Brown@Sun.COM  *
1522*10122SJordan.Brown@Sun.COM  * If username is NULL, all sessions from the specified client
1523*10122SJordan.Brown@Sun.COM  * will be disconnected.
1524*10122SJordan.Brown@Sun.COM  *
15258474SJose.Borrego@Sun.COM  * Return Values
1526*10122SJordan.Brown@Sun.COM  * On success, the return value is NERR_Success/ERROR_SUCCESS.
1527*10122SJordan.Brown@Sun.COM  * On failure, the return value can be one of the following errors:
15288474SJose.Borrego@Sun.COM  *
15298474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED 		The user does not have access to the
1530*10122SJordan.Brown@Sun.COM  * 				requested information.
15318474SJose.Borrego@Sun.COM  * ERROR_INVALID_PARAMETER	The specified parameter is invalid.
15328474SJose.Borrego@Sun.COM  * ERROR_NOT_ENOUGH_MEMORY	Insufficient memory is available.
15338474SJose.Borrego@Sun.COM  * NERR_ClientNameNotFound	A session does not exist with that
1534*10122SJordan.Brown@Sun.COM  *				computer name.
15358474SJose.Borrego@Sun.COM  */
15368474SJose.Borrego@Sun.COM static int
15378474SJose.Borrego@Sun.COM srvsvc_s_NetSessionDel(void *arg, ndr_xa_t *mxa)
15388474SJose.Borrego@Sun.COM {
1539*10122SJordan.Brown@Sun.COM 	static struct {
1540*10122SJordan.Brown@Sun.COM 		int errnum;
1541*10122SJordan.Brown@Sun.COM 		int nerr;
1542*10122SJordan.Brown@Sun.COM 	} errmap[] = {
1543*10122SJordan.Brown@Sun.COM 		0,	ERROR_SUCCESS,
1544*10122SJordan.Brown@Sun.COM 		EACCES,	ERROR_ACCESS_DENIED,
1545*10122SJordan.Brown@Sun.COM 		EPERM,	ERROR_ACCESS_DENIED,
1546*10122SJordan.Brown@Sun.COM 		EINVAL,	ERROR_INVALID_PARAMETER,
1547*10122SJordan.Brown@Sun.COM 		ENOMEM,	ERROR_NOT_ENOUGH_MEMORY,
1548*10122SJordan.Brown@Sun.COM 		ENOENT,	NERR_ClientNameNotFound
1549*10122SJordan.Brown@Sun.COM 	};
1550*10122SJordan.Brown@Sun.COM 
15518474SJose.Borrego@Sun.COM 	struct mslm_NetSessionDel *param = arg;
1552*10122SJordan.Brown@Sun.COM 	int	i;
1553*10122SJordan.Brown@Sun.COM 	int	rc;
1554*10122SJordan.Brown@Sun.COM 
1555*10122SJordan.Brown@Sun.COM 	if (!ndr_is_admin(mxa)) {
15568474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
15578474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
15588474SJose.Borrego@Sun.COM 	}
15598474SJose.Borrego@Sun.COM 
1560*10122SJordan.Brown@Sun.COM 	rc = smb_kmod_session_close((char *)param->unc_clientname,
1561*10122SJordan.Brown@Sun.COM 	    (char *)param->username);
1562*10122SJordan.Brown@Sun.COM 
1563*10122SJordan.Brown@Sun.COM 	for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) {
1564*10122SJordan.Brown@Sun.COM 		if (rc == errmap[i].errnum) {
1565*10122SJordan.Brown@Sun.COM 			param->status = errmap[i].nerr;
1566*10122SJordan.Brown@Sun.COM 			return (NDR_DRC_OK);
1567*10122SJordan.Brown@Sun.COM 		}
1568*10122SJordan.Brown@Sun.COM 	}
1569*10122SJordan.Brown@Sun.COM 
1570*10122SJordan.Brown@Sun.COM 	param->status = ERROR_INTERNAL_ERROR;
15718474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
15728474SJose.Borrego@Sun.COM }
15738474SJose.Borrego@Sun.COM 
15748474SJose.Borrego@Sun.COM /*
15758474SJose.Borrego@Sun.COM  * SRVSVC NetServerGetInfo
15768474SJose.Borrego@Sun.COM  *
15778474SJose.Borrego@Sun.COM  *	IN	LPTSTR servername,
15788474SJose.Borrego@Sun.COM  *	IN	DWORD level,
15798474SJose.Borrego@Sun.COM  *	OUT	union switch(level) {
15808474SJose.Borrego@Sun.COM  *		case 100:	mslm_SERVER_INFO_100 *p100;
15818474SJose.Borrego@Sun.COM  *		case 101:	mslm_SERVER_INFO_101 *p101;
15828474SJose.Borrego@Sun.COM  *		case 102:	mslm_SERVER_INFO_102 *p102;
15839832Samw@Sun.COM  *		...
15848474SJose.Borrego@Sun.COM  *		default:	char *nullptr;
15858474SJose.Borrego@Sun.COM  *		} bufptr,
15868474SJose.Borrego@Sun.COM  *	OUT	DWORD status
15878474SJose.Borrego@Sun.COM  */
15888474SJose.Borrego@Sun.COM static int
15898474SJose.Borrego@Sun.COM srvsvc_s_NetServerGetInfo(void *arg, ndr_xa_t *mxa)
15908474SJose.Borrego@Sun.COM {
15918474SJose.Borrego@Sun.COM 	struct mslm_NetServerGetInfo *param = arg;
15928474SJose.Borrego@Sun.COM 	struct mslm_SERVER_INFO_100 *info100;
15938474SJose.Borrego@Sun.COM 	struct mslm_SERVER_INFO_101 *info101;
15948474SJose.Borrego@Sun.COM 	struct mslm_SERVER_INFO_102 *info102;
15959832Samw@Sun.COM 	struct mslm_SERVER_INFO_502 *info502;
15969832Samw@Sun.COM 	struct mslm_SERVER_INFO_503 *info503;
15978474SJose.Borrego@Sun.COM 	char sys_comment[SMB_PI_MAX_COMMENT];
15988474SJose.Borrego@Sun.COM 	char hostname[NETBIOS_NAME_SZ];
15998474SJose.Borrego@Sun.COM 
16008474SJose.Borrego@Sun.COM 	if (smb_getnetbiosname(hostname, sizeof (hostname)) != 0) {
16018474SJose.Borrego@Sun.COM netservergetinfo_no_memory:
16028474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetServerGetInfo));
16038474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
16048474SJose.Borrego@Sun.COM 	}
16058474SJose.Borrego@Sun.COM 
16068474SJose.Borrego@Sun.COM 	(void) smb_config_getstr(SMB_CI_SYS_CMNT, sys_comment,
16078474SJose.Borrego@Sun.COM 	    sizeof (sys_comment));
16088474SJose.Borrego@Sun.COM 	if (*sys_comment == '\0')
16098474SJose.Borrego@Sun.COM 		(void) strcpy(sys_comment, " ");
16108474SJose.Borrego@Sun.COM 
16118474SJose.Borrego@Sun.COM 	switch (param->level) {
16128474SJose.Borrego@Sun.COM 	case 100:
16138474SJose.Borrego@Sun.COM 		info100 = NDR_NEW(mxa, struct mslm_SERVER_INFO_100);
16148474SJose.Borrego@Sun.COM 		if (info100 == NULL)
16158474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
16168474SJose.Borrego@Sun.COM 
16178474SJose.Borrego@Sun.COM 		bzero(info100, sizeof (struct mslm_SERVER_INFO_100));
16188474SJose.Borrego@Sun.COM 		info100->sv100_platform_id = SV_PLATFORM_ID_NT;
16198474SJose.Borrego@Sun.COM 		info100->sv100_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
16208474SJose.Borrego@Sun.COM 		if (info100->sv100_name == NULL)
16218474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
16228474SJose.Borrego@Sun.COM 
16238474SJose.Borrego@Sun.COM 		param->result.bufptr.bufptr100 = info100;
16248474SJose.Borrego@Sun.COM 		break;
16258474SJose.Borrego@Sun.COM 
16268474SJose.Borrego@Sun.COM 	case 101:
16278474SJose.Borrego@Sun.COM 		info101 = NDR_NEW(mxa, struct mslm_SERVER_INFO_101);
16288474SJose.Borrego@Sun.COM 		if (info101 == NULL)
16298474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
16308474SJose.Borrego@Sun.COM 
16318474SJose.Borrego@Sun.COM 		bzero(info101, sizeof (struct mslm_SERVER_INFO_101));
16328474SJose.Borrego@Sun.COM 		info101->sv101_platform_id = SV_PLATFORM_ID_NT;
16338474SJose.Borrego@Sun.COM 		info101->sv101_version_major = 4;
16348474SJose.Borrego@Sun.COM 		info101->sv101_version_minor = 0;
16358474SJose.Borrego@Sun.COM 		info101->sv101_type = SV_TYPE_SENT_BY_ME;
16368474SJose.Borrego@Sun.COM 		info101->sv101_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
16378474SJose.Borrego@Sun.COM 		info101->sv101_comment
16388474SJose.Borrego@Sun.COM 		    = (uint8_t *)NDR_STRDUP(mxa, sys_comment);
16398474SJose.Borrego@Sun.COM 
16408474SJose.Borrego@Sun.COM 		if (info101->sv101_name == NULL ||
16418474SJose.Borrego@Sun.COM 		    info101->sv101_comment == NULL)
16428474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
16438474SJose.Borrego@Sun.COM 
16448474SJose.Borrego@Sun.COM 		param->result.bufptr.bufptr101 = info101;
16458474SJose.Borrego@Sun.COM 		break;
16468474SJose.Borrego@Sun.COM 
16478474SJose.Borrego@Sun.COM 	case 102:
16488474SJose.Borrego@Sun.COM 		info102 = NDR_NEW(mxa, struct mslm_SERVER_INFO_102);
16498474SJose.Borrego@Sun.COM 		if (info102 == NULL)
16508474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
16518474SJose.Borrego@Sun.COM 
16528474SJose.Borrego@Sun.COM 		bzero(info102, sizeof (struct mslm_SERVER_INFO_102));
16538474SJose.Borrego@Sun.COM 		info102->sv102_platform_id = SV_PLATFORM_ID_NT;
16548474SJose.Borrego@Sun.COM 		info102->sv102_version_major = 4;
16558474SJose.Borrego@Sun.COM 		info102->sv102_version_minor = 0;
16568474SJose.Borrego@Sun.COM 		info102->sv102_type = SV_TYPE_SENT_BY_ME;
16578474SJose.Borrego@Sun.COM 		info102->sv102_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
16588474SJose.Borrego@Sun.COM 		info102->sv102_comment
16598474SJose.Borrego@Sun.COM 		    = (uint8_t *)NDR_STRDUP(mxa, sys_comment);
16608474SJose.Borrego@Sun.COM 
16618474SJose.Borrego@Sun.COM 		/*
16628474SJose.Borrego@Sun.COM 		 * The following level 102 fields are defaulted to zero
16638474SJose.Borrego@Sun.COM 		 * by virtue of the call to bzero above.
16648474SJose.Borrego@Sun.COM 		 *
16658474SJose.Borrego@Sun.COM 		 * sv102_users
16668474SJose.Borrego@Sun.COM 		 * sv102_disc
16678474SJose.Borrego@Sun.COM 		 * sv102_hidden
16688474SJose.Borrego@Sun.COM 		 * sv102_announce
16698474SJose.Borrego@Sun.COM 		 * sv102_anndelta
16708474SJose.Borrego@Sun.COM 		 * sv102_licenses
16718474SJose.Borrego@Sun.COM 		 * sv102_userpath
16728474SJose.Borrego@Sun.COM 		 */
16738474SJose.Borrego@Sun.COM 		if (info102->sv102_name == NULL ||
16748474SJose.Borrego@Sun.COM 		    info102->sv102_comment == NULL)
16758474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
16768474SJose.Borrego@Sun.COM 
16778474SJose.Borrego@Sun.COM 		param->result.bufptr.bufptr102 = info102;
16788474SJose.Borrego@Sun.COM 		break;
16798474SJose.Borrego@Sun.COM 
16809832Samw@Sun.COM 	case 502:
16819832Samw@Sun.COM 		info502 = NDR_NEW(mxa, struct mslm_SERVER_INFO_502);
16829832Samw@Sun.COM 		if (info502 == NULL)
16839832Samw@Sun.COM 			goto netservergetinfo_no_memory;
16849832Samw@Sun.COM 
16859832Samw@Sun.COM 		bzero(info502, sizeof (struct mslm_SERVER_INFO_502));
16869832Samw@Sun.COM 		param->result.bufptr.bufptr502 = info502;
16879832Samw@Sun.COM #ifdef SRVSVC_SATISFY_SMBTORTURE
16889832Samw@Sun.COM 		break;
16899832Samw@Sun.COM #else
16909832Samw@Sun.COM 		param->result.level = param->level;
16919832Samw@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
16929832Samw@Sun.COM 		return (NDR_DRC_OK);
16939832Samw@Sun.COM #endif /* SRVSVC_SATISFY_SMBTORTURE */
16949832Samw@Sun.COM 
16959832Samw@Sun.COM 	case 503:
16969832Samw@Sun.COM 		info503 = NDR_NEW(mxa, struct mslm_SERVER_INFO_503);
16979832Samw@Sun.COM 		if (info503 == NULL)
16989832Samw@Sun.COM 			goto netservergetinfo_no_memory;
16999832Samw@Sun.COM 
17009832Samw@Sun.COM 		bzero(info503, sizeof (struct mslm_SERVER_INFO_503));
17019832Samw@Sun.COM 		param->result.bufptr.bufptr503 = info503;
17029832Samw@Sun.COM #ifdef SRVSVC_SATISFY_SMBTORTURE
17039832Samw@Sun.COM 		break;
17049832Samw@Sun.COM #else
17059832Samw@Sun.COM 		param->result.level = param->level;
17069832Samw@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
17079832Samw@Sun.COM 		return (NDR_DRC_OK);
17089832Samw@Sun.COM #endif /* SRVSVC_SATISFY_SMBTORTURE */
17099832Samw@Sun.COM 
17108474SJose.Borrego@Sun.COM 	default:
17118474SJose.Borrego@Sun.COM 		bzero(&param->result,
17128474SJose.Borrego@Sun.COM 		    sizeof (struct mslm_NetServerGetInfo_result));
17138474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
17148474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
17158474SJose.Borrego@Sun.COM 	}
17168474SJose.Borrego@Sun.COM 
17178474SJose.Borrego@Sun.COM 	param->result.level = param->level;
17189832Samw@Sun.COM 	param->status = ERROR_SUCCESS;
17198474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
17208474SJose.Borrego@Sun.COM }
17218474SJose.Borrego@Sun.COM 
17228474SJose.Borrego@Sun.COM /*
17238474SJose.Borrego@Sun.COM  * NetRemoteTOD
17248474SJose.Borrego@Sun.COM  *
17258474SJose.Borrego@Sun.COM  * Returns information about the time of day on this server.
17268474SJose.Borrego@Sun.COM  *
17278474SJose.Borrego@Sun.COM  * typedef struct _TIME_OF_DAY_INFO {
17288474SJose.Borrego@Sun.COM  *	DWORD tod_elapsedt;  // seconds since 00:00:00 January 1 1970 GMT
17298474SJose.Borrego@Sun.COM  *	DWORD tod_msecs;     // arbitrary milliseconds (since reset)
17308474SJose.Borrego@Sun.COM  *	DWORD tod_hours;     // current hour [0-23]
17318474SJose.Borrego@Sun.COM  *	DWORD tod_mins;      // current minute [0-59]
17328474SJose.Borrego@Sun.COM  *	DWORD tod_secs;      // current second [0-59]
17338474SJose.Borrego@Sun.COM  *	DWORD tod_hunds;     // current hundredth (0.01) second [0-99]
17348474SJose.Borrego@Sun.COM  *	LONG tod_timezone;   // time zone of the server
17358474SJose.Borrego@Sun.COM  *	DWORD tod_tinterval; // clock tick time interval
17368474SJose.Borrego@Sun.COM  *	DWORD tod_day;       // day of the month [1-31]
17378474SJose.Borrego@Sun.COM  *	DWORD tod_month;     // month of the year [1-12]
17388474SJose.Borrego@Sun.COM  *	DWORD tod_year;      // current year
17398474SJose.Borrego@Sun.COM  *	DWORD tod_weekday;   // day of the week since Sunday [0-6]
17408474SJose.Borrego@Sun.COM  * } TIME_OF_DAY_INFO;
17418474SJose.Borrego@Sun.COM  *
17428474SJose.Borrego@Sun.COM  * The time zone of the server is calculated in minutes from Greenwich
17438474SJose.Borrego@Sun.COM  * Mean Time (GMT). For time zones west of Greenwich, the value is
17448474SJose.Borrego@Sun.COM  * positive; for time zones east of Greenwich, the value is negative.
17458474SJose.Borrego@Sun.COM  * A value of -1 indicates that the time zone is undefined.
17468474SJose.Borrego@Sun.COM  *
17478474SJose.Borrego@Sun.COM  * The clock tick value represents a resolution of one ten-thousandth
17488474SJose.Borrego@Sun.COM  * (0.0001) second.
17498474SJose.Borrego@Sun.COM  */
17508474SJose.Borrego@Sun.COM static int
17518474SJose.Borrego@Sun.COM srvsvc_s_NetRemoteTOD(void *arg, ndr_xa_t *mxa)
17528474SJose.Borrego@Sun.COM {
17538474SJose.Borrego@Sun.COM 	struct mslm_NetRemoteTOD *param = arg;
17548474SJose.Borrego@Sun.COM 	struct mslm_TIME_OF_DAY_INFO *tod;
17558474SJose.Borrego@Sun.COM 	struct timeval		time_val;
17568474SJose.Borrego@Sun.COM 	struct tm		tm;
17578474SJose.Borrego@Sun.COM 
17588474SJose.Borrego@Sun.COM 	(void) gettimeofday(&time_val, 0);
17598474SJose.Borrego@Sun.COM 	(void) gmtime_r(&time_val.tv_sec, &tm);
17608474SJose.Borrego@Sun.COM 
17618474SJose.Borrego@Sun.COM 	tod = NDR_NEW(mxa, struct mslm_TIME_OF_DAY_INFO);
17628474SJose.Borrego@Sun.COM 	if (tod == NULL) {
17638474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetRemoteTOD));
17648474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
17658474SJose.Borrego@Sun.COM 	}
17668474SJose.Borrego@Sun.COM 
17678474SJose.Borrego@Sun.COM 	tod->tod_elapsedt = time_val.tv_sec;
17688474SJose.Borrego@Sun.COM 	tod->tod_msecs = time_val.tv_usec;
17698474SJose.Borrego@Sun.COM 	tod->tod_hours = tm.tm_hour;
17708474SJose.Borrego@Sun.COM 	tod->tod_mins = tm.tm_min;
17718474SJose.Borrego@Sun.COM 	tod->tod_secs = tm.tm_sec;
17728474SJose.Borrego@Sun.COM 	tod->tod_hunds = 0;
17738474SJose.Borrego@Sun.COM 	tod->tod_tinterval = 1000;
17748474SJose.Borrego@Sun.COM 	tod->tod_day = tm.tm_mday;
17758474SJose.Borrego@Sun.COM 	tod->tod_month = tm.tm_mon+1;
17768474SJose.Borrego@Sun.COM 	tod->tod_year = tm.tm_year+1900;
17778474SJose.Borrego@Sun.COM 	tod->tod_weekday = tm.tm_wday;
17788474SJose.Borrego@Sun.COM 
17798474SJose.Borrego@Sun.COM 	(void) localtime_r(&time_val.tv_sec, &tm);
17808474SJose.Borrego@Sun.COM 
17818474SJose.Borrego@Sun.COM 	param->bufptr = tod;
17828474SJose.Borrego@Sun.COM 	param->status = ERROR_SUCCESS;
17838474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
17848474SJose.Borrego@Sun.COM }
17858474SJose.Borrego@Sun.COM 
17868474SJose.Borrego@Sun.COM /*
17878474SJose.Borrego@Sun.COM  * srvsvc_s_NetNameValidate
17888474SJose.Borrego@Sun.COM  *
17898474SJose.Borrego@Sun.COM  * Perform name validation.
17908474SJose.Borrego@Sun.COM  *
17918474SJose.Borrego@Sun.COM  * The share name is considered invalid if it contains any of the
17928474SJose.Borrego@Sun.COM  * following character (MSDN 236388).
17938474SJose.Borrego@Sun.COM  *
17948474SJose.Borrego@Sun.COM  * " / \ [ ] : | < > + ; , ? * =
17958474SJose.Borrego@Sun.COM  *
17968474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
17978474SJose.Borrego@Sun.COM  */
17988474SJose.Borrego@Sun.COM /*ARGSUSED*/
17998474SJose.Borrego@Sun.COM static int
18008474SJose.Borrego@Sun.COM srvsvc_s_NetNameValidate(void *arg, ndr_xa_t *mxa)
18018474SJose.Borrego@Sun.COM {
18028474SJose.Borrego@Sun.COM 	struct mslm_NetNameValidate *param = arg;
18038474SJose.Borrego@Sun.COM 	char *name;
18048474SJose.Borrego@Sun.COM 	int len;
18058474SJose.Borrego@Sun.COM 
18068474SJose.Borrego@Sun.COM 	if ((name = (char *)param->pathname) == NULL) {
18078474SJose.Borrego@Sun.COM 		param->status = ERROR_INVALID_PARAMETER;
18088474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
18098474SJose.Borrego@Sun.COM 	}
18108474SJose.Borrego@Sun.COM 
18118474SJose.Borrego@Sun.COM 	len = strlen(name);
18128474SJose.Borrego@Sun.COM 
18138474SJose.Borrego@Sun.COM 	if ((param->flags == 0 && len > 81) ||
18148474SJose.Borrego@Sun.COM 	    (param->flags == 0x80000000 && len > 13)) {
18158474SJose.Borrego@Sun.COM 		param->status = ERROR_INVALID_NAME;
18168474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
18178474SJose.Borrego@Sun.COM 	}
18188474SJose.Borrego@Sun.COM 
18198474SJose.Borrego@Sun.COM 	switch (param->type) {
18208474SJose.Borrego@Sun.COM 	case NAMETYPE_SHARE:
18218474SJose.Borrego@Sun.COM 		if (smb_shr_chkname(name))
18228474SJose.Borrego@Sun.COM 			param->status = ERROR_SUCCESS;
18238474SJose.Borrego@Sun.COM 		else
18248474SJose.Borrego@Sun.COM 			param->status = ERROR_INVALID_NAME;
18258474SJose.Borrego@Sun.COM 		break;
18268474SJose.Borrego@Sun.COM 
18278474SJose.Borrego@Sun.COM 	case NAMETYPE_USER:
18288474SJose.Borrego@Sun.COM 	case NAMETYPE_PASSWORD:
18298474SJose.Borrego@Sun.COM 	case NAMETYPE_GROUP:
18308474SJose.Borrego@Sun.COM 	case NAMETYPE_COMPUTER:
18318474SJose.Borrego@Sun.COM 	case NAMETYPE_EVENT:
18328474SJose.Borrego@Sun.COM 	case NAMETYPE_DOMAIN:
18338474SJose.Borrego@Sun.COM 	case NAMETYPE_SERVICE:
18348474SJose.Borrego@Sun.COM 	case NAMETYPE_NET:
18358474SJose.Borrego@Sun.COM 	case NAMETYPE_MESSAGE:
18368474SJose.Borrego@Sun.COM 	case NAMETYPE_MESSAGEDEST:
18378474SJose.Borrego@Sun.COM 	case NAMETYPE_SHAREPASSWORD:
18388474SJose.Borrego@Sun.COM 	case NAMETYPE_WORKGROUP:
18398474SJose.Borrego@Sun.COM 		param->status = ERROR_NOT_SUPPORTED;
18408474SJose.Borrego@Sun.COM 		break;
18418474SJose.Borrego@Sun.COM 
18428474SJose.Borrego@Sun.COM 	default:
18438474SJose.Borrego@Sun.COM 		param->status = ERROR_INVALID_PARAMETER;
18448474SJose.Borrego@Sun.COM 		break;
18458474SJose.Borrego@Sun.COM 	}
18468474SJose.Borrego@Sun.COM 
18478474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
18488474SJose.Borrego@Sun.COM }
18498474SJose.Borrego@Sun.COM 
18508474SJose.Borrego@Sun.COM /*
18518474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareAdd
18528474SJose.Borrego@Sun.COM  *
18539832Samw@Sun.COM  * Add a new share. Only power users groups can manage shares.
18548474SJose.Borrego@Sun.COM  *
18558474SJose.Borrego@Sun.COM  * This interface is used by the rmtshare command from the NT resource
18568474SJose.Borrego@Sun.COM  * kit. Rmtshare allows a client to add or remove shares on a server
18578474SJose.Borrego@Sun.COM  * from the client's command line.
18588474SJose.Borrego@Sun.COM  *
18598474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
18608474SJose.Borrego@Sun.COM  */
18618474SJose.Borrego@Sun.COM static int
18628474SJose.Borrego@Sun.COM srvsvc_s_NetShareAdd(void *arg, ndr_xa_t *mxa)
18638474SJose.Borrego@Sun.COM {
18648474SJose.Borrego@Sun.COM 	static DWORD parm_err = 0;
18658474SJose.Borrego@Sun.COM 	DWORD parm_stat;
18668474SJose.Borrego@Sun.COM 	struct mslm_NetShareAdd *param = arg;
18679343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
18689832Samw@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
18698474SJose.Borrego@Sun.COM 	char realpath[MAXPATHLEN];
18708474SJose.Borrego@Sun.COM 	int32_t native_os;
18719832Samw@Sun.COM 	uint8_t *sdbuf = NULL;
18729832Samw@Sun.COM 	uint32_t status;
18739832Samw@Sun.COM 	smb_share_t si;
18748474SJose.Borrego@Sun.COM 
18758474SJose.Borrego@Sun.COM 	native_os = ndr_native_os(mxa);
18768474SJose.Borrego@Sun.COM 
18778474SJose.Borrego@Sun.COM 	if (!ndr_is_poweruser(mxa)) {
18788474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
18798474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
18808474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
18818474SJose.Borrego@Sun.COM 	}
18828474SJose.Borrego@Sun.COM 
18838474SJose.Borrego@Sun.COM 	switch (param->level) {
18848474SJose.Borrego@Sun.COM 	case 2:
18859832Samw@Sun.COM 		info2 = (struct mslm_NetShareInfo_2 *)param->info.un.info2;
18868474SJose.Borrego@Sun.COM 		break;
18878474SJose.Borrego@Sun.COM 
18888474SJose.Borrego@Sun.COM 	case 502:
18899832Samw@Sun.COM 		info502 = (struct mslm_NetShareInfo_502 *)
18909832Samw@Sun.COM 		    param->info.un.info502;
18919832Samw@Sun.COM 		sdbuf = info502->shi502_security_descriptor;
18929832Samw@Sun.COM 		info2 = (struct mslm_NetShareInfo_2 *)info502;
18938474SJose.Borrego@Sun.COM 		break;
18948474SJose.Borrego@Sun.COM 
18958474SJose.Borrego@Sun.COM 	default:
18968474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
18978474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
18988474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
18998474SJose.Borrego@Sun.COM 	}
19008474SJose.Borrego@Sun.COM 
19018474SJose.Borrego@Sun.COM 	if (info2->shi2_netname == NULL || info2->shi2_path == NULL) {
19028474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
19038474SJose.Borrego@Sun.COM 		param->status = NERR_NetNameNotFound;
19048474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
19058474SJose.Borrego@Sun.COM 	}
19068474SJose.Borrego@Sun.COM 
19078474SJose.Borrego@Sun.COM 	if (smb_shr_is_restricted((char *)info2->shi2_netname)) {
19088474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
19098474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
19108474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
19118474SJose.Borrego@Sun.COM 	}
19128474SJose.Borrego@Sun.COM 
19139343SAfshin.Ardakani@Sun.COM 	if (info2->shi2_comment == NULL)
19149343SAfshin.Ardakani@Sun.COM 		info2->shi2_comment = (uint8_t *)"";
19158474SJose.Borrego@Sun.COM 
19168474SJose.Borrego@Sun.COM 	/*
19178474SJose.Borrego@Sun.COM 	 * Derive the real path which will be stored in the
19188474SJose.Borrego@Sun.COM 	 * directory field of the smb_share_t structure
19198474SJose.Borrego@Sun.COM 	 * from the path field in this RPC request.
19208474SJose.Borrego@Sun.COM 	 */
19218474SJose.Borrego@Sun.COM 	parm_stat = smb_shr_get_realpath((const char *)info2->shi2_path,
19228474SJose.Borrego@Sun.COM 	    realpath, MAXPATHLEN);
19238474SJose.Borrego@Sun.COM 
19248474SJose.Borrego@Sun.COM 	if (parm_stat != NERR_Success) {
19258474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
19268474SJose.Borrego@Sun.COM 		param->status = parm_stat;
19278474SJose.Borrego@Sun.COM 		param->parm_err
19288474SJose.Borrego@Sun.COM 		    = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
19298474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
19308474SJose.Borrego@Sun.COM 	}
19318474SJose.Borrego@Sun.COM 
19328474SJose.Borrego@Sun.COM 	param->status = srvsvc_sa_add((char *)info2->shi2_netname, realpath,
19339343SAfshin.Ardakani@Sun.COM 	    (char *)info2->shi2_comment);
19348474SJose.Borrego@Sun.COM 	if (param->status == NERR_Success) {
19359832Samw@Sun.COM 		status = smb_shr_get((char *)info2->shi2_netname, &si);
19369832Samw@Sun.COM 
19379832Samw@Sun.COM 		if ((sdbuf != NULL) && (status == NERR_Success))
19389832Samw@Sun.COM 			(void) srvsvc_sd_set(&si, sdbuf);
19398474SJose.Borrego@Sun.COM 	}
19408474SJose.Borrego@Sun.COM 	param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
19418474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
19428474SJose.Borrego@Sun.COM }
19438474SJose.Borrego@Sun.COM 
19448474SJose.Borrego@Sun.COM /*
1945*10122SJordan.Brown@Sun.COM  * srvsvc_estimate_limit
19468474SJose.Borrego@Sun.COM  *
19478474SJose.Borrego@Sun.COM  * Estimate the number of objects that will fit in prefmaxlen.
1948*10122SJordan.Brown@Sun.COM  * nlimit is adjusted here.
19498474SJose.Borrego@Sun.COM  */
1950*10122SJordan.Brown@Sun.COM static void
1951*10122SJordan.Brown@Sun.COM srvsvc_estimate_limit(smb_svcenum_t *se, uint32_t obj_size)
19528474SJose.Borrego@Sun.COM {
19538474SJose.Borrego@Sun.COM 	DWORD max_cnt;
19548474SJose.Borrego@Sun.COM 
1955*10122SJordan.Brown@Sun.COM 	if (obj_size == 0) {
1956*10122SJordan.Brown@Sun.COM 		se->se_nlimit = 0;
1957*10122SJordan.Brown@Sun.COM 		return;
1958*10122SJordan.Brown@Sun.COM 	}
1959*10122SJordan.Brown@Sun.COM 
1960*10122SJordan.Brown@Sun.COM 	if ((max_cnt = (se->se_prefmaxlen / obj_size)) == 0) {
1961*10122SJordan.Brown@Sun.COM 		se->se_nlimit = 0;
1962*10122SJordan.Brown@Sun.COM 		return;
1963*10122SJordan.Brown@Sun.COM 	}
1964*10122SJordan.Brown@Sun.COM 
1965*10122SJordan.Brown@Sun.COM 	if (se->se_ntotal > max_cnt)
1966*10122SJordan.Brown@Sun.COM 		se->se_nlimit = max_cnt;
1967*10122SJordan.Brown@Sun.COM 	else
1968*10122SJordan.Brown@Sun.COM 		se->se_nlimit = se->se_ntotal;
19698474SJose.Borrego@Sun.COM }
19708474SJose.Borrego@Sun.COM 
19718474SJose.Borrego@Sun.COM /*
19728474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareEnum
19738474SJose.Borrego@Sun.COM  *
19748474SJose.Borrego@Sun.COM  * Enumerate all shares (see also NetShareEnumSticky).
19758474SJose.Borrego@Sun.COM  *
19768474SJose.Borrego@Sun.COM  * Request for various levels of information about our shares.
19778474SJose.Borrego@Sun.COM  * Level 0: share names.
19788474SJose.Borrego@Sun.COM  * Level 1: share name, share type and comment field.
19798474SJose.Borrego@Sun.COM  * Level 2: everything that we know about the shares.
19808474SJose.Borrego@Sun.COM  * Level 501: level 1 + flags (flags must be zero).
19818474SJose.Borrego@Sun.COM  * Level 502: level 2 + security descriptor.
19828474SJose.Borrego@Sun.COM  */
19838474SJose.Borrego@Sun.COM static int
19848474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnum(void *arg, ndr_xa_t *mxa)
19858474SJose.Borrego@Sun.COM {
19868474SJose.Borrego@Sun.COM 	struct mslm_NetShareEnum *param = arg;
1987*10122SJordan.Brown@Sun.COM 	srvsvc_infonres_t *infonres;
1988*10122SJordan.Brown@Sun.COM 	smb_svcenum_t se;
19898474SJose.Borrego@Sun.COM 	DWORD status;
19908474SJose.Borrego@Sun.COM 
1991*10122SJordan.Brown@Sun.COM 	infonres = NDR_NEW(mxa, srvsvc_infonres_t);
19928474SJose.Borrego@Sun.COM 	if (infonres == NULL) {
19938474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareEnum));
19948474SJose.Borrego@Sun.COM 		param->status = ERROR_NOT_ENOUGH_MEMORY;
19958474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
19968474SJose.Borrego@Sun.COM 	}
19978474SJose.Borrego@Sun.COM 
19988474SJose.Borrego@Sun.COM 	infonres->entriesread = 0;
19998474SJose.Borrego@Sun.COM 	infonres->entries = NULL;
20008474SJose.Borrego@Sun.COM 	param->result.level = param->level;
20018474SJose.Borrego@Sun.COM 	param->result.bufptr.p = infonres;
20028474SJose.Borrego@Sun.COM 
2003*10122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
2004*10122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_SHARE;
20058474SJose.Borrego@Sun.COM 	se.se_level = param->level;
2006*10122SJordan.Brown@Sun.COM 	se.se_ntotal = smb_shr_count();
2007*10122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
20088474SJose.Borrego@Sun.COM 
20098474SJose.Borrego@Sun.COM 	if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN ||
20108474SJose.Borrego@Sun.COM 	    param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN)
20118474SJose.Borrego@Sun.COM 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
20128474SJose.Borrego@Sun.COM 	else
20138474SJose.Borrego@Sun.COM 		se.se_prefmaxlen = param->prefmaxlen;
20148474SJose.Borrego@Sun.COM 
20158474SJose.Borrego@Sun.COM 	if (param->resume_handle) {
2016*10122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
2017*10122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
2018*10122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
20198474SJose.Borrego@Sun.COM 	}
20208474SJose.Borrego@Sun.COM 
20218474SJose.Borrego@Sun.COM 	switch (param->level) {
20228474SJose.Borrego@Sun.COM 	case 0:
20238474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 0);
20248474SJose.Borrego@Sun.COM 		break;
20258474SJose.Borrego@Sun.COM 
20268474SJose.Borrego@Sun.COM 	case 1:
20278474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 0);
20288474SJose.Borrego@Sun.COM 		break;
20298474SJose.Borrego@Sun.COM 
20308474SJose.Borrego@Sun.COM 	case 2:
20318474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 0);
20328474SJose.Borrego@Sun.COM 		break;
20338474SJose.Borrego@Sun.COM 
20348474SJose.Borrego@Sun.COM 	case 501:
20358474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel501(mxa, infonres, &se, 0);
20368474SJose.Borrego@Sun.COM 		break;
20378474SJose.Borrego@Sun.COM 
20388474SJose.Borrego@Sun.COM 	case 502:
20398474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 0);
20408474SJose.Borrego@Sun.COM 		break;
20418474SJose.Borrego@Sun.COM 
20428474SJose.Borrego@Sun.COM 	default:
20439832Samw@Sun.COM 		status = ERROR_INVALID_LEVEL;
20448474SJose.Borrego@Sun.COM 		break;
20458474SJose.Borrego@Sun.COM 	}
20468474SJose.Borrego@Sun.COM 
20478474SJose.Borrego@Sun.COM 	if (status != 0) {
20488474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareEnum));
20498474SJose.Borrego@Sun.COM 		param->status = status;
20508474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
20518474SJose.Borrego@Sun.COM 	}
20528474SJose.Borrego@Sun.COM 
2053*10122SJordan.Brown@Sun.COM 	if (se.se_nlimit == 0) {
20548474SJose.Borrego@Sun.COM 		param->status = ERROR_SUCCESS;
20558474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
20568474SJose.Borrego@Sun.COM 	}
20578474SJose.Borrego@Sun.COM 
20588474SJose.Borrego@Sun.COM 	if (param->resume_handle &&
20598474SJose.Borrego@Sun.COM 	    param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) {
2060*10122SJordan.Brown@Sun.COM 		if (se.se_resume < se.se_ntotal) {
2061*10122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
20628474SJose.Borrego@Sun.COM 			status = ERROR_MORE_DATA;
20638474SJose.Borrego@Sun.COM 		}
20648474SJose.Borrego@Sun.COM 	}
20658474SJose.Borrego@Sun.COM 
2066*10122SJordan.Brown@Sun.COM 	param->totalentries = se.se_ntotal;
20678474SJose.Borrego@Sun.COM 	param->status = status;
20688474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
20698474SJose.Borrego@Sun.COM }
20708474SJose.Borrego@Sun.COM 
20718474SJose.Borrego@Sun.COM /*
20728474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareEnumSticky
20738474SJose.Borrego@Sun.COM  *
20748474SJose.Borrego@Sun.COM  * Enumerate sticky shares: all shares except those marked STYPE_SPECIAL.
20758474SJose.Borrego@Sun.COM  * Except for excluding STYPE_SPECIAL shares, NetShareEnumSticky is the
20768474SJose.Borrego@Sun.COM  * same as NetShareEnum.
20778474SJose.Borrego@Sun.COM  *
20788474SJose.Borrego@Sun.COM  * Request for various levels of information about our shares.
20798474SJose.Borrego@Sun.COM  * Level 0: share names.
20808474SJose.Borrego@Sun.COM  * Level 1: share name, share type and comment field.
20818474SJose.Borrego@Sun.COM  * Level 2: everything that we know about the shares.
20828474SJose.Borrego@Sun.COM  * Level 501: not valid for this request.
20838474SJose.Borrego@Sun.COM  * Level 502: level 2 + security descriptor.
20848474SJose.Borrego@Sun.COM  *
20858474SJose.Borrego@Sun.COM  * We set n_skip to resume_handle, which is used to find the appropriate
20868474SJose.Borrego@Sun.COM  * place to resume.  The resume_handle is similar to the readdir cookie.
20878474SJose.Borrego@Sun.COM  */
20888474SJose.Borrego@Sun.COM static int
20898474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnumSticky(void *arg, ndr_xa_t *mxa)
20908474SJose.Borrego@Sun.COM {
20918474SJose.Borrego@Sun.COM 	struct mslm_NetShareEnum *param = arg;
2092*10122SJordan.Brown@Sun.COM 	srvsvc_infonres_t *infonres;
2093*10122SJordan.Brown@Sun.COM 	smb_svcenum_t se;
20948474SJose.Borrego@Sun.COM 	DWORD status;
20958474SJose.Borrego@Sun.COM 
2096*10122SJordan.Brown@Sun.COM 	infonres = NDR_NEW(mxa, srvsvc_infonres_t);
20978474SJose.Borrego@Sun.COM 	if (infonres == NULL) {
20988474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareEnum));
20998474SJose.Borrego@Sun.COM 		param->status = ERROR_NOT_ENOUGH_MEMORY;
21008474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
21018474SJose.Borrego@Sun.COM 	}
21028474SJose.Borrego@Sun.COM 
21038474SJose.Borrego@Sun.COM 	infonres->entriesread = 0;
21048474SJose.Borrego@Sun.COM 	infonres->entries = NULL;
21058474SJose.Borrego@Sun.COM 	param->result.level = param->level;
21068474SJose.Borrego@Sun.COM 	param->result.bufptr.p = infonres;
21078474SJose.Borrego@Sun.COM 
2108*10122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
2109*10122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_SHARE;
21108474SJose.Borrego@Sun.COM 	se.se_level = param->level;
2111*10122SJordan.Brown@Sun.COM 	se.se_ntotal = smb_shr_count();
2112*10122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
21138474SJose.Borrego@Sun.COM 
21148474SJose.Borrego@Sun.COM 	if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN ||
21158474SJose.Borrego@Sun.COM 	    param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN)
21168474SJose.Borrego@Sun.COM 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
21178474SJose.Borrego@Sun.COM 	else
21188474SJose.Borrego@Sun.COM 		se.se_prefmaxlen = param->prefmaxlen;
21198474SJose.Borrego@Sun.COM 
21208474SJose.Borrego@Sun.COM 	if (param->resume_handle) {
2121*10122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
2122*10122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
2123*10122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
21248474SJose.Borrego@Sun.COM 	}
21258474SJose.Borrego@Sun.COM 
21268474SJose.Borrego@Sun.COM 	switch (param->level) {
21278474SJose.Borrego@Sun.COM 	case 0:
21288474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 1);
21298474SJose.Borrego@Sun.COM 		break;
21308474SJose.Borrego@Sun.COM 
21318474SJose.Borrego@Sun.COM 	case 1:
21328474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 1);
21338474SJose.Borrego@Sun.COM 		break;
21348474SJose.Borrego@Sun.COM 
21358474SJose.Borrego@Sun.COM 	case 2:
21368474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 1);
21378474SJose.Borrego@Sun.COM 		break;
21388474SJose.Borrego@Sun.COM 
21398474SJose.Borrego@Sun.COM 	case 502:
21408474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 1);
21418474SJose.Borrego@Sun.COM 		break;
21428474SJose.Borrego@Sun.COM 
21439832Samw@Sun.COM 	case 501:
21448474SJose.Borrego@Sun.COM 	default:
21458474SJose.Borrego@Sun.COM 		status = ERROR_INVALID_LEVEL;
21468474SJose.Borrego@Sun.COM 		break;
21478474SJose.Borrego@Sun.COM 	}
21488474SJose.Borrego@Sun.COM 
21498474SJose.Borrego@Sun.COM 	if (status != ERROR_SUCCESS) {
21508474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareEnum));
21518474SJose.Borrego@Sun.COM 		param->status = status;
21528474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
21538474SJose.Borrego@Sun.COM 	}
21548474SJose.Borrego@Sun.COM 
2155*10122SJordan.Brown@Sun.COM 	if (se.se_nlimit == 0) {
21568474SJose.Borrego@Sun.COM 		param->status = ERROR_SUCCESS;
21578474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
21588474SJose.Borrego@Sun.COM 	}
21598474SJose.Borrego@Sun.COM 
21608474SJose.Borrego@Sun.COM 	if (param->resume_handle &&
21618474SJose.Borrego@Sun.COM 	    param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) {
2162*10122SJordan.Brown@Sun.COM 		if (se.se_resume < se.se_ntotal) {
2163*10122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
21648474SJose.Borrego@Sun.COM 			status = ERROR_MORE_DATA;
21658474SJose.Borrego@Sun.COM 		}
21668474SJose.Borrego@Sun.COM 	}
21678474SJose.Borrego@Sun.COM 
2168*10122SJordan.Brown@Sun.COM 	param->totalentries = se.se_ntotal;
21698474SJose.Borrego@Sun.COM 	param->status = status;
21708474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
21718474SJose.Borrego@Sun.COM }
21728474SJose.Borrego@Sun.COM 
21738474SJose.Borrego@Sun.COM /*
21748474SJose.Borrego@Sun.COM  * NetShareEnum Level 0
21758474SJose.Borrego@Sun.COM  */
21768474SJose.Borrego@Sun.COM static DWORD
2177*10122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel0(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
2178*10122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
21798474SJose.Borrego@Sun.COM {
21809343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_0 *info0;
21818474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
21828474SJose.Borrego@Sun.COM 	smb_share_t *si;
21838474SJose.Borrego@Sun.COM 	DWORD status;
21848474SJose.Borrego@Sun.COM 
2185*10122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
2186*10122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_0) + MAXNAMELEN);
2187*10122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
21888474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
21898474SJose.Borrego@Sun.COM 
2190*10122SJordan.Brown@Sun.COM 	info0 = NDR_NEWN(mxa, struct mslm_NetShareInfo_0, se->se_nlimit);
21918474SJose.Borrego@Sun.COM 	if (info0 == NULL)
21928474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
21938474SJose.Borrego@Sun.COM 
21948474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
21958474SJose.Borrego@Sun.COM 
2196*10122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
21978474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
2198*10122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
2199*10122SJordan.Brown@Sun.COM 			--se->se_nskip;
22008474SJose.Borrego@Sun.COM 			continue;
22018474SJose.Borrego@Sun.COM 		}
22028474SJose.Borrego@Sun.COM 
2203*10122SJordan.Brown@Sun.COM 		++se->se_resume;
22048474SJose.Borrego@Sun.COM 
22058474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
22068474SJose.Borrego@Sun.COM 			continue;
22078474SJose.Borrego@Sun.COM 
22088474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
22098474SJose.Borrego@Sun.COM 			continue;
22108474SJose.Borrego@Sun.COM 
2211*10122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
2212*10122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
22138474SJose.Borrego@Sun.COM 			break;
22148474SJose.Borrego@Sun.COM 		}
22158474SJose.Borrego@Sun.COM 
22168474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info0);
22178474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
22188474SJose.Borrego@Sun.COM 			break;
22198474SJose.Borrego@Sun.COM 
2220*10122SJordan.Brown@Sun.COM 		++se->se_nitems;
22218474SJose.Borrego@Sun.COM 	}
22228474SJose.Borrego@Sun.COM 
2223*10122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
22248474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info0))
2225*10122SJordan.Brown@Sun.COM 			++se->se_nitems;
22268474SJose.Borrego@Sun.COM 	}
22278474SJose.Borrego@Sun.COM 
2228*10122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
22298474SJose.Borrego@Sun.COM 	infonres->entries = info0;
22308474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
22318474SJose.Borrego@Sun.COM }
22328474SJose.Borrego@Sun.COM 
22338474SJose.Borrego@Sun.COM /*
22348474SJose.Borrego@Sun.COM  * NetShareEnum Level 1
22358474SJose.Borrego@Sun.COM  */
22368474SJose.Borrego@Sun.COM static DWORD
2237*10122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel1(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
2238*10122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
22398474SJose.Borrego@Sun.COM {
22409343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1 *info1;
22418474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
22428474SJose.Borrego@Sun.COM 	smb_share_t *si;
22438474SJose.Borrego@Sun.COM 	DWORD status;
22448474SJose.Borrego@Sun.COM 
2245*10122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
2246*10122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_1) + MAXNAMELEN);
2247*10122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
22488474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
22498474SJose.Borrego@Sun.COM 
2250*10122SJordan.Brown@Sun.COM 	info1 = NDR_NEWN(mxa, struct mslm_NetShareInfo_1, se->se_nlimit);
22518474SJose.Borrego@Sun.COM 	if (info1 == NULL)
22528474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
22538474SJose.Borrego@Sun.COM 
22548474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
22558474SJose.Borrego@Sun.COM 
2256*10122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
22578474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != 0) {
2258*10122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
2259*10122SJordan.Brown@Sun.COM 			--se->se_nskip;
22608474SJose.Borrego@Sun.COM 			continue;
22618474SJose.Borrego@Sun.COM 		}
22628474SJose.Borrego@Sun.COM 
2263*10122SJordan.Brown@Sun.COM 		++se->se_resume;
22648474SJose.Borrego@Sun.COM 
22658474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
22668474SJose.Borrego@Sun.COM 			continue;
22678474SJose.Borrego@Sun.COM 
22688474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
22698474SJose.Borrego@Sun.COM 			continue;
22708474SJose.Borrego@Sun.COM 
2271*10122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
2272*10122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
22738474SJose.Borrego@Sun.COM 			break;
22748474SJose.Borrego@Sun.COM 		}
22758474SJose.Borrego@Sun.COM 
22768474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info1);
22778474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
22788474SJose.Borrego@Sun.COM 			break;
22798474SJose.Borrego@Sun.COM 
2280*10122SJordan.Brown@Sun.COM 		++se->se_nitems;
22818474SJose.Borrego@Sun.COM 	}
22828474SJose.Borrego@Sun.COM 
2283*10122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
22848474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info1))
2285*10122SJordan.Brown@Sun.COM 			++se->se_nitems;
22868474SJose.Borrego@Sun.COM 	}
22878474SJose.Borrego@Sun.COM 
2288*10122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
22898474SJose.Borrego@Sun.COM 	infonres->entries = info1;
22908474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
22918474SJose.Borrego@Sun.COM }
22928474SJose.Borrego@Sun.COM 
22938474SJose.Borrego@Sun.COM /*
22948474SJose.Borrego@Sun.COM  * NetShareEnum Level 2
22958474SJose.Borrego@Sun.COM  */
22968474SJose.Borrego@Sun.COM static DWORD
2297*10122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel2(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
2298*10122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
22998474SJose.Borrego@Sun.COM {
23009343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
23018474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
23028474SJose.Borrego@Sun.COM 	smb_share_t *si;
23038474SJose.Borrego@Sun.COM 	DWORD status;
23048474SJose.Borrego@Sun.COM 
2305*10122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
2306*10122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_2) + MAXNAMELEN);
2307*10122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
23088474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
23098474SJose.Borrego@Sun.COM 
2310*10122SJordan.Brown@Sun.COM 	info2 = NDR_NEWN(mxa, struct mslm_NetShareInfo_2, se->se_nlimit);
23118474SJose.Borrego@Sun.COM 	if (info2 == NULL)
23128474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
23138474SJose.Borrego@Sun.COM 
23148474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
23158474SJose.Borrego@Sun.COM 
2316*10122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
23178474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != 0) {
2318*10122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
2319*10122SJordan.Brown@Sun.COM 			--se->se_nskip;
23208474SJose.Borrego@Sun.COM 			continue;
23218474SJose.Borrego@Sun.COM 		}
23228474SJose.Borrego@Sun.COM 
2323*10122SJordan.Brown@Sun.COM 		++se->se_resume;
23248474SJose.Borrego@Sun.COM 
23258474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
23268474SJose.Borrego@Sun.COM 			continue;
23278474SJose.Borrego@Sun.COM 
23288474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
23298474SJose.Borrego@Sun.COM 			continue;
23308474SJose.Borrego@Sun.COM 
2331*10122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
2332*10122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
23338474SJose.Borrego@Sun.COM 			break;
23348474SJose.Borrego@Sun.COM 		}
23358474SJose.Borrego@Sun.COM 
23368474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info2);
23378474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
23388474SJose.Borrego@Sun.COM 			break;
23398474SJose.Borrego@Sun.COM 
2340*10122SJordan.Brown@Sun.COM 		++se->se_nitems;
23418474SJose.Borrego@Sun.COM 	}
23428474SJose.Borrego@Sun.COM 
2343*10122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
23448474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info2))
2345*10122SJordan.Brown@Sun.COM 			++se->se_nitems;
23468474SJose.Borrego@Sun.COM 	}
23478474SJose.Borrego@Sun.COM 
2348*10122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
23498474SJose.Borrego@Sun.COM 	infonres->entries = info2;
23508474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
23518474SJose.Borrego@Sun.COM }
23528474SJose.Borrego@Sun.COM 
23538474SJose.Borrego@Sun.COM /*
23548474SJose.Borrego@Sun.COM  * NetShareEnum Level 501
23558474SJose.Borrego@Sun.COM  */
23568474SJose.Borrego@Sun.COM static DWORD
2357*10122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel501(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
2358*10122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
23598474SJose.Borrego@Sun.COM {
23609343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_501 *info501;
23618474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
23628474SJose.Borrego@Sun.COM 	smb_share_t *si;
23638474SJose.Borrego@Sun.COM 	DWORD status;
23648474SJose.Borrego@Sun.COM 
2365*10122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
2366*10122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_501) + MAXNAMELEN);
2367*10122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
23688474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
23698474SJose.Borrego@Sun.COM 
23709343SAfshin.Ardakani@Sun.COM 	info501 = NDR_NEWN(mxa, struct mslm_NetShareInfo_501,
2371*10122SJordan.Brown@Sun.COM 	    se->se_nlimit);
23728474SJose.Borrego@Sun.COM 	if (info501 == NULL)
23738474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
23748474SJose.Borrego@Sun.COM 
23758474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
23768474SJose.Borrego@Sun.COM 
2377*10122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
23788474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != 0) {
2379*10122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
2380*10122SJordan.Brown@Sun.COM 			--se->se_nskip;
23818474SJose.Borrego@Sun.COM 			continue;
23828474SJose.Borrego@Sun.COM 		}
23838474SJose.Borrego@Sun.COM 
2384*10122SJordan.Brown@Sun.COM 		++se->se_resume;
23858474SJose.Borrego@Sun.COM 
23868474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
23878474SJose.Borrego@Sun.COM 			continue;
23888474SJose.Borrego@Sun.COM 
23898474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
23908474SJose.Borrego@Sun.COM 			continue;
23918474SJose.Borrego@Sun.COM 
2392*10122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
2393*10122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
23948474SJose.Borrego@Sun.COM 			break;
23958474SJose.Borrego@Sun.COM 		}
23968474SJose.Borrego@Sun.COM 
23978474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info501);
23988474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
23998474SJose.Borrego@Sun.COM 			break;
24008474SJose.Borrego@Sun.COM 
2401*10122SJordan.Brown@Sun.COM 		++se->se_nitems;
24028474SJose.Borrego@Sun.COM 	}
24038474SJose.Borrego@Sun.COM 
2404*10122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
24058474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info501))
2406*10122SJordan.Brown@Sun.COM 			++se->se_nitems;
24078474SJose.Borrego@Sun.COM 	}
24088474SJose.Borrego@Sun.COM 
2409*10122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
24108474SJose.Borrego@Sun.COM 	infonres->entries = info501;
24118474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
24128474SJose.Borrego@Sun.COM }
24138474SJose.Borrego@Sun.COM 
24148474SJose.Borrego@Sun.COM /*
24158474SJose.Borrego@Sun.COM  * NetShareEnum Level 502
24168474SJose.Borrego@Sun.COM  */
24178474SJose.Borrego@Sun.COM static DWORD
2418*10122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel502(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
2419*10122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
24208474SJose.Borrego@Sun.COM {
24219343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
24228474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
24238474SJose.Borrego@Sun.COM 	smb_share_t *si;
24248474SJose.Borrego@Sun.COM 	DWORD status;
24258474SJose.Borrego@Sun.COM 
2426*10122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
2427*10122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_502) + MAXNAMELEN);
2428*10122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
24298474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
24308474SJose.Borrego@Sun.COM 
24319343SAfshin.Ardakani@Sun.COM 	info502 = NDR_NEWN(mxa, struct mslm_NetShareInfo_502,
2432*10122SJordan.Brown@Sun.COM 	    se->se_nlimit);
24338474SJose.Borrego@Sun.COM 	if (info502 == NULL)
24348474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
24358474SJose.Borrego@Sun.COM 
24368474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
24378474SJose.Borrego@Sun.COM 
2438*10122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
24398474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
2440*10122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
2441*10122SJordan.Brown@Sun.COM 			--se->se_nskip;
24428474SJose.Borrego@Sun.COM 			continue;
24438474SJose.Borrego@Sun.COM 		}
24448474SJose.Borrego@Sun.COM 
2445*10122SJordan.Brown@Sun.COM 		++se->se_resume;
24468474SJose.Borrego@Sun.COM 
24478474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
24488474SJose.Borrego@Sun.COM 			continue;
24498474SJose.Borrego@Sun.COM 
24508474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
24518474SJose.Borrego@Sun.COM 			continue;
24528474SJose.Borrego@Sun.COM 
2453*10122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
2454*10122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
24558474SJose.Borrego@Sun.COM 			break;
24568474SJose.Borrego@Sun.COM 		}
24578474SJose.Borrego@Sun.COM 
24588474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info502);
24598474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
24608474SJose.Borrego@Sun.COM 			break;
24618474SJose.Borrego@Sun.COM 
2462*10122SJordan.Brown@Sun.COM 		++se->se_nitems;
24638474SJose.Borrego@Sun.COM 	}
24648474SJose.Borrego@Sun.COM 
2465*10122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
24668474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info502))
2467*10122SJordan.Brown@Sun.COM 			++se->se_nitems;
24688474SJose.Borrego@Sun.COM 	}
24698474SJose.Borrego@Sun.COM 
2470*10122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
24718474SJose.Borrego@Sun.COM 	infonres->entries = info502;
24728474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
24738474SJose.Borrego@Sun.COM }
24748474SJose.Borrego@Sun.COM 
24758474SJose.Borrego@Sun.COM /*
24768474SJose.Borrego@Sun.COM  * mlsvc_NetShareEnumCommon
24778474SJose.Borrego@Sun.COM  *
24788474SJose.Borrego@Sun.COM  * Build the levels 0, 1, 2, 501 and 502 share information. This function
24798474SJose.Borrego@Sun.COM  * is called by the various NetShareEnum levels for each share. If
24808474SJose.Borrego@Sun.COM  * we cannot build the share data for some reason, we return an error
24818474SJose.Borrego@Sun.COM  * but the actual value of the error is not important to the caller.
24828474SJose.Borrego@Sun.COM  * The caller just needs to know not to include this info in the RPC
24838474SJose.Borrego@Sun.COM  * response.
24848474SJose.Borrego@Sun.COM  *
24858474SJose.Borrego@Sun.COM  * Returns:
24868474SJose.Borrego@Sun.COM  *	ERROR_SUCCESS
24878474SJose.Borrego@Sun.COM  *	ERROR_NOT_ENOUGH_MEMORY
24888474SJose.Borrego@Sun.COM  *	ERROR_INVALID_LEVEL
24898474SJose.Borrego@Sun.COM  */
24908474SJose.Borrego@Sun.COM static DWORD
2491*10122SJordan.Brown@Sun.COM mlsvc_NetShareEnumCommon(ndr_xa_t *mxa, smb_svcenum_t *se,
24928474SJose.Borrego@Sun.COM     smb_share_t *si, void *infop)
24938474SJose.Borrego@Sun.COM {
24949343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_0 *info0;
24959343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1 *info1;
24969343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
24979343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_501 *info501;
24989343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
24999832Samw@Sun.COM 	srvsvc_sd_t sd;
25009832Samw@Sun.COM 	uint8_t *netname;
25019832Samw@Sun.COM 	uint8_t *comment;
25029832Samw@Sun.COM 	uint8_t *passwd;
25039832Samw@Sun.COM 	uint8_t *path;
2504*10122SJordan.Brown@Sun.COM 	int i = se->se_nitems;
25058474SJose.Borrego@Sun.COM 
25069832Samw@Sun.COM 	netname = (uint8_t *)NDR_STRDUP(mxa, si->shr_name);
25079832Samw@Sun.COM 	comment = (uint8_t *)NDR_STRDUP(mxa, si->shr_cmnt);
25089832Samw@Sun.COM 	passwd = (uint8_t *)NDR_STRDUP(mxa, empty_string);
25099832Samw@Sun.COM 	path = (uint8_t *)srvsvc_share_mkpath(mxa, si->shr_path);
25109832Samw@Sun.COM 
25119832Samw@Sun.COM 	if (!netname || !comment || !passwd || !path)
25129832Samw@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
25139832Samw@Sun.COM 
25148474SJose.Borrego@Sun.COM 	switch (se->se_level) {
25158474SJose.Borrego@Sun.COM 	case 0:
25169343SAfshin.Ardakani@Sun.COM 		info0 = (struct mslm_NetShareInfo_0 *)infop;
25179832Samw@Sun.COM 		info0[i].shi0_netname = netname;
25188474SJose.Borrego@Sun.COM 		break;
25198474SJose.Borrego@Sun.COM 
25208474SJose.Borrego@Sun.COM 	case 1:
25219343SAfshin.Ardakani@Sun.COM 		info1 = (struct mslm_NetShareInfo_1 *)infop;
25229832Samw@Sun.COM 		info1[i].shi1_netname = netname;
25239832Samw@Sun.COM 		info1[i].shi1_comment = comment;
25248474SJose.Borrego@Sun.COM 		info1[i].shi1_type = si->shr_type;
25258474SJose.Borrego@Sun.COM 		break;
25268474SJose.Borrego@Sun.COM 
25278474SJose.Borrego@Sun.COM 	case 2:
25289343SAfshin.Ardakani@Sun.COM 		info2 = (struct mslm_NetShareInfo_2 *)infop;
25299832Samw@Sun.COM 		info2[i].shi2_netname = netname;
25309832Samw@Sun.COM 		info2[i].shi2_comment = comment;
25319832Samw@Sun.COM 		info2[i].shi2_path = path;
25328474SJose.Borrego@Sun.COM 		info2[i].shi2_type = si->shr_type;
25338474SJose.Borrego@Sun.COM 		info2[i].shi2_permissions = 0;
25348474SJose.Borrego@Sun.COM 		info2[i].shi2_max_uses = SHI_USES_UNLIMITED;
25358474SJose.Borrego@Sun.COM 		info2[i].shi2_current_uses = 0;
25369832Samw@Sun.COM 		info2[i].shi2_passwd = passwd;
25378474SJose.Borrego@Sun.COM 		break;
25388474SJose.Borrego@Sun.COM 
25398474SJose.Borrego@Sun.COM 	case 501:
25409343SAfshin.Ardakani@Sun.COM 		info501 = (struct mslm_NetShareInfo_501 *)infop;
25419832Samw@Sun.COM 		info501[i].shi501_netname = netname;
25429832Samw@Sun.COM 		info501[i].shi501_comment = comment;
25438474SJose.Borrego@Sun.COM 		info501[i].shi501_type = si->shr_type;
25449343SAfshin.Ardakani@Sun.COM 		info501[i].shi501_reserved = 0;
25458474SJose.Borrego@Sun.COM 		break;
25468474SJose.Borrego@Sun.COM 
25478474SJose.Borrego@Sun.COM 	case 502:
25489343SAfshin.Ardakani@Sun.COM 		info502 = (struct mslm_NetShareInfo_502 *)infop;
25499832Samw@Sun.COM 		info502[i].shi502_netname = netname;
25509832Samw@Sun.COM 		info502[i].shi502_comment = comment;
25519832Samw@Sun.COM 		info502[i].shi502_path = path;
25528474SJose.Borrego@Sun.COM 		info502[i].shi502_type = si->shr_type;
25538474SJose.Borrego@Sun.COM 		info502[i].shi502_permissions = 0;
25548474SJose.Borrego@Sun.COM 		info502[i].shi502_max_uses = SHI_USES_UNLIMITED;
25558474SJose.Borrego@Sun.COM 		info502[i].shi502_current_uses = 0;
25569832Samw@Sun.COM 		info502[i].shi502_passwd = passwd;
25579832Samw@Sun.COM 
25589832Samw@Sun.COM 		if (srvsvc_share_getsd(mxa, si, &sd) == ERROR_SUCCESS) {
25599832Samw@Sun.COM 			info502[i].shi502_reserved = sd.sd_size;
25609832Samw@Sun.COM 			info502[i].shi502_security_descriptor = sd.sd_buf;
25619832Samw@Sun.COM 		} else {
25629832Samw@Sun.COM 			info502[i].shi502_reserved = 0;
25639832Samw@Sun.COM 			info502[i].shi502_security_descriptor = NULL;
25649832Samw@Sun.COM 		}
25659832Samw@Sun.COM 
25668474SJose.Borrego@Sun.COM 		break;
25678474SJose.Borrego@Sun.COM 
25688474SJose.Borrego@Sun.COM 	default:
25698474SJose.Borrego@Sun.COM 		return (ERROR_INVALID_LEVEL);
25708474SJose.Borrego@Sun.COM 	}
25718474SJose.Borrego@Sun.COM 
25728474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
25738474SJose.Borrego@Sun.COM }
25748474SJose.Borrego@Sun.COM 
25758474SJose.Borrego@Sun.COM /*
25768474SJose.Borrego@Sun.COM  * srvsvc_add_autohome
25778474SJose.Borrego@Sun.COM  *
25788474SJose.Borrego@Sun.COM  * Add the autohome share for the user. The share must not be a permanent
25798474SJose.Borrego@Sun.COM  * share to avoid duplicates.
25808474SJose.Borrego@Sun.COM  */
25818474SJose.Borrego@Sun.COM static boolean_t
2582*10122SJordan.Brown@Sun.COM srvsvc_add_autohome(ndr_xa_t *mxa, smb_svcenum_t *se, void *infop)
25838474SJose.Borrego@Sun.COM {
2584*10122SJordan.Brown@Sun.COM 	smb_netuserinfo_t *user = &mxa->pipe->np_user;
2585*10122SJordan.Brown@Sun.COM 	char *username = user->ui_account;
25868474SJose.Borrego@Sun.COM 	smb_share_t si;
25878474SJose.Borrego@Sun.COM 	DWORD status;
25888474SJose.Borrego@Sun.COM 
25898474SJose.Borrego@Sun.COM 	if (smb_shr_get(username, &si) != NERR_Success)
25908474SJose.Borrego@Sun.COM 		return (B_FALSE);
25918474SJose.Borrego@Sun.COM 
25928474SJose.Borrego@Sun.COM 	if ((si.shr_flags & SMB_SHRF_AUTOHOME) == 0)
25938474SJose.Borrego@Sun.COM 		return (B_FALSE);
25948474SJose.Borrego@Sun.COM 
25958474SJose.Borrego@Sun.COM 	status = mlsvc_NetShareEnumCommon(mxa, se, &si, infop);
25968474SJose.Borrego@Sun.COM 	return (status == ERROR_SUCCESS);
25978474SJose.Borrego@Sun.COM }
25988474SJose.Borrego@Sun.COM 
25998474SJose.Borrego@Sun.COM /*
26008474SJose.Borrego@Sun.COM  * srvsvc_share_mkpath
26018474SJose.Borrego@Sun.COM  *
26028474SJose.Borrego@Sun.COM  * Create the share path required by the share enum calls. The path
26038474SJose.Borrego@Sun.COM  * is created in a heap buffer ready for use by the caller.
26048474SJose.Borrego@Sun.COM  *
26058474SJose.Borrego@Sun.COM  * Some Windows over-the-wire backup applications do not work unless a
26068474SJose.Borrego@Sun.COM  * drive letter is present in the share path.  We don't care about the
26078474SJose.Borrego@Sun.COM  * drive letter since the path is fully qualified with the volume name.
26088474SJose.Borrego@Sun.COM  *
26098474SJose.Borrego@Sun.COM  * Windows clients seem to be mostly okay with forward slashes in
26108474SJose.Borrego@Sun.COM  * share paths but they cannot handle one immediately after the drive
26118474SJose.Borrego@Sun.COM  * letter, i.e. B:/.  For consistency we convert all the slashes in
26128474SJose.Borrego@Sun.COM  * the path.
26138474SJose.Borrego@Sun.COM  *
26148474SJose.Borrego@Sun.COM  * Returns a pointer to a heap buffer containing the share path, which
26158474SJose.Borrego@Sun.COM  * could be a null pointer if the heap allocation fails.
26168474SJose.Borrego@Sun.COM  */
26178474SJose.Borrego@Sun.COM static char *
26188474SJose.Borrego@Sun.COM srvsvc_share_mkpath(ndr_xa_t *mxa, char *path)
26198474SJose.Borrego@Sun.COM {
26208474SJose.Borrego@Sun.COM 	char tmpbuf[MAXPATHLEN];
26218474SJose.Borrego@Sun.COM 	char *p;
26228474SJose.Borrego@Sun.COM 
26238474SJose.Borrego@Sun.COM 	if (strlen(path) == 0)
26248474SJose.Borrego@Sun.COM 		return (NDR_STRDUP(mxa, path));
26258474SJose.Borrego@Sun.COM 
26268474SJose.Borrego@Sun.COM 	/*
26278474SJose.Borrego@Sun.COM 	 * Strip the volume name from the path (/vol1/home -> /home).
26288474SJose.Borrego@Sun.COM 	 */
26298474SJose.Borrego@Sun.COM 	p = path;
26308474SJose.Borrego@Sun.COM 	p += strspn(p, "/");
26318474SJose.Borrego@Sun.COM 	p += strcspn(p, "/");
26328474SJose.Borrego@Sun.COM 	p += strspn(p, "/");
26338474SJose.Borrego@Sun.COM 	(void) snprintf(tmpbuf, MAXPATHLEN, "%c:/%s", 'B', p);
26348474SJose.Borrego@Sun.COM 	(void) strsubst(tmpbuf, '/', '\\');
26358474SJose.Borrego@Sun.COM 
26368474SJose.Borrego@Sun.COM 	return (NDR_STRDUP(mxa, tmpbuf));
26378474SJose.Borrego@Sun.COM }
26388474SJose.Borrego@Sun.COM 
26399832Samw@Sun.COM static int
26409832Samw@Sun.COM srvsvc_s_NetShareCheck(void *arg, ndr_xa_t *mxa)
26419832Samw@Sun.COM {
26429832Samw@Sun.COM 	struct mslm_NetShareCheck *param = arg;
26439832Samw@Sun.COM 	smb_shriter_t iterator;
26449832Samw@Sun.COM 	smb_share_t *si;
26459832Samw@Sun.COM 	char *path;
26469832Samw@Sun.COM 
26479832Samw@Sun.COM 	if (param->path == NULL) {
26489832Samw@Sun.COM 		param->stype = STYPE_DISKTREE;
26499832Samw@Sun.COM 		param->status = NERR_NetNameNotFound;
26509832Samw@Sun.COM 		return (NDR_DRC_OK);
26519832Samw@Sun.COM 	}
26529832Samw@Sun.COM 
26539832Samw@Sun.COM 	(void) strsubst((char *)param->path, '/', '\\');
26549832Samw@Sun.COM 
26559832Samw@Sun.COM 	smb_shr_iterinit(&iterator);
26569832Samw@Sun.COM 
26579832Samw@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
26589832Samw@Sun.COM 		path = srvsvc_share_mkpath(mxa, si->shr_path);
26599832Samw@Sun.COM 
26609832Samw@Sun.COM 		if (utf8_strcasecmp(path, (char *)param->path) == 0) {
26619832Samw@Sun.COM 			param->stype = (si->shr_type & STYPE_MASK);
26629832Samw@Sun.COM 			param->status = NERR_Success;
26639832Samw@Sun.COM 			return (NDR_DRC_OK);
26649832Samw@Sun.COM 		}
26659832Samw@Sun.COM 	}
26669832Samw@Sun.COM 
26679832Samw@Sun.COM 	param->stype = STYPE_DISKTREE;
26689832Samw@Sun.COM 	param->status = NERR_NetNameNotFound;
26699832Samw@Sun.COM 	return (NDR_DRC_OK);
26709832Samw@Sun.COM }
26719832Samw@Sun.COM 
26728474SJose.Borrego@Sun.COM /*
26738474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareDel
26748474SJose.Borrego@Sun.COM  *
2675*10122SJordan.Brown@Sun.COM  * Delete a share.  Only members of the Administrators, Server Operators
2676*10122SJordan.Brown@Sun.COM  * or Power Users local groups are allowed to delete shares.
26778474SJose.Borrego@Sun.COM  *
26788474SJose.Borrego@Sun.COM  * This interface is used by the rmtshare command from the NT resource
26798474SJose.Borrego@Sun.COM  * kit. Rmtshare allows a client to add or remove shares on a server
26808474SJose.Borrego@Sun.COM  * from the client's command line.
26818474SJose.Borrego@Sun.COM  *
26828474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
26838474SJose.Borrego@Sun.COM  */
26848474SJose.Borrego@Sun.COM static int
26858474SJose.Borrego@Sun.COM srvsvc_s_NetShareDel(void *arg, ndr_xa_t *mxa)
26868474SJose.Borrego@Sun.COM {
26878474SJose.Borrego@Sun.COM 	struct mslm_NetShareDel *param = arg;
26888474SJose.Borrego@Sun.COM 
26898474SJose.Borrego@Sun.COM 	if (!ndr_is_poweruser(mxa) ||
26908474SJose.Borrego@Sun.COM 	    smb_shr_is_restricted((char *)param->netname)) {
26918474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
26928474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
26938474SJose.Borrego@Sun.COM 	}
26948474SJose.Borrego@Sun.COM 
26958474SJose.Borrego@Sun.COM 	param->status = srvsvc_sa_delete((char *)param->netname);
26968474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
26978474SJose.Borrego@Sun.COM }
26988474SJose.Borrego@Sun.COM 
26998474SJose.Borrego@Sun.COM /*
27008474SJose.Borrego@Sun.COM  * srvsvc_s_NetGetFileSecurity
27018474SJose.Borrego@Sun.COM  *
27028474SJose.Borrego@Sun.COM  * Get security descriptor of the requested file/folder
27038474SJose.Borrego@Sun.COM  *
27048474SJose.Borrego@Sun.COM  * Right now, just returns ERROR_ACCESS_DENIED, because we cannot
27058474SJose.Borrego@Sun.COM  * get the requested SD here in RPC code.
27068474SJose.Borrego@Sun.COM  */
27078474SJose.Borrego@Sun.COM /*ARGSUSED*/
27088474SJose.Borrego@Sun.COM static int
27098474SJose.Borrego@Sun.COM srvsvc_s_NetGetFileSecurity(void *arg, ndr_xa_t *mxa)
27108474SJose.Borrego@Sun.COM {
27118474SJose.Borrego@Sun.COM 	struct mslm_NetGetFileSecurity *param = arg;
27128474SJose.Borrego@Sun.COM 
27138474SJose.Borrego@Sun.COM 	param->length = 0;
27148474SJose.Borrego@Sun.COM 	param->status = ERROR_ACCESS_DENIED;
27158474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
27168474SJose.Borrego@Sun.COM }
27178474SJose.Borrego@Sun.COM 
27188474SJose.Borrego@Sun.COM /*
27198474SJose.Borrego@Sun.COM  * srvsvc_s_NetSetFileSecurity
27208474SJose.Borrego@Sun.COM  *
27218474SJose.Borrego@Sun.COM  * Set the given security descriptor for the requested file/folder
27228474SJose.Borrego@Sun.COM  *
27238474SJose.Borrego@Sun.COM  * Right now, just returns ERROR_ACCESS_DENIED, because we cannot
27248474SJose.Borrego@Sun.COM  * set the requested SD here in RPC code.
27258474SJose.Borrego@Sun.COM  */
27268474SJose.Borrego@Sun.COM /*ARGSUSED*/
27278474SJose.Borrego@Sun.COM static int
27288474SJose.Borrego@Sun.COM srvsvc_s_NetSetFileSecurity(void *arg, ndr_xa_t *mxa)
27298474SJose.Borrego@Sun.COM {
27308474SJose.Borrego@Sun.COM 	struct mslm_NetSetFileSecurity *param = arg;
27318474SJose.Borrego@Sun.COM 
27328474SJose.Borrego@Sun.COM 	param->status = ERROR_ACCESS_DENIED;
27338474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
27348474SJose.Borrego@Sun.COM }
27358474SJose.Borrego@Sun.COM 
27368474SJose.Borrego@Sun.COM /*
27378474SJose.Borrego@Sun.COM  * If the default "smb" share group exists then return the group
27388474SJose.Borrego@Sun.COM  * handle, otherwise create the group and return the handle.
27398474SJose.Borrego@Sun.COM  *
27408474SJose.Borrego@Sun.COM  * All shares created via the srvsvc will be added to the "smb"
27418474SJose.Borrego@Sun.COM  * group.
27428474SJose.Borrego@Sun.COM  */
27438474SJose.Borrego@Sun.COM static sa_group_t
27448474SJose.Borrego@Sun.COM srvsvc_sa_get_smbgrp(sa_handle_t handle)
27458474SJose.Borrego@Sun.COM {
27468474SJose.Borrego@Sun.COM 	sa_group_t group = NULL;
27478474SJose.Borrego@Sun.COM 	int err;
27488474SJose.Borrego@Sun.COM 
27498474SJose.Borrego@Sun.COM 	group = sa_get_group(handle, SMB_DEFAULT_SHARE_GROUP);
27508474SJose.Borrego@Sun.COM 	if (group != NULL)
27518474SJose.Borrego@Sun.COM 		return (group);
27528474SJose.Borrego@Sun.COM 
27538474SJose.Borrego@Sun.COM 	group = sa_create_group(handle, SMB_DEFAULT_SHARE_GROUP, &err);
27548474SJose.Borrego@Sun.COM 	if (group == NULL)
27558474SJose.Borrego@Sun.COM 		return (NULL);
27568474SJose.Borrego@Sun.COM 
27578474SJose.Borrego@Sun.COM 	if (sa_create_optionset(group, SMB_DEFAULT_SHARE_GROUP) == NULL) {
27588474SJose.Borrego@Sun.COM 		(void) sa_remove_group(group);
27598474SJose.Borrego@Sun.COM 		group = NULL;
27608474SJose.Borrego@Sun.COM 	}
27618474SJose.Borrego@Sun.COM 
27628474SJose.Borrego@Sun.COM 	return (group);
27638474SJose.Borrego@Sun.COM }
27648474SJose.Borrego@Sun.COM 
27658474SJose.Borrego@Sun.COM /*
27668474SJose.Borrego@Sun.COM  * Stores the given share in sharemgr
27678474SJose.Borrego@Sun.COM  */
27688474SJose.Borrego@Sun.COM static uint32_t
27698474SJose.Borrego@Sun.COM srvsvc_sa_add(char *sharename, char *path, char *cmnt)
27708474SJose.Borrego@Sun.COM {
27718474SJose.Borrego@Sun.COM 	sa_handle_t handle;
27728474SJose.Borrego@Sun.COM 	sa_share_t share;
27738474SJose.Borrego@Sun.COM 	sa_group_t group;
27748474SJose.Borrego@Sun.COM 	sa_resource_t resource;
27758474SJose.Borrego@Sun.COM 	boolean_t new_share = B_FALSE;
27768474SJose.Borrego@Sun.COM 	uint32_t status = NERR_Success;
27778474SJose.Borrego@Sun.COM 	int err;
27788474SJose.Borrego@Sun.COM 
27798474SJose.Borrego@Sun.COM 	if ((handle = smb_shr_sa_enter()) == NULL)
27808474SJose.Borrego@Sun.COM 		return (NERR_InternalError);
27818474SJose.Borrego@Sun.COM 
27828474SJose.Borrego@Sun.COM 	share = sa_find_share(handle, path);
27838474SJose.Borrego@Sun.COM 	if (share == NULL) {
27848474SJose.Borrego@Sun.COM 		group = srvsvc_sa_get_smbgrp(handle);
27858474SJose.Borrego@Sun.COM 		if (group == NULL) {
27868474SJose.Borrego@Sun.COM 			smb_shr_sa_exit();
27878474SJose.Borrego@Sun.COM 			return (NERR_InternalError);
27888474SJose.Borrego@Sun.COM 		}
27898474SJose.Borrego@Sun.COM 
27908474SJose.Borrego@Sun.COM 		share = sa_add_share(group, path, SA_SHARE_PERMANENT, &err);
27918474SJose.Borrego@Sun.COM 		if (share == NULL) {
27928474SJose.Borrego@Sun.COM 			smb_shr_sa_exit();
27938474SJose.Borrego@Sun.COM 			return (NERR_InternalError);
27948474SJose.Borrego@Sun.COM 		}
27958474SJose.Borrego@Sun.COM 		new_share = B_TRUE;
27968474SJose.Borrego@Sun.COM 	}
27978474SJose.Borrego@Sun.COM 
27988474SJose.Borrego@Sun.COM 	resource = sa_get_share_resource(share, sharename);
27998474SJose.Borrego@Sun.COM 	if (resource == NULL) {
28008474SJose.Borrego@Sun.COM 		resource = sa_add_resource(share, sharename,
28018474SJose.Borrego@Sun.COM 		    SA_SHARE_PERMANENT, &err);
28028474SJose.Borrego@Sun.COM 		if (resource == NULL) {
28038474SJose.Borrego@Sun.COM 			if (new_share)
28048474SJose.Borrego@Sun.COM 				(void) sa_remove_share(share);
28058474SJose.Borrego@Sun.COM 			smb_shr_sa_exit();
28068474SJose.Borrego@Sun.COM 			return (NERR_InternalError);
28078474SJose.Borrego@Sun.COM 		}
28088474SJose.Borrego@Sun.COM 	}
28098474SJose.Borrego@Sun.COM 
28108474SJose.Borrego@Sun.COM 	(void) sa_set_resource_description(resource, cmnt);
28118474SJose.Borrego@Sun.COM 
28128474SJose.Borrego@Sun.COM 	smb_shr_sa_exit();
28138474SJose.Borrego@Sun.COM 	return (status);
28148474SJose.Borrego@Sun.COM }
28158474SJose.Borrego@Sun.COM 
28168474SJose.Borrego@Sun.COM /*
28178474SJose.Borrego@Sun.COM  * Removes the share from sharemgr
28188474SJose.Borrego@Sun.COM  */
28198474SJose.Borrego@Sun.COM static uint32_t
28208474SJose.Borrego@Sun.COM srvsvc_sa_delete(char *sharename)
28218474SJose.Borrego@Sun.COM {
28228474SJose.Borrego@Sun.COM 	sa_handle_t handle;
28238474SJose.Borrego@Sun.COM 	sa_resource_t resource;
28248474SJose.Borrego@Sun.COM 	uint32_t status;
28258474SJose.Borrego@Sun.COM 
28268474SJose.Borrego@Sun.COM 	if ((handle = smb_shr_sa_enter()) == NULL)
28278474SJose.Borrego@Sun.COM 		return (NERR_InternalError);
28288474SJose.Borrego@Sun.COM 
28298474SJose.Borrego@Sun.COM 	status = NERR_InternalError;
28308474SJose.Borrego@Sun.COM 	if ((resource = sa_find_resource(handle, sharename)) != NULL) {
28318474SJose.Borrego@Sun.COM 		if (sa_remove_resource(resource) == SA_OK)
28328474SJose.Borrego@Sun.COM 			status = NERR_Success;
28338474SJose.Borrego@Sun.COM 	}
28348474SJose.Borrego@Sun.COM 
28358474SJose.Borrego@Sun.COM 	smb_shr_sa_exit();
28368474SJose.Borrego@Sun.COM 	return (status);
28378474SJose.Borrego@Sun.COM }
28388474SJose.Borrego@Sun.COM 
28399832Samw@Sun.COM /*
28409832Samw@Sun.COM  * Update the share information.
28419832Samw@Sun.COM  */
28429832Samw@Sun.COM static uint32_t
28439832Samw@Sun.COM srvsvc_sa_modify(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
28449832Samw@Sun.COM {
28459832Samw@Sun.COM 	sa_handle_t handle;
28469832Samw@Sun.COM 	sa_share_t share;
28479832Samw@Sun.COM 	sa_resource_t resource;
28489832Samw@Sun.COM 	boolean_t renamed = B_FALSE;
28499832Samw@Sun.COM 	uint32_t nerr = NERR_Success;
28509832Samw@Sun.COM 
28519832Samw@Sun.COM 	if ((handle = smb_shr_sa_enter()) == NULL)
28529832Samw@Sun.COM 		return (NERR_InternalError);
28539832Samw@Sun.COM 
28549832Samw@Sun.COM 	if ((share = sa_find_share(handle, si->shr_path)) == NULL) {
28559832Samw@Sun.COM 		smb_shr_sa_exit();
28569832Samw@Sun.COM 		return (NERR_InternalError);
28579832Samw@Sun.COM 	}
28589832Samw@Sun.COM 
28599832Samw@Sun.COM 	if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) {
28609832Samw@Sun.COM 		smb_shr_sa_exit();
28619832Samw@Sun.COM 		return (NERR_InternalError);
28629832Samw@Sun.COM 	}
28639832Samw@Sun.COM 
28649832Samw@Sun.COM 	if (info->nss_netname != NULL && info->nss_netname[0] != '\0' &&
28659832Samw@Sun.COM 	    utf8_strcasecmp(info->nss_netname, si->shr_name) != 0) {
28669832Samw@Sun.COM 		(void) sa_set_resource_attr(resource, SHOPT_NAME,
28679832Samw@Sun.COM 		    info->nss_netname);
28689832Samw@Sun.COM 		renamed = B_TRUE;
28699832Samw@Sun.COM 	}
28709832Samw@Sun.COM 
28719832Samw@Sun.COM 	if ((info->nss_comment != NULL) &&
28729832Samw@Sun.COM 	    (strcmp(info->nss_comment, si->shr_cmnt) != 0)) {
28739832Samw@Sun.COM 		(void) sa_set_resource_description(resource, info->nss_comment);
28749832Samw@Sun.COM 		(void) strlcpy(si->shr_cmnt, info->nss_comment,
28759832Samw@Sun.COM 		    SMB_SHARE_CMNT_MAX);
28769832Samw@Sun.COM 	}
28779832Samw@Sun.COM 
28789832Samw@Sun.COM 	smb_shr_sa_exit();
28799832Samw@Sun.COM 
28809832Samw@Sun.COM 	if (renamed) {
28819832Samw@Sun.COM 		nerr = smb_shr_rename(si->shr_name, info->nss_netname);
28829832Samw@Sun.COM 		if (nerr != NERR_Success)
28839832Samw@Sun.COM 			return (nerr);
28849832Samw@Sun.COM 
28859832Samw@Sun.COM 		(void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN);
28869832Samw@Sun.COM 	}
28879832Samw@Sun.COM 
28889832Samw@Sun.COM 	return (nerr);
28899832Samw@Sun.COM }
28909832Samw@Sun.COM 
28919832Samw@Sun.COM /*
28929832Samw@Sun.COM  * Update the share flags.
28939832Samw@Sun.COM  */
28949832Samw@Sun.COM static uint32_t
28959832Samw@Sun.COM srvsvc_sa_setattr(smb_share_t *si)
28969832Samw@Sun.COM {
28979832Samw@Sun.COM 	sa_handle_t handle;
28989832Samw@Sun.COM 	sa_share_t share;
28999832Samw@Sun.COM 	sa_resource_t resource;
29009832Samw@Sun.COM 	char *value;
29019832Samw@Sun.COM 
29029832Samw@Sun.COM 	if ((handle = smb_shr_sa_enter()) == NULL)
29039832Samw@Sun.COM 		return (NERR_InternalError);
29049832Samw@Sun.COM 
29059832Samw@Sun.COM 	if ((share = sa_find_share(handle, si->shr_path)) == NULL) {
29069832Samw@Sun.COM 		smb_shr_sa_exit();
29079832Samw@Sun.COM 		return (NERR_InternalError);
29089832Samw@Sun.COM 	}
29099832Samw@Sun.COM 
29109832Samw@Sun.COM 	if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) {
29119832Samw@Sun.COM 		smb_shr_sa_exit();
29129832Samw@Sun.COM 		return (NERR_InternalError);
29139832Samw@Sun.COM 	}
29149832Samw@Sun.COM 
29159832Samw@Sun.COM 	if ((value = smb_shr_sa_csc_name(si)) == NULL) {
29169832Samw@Sun.COM 		smb_shr_sa_exit();
29179832Samw@Sun.COM 		return (NERR_InternalError);
29189832Samw@Sun.COM 	}
29199832Samw@Sun.COM 
29209832Samw@Sun.COM 	(void) sa_set_resource_attr(resource, SHOPT_CSC, value);
29219832Samw@Sun.COM 	smb_shr_sa_exit();
29229832Samw@Sun.COM 	return (NERR_Success);
29239832Samw@Sun.COM }
29249832Samw@Sun.COM 
29258474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[] = {
29268474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetConnectEnum,	SRVSVC_OPNUM_NetConnectEnum },
29278474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetFileEnum,		SRVSVC_OPNUM_NetFileEnum },
29288474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetFileClose,	SRVSVC_OPNUM_NetFileClose },
29298474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareGetInfo,	SRVSVC_OPNUM_NetShareGetInfo },
29308474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareSetInfo,	SRVSVC_OPNUM_NetShareSetInfo },
29318474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetSessionEnum,	SRVSVC_OPNUM_NetSessionEnum },
29328474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetSessionDel,	SRVSVC_OPNUM_NetSessionDel },
29338474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetServerGetInfo,	SRVSVC_OPNUM_NetServerGetInfo },
29348474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetRemoteTOD,	SRVSVC_OPNUM_NetRemoteTOD },
29358474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetNameValidate,	SRVSVC_OPNUM_NetNameValidate },
29368474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareAdd,		SRVSVC_OPNUM_NetShareAdd },
29378474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareDel,		SRVSVC_OPNUM_NetShareDel },
29388474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareEnum,	SRVSVC_OPNUM_NetShareEnum },
29398474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareEnumSticky,	SRVSVC_OPNUM_NetShareEnumSticky },
29409832Samw@Sun.COM 	{ srvsvc_s_NetShareCheck,	SRVSVC_OPNUM_NetShareCheck },
29418474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetGetFileSecurity,	SRVSVC_OPNUM_NetGetFileSecurity },
29428474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetSetFileSecurity,	SRVSVC_OPNUM_NetSetFileSecurity },
29438474SJose.Borrego@Sun.COM 	{0}
29448474SJose.Borrego@Sun.COM };
2945