xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c (revision 12890:16985853e3aa)
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  */
2112508Samw@Sun.COM 
228474SJose.Borrego@Sun.COM /*
2312065SKeyur.Desai@Sun.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
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>
3510966SJordan.Brown@Sun.COM #include <sys/tzfile.h>
368474SJose.Borrego@Sun.COM #include <unistd.h>
378474SJose.Borrego@Sun.COM #include <netdb.h>
388474SJose.Borrego@Sun.COM #include <strings.h>
398474SJose.Borrego@Sun.COM #include <time.h>
408474SJose.Borrego@Sun.COM #include <thread.h>
418474SJose.Borrego@Sun.COM #include <ctype.h>
428474SJose.Borrego@Sun.COM #include <stdlib.h>
438474SJose.Borrego@Sun.COM #include <string.h>
448474SJose.Borrego@Sun.COM #include <sys/types.h>
458474SJose.Borrego@Sun.COM #include <sys/socket.h>
468474SJose.Borrego@Sun.COM #include <netinet/in.h>
478474SJose.Borrego@Sun.COM #include <arpa/inet.h>
488474SJose.Borrego@Sun.COM #include <libshare.h>
4910504SKeyur.Desai@Sun.COM #include <libnvpair.h>
5012065SKeyur.Desai@Sun.COM #include <sys/idmap.h>
5112065SKeyur.Desai@Sun.COM #include <pwd.h>
5212065SKeyur.Desai@Sun.COM #include <nss_dbdefs.h>
538474SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h>
548474SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h>
558474SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h>
5610966SJordan.Brown@Sun.COM #include <smbsrv/smb.h>
578474SJose.Borrego@Sun.COM #include <smbsrv/netrauth.h>
588474SJose.Borrego@Sun.COM #include <smbsrv/ndl/srvsvc.ndl>
599832Samw@Sun.COM #include "mlsvc.h"
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 
6810122SJordan.Brown@Sun.COM #define	SMB_SRVSVC_MAXBUFLEN		(8 * 1024 * 1024)
6910122SJordan.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 
9710122SJordan.Brown@Sun.COM typedef struct mslm_infonres srvsvc_infonres_t;
9810122SJordan.Brown@Sun.COM typedef struct mslm_NetConnectEnum srvsvc_NetConnectEnum_t;
9910122SJordan.Brown@Sun.COM 
10010122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_level0(ndr_xa_t *, smb_svcenum_t *,
10110122SJordan.Brown@Sun.COM     srvsvc_NetConnectEnum_t *);
10210122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_level1(ndr_xa_t *, smb_svcenum_t *,
10310122SJordan.Brown@Sun.COM     srvsvc_NetConnectEnum_t *);
10410122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_common(ndr_xa_t *,
10510122SJordan.Brown@Sun.COM     srvsvc_NetConnectInfo_t *, smb_netsvc_t *, smb_svcenum_t *);
10610122SJordan.Brown@Sun.COM 
10710122SJordan.Brown@Sun.COM static DWORD srvsvc_NetFileEnum2(ndr_xa_t *, struct mslm_NetFileEnum *,
10810122SJordan.Brown@Sun.COM     smb_svcenum_t *se);
10910122SJordan.Brown@Sun.COM static DWORD srvsvc_NetFileEnum3(ndr_xa_t *, struct mslm_NetFileEnum *,
11010122SJordan.Brown@Sun.COM     smb_svcenum_t *se);
11110122SJordan.Brown@Sun.COM 
11210122SJordan.Brown@Sun.COM static uint32_t srvsvc_NetSessionEnumCommon(ndr_xa_t *, srvsvc_infonres_t *,
11310122SJordan.Brown@Sun.COM     smb_netsvc_t *, smb_svcenum_t *);
11410122SJordan.Brown@Sun.COM 
11510122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel0(ndr_xa_t *, srvsvc_infonres_t *,
11610122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
11710122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel1(ndr_xa_t *, srvsvc_infonres_t *,
11810122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
11910122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel2(ndr_xa_t *, srvsvc_infonres_t *,
12010122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
12110122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel501(ndr_xa_t *, srvsvc_infonres_t *,
12210122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
12310122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel502(ndr_xa_t *, srvsvc_infonres_t *,
12410122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
12510122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumCommon(ndr_xa_t *, smb_svcenum_t *,
12610122SJordan.Brown@Sun.COM     smb_share_t *, void *);
12710122SJordan.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 *);
13210122SJordan.Brown@Sun.COM static void srvsvc_estimate_limit(smb_svcenum_t *, uint32_t);
13310122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_sessions(void);
13410122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_connections(uint32_t, const char *);
13510122SJordan.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);
14210504SKeyur.Desai@Sun.COM static uint32_t srvsvc_get_share_flags(smb_share_t *);
1439832Samw@Sun.COM 
1448474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_add(char *, char *, char *);
1458474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_delete(char *);
1469832Samw@Sun.COM static uint32_t srvsvc_sa_modify(smb_share_t *, srvsvc_netshare_setinfo_t *);
14710504SKeyur.Desai@Sun.COM static uint32_t srvsvc_sa_setprop(smb_share_t *, nvlist_t *);
1488474SJose.Borrego@Sun.COM 
1498474SJose.Borrego@Sun.COM static char empty_string[1];
1508474SJose.Borrego@Sun.COM 
1518474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[];
1528474SJose.Borrego@Sun.COM 
1538474SJose.Borrego@Sun.COM static ndr_service_t srvsvc_service = {
1548474SJose.Borrego@Sun.COM 	"SRVSVC",			/* name */
1558474SJose.Borrego@Sun.COM 	"Server services",		/* desc */
1568474SJose.Borrego@Sun.COM 	"\\srvsvc",			/* endpoint */
1578474SJose.Borrego@Sun.COM 	PIPE_NTSVCS,			/* sec_addr_port */
1588474SJose.Borrego@Sun.COM 	"4b324fc8-1670-01d3-1278-5a47bf6ee188", 3,	/* abstract */
1598474SJose.Borrego@Sun.COM 	NDR_TRANSFER_SYNTAX_UUID,		2,	/* transfer */
1608474SJose.Borrego@Sun.COM 	0,				/* no bind_instance_size */
1618474SJose.Borrego@Sun.COM 	0,				/* no bind_req() */
1628474SJose.Borrego@Sun.COM 	0,				/* no unbind_and_close() */
1638474SJose.Borrego@Sun.COM 	0,				/* use generic_call_stub() */
1648474SJose.Borrego@Sun.COM 	&TYPEINFO(srvsvc_interface),	/* interface ti */
1658474SJose.Borrego@Sun.COM 	srvsvc_stub_table		/* stub_table */
1668474SJose.Borrego@Sun.COM };
1678474SJose.Borrego@Sun.COM 
1688474SJose.Borrego@Sun.COM /*
1698474SJose.Borrego@Sun.COM  * srvsvc_initialize
1708474SJose.Borrego@Sun.COM  *
1718474SJose.Borrego@Sun.COM  * This function registers the SRVSVC RPC interface with the RPC runtime
1728474SJose.Borrego@Sun.COM  * library. It must be called in order to use either the client side
1738474SJose.Borrego@Sun.COM  * or the server side functions.
1748474SJose.Borrego@Sun.COM  */
1758474SJose.Borrego@Sun.COM void
srvsvc_initialize(void)1768474SJose.Borrego@Sun.COM srvsvc_initialize(void)
1778474SJose.Borrego@Sun.COM {
1788474SJose.Borrego@Sun.COM 	(void) ndr_svc_register(&srvsvc_service);
1798474SJose.Borrego@Sun.COM }
1808474SJose.Borrego@Sun.COM 
1818474SJose.Borrego@Sun.COM /*
18211963SAfshin.Ardakani@Sun.COM  * Turn "dfsroot" property on/off for the specified
18311963SAfshin.Ardakani@Sun.COM  * share and save it.
18411963SAfshin.Ardakani@Sun.COM  *
18511963SAfshin.Ardakani@Sun.COM  * If the requested value is the same as what is already
18611963SAfshin.Ardakani@Sun.COM  * set then no change is required and the function returns.
18711963SAfshin.Ardakani@Sun.COM  */
18811963SAfshin.Ardakani@Sun.COM uint32_t
srvsvc_shr_setdfsroot(smb_share_t * si,boolean_t on)18911963SAfshin.Ardakani@Sun.COM srvsvc_shr_setdfsroot(smb_share_t *si, boolean_t on)
19011963SAfshin.Ardakani@Sun.COM {
19111963SAfshin.Ardakani@Sun.COM 	char *dfs = NULL;
19211963SAfshin.Ardakani@Sun.COM 	nvlist_t *nvl;
19311963SAfshin.Ardakani@Sun.COM 	uint32_t nerr;
19411963SAfshin.Ardakani@Sun.COM 
19511963SAfshin.Ardakani@Sun.COM 	if (on && ((si->shr_flags & SMB_SHRF_DFSROOT) == 0)) {
19611963SAfshin.Ardakani@Sun.COM 		si->shr_flags |= SMB_SHRF_DFSROOT;
19711963SAfshin.Ardakani@Sun.COM 		dfs = "true";
19811963SAfshin.Ardakani@Sun.COM 	} else if (!on && (si->shr_flags & SMB_SHRF_DFSROOT)) {
19911963SAfshin.Ardakani@Sun.COM 		si->shr_flags &= ~SMB_SHRF_DFSROOT;
20011963SAfshin.Ardakani@Sun.COM 		dfs = "false";
20111963SAfshin.Ardakani@Sun.COM 	}
20211963SAfshin.Ardakani@Sun.COM 
20311963SAfshin.Ardakani@Sun.COM 	if (dfs == NULL)
20411963SAfshin.Ardakani@Sun.COM 		return (ERROR_SUCCESS);
20511963SAfshin.Ardakani@Sun.COM 
20611963SAfshin.Ardakani@Sun.COM 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
20711963SAfshin.Ardakani@Sun.COM 		return (NERR_InternalError);
20811963SAfshin.Ardakani@Sun.COM 
20911963SAfshin.Ardakani@Sun.COM 	if (nvlist_add_string(nvl, SHOPT_DFSROOT, dfs) != 0) {
21011963SAfshin.Ardakani@Sun.COM 		nvlist_free(nvl);
21111963SAfshin.Ardakani@Sun.COM 		return (NERR_InternalError);
21211963SAfshin.Ardakani@Sun.COM 	}
21311963SAfshin.Ardakani@Sun.COM 
21411963SAfshin.Ardakani@Sun.COM 	nerr = srvsvc_sa_setprop(si, nvl);
21511963SAfshin.Ardakani@Sun.COM 	nvlist_free(nvl);
21611963SAfshin.Ardakani@Sun.COM 
21711963SAfshin.Ardakani@Sun.COM 	if (nerr != NERR_Success)
21811963SAfshin.Ardakani@Sun.COM 		return (nerr);
21911963SAfshin.Ardakani@Sun.COM 
22011963SAfshin.Ardakani@Sun.COM 	return (smb_shr_modify(si));
22111963SAfshin.Ardakani@Sun.COM }
22211963SAfshin.Ardakani@Sun.COM 
22311963SAfshin.Ardakani@Sun.COM /*
2248474SJose.Borrego@Sun.COM  * srvsvc_s_NetConnectEnum
2258474SJose.Borrego@Sun.COM  *
2268474SJose.Borrego@Sun.COM  * List tree connections made to a share on this server or all tree
2278474SJose.Borrego@Sun.COM  * connections established from a specific client.  Administrator,
2288474SJose.Borrego@Sun.COM  * Server Operator, Print Operator or Power User group membership
2298474SJose.Borrego@Sun.COM  * is required to use this interface.
2308474SJose.Borrego@Sun.COM  *
2318474SJose.Borrego@Sun.COM  * There are three information levels:  0, 1, and 50.  We don't support
2328474SJose.Borrego@Sun.COM  * level 50, which is only used by Windows 9x clients.
2338474SJose.Borrego@Sun.COM  *
2348474SJose.Borrego@Sun.COM  * It seems Server Manger (srvmgr) only sends workstation as the qualifier
2358474SJose.Borrego@Sun.COM  * and the Computer Management Interface on Windows 2000 doesn't request
2368474SJose.Borrego@Sun.COM  * a list of connections.
2378474SJose.Borrego@Sun.COM  *
2388474SJose.Borrego@Sun.COM  * Return Values:
2398474SJose.Borrego@Sun.COM  * ERROR_SUCCESS            Success
2408474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED      Caller does not have access to this call.
2418474SJose.Borrego@Sun.COM  * ERROR_INVALID_PARAMETER  One of the parameters is invalid.
2428474SJose.Borrego@Sun.COM  * ERROR_INVALID_LEVEL      Unknown information level specified.
2438474SJose.Borrego@Sun.COM  * ERROR_MORE_DATA          Partial date returned, more entries available.
2448474SJose.Borrego@Sun.COM  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
2458474SJose.Borrego@Sun.COM  * NERR_NetNameNotFound     The share qualifier cannot be found.
2468474SJose.Borrego@Sun.COM  * NERR_BufTooSmall         The supplied buffer is too small.
2478474SJose.Borrego@Sun.COM  */
2488474SJose.Borrego@Sun.COM static int
srvsvc_s_NetConnectEnum(void * arg,ndr_xa_t * mxa)2498474SJose.Borrego@Sun.COM srvsvc_s_NetConnectEnum(void *arg, ndr_xa_t *mxa)
2508474SJose.Borrego@Sun.COM {
25110122SJordan.Brown@Sun.COM 	srvsvc_NetConnectEnum_t		*param = arg;
25210122SJordan.Brown@Sun.COM 	smb_netsvc_t			*ns;
25310122SJordan.Brown@Sun.COM 	smb_svcenum_t			se;
25410122SJordan.Brown@Sun.COM 	char				*qualifier;
25510122SJordan.Brown@Sun.COM 	int				qualtype;
25610122SJordan.Brown@Sun.COM 	DWORD				status = ERROR_SUCCESS;
2578474SJose.Borrego@Sun.COM 
2588474SJose.Borrego@Sun.COM 	if (!ndr_is_poweruser(mxa)) {
25910122SJordan.Brown@Sun.COM 		status = ERROR_ACCESS_DENIED;
26010122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
2618474SJose.Borrego@Sun.COM 	}
2628474SJose.Borrego@Sun.COM 
2638474SJose.Borrego@Sun.COM 	qualifier = (char *)param->qualifier;
2648474SJose.Borrego@Sun.COM 	qualtype = srvsvc_netconnect_qualifier(qualifier);
2658474SJose.Borrego@Sun.COM 	if (qualtype == SRVSVC_CONNECT_ENUM_NULL) {
26610122SJordan.Brown@Sun.COM 		status = NERR_NetNameNotFound;
26710122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
26810122SJordan.Brown@Sun.COM 	}
26910122SJordan.Brown@Sun.COM 
27010122SJordan.Brown@Sun.COM 	param->total_entries = srvsvc_open_connections(qualtype, qualifier);
27110122SJordan.Brown@Sun.COM 	if (param->total_entries == 0) {
27210122SJordan.Brown@Sun.COM 		bzero(param, sizeof (srvsvc_NetConnectEnum_t));
27310122SJordan.Brown@Sun.COM 		param->status = ERROR_SUCCESS;
2748474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
2758474SJose.Borrego@Sun.COM 	}
2768474SJose.Borrego@Sun.COM 
27710122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
27810122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_TREE;
27910122SJordan.Brown@Sun.COM 	se.se_level = param->info.level;
28010122SJordan.Brown@Sun.COM 	se.se_ntotal = param->total_entries;
28110122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
28210122SJordan.Brown@Sun.COM 
28310122SJordan.Brown@Sun.COM 	if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN ||
28410122SJordan.Brown@Sun.COM 	    param->pref_max_len > SMB_SRVSVC_MAXBUFLEN)
28510122SJordan.Brown@Sun.COM 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
28610122SJordan.Brown@Sun.COM 	else
28710122SJordan.Brown@Sun.COM 		se.se_prefmaxlen = param->pref_max_len;
28810122SJordan.Brown@Sun.COM 
28910122SJordan.Brown@Sun.COM 	if (param->resume_handle) {
29010122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
29110122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
29210122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
29310122SJordan.Brown@Sun.COM 	}
29410122SJordan.Brown@Sun.COM 
2958474SJose.Borrego@Sun.COM 	switch (param->info.level) {
2968474SJose.Borrego@Sun.COM 	case 0:
29710122SJordan.Brown@Sun.COM 		status = srvsvc_netconnectenum_level0(mxa, &se, param);
2988474SJose.Borrego@Sun.COM 		break;
2998474SJose.Borrego@Sun.COM 	case 1:
30010122SJordan.Brown@Sun.COM 		status = srvsvc_netconnectenum_level1(mxa, &se, param);
3018474SJose.Borrego@Sun.COM 		break;
3028474SJose.Borrego@Sun.COM 	case 50:
3038474SJose.Borrego@Sun.COM 		status = ERROR_NOT_SUPPORTED;
3048474SJose.Borrego@Sun.COM 		break;
3058474SJose.Borrego@Sun.COM 	default:
3068474SJose.Borrego@Sun.COM 		status = ERROR_INVALID_LEVEL;
3078474SJose.Borrego@Sun.COM 		break;
3088474SJose.Borrego@Sun.COM 	}
3098474SJose.Borrego@Sun.COM 
3108474SJose.Borrego@Sun.COM 	if (status != ERROR_SUCCESS)
31110122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
31210122SJordan.Brown@Sun.COM 
31310122SJordan.Brown@Sun.COM 	if ((ns = smb_kmod_enum_init(&se)) == NULL) {
31410122SJordan.Brown@Sun.COM 		status = ERROR_NOT_ENOUGH_MEMORY;
31510122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
31610122SJordan.Brown@Sun.COM 	}
31710122SJordan.Brown@Sun.COM 
31810122SJordan.Brown@Sun.COM 	status = srvsvc_netconnectenum_common(mxa, &param->info, ns, &se);
31910122SJordan.Brown@Sun.COM 	smb_kmod_enum_fini(ns);
32010122SJordan.Brown@Sun.COM 
32110122SJordan.Brown@Sun.COM 	if (status != ERROR_SUCCESS)
32210122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
32310122SJordan.Brown@Sun.COM 
32410122SJordan.Brown@Sun.COM 	if (param->resume_handle &&
32510122SJordan.Brown@Sun.COM 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
32610122SJordan.Brown@Sun.COM 		if (se.se_resume < param->total_entries) {
32710122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
32810122SJordan.Brown@Sun.COM 			status = ERROR_MORE_DATA;
32910122SJordan.Brown@Sun.COM 		}
33010122SJordan.Brown@Sun.COM 	}
33110122SJordan.Brown@Sun.COM 
33210122SJordan.Brown@Sun.COM 	param->status = status;
33310122SJordan.Brown@Sun.COM 	return (NDR_DRC_OK);
33410122SJordan.Brown@Sun.COM 
33510122SJordan.Brown@Sun.COM srvsvc_netconnectenum_error:
33610122SJordan.Brown@Sun.COM 	bzero(param, sizeof (srvsvc_NetConnectEnum_t));
3378474SJose.Borrego@Sun.COM 	param->status = status;
3388474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
3398474SJose.Borrego@Sun.COM }
3408474SJose.Borrego@Sun.COM 
34110122SJordan.Brown@Sun.COM /*
34210122SJordan.Brown@Sun.COM  * Allocate memory and estimate the number of objects that can
34310122SJordan.Brown@Sun.COM  * be returned for NetConnectEnum level 0.
34410122SJordan.Brown@Sun.COM  */
34510122SJordan.Brown@Sun.COM static uint32_t
srvsvc_netconnectenum_level0(ndr_xa_t * mxa,smb_svcenum_t * se,srvsvc_NetConnectEnum_t * param)34610122SJordan.Brown@Sun.COM srvsvc_netconnectenum_level0(ndr_xa_t *mxa, smb_svcenum_t *se,
34710122SJordan.Brown@Sun.COM     srvsvc_NetConnectEnum_t *param)
3488474SJose.Borrego@Sun.COM {
34910122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfo0_t	*info0;
35010122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfoBuf0_t	*ci0;
35110122SJordan.Brown@Sun.COM 
35210122SJordan.Brown@Sun.COM 	if ((info0 = NDR_NEW(mxa, srvsvc_NetConnectInfo0_t)) == NULL)
35310122SJordan.Brown@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
35410122SJordan.Brown@Sun.COM 
35510122SJordan.Brown@Sun.COM 	bzero(info0, sizeof (srvsvc_NetConnectInfo0_t));
35610122SJordan.Brown@Sun.COM 	param->info.ru.info0 = info0;
35710122SJordan.Brown@Sun.COM 
35810122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se, sizeof (srvsvc_NetConnectInfoBuf0_t));
35910122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
36010122SJordan.Brown@Sun.COM 		return (NERR_BufTooSmall);
36110122SJordan.Brown@Sun.COM 
36210122SJordan.Brown@Sun.COM 	do {
36310122SJordan.Brown@Sun.COM 		ci0 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf0_t, se->se_nlimit);
36410122SJordan.Brown@Sun.COM 		if (ci0 == NULL)
36510122SJordan.Brown@Sun.COM 			se->se_nlimit >>= 1;
36610122SJordan.Brown@Sun.COM 	} while ((se->se_nlimit > 0) && (ci0 == NULL));
36710122SJordan.Brown@Sun.COM 
3688474SJose.Borrego@Sun.COM 	if (ci0 == NULL)
3698474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
3708474SJose.Borrego@Sun.COM 
3718474SJose.Borrego@Sun.COM 	info0->ci0 = ci0;
37210122SJordan.Brown@Sun.COM 	info0->entries_read = 0;
3738474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
3748474SJose.Borrego@Sun.COM }
3758474SJose.Borrego@Sun.COM 
37610122SJordan.Brown@Sun.COM /*
37710122SJordan.Brown@Sun.COM  * Allocate memory and estimate the number of objects that can
37810122SJordan.Brown@Sun.COM  * be returned for NetConnectEnum level 1.
37910122SJordan.Brown@Sun.COM  */
38010122SJordan.Brown@Sun.COM static uint32_t
srvsvc_netconnectenum_level1(ndr_xa_t * mxa,smb_svcenum_t * se,srvsvc_NetConnectEnum_t * param)38110122SJordan.Brown@Sun.COM srvsvc_netconnectenum_level1(ndr_xa_t *mxa, smb_svcenum_t *se,
38210122SJordan.Brown@Sun.COM     srvsvc_NetConnectEnum_t *param)
3838474SJose.Borrego@Sun.COM {
38410122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfo1_t	*info1;
38510122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfoBuf1_t	*ci1;
38610122SJordan.Brown@Sun.COM 
38710122SJordan.Brown@Sun.COM 	if ((info1 = NDR_NEW(mxa, srvsvc_NetConnectInfo1_t)) == NULL)
38810122SJordan.Brown@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
38910122SJordan.Brown@Sun.COM 
39010122SJordan.Brown@Sun.COM 	bzero(info1, sizeof (srvsvc_NetConnectInfo1_t));
39110122SJordan.Brown@Sun.COM 	param->info.ru.info1 = info1;
39210122SJordan.Brown@Sun.COM 
39310122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
39410122SJordan.Brown@Sun.COM 	    sizeof (srvsvc_NetConnectInfoBuf1_t) + MAXNAMELEN);
39510122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
39610122SJordan.Brown@Sun.COM 		return (NERR_BufTooSmall);
39710122SJordan.Brown@Sun.COM 
39810122SJordan.Brown@Sun.COM 	do {
39910122SJordan.Brown@Sun.COM 		ci1 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf1_t, se->se_nlimit);
40010122SJordan.Brown@Sun.COM 		if (ci1 == NULL)
40110122SJordan.Brown@Sun.COM 			se->se_nlimit >>= 1;
40210122SJordan.Brown@Sun.COM 	} while ((se->se_nlimit > 0) && (ci1 == NULL));
40310122SJordan.Brown@Sun.COM 
4048474SJose.Borrego@Sun.COM 	if (ci1 == NULL)
4058474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
4068474SJose.Borrego@Sun.COM 
4078474SJose.Borrego@Sun.COM 	info1->ci1 = ci1;
40810122SJordan.Brown@Sun.COM 	info1->entries_read = 0;
40910122SJordan.Brown@Sun.COM 	return (ERROR_SUCCESS);
41010122SJordan.Brown@Sun.COM }
41110122SJordan.Brown@Sun.COM 
41210122SJordan.Brown@Sun.COM /*
41310122SJordan.Brown@Sun.COM  * Request a list of connections from the kernel and set up
41410122SJordan.Brown@Sun.COM  * the connection information to be returned to the client.
41510122SJordan.Brown@Sun.COM  */
41610122SJordan.Brown@Sun.COM static uint32_t
srvsvc_netconnectenum_common(ndr_xa_t * mxa,srvsvc_NetConnectInfo_t * info,smb_netsvc_t * ns,smb_svcenum_t * se)41710122SJordan.Brown@Sun.COM srvsvc_netconnectenum_common(ndr_xa_t *mxa, srvsvc_NetConnectInfo_t *info,
41810122SJordan.Brown@Sun.COM     smb_netsvc_t *ns, smb_svcenum_t *se)
41910122SJordan.Brown@Sun.COM {
42010122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfo0_t	*info0;
42110122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfo1_t	*info1;
42210122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfoBuf0_t	*ci0;
42310122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfoBuf1_t	*ci1;
42410122SJordan.Brown@Sun.COM 	smb_netsvcitem_t		*item;
42510122SJordan.Brown@Sun.COM 	smb_netconnectinfo_t		*tree;
42610122SJordan.Brown@Sun.COM 
42710122SJordan.Brown@Sun.COM 	if (smb_kmod_enum(ns) != 0)
42810122SJordan.Brown@Sun.COM 		return (ERROR_INTERNAL_ERROR);
42910122SJordan.Brown@Sun.COM 
43010122SJordan.Brown@Sun.COM 	info0 = info->ru.info0;
43110122SJordan.Brown@Sun.COM 	ci0 = info0->ci0;
43210122SJordan.Brown@Sun.COM 
43310122SJordan.Brown@Sun.COM 	info1 = info->ru.info1;
43410122SJordan.Brown@Sun.COM 	ci1 = info1->ci1;
43510122SJordan.Brown@Sun.COM 
43610122SJordan.Brown@Sun.COM 	item = list_head(&ns->ns_list);
43710122SJordan.Brown@Sun.COM 	while (item != NULL) {
43810122SJordan.Brown@Sun.COM 		tree = &item->nsi_un.nsi_tree;
43910122SJordan.Brown@Sun.COM 
44010122SJordan.Brown@Sun.COM 		switch (se->se_level) {
44110122SJordan.Brown@Sun.COM 		case 0:
44210122SJordan.Brown@Sun.COM 			ci0->coni0_id = tree->ci_id;
44310122SJordan.Brown@Sun.COM 			++ci0;
44410122SJordan.Brown@Sun.COM 			++info0->entries_read;
44510122SJordan.Brown@Sun.COM 			break;
44610122SJordan.Brown@Sun.COM 		case 1:
44710122SJordan.Brown@Sun.COM 			ci1->coni1_id = tree->ci_id;
44810122SJordan.Brown@Sun.COM 			ci1->coni1_type = tree->ci_type;
44910122SJordan.Brown@Sun.COM 			ci1->coni1_num_opens = tree->ci_numopens;
45010122SJordan.Brown@Sun.COM 			ci1->coni1_num_users = tree->ci_numusers;
45110122SJordan.Brown@Sun.COM 			ci1->coni1_time = tree->ci_time;
45210122SJordan.Brown@Sun.COM 			ci1->coni1_username = (uint8_t *)
45310122SJordan.Brown@Sun.COM 			    NDR_STRDUP(mxa, tree->ci_username);
45410122SJordan.Brown@Sun.COM 			ci1->coni1_netname = (uint8_t *)
45510122SJordan.Brown@Sun.COM 			    NDR_STRDUP(mxa, tree->ci_share);
45610122SJordan.Brown@Sun.COM 			++ci1;
45710122SJordan.Brown@Sun.COM 			++info1->entries_read;
45810122SJordan.Brown@Sun.COM 			break;
45910122SJordan.Brown@Sun.COM 		default:
46010122SJordan.Brown@Sun.COM 			return (ERROR_INVALID_LEVEL);
46110122SJordan.Brown@Sun.COM 		}
46210122SJordan.Brown@Sun.COM 
46310122SJordan.Brown@Sun.COM 		++se->se_resume;
46410122SJordan.Brown@Sun.COM 		item = list_next(&ns->ns_list, item);
46510122SJordan.Brown@Sun.COM 	}
46610122SJordan.Brown@Sun.COM 
4678474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
4688474SJose.Borrego@Sun.COM }
4698474SJose.Borrego@Sun.COM 
4708474SJose.Borrego@Sun.COM /*
4718474SJose.Borrego@Sun.COM  * srvsvc_netconnect_qualifier
4728474SJose.Borrego@Sun.COM  *
4738474SJose.Borrego@Sun.COM  * The qualifier is a string that specifies a share name or computer name
4748474SJose.Borrego@Sun.COM  * for the connections of interest.  If it is a share name then all the
4758474SJose.Borrego@Sun.COM  * connections made to that share name are listed.  If it is a computer
4768474SJose.Borrego@Sun.COM  * name (it starts with two backslash characters), then NetConnectEnum
4778474SJose.Borrego@Sun.COM  * lists all connections made from that computer to the specified server.
4788474SJose.Borrego@Sun.COM  */
4798474SJose.Borrego@Sun.COM static int
srvsvc_netconnect_qualifier(const char * qualifier)4808474SJose.Borrego@Sun.COM srvsvc_netconnect_qualifier(const char *qualifier)
4818474SJose.Borrego@Sun.COM {
4828474SJose.Borrego@Sun.COM 	if (qualifier == NULL || *qualifier == '\0')
4838474SJose.Borrego@Sun.COM 		return (SRVSVC_CONNECT_ENUM_NULL);
4848474SJose.Borrego@Sun.COM 
4858474SJose.Borrego@Sun.COM 	if (strlen(qualifier) > MAXHOSTNAMELEN)
4868474SJose.Borrego@Sun.COM 		return (SRVSVC_CONNECT_ENUM_NULL);
4878474SJose.Borrego@Sun.COM 
4888474SJose.Borrego@Sun.COM 	if (qualifier[0] == '\\' && qualifier[1] == '\\') {
4898474SJose.Borrego@Sun.COM 		return (SRVSVC_CONNECT_ENUM_WKSTN);
4908474SJose.Borrego@Sun.COM 	} else {
4918474SJose.Borrego@Sun.COM 		if (!smb_shr_exists((char *)qualifier))
4928474SJose.Borrego@Sun.COM 			return (SRVSVC_CONNECT_ENUM_NULL);
4938474SJose.Borrego@Sun.COM 
4948474SJose.Borrego@Sun.COM 		return (SRVSVC_CONNECT_ENUM_SHARE);
4958474SJose.Borrego@Sun.COM 	}
4968474SJose.Borrego@Sun.COM }
4978474SJose.Borrego@Sun.COM 
49810122SJordan.Brown@Sun.COM static uint32_t
srvsvc_open_sessions(void)49910122SJordan.Brown@Sun.COM srvsvc_open_sessions(void)
50010122SJordan.Brown@Sun.COM {
50110122SJordan.Brown@Sun.COM 	smb_opennum_t	opennum;
50210122SJordan.Brown@Sun.COM 
50310122SJordan.Brown@Sun.COM 	bzero(&opennum, sizeof (smb_opennum_t));
50410122SJordan.Brown@Sun.COM 	if (smb_kmod_get_open_num(&opennum) != 0)
50510122SJordan.Brown@Sun.COM 		return (0);
50610122SJordan.Brown@Sun.COM 
50710122SJordan.Brown@Sun.COM 	return (opennum.open_users);
50810122SJordan.Brown@Sun.COM }
50910122SJordan.Brown@Sun.COM 
51010122SJordan.Brown@Sun.COM static uint32_t
srvsvc_open_connections(uint32_t qualtype,const char * qualifier)51110122SJordan.Brown@Sun.COM srvsvc_open_connections(uint32_t qualtype, const char *qualifier)
51210122SJordan.Brown@Sun.COM {
51310122SJordan.Brown@Sun.COM 	smb_opennum_t	opennum;
51410122SJordan.Brown@Sun.COM 
51510122SJordan.Brown@Sun.COM 	bzero(&opennum, sizeof (smb_opennum_t));
51610122SJordan.Brown@Sun.COM 	opennum.qualtype = qualtype;
51710122SJordan.Brown@Sun.COM 	(void) strlcpy(opennum.qualifier, qualifier, MAXNAMELEN);
51810122SJordan.Brown@Sun.COM 
51910122SJordan.Brown@Sun.COM 	if (smb_kmod_get_open_num(&opennum) != 0)
52010122SJordan.Brown@Sun.COM 		return (0);
52110122SJordan.Brown@Sun.COM 
52210122SJordan.Brown@Sun.COM 	return (opennum.open_trees);
52310122SJordan.Brown@Sun.COM }
52410122SJordan.Brown@Sun.COM 
52510122SJordan.Brown@Sun.COM static uint32_t
srvsvc_open_files(void)52610122SJordan.Brown@Sun.COM srvsvc_open_files(void)
52710122SJordan.Brown@Sun.COM {
52810122SJordan.Brown@Sun.COM 	smb_opennum_t	opennum;
52910122SJordan.Brown@Sun.COM 
53010122SJordan.Brown@Sun.COM 	bzero(&opennum, sizeof (smb_opennum_t));
53110122SJordan.Brown@Sun.COM 	if (smb_kmod_get_open_num(&opennum) != 0)
53210122SJordan.Brown@Sun.COM 		return (0);
53310122SJordan.Brown@Sun.COM 
53410122SJordan.Brown@Sun.COM 	return (opennum.open_files);
53510122SJordan.Brown@Sun.COM }
53610122SJordan.Brown@Sun.COM 
5378474SJose.Borrego@Sun.COM /*
5388474SJose.Borrego@Sun.COM  * srvsvc_s_NetFileEnum
5398474SJose.Borrego@Sun.COM  *
5408474SJose.Borrego@Sun.COM  * Return information on open files or named pipes. Only members of the
5418474SJose.Borrego@Sun.COM  * Administrators or Server Operators local groups are allowed to make
5428474SJose.Borrego@Sun.COM  * this call. Currently, we only support Administrators.
5438474SJose.Borrego@Sun.COM  *
5448474SJose.Borrego@Sun.COM  * If basepath is null, all open resources are enumerated. If basepath
5458474SJose.Borrego@Sun.COM  * is non-null, only resources that have basepath as a prefix should
5468474SJose.Borrego@Sun.COM  * be returned.
5478474SJose.Borrego@Sun.COM  *
5488474SJose.Borrego@Sun.COM  * If username is specified (non-null), only files opened by username
5498474SJose.Borrego@Sun.COM  * should be returned.
5508474SJose.Borrego@Sun.COM  *
5518474SJose.Borrego@Sun.COM  * Notes:
5528474SJose.Borrego@Sun.COM  * 1. We don't validate the servername because we would have to check
5538474SJose.Borrego@Sun.COM  * all primary IPs and the ROI seems unlikely to be worth it.
5548474SJose.Borrego@Sun.COM  * 2. Both basepath and username are currently ignored because both
5558474SJose.Borrego@Sun.COM  * Server Manger (NT 4.0) and CMI (Windows 2000) always set them to null.
5568474SJose.Borrego@Sun.COM  *
5578474SJose.Borrego@Sun.COM  * The level of information requested may be one of:
5588474SJose.Borrego@Sun.COM  *
5598474SJose.Borrego@Sun.COM  *  2   Return the file identification number.
5608474SJose.Borrego@Sun.COM  *      This level is not supported on Windows Me/98/95.
5618474SJose.Borrego@Sun.COM  *
5628474SJose.Borrego@Sun.COM  *  3   Return information about the file.
5638474SJose.Borrego@Sun.COM  *      This level is not supported on Windows Me/98/95.
5648474SJose.Borrego@Sun.COM  *
5658474SJose.Borrego@Sun.COM  *  50  Windows Me/98/95:  Return information about the file.
5668474SJose.Borrego@Sun.COM  *
5678474SJose.Borrego@Sun.COM  * Note:
5688474SJose.Borrego@Sun.COM  * If pref_max_len is unlimited and resume_handle is null, the client
5698474SJose.Borrego@Sun.COM  * expects to receive all data in a single call.
5708474SJose.Borrego@Sun.COM  * If we are unable to do fit all data in a single response, we would
5718474SJose.Borrego@Sun.COM  * normally return ERROR_MORE_DATA with a partial list.
5728474SJose.Borrego@Sun.COM  *
5738474SJose.Borrego@Sun.COM  * Unfortunately, when both of these conditions occur, Server Manager
5748474SJose.Borrego@Sun.COM  * pops up an error box with the message "more data available" and
5758474SJose.Borrego@Sun.COM  * doesn't display any of the returned data. In this case, it is
5768474SJose.Borrego@Sun.COM  * probably better to return ERROR_SUCCESS with the partial list.
5778474SJose.Borrego@Sun.COM  * Windows 2000 doesn't have this problem because it always sends a
5788474SJose.Borrego@Sun.COM  * non-null resume_handle.
5798474SJose.Borrego@Sun.COM  *
5808474SJose.Borrego@Sun.COM  * Return Values:
5818474SJose.Borrego@Sun.COM  * ERROR_SUCCESS            Success
5828474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED      Caller does not have access to this call.
5838474SJose.Borrego@Sun.COM  * ERROR_INVALID_PARAMETER  One of the parameters is invalid.
5848474SJose.Borrego@Sun.COM  * ERROR_INVALID_LEVEL      Unknown information level specified.
5858474SJose.Borrego@Sun.COM  * ERROR_MORE_DATA          Partial date returned, more entries available.
5868474SJose.Borrego@Sun.COM  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
5878474SJose.Borrego@Sun.COM  * NERR_BufTooSmall         The supplied buffer is too small.
5888474SJose.Borrego@Sun.COM  */
5898474SJose.Borrego@Sun.COM static int
srvsvc_s_NetFileEnum(void * arg,ndr_xa_t * mxa)5908474SJose.Borrego@Sun.COM srvsvc_s_NetFileEnum(void *arg, ndr_xa_t *mxa)
5918474SJose.Borrego@Sun.COM {
59210122SJordan.Brown@Sun.COM 	struct mslm_NetFileEnum	*param = arg;
59310122SJordan.Brown@Sun.COM 	smb_svcenum_t		se;
59410122SJordan.Brown@Sun.COM 	DWORD			status;
5958474SJose.Borrego@Sun.COM 
5968474SJose.Borrego@Sun.COM 	if (!ndr_is_admin(mxa)) {
5978474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetFileEnum));
5988474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
5998474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
6008474SJose.Borrego@Sun.COM 	}
6018474SJose.Borrego@Sun.COM 
60210122SJordan.Brown@Sun.COM 	if ((param->total_entries = srvsvc_open_files()) == 0) {
60310122SJordan.Brown@Sun.COM 		bzero(param, sizeof (struct mslm_NetFileEnum));
60410122SJordan.Brown@Sun.COM 		param->status = ERROR_SUCCESS;
60510122SJordan.Brown@Sun.COM 		return (NDR_DRC_OK);
60610122SJordan.Brown@Sun.COM 	}
60710122SJordan.Brown@Sun.COM 
60810122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
60910122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_FILE;
61010122SJordan.Brown@Sun.COM 	se.se_level = param->info.switch_value;
61110122SJordan.Brown@Sun.COM 	se.se_ntotal = param->total_entries;
61210122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
61310122SJordan.Brown@Sun.COM 
61410122SJordan.Brown@Sun.COM 	if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN ||
61510122SJordan.Brown@Sun.COM 	    param->pref_max_len > SMB_SRVSVC_MAXBUFLEN)
61610122SJordan.Brown@Sun.COM 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
61710122SJordan.Brown@Sun.COM 	else
61810122SJordan.Brown@Sun.COM 		se.se_prefmaxlen = param->pref_max_len;
61910122SJordan.Brown@Sun.COM 
62010122SJordan.Brown@Sun.COM 	if (param->resume_handle) {
62110122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
62210122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
62310122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
62410122SJordan.Brown@Sun.COM 	}
62510122SJordan.Brown@Sun.COM 
6268474SJose.Borrego@Sun.COM 	switch (param->info.switch_value) {
6278474SJose.Borrego@Sun.COM 	case 2:
62810122SJordan.Brown@Sun.COM 		status = srvsvc_NetFileEnum2(mxa, param, &se);
6298474SJose.Borrego@Sun.COM 		break;
6308474SJose.Borrego@Sun.COM 
6318474SJose.Borrego@Sun.COM 	case 3:
63210122SJordan.Brown@Sun.COM 		status = srvsvc_NetFileEnum3(mxa, param, &se);
6338474SJose.Borrego@Sun.COM 		break;
6348474SJose.Borrego@Sun.COM 
6358474SJose.Borrego@Sun.COM 	case 50:
6368474SJose.Borrego@Sun.COM 		status = ERROR_NOT_SUPPORTED;
6378474SJose.Borrego@Sun.COM 		break;
6388474SJose.Borrego@Sun.COM 
6398474SJose.Borrego@Sun.COM 	default:
6408474SJose.Borrego@Sun.COM 		status = ERROR_INVALID_LEVEL;
6418474SJose.Borrego@Sun.COM 		break;
6428474SJose.Borrego@Sun.COM 	}
6438474SJose.Borrego@Sun.COM 
6448474SJose.Borrego@Sun.COM 	if (status != ERROR_SUCCESS) {
6458474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetFileEnum));
6468474SJose.Borrego@Sun.COM 		param->status = status;
6478474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
6488474SJose.Borrego@Sun.COM 	}
6498474SJose.Borrego@Sun.COM 
65010122SJordan.Brown@Sun.COM 	if (param->resume_handle &&
65110122SJordan.Brown@Sun.COM 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
65210122SJordan.Brown@Sun.COM 		if (se.se_resume < param->total_entries) {
65310122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
65410122SJordan.Brown@Sun.COM 			status = ERROR_MORE_DATA;
65510122SJordan.Brown@Sun.COM 		}
65610122SJordan.Brown@Sun.COM 	}
65710122SJordan.Brown@Sun.COM 
65810122SJordan.Brown@Sun.COM 	param->status = status;
6598474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
6608474SJose.Borrego@Sun.COM }
6618474SJose.Borrego@Sun.COM 
6628474SJose.Borrego@Sun.COM /*
6638474SJose.Borrego@Sun.COM  * Build level 2 file information.
6648474SJose.Borrego@Sun.COM  *
66510122SJordan.Brown@Sun.COM  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
66610122SJordan.Brown@Sun.COM  * So we use the uniqid here.
66710122SJordan.Brown@Sun.COM  *
6688474SJose.Borrego@Sun.COM  * On success, the caller expects that the info2, fi2 and entries_read
6698474SJose.Borrego@Sun.COM  * fields have been set up.
6708474SJose.Borrego@Sun.COM  */
6718474SJose.Borrego@Sun.COM static DWORD
srvsvc_NetFileEnum2(ndr_xa_t * mxa,struct mslm_NetFileEnum * param,smb_svcenum_t * se)67210122SJordan.Brown@Sun.COM srvsvc_NetFileEnum2(ndr_xa_t *mxa, struct mslm_NetFileEnum *param,
67310122SJordan.Brown@Sun.COM     smb_svcenum_t *se)
6748474SJose.Borrego@Sun.COM {
67510122SJordan.Brown@Sun.COM 	struct mslm_NetFileInfoBuf2	*fi2;
67610122SJordan.Brown@Sun.COM 	smb_netsvc_t			*ns;
67710122SJordan.Brown@Sun.COM 	smb_netsvcitem_t		*item;
67810122SJordan.Brown@Sun.COM 	smb_netfileinfo_t		*ofile;
67910122SJordan.Brown@Sun.COM 	uint32_t			entries_read = 0;
6808474SJose.Borrego@Sun.COM 
6818474SJose.Borrego@Sun.COM 	param->info.ru.info2 = NDR_NEW(mxa, struct mslm_NetFileInfo2);
6829832Samw@Sun.COM 	if (param->info.ru.info2 == NULL)
6838474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
6848474SJose.Borrego@Sun.COM 
68510122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se, sizeof (struct mslm_NetFileInfoBuf2));
68610122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
68710122SJordan.Brown@Sun.COM 		return (NERR_BufTooSmall);
68810122SJordan.Brown@Sun.COM 
68910122SJordan.Brown@Sun.COM 	do {
69010122SJordan.Brown@Sun.COM 		fi2 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf2, se->se_nlimit);
69110122SJordan.Brown@Sun.COM 		if (fi2 == NULL)
69210122SJordan.Brown@Sun.COM 			se->se_nlimit >>= 1;
69310122SJordan.Brown@Sun.COM 	} while ((se->se_nlimit > 0) && (fi2 == NULL));
69410122SJordan.Brown@Sun.COM 
6958474SJose.Borrego@Sun.COM 	if (fi2 == NULL)
6968474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
6978474SJose.Borrego@Sun.COM 
6988474SJose.Borrego@Sun.COM 	param->info.ru.info2->fi2 = fi2;
6998474SJose.Borrego@Sun.COM 
70010122SJordan.Brown@Sun.COM 	if ((ns = smb_kmod_enum_init(se)) == NULL)
70110122SJordan.Brown@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
70210122SJordan.Brown@Sun.COM 
70310122SJordan.Brown@Sun.COM 	if (smb_kmod_enum(ns) != 0) {
70410122SJordan.Brown@Sun.COM 		smb_kmod_enum_fini(ns);
70510122SJordan.Brown@Sun.COM 		return (ERROR_INTERNAL_ERROR);
70610122SJordan.Brown@Sun.COM 	}
70710122SJordan.Brown@Sun.COM 
70810122SJordan.Brown@Sun.COM 	item = list_head(&ns->ns_list);
70910122SJordan.Brown@Sun.COM 	while (item != NULL) {
71010122SJordan.Brown@Sun.COM 		ofile = &item->nsi_un.nsi_ofile;
71110122SJordan.Brown@Sun.COM 		fi2->fi2_id = ofile->fi_uniqid;
7128474SJose.Borrego@Sun.COM 
7138474SJose.Borrego@Sun.COM 		++entries_read;
7148474SJose.Borrego@Sun.COM 		++fi2;
71510122SJordan.Brown@Sun.COM 		item = list_next(&ns->ns_list, item);
7168474SJose.Borrego@Sun.COM 	}
7178474SJose.Borrego@Sun.COM 
71810122SJordan.Brown@Sun.COM 	se->se_resume += entries_read;
7198474SJose.Borrego@Sun.COM 	param->info.ru.info2->entries_read = entries_read;
72010122SJordan.Brown@Sun.COM 	smb_kmod_enum_fini(ns);
7218474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
7228474SJose.Borrego@Sun.COM }
7238474SJose.Borrego@Sun.COM 
7248474SJose.Borrego@Sun.COM /*
7258474SJose.Borrego@Sun.COM  * Build level 3 file information.
7268474SJose.Borrego@Sun.COM  *
72710122SJordan.Brown@Sun.COM  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
72810122SJordan.Brown@Sun.COM  * So we use the uniqid here.
72910122SJordan.Brown@Sun.COM  *
7308474SJose.Borrego@Sun.COM  * On success, the caller expects that the info3, fi3 and entries_read
7318474SJose.Borrego@Sun.COM  * fields have been set up.
7328474SJose.Borrego@Sun.COM  */
7338474SJose.Borrego@Sun.COM static DWORD
srvsvc_NetFileEnum3(ndr_xa_t * mxa,struct mslm_NetFileEnum * param,smb_svcenum_t * se)73410122SJordan.Brown@Sun.COM srvsvc_NetFileEnum3(ndr_xa_t *mxa, struct mslm_NetFileEnum *param,
73510122SJordan.Brown@Sun.COM     smb_svcenum_t *se)
7368474SJose.Borrego@Sun.COM {
73710122SJordan.Brown@Sun.COM 	struct mslm_NetFileInfoBuf3	*fi3;
73810122SJordan.Brown@Sun.COM 	smb_netsvc_t			*ns;
73910122SJordan.Brown@Sun.COM 	smb_netsvcitem_t		*item;
74010122SJordan.Brown@Sun.COM 	smb_netfileinfo_t		*ofile;
74110122SJordan.Brown@Sun.COM 	uint32_t			entries_read = 0;
7428474SJose.Borrego@Sun.COM 
7438474SJose.Borrego@Sun.COM 	param->info.ru.info3 = NDR_NEW(mxa, struct mslm_NetFileInfo3);
7448474SJose.Borrego@Sun.COM 	if (param->info.ru.info3 == NULL)
7458474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
7468474SJose.Borrego@Sun.COM 
74710122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
74810122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetFileInfoBuf3) + MAXNAMELEN);
74910122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
75010122SJordan.Brown@Sun.COM 		return (NERR_BufTooSmall);
75110122SJordan.Brown@Sun.COM 
75210122SJordan.Brown@Sun.COM 	do {
75310122SJordan.Brown@Sun.COM 		fi3 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf3, se->se_nlimit);
75410122SJordan.Brown@Sun.COM 		if (fi3 == NULL)
75510122SJordan.Brown@Sun.COM 			se->se_nlimit >>= 1;
75610122SJordan.Brown@Sun.COM 	} while ((se->se_nlimit > 0) && (fi3 == NULL));
75710122SJordan.Brown@Sun.COM 
7588474SJose.Borrego@Sun.COM 	if (fi3 == NULL)
7598474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
7608474SJose.Borrego@Sun.COM 
7618474SJose.Borrego@Sun.COM 	param->info.ru.info3->fi3 = fi3;
7628474SJose.Borrego@Sun.COM 
76310122SJordan.Brown@Sun.COM 	if ((ns = smb_kmod_enum_init(se)) == NULL)
76410122SJordan.Brown@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
76510122SJordan.Brown@Sun.COM 
76610122SJordan.Brown@Sun.COM 	if (smb_kmod_enum(ns) != 0) {
76710122SJordan.Brown@Sun.COM 		smb_kmod_enum_fini(ns);
76810122SJordan.Brown@Sun.COM 		return (ERROR_INTERNAL_ERROR);
76910122SJordan.Brown@Sun.COM 	}
77010122SJordan.Brown@Sun.COM 
77110122SJordan.Brown@Sun.COM 	item = list_head(&ns->ns_list);
77210122SJordan.Brown@Sun.COM 	while (item != NULL) {
77310122SJordan.Brown@Sun.COM 		ofile = &item->nsi_un.nsi_ofile;
77410122SJordan.Brown@Sun.COM 		fi3->fi3_id = ofile->fi_uniqid;
77510122SJordan.Brown@Sun.COM 		fi3->fi3_permissions = ofile->fi_permissions;
77610122SJordan.Brown@Sun.COM 		fi3->fi3_num_locks = ofile->fi_numlocks;
7778474SJose.Borrego@Sun.COM 		fi3->fi3_pathname = (uint8_t *)
77810122SJordan.Brown@Sun.COM 		    NDR_STRDUP(mxa, ofile->fi_path);
7798474SJose.Borrego@Sun.COM 		fi3->fi3_username = (uint8_t *)
78010122SJordan.Brown@Sun.COM 		    NDR_STRDUP(mxa, ofile->fi_username);
7818474SJose.Borrego@Sun.COM 
7828474SJose.Borrego@Sun.COM 		++entries_read;
7838474SJose.Borrego@Sun.COM 		++fi3;
78410122SJordan.Brown@Sun.COM 		item = list_next(&ns->ns_list, item);
7858474SJose.Borrego@Sun.COM 	}
7868474SJose.Borrego@Sun.COM 
78710122SJordan.Brown@Sun.COM 	se->se_resume += entries_read;
7888474SJose.Borrego@Sun.COM 	param->info.ru.info3->entries_read = entries_read;
7898474SJose.Borrego@Sun.COM 	param->total_entries = entries_read;
79011963SAfshin.Ardakani@Sun.COM 	smb_kmod_enum_fini(ns);
7918474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
7928474SJose.Borrego@Sun.COM }
7938474SJose.Borrego@Sun.COM 
7948474SJose.Borrego@Sun.COM /*
7958474SJose.Borrego@Sun.COM  * srvsvc_s_NetFileClose
7968474SJose.Borrego@Sun.COM  *
7978474SJose.Borrego@Sun.COM  * NetFileClose forces a file to close. This function can be used when
79810122SJordan.Brown@Sun.COM  * an error prevents closure by other means.  Use NetFileClose with
7998474SJose.Borrego@Sun.COM  * caution because it does not flush data, cached on a client, to the
8008474SJose.Borrego@Sun.COM  * file before closing the file.
8018474SJose.Borrego@Sun.COM  *
80210122SJordan.Brown@Sun.COM  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
80310122SJordan.Brown@Sun.COM  * So we use the uniqid here.
80410122SJordan.Brown@Sun.COM  *
8058474SJose.Borrego@Sun.COM  * Return Values
8068474SJose.Borrego@Sun.COM  * ERROR_SUCCESS            Operation succeeded.
8078474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED      Operation denied.
8088474SJose.Borrego@Sun.COM  * NERR_FileIdNotFound      No open file with the specified id.
8098474SJose.Borrego@Sun.COM  *
81010122SJordan.Brown@Sun.COM  * Note: MSDN suggests ERROR_FILE_NOT_FOUND for NetFileClose but network
81110122SJordan.Brown@Sun.COM  * captures using NT show NERR_FileIdNotFound, which is consistent with
81210122SJordan.Brown@Sun.COM  * the NetFileClose2 page on MSDN.
8138474SJose.Borrego@Sun.COM  */
8148474SJose.Borrego@Sun.COM static int
srvsvc_s_NetFileClose(void * arg,ndr_xa_t * mxa)8158474SJose.Borrego@Sun.COM srvsvc_s_NetFileClose(void *arg, ndr_xa_t *mxa)
8168474SJose.Borrego@Sun.COM {
81710122SJordan.Brown@Sun.COM 	static struct {
81810122SJordan.Brown@Sun.COM 		int errnum;
81910122SJordan.Brown@Sun.COM 		int nerr;
82010122SJordan.Brown@Sun.COM 	} errmap[] = {
82110122SJordan.Brown@Sun.COM 		0,	ERROR_SUCCESS,
82210122SJordan.Brown@Sun.COM 		EACCES,	ERROR_ACCESS_DENIED,
82310122SJordan.Brown@Sun.COM 		EPERM,	ERROR_ACCESS_DENIED,
82410122SJordan.Brown@Sun.COM 		EINVAL,	ERROR_INVALID_PARAMETER,
82510122SJordan.Brown@Sun.COM 		ENOMEM,	ERROR_NOT_ENOUGH_MEMORY,
82610122SJordan.Brown@Sun.COM 		ENOENT,	NERR_FileIdNotFound
82710122SJordan.Brown@Sun.COM 	};
82810122SJordan.Brown@Sun.COM 
8298474SJose.Borrego@Sun.COM 	struct mslm_NetFileClose *param = arg;
83010122SJordan.Brown@Sun.COM 	int		i;
83110122SJordan.Brown@Sun.COM 	int		rc;
8328474SJose.Borrego@Sun.COM 
8338474SJose.Borrego@Sun.COM 	if (!ndr_is_admin(mxa)) {
8348474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
8358474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
8368474SJose.Borrego@Sun.COM 	}
8378474SJose.Borrego@Sun.COM 
83810122SJordan.Brown@Sun.COM 	rc = smb_kmod_file_close(param->file_id);
83910122SJordan.Brown@Sun.COM 
84010122SJordan.Brown@Sun.COM 	for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) {
84110122SJordan.Brown@Sun.COM 		if (rc == errmap[i].errnum) {
84210122SJordan.Brown@Sun.COM 			param->status = errmap[i].nerr;
84310122SJordan.Brown@Sun.COM 			return (NDR_DRC_OK);
84410122SJordan.Brown@Sun.COM 		}
84510122SJordan.Brown@Sun.COM 	}
84610122SJordan.Brown@Sun.COM 
84710122SJordan.Brown@Sun.COM 	param->status = ERROR_INTERNAL_ERROR;
8488474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
8498474SJose.Borrego@Sun.COM }
8508474SJose.Borrego@Sun.COM 
8518474SJose.Borrego@Sun.COM /*
8528474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareGetInfo
8538474SJose.Borrego@Sun.COM  *
8548474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
8558474SJose.Borrego@Sun.COM  */
8568474SJose.Borrego@Sun.COM static int
srvsvc_s_NetShareGetInfo(void * arg,ndr_xa_t * mxa)8578474SJose.Borrego@Sun.COM srvsvc_s_NetShareGetInfo(void *arg, ndr_xa_t *mxa)
8588474SJose.Borrego@Sun.COM {
8598474SJose.Borrego@Sun.COM 	struct mlsm_NetShareGetInfo *param = arg;
8609343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_0 *info0;
8619343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1 *info1;
8629343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
8639343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_501 *info501;
8649343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
8659832Samw@Sun.COM 	struct mslm_NetShareInfo_503 *info503;
8669343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1004 *info1004;
8679343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1005 *info1005;
8689343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1006 *info1006;
8699832Samw@Sun.COM 	struct mslm_NetShareInfo_1501 *info1501;
8709832Samw@Sun.COM 	srvsvc_netshare_getinfo_t *info;
8719832Samw@Sun.COM 	uint8_t *netname;
8729832Samw@Sun.COM 	uint8_t *comment;
8738474SJose.Borrego@Sun.COM 	smb_share_t si;
8749832Samw@Sun.COM 	srvsvc_sd_t sd;
8758474SJose.Borrego@Sun.COM 	DWORD status;
8768474SJose.Borrego@Sun.COM 
8778474SJose.Borrego@Sun.COM 	status = smb_shr_get((char *)param->netname, &si);
8788474SJose.Borrego@Sun.COM 	if (status != NERR_Success) {
8798474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
8808474SJose.Borrego@Sun.COM 		param->status = status;
8818474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
8828474SJose.Borrego@Sun.COM 	}
8838474SJose.Borrego@Sun.COM 
8849832Samw@Sun.COM 	netname = (uint8_t *)NDR_STRDUP(mxa, si.shr_name);
8859832Samw@Sun.COM 	comment = (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt);
8869832Samw@Sun.COM 	info = NDR_NEW(mxa, srvsvc_netshare_getinfo_t);
8879832Samw@Sun.COM 
8889832Samw@Sun.COM 	if (netname == NULL || comment == NULL || info == NULL) {
8899832Samw@Sun.COM 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
8909832Samw@Sun.COM 		param->status = ERROR_NOT_ENOUGH_MEMORY;
8919832Samw@Sun.COM 		return (NDR_DRC_OK);
8929832Samw@Sun.COM 	}
8939832Samw@Sun.COM 
8948474SJose.Borrego@Sun.COM 	switch (param->level) {
8958474SJose.Borrego@Sun.COM 	case 0:
8969832Samw@Sun.COM 		info0 = &info->nsg_info0;
8979832Samw@Sun.COM 		info0->shi0_netname = netname;
8988474SJose.Borrego@Sun.COM 		param->result.ru.info0 = info0;
8998474SJose.Borrego@Sun.COM 		break;
9008474SJose.Borrego@Sun.COM 
9018474SJose.Borrego@Sun.COM 	case 1:
9029832Samw@Sun.COM 		info1 = &info->nsg_info1;
9039832Samw@Sun.COM 		info1->shi1_netname = netname;
9049832Samw@Sun.COM 		info1->shi1_comment = comment;
9058474SJose.Borrego@Sun.COM 		info1->shi1_type = si.shr_type;
9068474SJose.Borrego@Sun.COM 		param->result.ru.info1 = info1;
9078474SJose.Borrego@Sun.COM 		break;
9088474SJose.Borrego@Sun.COM 
9098474SJose.Borrego@Sun.COM 	case 2:
9109832Samw@Sun.COM 		info2 = &info->nsg_info2;
9119832Samw@Sun.COM 		info2->shi2_netname = netname;
9129832Samw@Sun.COM 		info2->shi2_comment = comment;
9138474SJose.Borrego@Sun.COM 		info2->shi2_path =
9148474SJose.Borrego@Sun.COM 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
9158474SJose.Borrego@Sun.COM 		info2->shi2_passwd = 0;
9168474SJose.Borrego@Sun.COM 		info2->shi2_type = si.shr_type;
9178474SJose.Borrego@Sun.COM 		info2->shi2_permissions = 0;
9188474SJose.Borrego@Sun.COM 		info2->shi2_max_uses = SHI_USES_UNLIMITED;
9198474SJose.Borrego@Sun.COM 		info2->shi2_current_uses = 0;
9208474SJose.Borrego@Sun.COM 		param->result.ru.info2 = info2;
9218474SJose.Borrego@Sun.COM 		break;
9228474SJose.Borrego@Sun.COM 
9239832Samw@Sun.COM 	case 501:
9249832Samw@Sun.COM 		info501 = &info->nsg_info501;
9259832Samw@Sun.COM 		info501->shi501_netname = netname;
9269832Samw@Sun.COM 		info501->shi501_comment = comment;
9279832Samw@Sun.COM 		info501->shi501_type = si.shr_type;
92810504SKeyur.Desai@Sun.COM 		info501->shi501_flags = srvsvc_get_share_flags(&si);
9299832Samw@Sun.COM 		param->result.ru.info501 = info501;
9309832Samw@Sun.COM 		break;
9319832Samw@Sun.COM 
9329832Samw@Sun.COM 	case 502:
9339832Samw@Sun.COM 		info502 = &info->nsg_info502;
9349832Samw@Sun.COM 		info502->shi502_netname = netname;
9359832Samw@Sun.COM 		info502->shi502_comment = comment;
9369832Samw@Sun.COM 		info502->shi502_path =
9379832Samw@Sun.COM 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
9389832Samw@Sun.COM 		info502->shi502_passwd = 0;
9399832Samw@Sun.COM 		info502->shi502_type = si.shr_type;
9409832Samw@Sun.COM 		info502->shi502_permissions = 0;
9419832Samw@Sun.COM 		info502->shi502_max_uses = SHI_USES_UNLIMITED;
9429832Samw@Sun.COM 		info502->shi502_current_uses = 0;
9439832Samw@Sun.COM 
9449832Samw@Sun.COM 		status = srvsvc_share_getsd(mxa, &si, &sd);
9459832Samw@Sun.COM 		if (status == ERROR_SUCCESS) {
9469832Samw@Sun.COM 			info502->shi502_reserved = sd.sd_size;
9479832Samw@Sun.COM 			info502->shi502_security_descriptor = sd.sd_buf;
9489832Samw@Sun.COM 		} else {
9499832Samw@Sun.COM 			info502->shi502_reserved = 0;
9509832Samw@Sun.COM 			info502->shi502_security_descriptor = NULL;
9518474SJose.Borrego@Sun.COM 		}
9528474SJose.Borrego@Sun.COM 
9539832Samw@Sun.COM 		param->result.ru.info502 = info502;
9549832Samw@Sun.COM 		break;
9559832Samw@Sun.COM 
9569832Samw@Sun.COM 	case 503:
9579832Samw@Sun.COM 		info503 = &info->nsg_info503;
9589832Samw@Sun.COM 		info503->shi503_netname = netname;
9599832Samw@Sun.COM 		info503->shi503_comment = comment;
9609832Samw@Sun.COM 		info503->shi503_path =
9619832Samw@Sun.COM 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
9629832Samw@Sun.COM 		info503->shi503_passwd = NULL;
9639832Samw@Sun.COM 		info503->shi503_type = si.shr_type;
9649832Samw@Sun.COM 		info503->shi503_permissions = 0;
9659832Samw@Sun.COM 		info503->shi503_max_uses = SHI_USES_UNLIMITED;
9669832Samw@Sun.COM 		info503->shi503_current_uses = 0;
9679832Samw@Sun.COM 		info503->shi503_servername = NULL;
9689832Samw@Sun.COM 
9699832Samw@Sun.COM 		status = srvsvc_share_getsd(mxa, &si, &sd);
9709832Samw@Sun.COM 		if (status == ERROR_SUCCESS) {
9719832Samw@Sun.COM 			info503->shi503_reserved = sd.sd_size;
9729832Samw@Sun.COM 			info503->shi503_security_descriptor = sd.sd_buf;
9739832Samw@Sun.COM 		} else {
9749832Samw@Sun.COM 			info503->shi503_reserved = 0;
9759832Samw@Sun.COM 			info503->shi503_security_descriptor = NULL;
9769832Samw@Sun.COM 		}
9779832Samw@Sun.COM 
9789832Samw@Sun.COM 		param->result.ru.info503 = info503;
9799832Samw@Sun.COM 		break;
9809832Samw@Sun.COM 
9819832Samw@Sun.COM 	case 1004:
9829832Samw@Sun.COM 		info1004 = &info->nsg_info1004;
9839832Samw@Sun.COM 		info1004->shi1004_comment = comment;
9849832Samw@Sun.COM 		param->result.ru.info1004 = info1004;
9858474SJose.Borrego@Sun.COM 		break;
9868474SJose.Borrego@Sun.COM 
9878474SJose.Borrego@Sun.COM 	case 1005:
9889832Samw@Sun.COM 		info1005 = &info->nsg_info1005;
98910504SKeyur.Desai@Sun.COM 		info1005->shi1005_flags = srvsvc_get_share_flags(&si);
9908474SJose.Borrego@Sun.COM 		param->result.ru.info1005 = info1005;
9918474SJose.Borrego@Sun.COM 		break;
9928474SJose.Borrego@Sun.COM 
9938474SJose.Borrego@Sun.COM 	case 1006:
9949832Samw@Sun.COM 		info1006 = &info->nsg_info1006;
9958474SJose.Borrego@Sun.COM 		info1006->shi1006_max_uses = SHI_USES_UNLIMITED;
9968474SJose.Borrego@Sun.COM 		param->result.ru.info1006 = info1006;
9978474SJose.Borrego@Sun.COM 		break;
9988474SJose.Borrego@Sun.COM 
9999832Samw@Sun.COM 	case 1501:
10009832Samw@Sun.COM 		info1501 = &info->nsg_info1501;
10019832Samw@Sun.COM 
10029832Samw@Sun.COM 		status = srvsvc_share_getsd(mxa, &si, &sd);
10039832Samw@Sun.COM 		if (status == ERROR_SUCCESS) {
10049832Samw@Sun.COM 			info503->shi503_reserved = sd.sd_size;
10059832Samw@Sun.COM 			info503->shi503_security_descriptor = sd.sd_buf;
10069832Samw@Sun.COM 		} else {
10079832Samw@Sun.COM 			info503->shi503_reserved = 0;
10089832Samw@Sun.COM 			info503->shi503_security_descriptor = NULL;
10098474SJose.Borrego@Sun.COM 		}
10108474SJose.Borrego@Sun.COM 
10119832Samw@Sun.COM 		param->result.ru.info1501 = info1501;
10128474SJose.Borrego@Sun.COM 		break;
10138474SJose.Borrego@Sun.COM 
10148474SJose.Borrego@Sun.COM 	default:
10158474SJose.Borrego@Sun.COM 		status = ERROR_ACCESS_DENIED;
10168474SJose.Borrego@Sun.COM 		break;
10178474SJose.Borrego@Sun.COM 	}
10188474SJose.Borrego@Sun.COM 
10198474SJose.Borrego@Sun.COM 	if (status != ERROR_SUCCESS)
10208474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
10218474SJose.Borrego@Sun.COM 	else
10228474SJose.Borrego@Sun.COM 		param->result.switch_value = param->level;
10238474SJose.Borrego@Sun.COM 
10248474SJose.Borrego@Sun.COM 	param->status = status;
10258474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
10268474SJose.Borrego@Sun.COM }
10278474SJose.Borrego@Sun.COM 
10289832Samw@Sun.COM static uint32_t
srvsvc_share_getsd(ndr_xa_t * mxa,smb_share_t * si,srvsvc_sd_t * sd)10299832Samw@Sun.COM srvsvc_share_getsd(ndr_xa_t *mxa, smb_share_t *si, srvsvc_sd_t *sd)
10309832Samw@Sun.COM {
10319832Samw@Sun.COM 	uint32_t status;
10329832Samw@Sun.COM 
10339832Samw@Sun.COM 	status = srvsvc_sd_get(si, NULL, &sd->sd_size);
10349832Samw@Sun.COM 	if (status != ERROR_SUCCESS) {
10359832Samw@Sun.COM 		if (status == ERROR_PATH_NOT_FOUND) {
10369832Samw@Sun.COM 			bzero(sd, sizeof (srvsvc_sd_t));
10379832Samw@Sun.COM 			status = ERROR_SUCCESS;
10389832Samw@Sun.COM 		}
10399832Samw@Sun.COM 
10409832Samw@Sun.COM 		return (status);
10419832Samw@Sun.COM 	}
10429832Samw@Sun.COM 
10439832Samw@Sun.COM 	if ((sd->sd_buf = NDR_MALLOC(mxa, sd->sd_size)) == NULL)
10449832Samw@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
10459832Samw@Sun.COM 
10469832Samw@Sun.COM 	status = srvsvc_sd_get(si, sd->sd_buf, NULL);
10479832Samw@Sun.COM 	if (status == ERROR_PATH_NOT_FOUND) {
10489832Samw@Sun.COM 		bzero(sd, sizeof (srvsvc_sd_t));
10499832Samw@Sun.COM 		status = ERROR_SUCCESS;
10509832Samw@Sun.COM 	}
10519832Samw@Sun.COM 
10529832Samw@Sun.COM 	return (status);
10539832Samw@Sun.COM }
10548474SJose.Borrego@Sun.COM 
10558474SJose.Borrego@Sun.COM /*
10568474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareSetInfo
10578474SJose.Borrego@Sun.COM  *
10588474SJose.Borrego@Sun.COM  * This call is made by SrvMgr to set share information.
10599832Samw@Sun.COM  * Only power users groups can manage shares.
10609832Samw@Sun.COM  *
10619832Samw@Sun.COM  * To avoid misleading errors, we don't report an error
10629832Samw@Sun.COM  * when a FS doesn't support ACLs on shares.
10638474SJose.Borrego@Sun.COM  *
10648474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
10658474SJose.Borrego@Sun.COM  */
10668474SJose.Borrego@Sun.COM static int
srvsvc_s_NetShareSetInfo(void * arg,ndr_xa_t * mxa)10678474SJose.Borrego@Sun.COM srvsvc_s_NetShareSetInfo(void *arg, ndr_xa_t *mxa)
10688474SJose.Borrego@Sun.COM {
10698474SJose.Borrego@Sun.COM 	struct mlsm_NetShareSetInfo *param = arg;
10709832Samw@Sun.COM 	struct mslm_NetShareInfo_0 *info0;
10719832Samw@Sun.COM 	struct mslm_NetShareInfo_1 *info1;
10729832Samw@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
10739832Samw@Sun.COM 	struct mslm_NetShareInfo_501 *info501;
10749832Samw@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
10759832Samw@Sun.COM 	struct mslm_NetShareInfo_503 *info503;
10769832Samw@Sun.COM 	struct mslm_NetShareInfo_1004 *info1004;
10779832Samw@Sun.COM 	struct mslm_NetShareInfo_1005 *info1005;
10789832Samw@Sun.COM 	struct mslm_NetShareInfo_1501 *info1501;
10799832Samw@Sun.COM 	static DWORD parm_err = 0;
10809832Samw@Sun.COM 	srvsvc_netshare_setinfo_t info;
10819832Samw@Sun.COM 	smb_share_t si;
10829832Samw@Sun.COM 	uint8_t *sdbuf;
10839832Samw@Sun.COM 	int32_t native_os;
10849832Samw@Sun.COM 	DWORD status;
10859832Samw@Sun.COM 
10869832Samw@Sun.COM 	native_os = ndr_native_os(mxa);
10879832Samw@Sun.COM 
10889832Samw@Sun.COM 	if (!ndr_is_poweruser(mxa)) {
10899832Samw@Sun.COM 		status = ERROR_ACCESS_DENIED;
10909832Samw@Sun.COM 		goto netsharesetinfo_exit;
10919832Samw@Sun.COM 	}
10929832Samw@Sun.COM 
10939832Samw@Sun.COM 	if (smb_shr_get((char *)param->netname, &si) != NERR_Success) {
10949832Samw@Sun.COM 		status = ERROR_INVALID_NETNAME;
10959832Samw@Sun.COM 		goto netsharesetinfo_exit;
10969832Samw@Sun.COM 	}
10979832Samw@Sun.COM 
10989832Samw@Sun.COM 	if (param->result.ru.nullptr == NULL) {
10999832Samw@Sun.COM 		status = ERROR_INVALID_PARAMETER;
11009832Samw@Sun.COM 		goto netsharesetinfo_exit;
11019832Samw@Sun.COM 	}
11029832Samw@Sun.COM 
11039832Samw@Sun.COM 	bzero(&info, sizeof (srvsvc_netshare_setinfo_t));
11049832Samw@Sun.COM 
11059832Samw@Sun.COM 	switch (param->level) {
11069832Samw@Sun.COM 	case 0:
11079832Samw@Sun.COM 		info0 = (struct mslm_NetShareInfo_0 *)param->result.ru.info0;
11089832Samw@Sun.COM 		info.nss_netname = (char *)info0->shi0_netname;
11099832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11109832Samw@Sun.COM 		break;
11119832Samw@Sun.COM 
11129832Samw@Sun.COM 	case 1:
11139832Samw@Sun.COM 		info1 = (struct mslm_NetShareInfo_1 *)param->result.ru.info1;
11149832Samw@Sun.COM 		info.nss_netname = (char *)info1->shi1_netname;
11159832Samw@Sun.COM 		info.nss_comment = (char *)info1->shi1_comment;
11169832Samw@Sun.COM 		info.nss_type = info1->shi1_type;
11179832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11189832Samw@Sun.COM 		break;
11199832Samw@Sun.COM 
11209832Samw@Sun.COM 	case 2:
11219832Samw@Sun.COM 		info2 = (struct mslm_NetShareInfo_2 *)param->result.ru.info2;
11229832Samw@Sun.COM 		info.nss_netname = (char *)info2->shi2_netname;
11239832Samw@Sun.COM 		info.nss_comment = (char *)info2->shi2_comment;
11249832Samw@Sun.COM 		info.nss_path = (char *)info2->shi2_path;
11259832Samw@Sun.COM 		info.nss_type = info2->shi2_type;
11269832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11279832Samw@Sun.COM 		break;
11289832Samw@Sun.COM 
11299832Samw@Sun.COM 	case 501:
11309832Samw@Sun.COM 		info501 = (struct mslm_NetShareInfo_501 *)
11319832Samw@Sun.COM 		    param->result.ru.info501;
11329832Samw@Sun.COM 		info.nss_netname = (char *)info501->shi501_netname;
11339832Samw@Sun.COM 		info.nss_comment = (char *)info501->shi501_comment;
11349832Samw@Sun.COM 		info.nss_type = info501->shi501_type;
11359832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
113610504SKeyur.Desai@Sun.COM 		if (status == ERROR_SUCCESS)
113710504SKeyur.Desai@Sun.COM 			status = srvsvc_update_share_flags(&si,
113810504SKeyur.Desai@Sun.COM 			    info501->shi501_flags);
11399832Samw@Sun.COM 		break;
11409832Samw@Sun.COM 
11419832Samw@Sun.COM 	case 502:
11429832Samw@Sun.COM 		info502 = (struct mslm_NetShareInfo_502 *)
11439832Samw@Sun.COM 		    param->result.ru.info502;
11449832Samw@Sun.COM 		info.nss_netname = (char *)info502->shi502_netname;
11459832Samw@Sun.COM 		info.nss_comment = (char *)info502->shi502_comment;
11469832Samw@Sun.COM 		info.nss_path = (char *)info502->shi502_path;
11479832Samw@Sun.COM 		info.nss_type = info502->shi502_type;
11489832Samw@Sun.COM 		info.nss_sd.sd_buf = info502->shi502_security_descriptor;
11499832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11509832Samw@Sun.COM 		break;
11519832Samw@Sun.COM 
11529832Samw@Sun.COM 	case 503:
11539832Samw@Sun.COM 		info503 = (struct mslm_NetShareInfo_503 *)
11549832Samw@Sun.COM 		    param->result.ru.info503;
11559832Samw@Sun.COM 		info.nss_netname = (char *)info503->shi503_netname;
11569832Samw@Sun.COM 		info.nss_comment = (char *)info503->shi503_comment;
11579832Samw@Sun.COM 		info.nss_path = (char *)info503->shi503_path;
11589832Samw@Sun.COM 		info.nss_type = info503->shi503_type;
11599832Samw@Sun.COM 		info.nss_sd.sd_buf = info503->shi503_security_descriptor;
11609832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11619832Samw@Sun.COM 		break;
11629832Samw@Sun.COM 
11639832Samw@Sun.COM 	case 1004:
11649832Samw@Sun.COM 		info1004 = (struct mslm_NetShareInfo_1004 *)
11659832Samw@Sun.COM 		    param->result.ru.info1004;
11669832Samw@Sun.COM 		info.nss_comment = (char *)info1004->shi1004_comment;
11679832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11689832Samw@Sun.COM 		break;
11699832Samw@Sun.COM 
11709832Samw@Sun.COM 	case 1005:
11719832Samw@Sun.COM 		info1005 = (struct mslm_NetShareInfo_1005 *)
11729832Samw@Sun.COM 		    param->result.ru.info1005;
11739832Samw@Sun.COM 		status = srvsvc_update_share_flags(&si,
11749832Samw@Sun.COM 		    info1005->shi1005_flags);
11759832Samw@Sun.COM 		break;
11769832Samw@Sun.COM 
11779832Samw@Sun.COM 	case 1006:
11789832Samw@Sun.COM 		/*
11799832Samw@Sun.COM 		 * We don't limit the maximum number of concurrent
11809832Samw@Sun.COM 		 * connections to a share.
11819832Samw@Sun.COM 		 */
11829832Samw@Sun.COM 		status = ERROR_SUCCESS;
11839832Samw@Sun.COM 		break;
11849832Samw@Sun.COM 
11859832Samw@Sun.COM 	case 1501:
11869832Samw@Sun.COM 		info1501 = (struct mslm_NetShareInfo_1501 *)
11879832Samw@Sun.COM 		    param->result.ru.info1501;
11889832Samw@Sun.COM 		sdbuf = info1501->shi1501_security_descriptor;
11899832Samw@Sun.COM 		status = ERROR_SUCCESS;
11909832Samw@Sun.COM 
11919832Samw@Sun.COM 		if (sdbuf != NULL) {
11929832Samw@Sun.COM 			status = srvsvc_sd_set(&si, sdbuf);
11939832Samw@Sun.COM 			if (status == ERROR_PATH_NOT_FOUND)
11949832Samw@Sun.COM 				status = ERROR_SUCCESS;
11959832Samw@Sun.COM 		}
11969832Samw@Sun.COM 		break;
11979832Samw@Sun.COM 
11989832Samw@Sun.COM 	default:
11999832Samw@Sun.COM 		status = ERROR_ACCESS_DENIED;
12009832Samw@Sun.COM 		break;
12019832Samw@Sun.COM 	}
12029832Samw@Sun.COM 
12039832Samw@Sun.COM netsharesetinfo_exit:
12049832Samw@Sun.COM 	if (status != ERROR_SUCCESS)
12059832Samw@Sun.COM 		bzero(param, sizeof (struct mlsm_NetShareSetInfo));
12069832Samw@Sun.COM 
12079832Samw@Sun.COM 	param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
12089832Samw@Sun.COM 	param->status = status;
12098474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
12108474SJose.Borrego@Sun.COM }
12118474SJose.Borrego@Sun.COM 
12129832Samw@Sun.COM static uint32_t
srvsvc_modify_share(smb_share_t * si,srvsvc_netshare_setinfo_t * info)12139832Samw@Sun.COM srvsvc_modify_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
12149832Samw@Sun.COM {
12159832Samw@Sun.COM 	uint32_t nerr = NERR_Success;
12169832Samw@Sun.COM 
12179832Samw@Sun.COM 	if (si->shr_flags & SMB_SHRF_TRANS)
12189832Samw@Sun.COM 		return (srvsvc_modify_transient_share(si, info));
12199832Samw@Sun.COM 
12209832Samw@Sun.COM 	if (info->nss_sd.sd_buf != NULL) {
12219832Samw@Sun.COM 		nerr = srvsvc_sd_set(si, info->nss_sd.sd_buf);
12229832Samw@Sun.COM 		if (nerr == ERROR_PATH_NOT_FOUND)
12239832Samw@Sun.COM 			nerr = NERR_Success;
12249832Samw@Sun.COM 	}
12259832Samw@Sun.COM 
12269832Samw@Sun.COM 	if ((nerr = srvsvc_sa_modify(si, info)) == NERR_Success)
12279832Samw@Sun.COM 		nerr = smb_shr_modify(si);
12289832Samw@Sun.COM 
12299832Samw@Sun.COM 	return (nerr);
12309832Samw@Sun.COM }
12319832Samw@Sun.COM 
12329832Samw@Sun.COM /*
12339832Samw@Sun.COM  * Update transient shares.  This includes autohome shares.
12349832Samw@Sun.COM  */
12359832Samw@Sun.COM static uint32_t
srvsvc_modify_transient_share(smb_share_t * si,srvsvc_netshare_setinfo_t * info)12369832Samw@Sun.COM srvsvc_modify_transient_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
12379832Samw@Sun.COM {
12389832Samw@Sun.COM 	uint32_t nerr;
12399832Samw@Sun.COM 
12409832Samw@Sun.COM 	if (info->nss_netname != NULL && info->nss_netname[0] != '\0' &&
124110966SJordan.Brown@Sun.COM 	    smb_strcasecmp(info->nss_netname, si->shr_name, 0) != 0) {
12429832Samw@Sun.COM 		nerr = smb_shr_rename(si->shr_name, info->nss_netname);
12439832Samw@Sun.COM 		if (nerr != NERR_Success)
12449832Samw@Sun.COM 			return (nerr);
12459832Samw@Sun.COM 
12469832Samw@Sun.COM 		(void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN);
12479832Samw@Sun.COM 	}
12489832Samw@Sun.COM 
12499832Samw@Sun.COM 	if ((info->nss_comment != NULL) &&
12509832Samw@Sun.COM 	    (strcmp(info->nss_comment, si->shr_cmnt) != 0)) {
12519832Samw@Sun.COM 		(void) strlcpy(si->shr_cmnt, info->nss_comment,
12529832Samw@Sun.COM 		    SMB_SHARE_CMNT_MAX);
12539832Samw@Sun.COM 
12549832Samw@Sun.COM 		if ((nerr = smb_shr_modify(si)) != NERR_Success)
12559832Samw@Sun.COM 			return (nerr);
12569832Samw@Sun.COM 	}
12579832Samw@Sun.COM 
12589832Samw@Sun.COM 	return (NERR_Success);
12599832Samw@Sun.COM }
12609832Samw@Sun.COM 
126110504SKeyur.Desai@Sun.COM /*
126210504SKeyur.Desai@Sun.COM  * srvsvc_update_share_flags
126310504SKeyur.Desai@Sun.COM  *
126410504SKeyur.Desai@Sun.COM  * This function updates flags for shares.
126510504SKeyur.Desai@Sun.COM  * Flags for Persistent shares are updated in both libshare and the local cache.
126610504SKeyur.Desai@Sun.COM  * Flags for Transient shares are updated only in the local cache.
126710504SKeyur.Desai@Sun.COM  */
12689832Samw@Sun.COM static uint32_t
srvsvc_update_share_flags(smb_share_t * si,uint32_t shi_flags)12699832Samw@Sun.COM srvsvc_update_share_flags(smb_share_t *si, uint32_t shi_flags)
12709832Samw@Sun.COM {
12719832Samw@Sun.COM 	uint32_t nerr = NERR_Success;
127210504SKeyur.Desai@Sun.COM 	uint32_t flag = 0;
127310504SKeyur.Desai@Sun.COM 	char *csc_value;
127410504SKeyur.Desai@Sun.COM 	char *abe_value = "false";
127510504SKeyur.Desai@Sun.COM 	nvlist_t *nvl;
127610504SKeyur.Desai@Sun.COM 	int err = 0;
127710504SKeyur.Desai@Sun.COM 
127810504SKeyur.Desai@Sun.COM 	if (shi_flags & SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM) {
127910504SKeyur.Desai@Sun.COM 		flag = SMB_SHRF_ABE;
128010504SKeyur.Desai@Sun.COM 		abe_value = "true";
128110504SKeyur.Desai@Sun.COM 	}
128210504SKeyur.Desai@Sun.COM 
128310504SKeyur.Desai@Sun.COM 	si->shr_flags &= ~SMB_SHRF_ABE;
128410504SKeyur.Desai@Sun.COM 	si->shr_flags |= flag;
12859832Samw@Sun.COM 
12869832Samw@Sun.COM 	switch ((shi_flags & CSC_MASK)) {
12879832Samw@Sun.COM 	case CSC_CACHE_AUTO_REINT:
128810504SKeyur.Desai@Sun.COM 		flag = SMB_SHRF_CSC_AUTO;
12899832Samw@Sun.COM 		break;
12909832Samw@Sun.COM 	case CSC_CACHE_VDO:
129110504SKeyur.Desai@Sun.COM 		flag = SMB_SHRF_CSC_VDO;
12929832Samw@Sun.COM 		break;
12939832Samw@Sun.COM 	case CSC_CACHE_NONE:
129410504SKeyur.Desai@Sun.COM 		flag = SMB_SHRF_CSC_DISABLED;
12959832Samw@Sun.COM 		break;
12969832Samw@Sun.COM 	case CSC_CACHE_MANUAL_REINT:
129710504SKeyur.Desai@Sun.COM 		flag = SMB_SHRF_CSC_MANUAL;
12989832Samw@Sun.COM 		break;
12999832Samw@Sun.COM 	default:
130010504SKeyur.Desai@Sun.COM 		return (NERR_InternalError);
13019832Samw@Sun.COM 	}
13029832Samw@Sun.COM 
13039832Samw@Sun.COM 	si->shr_flags &= ~SMB_SHRF_CSC_MASK;
130410504SKeyur.Desai@Sun.COM 	si->shr_flags |= flag;
13059832Samw@Sun.COM 
13069832Samw@Sun.COM 	if ((si->shr_flags & SMB_SHRF_TRANS) == 0) {
130710504SKeyur.Desai@Sun.COM 		csc_value = smb_shr_sa_csc_name(si);
130810504SKeyur.Desai@Sun.COM 
130910504SKeyur.Desai@Sun.COM 		if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
131010504SKeyur.Desai@Sun.COM 			return (NERR_InternalError);
131110504SKeyur.Desai@Sun.COM 
131210504SKeyur.Desai@Sun.COM 		err |= nvlist_add_string(nvl, SHOPT_CSC, csc_value);
131310504SKeyur.Desai@Sun.COM 		err |= nvlist_add_string(nvl, SHOPT_ABE, abe_value);
131410504SKeyur.Desai@Sun.COM 		if (err) {
131510504SKeyur.Desai@Sun.COM 			nvlist_free(nvl);
131610504SKeyur.Desai@Sun.COM 			return (NERR_InternalError);
131710504SKeyur.Desai@Sun.COM 		}
131810504SKeyur.Desai@Sun.COM 
131910504SKeyur.Desai@Sun.COM 		nerr = srvsvc_sa_setprop(si, nvl);
132010504SKeyur.Desai@Sun.COM 		nvlist_free(nvl);
132110504SKeyur.Desai@Sun.COM 
132210504SKeyur.Desai@Sun.COM 		if (nerr != NERR_Success)
13239832Samw@Sun.COM 			return (nerr);
13249832Samw@Sun.COM 	}
13259832Samw@Sun.COM 
13269832Samw@Sun.COM 	return (smb_shr_modify(si));
13279832Samw@Sun.COM }
13289832Samw@Sun.COM 
132910504SKeyur.Desai@Sun.COM static uint32_t
srvsvc_get_share_flags(smb_share_t * si)133010504SKeyur.Desai@Sun.COM srvsvc_get_share_flags(smb_share_t *si)
133110504SKeyur.Desai@Sun.COM {
133210504SKeyur.Desai@Sun.COM 	uint32_t flags = 0;
1333*12890SJoyce.McIntosh@Sun.COM 	boolean_t shortnames = B_TRUE;
133410504SKeyur.Desai@Sun.COM 
133510504SKeyur.Desai@Sun.COM 	switch (si->shr_flags & SMB_SHRF_CSC_MASK) {
133610504SKeyur.Desai@Sun.COM 	case SMB_SHRF_CSC_DISABLED:
133710504SKeyur.Desai@Sun.COM 		flags |= CSC_CACHE_NONE;
133810504SKeyur.Desai@Sun.COM 		break;
133910504SKeyur.Desai@Sun.COM 	case SMB_SHRF_CSC_AUTO:
134010504SKeyur.Desai@Sun.COM 		flags |= CSC_CACHE_AUTO_REINT;
134110504SKeyur.Desai@Sun.COM 		break;
134210504SKeyur.Desai@Sun.COM 	case SMB_SHRF_CSC_VDO:
134310504SKeyur.Desai@Sun.COM 		flags |= CSC_CACHE_VDO;
134410504SKeyur.Desai@Sun.COM 		break;
134510504SKeyur.Desai@Sun.COM 	case SMB_SHRF_CSC_MANUAL:
134610504SKeyur.Desai@Sun.COM 	default:
134710504SKeyur.Desai@Sun.COM 		/*
134810504SKeyur.Desai@Sun.COM 		 * Default to CSC_CACHE_MANUAL_REINT.
134910504SKeyur.Desai@Sun.COM 		 */
135010504SKeyur.Desai@Sun.COM 		break;
135110504SKeyur.Desai@Sun.COM 	}
135210504SKeyur.Desai@Sun.COM 
135310504SKeyur.Desai@Sun.COM 	if (si->shr_flags & SMB_SHRF_ABE)
135410504SKeyur.Desai@Sun.COM 		flags |= SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM;
135510504SKeyur.Desai@Sun.COM 
1356*12890SJoyce.McIntosh@Sun.COM 	/* if 'smb' zfs property: shortnames=disabled */
1357*12890SJoyce.McIntosh@Sun.COM 	if ((smb_kmod_shareinfo(si->shr_name, &shortnames) == 0) &&
1358*12890SJoyce.McIntosh@Sun.COM 	    (shortnames == B_FALSE)) {
1359*12890SJoyce.McIntosh@Sun.COM 		flags |= SHI1005_FLAGS_ALLOW_NAMESPACE_CACHING;
1360*12890SJoyce.McIntosh@Sun.COM 	}
1361*12890SJoyce.McIntosh@Sun.COM 
136210504SKeyur.Desai@Sun.COM 	return (flags);
136310504SKeyur.Desai@Sun.COM }
136410504SKeyur.Desai@Sun.COM 
13658474SJose.Borrego@Sun.COM /*
13668474SJose.Borrego@Sun.COM  * srvsvc_s_NetSessionEnum
13678474SJose.Borrego@Sun.COM  *
13688474SJose.Borrego@Sun.COM  * Level 1 request is made by (Server Manager (srvmgr) on NT Server when
13698474SJose.Borrego@Sun.COM  * the user info icon is selected.
13708474SJose.Borrego@Sun.COM  *
13718474SJose.Borrego@Sun.COM  * On success, the return value is NERR_Success.
13728474SJose.Borrego@Sun.COM  * On error, the return value can be one of the following error codes:
13738474SJose.Borrego@Sun.COM  *
13748474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED      The user does not have access to the requested
13758474SJose.Borrego@Sun.COM  *                          information.
13768474SJose.Borrego@Sun.COM  * ERROR_INVALID_LEVEL      The value specified for the level is invalid.
13778474SJose.Borrego@Sun.COM  * ERROR_INVALID_PARAMETER  The specified parameter is invalid.
13788474SJose.Borrego@Sun.COM  * ERROR_MORE_DATA          More entries are available. Specify a large
13798474SJose.Borrego@Sun.COM  *                          enough buffer to receive all entries.
13808474SJose.Borrego@Sun.COM  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
13818474SJose.Borrego@Sun.COM  * NERR_ClientNameNotFound  A session does not exist with the computer name.
13828474SJose.Borrego@Sun.COM  * NERR_InvalidComputer     The computer name is invalid.
13838474SJose.Borrego@Sun.COM  * NERR_UserNotFound        The user name could not be found.
13848474SJose.Borrego@Sun.COM  */
13858474SJose.Borrego@Sun.COM static int
srvsvc_s_NetSessionEnum(void * arg,ndr_xa_t * mxa)13868474SJose.Borrego@Sun.COM srvsvc_s_NetSessionEnum(void *arg, ndr_xa_t *mxa)
13878474SJose.Borrego@Sun.COM {
138810122SJordan.Brown@Sun.COM 	struct mslm_NetSessionEnum	*param = arg;
138910122SJordan.Brown@Sun.COM 	srvsvc_infonres_t		*info;
139010122SJordan.Brown@Sun.COM 	smb_netsvc_t			*ns;
139110122SJordan.Brown@Sun.COM 	smb_svcenum_t			se;
139210122SJordan.Brown@Sun.COM 	DWORD				status = ERROR_SUCCESS;
139310122SJordan.Brown@Sun.COM 
139410122SJordan.Brown@Sun.COM 	if (!ndr_is_admin(mxa)) {
139510122SJordan.Brown@Sun.COM 		status = ERROR_ACCESS_DENIED;
139610122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
139710122SJordan.Brown@Sun.COM 	}
139810122SJordan.Brown@Sun.COM 
139910122SJordan.Brown@Sun.COM 	if ((info = NDR_NEW(mxa, srvsvc_infonres_t)) == NULL) {
140010122SJordan.Brown@Sun.COM 		status = ERROR_NOT_ENOUGH_MEMORY;
140110122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
140210122SJordan.Brown@Sun.COM 	}
140310122SJordan.Brown@Sun.COM 
140410122SJordan.Brown@Sun.COM 	info->entriesread = 0;
140510122SJordan.Brown@Sun.COM 	info->entries = NULL;
140610122SJordan.Brown@Sun.COM 	param->result.level = param->level;
140710122SJordan.Brown@Sun.COM 	param->result.bufptr.p = info;
140810122SJordan.Brown@Sun.COM 
140910122SJordan.Brown@Sun.COM 	if ((param->total_entries = srvsvc_open_sessions()) == 0) {
141010122SJordan.Brown@Sun.COM 		param->resume_handle = NULL;
141110122SJordan.Brown@Sun.COM 		param->status = ERROR_SUCCESS;
14128474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
14138474SJose.Borrego@Sun.COM 	}
14148474SJose.Borrego@Sun.COM 
141510122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
141610122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_USER;
141710122SJordan.Brown@Sun.COM 	se.se_level = param->level;
141810122SJordan.Brown@Sun.COM 	se.se_ntotal = param->total_entries;
141910122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
142010122SJordan.Brown@Sun.COM 
142110122SJordan.Brown@Sun.COM 	if (param->resume_handle) {
142210122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
142310122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
142410122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
142510122SJordan.Brown@Sun.COM 	}
14268474SJose.Borrego@Sun.COM 
14278474SJose.Borrego@Sun.COM 	switch (param->level) {
14288474SJose.Borrego@Sun.COM 	case 0:
142910122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_0,
143010122SJordan.Brown@Sun.COM 		    se.se_nlimit);
14318474SJose.Borrego@Sun.COM 		break;
143210122SJordan.Brown@Sun.COM 	case 1:
143310122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_1,
143410122SJordan.Brown@Sun.COM 		    se.se_nlimit);
14359832Samw@Sun.COM 		break;
143610122SJordan.Brown@Sun.COM 	case 2:
143710122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_2,
143810122SJordan.Brown@Sun.COM 		    se.se_nlimit);
14399832Samw@Sun.COM 		break;
144010122SJordan.Brown@Sun.COM 	case 10:
144110122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_10,
144210122SJordan.Brown@Sun.COM 		    se.se_nlimit);
144310122SJordan.Brown@Sun.COM 		break;
14449832Samw@Sun.COM 	case 502:
144510122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_502,
144610122SJordan.Brown@Sun.COM 		    se.se_nlimit);
14479832Samw@Sun.COM 		break;
14488474SJose.Borrego@Sun.COM 	default:
14498474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetSessionEnum));
145010122SJordan.Brown@Sun.COM 		param->status = ERROR_INVALID_LEVEL;
14518474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
14528474SJose.Borrego@Sun.COM 	}
14538474SJose.Borrego@Sun.COM 
145410122SJordan.Brown@Sun.COM 	if (info->entries == NULL) {
145510122SJordan.Brown@Sun.COM 		status = ERROR_NOT_ENOUGH_MEMORY;
145610122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
145710122SJordan.Brown@Sun.COM 	}
145810122SJordan.Brown@Sun.COM 
145910122SJordan.Brown@Sun.COM 	if ((ns = smb_kmod_enum_init(&se)) == NULL) {
146010122SJordan.Brown@Sun.COM 		status = ERROR_NOT_ENOUGH_MEMORY;
146110122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
146210122SJordan.Brown@Sun.COM 	}
146310122SJordan.Brown@Sun.COM 
146410122SJordan.Brown@Sun.COM 	status = srvsvc_NetSessionEnumCommon(mxa, info, ns, &se);
146510122SJordan.Brown@Sun.COM 	smb_kmod_enum_fini(ns);
146610122SJordan.Brown@Sun.COM 
146710122SJordan.Brown@Sun.COM 	if (status != ERROR_SUCCESS)
146810122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
146910122SJordan.Brown@Sun.COM 
147010122SJordan.Brown@Sun.COM 	if (param->resume_handle &&
147110122SJordan.Brown@Sun.COM 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
147210122SJordan.Brown@Sun.COM 		if (se.se_resume < param->total_entries) {
147310122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
147410122SJordan.Brown@Sun.COM 			status = ERROR_MORE_DATA;
147510122SJordan.Brown@Sun.COM 		}
147610122SJordan.Brown@Sun.COM 	}
147710122SJordan.Brown@Sun.COM 
147810122SJordan.Brown@Sun.COM 	param->total_entries = info->entriesread;
147910122SJordan.Brown@Sun.COM 	param->status = status;
148010122SJordan.Brown@Sun.COM 	return (NDR_DRC_OK);
148110122SJordan.Brown@Sun.COM 
148210122SJordan.Brown@Sun.COM srvsvc_netsessionenum_error:
148310122SJordan.Brown@Sun.COM 	bzero(param, sizeof (struct mslm_NetSessionEnum));
14848474SJose.Borrego@Sun.COM 	param->status = status;
14858474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
14868474SJose.Borrego@Sun.COM }
14878474SJose.Borrego@Sun.COM 
148810122SJordan.Brown@Sun.COM static uint32_t
srvsvc_NetSessionEnumCommon(ndr_xa_t * mxa,srvsvc_infonres_t * info,smb_netsvc_t * ns,smb_svcenum_t * se)148910122SJordan.Brown@Sun.COM srvsvc_NetSessionEnumCommon(ndr_xa_t *mxa, srvsvc_infonres_t *info,
149010122SJordan.Brown@Sun.COM     smb_netsvc_t *ns, smb_svcenum_t *se)
14918474SJose.Borrego@Sun.COM {
149210122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_0	*info0 = info->entries;
149310122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_1	*info1 = info->entries;
149410122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_2	*info2 = info->entries;
149510122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_10	*info10 = info->entries;
149610122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_502	*info502 = info->entries;
149710122SJordan.Brown@Sun.COM 	smb_netsvcitem_t		*item;
149810122SJordan.Brown@Sun.COM 	smb_netuserinfo_t		*user;
149910122SJordan.Brown@Sun.COM 	char				*workstation;
150010122SJordan.Brown@Sun.COM 	char				account[MAXNAMELEN];
150110122SJordan.Brown@Sun.COM 	char				ipaddr_buf[INET6_ADDRSTRLEN];
150210122SJordan.Brown@Sun.COM 	uint32_t			logon_time;
150310122SJordan.Brown@Sun.COM 	uint32_t			flags;
150410122SJordan.Brown@Sun.COM 	uint32_t			entries_read = 0;
150510122SJordan.Brown@Sun.COM 
150610122SJordan.Brown@Sun.COM 	if (smb_kmod_enum(ns) != 0)
150710122SJordan.Brown@Sun.COM 		return (ERROR_INTERNAL_ERROR);
150810122SJordan.Brown@Sun.COM 
150910122SJordan.Brown@Sun.COM 	item = list_head(&ns->ns_list);
151010122SJordan.Brown@Sun.COM 	while (item != NULL) {
151110122SJordan.Brown@Sun.COM 		user = &item->nsi_un.nsi_user;
151210122SJordan.Brown@Sun.COM 
151310122SJordan.Brown@Sun.COM 		workstation = user->ui_workstation;
15148474SJose.Borrego@Sun.COM 		if (workstation == NULL || *workstation == '\0') {
151510122SJordan.Brown@Sun.COM 			(void) smb_inet_ntop(&user->ui_ipaddr, ipaddr_buf,
151610122SJordan.Brown@Sun.COM 			    SMB_IPSTRLEN(user->ui_ipaddr.a_family));
15178474SJose.Borrego@Sun.COM 			workstation = ipaddr_buf;
15188474SJose.Borrego@Sun.COM 		}
15198474SJose.Borrego@Sun.COM 
15208474SJose.Borrego@Sun.COM 		(void) snprintf(account, MAXNAMELEN, "%s\\%s",
152110122SJordan.Brown@Sun.COM 		    user->ui_domain, user->ui_account);
152210122SJordan.Brown@Sun.COM 
152310122SJordan.Brown@Sun.COM 		logon_time = time(0) - user->ui_logon_time;
152410122SJordan.Brown@Sun.COM 		flags = (user->ui_flags & SMB_ATF_GUEST) ? SESS_GUEST : 0;
152510122SJordan.Brown@Sun.COM 
152610122SJordan.Brown@Sun.COM 		switch (se->se_level) {
152710122SJordan.Brown@Sun.COM 		case 0:
152810122SJordan.Brown@Sun.COM 			info0->sesi0_cname = NDR_STRDUP(mxa, workstation);
152910122SJordan.Brown@Sun.COM 			if (info0->sesi0_cname == NULL)
153010122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
153110122SJordan.Brown@Sun.COM 			++info0;
153210122SJordan.Brown@Sun.COM 			break;
153310122SJordan.Brown@Sun.COM 
153410122SJordan.Brown@Sun.COM 		case 1:
153510122SJordan.Brown@Sun.COM 			info1->sesi1_cname = NDR_STRDUP(mxa, workstation);
153610122SJordan.Brown@Sun.COM 			info1->sesi1_uname = NDR_STRDUP(mxa, account);
153710122SJordan.Brown@Sun.COM 
153810122SJordan.Brown@Sun.COM 			if (info1->sesi1_cname == NULL ||
153910122SJordan.Brown@Sun.COM 			    info1->sesi1_uname == NULL)
154010122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
154110122SJordan.Brown@Sun.COM 
154210122SJordan.Brown@Sun.COM 			info1->sesi1_nopens = user->ui_numopens;
154310122SJordan.Brown@Sun.COM 			info1->sesi1_time = logon_time;
154410122SJordan.Brown@Sun.COM 			info1->sesi1_itime = 0;
154510122SJordan.Brown@Sun.COM 			info1->sesi1_uflags = flags;
154610122SJordan.Brown@Sun.COM 			++info1;
154710122SJordan.Brown@Sun.COM 			break;
154810122SJordan.Brown@Sun.COM 
154910122SJordan.Brown@Sun.COM 		case 2:
155010122SJordan.Brown@Sun.COM 			info2->sesi2_cname = NDR_STRDUP(mxa, workstation);
155110122SJordan.Brown@Sun.COM 			info2->sesi2_uname = NDR_STRDUP(mxa, account);
155210122SJordan.Brown@Sun.COM 
155310122SJordan.Brown@Sun.COM 			if (info2->sesi2_cname == NULL ||
155410122SJordan.Brown@Sun.COM 			    info2->sesi2_uname == NULL)
155510122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
155610122SJordan.Brown@Sun.COM 
155710122SJordan.Brown@Sun.COM 			info2->sesi2_nopens = user->ui_numopens;
155810122SJordan.Brown@Sun.COM 			info2->sesi2_time = logon_time;
155910122SJordan.Brown@Sun.COM 			info2->sesi2_itime = 0;
156010122SJordan.Brown@Sun.COM 			info2->sesi2_uflags = flags;
156110122SJordan.Brown@Sun.COM 			info2->sesi2_cltype_name = (uint8_t *)"";
156210122SJordan.Brown@Sun.COM 			++info2;
156310122SJordan.Brown@Sun.COM 			break;
156410122SJordan.Brown@Sun.COM 
156510122SJordan.Brown@Sun.COM 		case 10:
156610122SJordan.Brown@Sun.COM 			info10->sesi10_cname = NDR_STRDUP(mxa, workstation);
156710122SJordan.Brown@Sun.COM 			info10->sesi10_uname = NDR_STRDUP(mxa, account);
156810122SJordan.Brown@Sun.COM 
156910122SJordan.Brown@Sun.COM 			if (info10->sesi10_cname == NULL ||
157010122SJordan.Brown@Sun.COM 			    info10->sesi10_uname == NULL)
157110122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
157210122SJordan.Brown@Sun.COM 
157310122SJordan.Brown@Sun.COM 			info10->sesi10_time = logon_time;
157410122SJordan.Brown@Sun.COM 			info10->sesi10_itime = 0;
157510122SJordan.Brown@Sun.COM 			++info10;
157610122SJordan.Brown@Sun.COM 			break;
157710122SJordan.Brown@Sun.COM 
157810122SJordan.Brown@Sun.COM 		case 502:
157910122SJordan.Brown@Sun.COM 			info502->sesi502_cname = NDR_STRDUP(mxa, workstation);
158010122SJordan.Brown@Sun.COM 			info502->sesi502_uname = NDR_STRDUP(mxa, account);
158110122SJordan.Brown@Sun.COM 
158210122SJordan.Brown@Sun.COM 			if (info502->sesi502_cname == NULL ||
158310122SJordan.Brown@Sun.COM 			    info502->sesi502_uname == NULL)
158410122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
158510122SJordan.Brown@Sun.COM 
158610122SJordan.Brown@Sun.COM 			info502->sesi502_nopens = user->ui_numopens;
158710122SJordan.Brown@Sun.COM 			info502->sesi502_time = logon_time;
158810122SJordan.Brown@Sun.COM 			info502->sesi502_itime = 0;
158910122SJordan.Brown@Sun.COM 			info502->sesi502_uflags = flags;
159010122SJordan.Brown@Sun.COM 			info502->sesi502_cltype_name = (uint8_t *)"";
159110122SJordan.Brown@Sun.COM 			info502->sesi502_transport = (uint8_t *)"";
159210122SJordan.Brown@Sun.COM 			++info502;
159310122SJordan.Brown@Sun.COM 			break;
159410122SJordan.Brown@Sun.COM 
159510122SJordan.Brown@Sun.COM 		default:
159610122SJordan.Brown@Sun.COM 			return (ERROR_INVALID_LEVEL);
15978474SJose.Borrego@Sun.COM 		}
15988474SJose.Borrego@Sun.COM 
159910122SJordan.Brown@Sun.COM 		++entries_read;
160010122SJordan.Brown@Sun.COM 		item = list_next(&ns->ns_list, item);
16019832Samw@Sun.COM 	}
16029832Samw@Sun.COM 
160310122SJordan.Brown@Sun.COM 	info->entriesread = entries_read;
16049832Samw@Sun.COM 	return (ERROR_SUCCESS);
16059832Samw@Sun.COM }
16069832Samw@Sun.COM 
16079832Samw@Sun.COM /*
16088474SJose.Borrego@Sun.COM  * srvsvc_s_NetSessionDel
16098474SJose.Borrego@Sun.COM  *
16108474SJose.Borrego@Sun.COM  * Ends a network session between a server and a workstation.
16118474SJose.Borrego@Sun.COM  * On NT only members of the Administrators or Account Operators
16128474SJose.Borrego@Sun.COM  * local groups are permitted to use NetSessionDel.
16138474SJose.Borrego@Sun.COM  *
161410122SJordan.Brown@Sun.COM  * If unc_clientname is NULL, all sessions associated with the
161510122SJordan.Brown@Sun.COM  * specified user will be disconnected.
161610122SJordan.Brown@Sun.COM  *
161710122SJordan.Brown@Sun.COM  * If username is NULL, all sessions from the specified client
161810122SJordan.Brown@Sun.COM  * will be disconnected.
161910122SJordan.Brown@Sun.COM  *
16208474SJose.Borrego@Sun.COM  * Return Values
162110122SJordan.Brown@Sun.COM  * On success, the return value is NERR_Success/ERROR_SUCCESS.
162210122SJordan.Brown@Sun.COM  * On failure, the return value can be one of the following errors:
16238474SJose.Borrego@Sun.COM  *
16248474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED 		The user does not have access to the
162510122SJordan.Brown@Sun.COM  * 				requested information.
16268474SJose.Borrego@Sun.COM  * ERROR_INVALID_PARAMETER	The specified parameter is invalid.
16278474SJose.Borrego@Sun.COM  * ERROR_NOT_ENOUGH_MEMORY	Insufficient memory is available.
16288474SJose.Borrego@Sun.COM  * NERR_ClientNameNotFound	A session does not exist with that
162910122SJordan.Brown@Sun.COM  *				computer name.
16308474SJose.Borrego@Sun.COM  */
16318474SJose.Borrego@Sun.COM static int
srvsvc_s_NetSessionDel(void * arg,ndr_xa_t * mxa)16328474SJose.Borrego@Sun.COM srvsvc_s_NetSessionDel(void *arg, ndr_xa_t *mxa)
16338474SJose.Borrego@Sun.COM {
163410122SJordan.Brown@Sun.COM 	static struct {
163510122SJordan.Brown@Sun.COM 		int errnum;
163610122SJordan.Brown@Sun.COM 		int nerr;
163710122SJordan.Brown@Sun.COM 	} errmap[] = {
163810122SJordan.Brown@Sun.COM 		0,	ERROR_SUCCESS,
163910122SJordan.Brown@Sun.COM 		EACCES,	ERROR_ACCESS_DENIED,
164010122SJordan.Brown@Sun.COM 		EPERM,	ERROR_ACCESS_DENIED,
164110122SJordan.Brown@Sun.COM 		EINVAL,	ERROR_INVALID_PARAMETER,
164210122SJordan.Brown@Sun.COM 		ENOMEM,	ERROR_NOT_ENOUGH_MEMORY,
164310122SJordan.Brown@Sun.COM 		ENOENT,	NERR_ClientNameNotFound
164410122SJordan.Brown@Sun.COM 	};
164510122SJordan.Brown@Sun.COM 
16468474SJose.Borrego@Sun.COM 	struct mslm_NetSessionDel *param = arg;
164710122SJordan.Brown@Sun.COM 	int	i;
164810122SJordan.Brown@Sun.COM 	int	rc;
164910122SJordan.Brown@Sun.COM 
165010122SJordan.Brown@Sun.COM 	if (!ndr_is_admin(mxa)) {
16518474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
16528474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
16538474SJose.Borrego@Sun.COM 	}
16548474SJose.Borrego@Sun.COM 
165510122SJordan.Brown@Sun.COM 	rc = smb_kmod_session_close((char *)param->unc_clientname,
165610122SJordan.Brown@Sun.COM 	    (char *)param->username);
165710122SJordan.Brown@Sun.COM 
165810122SJordan.Brown@Sun.COM 	for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) {
165910122SJordan.Brown@Sun.COM 		if (rc == errmap[i].errnum) {
166010122SJordan.Brown@Sun.COM 			param->status = errmap[i].nerr;
166110122SJordan.Brown@Sun.COM 			return (NDR_DRC_OK);
166210122SJordan.Brown@Sun.COM 		}
166310122SJordan.Brown@Sun.COM 	}
166410122SJordan.Brown@Sun.COM 
166510122SJordan.Brown@Sun.COM 	param->status = ERROR_INTERNAL_ERROR;
16668474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
16678474SJose.Borrego@Sun.COM }
16688474SJose.Borrego@Sun.COM 
16698474SJose.Borrego@Sun.COM static int
srvsvc_s_NetServerGetInfo(void * arg,ndr_xa_t * mxa)16708474SJose.Borrego@Sun.COM srvsvc_s_NetServerGetInfo(void *arg, ndr_xa_t *mxa)
16718474SJose.Borrego@Sun.COM {
16728474SJose.Borrego@Sun.COM 	struct mslm_NetServerGetInfo *param = arg;
16738474SJose.Borrego@Sun.COM 	struct mslm_SERVER_INFO_100 *info100;
16748474SJose.Borrego@Sun.COM 	struct mslm_SERVER_INFO_101 *info101;
16758474SJose.Borrego@Sun.COM 	struct mslm_SERVER_INFO_102 *info102;
16769832Samw@Sun.COM 	struct mslm_SERVER_INFO_502 *info502;
16779832Samw@Sun.COM 	struct mslm_SERVER_INFO_503 *info503;
16788474SJose.Borrego@Sun.COM 	char sys_comment[SMB_PI_MAX_COMMENT];
16798474SJose.Borrego@Sun.COM 	char hostname[NETBIOS_NAME_SZ];
168011963SAfshin.Ardakani@Sun.COM 	smb_version_t version;
16818474SJose.Borrego@Sun.COM 
16828474SJose.Borrego@Sun.COM 	if (smb_getnetbiosname(hostname, sizeof (hostname)) != 0) {
16838474SJose.Borrego@Sun.COM netservergetinfo_no_memory:
16848474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetServerGetInfo));
16858474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
16868474SJose.Borrego@Sun.COM 	}
16878474SJose.Borrego@Sun.COM 
16888474SJose.Borrego@Sun.COM 	(void) smb_config_getstr(SMB_CI_SYS_CMNT, sys_comment,
16898474SJose.Borrego@Sun.COM 	    sizeof (sys_comment));
16908474SJose.Borrego@Sun.COM 	if (*sys_comment == '\0')
16918474SJose.Borrego@Sun.COM 		(void) strcpy(sys_comment, " ");
16928474SJose.Borrego@Sun.COM 
169311963SAfshin.Ardakani@Sun.COM 	smb_config_get_version(&version);
169411963SAfshin.Ardakani@Sun.COM 
16958474SJose.Borrego@Sun.COM 	switch (param->level) {
16968474SJose.Borrego@Sun.COM 	case 100:
16978474SJose.Borrego@Sun.COM 		info100 = NDR_NEW(mxa, struct mslm_SERVER_INFO_100);
16988474SJose.Borrego@Sun.COM 		if (info100 == NULL)
16998474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
17008474SJose.Borrego@Sun.COM 
17018474SJose.Borrego@Sun.COM 		bzero(info100, sizeof (struct mslm_SERVER_INFO_100));
17028474SJose.Borrego@Sun.COM 		info100->sv100_platform_id = SV_PLATFORM_ID_NT;
17038474SJose.Borrego@Sun.COM 		info100->sv100_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
17048474SJose.Borrego@Sun.COM 		if (info100->sv100_name == NULL)
17058474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
17068474SJose.Borrego@Sun.COM 
17078474SJose.Borrego@Sun.COM 		param->result.bufptr.bufptr100 = info100;
17088474SJose.Borrego@Sun.COM 		break;
17098474SJose.Borrego@Sun.COM 
17108474SJose.Borrego@Sun.COM 	case 101:
17118474SJose.Borrego@Sun.COM 		info101 = NDR_NEW(mxa, struct mslm_SERVER_INFO_101);
17128474SJose.Borrego@Sun.COM 		if (info101 == NULL)
17138474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
17148474SJose.Borrego@Sun.COM 
17158474SJose.Borrego@Sun.COM 		bzero(info101, sizeof (struct mslm_SERVER_INFO_101));
17168474SJose.Borrego@Sun.COM 		info101->sv101_platform_id = SV_PLATFORM_ID_NT;
171711963SAfshin.Ardakani@Sun.COM 		info101->sv101_version_major = version.sv_major;
171811963SAfshin.Ardakani@Sun.COM 		info101->sv101_version_minor = version.sv_minor;
171911337SWilliam.Krier@Sun.COM 		info101->sv101_type = SV_TYPE_DEFAULT;
17208474SJose.Borrego@Sun.COM 		info101->sv101_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
17218474SJose.Borrego@Sun.COM 		info101->sv101_comment
17228474SJose.Borrego@Sun.COM 		    = (uint8_t *)NDR_STRDUP(mxa, sys_comment);
17238474SJose.Borrego@Sun.COM 
17248474SJose.Borrego@Sun.COM 		if (info101->sv101_name == NULL ||
17258474SJose.Borrego@Sun.COM 		    info101->sv101_comment == NULL)
17268474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
17278474SJose.Borrego@Sun.COM 
17288474SJose.Borrego@Sun.COM 		param->result.bufptr.bufptr101 = info101;
17298474SJose.Borrego@Sun.COM 		break;
17308474SJose.Borrego@Sun.COM 
17318474SJose.Borrego@Sun.COM 	case 102:
17328474SJose.Borrego@Sun.COM 		info102 = NDR_NEW(mxa, struct mslm_SERVER_INFO_102);
17338474SJose.Borrego@Sun.COM 		if (info102 == NULL)
17348474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
17358474SJose.Borrego@Sun.COM 
17368474SJose.Borrego@Sun.COM 		bzero(info102, sizeof (struct mslm_SERVER_INFO_102));
17378474SJose.Borrego@Sun.COM 		info102->sv102_platform_id = SV_PLATFORM_ID_NT;
173811963SAfshin.Ardakani@Sun.COM 		info102->sv102_version_major = version.sv_major;
173911963SAfshin.Ardakani@Sun.COM 		info102->sv102_version_minor = version.sv_minor;
174011337SWilliam.Krier@Sun.COM 		info102->sv102_type = SV_TYPE_DEFAULT;
17418474SJose.Borrego@Sun.COM 		info102->sv102_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
17428474SJose.Borrego@Sun.COM 		info102->sv102_comment
17438474SJose.Borrego@Sun.COM 		    = (uint8_t *)NDR_STRDUP(mxa, sys_comment);
17448474SJose.Borrego@Sun.COM 
17458474SJose.Borrego@Sun.COM 		/*
17468474SJose.Borrego@Sun.COM 		 * The following level 102 fields are defaulted to zero
17478474SJose.Borrego@Sun.COM 		 * by virtue of the call to bzero above.
17488474SJose.Borrego@Sun.COM 		 *
17498474SJose.Borrego@Sun.COM 		 * sv102_users
17508474SJose.Borrego@Sun.COM 		 * sv102_disc
17518474SJose.Borrego@Sun.COM 		 * sv102_hidden
17528474SJose.Borrego@Sun.COM 		 * sv102_announce
17538474SJose.Borrego@Sun.COM 		 * sv102_anndelta
17548474SJose.Borrego@Sun.COM 		 * sv102_licenses
17558474SJose.Borrego@Sun.COM 		 * sv102_userpath
17568474SJose.Borrego@Sun.COM 		 */
17578474SJose.Borrego@Sun.COM 		if (info102->sv102_name == NULL ||
17588474SJose.Borrego@Sun.COM 		    info102->sv102_comment == NULL)
17598474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
17608474SJose.Borrego@Sun.COM 
17618474SJose.Borrego@Sun.COM 		param->result.bufptr.bufptr102 = info102;
17628474SJose.Borrego@Sun.COM 		break;
17638474SJose.Borrego@Sun.COM 
17649832Samw@Sun.COM 	case 502:
17659832Samw@Sun.COM 		info502 = NDR_NEW(mxa, struct mslm_SERVER_INFO_502);
17669832Samw@Sun.COM 		if (info502 == NULL)
17679832Samw@Sun.COM 			goto netservergetinfo_no_memory;
17689832Samw@Sun.COM 
17699832Samw@Sun.COM 		bzero(info502, sizeof (struct mslm_SERVER_INFO_502));
17709832Samw@Sun.COM 		param->result.bufptr.bufptr502 = info502;
17719832Samw@Sun.COM #ifdef SRVSVC_SATISFY_SMBTORTURE
17729832Samw@Sun.COM 		break;
17739832Samw@Sun.COM #else
17749832Samw@Sun.COM 		param->result.level = param->level;
17759832Samw@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
17769832Samw@Sun.COM 		return (NDR_DRC_OK);
17779832Samw@Sun.COM #endif /* SRVSVC_SATISFY_SMBTORTURE */
17789832Samw@Sun.COM 
17799832Samw@Sun.COM 	case 503:
17809832Samw@Sun.COM 		info503 = NDR_NEW(mxa, struct mslm_SERVER_INFO_503);
17819832Samw@Sun.COM 		if (info503 == NULL)
17829832Samw@Sun.COM 			goto netservergetinfo_no_memory;
17839832Samw@Sun.COM 
17849832Samw@Sun.COM 		bzero(info503, sizeof (struct mslm_SERVER_INFO_503));
17859832Samw@Sun.COM 		param->result.bufptr.bufptr503 = info503;
17869832Samw@Sun.COM #ifdef SRVSVC_SATISFY_SMBTORTURE
17879832Samw@Sun.COM 		break;
17889832Samw@Sun.COM #else
17899832Samw@Sun.COM 		param->result.level = param->level;
17909832Samw@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
17919832Samw@Sun.COM 		return (NDR_DRC_OK);
17929832Samw@Sun.COM #endif /* SRVSVC_SATISFY_SMBTORTURE */
17939832Samw@Sun.COM 
17948474SJose.Borrego@Sun.COM 	default:
17958474SJose.Borrego@Sun.COM 		bzero(&param->result,
17968474SJose.Borrego@Sun.COM 		    sizeof (struct mslm_NetServerGetInfo_result));
17978474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
17988474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
17998474SJose.Borrego@Sun.COM 	}
18008474SJose.Borrego@Sun.COM 
18018474SJose.Borrego@Sun.COM 	param->result.level = param->level;
18029832Samw@Sun.COM 	param->status = ERROR_SUCCESS;
18038474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
18048474SJose.Borrego@Sun.COM }
18058474SJose.Borrego@Sun.COM 
18068474SJose.Borrego@Sun.COM /*
18078474SJose.Borrego@Sun.COM  * NetRemoteTOD
18088474SJose.Borrego@Sun.COM  *
18098474SJose.Borrego@Sun.COM  * Returns information about the time of day on this server.
18108474SJose.Borrego@Sun.COM  *
18118474SJose.Borrego@Sun.COM  * typedef struct _TIME_OF_DAY_INFO {
18128474SJose.Borrego@Sun.COM  *	DWORD tod_elapsedt;  // seconds since 00:00:00 January 1 1970 GMT
18138474SJose.Borrego@Sun.COM  *	DWORD tod_msecs;     // arbitrary milliseconds (since reset)
18148474SJose.Borrego@Sun.COM  *	DWORD tod_hours;     // current hour [0-23]
18158474SJose.Borrego@Sun.COM  *	DWORD tod_mins;      // current minute [0-59]
18168474SJose.Borrego@Sun.COM  *	DWORD tod_secs;      // current second [0-59]
18178474SJose.Borrego@Sun.COM  *	DWORD tod_hunds;     // current hundredth (0.01) second [0-99]
18188474SJose.Borrego@Sun.COM  *	LONG tod_timezone;   // time zone of the server
18198474SJose.Borrego@Sun.COM  *	DWORD tod_tinterval; // clock tick time interval
18208474SJose.Borrego@Sun.COM  *	DWORD tod_day;       // day of the month [1-31]
18218474SJose.Borrego@Sun.COM  *	DWORD tod_month;     // month of the year [1-12]
18228474SJose.Borrego@Sun.COM  *	DWORD tod_year;      // current year
18238474SJose.Borrego@Sun.COM  *	DWORD tod_weekday;   // day of the week since Sunday [0-6]
18248474SJose.Borrego@Sun.COM  * } TIME_OF_DAY_INFO;
18258474SJose.Borrego@Sun.COM  *
18268474SJose.Borrego@Sun.COM  * The time zone of the server is calculated in minutes from Greenwich
18278474SJose.Borrego@Sun.COM  * Mean Time (GMT). For time zones west of Greenwich, the value is
18288474SJose.Borrego@Sun.COM  * positive; for time zones east of Greenwich, the value is negative.
18298474SJose.Borrego@Sun.COM  * A value of -1 indicates that the time zone is undefined.
18308474SJose.Borrego@Sun.COM  *
183110966SJordan.Brown@Sun.COM  * Determine offset from GMT. If daylight saving time use altzone,
183210966SJordan.Brown@Sun.COM  * otherwise use timezone.
183310966SJordan.Brown@Sun.COM  *
18348474SJose.Borrego@Sun.COM  * The clock tick value represents a resolution of one ten-thousandth
18358474SJose.Borrego@Sun.COM  * (0.0001) second.
18368474SJose.Borrego@Sun.COM  */
18378474SJose.Borrego@Sun.COM static int
srvsvc_s_NetRemoteTOD(void * arg,ndr_xa_t * mxa)18388474SJose.Borrego@Sun.COM srvsvc_s_NetRemoteTOD(void *arg, ndr_xa_t *mxa)
18398474SJose.Borrego@Sun.COM {
18408474SJose.Borrego@Sun.COM 	struct mslm_NetRemoteTOD *param = arg;
18418474SJose.Borrego@Sun.COM 	struct mslm_TIME_OF_DAY_INFO *tod;
18428474SJose.Borrego@Sun.COM 	struct timeval		time_val;
18438474SJose.Borrego@Sun.COM 	struct tm		tm;
184410966SJordan.Brown@Sun.COM 	time_t			gmtoff;
184510966SJordan.Brown@Sun.COM 
18468474SJose.Borrego@Sun.COM 
18478474SJose.Borrego@Sun.COM 	(void) gettimeofday(&time_val, 0);
18488474SJose.Borrego@Sun.COM 	(void) gmtime_r(&time_val.tv_sec, &tm);
18498474SJose.Borrego@Sun.COM 
18508474SJose.Borrego@Sun.COM 	tod = NDR_NEW(mxa, struct mslm_TIME_OF_DAY_INFO);
18518474SJose.Borrego@Sun.COM 	if (tod == NULL) {
18528474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetRemoteTOD));
18538474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
18548474SJose.Borrego@Sun.COM 	}
18558474SJose.Borrego@Sun.COM 
185610966SJordan.Brown@Sun.COM 	bzero(tod, sizeof (struct mslm_TIME_OF_DAY_INFO));
185710966SJordan.Brown@Sun.COM 
18588474SJose.Borrego@Sun.COM 	tod->tod_elapsedt = time_val.tv_sec;
18598474SJose.Borrego@Sun.COM 	tod->tod_msecs = time_val.tv_usec;
18608474SJose.Borrego@Sun.COM 	tod->tod_hours = tm.tm_hour;
18618474SJose.Borrego@Sun.COM 	tod->tod_mins = tm.tm_min;
18628474SJose.Borrego@Sun.COM 	tod->tod_secs = tm.tm_sec;
18638474SJose.Borrego@Sun.COM 	tod->tod_hunds = 0;
18648474SJose.Borrego@Sun.COM 	tod->tod_tinterval = 1000;
18658474SJose.Borrego@Sun.COM 	tod->tod_day = tm.tm_mday;
18668474SJose.Borrego@Sun.COM 	tod->tod_month = tm.tm_mon+1;
18678474SJose.Borrego@Sun.COM 	tod->tod_year = tm.tm_year+1900;
18688474SJose.Borrego@Sun.COM 	tod->tod_weekday = tm.tm_wday;
18698474SJose.Borrego@Sun.COM 
18708474SJose.Borrego@Sun.COM 	(void) localtime_r(&time_val.tv_sec, &tm);
187110966SJordan.Brown@Sun.COM 	gmtoff = (tm.tm_isdst) ? altzone : timezone;
187210966SJordan.Brown@Sun.COM 	tod->tod_timezone = gmtoff / SECSPERMIN;
18738474SJose.Borrego@Sun.COM 
18748474SJose.Borrego@Sun.COM 	param->bufptr = tod;
18758474SJose.Borrego@Sun.COM 	param->status = ERROR_SUCCESS;
18768474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
18778474SJose.Borrego@Sun.COM }
18788474SJose.Borrego@Sun.COM 
18798474SJose.Borrego@Sun.COM /*
18808474SJose.Borrego@Sun.COM  * srvsvc_s_NetNameValidate
18818474SJose.Borrego@Sun.COM  *
18828474SJose.Borrego@Sun.COM  * Perform name validation.
18838474SJose.Borrego@Sun.COM  *
18848474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
18858474SJose.Borrego@Sun.COM  */
18868474SJose.Borrego@Sun.COM /*ARGSUSED*/
18878474SJose.Borrego@Sun.COM static int
srvsvc_s_NetNameValidate(void * arg,ndr_xa_t * mxa)18888474SJose.Borrego@Sun.COM srvsvc_s_NetNameValidate(void *arg, ndr_xa_t *mxa)
18898474SJose.Borrego@Sun.COM {
18908474SJose.Borrego@Sun.COM 	struct mslm_NetNameValidate *param = arg;
18918474SJose.Borrego@Sun.COM 	char *name;
189211337SWilliam.Krier@Sun.COM 	int maxlen;
18938474SJose.Borrego@Sun.COM 	int len;
18948474SJose.Borrego@Sun.COM 
18958474SJose.Borrego@Sun.COM 	if ((name = (char *)param->pathname) == NULL) {
18968474SJose.Borrego@Sun.COM 		param->status = ERROR_INVALID_PARAMETER;
18978474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
18988474SJose.Borrego@Sun.COM 	}
18998474SJose.Borrego@Sun.COM 
19008474SJose.Borrego@Sun.COM 	switch (param->type) {
19018474SJose.Borrego@Sun.COM 	case NAMETYPE_SHARE:
190211337SWilliam.Krier@Sun.COM 		len = strlen(name);
190311337SWilliam.Krier@Sun.COM 		maxlen = (param->flags & NAMEFLAG_LM2) ?
190411337SWilliam.Krier@Sun.COM 		    SMB_SHARE_OEMNAME_MAX : SMB_SHARE_NTNAME_MAX;
190511337SWilliam.Krier@Sun.COM 
190611337SWilliam.Krier@Sun.COM 		if (len > maxlen) {
19078474SJose.Borrego@Sun.COM 			param->status = ERROR_INVALID_NAME;
190811337SWilliam.Krier@Sun.COM 			return (NDR_DRC_OK);
190911337SWilliam.Krier@Sun.COM 		}
191011337SWilliam.Krier@Sun.COM 
191111337SWilliam.Krier@Sun.COM 		param->status = smb_name_validate_share(name);
19128474SJose.Borrego@Sun.COM 		break;
19138474SJose.Borrego@Sun.COM 
19148474SJose.Borrego@Sun.COM 	case NAMETYPE_USER:
191511337SWilliam.Krier@Sun.COM 	case NAMETYPE_GROUP:
191611337SWilliam.Krier@Sun.COM 		param->status = smb_name_validate_account(name);
191711337SWilliam.Krier@Sun.COM 		break;
191811337SWilliam.Krier@Sun.COM 
191911337SWilliam.Krier@Sun.COM 	case NAMETYPE_DOMAIN:	/* NetBIOS domain name */
192011337SWilliam.Krier@Sun.COM 		param->status = smb_name_validate_nbdomain(name);
192111337SWilliam.Krier@Sun.COM 		break;
192211337SWilliam.Krier@Sun.COM 
192311337SWilliam.Krier@Sun.COM 	case NAMETYPE_WORKGROUP:
192411337SWilliam.Krier@Sun.COM 		param->status = smb_name_validate_workgroup(name);
192511337SWilliam.Krier@Sun.COM 		break;
192611337SWilliam.Krier@Sun.COM 
19278474SJose.Borrego@Sun.COM 	case NAMETYPE_PASSWORD:
19288474SJose.Borrego@Sun.COM 	case NAMETYPE_COMPUTER:
19298474SJose.Borrego@Sun.COM 	case NAMETYPE_EVENT:
19308474SJose.Borrego@Sun.COM 	case NAMETYPE_SERVICE:
19318474SJose.Borrego@Sun.COM 	case NAMETYPE_NET:
19328474SJose.Borrego@Sun.COM 	case NAMETYPE_MESSAGE:
19338474SJose.Borrego@Sun.COM 	case NAMETYPE_MESSAGEDEST:
19348474SJose.Borrego@Sun.COM 	case NAMETYPE_SHAREPASSWORD:
19358474SJose.Borrego@Sun.COM 		param->status = ERROR_NOT_SUPPORTED;
19368474SJose.Borrego@Sun.COM 		break;
19378474SJose.Borrego@Sun.COM 
19388474SJose.Borrego@Sun.COM 	default:
19398474SJose.Borrego@Sun.COM 		param->status = ERROR_INVALID_PARAMETER;
19408474SJose.Borrego@Sun.COM 		break;
19418474SJose.Borrego@Sun.COM 	}
19428474SJose.Borrego@Sun.COM 
19438474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
19448474SJose.Borrego@Sun.COM }
19458474SJose.Borrego@Sun.COM 
19468474SJose.Borrego@Sun.COM /*
19478474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareAdd
19488474SJose.Borrego@Sun.COM  *
19499832Samw@Sun.COM  * Add a new share. Only power users groups can manage shares.
19508474SJose.Borrego@Sun.COM  *
19518474SJose.Borrego@Sun.COM  * This interface is used by the rmtshare command from the NT resource
19528474SJose.Borrego@Sun.COM  * kit. Rmtshare allows a client to add or remove shares on a server
19538474SJose.Borrego@Sun.COM  * from the client's command line.
19548474SJose.Borrego@Sun.COM  *
19558474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
19568474SJose.Borrego@Sun.COM  */
19578474SJose.Borrego@Sun.COM static int
srvsvc_s_NetShareAdd(void * arg,ndr_xa_t * mxa)19588474SJose.Borrego@Sun.COM srvsvc_s_NetShareAdd(void *arg, ndr_xa_t *mxa)
19598474SJose.Borrego@Sun.COM {
19608474SJose.Borrego@Sun.COM 	static DWORD parm_err = 0;
19618474SJose.Borrego@Sun.COM 	DWORD parm_stat;
19628474SJose.Borrego@Sun.COM 	struct mslm_NetShareAdd *param = arg;
19639343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
19649832Samw@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
19658474SJose.Borrego@Sun.COM 	char realpath[MAXPATHLEN];
19668474SJose.Borrego@Sun.COM 	int32_t native_os;
19679832Samw@Sun.COM 	uint8_t *sdbuf = NULL;
19689832Samw@Sun.COM 	uint32_t status;
19699832Samw@Sun.COM 	smb_share_t si;
19708474SJose.Borrego@Sun.COM 
19718474SJose.Borrego@Sun.COM 	native_os = ndr_native_os(mxa);
19728474SJose.Borrego@Sun.COM 
19738474SJose.Borrego@Sun.COM 	if (!ndr_is_poweruser(mxa)) {
19748474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
19758474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
19768474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
19778474SJose.Borrego@Sun.COM 	}
19788474SJose.Borrego@Sun.COM 
19798474SJose.Borrego@Sun.COM 	switch (param->level) {
19808474SJose.Borrego@Sun.COM 	case 2:
19819832Samw@Sun.COM 		info2 = (struct mslm_NetShareInfo_2 *)param->info.un.info2;
19828474SJose.Borrego@Sun.COM 		break;
19838474SJose.Borrego@Sun.COM 
19848474SJose.Borrego@Sun.COM 	case 502:
19859832Samw@Sun.COM 		info502 = (struct mslm_NetShareInfo_502 *)
19869832Samw@Sun.COM 		    param->info.un.info502;
19879832Samw@Sun.COM 		sdbuf = info502->shi502_security_descriptor;
19889832Samw@Sun.COM 		info2 = (struct mslm_NetShareInfo_2 *)info502;
19898474SJose.Borrego@Sun.COM 		break;
19908474SJose.Borrego@Sun.COM 
19918474SJose.Borrego@Sun.COM 	default:
19928474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
19938474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
19948474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
19958474SJose.Borrego@Sun.COM 	}
19968474SJose.Borrego@Sun.COM 
19978474SJose.Borrego@Sun.COM 	if (info2->shi2_netname == NULL || info2->shi2_path == NULL) {
19988474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
19998474SJose.Borrego@Sun.COM 		param->status = NERR_NetNameNotFound;
20008474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
20018474SJose.Borrego@Sun.COM 	}
20028474SJose.Borrego@Sun.COM 
20038474SJose.Borrego@Sun.COM 	if (smb_shr_is_restricted((char *)info2->shi2_netname)) {
20048474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
20058474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
20068474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
20078474SJose.Borrego@Sun.COM 	}
20088474SJose.Borrego@Sun.COM 
20099343SAfshin.Ardakani@Sun.COM 	if (info2->shi2_comment == NULL)
20109343SAfshin.Ardakani@Sun.COM 		info2->shi2_comment = (uint8_t *)"";
20118474SJose.Borrego@Sun.COM 
20128474SJose.Borrego@Sun.COM 	/*
20138474SJose.Borrego@Sun.COM 	 * Derive the real path which will be stored in the
20148474SJose.Borrego@Sun.COM 	 * directory field of the smb_share_t structure
20158474SJose.Borrego@Sun.COM 	 * from the path field in this RPC request.
20168474SJose.Borrego@Sun.COM 	 */
20178474SJose.Borrego@Sun.COM 	parm_stat = smb_shr_get_realpath((const char *)info2->shi2_path,
20188474SJose.Borrego@Sun.COM 	    realpath, MAXPATHLEN);
20198474SJose.Borrego@Sun.COM 
20208474SJose.Borrego@Sun.COM 	if (parm_stat != NERR_Success) {
20218474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
20228474SJose.Borrego@Sun.COM 		param->status = parm_stat;
20238474SJose.Borrego@Sun.COM 		param->parm_err
20248474SJose.Borrego@Sun.COM 		    = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
20258474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
20268474SJose.Borrego@Sun.COM 	}
20278474SJose.Borrego@Sun.COM 
20288474SJose.Borrego@Sun.COM 	param->status = srvsvc_sa_add((char *)info2->shi2_netname, realpath,
20299343SAfshin.Ardakani@Sun.COM 	    (char *)info2->shi2_comment);
20308474SJose.Borrego@Sun.COM 	if (param->status == NERR_Success) {
20319832Samw@Sun.COM 		status = smb_shr_get((char *)info2->shi2_netname, &si);
20329832Samw@Sun.COM 
20339832Samw@Sun.COM 		if ((sdbuf != NULL) && (status == NERR_Success))
20349832Samw@Sun.COM 			(void) srvsvc_sd_set(&si, sdbuf);
20358474SJose.Borrego@Sun.COM 	}
20368474SJose.Borrego@Sun.COM 	param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
20378474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
20388474SJose.Borrego@Sun.COM }
20398474SJose.Borrego@Sun.COM 
20408474SJose.Borrego@Sun.COM /*
204110122SJordan.Brown@Sun.COM  * srvsvc_estimate_limit
20428474SJose.Borrego@Sun.COM  *
20438474SJose.Borrego@Sun.COM  * Estimate the number of objects that will fit in prefmaxlen.
204410122SJordan.Brown@Sun.COM  * nlimit is adjusted here.
20458474SJose.Borrego@Sun.COM  */
204610122SJordan.Brown@Sun.COM static void
srvsvc_estimate_limit(smb_svcenum_t * se,uint32_t obj_size)204710122SJordan.Brown@Sun.COM srvsvc_estimate_limit(smb_svcenum_t *se, uint32_t obj_size)
20488474SJose.Borrego@Sun.COM {
20498474SJose.Borrego@Sun.COM 	DWORD max_cnt;
20508474SJose.Borrego@Sun.COM 
205110122SJordan.Brown@Sun.COM 	if (obj_size == 0) {
205210122SJordan.Brown@Sun.COM 		se->se_nlimit = 0;
205310122SJordan.Brown@Sun.COM 		return;
205410122SJordan.Brown@Sun.COM 	}
205510122SJordan.Brown@Sun.COM 
205610122SJordan.Brown@Sun.COM 	if ((max_cnt = (se->se_prefmaxlen / obj_size)) == 0) {
205710122SJordan.Brown@Sun.COM 		se->se_nlimit = 0;
205810122SJordan.Brown@Sun.COM 		return;
205910122SJordan.Brown@Sun.COM 	}
206010122SJordan.Brown@Sun.COM 
206110122SJordan.Brown@Sun.COM 	if (se->se_ntotal > max_cnt)
206210122SJordan.Brown@Sun.COM 		se->se_nlimit = max_cnt;
206310122SJordan.Brown@Sun.COM 	else
206410122SJordan.Brown@Sun.COM 		se->se_nlimit = se->se_ntotal;
20658474SJose.Borrego@Sun.COM }
20668474SJose.Borrego@Sun.COM 
20678474SJose.Borrego@Sun.COM /*
20688474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareEnum
20698474SJose.Borrego@Sun.COM  *
20708474SJose.Borrego@Sun.COM  * Enumerate all shares (see also NetShareEnumSticky).
20718474SJose.Borrego@Sun.COM  *
20728474SJose.Borrego@Sun.COM  * Request for various levels of information about our shares.
20738474SJose.Borrego@Sun.COM  * Level 0: share names.
20748474SJose.Borrego@Sun.COM  * Level 1: share name, share type and comment field.
20758474SJose.Borrego@Sun.COM  * Level 2: everything that we know about the shares.
207610504SKeyur.Desai@Sun.COM  * Level 501: level 1 + flags.
20778474SJose.Borrego@Sun.COM  * Level 502: level 2 + security descriptor.
20788474SJose.Borrego@Sun.COM  */
20798474SJose.Borrego@Sun.COM static int
srvsvc_s_NetShareEnum(void * arg,ndr_xa_t * mxa)20808474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnum(void *arg, ndr_xa_t *mxa)
20818474SJose.Borrego@Sun.COM {
20828474SJose.Borrego@Sun.COM 	struct mslm_NetShareEnum *param = arg;
208310122SJordan.Brown@Sun.COM 	srvsvc_infonres_t *infonres;
208410122SJordan.Brown@Sun.COM 	smb_svcenum_t se;
20858474SJose.Borrego@Sun.COM 	DWORD status;
20868474SJose.Borrego@Sun.COM 
208710122SJordan.Brown@Sun.COM 	infonres = NDR_NEW(mxa, srvsvc_infonres_t);
20888474SJose.Borrego@Sun.COM 	if (infonres == NULL) {
20898474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareEnum));
20908474SJose.Borrego@Sun.COM 		param->status = ERROR_NOT_ENOUGH_MEMORY;
20918474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
20928474SJose.Borrego@Sun.COM 	}
20938474SJose.Borrego@Sun.COM 
20948474SJose.Borrego@Sun.COM 	infonres->entriesread = 0;
20958474SJose.Borrego@Sun.COM 	infonres->entries = NULL;
20968474SJose.Borrego@Sun.COM 	param->result.level = param->level;
20978474SJose.Borrego@Sun.COM 	param->result.bufptr.p = infonres;
20988474SJose.Borrego@Sun.COM 
209910122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
210010122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_SHARE;
21018474SJose.Borrego@Sun.COM 	se.se_level = param->level;
210210122SJordan.Brown@Sun.COM 	se.se_ntotal = smb_shr_count();
210310122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
21048474SJose.Borrego@Sun.COM 
21058474SJose.Borrego@Sun.COM 	if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN ||
21068474SJose.Borrego@Sun.COM 	    param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN)
21078474SJose.Borrego@Sun.COM 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
21088474SJose.Borrego@Sun.COM 	else
21098474SJose.Borrego@Sun.COM 		se.se_prefmaxlen = param->prefmaxlen;
21108474SJose.Borrego@Sun.COM 
21118474SJose.Borrego@Sun.COM 	if (param->resume_handle) {
211210122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
211310122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
211410122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
21158474SJose.Borrego@Sun.COM 	}
21168474SJose.Borrego@Sun.COM 
21178474SJose.Borrego@Sun.COM 	switch (param->level) {
21188474SJose.Borrego@Sun.COM 	case 0:
21198474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 0);
21208474SJose.Borrego@Sun.COM 		break;
21218474SJose.Borrego@Sun.COM 
21228474SJose.Borrego@Sun.COM 	case 1:
21238474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 0);
21248474SJose.Borrego@Sun.COM 		break;
21258474SJose.Borrego@Sun.COM 
21268474SJose.Borrego@Sun.COM 	case 2:
21278474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 0);
21288474SJose.Borrego@Sun.COM 		break;
21298474SJose.Borrego@Sun.COM 
21308474SJose.Borrego@Sun.COM 	case 501:
21318474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel501(mxa, infonres, &se, 0);
21328474SJose.Borrego@Sun.COM 		break;
21338474SJose.Borrego@Sun.COM 
21348474SJose.Borrego@Sun.COM 	case 502:
21358474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 0);
21368474SJose.Borrego@Sun.COM 		break;
21378474SJose.Borrego@Sun.COM 
21388474SJose.Borrego@Sun.COM 	default:
21399832Samw@Sun.COM 		status = ERROR_INVALID_LEVEL;
21408474SJose.Borrego@Sun.COM 		break;
21418474SJose.Borrego@Sun.COM 	}
21428474SJose.Borrego@Sun.COM 
21438474SJose.Borrego@Sun.COM 	if (status != 0) {
21448474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareEnum));
21458474SJose.Borrego@Sun.COM 		param->status = status;
21468474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
21478474SJose.Borrego@Sun.COM 	}
21488474SJose.Borrego@Sun.COM 
214910122SJordan.Brown@Sun.COM 	if (se.se_nlimit == 0) {
21508474SJose.Borrego@Sun.COM 		param->status = ERROR_SUCCESS;
21518474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
21528474SJose.Borrego@Sun.COM 	}
21538474SJose.Borrego@Sun.COM 
21548474SJose.Borrego@Sun.COM 	if (param->resume_handle &&
21558474SJose.Borrego@Sun.COM 	    param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) {
215610122SJordan.Brown@Sun.COM 		if (se.se_resume < se.se_ntotal) {
215710122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
21588474SJose.Borrego@Sun.COM 			status = ERROR_MORE_DATA;
21598474SJose.Borrego@Sun.COM 		}
21608474SJose.Borrego@Sun.COM 	}
21618474SJose.Borrego@Sun.COM 
216210122SJordan.Brown@Sun.COM 	param->totalentries = se.se_ntotal;
21638474SJose.Borrego@Sun.COM 	param->status = status;
21648474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
21658474SJose.Borrego@Sun.COM }
21668474SJose.Borrego@Sun.COM 
21678474SJose.Borrego@Sun.COM /*
21688474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareEnumSticky
21698474SJose.Borrego@Sun.COM  *
21708474SJose.Borrego@Sun.COM  * Enumerate sticky shares: all shares except those marked STYPE_SPECIAL.
21718474SJose.Borrego@Sun.COM  * Except for excluding STYPE_SPECIAL shares, NetShareEnumSticky is the
21728474SJose.Borrego@Sun.COM  * same as NetShareEnum.
21738474SJose.Borrego@Sun.COM  *
21748474SJose.Borrego@Sun.COM  * Request for various levels of information about our shares.
21758474SJose.Borrego@Sun.COM  * Level 0: share names.
21768474SJose.Borrego@Sun.COM  * Level 1: share name, share type and comment field.
21778474SJose.Borrego@Sun.COM  * Level 2: everything that we know about the shares.
21788474SJose.Borrego@Sun.COM  * Level 501: not valid for this request.
21798474SJose.Borrego@Sun.COM  * Level 502: level 2 + security descriptor.
21808474SJose.Borrego@Sun.COM  *
21818474SJose.Borrego@Sun.COM  * We set n_skip to resume_handle, which is used to find the appropriate
21828474SJose.Borrego@Sun.COM  * place to resume.  The resume_handle is similar to the readdir cookie.
21838474SJose.Borrego@Sun.COM  */
21848474SJose.Borrego@Sun.COM static int
srvsvc_s_NetShareEnumSticky(void * arg,ndr_xa_t * mxa)21858474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnumSticky(void *arg, ndr_xa_t *mxa)
21868474SJose.Borrego@Sun.COM {
21878474SJose.Borrego@Sun.COM 	struct mslm_NetShareEnum *param = arg;
218810122SJordan.Brown@Sun.COM 	srvsvc_infonres_t *infonres;
218910122SJordan.Brown@Sun.COM 	smb_svcenum_t se;
21908474SJose.Borrego@Sun.COM 	DWORD status;
21918474SJose.Borrego@Sun.COM 
219210122SJordan.Brown@Sun.COM 	infonres = NDR_NEW(mxa, srvsvc_infonres_t);
21938474SJose.Borrego@Sun.COM 	if (infonres == NULL) {
21948474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareEnum));
21958474SJose.Borrego@Sun.COM 		param->status = ERROR_NOT_ENOUGH_MEMORY;
21968474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
21978474SJose.Borrego@Sun.COM 	}
21988474SJose.Borrego@Sun.COM 
21998474SJose.Borrego@Sun.COM 	infonres->entriesread = 0;
22008474SJose.Borrego@Sun.COM 	infonres->entries = NULL;
22018474SJose.Borrego@Sun.COM 	param->result.level = param->level;
22028474SJose.Borrego@Sun.COM 	param->result.bufptr.p = infonres;
22038474SJose.Borrego@Sun.COM 
220410122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
220510122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_SHARE;
22068474SJose.Borrego@Sun.COM 	se.se_level = param->level;
220710122SJordan.Brown@Sun.COM 	se.se_ntotal = smb_shr_count();
220810122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
22098474SJose.Borrego@Sun.COM 
22108474SJose.Borrego@Sun.COM 	if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN ||
22118474SJose.Borrego@Sun.COM 	    param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN)
22128474SJose.Borrego@Sun.COM 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
22138474SJose.Borrego@Sun.COM 	else
22148474SJose.Borrego@Sun.COM 		se.se_prefmaxlen = param->prefmaxlen;
22158474SJose.Borrego@Sun.COM 
22168474SJose.Borrego@Sun.COM 	if (param->resume_handle) {
221710122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
221810122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
221910122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
22208474SJose.Borrego@Sun.COM 	}
22218474SJose.Borrego@Sun.COM 
22228474SJose.Borrego@Sun.COM 	switch (param->level) {
22238474SJose.Borrego@Sun.COM 	case 0:
22248474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 1);
22258474SJose.Borrego@Sun.COM 		break;
22268474SJose.Borrego@Sun.COM 
22278474SJose.Borrego@Sun.COM 	case 1:
22288474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 1);
22298474SJose.Borrego@Sun.COM 		break;
22308474SJose.Borrego@Sun.COM 
22318474SJose.Borrego@Sun.COM 	case 2:
22328474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 1);
22338474SJose.Borrego@Sun.COM 		break;
22348474SJose.Borrego@Sun.COM 
22358474SJose.Borrego@Sun.COM 	case 502:
22368474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 1);
22378474SJose.Borrego@Sun.COM 		break;
22388474SJose.Borrego@Sun.COM 
22399832Samw@Sun.COM 	case 501:
22408474SJose.Borrego@Sun.COM 	default:
22418474SJose.Borrego@Sun.COM 		status = ERROR_INVALID_LEVEL;
22428474SJose.Borrego@Sun.COM 		break;
22438474SJose.Borrego@Sun.COM 	}
22448474SJose.Borrego@Sun.COM 
22458474SJose.Borrego@Sun.COM 	if (status != ERROR_SUCCESS) {
22468474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareEnum));
22478474SJose.Borrego@Sun.COM 		param->status = status;
22488474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
22498474SJose.Borrego@Sun.COM 	}
22508474SJose.Borrego@Sun.COM 
225110122SJordan.Brown@Sun.COM 	if (se.se_nlimit == 0) {
22528474SJose.Borrego@Sun.COM 		param->status = ERROR_SUCCESS;
22538474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
22548474SJose.Borrego@Sun.COM 	}
22558474SJose.Borrego@Sun.COM 
22568474SJose.Borrego@Sun.COM 	if (param->resume_handle &&
22578474SJose.Borrego@Sun.COM 	    param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) {
225810122SJordan.Brown@Sun.COM 		if (se.se_resume < se.se_ntotal) {
225910122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
22608474SJose.Borrego@Sun.COM 			status = ERROR_MORE_DATA;
22618474SJose.Borrego@Sun.COM 		}
22628474SJose.Borrego@Sun.COM 	}
22638474SJose.Borrego@Sun.COM 
226410122SJordan.Brown@Sun.COM 	param->totalentries = se.se_ntotal;
22658474SJose.Borrego@Sun.COM 	param->status = status;
22668474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
22678474SJose.Borrego@Sun.COM }
22688474SJose.Borrego@Sun.COM 
22698474SJose.Borrego@Sun.COM /*
22708474SJose.Borrego@Sun.COM  * NetShareEnum Level 0
22718474SJose.Borrego@Sun.COM  */
22728474SJose.Borrego@Sun.COM static DWORD
mlsvc_NetShareEnumLevel0(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)227310122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel0(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
227410122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
22758474SJose.Borrego@Sun.COM {
22769343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_0 *info0;
22778474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
22788474SJose.Borrego@Sun.COM 	smb_share_t *si;
22798474SJose.Borrego@Sun.COM 	DWORD status;
22808474SJose.Borrego@Sun.COM 
228110122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
228210122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_0) + MAXNAMELEN);
228310122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
22848474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
22858474SJose.Borrego@Sun.COM 
228610122SJordan.Brown@Sun.COM 	info0 = NDR_NEWN(mxa, struct mslm_NetShareInfo_0, se->se_nlimit);
22878474SJose.Borrego@Sun.COM 	if (info0 == NULL)
22888474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
22898474SJose.Borrego@Sun.COM 
22908474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
22918474SJose.Borrego@Sun.COM 
229210122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
22938474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
229410122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
229510122SJordan.Brown@Sun.COM 			--se->se_nskip;
22968474SJose.Borrego@Sun.COM 			continue;
22978474SJose.Borrego@Sun.COM 		}
22988474SJose.Borrego@Sun.COM 
229910122SJordan.Brown@Sun.COM 		++se->se_resume;
23008474SJose.Borrego@Sun.COM 
23018474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
23028474SJose.Borrego@Sun.COM 			continue;
23038474SJose.Borrego@Sun.COM 
23048474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
23058474SJose.Borrego@Sun.COM 			continue;
23068474SJose.Borrego@Sun.COM 
230710122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
230810122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
23098474SJose.Borrego@Sun.COM 			break;
23108474SJose.Borrego@Sun.COM 		}
23118474SJose.Borrego@Sun.COM 
23128474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info0);
23138474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
23148474SJose.Borrego@Sun.COM 			break;
23158474SJose.Borrego@Sun.COM 
231610122SJordan.Brown@Sun.COM 		++se->se_nitems;
23178474SJose.Borrego@Sun.COM 	}
23188474SJose.Borrego@Sun.COM 
231910122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
23208474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info0))
232110122SJordan.Brown@Sun.COM 			++se->se_nitems;
23228474SJose.Borrego@Sun.COM 	}
23238474SJose.Borrego@Sun.COM 
232410122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
23258474SJose.Borrego@Sun.COM 	infonres->entries = info0;
23268474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
23278474SJose.Borrego@Sun.COM }
23288474SJose.Borrego@Sun.COM 
23298474SJose.Borrego@Sun.COM /*
23308474SJose.Borrego@Sun.COM  * NetShareEnum Level 1
23318474SJose.Borrego@Sun.COM  */
23328474SJose.Borrego@Sun.COM static DWORD
mlsvc_NetShareEnumLevel1(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)233310122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel1(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
233410122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
23358474SJose.Borrego@Sun.COM {
23369343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1 *info1;
23378474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
23388474SJose.Borrego@Sun.COM 	smb_share_t *si;
23398474SJose.Borrego@Sun.COM 	DWORD status;
23408474SJose.Borrego@Sun.COM 
234110122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
234210122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_1) + MAXNAMELEN);
234310122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
23448474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
23458474SJose.Borrego@Sun.COM 
234610122SJordan.Brown@Sun.COM 	info1 = NDR_NEWN(mxa, struct mslm_NetShareInfo_1, se->se_nlimit);
23478474SJose.Borrego@Sun.COM 	if (info1 == NULL)
23488474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
23498474SJose.Borrego@Sun.COM 
23508474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
23518474SJose.Borrego@Sun.COM 
235210122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
23538474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != 0) {
235410122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
235510122SJordan.Brown@Sun.COM 			--se->se_nskip;
23568474SJose.Borrego@Sun.COM 			continue;
23578474SJose.Borrego@Sun.COM 		}
23588474SJose.Borrego@Sun.COM 
235910122SJordan.Brown@Sun.COM 		++se->se_resume;
23608474SJose.Borrego@Sun.COM 
23618474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
23628474SJose.Borrego@Sun.COM 			continue;
23638474SJose.Borrego@Sun.COM 
23648474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
23658474SJose.Borrego@Sun.COM 			continue;
23668474SJose.Borrego@Sun.COM 
236710122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
236810122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
23698474SJose.Borrego@Sun.COM 			break;
23708474SJose.Borrego@Sun.COM 		}
23718474SJose.Borrego@Sun.COM 
23728474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info1);
23738474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
23748474SJose.Borrego@Sun.COM 			break;
23758474SJose.Borrego@Sun.COM 
237610122SJordan.Brown@Sun.COM 		++se->se_nitems;
23778474SJose.Borrego@Sun.COM 	}
23788474SJose.Borrego@Sun.COM 
237910122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
23808474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info1))
238110122SJordan.Brown@Sun.COM 			++se->se_nitems;
23828474SJose.Borrego@Sun.COM 	}
23838474SJose.Borrego@Sun.COM 
238410122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
23858474SJose.Borrego@Sun.COM 	infonres->entries = info1;
23868474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
23878474SJose.Borrego@Sun.COM }
23888474SJose.Borrego@Sun.COM 
23898474SJose.Borrego@Sun.COM /*
23908474SJose.Borrego@Sun.COM  * NetShareEnum Level 2
23918474SJose.Borrego@Sun.COM  */
23928474SJose.Borrego@Sun.COM static DWORD
mlsvc_NetShareEnumLevel2(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)239310122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel2(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
239410122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
23958474SJose.Borrego@Sun.COM {
23969343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
23978474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
23988474SJose.Borrego@Sun.COM 	smb_share_t *si;
23998474SJose.Borrego@Sun.COM 	DWORD status;
24008474SJose.Borrego@Sun.COM 
240110122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
240210122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_2) + MAXNAMELEN);
240310122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
24048474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
24058474SJose.Borrego@Sun.COM 
240610122SJordan.Brown@Sun.COM 	info2 = NDR_NEWN(mxa, struct mslm_NetShareInfo_2, se->se_nlimit);
24078474SJose.Borrego@Sun.COM 	if (info2 == NULL)
24088474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
24098474SJose.Borrego@Sun.COM 
24108474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
24118474SJose.Borrego@Sun.COM 
241210122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
24138474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != 0) {
241410122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
241510122SJordan.Brown@Sun.COM 			--se->se_nskip;
24168474SJose.Borrego@Sun.COM 			continue;
24178474SJose.Borrego@Sun.COM 		}
24188474SJose.Borrego@Sun.COM 
241910122SJordan.Brown@Sun.COM 		++se->se_resume;
24208474SJose.Borrego@Sun.COM 
24218474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
24228474SJose.Borrego@Sun.COM 			continue;
24238474SJose.Borrego@Sun.COM 
24248474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
24258474SJose.Borrego@Sun.COM 			continue;
24268474SJose.Borrego@Sun.COM 
242710122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
242810122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
24298474SJose.Borrego@Sun.COM 			break;
24308474SJose.Borrego@Sun.COM 		}
24318474SJose.Borrego@Sun.COM 
24328474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info2);
24338474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
24348474SJose.Borrego@Sun.COM 			break;
24358474SJose.Borrego@Sun.COM 
243610122SJordan.Brown@Sun.COM 		++se->se_nitems;
24378474SJose.Borrego@Sun.COM 	}
24388474SJose.Borrego@Sun.COM 
243910122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
24408474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info2))
244110122SJordan.Brown@Sun.COM 			++se->se_nitems;
24428474SJose.Borrego@Sun.COM 	}
24438474SJose.Borrego@Sun.COM 
244410122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
24458474SJose.Borrego@Sun.COM 	infonres->entries = info2;
24468474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
24478474SJose.Borrego@Sun.COM }
24488474SJose.Borrego@Sun.COM 
24498474SJose.Borrego@Sun.COM /*
24508474SJose.Borrego@Sun.COM  * NetShareEnum Level 501
24518474SJose.Borrego@Sun.COM  */
24528474SJose.Borrego@Sun.COM static DWORD
mlsvc_NetShareEnumLevel501(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)245310122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel501(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
245410122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
24558474SJose.Borrego@Sun.COM {
24569343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_501 *info501;
24578474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
24588474SJose.Borrego@Sun.COM 	smb_share_t *si;
24598474SJose.Borrego@Sun.COM 	DWORD status;
24608474SJose.Borrego@Sun.COM 
246110122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
246210122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_501) + MAXNAMELEN);
246310122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
24648474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
24658474SJose.Borrego@Sun.COM 
24669343SAfshin.Ardakani@Sun.COM 	info501 = NDR_NEWN(mxa, struct mslm_NetShareInfo_501,
246710122SJordan.Brown@Sun.COM 	    se->se_nlimit);
24688474SJose.Borrego@Sun.COM 	if (info501 == NULL)
24698474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
24708474SJose.Borrego@Sun.COM 
24718474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
24728474SJose.Borrego@Sun.COM 
247310122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
24748474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != 0) {
247510122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
247610122SJordan.Brown@Sun.COM 			--se->se_nskip;
24778474SJose.Borrego@Sun.COM 			continue;
24788474SJose.Borrego@Sun.COM 		}
24798474SJose.Borrego@Sun.COM 
248010122SJordan.Brown@Sun.COM 		++se->se_resume;
24818474SJose.Borrego@Sun.COM 
24828474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
24838474SJose.Borrego@Sun.COM 			continue;
24848474SJose.Borrego@Sun.COM 
24858474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
24868474SJose.Borrego@Sun.COM 			continue;
24878474SJose.Borrego@Sun.COM 
248810122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
248910122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
24908474SJose.Borrego@Sun.COM 			break;
24918474SJose.Borrego@Sun.COM 		}
24928474SJose.Borrego@Sun.COM 
24938474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info501);
24948474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
24958474SJose.Borrego@Sun.COM 			break;
24968474SJose.Borrego@Sun.COM 
249710122SJordan.Brown@Sun.COM 		++se->se_nitems;
24988474SJose.Borrego@Sun.COM 	}
24998474SJose.Borrego@Sun.COM 
250010122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
25018474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info501))
250210122SJordan.Brown@Sun.COM 			++se->se_nitems;
25038474SJose.Borrego@Sun.COM 	}
25048474SJose.Borrego@Sun.COM 
250510122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
25068474SJose.Borrego@Sun.COM 	infonres->entries = info501;
25078474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
25088474SJose.Borrego@Sun.COM }
25098474SJose.Borrego@Sun.COM 
25108474SJose.Borrego@Sun.COM /*
25118474SJose.Borrego@Sun.COM  * NetShareEnum Level 502
25128474SJose.Borrego@Sun.COM  */
25138474SJose.Borrego@Sun.COM static DWORD
mlsvc_NetShareEnumLevel502(ndr_xa_t * mxa,srvsvc_infonres_t * infonres,smb_svcenum_t * se,int sticky)251410122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel502(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
251510122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
25168474SJose.Borrego@Sun.COM {
25179343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
25188474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
25198474SJose.Borrego@Sun.COM 	smb_share_t *si;
25208474SJose.Borrego@Sun.COM 	DWORD status;
25218474SJose.Borrego@Sun.COM 
252210122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
252310122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_502) + MAXNAMELEN);
252410122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
25258474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
25268474SJose.Borrego@Sun.COM 
25279343SAfshin.Ardakani@Sun.COM 	info502 = NDR_NEWN(mxa, struct mslm_NetShareInfo_502,
252810122SJordan.Brown@Sun.COM 	    se->se_nlimit);
25298474SJose.Borrego@Sun.COM 	if (info502 == NULL)
25308474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
25318474SJose.Borrego@Sun.COM 
25328474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
25338474SJose.Borrego@Sun.COM 
253410122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
25358474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
253610122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
253710122SJordan.Brown@Sun.COM 			--se->se_nskip;
25388474SJose.Borrego@Sun.COM 			continue;
25398474SJose.Borrego@Sun.COM 		}
25408474SJose.Borrego@Sun.COM 
254110122SJordan.Brown@Sun.COM 		++se->se_resume;
25428474SJose.Borrego@Sun.COM 
25438474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
25448474SJose.Borrego@Sun.COM 			continue;
25458474SJose.Borrego@Sun.COM 
25468474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
25478474SJose.Borrego@Sun.COM 			continue;
25488474SJose.Borrego@Sun.COM 
254910122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
255010122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
25518474SJose.Borrego@Sun.COM 			break;
25528474SJose.Borrego@Sun.COM 		}
25538474SJose.Borrego@Sun.COM 
25548474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info502);
25558474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
25568474SJose.Borrego@Sun.COM 			break;
25578474SJose.Borrego@Sun.COM 
255810122SJordan.Brown@Sun.COM 		++se->se_nitems;
25598474SJose.Borrego@Sun.COM 	}
25608474SJose.Borrego@Sun.COM 
256110122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
25628474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info502))
256310122SJordan.Brown@Sun.COM 			++se->se_nitems;
25648474SJose.Borrego@Sun.COM 	}
25658474SJose.Borrego@Sun.COM 
256610122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
25678474SJose.Borrego@Sun.COM 	infonres->entries = info502;
25688474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
25698474SJose.Borrego@Sun.COM }
25708474SJose.Borrego@Sun.COM 
25718474SJose.Borrego@Sun.COM /*
25728474SJose.Borrego@Sun.COM  * mlsvc_NetShareEnumCommon
25738474SJose.Borrego@Sun.COM  *
25748474SJose.Borrego@Sun.COM  * Build the levels 0, 1, 2, 501 and 502 share information. This function
25758474SJose.Borrego@Sun.COM  * is called by the various NetShareEnum levels for each share. If
25768474SJose.Borrego@Sun.COM  * we cannot build the share data for some reason, we return an error
25778474SJose.Borrego@Sun.COM  * but the actual value of the error is not important to the caller.
25788474SJose.Borrego@Sun.COM  * The caller just needs to know not to include this info in the RPC
25798474SJose.Borrego@Sun.COM  * response.
25808474SJose.Borrego@Sun.COM  *
25818474SJose.Borrego@Sun.COM  * Returns:
25828474SJose.Borrego@Sun.COM  *	ERROR_SUCCESS
25838474SJose.Borrego@Sun.COM  *	ERROR_NOT_ENOUGH_MEMORY
25848474SJose.Borrego@Sun.COM  *	ERROR_INVALID_LEVEL
25858474SJose.Borrego@Sun.COM  */
25868474SJose.Borrego@Sun.COM static DWORD
mlsvc_NetShareEnumCommon(ndr_xa_t * mxa,smb_svcenum_t * se,smb_share_t * si,void * infop)258710122SJordan.Brown@Sun.COM mlsvc_NetShareEnumCommon(ndr_xa_t *mxa, smb_svcenum_t *se,
25888474SJose.Borrego@Sun.COM     smb_share_t *si, void *infop)
25898474SJose.Borrego@Sun.COM {
25909343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_0 *info0;
25919343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1 *info1;
25929343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
25939343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_501 *info501;
25949343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
25959832Samw@Sun.COM 	srvsvc_sd_t sd;
25969832Samw@Sun.COM 	uint8_t *netname;
25979832Samw@Sun.COM 	uint8_t *comment;
25989832Samw@Sun.COM 	uint8_t *passwd;
25999832Samw@Sun.COM 	uint8_t *path;
260010122SJordan.Brown@Sun.COM 	int i = se->se_nitems;
26018474SJose.Borrego@Sun.COM 
26029832Samw@Sun.COM 	netname = (uint8_t *)NDR_STRDUP(mxa, si->shr_name);
26039832Samw@Sun.COM 	comment = (uint8_t *)NDR_STRDUP(mxa, si->shr_cmnt);
26049832Samw@Sun.COM 	passwd = (uint8_t *)NDR_STRDUP(mxa, empty_string);
26059832Samw@Sun.COM 	path = (uint8_t *)srvsvc_share_mkpath(mxa, si->shr_path);
26069832Samw@Sun.COM 
26079832Samw@Sun.COM 	if (!netname || !comment || !passwd || !path)
26089832Samw@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
26099832Samw@Sun.COM 
26108474SJose.Borrego@Sun.COM 	switch (se->se_level) {
26118474SJose.Borrego@Sun.COM 	case 0:
26129343SAfshin.Ardakani@Sun.COM 		info0 = (struct mslm_NetShareInfo_0 *)infop;
26139832Samw@Sun.COM 		info0[i].shi0_netname = netname;
26148474SJose.Borrego@Sun.COM 		break;
26158474SJose.Borrego@Sun.COM 
26168474SJose.Borrego@Sun.COM 	case 1:
26179343SAfshin.Ardakani@Sun.COM 		info1 = (struct mslm_NetShareInfo_1 *)infop;
26189832Samw@Sun.COM 		info1[i].shi1_netname = netname;
26199832Samw@Sun.COM 		info1[i].shi1_comment = comment;
26208474SJose.Borrego@Sun.COM 		info1[i].shi1_type = si->shr_type;
26218474SJose.Borrego@Sun.COM 		break;
26228474SJose.Borrego@Sun.COM 
26238474SJose.Borrego@Sun.COM 	case 2:
26249343SAfshin.Ardakani@Sun.COM 		info2 = (struct mslm_NetShareInfo_2 *)infop;
26259832Samw@Sun.COM 		info2[i].shi2_netname = netname;
26269832Samw@Sun.COM 		info2[i].shi2_comment = comment;
26279832Samw@Sun.COM 		info2[i].shi2_path = path;
26288474SJose.Borrego@Sun.COM 		info2[i].shi2_type = si->shr_type;
26298474SJose.Borrego@Sun.COM 		info2[i].shi2_permissions = 0;
26308474SJose.Borrego@Sun.COM 		info2[i].shi2_max_uses = SHI_USES_UNLIMITED;
26318474SJose.Borrego@Sun.COM 		info2[i].shi2_current_uses = 0;
26329832Samw@Sun.COM 		info2[i].shi2_passwd = passwd;
26338474SJose.Borrego@Sun.COM 		break;
26348474SJose.Borrego@Sun.COM 
26358474SJose.Borrego@Sun.COM 	case 501:
26369343SAfshin.Ardakani@Sun.COM 		info501 = (struct mslm_NetShareInfo_501 *)infop;
26379832Samw@Sun.COM 		info501[i].shi501_netname = netname;
26389832Samw@Sun.COM 		info501[i].shi501_comment = comment;
26398474SJose.Borrego@Sun.COM 		info501[i].shi501_type = si->shr_type;
264010504SKeyur.Desai@Sun.COM 		info501[i].shi501_flags = srvsvc_get_share_flags(si);
26418474SJose.Borrego@Sun.COM 		break;
26428474SJose.Borrego@Sun.COM 
26438474SJose.Borrego@Sun.COM 	case 502:
26449343SAfshin.Ardakani@Sun.COM 		info502 = (struct mslm_NetShareInfo_502 *)infop;
26459832Samw@Sun.COM 		info502[i].shi502_netname = netname;
26469832Samw@Sun.COM 		info502[i].shi502_comment = comment;
26479832Samw@Sun.COM 		info502[i].shi502_path = path;
26488474SJose.Borrego@Sun.COM 		info502[i].shi502_type = si->shr_type;
26498474SJose.Borrego@Sun.COM 		info502[i].shi502_permissions = 0;
26508474SJose.Borrego@Sun.COM 		info502[i].shi502_max_uses = SHI_USES_UNLIMITED;
26518474SJose.Borrego@Sun.COM 		info502[i].shi502_current_uses = 0;
26529832Samw@Sun.COM 		info502[i].shi502_passwd = passwd;
26539832Samw@Sun.COM 
26549832Samw@Sun.COM 		if (srvsvc_share_getsd(mxa, si, &sd) == ERROR_SUCCESS) {
26559832Samw@Sun.COM 			info502[i].shi502_reserved = sd.sd_size;
26569832Samw@Sun.COM 			info502[i].shi502_security_descriptor = sd.sd_buf;
26579832Samw@Sun.COM 		} else {
26589832Samw@Sun.COM 			info502[i].shi502_reserved = 0;
26599832Samw@Sun.COM 			info502[i].shi502_security_descriptor = NULL;
26609832Samw@Sun.COM 		}
26619832Samw@Sun.COM 
26628474SJose.Borrego@Sun.COM 		break;
26638474SJose.Borrego@Sun.COM 
26648474SJose.Borrego@Sun.COM 	default:
26658474SJose.Borrego@Sun.COM 		return (ERROR_INVALID_LEVEL);
26668474SJose.Borrego@Sun.COM 	}
26678474SJose.Borrego@Sun.COM 
26688474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
26698474SJose.Borrego@Sun.COM }
26708474SJose.Borrego@Sun.COM 
26718474SJose.Borrego@Sun.COM /*
26728474SJose.Borrego@Sun.COM  * srvsvc_add_autohome
26738474SJose.Borrego@Sun.COM  *
26748474SJose.Borrego@Sun.COM  * Add the autohome share for the user. The share must not be a permanent
26758474SJose.Borrego@Sun.COM  * share to avoid duplicates.
26768474SJose.Borrego@Sun.COM  */
26778474SJose.Borrego@Sun.COM static boolean_t
srvsvc_add_autohome(ndr_xa_t * mxa,smb_svcenum_t * se,void * infop)267810122SJordan.Brown@Sun.COM srvsvc_add_autohome(ndr_xa_t *mxa, smb_svcenum_t *se, void *infop)
26798474SJose.Borrego@Sun.COM {
268010122SJordan.Brown@Sun.COM 	smb_netuserinfo_t *user = &mxa->pipe->np_user;
268112065SKeyur.Desai@Sun.COM 	char *username;
26828474SJose.Borrego@Sun.COM 	smb_share_t si;
26838474SJose.Borrego@Sun.COM 	DWORD status;
268412065SKeyur.Desai@Sun.COM 	struct passwd pw;
268512065SKeyur.Desai@Sun.COM 	char buf[NSS_LINELEN_PASSWD];
268612065SKeyur.Desai@Sun.COM 
268712065SKeyur.Desai@Sun.COM 	if (IDMAP_ID_IS_EPHEMERAL(user->ui_posix_uid)) {
268812065SKeyur.Desai@Sun.COM 		username = user->ui_account;
268912065SKeyur.Desai@Sun.COM 	} else {
269012065SKeyur.Desai@Sun.COM 		if (getpwuid_r(user->ui_posix_uid, &pw, buf, sizeof (buf)) ==
269112065SKeyur.Desai@Sun.COM 		    NULL)
269212065SKeyur.Desai@Sun.COM 			return (B_FALSE);
269312065SKeyur.Desai@Sun.COM 
269412065SKeyur.Desai@Sun.COM 		username = pw.pw_name;
269512065SKeyur.Desai@Sun.COM 	}
26968474SJose.Borrego@Sun.COM 
26978474SJose.Borrego@Sun.COM 	if (smb_shr_get(username, &si) != NERR_Success)
26988474SJose.Borrego@Sun.COM 		return (B_FALSE);
26998474SJose.Borrego@Sun.COM 
27008474SJose.Borrego@Sun.COM 	if ((si.shr_flags & SMB_SHRF_AUTOHOME) == 0)
27018474SJose.Borrego@Sun.COM 		return (B_FALSE);
27028474SJose.Borrego@Sun.COM 
27038474SJose.Borrego@Sun.COM 	status = mlsvc_NetShareEnumCommon(mxa, se, &si, infop);
27048474SJose.Borrego@Sun.COM 	return (status == ERROR_SUCCESS);
27058474SJose.Borrego@Sun.COM }
27068474SJose.Borrego@Sun.COM 
27078474SJose.Borrego@Sun.COM /*
27088474SJose.Borrego@Sun.COM  * srvsvc_share_mkpath
27098474SJose.Borrego@Sun.COM  *
27108474SJose.Borrego@Sun.COM  * Create the share path required by the share enum calls. The path
27118474SJose.Borrego@Sun.COM  * is created in a heap buffer ready for use by the caller.
27128474SJose.Borrego@Sun.COM  *
27138474SJose.Borrego@Sun.COM  * Some Windows over-the-wire backup applications do not work unless a
27148474SJose.Borrego@Sun.COM  * drive letter is present in the share path.  We don't care about the
27158474SJose.Borrego@Sun.COM  * drive letter since the path is fully qualified with the volume name.
27168474SJose.Borrego@Sun.COM  *
27178474SJose.Borrego@Sun.COM  * Windows clients seem to be mostly okay with forward slashes in
27188474SJose.Borrego@Sun.COM  * share paths but they cannot handle one immediately after the drive
27198474SJose.Borrego@Sun.COM  * letter, i.e. B:/.  For consistency we convert all the slashes in
27208474SJose.Borrego@Sun.COM  * the path.
27218474SJose.Borrego@Sun.COM  *
27228474SJose.Borrego@Sun.COM  * Returns a pointer to a heap buffer containing the share path, which
27238474SJose.Borrego@Sun.COM  * could be a null pointer if the heap allocation fails.
27248474SJose.Borrego@Sun.COM  */
27258474SJose.Borrego@Sun.COM static char *
srvsvc_share_mkpath(ndr_xa_t * mxa,char * path)27268474SJose.Borrego@Sun.COM srvsvc_share_mkpath(ndr_xa_t *mxa, char *path)
27278474SJose.Borrego@Sun.COM {
27288474SJose.Borrego@Sun.COM 	char tmpbuf[MAXPATHLEN];
27298474SJose.Borrego@Sun.COM 	char *p;
273012065SKeyur.Desai@Sun.COM 	char drive_letter;
27318474SJose.Borrego@Sun.COM 
27328474SJose.Borrego@Sun.COM 	if (strlen(path) == 0)
27338474SJose.Borrego@Sun.COM 		return (NDR_STRDUP(mxa, path));
27348474SJose.Borrego@Sun.COM 
273512065SKeyur.Desai@Sun.COM 	drive_letter = smb_shr_drive_letter(path);
273612065SKeyur.Desai@Sun.COM 	if (drive_letter != '\0') {
273712065SKeyur.Desai@Sun.COM 		(void) snprintf(tmpbuf, MAXPATHLEN, "%c:\\", drive_letter);
273812065SKeyur.Desai@Sun.COM 		return (NDR_STRDUP(mxa, tmpbuf));
273912065SKeyur.Desai@Sun.COM 	}
274012065SKeyur.Desai@Sun.COM 
27418474SJose.Borrego@Sun.COM 	/*
27428474SJose.Borrego@Sun.COM 	 * Strip the volume name from the path (/vol1/home -> /home).
27438474SJose.Borrego@Sun.COM 	 */
27448474SJose.Borrego@Sun.COM 	p = path;
27458474SJose.Borrego@Sun.COM 	p += strspn(p, "/");
27468474SJose.Borrego@Sun.COM 	p += strcspn(p, "/");
27478474SJose.Borrego@Sun.COM 	p += strspn(p, "/");
27488474SJose.Borrego@Sun.COM 	(void) snprintf(tmpbuf, MAXPATHLEN, "%c:/%s", 'B', p);
27498474SJose.Borrego@Sun.COM 	(void) strsubst(tmpbuf, '/', '\\');
27508474SJose.Borrego@Sun.COM 
27518474SJose.Borrego@Sun.COM 	return (NDR_STRDUP(mxa, tmpbuf));
27528474SJose.Borrego@Sun.COM }
27538474SJose.Borrego@Sun.COM 
27549832Samw@Sun.COM static int
srvsvc_s_NetShareCheck(void * arg,ndr_xa_t * mxa)27559832Samw@Sun.COM srvsvc_s_NetShareCheck(void *arg, ndr_xa_t *mxa)
27569832Samw@Sun.COM {
27579832Samw@Sun.COM 	struct mslm_NetShareCheck *param = arg;
27589832Samw@Sun.COM 	smb_shriter_t iterator;
27599832Samw@Sun.COM 	smb_share_t *si;
27609832Samw@Sun.COM 	char *path;
27619832Samw@Sun.COM 
27629832Samw@Sun.COM 	if (param->path == NULL) {
27639832Samw@Sun.COM 		param->stype = STYPE_DISKTREE;
27649832Samw@Sun.COM 		param->status = NERR_NetNameNotFound;
27659832Samw@Sun.COM 		return (NDR_DRC_OK);
27669832Samw@Sun.COM 	}
27679832Samw@Sun.COM 
27689832Samw@Sun.COM 	(void) strsubst((char *)param->path, '/', '\\');
27699832Samw@Sun.COM 
27709832Samw@Sun.COM 	smb_shr_iterinit(&iterator);
27719832Samw@Sun.COM 
27729832Samw@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
27739832Samw@Sun.COM 		path = srvsvc_share_mkpath(mxa, si->shr_path);
27749832Samw@Sun.COM 
277510966SJordan.Brown@Sun.COM 		if (smb_strcasecmp(path, (char *)param->path, 0) == 0) {
27769832Samw@Sun.COM 			param->stype = (si->shr_type & STYPE_MASK);
27779832Samw@Sun.COM 			param->status = NERR_Success;
27789832Samw@Sun.COM 			return (NDR_DRC_OK);
27799832Samw@Sun.COM 		}
27809832Samw@Sun.COM 	}
27819832Samw@Sun.COM 
27829832Samw@Sun.COM 	param->stype = STYPE_DISKTREE;
27839832Samw@Sun.COM 	param->status = NERR_NetNameNotFound;
27849832Samw@Sun.COM 	return (NDR_DRC_OK);
27859832Samw@Sun.COM }
27869832Samw@Sun.COM 
27878474SJose.Borrego@Sun.COM /*
278810122SJordan.Brown@Sun.COM  * Delete a share.  Only members of the Administrators, Server Operators
278910122SJordan.Brown@Sun.COM  * or Power Users local groups are allowed to delete shares.
27908474SJose.Borrego@Sun.COM  *
27918474SJose.Borrego@Sun.COM  * This interface is used by the rmtshare command from the NT resource
27928474SJose.Borrego@Sun.COM  * kit. Rmtshare allows a client to add or remove shares on a server
27938474SJose.Borrego@Sun.COM  * from the client's command line.
27948474SJose.Borrego@Sun.COM  *
27958474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
27968474SJose.Borrego@Sun.COM  */
27978474SJose.Borrego@Sun.COM static int
srvsvc_s_NetShareDel(void * arg,ndr_xa_t * mxa)27988474SJose.Borrego@Sun.COM srvsvc_s_NetShareDel(void *arg, ndr_xa_t *mxa)
27998474SJose.Borrego@Sun.COM {
28008474SJose.Borrego@Sun.COM 	struct mslm_NetShareDel *param = arg;
280111963SAfshin.Ardakani@Sun.COM 	smb_share_t si;
28028474SJose.Borrego@Sun.COM 
28038474SJose.Borrego@Sun.COM 	if (!ndr_is_poweruser(mxa) ||
28048474SJose.Borrego@Sun.COM 	    smb_shr_is_restricted((char *)param->netname)) {
28058474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
28068474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
28078474SJose.Borrego@Sun.COM 	}
28088474SJose.Borrego@Sun.COM 
280911963SAfshin.Ardakani@Sun.COM 	if (smb_shr_get((char *)param->netname, &si) == NERR_Success) {
281011963SAfshin.Ardakani@Sun.COM 		if (si.shr_flags & SMB_SHRF_DFSROOT) {
281111963SAfshin.Ardakani@Sun.COM 			param->status = NERR_IsDfsShare;
281211963SAfshin.Ardakani@Sun.COM 			return (NDR_DRC_OK);
281311963SAfshin.Ardakani@Sun.COM 		}
281411963SAfshin.Ardakani@Sun.COM 	}
281511963SAfshin.Ardakani@Sun.COM 
28168474SJose.Borrego@Sun.COM 	param->status = srvsvc_sa_delete((char *)param->netname);
28178474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
28188474SJose.Borrego@Sun.COM }
28198474SJose.Borrego@Sun.COM 
28208474SJose.Borrego@Sun.COM /*
28218474SJose.Borrego@Sun.COM  * srvsvc_s_NetGetFileSecurity
28228474SJose.Borrego@Sun.COM  *
28238474SJose.Borrego@Sun.COM  * Get security descriptor of the requested file/folder
28248474SJose.Borrego@Sun.COM  *
28258474SJose.Borrego@Sun.COM  * Right now, just returns ERROR_ACCESS_DENIED, because we cannot
28268474SJose.Borrego@Sun.COM  * get the requested SD here in RPC code.
28278474SJose.Borrego@Sun.COM  */
28288474SJose.Borrego@Sun.COM /*ARGSUSED*/
28298474SJose.Borrego@Sun.COM static int
srvsvc_s_NetGetFileSecurity(void * arg,ndr_xa_t * mxa)28308474SJose.Borrego@Sun.COM srvsvc_s_NetGetFileSecurity(void *arg, ndr_xa_t *mxa)
28318474SJose.Borrego@Sun.COM {
28328474SJose.Borrego@Sun.COM 	struct mslm_NetGetFileSecurity *param = arg;
28338474SJose.Borrego@Sun.COM 
28348474SJose.Borrego@Sun.COM 	param->length = 0;
28358474SJose.Borrego@Sun.COM 	param->status = ERROR_ACCESS_DENIED;
28368474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
28378474SJose.Borrego@Sun.COM }
28388474SJose.Borrego@Sun.COM 
28398474SJose.Borrego@Sun.COM /*
28408474SJose.Borrego@Sun.COM  * srvsvc_s_NetSetFileSecurity
28418474SJose.Borrego@Sun.COM  *
28428474SJose.Borrego@Sun.COM  * Set the given security descriptor for the requested file/folder
28438474SJose.Borrego@Sun.COM  *
28448474SJose.Borrego@Sun.COM  * Right now, just returns ERROR_ACCESS_DENIED, because we cannot
28458474SJose.Borrego@Sun.COM  * set the requested SD here in RPC code.
28468474SJose.Borrego@Sun.COM  */
28478474SJose.Borrego@Sun.COM /*ARGSUSED*/
28488474SJose.Borrego@Sun.COM static int
srvsvc_s_NetSetFileSecurity(void * arg,ndr_xa_t * mxa)28498474SJose.Borrego@Sun.COM srvsvc_s_NetSetFileSecurity(void *arg, ndr_xa_t *mxa)
28508474SJose.Borrego@Sun.COM {
28518474SJose.Borrego@Sun.COM 	struct mslm_NetSetFileSecurity *param = arg;
28528474SJose.Borrego@Sun.COM 
28538474SJose.Borrego@Sun.COM 	param->status = ERROR_ACCESS_DENIED;
28548474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
28558474SJose.Borrego@Sun.COM }
28568474SJose.Borrego@Sun.COM 
28578474SJose.Borrego@Sun.COM /*
28588474SJose.Borrego@Sun.COM  * If the default "smb" share group exists then return the group
28598474SJose.Borrego@Sun.COM  * handle, otherwise create the group and return the handle.
28608474SJose.Borrego@Sun.COM  *
28618474SJose.Borrego@Sun.COM  * All shares created via the srvsvc will be added to the "smb"
28628474SJose.Borrego@Sun.COM  * group.
28638474SJose.Borrego@Sun.COM  */
28648474SJose.Borrego@Sun.COM static sa_group_t
srvsvc_sa_get_smbgrp(sa_handle_t handle)28658474SJose.Borrego@Sun.COM srvsvc_sa_get_smbgrp(sa_handle_t handle)
28668474SJose.Borrego@Sun.COM {
28678474SJose.Borrego@Sun.COM 	sa_group_t group = NULL;
28688474SJose.Borrego@Sun.COM 	int err;
28698474SJose.Borrego@Sun.COM 
28708474SJose.Borrego@Sun.COM 	group = sa_get_group(handle, SMB_DEFAULT_SHARE_GROUP);
28718474SJose.Borrego@Sun.COM 	if (group != NULL)
28728474SJose.Borrego@Sun.COM 		return (group);
28738474SJose.Borrego@Sun.COM 
28748474SJose.Borrego@Sun.COM 	group = sa_create_group(handle, SMB_DEFAULT_SHARE_GROUP, &err);
28758474SJose.Borrego@Sun.COM 	if (group == NULL)
28768474SJose.Borrego@Sun.COM 		return (NULL);
28778474SJose.Borrego@Sun.COM 
28788474SJose.Borrego@Sun.COM 	if (sa_create_optionset(group, SMB_DEFAULT_SHARE_GROUP) == NULL) {
28798474SJose.Borrego@Sun.COM 		(void) sa_remove_group(group);
28808474SJose.Borrego@Sun.COM 		group = NULL;
28818474SJose.Borrego@Sun.COM 	}
28828474SJose.Borrego@Sun.COM 
28838474SJose.Borrego@Sun.COM 	return (group);
28848474SJose.Borrego@Sun.COM }
28858474SJose.Borrego@Sun.COM 
28868474SJose.Borrego@Sun.COM /*
28878474SJose.Borrego@Sun.COM  * Stores the given share in sharemgr
28888474SJose.Borrego@Sun.COM  */
28898474SJose.Borrego@Sun.COM static uint32_t
srvsvc_sa_add(char * sharename,char * path,char * cmnt)28908474SJose.Borrego@Sun.COM srvsvc_sa_add(char *sharename, char *path, char *cmnt)
28918474SJose.Borrego@Sun.COM {
28928474SJose.Borrego@Sun.COM 	sa_handle_t handle;
28938474SJose.Borrego@Sun.COM 	sa_share_t share;
28948474SJose.Borrego@Sun.COM 	sa_group_t group;
28958474SJose.Borrego@Sun.COM 	sa_resource_t resource;
28968474SJose.Borrego@Sun.COM 	boolean_t new_share = B_FALSE;
28978474SJose.Borrego@Sun.COM 	uint32_t status = NERR_Success;
28988474SJose.Borrego@Sun.COM 	int err;
28998474SJose.Borrego@Sun.COM 
29008474SJose.Borrego@Sun.COM 	if ((handle = smb_shr_sa_enter()) == NULL)
29018474SJose.Borrego@Sun.COM 		return (NERR_InternalError);
29028474SJose.Borrego@Sun.COM 
29038474SJose.Borrego@Sun.COM 	share = sa_find_share(handle, path);
29048474SJose.Borrego@Sun.COM 	if (share == NULL) {
29058474SJose.Borrego@Sun.COM 		group = srvsvc_sa_get_smbgrp(handle);
29068474SJose.Borrego@Sun.COM 		if (group == NULL) {
29078474SJose.Borrego@Sun.COM 			smb_shr_sa_exit();
29088474SJose.Borrego@Sun.COM 			return (NERR_InternalError);
29098474SJose.Borrego@Sun.COM 		}
29108474SJose.Borrego@Sun.COM 
29118474SJose.Borrego@Sun.COM 		share = sa_add_share(group, path, SA_SHARE_PERMANENT, &err);
29128474SJose.Borrego@Sun.COM 		if (share == NULL) {
29138474SJose.Borrego@Sun.COM 			smb_shr_sa_exit();
29148474SJose.Borrego@Sun.COM 			return (NERR_InternalError);
29158474SJose.Borrego@Sun.COM 		}
29168474SJose.Borrego@Sun.COM 		new_share = B_TRUE;
29178474SJose.Borrego@Sun.COM 	}
29188474SJose.Borrego@Sun.COM 
29198474SJose.Borrego@Sun.COM 	resource = sa_get_share_resource(share, sharename);
29208474SJose.Borrego@Sun.COM 	if (resource == NULL) {
29218474SJose.Borrego@Sun.COM 		resource = sa_add_resource(share, sharename,
29228474SJose.Borrego@Sun.COM 		    SA_SHARE_PERMANENT, &err);
29238474SJose.Borrego@Sun.COM 		if (resource == NULL) {
29248474SJose.Borrego@Sun.COM 			if (new_share)
29258474SJose.Borrego@Sun.COM 				(void) sa_remove_share(share);
29268474SJose.Borrego@Sun.COM 			smb_shr_sa_exit();
29278474SJose.Borrego@Sun.COM 			return (NERR_InternalError);
29288474SJose.Borrego@Sun.COM 		}
29298474SJose.Borrego@Sun.COM 	}
29308474SJose.Borrego@Sun.COM 
29318474SJose.Borrego@Sun.COM 	(void) sa_set_resource_description(resource, cmnt);
29328474SJose.Borrego@Sun.COM 
29338474SJose.Borrego@Sun.COM 	smb_shr_sa_exit();
29348474SJose.Borrego@Sun.COM 	return (status);
29358474SJose.Borrego@Sun.COM }
29368474SJose.Borrego@Sun.COM 
29378474SJose.Borrego@Sun.COM /*
29388474SJose.Borrego@Sun.COM  * Removes the share from sharemgr
29398474SJose.Borrego@Sun.COM  */
29408474SJose.Borrego@Sun.COM static uint32_t
srvsvc_sa_delete(char * sharename)29418474SJose.Borrego@Sun.COM srvsvc_sa_delete(char *sharename)
29428474SJose.Borrego@Sun.COM {
29438474SJose.Borrego@Sun.COM 	sa_handle_t handle;
29448474SJose.Borrego@Sun.COM 	sa_resource_t resource;
29458474SJose.Borrego@Sun.COM 	uint32_t status;
29468474SJose.Borrego@Sun.COM 
29478474SJose.Borrego@Sun.COM 	if ((handle = smb_shr_sa_enter()) == NULL)
29488474SJose.Borrego@Sun.COM 		return (NERR_InternalError);
29498474SJose.Borrego@Sun.COM 
29508474SJose.Borrego@Sun.COM 	status = NERR_InternalError;
29518474SJose.Borrego@Sun.COM 	if ((resource = sa_find_resource(handle, sharename)) != NULL) {
29528474SJose.Borrego@Sun.COM 		if (sa_remove_resource(resource) == SA_OK)
29538474SJose.Borrego@Sun.COM 			status = NERR_Success;
29548474SJose.Borrego@Sun.COM 	}
29558474SJose.Borrego@Sun.COM 
29568474SJose.Borrego@Sun.COM 	smb_shr_sa_exit();
29578474SJose.Borrego@Sun.COM 	return (status);
29588474SJose.Borrego@Sun.COM }
29598474SJose.Borrego@Sun.COM 
29609832Samw@Sun.COM /*
29619832Samw@Sun.COM  * Update the share information.
29629832Samw@Sun.COM  */
29639832Samw@Sun.COM static uint32_t
srvsvc_sa_modify(smb_share_t * si,srvsvc_netshare_setinfo_t * info)29649832Samw@Sun.COM srvsvc_sa_modify(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
29659832Samw@Sun.COM {
29669832Samw@Sun.COM 	sa_handle_t handle;
29679832Samw@Sun.COM 	sa_share_t share;
29689832Samw@Sun.COM 	sa_resource_t resource;
296912508Samw@Sun.COM 	boolean_t renamed = B_FALSE, is_zfs = B_FALSE;
297012508Samw@Sun.COM 	nvlist_t *nvl;
29719832Samw@Sun.COM 	uint32_t nerr = NERR_Success;
29729832Samw@Sun.COM 
29739832Samw@Sun.COM 	if ((handle = smb_shr_sa_enter()) == NULL)
29749832Samw@Sun.COM 		return (NERR_InternalError);
29759832Samw@Sun.COM 
29769832Samw@Sun.COM 	if ((share = sa_find_share(handle, si->shr_path)) == NULL) {
29779832Samw@Sun.COM 		smb_shr_sa_exit();
29789832Samw@Sun.COM 		return (NERR_InternalError);
29799832Samw@Sun.COM 	}
29809832Samw@Sun.COM 
29819832Samw@Sun.COM 	if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) {
29829832Samw@Sun.COM 		smb_shr_sa_exit();
29839832Samw@Sun.COM 		return (NERR_InternalError);
29849832Samw@Sun.COM 	}
29859832Samw@Sun.COM 
298612508Samw@Sun.COM 	if (sa_group_is_zfs(sa_get_parent_group(share))) {
298712508Samw@Sun.COM 		is_zfs = B_TRUE;
298812508Samw@Sun.COM 		if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
298912508Samw@Sun.COM 			smb_shr_sa_exit();
299012508Samw@Sun.COM 			return (NERR_InternalError);
299112508Samw@Sun.COM 		}
299212508Samw@Sun.COM 	}
299312508Samw@Sun.COM 
29949832Samw@Sun.COM 	if (info->nss_netname != NULL && info->nss_netname[0] != '\0' &&
299510966SJordan.Brown@Sun.COM 	    smb_strcasecmp(info->nss_netname, si->shr_name, 0) != 0) {
299612508Samw@Sun.COM 		if (is_zfs)
299712508Samw@Sun.COM 			(void) nvlist_add_string(nvl, SHOPT_NAME,
299812508Samw@Sun.COM 			    info->nss_netname);
299912508Samw@Sun.COM 		else
300012508Samw@Sun.COM 			(void) sa_set_resource_attr(resource, SHOPT_NAME,
300112508Samw@Sun.COM 			    info->nss_netname);
30029832Samw@Sun.COM 		renamed = B_TRUE;
30039832Samw@Sun.COM 	}
30049832Samw@Sun.COM 
30059832Samw@Sun.COM 	if ((info->nss_comment != NULL) &&
30069832Samw@Sun.COM 	    (strcmp(info->nss_comment, si->shr_cmnt) != 0)) {
300712508Samw@Sun.COM 		if (is_zfs)
300812508Samw@Sun.COM 			(void) nvlist_add_string(nvl, SHOPT_DESCRIPTION,
300912508Samw@Sun.COM 			    info->nss_comment);
301012508Samw@Sun.COM 		else
301112508Samw@Sun.COM 			(void) sa_set_resource_description(resource,
301212508Samw@Sun.COM 			    info->nss_comment);
30139832Samw@Sun.COM 		(void) strlcpy(si->shr_cmnt, info->nss_comment,
30149832Samw@Sun.COM 		    SMB_SHARE_CMNT_MAX);
30159832Samw@Sun.COM 	}
30169832Samw@Sun.COM 
301712508Samw@Sun.COM 	if (is_zfs) {
301812508Samw@Sun.COM 		if (sa_zfs_setprop(handle, si->shr_path, nvl) != 0) {
301912508Samw@Sun.COM 			smb_shr_sa_exit();
302012508Samw@Sun.COM 			nvlist_free(nvl);
302112508Samw@Sun.COM 			return (NERR_InternalError);
302212508Samw@Sun.COM 		}
302312508Samw@Sun.COM 		nvlist_free(nvl);
302412508Samw@Sun.COM 	}
30259832Samw@Sun.COM 	smb_shr_sa_exit();
30269832Samw@Sun.COM 
30279832Samw@Sun.COM 	if (renamed) {
30289832Samw@Sun.COM 		nerr = smb_shr_rename(si->shr_name, info->nss_netname);
30299832Samw@Sun.COM 		if (nerr != NERR_Success)
30309832Samw@Sun.COM 			return (nerr);
30319832Samw@Sun.COM 
30329832Samw@Sun.COM 		(void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN);
30339832Samw@Sun.COM 	}
30349832Samw@Sun.COM 
30359832Samw@Sun.COM 	return (nerr);
30369832Samw@Sun.COM }
30379832Samw@Sun.COM 
30389832Samw@Sun.COM /*
303912508Samw@Sun.COM  * Sets the share properties.
304010504SKeyur.Desai@Sun.COM  *
304112508Samw@Sun.COM  * This method sets share properties. If its a ZFS share, then properties
304212508Samw@Sun.COM  * are set by calling the sa_zfs_setprop method. Else the optionset properties
304312508Samw@Sun.COM  * of the share resource are set.The properties to be set are given as a list
304412508Samw@Sun.COM  * of name-value pair.
30459832Samw@Sun.COM  */
30469832Samw@Sun.COM static uint32_t
srvsvc_sa_setprop(smb_share_t * si,nvlist_t * nvl)304710504SKeyur.Desai@Sun.COM srvsvc_sa_setprop(smb_share_t *si, nvlist_t *nvl)
30489832Samw@Sun.COM {
30499832Samw@Sun.COM 	sa_handle_t handle;
30509832Samw@Sun.COM 	sa_share_t share;
30519832Samw@Sun.COM 	sa_resource_t resource;
305210504SKeyur.Desai@Sun.COM 	sa_property_t prop;
305310504SKeyur.Desai@Sun.COM 	sa_optionset_t opts;
305410504SKeyur.Desai@Sun.COM 	uint32_t nerr = NERR_Success;
305510504SKeyur.Desai@Sun.COM 	nvpair_t *cur;
305610504SKeyur.Desai@Sun.COM 	int err = 0;
305710504SKeyur.Desai@Sun.COM 	char *name, *val;
30589832Samw@Sun.COM 
305911963SAfshin.Ardakani@Sun.COM 	if ((handle = sa_init(SA_INIT_SHARE_API)) == NULL)
30609832Samw@Sun.COM 		return (NERR_InternalError);
30619832Samw@Sun.COM 
30629832Samw@Sun.COM 	if ((share = sa_find_share(handle, si->shr_path)) == NULL) {
306311963SAfshin.Ardakani@Sun.COM 		sa_fini(handle);
30649832Samw@Sun.COM 		return (NERR_InternalError);
30659832Samw@Sun.COM 	}
30669832Samw@Sun.COM 
30679832Samw@Sun.COM 	if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) {
306811963SAfshin.Ardakani@Sun.COM 		sa_fini(handle);
30699832Samw@Sun.COM 		return (NERR_InternalError);
30709832Samw@Sun.COM 	}
30719832Samw@Sun.COM 
307212508Samw@Sun.COM 	if (sa_group_is_zfs(sa_get_parent_group(share))) {
307312508Samw@Sun.COM 		if (sa_zfs_setprop(handle, si->shr_path, nvl) != 0)
307412508Samw@Sun.COM 			nerr = NERR_InternalError;
307512508Samw@Sun.COM 		sa_fini(handle);
307612508Samw@Sun.COM 		return (nerr);
307712508Samw@Sun.COM 	}
307812508Samw@Sun.COM 
307910504SKeyur.Desai@Sun.COM 	if ((opts = sa_get_optionset(resource, SMB_PROTOCOL_NAME)) == NULL) {
308010504SKeyur.Desai@Sun.COM 		opts = sa_create_optionset(resource, SMB_PROTOCOL_NAME);
308110504SKeyur.Desai@Sun.COM 		if (opts == NULL) {
308211963SAfshin.Ardakani@Sun.COM 			sa_fini(handle);
308310504SKeyur.Desai@Sun.COM 			return (NERR_InternalError);
308410504SKeyur.Desai@Sun.COM 		}
30859832Samw@Sun.COM 	}
30869832Samw@Sun.COM 
308710504SKeyur.Desai@Sun.COM 	cur = nvlist_next_nvpair(nvl, NULL);
308810504SKeyur.Desai@Sun.COM 	while (cur != NULL) {
308910504SKeyur.Desai@Sun.COM 		name = nvpair_name(cur);
309010504SKeyur.Desai@Sun.COM 		err = nvpair_value_string(cur, &val);
309110504SKeyur.Desai@Sun.COM 		if ((err != 0) || (name == NULL) || (val == NULL)) {
309210504SKeyur.Desai@Sun.COM 			nerr = NERR_InternalError;
309310504SKeyur.Desai@Sun.COM 			break;
309410504SKeyur.Desai@Sun.COM 		}
309510504SKeyur.Desai@Sun.COM 
309610504SKeyur.Desai@Sun.COM 		prop = NULL;
309710504SKeyur.Desai@Sun.COM 		if ((prop = sa_get_property(opts, name)) == NULL) {
309810504SKeyur.Desai@Sun.COM 			prop = sa_create_property(name, val);
309910504SKeyur.Desai@Sun.COM 			if (prop != NULL) {
310010504SKeyur.Desai@Sun.COM 				nerr = sa_valid_property(handle, opts,
310110504SKeyur.Desai@Sun.COM 				    SMB_PROTOCOL_NAME, prop);
310210504SKeyur.Desai@Sun.COM 				if (nerr != NERR_Success) {
310310504SKeyur.Desai@Sun.COM 					(void) sa_remove_property(prop);
310410504SKeyur.Desai@Sun.COM 					break;
310510504SKeyur.Desai@Sun.COM 				}
310610504SKeyur.Desai@Sun.COM 			}
310710504SKeyur.Desai@Sun.COM 			nerr = sa_add_property(opts, prop);
310810504SKeyur.Desai@Sun.COM 			if (nerr != NERR_Success)
310910504SKeyur.Desai@Sun.COM 				break;
311010504SKeyur.Desai@Sun.COM 		} else {
311110504SKeyur.Desai@Sun.COM 			nerr = sa_update_property(prop, val);
311210504SKeyur.Desai@Sun.COM 			if (nerr != NERR_Success)
311310504SKeyur.Desai@Sun.COM 				break;
311410504SKeyur.Desai@Sun.COM 		}
311510504SKeyur.Desai@Sun.COM 
311610504SKeyur.Desai@Sun.COM 		cur = nvlist_next_nvpair(nvl, cur);
311710504SKeyur.Desai@Sun.COM 	}
311810504SKeyur.Desai@Sun.COM 
311910504SKeyur.Desai@Sun.COM 	if (nerr == NERR_Success)
312010504SKeyur.Desai@Sun.COM 		nerr = sa_commit_properties(opts, 0);
312110504SKeyur.Desai@Sun.COM 
312211963SAfshin.Ardakani@Sun.COM 	sa_fini(handle);
312310504SKeyur.Desai@Sun.COM 	return (nerr);
31249832Samw@Sun.COM }
31259832Samw@Sun.COM 
31268474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[] = {
31278474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetConnectEnum,	SRVSVC_OPNUM_NetConnectEnum },
31288474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetFileEnum,		SRVSVC_OPNUM_NetFileEnum },
31298474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetFileClose,	SRVSVC_OPNUM_NetFileClose },
31308474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareGetInfo,	SRVSVC_OPNUM_NetShareGetInfo },
31318474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareSetInfo,	SRVSVC_OPNUM_NetShareSetInfo },
31328474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetSessionEnum,	SRVSVC_OPNUM_NetSessionEnum },
31338474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetSessionDel,	SRVSVC_OPNUM_NetSessionDel },
31348474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetServerGetInfo,	SRVSVC_OPNUM_NetServerGetInfo },
31358474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetRemoteTOD,	SRVSVC_OPNUM_NetRemoteTOD },
31368474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetNameValidate,	SRVSVC_OPNUM_NetNameValidate },
31378474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareAdd,		SRVSVC_OPNUM_NetShareAdd },
31388474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareDel,		SRVSVC_OPNUM_NetShareDel },
31398474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareEnum,	SRVSVC_OPNUM_NetShareEnum },
31408474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareEnumSticky,	SRVSVC_OPNUM_NetShareEnumSticky },
31419832Samw@Sun.COM 	{ srvsvc_s_NetShareCheck,	SRVSVC_OPNUM_NetShareCheck },
31428474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetGetFileSecurity,	SRVSVC_OPNUM_NetGetFileSecurity },
31438474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetSetFileSecurity,	SRVSVC_OPNUM_NetSetFileSecurity },
31448474SJose.Borrego@Sun.COM 	{0}
31458474SJose.Borrego@Sun.COM };
3146