xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c (revision 11337:1f8fe42c7b83)
18474SJose.Borrego@Sun.COM /*
28474SJose.Borrego@Sun.COM  * CDDL HEADER START
38474SJose.Borrego@Sun.COM  *
48474SJose.Borrego@Sun.COM  * The contents of this file are subject to the terms of the
58474SJose.Borrego@Sun.COM  * Common Development and Distribution License (the "License").
68474SJose.Borrego@Sun.COM  * You may not use this file except in compliance with the License.
78474SJose.Borrego@Sun.COM  *
88474SJose.Borrego@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98474SJose.Borrego@Sun.COM  * or http://www.opensolaris.org/os/licensing.
108474SJose.Borrego@Sun.COM  * See the License for the specific language governing permissions
118474SJose.Borrego@Sun.COM  * and limitations under the License.
128474SJose.Borrego@Sun.COM  *
138474SJose.Borrego@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
148474SJose.Borrego@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158474SJose.Borrego@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
168474SJose.Borrego@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
178474SJose.Borrego@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
188474SJose.Borrego@Sun.COM  *
198474SJose.Borrego@Sun.COM  * CDDL HEADER END
208474SJose.Borrego@Sun.COM  */
218474SJose.Borrego@Sun.COM /*
228474SJose.Borrego@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
238474SJose.Borrego@Sun.COM  * Use is subject to license terms.
248474SJose.Borrego@Sun.COM  */
258474SJose.Borrego@Sun.COM 
268474SJose.Borrego@Sun.COM /*
278474SJose.Borrego@Sun.COM  * Server Service RPC (SRVSVC) server-side interface definition.
288474SJose.Borrego@Sun.COM  * The server service provides a remote administration interface.
298474SJose.Borrego@Sun.COM  *
308474SJose.Borrego@Sun.COM  * This service uses NERR/Win32 error codes rather than NT status
318474SJose.Borrego@Sun.COM  * values.
328474SJose.Borrego@Sun.COM  */
338474SJose.Borrego@Sun.COM 
348474SJose.Borrego@Sun.COM #include <sys/errno.h>
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>
508474SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h>
518474SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h>
528474SJose.Borrego@Sun.COM #include <smbsrv/lmerr.h>
538474SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h>
5410966SJordan.Brown@Sun.COM #include <smbsrv/smb.h>
558474SJose.Borrego@Sun.COM #include <smbsrv/netrauth.h>
568474SJose.Borrego@Sun.COM #include <smbsrv/ndl/srvsvc.ndl>
578474SJose.Borrego@Sun.COM #include <smbsrv/smb_common_door.h>
589832Samw@Sun.COM #include "mlsvc.h"
598474SJose.Borrego@Sun.COM 
608474SJose.Borrego@Sun.COM /*
618474SJose.Borrego@Sun.COM  * Qualifier types for NetConnectEnum.
628474SJose.Borrego@Sun.COM  */
638474SJose.Borrego@Sun.COM #define	SRVSVC_CONNECT_ENUM_NULL	0
648474SJose.Borrego@Sun.COM #define	SRVSVC_CONNECT_ENUM_SHARE	1
658474SJose.Borrego@Sun.COM #define	SRVSVC_CONNECT_ENUM_WKSTN	2
668474SJose.Borrego@Sun.COM 
6710122SJordan.Brown@Sun.COM #define	SMB_SRVSVC_MAXBUFLEN		(8 * 1024 * 1024)
6810122SJordan.Brown@Sun.COM #define	SMB_SRVSVC_MAXPREFLEN		((uint32_t)(-1))
698474SJose.Borrego@Sun.COM 
709832Samw@Sun.COM typedef struct srvsvc_sd {
719832Samw@Sun.COM 	uint8_t *sd_buf;
729832Samw@Sun.COM 	uint32_t sd_size;
739832Samw@Sun.COM } srvsvc_sd_t;
749832Samw@Sun.COM 
759832Samw@Sun.COM typedef struct srvsvc_netshare_setinfo {
769832Samw@Sun.COM 	char *nss_netname;
779832Samw@Sun.COM 	char *nss_comment;
789832Samw@Sun.COM 	char *nss_path;
799832Samw@Sun.COM 	uint32_t nss_type;
809832Samw@Sun.COM 	srvsvc_sd_t nss_sd;
819832Samw@Sun.COM } srvsvc_netshare_setinfo_t;
829832Samw@Sun.COM 
839832Samw@Sun.COM typedef union srvsvc_netshare_getinfo {
849832Samw@Sun.COM 	struct mslm_NetShareInfo_0 nsg_info0;
859832Samw@Sun.COM 	struct mslm_NetShareInfo_1 nsg_info1;
869832Samw@Sun.COM 	struct mslm_NetShareInfo_2 nsg_info2;
879832Samw@Sun.COM 	struct mslm_NetShareInfo_501 nsg_info501;
889832Samw@Sun.COM 	struct mslm_NetShareInfo_502 nsg_info502;
899832Samw@Sun.COM 	struct mslm_NetShareInfo_503 nsg_info503;
909832Samw@Sun.COM 	struct mslm_NetShareInfo_1004 nsg_info1004;
919832Samw@Sun.COM 	struct mslm_NetShareInfo_1005 nsg_info1005;
929832Samw@Sun.COM 	struct mslm_NetShareInfo_1006 nsg_info1006;
939832Samw@Sun.COM 	struct mslm_NetShareInfo_1501 nsg_info1501;
949832Samw@Sun.COM } srvsvc_netshare_getinfo_t;
959832Samw@Sun.COM 
9610122SJordan.Brown@Sun.COM typedef struct mslm_infonres srvsvc_infonres_t;
9710122SJordan.Brown@Sun.COM typedef struct mslm_NetConnectEnum srvsvc_NetConnectEnum_t;
9810122SJordan.Brown@Sun.COM 
9910122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_level0(ndr_xa_t *, smb_svcenum_t *,
10010122SJordan.Brown@Sun.COM     srvsvc_NetConnectEnum_t *);
10110122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_level1(ndr_xa_t *, smb_svcenum_t *,
10210122SJordan.Brown@Sun.COM     srvsvc_NetConnectEnum_t *);
10310122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_common(ndr_xa_t *,
10410122SJordan.Brown@Sun.COM     srvsvc_NetConnectInfo_t *, smb_netsvc_t *, smb_svcenum_t *);
10510122SJordan.Brown@Sun.COM 
10610122SJordan.Brown@Sun.COM static DWORD srvsvc_NetFileEnum2(ndr_xa_t *, struct mslm_NetFileEnum *,
10710122SJordan.Brown@Sun.COM     smb_svcenum_t *se);
10810122SJordan.Brown@Sun.COM static DWORD srvsvc_NetFileEnum3(ndr_xa_t *, struct mslm_NetFileEnum *,
10910122SJordan.Brown@Sun.COM     smb_svcenum_t *se);
11010122SJordan.Brown@Sun.COM 
11110122SJordan.Brown@Sun.COM static uint32_t srvsvc_NetSessionEnumCommon(ndr_xa_t *, srvsvc_infonres_t *,
11210122SJordan.Brown@Sun.COM     smb_netsvc_t *, smb_svcenum_t *);
11310122SJordan.Brown@Sun.COM 
11410122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel0(ndr_xa_t *, srvsvc_infonres_t *,
11510122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
11610122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel1(ndr_xa_t *, srvsvc_infonres_t *,
11710122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
11810122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel2(ndr_xa_t *, srvsvc_infonres_t *,
11910122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
12010122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel501(ndr_xa_t *, srvsvc_infonres_t *,
12110122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
12210122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel502(ndr_xa_t *, srvsvc_infonres_t *,
12310122SJordan.Brown@Sun.COM     smb_svcenum_t *, int);
12410122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumCommon(ndr_xa_t *, smb_svcenum_t *,
12510122SJordan.Brown@Sun.COM     smb_share_t *, void *);
12610122SJordan.Brown@Sun.COM static boolean_t srvsvc_add_autohome(ndr_xa_t *, smb_svcenum_t *, void *);
1278474SJose.Borrego@Sun.COM static char *srvsvc_share_mkpath(ndr_xa_t *, char *);
1289832Samw@Sun.COM static uint32_t srvsvc_share_getsd(ndr_xa_t *, smb_share_t *, srvsvc_sd_t *);
1298474SJose.Borrego@Sun.COM 
1308474SJose.Borrego@Sun.COM static int srvsvc_netconnect_qualifier(const char *);
13110122SJordan.Brown@Sun.COM static void srvsvc_estimate_limit(smb_svcenum_t *, uint32_t);
13210122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_sessions(void);
13310122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_connections(uint32_t, const char *);
13410122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_files(void);
1358474SJose.Borrego@Sun.COM 
1369832Samw@Sun.COM static uint32_t srvsvc_modify_share(smb_share_t *,
1379832Samw@Sun.COM     srvsvc_netshare_setinfo_t *);
1389832Samw@Sun.COM static uint32_t srvsvc_modify_transient_share(smb_share_t *,
1399832Samw@Sun.COM     srvsvc_netshare_setinfo_t *);
1409832Samw@Sun.COM static uint32_t srvsvc_update_share_flags(smb_share_t *, uint32_t);
14110504SKeyur.Desai@Sun.COM static uint32_t srvsvc_get_share_flags(smb_share_t *);
1429832Samw@Sun.COM 
1438474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_add(char *, char *, char *);
1448474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_delete(char *);
1459832Samw@Sun.COM static uint32_t srvsvc_sa_modify(smb_share_t *, srvsvc_netshare_setinfo_t *);
14610504SKeyur.Desai@Sun.COM static uint32_t srvsvc_sa_setprop(smb_share_t *, nvlist_t *);
1478474SJose.Borrego@Sun.COM 
1488474SJose.Borrego@Sun.COM static char empty_string[1];
1498474SJose.Borrego@Sun.COM 
1508474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[];
1518474SJose.Borrego@Sun.COM 
1528474SJose.Borrego@Sun.COM static ndr_service_t srvsvc_service = {
1538474SJose.Borrego@Sun.COM 	"SRVSVC",			/* name */
1548474SJose.Borrego@Sun.COM 	"Server services",		/* desc */
1558474SJose.Borrego@Sun.COM 	"\\srvsvc",			/* endpoint */
1568474SJose.Borrego@Sun.COM 	PIPE_NTSVCS,			/* sec_addr_port */
1578474SJose.Borrego@Sun.COM 	"4b324fc8-1670-01d3-1278-5a47bf6ee188", 3,	/* abstract */
1588474SJose.Borrego@Sun.COM 	NDR_TRANSFER_SYNTAX_UUID,		2,	/* transfer */
1598474SJose.Borrego@Sun.COM 	0,				/* no bind_instance_size */
1608474SJose.Borrego@Sun.COM 	0,				/* no bind_req() */
1618474SJose.Borrego@Sun.COM 	0,				/* no unbind_and_close() */
1628474SJose.Borrego@Sun.COM 	0,				/* use generic_call_stub() */
1638474SJose.Borrego@Sun.COM 	&TYPEINFO(srvsvc_interface),	/* interface ti */
1648474SJose.Borrego@Sun.COM 	srvsvc_stub_table		/* stub_table */
1658474SJose.Borrego@Sun.COM };
1668474SJose.Borrego@Sun.COM 
1678474SJose.Borrego@Sun.COM /*
1688474SJose.Borrego@Sun.COM  * srvsvc_initialize
1698474SJose.Borrego@Sun.COM  *
1708474SJose.Borrego@Sun.COM  * This function registers the SRVSVC RPC interface with the RPC runtime
1718474SJose.Borrego@Sun.COM  * library. It must be called in order to use either the client side
1728474SJose.Borrego@Sun.COM  * or the server side functions.
1738474SJose.Borrego@Sun.COM  */
1748474SJose.Borrego@Sun.COM void
1758474SJose.Borrego@Sun.COM srvsvc_initialize(void)
1768474SJose.Borrego@Sun.COM {
1778474SJose.Borrego@Sun.COM 	(void) ndr_svc_register(&srvsvc_service);
1788474SJose.Borrego@Sun.COM }
1798474SJose.Borrego@Sun.COM 
1808474SJose.Borrego@Sun.COM /*
1818474SJose.Borrego@Sun.COM  * srvsvc_s_NetConnectEnum
1828474SJose.Borrego@Sun.COM  *
1838474SJose.Borrego@Sun.COM  * List tree connections made to a share on this server or all tree
1848474SJose.Borrego@Sun.COM  * connections established from a specific client.  Administrator,
1858474SJose.Borrego@Sun.COM  * Server Operator, Print Operator or Power User group membership
1868474SJose.Borrego@Sun.COM  * is required to use this interface.
1878474SJose.Borrego@Sun.COM  *
1888474SJose.Borrego@Sun.COM  * There are three information levels:  0, 1, and 50.  We don't support
1898474SJose.Borrego@Sun.COM  * level 50, which is only used by Windows 9x clients.
1908474SJose.Borrego@Sun.COM  *
1918474SJose.Borrego@Sun.COM  * It seems Server Manger (srvmgr) only sends workstation as the qualifier
1928474SJose.Borrego@Sun.COM  * and the Computer Management Interface on Windows 2000 doesn't request
1938474SJose.Borrego@Sun.COM  * a list of connections.
1948474SJose.Borrego@Sun.COM  *
1958474SJose.Borrego@Sun.COM  * Return Values:
1968474SJose.Borrego@Sun.COM  * ERROR_SUCCESS            Success
1978474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED      Caller does not have access to this call.
1988474SJose.Borrego@Sun.COM  * ERROR_INVALID_PARAMETER  One of the parameters is invalid.
1998474SJose.Borrego@Sun.COM  * ERROR_INVALID_LEVEL      Unknown information level specified.
2008474SJose.Borrego@Sun.COM  * ERROR_MORE_DATA          Partial date returned, more entries available.
2018474SJose.Borrego@Sun.COM  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
2028474SJose.Borrego@Sun.COM  * NERR_NetNameNotFound     The share qualifier cannot be found.
2038474SJose.Borrego@Sun.COM  * NERR_BufTooSmall         The supplied buffer is too small.
2048474SJose.Borrego@Sun.COM  */
2058474SJose.Borrego@Sun.COM static int
2068474SJose.Borrego@Sun.COM srvsvc_s_NetConnectEnum(void *arg, ndr_xa_t *mxa)
2078474SJose.Borrego@Sun.COM {
20810122SJordan.Brown@Sun.COM 	srvsvc_NetConnectEnum_t		*param = arg;
20910122SJordan.Brown@Sun.COM 	smb_netsvc_t			*ns;
21010122SJordan.Brown@Sun.COM 	smb_svcenum_t			se;
21110122SJordan.Brown@Sun.COM 	char				*qualifier;
21210122SJordan.Brown@Sun.COM 	int				qualtype;
21310122SJordan.Brown@Sun.COM 	DWORD				status = ERROR_SUCCESS;
2148474SJose.Borrego@Sun.COM 
2158474SJose.Borrego@Sun.COM 	if (!ndr_is_poweruser(mxa)) {
21610122SJordan.Brown@Sun.COM 		status = ERROR_ACCESS_DENIED;
21710122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
2188474SJose.Borrego@Sun.COM 	}
2198474SJose.Borrego@Sun.COM 
2208474SJose.Borrego@Sun.COM 	qualifier = (char *)param->qualifier;
2218474SJose.Borrego@Sun.COM 	qualtype = srvsvc_netconnect_qualifier(qualifier);
2228474SJose.Borrego@Sun.COM 	if (qualtype == SRVSVC_CONNECT_ENUM_NULL) {
22310122SJordan.Brown@Sun.COM 		status = NERR_NetNameNotFound;
22410122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
22510122SJordan.Brown@Sun.COM 	}
22610122SJordan.Brown@Sun.COM 
22710122SJordan.Brown@Sun.COM 	param->total_entries = srvsvc_open_connections(qualtype, qualifier);
22810122SJordan.Brown@Sun.COM 	if (param->total_entries == 0) {
22910122SJordan.Brown@Sun.COM 		bzero(param, sizeof (srvsvc_NetConnectEnum_t));
23010122SJordan.Brown@Sun.COM 		param->status = ERROR_SUCCESS;
2318474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
2328474SJose.Borrego@Sun.COM 	}
2338474SJose.Borrego@Sun.COM 
23410122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
23510122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_TREE;
23610122SJordan.Brown@Sun.COM 	se.se_level = param->info.level;
23710122SJordan.Brown@Sun.COM 	se.se_ntotal = param->total_entries;
23810122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
23910122SJordan.Brown@Sun.COM 
24010122SJordan.Brown@Sun.COM 	if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN ||
24110122SJordan.Brown@Sun.COM 	    param->pref_max_len > SMB_SRVSVC_MAXBUFLEN)
24210122SJordan.Brown@Sun.COM 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
24310122SJordan.Brown@Sun.COM 	else
24410122SJordan.Brown@Sun.COM 		se.se_prefmaxlen = param->pref_max_len;
24510122SJordan.Brown@Sun.COM 
24610122SJordan.Brown@Sun.COM 	if (param->resume_handle) {
24710122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
24810122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
24910122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
25010122SJordan.Brown@Sun.COM 	}
25110122SJordan.Brown@Sun.COM 
2528474SJose.Borrego@Sun.COM 	switch (param->info.level) {
2538474SJose.Borrego@Sun.COM 	case 0:
25410122SJordan.Brown@Sun.COM 		status = srvsvc_netconnectenum_level0(mxa, &se, param);
2558474SJose.Borrego@Sun.COM 		break;
2568474SJose.Borrego@Sun.COM 	case 1:
25710122SJordan.Brown@Sun.COM 		status = srvsvc_netconnectenum_level1(mxa, &se, param);
2588474SJose.Borrego@Sun.COM 		break;
2598474SJose.Borrego@Sun.COM 	case 50:
2608474SJose.Borrego@Sun.COM 		status = ERROR_NOT_SUPPORTED;
2618474SJose.Borrego@Sun.COM 		break;
2628474SJose.Borrego@Sun.COM 	default:
2638474SJose.Borrego@Sun.COM 		status = ERROR_INVALID_LEVEL;
2648474SJose.Borrego@Sun.COM 		break;
2658474SJose.Borrego@Sun.COM 	}
2668474SJose.Borrego@Sun.COM 
2678474SJose.Borrego@Sun.COM 	if (status != ERROR_SUCCESS)
26810122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
26910122SJordan.Brown@Sun.COM 
27010122SJordan.Brown@Sun.COM 	if ((ns = smb_kmod_enum_init(&se)) == NULL) {
27110122SJordan.Brown@Sun.COM 		status = ERROR_NOT_ENOUGH_MEMORY;
27210122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
27310122SJordan.Brown@Sun.COM 	}
27410122SJordan.Brown@Sun.COM 
27510122SJordan.Brown@Sun.COM 	status = srvsvc_netconnectenum_common(mxa, &param->info, ns, &se);
27610122SJordan.Brown@Sun.COM 	smb_kmod_enum_fini(ns);
27710122SJordan.Brown@Sun.COM 
27810122SJordan.Brown@Sun.COM 	if (status != ERROR_SUCCESS)
27910122SJordan.Brown@Sun.COM 		goto srvsvc_netconnectenum_error;
28010122SJordan.Brown@Sun.COM 
28110122SJordan.Brown@Sun.COM 	if (param->resume_handle &&
28210122SJordan.Brown@Sun.COM 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
28310122SJordan.Brown@Sun.COM 		if (se.se_resume < param->total_entries) {
28410122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
28510122SJordan.Brown@Sun.COM 			status = ERROR_MORE_DATA;
28610122SJordan.Brown@Sun.COM 		}
28710122SJordan.Brown@Sun.COM 	}
28810122SJordan.Brown@Sun.COM 
28910122SJordan.Brown@Sun.COM 	param->status = status;
29010122SJordan.Brown@Sun.COM 	return (NDR_DRC_OK);
29110122SJordan.Brown@Sun.COM 
29210122SJordan.Brown@Sun.COM srvsvc_netconnectenum_error:
29310122SJordan.Brown@Sun.COM 	bzero(param, sizeof (srvsvc_NetConnectEnum_t));
2948474SJose.Borrego@Sun.COM 	param->status = status;
2958474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
2968474SJose.Borrego@Sun.COM }
2978474SJose.Borrego@Sun.COM 
29810122SJordan.Brown@Sun.COM /*
29910122SJordan.Brown@Sun.COM  * Allocate memory and estimate the number of objects that can
30010122SJordan.Brown@Sun.COM  * be returned for NetConnectEnum level 0.
30110122SJordan.Brown@Sun.COM  */
30210122SJordan.Brown@Sun.COM static uint32_t
30310122SJordan.Brown@Sun.COM srvsvc_netconnectenum_level0(ndr_xa_t *mxa, smb_svcenum_t *se,
30410122SJordan.Brown@Sun.COM     srvsvc_NetConnectEnum_t *param)
3058474SJose.Borrego@Sun.COM {
30610122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfo0_t	*info0;
30710122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfoBuf0_t	*ci0;
30810122SJordan.Brown@Sun.COM 
30910122SJordan.Brown@Sun.COM 	if ((info0 = NDR_NEW(mxa, srvsvc_NetConnectInfo0_t)) == NULL)
31010122SJordan.Brown@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
31110122SJordan.Brown@Sun.COM 
31210122SJordan.Brown@Sun.COM 	bzero(info0, sizeof (srvsvc_NetConnectInfo0_t));
31310122SJordan.Brown@Sun.COM 	param->info.ru.info0 = info0;
31410122SJordan.Brown@Sun.COM 
31510122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se, sizeof (srvsvc_NetConnectInfoBuf0_t));
31610122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
31710122SJordan.Brown@Sun.COM 		return (NERR_BufTooSmall);
31810122SJordan.Brown@Sun.COM 
31910122SJordan.Brown@Sun.COM 	do {
32010122SJordan.Brown@Sun.COM 		ci0 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf0_t, se->se_nlimit);
32110122SJordan.Brown@Sun.COM 		if (ci0 == NULL)
32210122SJordan.Brown@Sun.COM 			se->se_nlimit >>= 1;
32310122SJordan.Brown@Sun.COM 	} while ((se->se_nlimit > 0) && (ci0 == NULL));
32410122SJordan.Brown@Sun.COM 
3258474SJose.Borrego@Sun.COM 	if (ci0 == NULL)
3268474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
3278474SJose.Borrego@Sun.COM 
3288474SJose.Borrego@Sun.COM 	info0->ci0 = ci0;
32910122SJordan.Brown@Sun.COM 	info0->entries_read = 0;
3308474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
3318474SJose.Borrego@Sun.COM }
3328474SJose.Borrego@Sun.COM 
33310122SJordan.Brown@Sun.COM /*
33410122SJordan.Brown@Sun.COM  * Allocate memory and estimate the number of objects that can
33510122SJordan.Brown@Sun.COM  * be returned for NetConnectEnum level 1.
33610122SJordan.Brown@Sun.COM  */
33710122SJordan.Brown@Sun.COM static uint32_t
33810122SJordan.Brown@Sun.COM srvsvc_netconnectenum_level1(ndr_xa_t *mxa, smb_svcenum_t *se,
33910122SJordan.Brown@Sun.COM     srvsvc_NetConnectEnum_t *param)
3408474SJose.Borrego@Sun.COM {
34110122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfo1_t	*info1;
34210122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfoBuf1_t	*ci1;
34310122SJordan.Brown@Sun.COM 
34410122SJordan.Brown@Sun.COM 	if ((info1 = NDR_NEW(mxa, srvsvc_NetConnectInfo1_t)) == NULL)
34510122SJordan.Brown@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
34610122SJordan.Brown@Sun.COM 
34710122SJordan.Brown@Sun.COM 	bzero(info1, sizeof (srvsvc_NetConnectInfo1_t));
34810122SJordan.Brown@Sun.COM 	param->info.ru.info1 = info1;
34910122SJordan.Brown@Sun.COM 
35010122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
35110122SJordan.Brown@Sun.COM 	    sizeof (srvsvc_NetConnectInfoBuf1_t) + MAXNAMELEN);
35210122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
35310122SJordan.Brown@Sun.COM 		return (NERR_BufTooSmall);
35410122SJordan.Brown@Sun.COM 
35510122SJordan.Brown@Sun.COM 	do {
35610122SJordan.Brown@Sun.COM 		ci1 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf1_t, se->se_nlimit);
35710122SJordan.Brown@Sun.COM 		if (ci1 == NULL)
35810122SJordan.Brown@Sun.COM 			se->se_nlimit >>= 1;
35910122SJordan.Brown@Sun.COM 	} while ((se->se_nlimit > 0) && (ci1 == NULL));
36010122SJordan.Brown@Sun.COM 
3618474SJose.Borrego@Sun.COM 	if (ci1 == NULL)
3628474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
3638474SJose.Borrego@Sun.COM 
3648474SJose.Borrego@Sun.COM 	info1->ci1 = ci1;
36510122SJordan.Brown@Sun.COM 	info1->entries_read = 0;
36610122SJordan.Brown@Sun.COM 	return (ERROR_SUCCESS);
36710122SJordan.Brown@Sun.COM }
36810122SJordan.Brown@Sun.COM 
36910122SJordan.Brown@Sun.COM /*
37010122SJordan.Brown@Sun.COM  * Request a list of connections from the kernel and set up
37110122SJordan.Brown@Sun.COM  * the connection information to be returned to the client.
37210122SJordan.Brown@Sun.COM  */
37310122SJordan.Brown@Sun.COM static uint32_t
37410122SJordan.Brown@Sun.COM srvsvc_netconnectenum_common(ndr_xa_t *mxa, srvsvc_NetConnectInfo_t *info,
37510122SJordan.Brown@Sun.COM     smb_netsvc_t *ns, smb_svcenum_t *se)
37610122SJordan.Brown@Sun.COM {
37710122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfo0_t	*info0;
37810122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfo1_t	*info1;
37910122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfoBuf0_t	*ci0;
38010122SJordan.Brown@Sun.COM 	srvsvc_NetConnectInfoBuf1_t	*ci1;
38110122SJordan.Brown@Sun.COM 	smb_netsvcitem_t		*item;
38210122SJordan.Brown@Sun.COM 	smb_netconnectinfo_t		*tree;
38310122SJordan.Brown@Sun.COM 
38410122SJordan.Brown@Sun.COM 	if (smb_kmod_enum(ns) != 0)
38510122SJordan.Brown@Sun.COM 		return (ERROR_INTERNAL_ERROR);
38610122SJordan.Brown@Sun.COM 
38710122SJordan.Brown@Sun.COM 	info0 = info->ru.info0;
38810122SJordan.Brown@Sun.COM 	ci0 = info0->ci0;
38910122SJordan.Brown@Sun.COM 
39010122SJordan.Brown@Sun.COM 	info1 = info->ru.info1;
39110122SJordan.Brown@Sun.COM 	ci1 = info1->ci1;
39210122SJordan.Brown@Sun.COM 
39310122SJordan.Brown@Sun.COM 	item = list_head(&ns->ns_list);
39410122SJordan.Brown@Sun.COM 	while (item != NULL) {
39510122SJordan.Brown@Sun.COM 		tree = &item->nsi_un.nsi_tree;
39610122SJordan.Brown@Sun.COM 
39710122SJordan.Brown@Sun.COM 		switch (se->se_level) {
39810122SJordan.Brown@Sun.COM 		case 0:
39910122SJordan.Brown@Sun.COM 			ci0->coni0_id = tree->ci_id;
40010122SJordan.Brown@Sun.COM 			++ci0;
40110122SJordan.Brown@Sun.COM 			++info0->entries_read;
40210122SJordan.Brown@Sun.COM 			break;
40310122SJordan.Brown@Sun.COM 		case 1:
40410122SJordan.Brown@Sun.COM 			ci1->coni1_id = tree->ci_id;
40510122SJordan.Brown@Sun.COM 			ci1->coni1_type = tree->ci_type;
40610122SJordan.Brown@Sun.COM 			ci1->coni1_num_opens = tree->ci_numopens;
40710122SJordan.Brown@Sun.COM 			ci1->coni1_num_users = tree->ci_numusers;
40810122SJordan.Brown@Sun.COM 			ci1->coni1_time = tree->ci_time;
40910122SJordan.Brown@Sun.COM 			ci1->coni1_username = (uint8_t *)
41010122SJordan.Brown@Sun.COM 			    NDR_STRDUP(mxa, tree->ci_username);
41110122SJordan.Brown@Sun.COM 			ci1->coni1_netname = (uint8_t *)
41210122SJordan.Brown@Sun.COM 			    NDR_STRDUP(mxa, tree->ci_share);
41310122SJordan.Brown@Sun.COM 			++ci1;
41410122SJordan.Brown@Sun.COM 			++info1->entries_read;
41510122SJordan.Brown@Sun.COM 			break;
41610122SJordan.Brown@Sun.COM 		default:
41710122SJordan.Brown@Sun.COM 			return (ERROR_INVALID_LEVEL);
41810122SJordan.Brown@Sun.COM 		}
41910122SJordan.Brown@Sun.COM 
42010122SJordan.Brown@Sun.COM 		++se->se_resume;
42110122SJordan.Brown@Sun.COM 		item = list_next(&ns->ns_list, item);
42210122SJordan.Brown@Sun.COM 	}
42310122SJordan.Brown@Sun.COM 
4248474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
4258474SJose.Borrego@Sun.COM }
4268474SJose.Borrego@Sun.COM 
4278474SJose.Borrego@Sun.COM /*
4288474SJose.Borrego@Sun.COM  * srvsvc_netconnect_qualifier
4298474SJose.Borrego@Sun.COM  *
4308474SJose.Borrego@Sun.COM  * The qualifier is a string that specifies a share name or computer name
4318474SJose.Borrego@Sun.COM  * for the connections of interest.  If it is a share name then all the
4328474SJose.Borrego@Sun.COM  * connections made to that share name are listed.  If it is a computer
4338474SJose.Borrego@Sun.COM  * name (it starts with two backslash characters), then NetConnectEnum
4348474SJose.Borrego@Sun.COM  * lists all connections made from that computer to the specified server.
4358474SJose.Borrego@Sun.COM  */
4368474SJose.Borrego@Sun.COM static int
4378474SJose.Borrego@Sun.COM srvsvc_netconnect_qualifier(const char *qualifier)
4388474SJose.Borrego@Sun.COM {
4398474SJose.Borrego@Sun.COM 	if (qualifier == NULL || *qualifier == '\0')
4408474SJose.Borrego@Sun.COM 		return (SRVSVC_CONNECT_ENUM_NULL);
4418474SJose.Borrego@Sun.COM 
4428474SJose.Borrego@Sun.COM 	if (strlen(qualifier) > MAXHOSTNAMELEN)
4438474SJose.Borrego@Sun.COM 		return (SRVSVC_CONNECT_ENUM_NULL);
4448474SJose.Borrego@Sun.COM 
4458474SJose.Borrego@Sun.COM 	if (qualifier[0] == '\\' && qualifier[1] == '\\') {
4468474SJose.Borrego@Sun.COM 		return (SRVSVC_CONNECT_ENUM_WKSTN);
4478474SJose.Borrego@Sun.COM 	} else {
4488474SJose.Borrego@Sun.COM 		if (!smb_shr_exists((char *)qualifier))
4498474SJose.Borrego@Sun.COM 			return (SRVSVC_CONNECT_ENUM_NULL);
4508474SJose.Borrego@Sun.COM 
4518474SJose.Borrego@Sun.COM 		return (SRVSVC_CONNECT_ENUM_SHARE);
4528474SJose.Borrego@Sun.COM 	}
4538474SJose.Borrego@Sun.COM }
4548474SJose.Borrego@Sun.COM 
45510122SJordan.Brown@Sun.COM static uint32_t
45610122SJordan.Brown@Sun.COM srvsvc_open_sessions(void)
45710122SJordan.Brown@Sun.COM {
45810122SJordan.Brown@Sun.COM 	smb_opennum_t	opennum;
45910122SJordan.Brown@Sun.COM 
46010122SJordan.Brown@Sun.COM 	bzero(&opennum, sizeof (smb_opennum_t));
46110122SJordan.Brown@Sun.COM 	if (smb_kmod_get_open_num(&opennum) != 0)
46210122SJordan.Brown@Sun.COM 		return (0);
46310122SJordan.Brown@Sun.COM 
46410122SJordan.Brown@Sun.COM 	return (opennum.open_users);
46510122SJordan.Brown@Sun.COM }
46610122SJordan.Brown@Sun.COM 
46710122SJordan.Brown@Sun.COM static uint32_t
46810122SJordan.Brown@Sun.COM srvsvc_open_connections(uint32_t qualtype, const char *qualifier)
46910122SJordan.Brown@Sun.COM {
47010122SJordan.Brown@Sun.COM 	smb_opennum_t	opennum;
47110122SJordan.Brown@Sun.COM 
47210122SJordan.Brown@Sun.COM 	bzero(&opennum, sizeof (smb_opennum_t));
47310122SJordan.Brown@Sun.COM 	opennum.qualtype = qualtype;
47410122SJordan.Brown@Sun.COM 	(void) strlcpy(opennum.qualifier, qualifier, MAXNAMELEN);
47510122SJordan.Brown@Sun.COM 
47610122SJordan.Brown@Sun.COM 	if (smb_kmod_get_open_num(&opennum) != 0)
47710122SJordan.Brown@Sun.COM 		return (0);
47810122SJordan.Brown@Sun.COM 
47910122SJordan.Brown@Sun.COM 	return (opennum.open_trees);
48010122SJordan.Brown@Sun.COM }
48110122SJordan.Brown@Sun.COM 
48210122SJordan.Brown@Sun.COM static uint32_t
48310122SJordan.Brown@Sun.COM srvsvc_open_files(void)
48410122SJordan.Brown@Sun.COM {
48510122SJordan.Brown@Sun.COM 	smb_opennum_t	opennum;
48610122SJordan.Brown@Sun.COM 
48710122SJordan.Brown@Sun.COM 	bzero(&opennum, sizeof (smb_opennum_t));
48810122SJordan.Brown@Sun.COM 	if (smb_kmod_get_open_num(&opennum) != 0)
48910122SJordan.Brown@Sun.COM 		return (0);
49010122SJordan.Brown@Sun.COM 
49110122SJordan.Brown@Sun.COM 	return (opennum.open_files);
49210122SJordan.Brown@Sun.COM }
49310122SJordan.Brown@Sun.COM 
4948474SJose.Borrego@Sun.COM /*
4958474SJose.Borrego@Sun.COM  * srvsvc_s_NetFileEnum
4968474SJose.Borrego@Sun.COM  *
4978474SJose.Borrego@Sun.COM  * Return information on open files or named pipes. Only members of the
4988474SJose.Borrego@Sun.COM  * Administrators or Server Operators local groups are allowed to make
4998474SJose.Borrego@Sun.COM  * this call. Currently, we only support Administrators.
5008474SJose.Borrego@Sun.COM  *
5018474SJose.Borrego@Sun.COM  * If basepath is null, all open resources are enumerated. If basepath
5028474SJose.Borrego@Sun.COM  * is non-null, only resources that have basepath as a prefix should
5038474SJose.Borrego@Sun.COM  * be returned.
5048474SJose.Borrego@Sun.COM  *
5058474SJose.Borrego@Sun.COM  * If username is specified (non-null), only files opened by username
5068474SJose.Borrego@Sun.COM  * should be returned.
5078474SJose.Borrego@Sun.COM  *
5088474SJose.Borrego@Sun.COM  * Notes:
5098474SJose.Borrego@Sun.COM  * 1. We don't validate the servername because we would have to check
5108474SJose.Borrego@Sun.COM  * all primary IPs and the ROI seems unlikely to be worth it.
5118474SJose.Borrego@Sun.COM  * 2. Both basepath and username are currently ignored because both
5128474SJose.Borrego@Sun.COM  * Server Manger (NT 4.0) and CMI (Windows 2000) always set them to null.
5138474SJose.Borrego@Sun.COM  *
5148474SJose.Borrego@Sun.COM  * The level of information requested may be one of:
5158474SJose.Borrego@Sun.COM  *
5168474SJose.Borrego@Sun.COM  *  2   Return the file identification number.
5178474SJose.Borrego@Sun.COM  *      This level is not supported on Windows Me/98/95.
5188474SJose.Borrego@Sun.COM  *
5198474SJose.Borrego@Sun.COM  *  3   Return information about the file.
5208474SJose.Borrego@Sun.COM  *      This level is not supported on Windows Me/98/95.
5218474SJose.Borrego@Sun.COM  *
5228474SJose.Borrego@Sun.COM  *  50  Windows Me/98/95:  Return information about the file.
5238474SJose.Borrego@Sun.COM  *
5248474SJose.Borrego@Sun.COM  * Note:
5258474SJose.Borrego@Sun.COM  * If pref_max_len is unlimited and resume_handle is null, the client
5268474SJose.Borrego@Sun.COM  * expects to receive all data in a single call.
5278474SJose.Borrego@Sun.COM  * If we are unable to do fit all data in a single response, we would
5288474SJose.Borrego@Sun.COM  * normally return ERROR_MORE_DATA with a partial list.
5298474SJose.Borrego@Sun.COM  *
5308474SJose.Borrego@Sun.COM  * Unfortunately, when both of these conditions occur, Server Manager
5318474SJose.Borrego@Sun.COM  * pops up an error box with the message "more data available" and
5328474SJose.Borrego@Sun.COM  * doesn't display any of the returned data. In this case, it is
5338474SJose.Borrego@Sun.COM  * probably better to return ERROR_SUCCESS with the partial list.
5348474SJose.Borrego@Sun.COM  * Windows 2000 doesn't have this problem because it always sends a
5358474SJose.Borrego@Sun.COM  * non-null resume_handle.
5368474SJose.Borrego@Sun.COM  *
5378474SJose.Borrego@Sun.COM  * Return Values:
5388474SJose.Borrego@Sun.COM  * ERROR_SUCCESS            Success
5398474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED      Caller does not have access to this call.
5408474SJose.Borrego@Sun.COM  * ERROR_INVALID_PARAMETER  One of the parameters is invalid.
5418474SJose.Borrego@Sun.COM  * ERROR_INVALID_LEVEL      Unknown information level specified.
5428474SJose.Borrego@Sun.COM  * ERROR_MORE_DATA          Partial date returned, more entries available.
5438474SJose.Borrego@Sun.COM  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
5448474SJose.Borrego@Sun.COM  * NERR_BufTooSmall         The supplied buffer is too small.
5458474SJose.Borrego@Sun.COM  */
5468474SJose.Borrego@Sun.COM static int
5478474SJose.Borrego@Sun.COM srvsvc_s_NetFileEnum(void *arg, ndr_xa_t *mxa)
5488474SJose.Borrego@Sun.COM {
54910122SJordan.Brown@Sun.COM 	struct mslm_NetFileEnum	*param = arg;
55010122SJordan.Brown@Sun.COM 	smb_svcenum_t		se;
55110122SJordan.Brown@Sun.COM 	DWORD			status;
5528474SJose.Borrego@Sun.COM 
5538474SJose.Borrego@Sun.COM 	if (!ndr_is_admin(mxa)) {
5548474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetFileEnum));
5558474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
5568474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
5578474SJose.Borrego@Sun.COM 	}
5588474SJose.Borrego@Sun.COM 
55910122SJordan.Brown@Sun.COM 	if ((param->total_entries = srvsvc_open_files()) == 0) {
56010122SJordan.Brown@Sun.COM 		bzero(param, sizeof (struct mslm_NetFileEnum));
56110122SJordan.Brown@Sun.COM 		param->status = ERROR_SUCCESS;
56210122SJordan.Brown@Sun.COM 		return (NDR_DRC_OK);
56310122SJordan.Brown@Sun.COM 	}
56410122SJordan.Brown@Sun.COM 
56510122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
56610122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_FILE;
56710122SJordan.Brown@Sun.COM 	se.se_level = param->info.switch_value;
56810122SJordan.Brown@Sun.COM 	se.se_ntotal = param->total_entries;
56910122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
57010122SJordan.Brown@Sun.COM 
57110122SJordan.Brown@Sun.COM 	if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN ||
57210122SJordan.Brown@Sun.COM 	    param->pref_max_len > SMB_SRVSVC_MAXBUFLEN)
57310122SJordan.Brown@Sun.COM 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
57410122SJordan.Brown@Sun.COM 	else
57510122SJordan.Brown@Sun.COM 		se.se_prefmaxlen = param->pref_max_len;
57610122SJordan.Brown@Sun.COM 
57710122SJordan.Brown@Sun.COM 	if (param->resume_handle) {
57810122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
57910122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
58010122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
58110122SJordan.Brown@Sun.COM 	}
58210122SJordan.Brown@Sun.COM 
5838474SJose.Borrego@Sun.COM 	switch (param->info.switch_value) {
5848474SJose.Borrego@Sun.COM 	case 2:
58510122SJordan.Brown@Sun.COM 		status = srvsvc_NetFileEnum2(mxa, param, &se);
5868474SJose.Borrego@Sun.COM 		break;
5878474SJose.Borrego@Sun.COM 
5888474SJose.Borrego@Sun.COM 	case 3:
58910122SJordan.Brown@Sun.COM 		status = srvsvc_NetFileEnum3(mxa, param, &se);
5908474SJose.Borrego@Sun.COM 		break;
5918474SJose.Borrego@Sun.COM 
5928474SJose.Borrego@Sun.COM 	case 50:
5938474SJose.Borrego@Sun.COM 		status = ERROR_NOT_SUPPORTED;
5948474SJose.Borrego@Sun.COM 		break;
5958474SJose.Borrego@Sun.COM 
5968474SJose.Borrego@Sun.COM 	default:
5978474SJose.Borrego@Sun.COM 		status = ERROR_INVALID_LEVEL;
5988474SJose.Borrego@Sun.COM 		break;
5998474SJose.Borrego@Sun.COM 	}
6008474SJose.Borrego@Sun.COM 
6018474SJose.Borrego@Sun.COM 	if (status != ERROR_SUCCESS) {
6028474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetFileEnum));
6038474SJose.Borrego@Sun.COM 		param->status = status;
6048474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
6058474SJose.Borrego@Sun.COM 	}
6068474SJose.Borrego@Sun.COM 
60710122SJordan.Brown@Sun.COM 	if (param->resume_handle &&
60810122SJordan.Brown@Sun.COM 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
60910122SJordan.Brown@Sun.COM 		if (se.se_resume < param->total_entries) {
61010122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
61110122SJordan.Brown@Sun.COM 			status = ERROR_MORE_DATA;
61210122SJordan.Brown@Sun.COM 		}
61310122SJordan.Brown@Sun.COM 	}
61410122SJordan.Brown@Sun.COM 
61510122SJordan.Brown@Sun.COM 	param->status = status;
6168474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
6178474SJose.Borrego@Sun.COM }
6188474SJose.Borrego@Sun.COM 
6198474SJose.Borrego@Sun.COM /*
6208474SJose.Borrego@Sun.COM  * Build level 2 file information.
6218474SJose.Borrego@Sun.COM  *
62210122SJordan.Brown@Sun.COM  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
62310122SJordan.Brown@Sun.COM  * So we use the uniqid here.
62410122SJordan.Brown@Sun.COM  *
6258474SJose.Borrego@Sun.COM  * On success, the caller expects that the info2, fi2 and entries_read
6268474SJose.Borrego@Sun.COM  * fields have been set up.
6278474SJose.Borrego@Sun.COM  */
6288474SJose.Borrego@Sun.COM static DWORD
62910122SJordan.Brown@Sun.COM srvsvc_NetFileEnum2(ndr_xa_t *mxa, struct mslm_NetFileEnum *param,
63010122SJordan.Brown@Sun.COM     smb_svcenum_t *se)
6318474SJose.Borrego@Sun.COM {
63210122SJordan.Brown@Sun.COM 	struct mslm_NetFileInfoBuf2	*fi2;
63310122SJordan.Brown@Sun.COM 	smb_netsvc_t			*ns;
63410122SJordan.Brown@Sun.COM 	smb_netsvcitem_t		*item;
63510122SJordan.Brown@Sun.COM 	smb_netfileinfo_t		*ofile;
63610122SJordan.Brown@Sun.COM 	uint32_t			entries_read = 0;
6378474SJose.Borrego@Sun.COM 
6388474SJose.Borrego@Sun.COM 	param->info.ru.info2 = NDR_NEW(mxa, struct mslm_NetFileInfo2);
6399832Samw@Sun.COM 	if (param->info.ru.info2 == NULL)
6408474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
6418474SJose.Borrego@Sun.COM 
64210122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se, sizeof (struct mslm_NetFileInfoBuf2));
64310122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
64410122SJordan.Brown@Sun.COM 		return (NERR_BufTooSmall);
64510122SJordan.Brown@Sun.COM 
64610122SJordan.Brown@Sun.COM 	do {
64710122SJordan.Brown@Sun.COM 		fi2 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf2, se->se_nlimit);
64810122SJordan.Brown@Sun.COM 		if (fi2 == NULL)
64910122SJordan.Brown@Sun.COM 			se->se_nlimit >>= 1;
65010122SJordan.Brown@Sun.COM 	} while ((se->se_nlimit > 0) && (fi2 == NULL));
65110122SJordan.Brown@Sun.COM 
6528474SJose.Borrego@Sun.COM 	if (fi2 == NULL)
6538474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
6548474SJose.Borrego@Sun.COM 
6558474SJose.Borrego@Sun.COM 	param->info.ru.info2->fi2 = fi2;
6568474SJose.Borrego@Sun.COM 
65710122SJordan.Brown@Sun.COM 	if ((ns = smb_kmod_enum_init(se)) == NULL)
65810122SJordan.Brown@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
65910122SJordan.Brown@Sun.COM 
66010122SJordan.Brown@Sun.COM 	if (smb_kmod_enum(ns) != 0) {
66110122SJordan.Brown@Sun.COM 		smb_kmod_enum_fini(ns);
66210122SJordan.Brown@Sun.COM 		return (ERROR_INTERNAL_ERROR);
66310122SJordan.Brown@Sun.COM 	}
66410122SJordan.Brown@Sun.COM 
66510122SJordan.Brown@Sun.COM 	item = list_head(&ns->ns_list);
66610122SJordan.Brown@Sun.COM 	while (item != NULL) {
66710122SJordan.Brown@Sun.COM 		ofile = &item->nsi_un.nsi_ofile;
66810122SJordan.Brown@Sun.COM 		fi2->fi2_id = ofile->fi_uniqid;
6698474SJose.Borrego@Sun.COM 
6708474SJose.Borrego@Sun.COM 		++entries_read;
6718474SJose.Borrego@Sun.COM 		++fi2;
67210122SJordan.Brown@Sun.COM 		item = list_next(&ns->ns_list, item);
6738474SJose.Borrego@Sun.COM 	}
6748474SJose.Borrego@Sun.COM 
67510122SJordan.Brown@Sun.COM 	se->se_resume += entries_read;
6768474SJose.Borrego@Sun.COM 	param->info.ru.info2->entries_read = entries_read;
67710122SJordan.Brown@Sun.COM 	smb_kmod_enum_fini(ns);
6788474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
6798474SJose.Borrego@Sun.COM }
6808474SJose.Borrego@Sun.COM 
6818474SJose.Borrego@Sun.COM /*
6828474SJose.Borrego@Sun.COM  * Build level 3 file information.
6838474SJose.Borrego@Sun.COM  *
68410122SJordan.Brown@Sun.COM  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
68510122SJordan.Brown@Sun.COM  * So we use the uniqid here.
68610122SJordan.Brown@Sun.COM  *
6878474SJose.Borrego@Sun.COM  * On success, the caller expects that the info3, fi3 and entries_read
6888474SJose.Borrego@Sun.COM  * fields have been set up.
6898474SJose.Borrego@Sun.COM  */
6908474SJose.Borrego@Sun.COM static DWORD
69110122SJordan.Brown@Sun.COM srvsvc_NetFileEnum3(ndr_xa_t *mxa, struct mslm_NetFileEnum *param,
69210122SJordan.Brown@Sun.COM     smb_svcenum_t *se)
6938474SJose.Borrego@Sun.COM {
69410122SJordan.Brown@Sun.COM 	struct mslm_NetFileInfoBuf3	*fi3;
69510122SJordan.Brown@Sun.COM 	smb_netsvc_t			*ns;
69610122SJordan.Brown@Sun.COM 	smb_netsvcitem_t		*item;
69710122SJordan.Brown@Sun.COM 	smb_netfileinfo_t		*ofile;
69810122SJordan.Brown@Sun.COM 	uint32_t			entries_read = 0;
6998474SJose.Borrego@Sun.COM 
7008474SJose.Borrego@Sun.COM 	param->info.ru.info3 = NDR_NEW(mxa, struct mslm_NetFileInfo3);
7018474SJose.Borrego@Sun.COM 	if (param->info.ru.info3 == NULL)
7028474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
7038474SJose.Borrego@Sun.COM 
70410122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
70510122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetFileInfoBuf3) + MAXNAMELEN);
70610122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
70710122SJordan.Brown@Sun.COM 		return (NERR_BufTooSmall);
70810122SJordan.Brown@Sun.COM 
70910122SJordan.Brown@Sun.COM 	do {
71010122SJordan.Brown@Sun.COM 		fi3 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf3, se->se_nlimit);
71110122SJordan.Brown@Sun.COM 		if (fi3 == NULL)
71210122SJordan.Brown@Sun.COM 			se->se_nlimit >>= 1;
71310122SJordan.Brown@Sun.COM 	} while ((se->se_nlimit > 0) && (fi3 == NULL));
71410122SJordan.Brown@Sun.COM 
7158474SJose.Borrego@Sun.COM 	if (fi3 == NULL)
7168474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
7178474SJose.Borrego@Sun.COM 
7188474SJose.Borrego@Sun.COM 	param->info.ru.info3->fi3 = fi3;
7198474SJose.Borrego@Sun.COM 
72010122SJordan.Brown@Sun.COM 	if ((ns = smb_kmod_enum_init(se)) == NULL)
72110122SJordan.Brown@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
72210122SJordan.Brown@Sun.COM 
72310122SJordan.Brown@Sun.COM 	if (smb_kmod_enum(ns) != 0) {
72410122SJordan.Brown@Sun.COM 		smb_kmod_enum_fini(ns);
72510122SJordan.Brown@Sun.COM 		return (ERROR_INTERNAL_ERROR);
72610122SJordan.Brown@Sun.COM 	}
72710122SJordan.Brown@Sun.COM 
72810122SJordan.Brown@Sun.COM 	item = list_head(&ns->ns_list);
72910122SJordan.Brown@Sun.COM 	while (item != NULL) {
73010122SJordan.Brown@Sun.COM 		ofile = &item->nsi_un.nsi_ofile;
73110122SJordan.Brown@Sun.COM 		fi3->fi3_id = ofile->fi_uniqid;
73210122SJordan.Brown@Sun.COM 		fi3->fi3_permissions = ofile->fi_permissions;
73310122SJordan.Brown@Sun.COM 		fi3->fi3_num_locks = ofile->fi_numlocks;
7348474SJose.Borrego@Sun.COM 		fi3->fi3_pathname = (uint8_t *)
73510122SJordan.Brown@Sun.COM 		    NDR_STRDUP(mxa, ofile->fi_path);
7368474SJose.Borrego@Sun.COM 		fi3->fi3_username = (uint8_t *)
73710122SJordan.Brown@Sun.COM 		    NDR_STRDUP(mxa, ofile->fi_username);
7388474SJose.Borrego@Sun.COM 
7398474SJose.Borrego@Sun.COM 		++entries_read;
7408474SJose.Borrego@Sun.COM 		++fi3;
74110122SJordan.Brown@Sun.COM 		item = list_next(&ns->ns_list, item);
7428474SJose.Borrego@Sun.COM 	}
7438474SJose.Borrego@Sun.COM 
74410122SJordan.Brown@Sun.COM 	se->se_resume += entries_read;
7458474SJose.Borrego@Sun.COM 	param->info.ru.info3->entries_read = entries_read;
7468474SJose.Borrego@Sun.COM 	param->total_entries = entries_read;
7478474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
7488474SJose.Borrego@Sun.COM }
7498474SJose.Borrego@Sun.COM 
7508474SJose.Borrego@Sun.COM /*
7518474SJose.Borrego@Sun.COM  * srvsvc_s_NetFileClose
7528474SJose.Borrego@Sun.COM  *
7538474SJose.Borrego@Sun.COM  * NetFileClose forces a file to close. This function can be used when
75410122SJordan.Brown@Sun.COM  * an error prevents closure by other means.  Use NetFileClose with
7558474SJose.Borrego@Sun.COM  * caution because it does not flush data, cached on a client, to the
7568474SJose.Borrego@Sun.COM  * file before closing the file.
7578474SJose.Borrego@Sun.COM  *
75810122SJordan.Brown@Sun.COM  * SMB fids are 16-bit values but this interface expects 32-bit file ids.
75910122SJordan.Brown@Sun.COM  * So we use the uniqid here.
76010122SJordan.Brown@Sun.COM  *
7618474SJose.Borrego@Sun.COM  * Return Values
7628474SJose.Borrego@Sun.COM  * ERROR_SUCCESS            Operation succeeded.
7638474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED      Operation denied.
7648474SJose.Borrego@Sun.COM  * NERR_FileIdNotFound      No open file with the specified id.
7658474SJose.Borrego@Sun.COM  *
76610122SJordan.Brown@Sun.COM  * Note: MSDN suggests ERROR_FILE_NOT_FOUND for NetFileClose but network
76710122SJordan.Brown@Sun.COM  * captures using NT show NERR_FileIdNotFound, which is consistent with
76810122SJordan.Brown@Sun.COM  * the NetFileClose2 page on MSDN.
7698474SJose.Borrego@Sun.COM  */
7708474SJose.Borrego@Sun.COM static int
7718474SJose.Borrego@Sun.COM srvsvc_s_NetFileClose(void *arg, ndr_xa_t *mxa)
7728474SJose.Borrego@Sun.COM {
77310122SJordan.Brown@Sun.COM 	static struct {
77410122SJordan.Brown@Sun.COM 		int errnum;
77510122SJordan.Brown@Sun.COM 		int nerr;
77610122SJordan.Brown@Sun.COM 	} errmap[] = {
77710122SJordan.Brown@Sun.COM 		0,	ERROR_SUCCESS,
77810122SJordan.Brown@Sun.COM 		EACCES,	ERROR_ACCESS_DENIED,
77910122SJordan.Brown@Sun.COM 		EPERM,	ERROR_ACCESS_DENIED,
78010122SJordan.Brown@Sun.COM 		EINVAL,	ERROR_INVALID_PARAMETER,
78110122SJordan.Brown@Sun.COM 		ENOMEM,	ERROR_NOT_ENOUGH_MEMORY,
78210122SJordan.Brown@Sun.COM 		ENOENT,	NERR_FileIdNotFound
78310122SJordan.Brown@Sun.COM 	};
78410122SJordan.Brown@Sun.COM 
7858474SJose.Borrego@Sun.COM 	struct mslm_NetFileClose *param = arg;
78610122SJordan.Brown@Sun.COM 	int		i;
78710122SJordan.Brown@Sun.COM 	int		rc;
7888474SJose.Borrego@Sun.COM 
7898474SJose.Borrego@Sun.COM 	if (!ndr_is_admin(mxa)) {
7908474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
7918474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
7928474SJose.Borrego@Sun.COM 	}
7938474SJose.Borrego@Sun.COM 
79410122SJordan.Brown@Sun.COM 	rc = smb_kmod_file_close(param->file_id);
79510122SJordan.Brown@Sun.COM 
79610122SJordan.Brown@Sun.COM 	for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) {
79710122SJordan.Brown@Sun.COM 		if (rc == errmap[i].errnum) {
79810122SJordan.Brown@Sun.COM 			param->status = errmap[i].nerr;
79910122SJordan.Brown@Sun.COM 			return (NDR_DRC_OK);
80010122SJordan.Brown@Sun.COM 		}
80110122SJordan.Brown@Sun.COM 	}
80210122SJordan.Brown@Sun.COM 
80310122SJordan.Brown@Sun.COM 	param->status = ERROR_INTERNAL_ERROR;
8048474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
8058474SJose.Borrego@Sun.COM }
8068474SJose.Borrego@Sun.COM 
8078474SJose.Borrego@Sun.COM /*
8088474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareGetInfo
8098474SJose.Borrego@Sun.COM  *
8108474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
8118474SJose.Borrego@Sun.COM  */
8128474SJose.Borrego@Sun.COM static int
8138474SJose.Borrego@Sun.COM srvsvc_s_NetShareGetInfo(void *arg, ndr_xa_t *mxa)
8148474SJose.Borrego@Sun.COM {
8158474SJose.Borrego@Sun.COM 	struct mlsm_NetShareGetInfo *param = arg;
8169343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_0 *info0;
8179343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1 *info1;
8189343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
8199343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_501 *info501;
8209343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
8219832Samw@Sun.COM 	struct mslm_NetShareInfo_503 *info503;
8229343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1004 *info1004;
8239343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1005 *info1005;
8249343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1006 *info1006;
8259832Samw@Sun.COM 	struct mslm_NetShareInfo_1501 *info1501;
8269832Samw@Sun.COM 	srvsvc_netshare_getinfo_t *info;
8279832Samw@Sun.COM 	uint8_t *netname;
8289832Samw@Sun.COM 	uint8_t *comment;
8298474SJose.Borrego@Sun.COM 	smb_share_t si;
8309832Samw@Sun.COM 	srvsvc_sd_t sd;
8318474SJose.Borrego@Sun.COM 	DWORD status;
8328474SJose.Borrego@Sun.COM 
8338474SJose.Borrego@Sun.COM 	status = smb_shr_get((char *)param->netname, &si);
8348474SJose.Borrego@Sun.COM 	if (status != NERR_Success) {
8358474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
8368474SJose.Borrego@Sun.COM 		param->status = status;
8378474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
8388474SJose.Borrego@Sun.COM 	}
8398474SJose.Borrego@Sun.COM 
8409832Samw@Sun.COM 	netname = (uint8_t *)NDR_STRDUP(mxa, si.shr_name);
8419832Samw@Sun.COM 	comment = (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt);
8429832Samw@Sun.COM 	info = NDR_NEW(mxa, srvsvc_netshare_getinfo_t);
8439832Samw@Sun.COM 
8449832Samw@Sun.COM 	if (netname == NULL || comment == NULL || info == NULL) {
8459832Samw@Sun.COM 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
8469832Samw@Sun.COM 		param->status = ERROR_NOT_ENOUGH_MEMORY;
8479832Samw@Sun.COM 		return (NDR_DRC_OK);
8489832Samw@Sun.COM 	}
8499832Samw@Sun.COM 
8508474SJose.Borrego@Sun.COM 	switch (param->level) {
8518474SJose.Borrego@Sun.COM 	case 0:
8529832Samw@Sun.COM 		info0 = &info->nsg_info0;
8539832Samw@Sun.COM 		info0->shi0_netname = netname;
8548474SJose.Borrego@Sun.COM 		param->result.ru.info0 = info0;
8558474SJose.Borrego@Sun.COM 		break;
8568474SJose.Borrego@Sun.COM 
8578474SJose.Borrego@Sun.COM 	case 1:
8589832Samw@Sun.COM 		info1 = &info->nsg_info1;
8599832Samw@Sun.COM 		info1->shi1_netname = netname;
8609832Samw@Sun.COM 		info1->shi1_comment = comment;
8618474SJose.Borrego@Sun.COM 		info1->shi1_type = si.shr_type;
8628474SJose.Borrego@Sun.COM 		param->result.ru.info1 = info1;
8638474SJose.Borrego@Sun.COM 		break;
8648474SJose.Borrego@Sun.COM 
8658474SJose.Borrego@Sun.COM 	case 2:
8669832Samw@Sun.COM 		info2 = &info->nsg_info2;
8679832Samw@Sun.COM 		info2->shi2_netname = netname;
8689832Samw@Sun.COM 		info2->shi2_comment = comment;
8698474SJose.Borrego@Sun.COM 		info2->shi2_path =
8708474SJose.Borrego@Sun.COM 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
8718474SJose.Borrego@Sun.COM 		info2->shi2_passwd = 0;
8728474SJose.Borrego@Sun.COM 		info2->shi2_type = si.shr_type;
8738474SJose.Borrego@Sun.COM 		info2->shi2_permissions = 0;
8748474SJose.Borrego@Sun.COM 		info2->shi2_max_uses = SHI_USES_UNLIMITED;
8758474SJose.Borrego@Sun.COM 		info2->shi2_current_uses = 0;
8768474SJose.Borrego@Sun.COM 		param->result.ru.info2 = info2;
8778474SJose.Borrego@Sun.COM 		break;
8788474SJose.Borrego@Sun.COM 
8799832Samw@Sun.COM 	case 501:
8809832Samw@Sun.COM 		info501 = &info->nsg_info501;
8819832Samw@Sun.COM 		info501->shi501_netname = netname;
8829832Samw@Sun.COM 		info501->shi501_comment = comment;
8839832Samw@Sun.COM 		info501->shi501_type = si.shr_type;
88410504SKeyur.Desai@Sun.COM 		info501->shi501_flags = srvsvc_get_share_flags(&si);
8859832Samw@Sun.COM 		param->result.ru.info501 = info501;
8869832Samw@Sun.COM 		break;
8879832Samw@Sun.COM 
8889832Samw@Sun.COM 	case 502:
8899832Samw@Sun.COM 		info502 = &info->nsg_info502;
8909832Samw@Sun.COM 		info502->shi502_netname = netname;
8919832Samw@Sun.COM 		info502->shi502_comment = comment;
8929832Samw@Sun.COM 		info502->shi502_path =
8939832Samw@Sun.COM 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
8949832Samw@Sun.COM 		info502->shi502_passwd = 0;
8959832Samw@Sun.COM 		info502->shi502_type = si.shr_type;
8969832Samw@Sun.COM 		info502->shi502_permissions = 0;
8979832Samw@Sun.COM 		info502->shi502_max_uses = SHI_USES_UNLIMITED;
8989832Samw@Sun.COM 		info502->shi502_current_uses = 0;
8999832Samw@Sun.COM 
9009832Samw@Sun.COM 		status = srvsvc_share_getsd(mxa, &si, &sd);
9019832Samw@Sun.COM 		if (status == ERROR_SUCCESS) {
9029832Samw@Sun.COM 			info502->shi502_reserved = sd.sd_size;
9039832Samw@Sun.COM 			info502->shi502_security_descriptor = sd.sd_buf;
9049832Samw@Sun.COM 		} else {
9059832Samw@Sun.COM 			info502->shi502_reserved = 0;
9069832Samw@Sun.COM 			info502->shi502_security_descriptor = NULL;
9078474SJose.Borrego@Sun.COM 		}
9088474SJose.Borrego@Sun.COM 
9099832Samw@Sun.COM 		param->result.ru.info502 = info502;
9109832Samw@Sun.COM 		break;
9119832Samw@Sun.COM 
9129832Samw@Sun.COM 	case 503:
9139832Samw@Sun.COM 		info503 = &info->nsg_info503;
9149832Samw@Sun.COM 		info503->shi503_netname = netname;
9159832Samw@Sun.COM 		info503->shi503_comment = comment;
9169832Samw@Sun.COM 		info503->shi503_path =
9179832Samw@Sun.COM 		    (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path);
9189832Samw@Sun.COM 		info503->shi503_passwd = NULL;
9199832Samw@Sun.COM 		info503->shi503_type = si.shr_type;
9209832Samw@Sun.COM 		info503->shi503_permissions = 0;
9219832Samw@Sun.COM 		info503->shi503_max_uses = SHI_USES_UNLIMITED;
9229832Samw@Sun.COM 		info503->shi503_current_uses = 0;
9239832Samw@Sun.COM 		info503->shi503_servername = NULL;
9249832Samw@Sun.COM 
9259832Samw@Sun.COM 		status = srvsvc_share_getsd(mxa, &si, &sd);
9269832Samw@Sun.COM 		if (status == ERROR_SUCCESS) {
9279832Samw@Sun.COM 			info503->shi503_reserved = sd.sd_size;
9289832Samw@Sun.COM 			info503->shi503_security_descriptor = sd.sd_buf;
9299832Samw@Sun.COM 		} else {
9309832Samw@Sun.COM 			info503->shi503_reserved = 0;
9319832Samw@Sun.COM 			info503->shi503_security_descriptor = NULL;
9329832Samw@Sun.COM 		}
9339832Samw@Sun.COM 
9349832Samw@Sun.COM 		param->result.ru.info503 = info503;
9359832Samw@Sun.COM 		break;
9369832Samw@Sun.COM 
9379832Samw@Sun.COM 	case 1004:
9389832Samw@Sun.COM 		info1004 = &info->nsg_info1004;
9399832Samw@Sun.COM 		info1004->shi1004_comment = comment;
9409832Samw@Sun.COM 		param->result.ru.info1004 = info1004;
9418474SJose.Borrego@Sun.COM 		break;
9428474SJose.Borrego@Sun.COM 
9438474SJose.Borrego@Sun.COM 	case 1005:
9449832Samw@Sun.COM 		info1005 = &info->nsg_info1005;
94510504SKeyur.Desai@Sun.COM 		info1005->shi1005_flags = srvsvc_get_share_flags(&si);
9468474SJose.Borrego@Sun.COM 		param->result.ru.info1005 = info1005;
9478474SJose.Borrego@Sun.COM 		break;
9488474SJose.Borrego@Sun.COM 
9498474SJose.Borrego@Sun.COM 	case 1006:
9509832Samw@Sun.COM 		info1006 = &info->nsg_info1006;
9518474SJose.Borrego@Sun.COM 		info1006->shi1006_max_uses = SHI_USES_UNLIMITED;
9528474SJose.Borrego@Sun.COM 		param->result.ru.info1006 = info1006;
9538474SJose.Borrego@Sun.COM 		break;
9548474SJose.Borrego@Sun.COM 
9559832Samw@Sun.COM 	case 1501:
9569832Samw@Sun.COM 		info1501 = &info->nsg_info1501;
9579832Samw@Sun.COM 
9589832Samw@Sun.COM 		status = srvsvc_share_getsd(mxa, &si, &sd);
9599832Samw@Sun.COM 		if (status == ERROR_SUCCESS) {
9609832Samw@Sun.COM 			info503->shi503_reserved = sd.sd_size;
9619832Samw@Sun.COM 			info503->shi503_security_descriptor = sd.sd_buf;
9629832Samw@Sun.COM 		} else {
9639832Samw@Sun.COM 			info503->shi503_reserved = 0;
9649832Samw@Sun.COM 			info503->shi503_security_descriptor = NULL;
9658474SJose.Borrego@Sun.COM 		}
9668474SJose.Borrego@Sun.COM 
9679832Samw@Sun.COM 		param->result.ru.info1501 = info1501;
9688474SJose.Borrego@Sun.COM 		break;
9698474SJose.Borrego@Sun.COM 
9708474SJose.Borrego@Sun.COM 	default:
9718474SJose.Borrego@Sun.COM 		status = ERROR_ACCESS_DENIED;
9728474SJose.Borrego@Sun.COM 		break;
9738474SJose.Borrego@Sun.COM 	}
9748474SJose.Borrego@Sun.COM 
9758474SJose.Borrego@Sun.COM 	if (status != ERROR_SUCCESS)
9768474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mlsm_NetShareGetInfo));
9778474SJose.Borrego@Sun.COM 	else
9788474SJose.Borrego@Sun.COM 		param->result.switch_value = param->level;
9798474SJose.Borrego@Sun.COM 
9808474SJose.Borrego@Sun.COM 	param->status = status;
9818474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
9828474SJose.Borrego@Sun.COM }
9838474SJose.Borrego@Sun.COM 
9849832Samw@Sun.COM static uint32_t
9859832Samw@Sun.COM srvsvc_share_getsd(ndr_xa_t *mxa, smb_share_t *si, srvsvc_sd_t *sd)
9869832Samw@Sun.COM {
9879832Samw@Sun.COM 	uint32_t status;
9889832Samw@Sun.COM 
9899832Samw@Sun.COM 	status = srvsvc_sd_get(si, NULL, &sd->sd_size);
9909832Samw@Sun.COM 	if (status != ERROR_SUCCESS) {
9919832Samw@Sun.COM 		if (status == ERROR_PATH_NOT_FOUND) {
9929832Samw@Sun.COM 			bzero(sd, sizeof (srvsvc_sd_t));
9939832Samw@Sun.COM 			status = ERROR_SUCCESS;
9949832Samw@Sun.COM 		}
9959832Samw@Sun.COM 
9969832Samw@Sun.COM 		return (status);
9979832Samw@Sun.COM 	}
9989832Samw@Sun.COM 
9999832Samw@Sun.COM 	if ((sd->sd_buf = NDR_MALLOC(mxa, sd->sd_size)) == NULL)
10009832Samw@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
10019832Samw@Sun.COM 
10029832Samw@Sun.COM 	status = srvsvc_sd_get(si, sd->sd_buf, NULL);
10039832Samw@Sun.COM 	if (status == ERROR_PATH_NOT_FOUND) {
10049832Samw@Sun.COM 		bzero(sd, sizeof (srvsvc_sd_t));
10059832Samw@Sun.COM 		status = ERROR_SUCCESS;
10069832Samw@Sun.COM 	}
10079832Samw@Sun.COM 
10089832Samw@Sun.COM 	return (status);
10099832Samw@Sun.COM }
10108474SJose.Borrego@Sun.COM 
10118474SJose.Borrego@Sun.COM /*
10128474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareSetInfo
10138474SJose.Borrego@Sun.COM  *
10148474SJose.Borrego@Sun.COM  * This call is made by SrvMgr to set share information.
10159832Samw@Sun.COM  * Only power users groups can manage shares.
10169832Samw@Sun.COM  *
10179832Samw@Sun.COM  * To avoid misleading errors, we don't report an error
10189832Samw@Sun.COM  * when a FS doesn't support ACLs on shares.
10198474SJose.Borrego@Sun.COM  *
10208474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
10218474SJose.Borrego@Sun.COM  */
10228474SJose.Borrego@Sun.COM static int
10238474SJose.Borrego@Sun.COM srvsvc_s_NetShareSetInfo(void *arg, ndr_xa_t *mxa)
10248474SJose.Borrego@Sun.COM {
10258474SJose.Borrego@Sun.COM 	struct mlsm_NetShareSetInfo *param = arg;
10269832Samw@Sun.COM 	struct mslm_NetShareInfo_0 *info0;
10279832Samw@Sun.COM 	struct mslm_NetShareInfo_1 *info1;
10289832Samw@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
10299832Samw@Sun.COM 	struct mslm_NetShareInfo_501 *info501;
10309832Samw@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
10319832Samw@Sun.COM 	struct mslm_NetShareInfo_503 *info503;
10329832Samw@Sun.COM 	struct mslm_NetShareInfo_1004 *info1004;
10339832Samw@Sun.COM 	struct mslm_NetShareInfo_1005 *info1005;
10349832Samw@Sun.COM 	struct mslm_NetShareInfo_1501 *info1501;
10359832Samw@Sun.COM 	static DWORD parm_err = 0;
10369832Samw@Sun.COM 	srvsvc_netshare_setinfo_t info;
10379832Samw@Sun.COM 	smb_share_t si;
10389832Samw@Sun.COM 	uint8_t *sdbuf;
10399832Samw@Sun.COM 	int32_t native_os;
10409832Samw@Sun.COM 	DWORD status;
10419832Samw@Sun.COM 
10429832Samw@Sun.COM 	native_os = ndr_native_os(mxa);
10439832Samw@Sun.COM 
10449832Samw@Sun.COM 	if (!ndr_is_poweruser(mxa)) {
10459832Samw@Sun.COM 		status = ERROR_ACCESS_DENIED;
10469832Samw@Sun.COM 		goto netsharesetinfo_exit;
10479832Samw@Sun.COM 	}
10489832Samw@Sun.COM 
10499832Samw@Sun.COM 	if (smb_shr_get((char *)param->netname, &si) != NERR_Success) {
10509832Samw@Sun.COM 		status = ERROR_INVALID_NETNAME;
10519832Samw@Sun.COM 		goto netsharesetinfo_exit;
10529832Samw@Sun.COM 	}
10539832Samw@Sun.COM 
10549832Samw@Sun.COM 	if (param->result.ru.nullptr == NULL) {
10559832Samw@Sun.COM 		status = ERROR_INVALID_PARAMETER;
10569832Samw@Sun.COM 		goto netsharesetinfo_exit;
10579832Samw@Sun.COM 	}
10589832Samw@Sun.COM 
10599832Samw@Sun.COM 	bzero(&info, sizeof (srvsvc_netshare_setinfo_t));
10609832Samw@Sun.COM 
10619832Samw@Sun.COM 	switch (param->level) {
10629832Samw@Sun.COM 	case 0:
10639832Samw@Sun.COM 		info0 = (struct mslm_NetShareInfo_0 *)param->result.ru.info0;
10649832Samw@Sun.COM 		info.nss_netname = (char *)info0->shi0_netname;
10659832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
10669832Samw@Sun.COM 		break;
10679832Samw@Sun.COM 
10689832Samw@Sun.COM 	case 1:
10699832Samw@Sun.COM 		info1 = (struct mslm_NetShareInfo_1 *)param->result.ru.info1;
10709832Samw@Sun.COM 		info.nss_netname = (char *)info1->shi1_netname;
10719832Samw@Sun.COM 		info.nss_comment = (char *)info1->shi1_comment;
10729832Samw@Sun.COM 		info.nss_type = info1->shi1_type;
10739832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
10749832Samw@Sun.COM 		break;
10759832Samw@Sun.COM 
10769832Samw@Sun.COM 	case 2:
10779832Samw@Sun.COM 		info2 = (struct mslm_NetShareInfo_2 *)param->result.ru.info2;
10789832Samw@Sun.COM 		info.nss_netname = (char *)info2->shi2_netname;
10799832Samw@Sun.COM 		info.nss_comment = (char *)info2->shi2_comment;
10809832Samw@Sun.COM 		info.nss_path = (char *)info2->shi2_path;
10819832Samw@Sun.COM 		info.nss_type = info2->shi2_type;
10829832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
10839832Samw@Sun.COM 		break;
10849832Samw@Sun.COM 
10859832Samw@Sun.COM 	case 501:
10869832Samw@Sun.COM 		info501 = (struct mslm_NetShareInfo_501 *)
10879832Samw@Sun.COM 		    param->result.ru.info501;
10889832Samw@Sun.COM 		info.nss_netname = (char *)info501->shi501_netname;
10899832Samw@Sun.COM 		info.nss_comment = (char *)info501->shi501_comment;
10909832Samw@Sun.COM 		info.nss_type = info501->shi501_type;
10919832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
109210504SKeyur.Desai@Sun.COM 		if (status == ERROR_SUCCESS)
109310504SKeyur.Desai@Sun.COM 			status = srvsvc_update_share_flags(&si,
109410504SKeyur.Desai@Sun.COM 			    info501->shi501_flags);
10959832Samw@Sun.COM 		break;
10969832Samw@Sun.COM 
10979832Samw@Sun.COM 	case 502:
10989832Samw@Sun.COM 		info502 = (struct mslm_NetShareInfo_502 *)
10999832Samw@Sun.COM 		    param->result.ru.info502;
11009832Samw@Sun.COM 		info.nss_netname = (char *)info502->shi502_netname;
11019832Samw@Sun.COM 		info.nss_comment = (char *)info502->shi502_comment;
11029832Samw@Sun.COM 		info.nss_path = (char *)info502->shi502_path;
11039832Samw@Sun.COM 		info.nss_type = info502->shi502_type;
11049832Samw@Sun.COM 		info.nss_sd.sd_buf = info502->shi502_security_descriptor;
11059832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11069832Samw@Sun.COM 		break;
11079832Samw@Sun.COM 
11089832Samw@Sun.COM 	case 503:
11099832Samw@Sun.COM 		info503 = (struct mslm_NetShareInfo_503 *)
11109832Samw@Sun.COM 		    param->result.ru.info503;
11119832Samw@Sun.COM 		info.nss_netname = (char *)info503->shi503_netname;
11129832Samw@Sun.COM 		info.nss_comment = (char *)info503->shi503_comment;
11139832Samw@Sun.COM 		info.nss_path = (char *)info503->shi503_path;
11149832Samw@Sun.COM 		info.nss_type = info503->shi503_type;
11159832Samw@Sun.COM 		info.nss_sd.sd_buf = info503->shi503_security_descriptor;
11169832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11179832Samw@Sun.COM 		break;
11189832Samw@Sun.COM 
11199832Samw@Sun.COM 	case 1004:
11209832Samw@Sun.COM 		info1004 = (struct mslm_NetShareInfo_1004 *)
11219832Samw@Sun.COM 		    param->result.ru.info1004;
11229832Samw@Sun.COM 		info.nss_comment = (char *)info1004->shi1004_comment;
11239832Samw@Sun.COM 		status = srvsvc_modify_share(&si, &info);
11249832Samw@Sun.COM 		break;
11259832Samw@Sun.COM 
11269832Samw@Sun.COM 	case 1005:
11279832Samw@Sun.COM 		info1005 = (struct mslm_NetShareInfo_1005 *)
11289832Samw@Sun.COM 		    param->result.ru.info1005;
11299832Samw@Sun.COM 		status = srvsvc_update_share_flags(&si,
11309832Samw@Sun.COM 		    info1005->shi1005_flags);
11319832Samw@Sun.COM 		break;
11329832Samw@Sun.COM 
11339832Samw@Sun.COM 	case 1006:
11349832Samw@Sun.COM 		/*
11359832Samw@Sun.COM 		 * We don't limit the maximum number of concurrent
11369832Samw@Sun.COM 		 * connections to a share.
11379832Samw@Sun.COM 		 */
11389832Samw@Sun.COM 		status = ERROR_SUCCESS;
11399832Samw@Sun.COM 		break;
11409832Samw@Sun.COM 
11419832Samw@Sun.COM 	case 1501:
11429832Samw@Sun.COM 		info1501 = (struct mslm_NetShareInfo_1501 *)
11439832Samw@Sun.COM 		    param->result.ru.info1501;
11449832Samw@Sun.COM 		sdbuf = info1501->shi1501_security_descriptor;
11459832Samw@Sun.COM 		status = ERROR_SUCCESS;
11469832Samw@Sun.COM 
11479832Samw@Sun.COM 		if (sdbuf != NULL) {
11489832Samw@Sun.COM 			status = srvsvc_sd_set(&si, sdbuf);
11499832Samw@Sun.COM 			if (status == ERROR_PATH_NOT_FOUND)
11509832Samw@Sun.COM 				status = ERROR_SUCCESS;
11519832Samw@Sun.COM 		}
11529832Samw@Sun.COM 		break;
11539832Samw@Sun.COM 
11549832Samw@Sun.COM 	default:
11559832Samw@Sun.COM 		status = ERROR_ACCESS_DENIED;
11569832Samw@Sun.COM 		break;
11579832Samw@Sun.COM 	}
11589832Samw@Sun.COM 
11599832Samw@Sun.COM netsharesetinfo_exit:
11609832Samw@Sun.COM 	if (status != ERROR_SUCCESS)
11619832Samw@Sun.COM 		bzero(param, sizeof (struct mlsm_NetShareSetInfo));
11629832Samw@Sun.COM 
11639832Samw@Sun.COM 	param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
11649832Samw@Sun.COM 	param->status = status;
11658474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
11668474SJose.Borrego@Sun.COM }
11678474SJose.Borrego@Sun.COM 
11689832Samw@Sun.COM static uint32_t
11699832Samw@Sun.COM srvsvc_modify_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
11709832Samw@Sun.COM {
11719832Samw@Sun.COM 	uint32_t nerr = NERR_Success;
11729832Samw@Sun.COM 
11739832Samw@Sun.COM 	if (si->shr_flags & SMB_SHRF_TRANS)
11749832Samw@Sun.COM 		return (srvsvc_modify_transient_share(si, info));
11759832Samw@Sun.COM 
11769832Samw@Sun.COM 	if (info->nss_sd.sd_buf != NULL) {
11779832Samw@Sun.COM 		nerr = srvsvc_sd_set(si, info->nss_sd.sd_buf);
11789832Samw@Sun.COM 		if (nerr == ERROR_PATH_NOT_FOUND)
11799832Samw@Sun.COM 			nerr = NERR_Success;
11809832Samw@Sun.COM 	}
11819832Samw@Sun.COM 
11829832Samw@Sun.COM 	if ((nerr = srvsvc_sa_modify(si, info)) == NERR_Success)
11839832Samw@Sun.COM 		nerr = smb_shr_modify(si);
11849832Samw@Sun.COM 
11859832Samw@Sun.COM 	return (nerr);
11869832Samw@Sun.COM }
11879832Samw@Sun.COM 
11889832Samw@Sun.COM /*
11899832Samw@Sun.COM  * Update transient shares.  This includes autohome shares.
11909832Samw@Sun.COM  */
11919832Samw@Sun.COM static uint32_t
11929832Samw@Sun.COM srvsvc_modify_transient_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
11939832Samw@Sun.COM {
11949832Samw@Sun.COM 	uint32_t nerr;
11959832Samw@Sun.COM 
11969832Samw@Sun.COM 	if (info->nss_netname != NULL && info->nss_netname[0] != '\0' &&
119710966SJordan.Brown@Sun.COM 	    smb_strcasecmp(info->nss_netname, si->shr_name, 0) != 0) {
11989832Samw@Sun.COM 		nerr = smb_shr_rename(si->shr_name, info->nss_netname);
11999832Samw@Sun.COM 		if (nerr != NERR_Success)
12009832Samw@Sun.COM 			return (nerr);
12019832Samw@Sun.COM 
12029832Samw@Sun.COM 		(void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN);
12039832Samw@Sun.COM 	}
12049832Samw@Sun.COM 
12059832Samw@Sun.COM 	if ((info->nss_comment != NULL) &&
12069832Samw@Sun.COM 	    (strcmp(info->nss_comment, si->shr_cmnt) != 0)) {
12079832Samw@Sun.COM 		(void) strlcpy(si->shr_cmnt, info->nss_comment,
12089832Samw@Sun.COM 		    SMB_SHARE_CMNT_MAX);
12099832Samw@Sun.COM 
12109832Samw@Sun.COM 		if ((nerr = smb_shr_modify(si)) != NERR_Success)
12119832Samw@Sun.COM 			return (nerr);
12129832Samw@Sun.COM 	}
12139832Samw@Sun.COM 
12149832Samw@Sun.COM 	return (NERR_Success);
12159832Samw@Sun.COM }
12169832Samw@Sun.COM 
121710504SKeyur.Desai@Sun.COM /*
121810504SKeyur.Desai@Sun.COM  * srvsvc_update_share_flags
121910504SKeyur.Desai@Sun.COM  *
122010504SKeyur.Desai@Sun.COM  * This function updates flags for shares.
122110504SKeyur.Desai@Sun.COM  * Flags for Persistent shares are updated in both libshare and the local cache.
122210504SKeyur.Desai@Sun.COM  * Flags for Transient shares are updated only in the local cache.
122310504SKeyur.Desai@Sun.COM  */
12249832Samw@Sun.COM static uint32_t
12259832Samw@Sun.COM srvsvc_update_share_flags(smb_share_t *si, uint32_t shi_flags)
12269832Samw@Sun.COM {
12279832Samw@Sun.COM 	uint32_t nerr = NERR_Success;
122810504SKeyur.Desai@Sun.COM 	uint32_t flag = 0;
122910504SKeyur.Desai@Sun.COM 	char *csc_value;
123010504SKeyur.Desai@Sun.COM 	char *abe_value = "false";
123110504SKeyur.Desai@Sun.COM 	nvlist_t *nvl;
123210504SKeyur.Desai@Sun.COM 	int err = 0;
123310504SKeyur.Desai@Sun.COM 
123410504SKeyur.Desai@Sun.COM 	if (shi_flags & SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM) {
123510504SKeyur.Desai@Sun.COM 		flag = SMB_SHRF_ABE;
123610504SKeyur.Desai@Sun.COM 		abe_value = "true";
123710504SKeyur.Desai@Sun.COM 	}
123810504SKeyur.Desai@Sun.COM 
123910504SKeyur.Desai@Sun.COM 	si->shr_flags &= ~SMB_SHRF_ABE;
124010504SKeyur.Desai@Sun.COM 	si->shr_flags |= flag;
12419832Samw@Sun.COM 
12429832Samw@Sun.COM 	switch ((shi_flags & CSC_MASK)) {
12439832Samw@Sun.COM 	case CSC_CACHE_AUTO_REINT:
124410504SKeyur.Desai@Sun.COM 		flag = SMB_SHRF_CSC_AUTO;
12459832Samw@Sun.COM 		break;
12469832Samw@Sun.COM 	case CSC_CACHE_VDO:
124710504SKeyur.Desai@Sun.COM 		flag = SMB_SHRF_CSC_VDO;
12489832Samw@Sun.COM 		break;
12499832Samw@Sun.COM 	case CSC_CACHE_NONE:
125010504SKeyur.Desai@Sun.COM 		flag = SMB_SHRF_CSC_DISABLED;
12519832Samw@Sun.COM 		break;
12529832Samw@Sun.COM 	case CSC_CACHE_MANUAL_REINT:
125310504SKeyur.Desai@Sun.COM 		flag = SMB_SHRF_CSC_MANUAL;
12549832Samw@Sun.COM 		break;
12559832Samw@Sun.COM 	default:
125610504SKeyur.Desai@Sun.COM 		return (NERR_InternalError);
12579832Samw@Sun.COM 	}
12589832Samw@Sun.COM 
12599832Samw@Sun.COM 	si->shr_flags &= ~SMB_SHRF_CSC_MASK;
126010504SKeyur.Desai@Sun.COM 	si->shr_flags |= flag;
12619832Samw@Sun.COM 
12629832Samw@Sun.COM 	if ((si->shr_flags & SMB_SHRF_TRANS) == 0) {
126310504SKeyur.Desai@Sun.COM 		csc_value = smb_shr_sa_csc_name(si);
126410504SKeyur.Desai@Sun.COM 
126510504SKeyur.Desai@Sun.COM 		if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
126610504SKeyur.Desai@Sun.COM 			return (NERR_InternalError);
126710504SKeyur.Desai@Sun.COM 
126810504SKeyur.Desai@Sun.COM 		err |= nvlist_add_string(nvl, SHOPT_CSC, csc_value);
126910504SKeyur.Desai@Sun.COM 		err |= nvlist_add_string(nvl, SHOPT_ABE, abe_value);
127010504SKeyur.Desai@Sun.COM 		if (err) {
127110504SKeyur.Desai@Sun.COM 			nvlist_free(nvl);
127210504SKeyur.Desai@Sun.COM 			return (NERR_InternalError);
127310504SKeyur.Desai@Sun.COM 		}
127410504SKeyur.Desai@Sun.COM 
127510504SKeyur.Desai@Sun.COM 		nerr = srvsvc_sa_setprop(si, nvl);
127610504SKeyur.Desai@Sun.COM 		nvlist_free(nvl);
127710504SKeyur.Desai@Sun.COM 
127810504SKeyur.Desai@Sun.COM 		if (nerr != NERR_Success)
12799832Samw@Sun.COM 			return (nerr);
12809832Samw@Sun.COM 	}
12819832Samw@Sun.COM 
12829832Samw@Sun.COM 	return (smb_shr_modify(si));
12839832Samw@Sun.COM }
12849832Samw@Sun.COM 
128510504SKeyur.Desai@Sun.COM static uint32_t
128610504SKeyur.Desai@Sun.COM srvsvc_get_share_flags(smb_share_t *si)
128710504SKeyur.Desai@Sun.COM {
128810504SKeyur.Desai@Sun.COM 	uint32_t flags = 0;
128910504SKeyur.Desai@Sun.COM 
129010504SKeyur.Desai@Sun.COM 	switch (si->shr_flags & SMB_SHRF_CSC_MASK) {
129110504SKeyur.Desai@Sun.COM 	case SMB_SHRF_CSC_DISABLED:
129210504SKeyur.Desai@Sun.COM 		flags |= CSC_CACHE_NONE;
129310504SKeyur.Desai@Sun.COM 		break;
129410504SKeyur.Desai@Sun.COM 	case SMB_SHRF_CSC_AUTO:
129510504SKeyur.Desai@Sun.COM 		flags |= CSC_CACHE_AUTO_REINT;
129610504SKeyur.Desai@Sun.COM 		break;
129710504SKeyur.Desai@Sun.COM 	case SMB_SHRF_CSC_VDO:
129810504SKeyur.Desai@Sun.COM 		flags |= CSC_CACHE_VDO;
129910504SKeyur.Desai@Sun.COM 		break;
130010504SKeyur.Desai@Sun.COM 	case SMB_SHRF_CSC_MANUAL:
130110504SKeyur.Desai@Sun.COM 	default:
130210504SKeyur.Desai@Sun.COM 		/*
130310504SKeyur.Desai@Sun.COM 		 * Default to CSC_CACHE_MANUAL_REINT.
130410504SKeyur.Desai@Sun.COM 		 */
130510504SKeyur.Desai@Sun.COM 		break;
130610504SKeyur.Desai@Sun.COM 	}
130710504SKeyur.Desai@Sun.COM 
130810504SKeyur.Desai@Sun.COM 	if (si->shr_flags & SMB_SHRF_ABE)
130910504SKeyur.Desai@Sun.COM 		flags |= SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM;
131010504SKeyur.Desai@Sun.COM 
131110504SKeyur.Desai@Sun.COM 	return (flags);
131210504SKeyur.Desai@Sun.COM }
131310504SKeyur.Desai@Sun.COM 
13148474SJose.Borrego@Sun.COM /*
13158474SJose.Borrego@Sun.COM  * srvsvc_s_NetSessionEnum
13168474SJose.Borrego@Sun.COM  *
13178474SJose.Borrego@Sun.COM  * Level 1 request is made by (Server Manager (srvmgr) on NT Server when
13188474SJose.Borrego@Sun.COM  * the user info icon is selected.
13198474SJose.Borrego@Sun.COM  *
13208474SJose.Borrego@Sun.COM  * On success, the return value is NERR_Success.
13218474SJose.Borrego@Sun.COM  * On error, the return value can be one of the following error codes:
13228474SJose.Borrego@Sun.COM  *
13238474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED      The user does not have access to the requested
13248474SJose.Borrego@Sun.COM  *                          information.
13258474SJose.Borrego@Sun.COM  * ERROR_INVALID_LEVEL      The value specified for the level is invalid.
13268474SJose.Borrego@Sun.COM  * ERROR_INVALID_PARAMETER  The specified parameter is invalid.
13278474SJose.Borrego@Sun.COM  * ERROR_MORE_DATA          More entries are available. Specify a large
13288474SJose.Borrego@Sun.COM  *                          enough buffer to receive all entries.
13298474SJose.Borrego@Sun.COM  * ERROR_NOT_ENOUGH_MEMORY  Insufficient memory is available.
13308474SJose.Borrego@Sun.COM  * NERR_ClientNameNotFound  A session does not exist with the computer name.
13318474SJose.Borrego@Sun.COM  * NERR_InvalidComputer     The computer name is invalid.
13328474SJose.Borrego@Sun.COM  * NERR_UserNotFound        The user name could not be found.
13338474SJose.Borrego@Sun.COM  */
13348474SJose.Borrego@Sun.COM static int
13358474SJose.Borrego@Sun.COM srvsvc_s_NetSessionEnum(void *arg, ndr_xa_t *mxa)
13368474SJose.Borrego@Sun.COM {
133710122SJordan.Brown@Sun.COM 	struct mslm_NetSessionEnum	*param = arg;
133810122SJordan.Brown@Sun.COM 	srvsvc_infonres_t		*info;
133910122SJordan.Brown@Sun.COM 	smb_netsvc_t			*ns;
134010122SJordan.Brown@Sun.COM 	smb_svcenum_t			se;
134110122SJordan.Brown@Sun.COM 	DWORD				status = ERROR_SUCCESS;
134210122SJordan.Brown@Sun.COM 
134310122SJordan.Brown@Sun.COM 	if (!ndr_is_admin(mxa)) {
134410122SJordan.Brown@Sun.COM 		status = ERROR_ACCESS_DENIED;
134510122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
134610122SJordan.Brown@Sun.COM 	}
134710122SJordan.Brown@Sun.COM 
134810122SJordan.Brown@Sun.COM 	if ((info = NDR_NEW(mxa, srvsvc_infonres_t)) == NULL) {
134910122SJordan.Brown@Sun.COM 		status = ERROR_NOT_ENOUGH_MEMORY;
135010122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
135110122SJordan.Brown@Sun.COM 	}
135210122SJordan.Brown@Sun.COM 
135310122SJordan.Brown@Sun.COM 	info->entriesread = 0;
135410122SJordan.Brown@Sun.COM 	info->entries = NULL;
135510122SJordan.Brown@Sun.COM 	param->result.level = param->level;
135610122SJordan.Brown@Sun.COM 	param->result.bufptr.p = info;
135710122SJordan.Brown@Sun.COM 
135810122SJordan.Brown@Sun.COM 	if ((param->total_entries = srvsvc_open_sessions()) == 0) {
135910122SJordan.Brown@Sun.COM 		param->resume_handle = NULL;
136010122SJordan.Brown@Sun.COM 		param->status = ERROR_SUCCESS;
13618474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
13628474SJose.Borrego@Sun.COM 	}
13638474SJose.Borrego@Sun.COM 
136410122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
136510122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_USER;
136610122SJordan.Brown@Sun.COM 	se.se_level = param->level;
136710122SJordan.Brown@Sun.COM 	se.se_ntotal = param->total_entries;
136810122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
136910122SJordan.Brown@Sun.COM 
137010122SJordan.Brown@Sun.COM 	if (param->resume_handle) {
137110122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
137210122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
137310122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
137410122SJordan.Brown@Sun.COM 	}
13758474SJose.Borrego@Sun.COM 
13768474SJose.Borrego@Sun.COM 	switch (param->level) {
13778474SJose.Borrego@Sun.COM 	case 0:
137810122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_0,
137910122SJordan.Brown@Sun.COM 		    se.se_nlimit);
13808474SJose.Borrego@Sun.COM 		break;
138110122SJordan.Brown@Sun.COM 	case 1:
138210122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_1,
138310122SJordan.Brown@Sun.COM 		    se.se_nlimit);
13849832Samw@Sun.COM 		break;
138510122SJordan.Brown@Sun.COM 	case 2:
138610122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_2,
138710122SJordan.Brown@Sun.COM 		    se.se_nlimit);
13889832Samw@Sun.COM 		break;
138910122SJordan.Brown@Sun.COM 	case 10:
139010122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_10,
139110122SJordan.Brown@Sun.COM 		    se.se_nlimit);
139210122SJordan.Brown@Sun.COM 		break;
13939832Samw@Sun.COM 	case 502:
139410122SJordan.Brown@Sun.COM 		info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_502,
139510122SJordan.Brown@Sun.COM 		    se.se_nlimit);
13969832Samw@Sun.COM 		break;
13978474SJose.Borrego@Sun.COM 	default:
13988474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetSessionEnum));
139910122SJordan.Brown@Sun.COM 		param->status = ERROR_INVALID_LEVEL;
14008474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
14018474SJose.Borrego@Sun.COM 	}
14028474SJose.Borrego@Sun.COM 
140310122SJordan.Brown@Sun.COM 	if (info->entries == NULL) {
140410122SJordan.Brown@Sun.COM 		status = ERROR_NOT_ENOUGH_MEMORY;
140510122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
140610122SJordan.Brown@Sun.COM 	}
140710122SJordan.Brown@Sun.COM 
140810122SJordan.Brown@Sun.COM 	if ((ns = smb_kmod_enum_init(&se)) == NULL) {
140910122SJordan.Brown@Sun.COM 		status = ERROR_NOT_ENOUGH_MEMORY;
141010122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
141110122SJordan.Brown@Sun.COM 	}
141210122SJordan.Brown@Sun.COM 
141310122SJordan.Brown@Sun.COM 	status = srvsvc_NetSessionEnumCommon(mxa, info, ns, &se);
141410122SJordan.Brown@Sun.COM 	smb_kmod_enum_fini(ns);
141510122SJordan.Brown@Sun.COM 
141610122SJordan.Brown@Sun.COM 	if (status != ERROR_SUCCESS)
141710122SJordan.Brown@Sun.COM 		goto srvsvc_netsessionenum_error;
141810122SJordan.Brown@Sun.COM 
141910122SJordan.Brown@Sun.COM 	if (param->resume_handle &&
142010122SJordan.Brown@Sun.COM 	    param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) {
142110122SJordan.Brown@Sun.COM 		if (se.se_resume < param->total_entries) {
142210122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
142310122SJordan.Brown@Sun.COM 			status = ERROR_MORE_DATA;
142410122SJordan.Brown@Sun.COM 		}
142510122SJordan.Brown@Sun.COM 	}
142610122SJordan.Brown@Sun.COM 
142710122SJordan.Brown@Sun.COM 	param->total_entries = info->entriesread;
142810122SJordan.Brown@Sun.COM 	param->status = status;
142910122SJordan.Brown@Sun.COM 	return (NDR_DRC_OK);
143010122SJordan.Brown@Sun.COM 
143110122SJordan.Brown@Sun.COM srvsvc_netsessionenum_error:
143210122SJordan.Brown@Sun.COM 	bzero(param, sizeof (struct mslm_NetSessionEnum));
14338474SJose.Borrego@Sun.COM 	param->status = status;
14348474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
14358474SJose.Borrego@Sun.COM }
14368474SJose.Borrego@Sun.COM 
143710122SJordan.Brown@Sun.COM static uint32_t
143810122SJordan.Brown@Sun.COM srvsvc_NetSessionEnumCommon(ndr_xa_t *mxa, srvsvc_infonres_t *info,
143910122SJordan.Brown@Sun.COM     smb_netsvc_t *ns, smb_svcenum_t *se)
14408474SJose.Borrego@Sun.COM {
144110122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_0	*info0 = info->entries;
144210122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_1	*info1 = info->entries;
144310122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_2	*info2 = info->entries;
144410122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_10	*info10 = info->entries;
144510122SJordan.Brown@Sun.COM 	struct mslm_SESSION_INFO_502	*info502 = info->entries;
144610122SJordan.Brown@Sun.COM 	smb_netsvcitem_t		*item;
144710122SJordan.Brown@Sun.COM 	smb_netuserinfo_t		*user;
144810122SJordan.Brown@Sun.COM 	char				*workstation;
144910122SJordan.Brown@Sun.COM 	char				account[MAXNAMELEN];
145010122SJordan.Brown@Sun.COM 	char				ipaddr_buf[INET6_ADDRSTRLEN];
145110122SJordan.Brown@Sun.COM 	uint32_t			logon_time;
145210122SJordan.Brown@Sun.COM 	uint32_t			flags;
145310122SJordan.Brown@Sun.COM 	uint32_t			entries_read = 0;
145410122SJordan.Brown@Sun.COM 
145510122SJordan.Brown@Sun.COM 	if (smb_kmod_enum(ns) != 0)
145610122SJordan.Brown@Sun.COM 		return (ERROR_INTERNAL_ERROR);
145710122SJordan.Brown@Sun.COM 
145810122SJordan.Brown@Sun.COM 	item = list_head(&ns->ns_list);
145910122SJordan.Brown@Sun.COM 	while (item != NULL) {
146010122SJordan.Brown@Sun.COM 		user = &item->nsi_un.nsi_user;
146110122SJordan.Brown@Sun.COM 
146210122SJordan.Brown@Sun.COM 		workstation = user->ui_workstation;
14638474SJose.Borrego@Sun.COM 		if (workstation == NULL || *workstation == '\0') {
146410122SJordan.Brown@Sun.COM 			(void) smb_inet_ntop(&user->ui_ipaddr, ipaddr_buf,
146510122SJordan.Brown@Sun.COM 			    SMB_IPSTRLEN(user->ui_ipaddr.a_family));
14668474SJose.Borrego@Sun.COM 			workstation = ipaddr_buf;
14678474SJose.Borrego@Sun.COM 		}
14688474SJose.Borrego@Sun.COM 
14698474SJose.Borrego@Sun.COM 		(void) snprintf(account, MAXNAMELEN, "%s\\%s",
147010122SJordan.Brown@Sun.COM 		    user->ui_domain, user->ui_account);
147110122SJordan.Brown@Sun.COM 
147210122SJordan.Brown@Sun.COM 		logon_time = time(0) - user->ui_logon_time;
147310122SJordan.Brown@Sun.COM 		flags = (user->ui_flags & SMB_ATF_GUEST) ? SESS_GUEST : 0;
147410122SJordan.Brown@Sun.COM 
147510122SJordan.Brown@Sun.COM 		switch (se->se_level) {
147610122SJordan.Brown@Sun.COM 		case 0:
147710122SJordan.Brown@Sun.COM 			info0->sesi0_cname = NDR_STRDUP(mxa, workstation);
147810122SJordan.Brown@Sun.COM 			if (info0->sesi0_cname == NULL)
147910122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
148010122SJordan.Brown@Sun.COM 			++info0;
148110122SJordan.Brown@Sun.COM 			break;
148210122SJordan.Brown@Sun.COM 
148310122SJordan.Brown@Sun.COM 		case 1:
148410122SJordan.Brown@Sun.COM 			info1->sesi1_cname = NDR_STRDUP(mxa, workstation);
148510122SJordan.Brown@Sun.COM 			info1->sesi1_uname = NDR_STRDUP(mxa, account);
148610122SJordan.Brown@Sun.COM 
148710122SJordan.Brown@Sun.COM 			if (info1->sesi1_cname == NULL ||
148810122SJordan.Brown@Sun.COM 			    info1->sesi1_uname == NULL)
148910122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
149010122SJordan.Brown@Sun.COM 
149110122SJordan.Brown@Sun.COM 			info1->sesi1_nopens = user->ui_numopens;
149210122SJordan.Brown@Sun.COM 			info1->sesi1_time = logon_time;
149310122SJordan.Brown@Sun.COM 			info1->sesi1_itime = 0;
149410122SJordan.Brown@Sun.COM 			info1->sesi1_uflags = flags;
149510122SJordan.Brown@Sun.COM 			++info1;
149610122SJordan.Brown@Sun.COM 			break;
149710122SJordan.Brown@Sun.COM 
149810122SJordan.Brown@Sun.COM 		case 2:
149910122SJordan.Brown@Sun.COM 			info2->sesi2_cname = NDR_STRDUP(mxa, workstation);
150010122SJordan.Brown@Sun.COM 			info2->sesi2_uname = NDR_STRDUP(mxa, account);
150110122SJordan.Brown@Sun.COM 
150210122SJordan.Brown@Sun.COM 			if (info2->sesi2_cname == NULL ||
150310122SJordan.Brown@Sun.COM 			    info2->sesi2_uname == NULL)
150410122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
150510122SJordan.Brown@Sun.COM 
150610122SJordan.Brown@Sun.COM 			info2->sesi2_nopens = user->ui_numopens;
150710122SJordan.Brown@Sun.COM 			info2->sesi2_time = logon_time;
150810122SJordan.Brown@Sun.COM 			info2->sesi2_itime = 0;
150910122SJordan.Brown@Sun.COM 			info2->sesi2_uflags = flags;
151010122SJordan.Brown@Sun.COM 			info2->sesi2_cltype_name = (uint8_t *)"";
151110122SJordan.Brown@Sun.COM 			++info2;
151210122SJordan.Brown@Sun.COM 			break;
151310122SJordan.Brown@Sun.COM 
151410122SJordan.Brown@Sun.COM 		case 10:
151510122SJordan.Brown@Sun.COM 			info10->sesi10_cname = NDR_STRDUP(mxa, workstation);
151610122SJordan.Brown@Sun.COM 			info10->sesi10_uname = NDR_STRDUP(mxa, account);
151710122SJordan.Brown@Sun.COM 
151810122SJordan.Brown@Sun.COM 			if (info10->sesi10_cname == NULL ||
151910122SJordan.Brown@Sun.COM 			    info10->sesi10_uname == NULL)
152010122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
152110122SJordan.Brown@Sun.COM 
152210122SJordan.Brown@Sun.COM 			info10->sesi10_time = logon_time;
152310122SJordan.Brown@Sun.COM 			info10->sesi10_itime = 0;
152410122SJordan.Brown@Sun.COM 			++info10;
152510122SJordan.Brown@Sun.COM 			break;
152610122SJordan.Brown@Sun.COM 
152710122SJordan.Brown@Sun.COM 		case 502:
152810122SJordan.Brown@Sun.COM 			info502->sesi502_cname = NDR_STRDUP(mxa, workstation);
152910122SJordan.Brown@Sun.COM 			info502->sesi502_uname = NDR_STRDUP(mxa, account);
153010122SJordan.Brown@Sun.COM 
153110122SJordan.Brown@Sun.COM 			if (info502->sesi502_cname == NULL ||
153210122SJordan.Brown@Sun.COM 			    info502->sesi502_uname == NULL)
153310122SJordan.Brown@Sun.COM 				return (ERROR_NOT_ENOUGH_MEMORY);
153410122SJordan.Brown@Sun.COM 
153510122SJordan.Brown@Sun.COM 			info502->sesi502_nopens = user->ui_numopens;
153610122SJordan.Brown@Sun.COM 			info502->sesi502_time = logon_time;
153710122SJordan.Brown@Sun.COM 			info502->sesi502_itime = 0;
153810122SJordan.Brown@Sun.COM 			info502->sesi502_uflags = flags;
153910122SJordan.Brown@Sun.COM 			info502->sesi502_cltype_name = (uint8_t *)"";
154010122SJordan.Brown@Sun.COM 			info502->sesi502_transport = (uint8_t *)"";
154110122SJordan.Brown@Sun.COM 			++info502;
154210122SJordan.Brown@Sun.COM 			break;
154310122SJordan.Brown@Sun.COM 
154410122SJordan.Brown@Sun.COM 		default:
154510122SJordan.Brown@Sun.COM 			return (ERROR_INVALID_LEVEL);
15468474SJose.Borrego@Sun.COM 		}
15478474SJose.Borrego@Sun.COM 
154810122SJordan.Brown@Sun.COM 		++entries_read;
154910122SJordan.Brown@Sun.COM 		item = list_next(&ns->ns_list, item);
15509832Samw@Sun.COM 	}
15519832Samw@Sun.COM 
155210122SJordan.Brown@Sun.COM 	info->entriesread = entries_read;
15539832Samw@Sun.COM 	return (ERROR_SUCCESS);
15549832Samw@Sun.COM }
15559832Samw@Sun.COM 
15569832Samw@Sun.COM /*
15578474SJose.Borrego@Sun.COM  * srvsvc_s_NetSessionDel
15588474SJose.Borrego@Sun.COM  *
15598474SJose.Borrego@Sun.COM  * Ends a network session between a server and a workstation.
15608474SJose.Borrego@Sun.COM  * On NT only members of the Administrators or Account Operators
15618474SJose.Borrego@Sun.COM  * local groups are permitted to use NetSessionDel.
15628474SJose.Borrego@Sun.COM  *
156310122SJordan.Brown@Sun.COM  * If unc_clientname is NULL, all sessions associated with the
156410122SJordan.Brown@Sun.COM  * specified user will be disconnected.
156510122SJordan.Brown@Sun.COM  *
156610122SJordan.Brown@Sun.COM  * If username is NULL, all sessions from the specified client
156710122SJordan.Brown@Sun.COM  * will be disconnected.
156810122SJordan.Brown@Sun.COM  *
15698474SJose.Borrego@Sun.COM  * Return Values
157010122SJordan.Brown@Sun.COM  * On success, the return value is NERR_Success/ERROR_SUCCESS.
157110122SJordan.Brown@Sun.COM  * On failure, the return value can be one of the following errors:
15728474SJose.Borrego@Sun.COM  *
15738474SJose.Borrego@Sun.COM  * ERROR_ACCESS_DENIED 		The user does not have access to the
157410122SJordan.Brown@Sun.COM  * 				requested information.
15758474SJose.Borrego@Sun.COM  * ERROR_INVALID_PARAMETER	The specified parameter is invalid.
15768474SJose.Borrego@Sun.COM  * ERROR_NOT_ENOUGH_MEMORY	Insufficient memory is available.
15778474SJose.Borrego@Sun.COM  * NERR_ClientNameNotFound	A session does not exist with that
157810122SJordan.Brown@Sun.COM  *				computer name.
15798474SJose.Borrego@Sun.COM  */
15808474SJose.Borrego@Sun.COM static int
15818474SJose.Borrego@Sun.COM srvsvc_s_NetSessionDel(void *arg, ndr_xa_t *mxa)
15828474SJose.Borrego@Sun.COM {
158310122SJordan.Brown@Sun.COM 	static struct {
158410122SJordan.Brown@Sun.COM 		int errnum;
158510122SJordan.Brown@Sun.COM 		int nerr;
158610122SJordan.Brown@Sun.COM 	} errmap[] = {
158710122SJordan.Brown@Sun.COM 		0,	ERROR_SUCCESS,
158810122SJordan.Brown@Sun.COM 		EACCES,	ERROR_ACCESS_DENIED,
158910122SJordan.Brown@Sun.COM 		EPERM,	ERROR_ACCESS_DENIED,
159010122SJordan.Brown@Sun.COM 		EINVAL,	ERROR_INVALID_PARAMETER,
159110122SJordan.Brown@Sun.COM 		ENOMEM,	ERROR_NOT_ENOUGH_MEMORY,
159210122SJordan.Brown@Sun.COM 		ENOENT,	NERR_ClientNameNotFound
159310122SJordan.Brown@Sun.COM 	};
159410122SJordan.Brown@Sun.COM 
15958474SJose.Borrego@Sun.COM 	struct mslm_NetSessionDel *param = arg;
159610122SJordan.Brown@Sun.COM 	int	i;
159710122SJordan.Brown@Sun.COM 	int	rc;
159810122SJordan.Brown@Sun.COM 
159910122SJordan.Brown@Sun.COM 	if (!ndr_is_admin(mxa)) {
16008474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
16018474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
16028474SJose.Borrego@Sun.COM 	}
16038474SJose.Borrego@Sun.COM 
160410122SJordan.Brown@Sun.COM 	rc = smb_kmod_session_close((char *)param->unc_clientname,
160510122SJordan.Brown@Sun.COM 	    (char *)param->username);
160610122SJordan.Brown@Sun.COM 
160710122SJordan.Brown@Sun.COM 	for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) {
160810122SJordan.Brown@Sun.COM 		if (rc == errmap[i].errnum) {
160910122SJordan.Brown@Sun.COM 			param->status = errmap[i].nerr;
161010122SJordan.Brown@Sun.COM 			return (NDR_DRC_OK);
161110122SJordan.Brown@Sun.COM 		}
161210122SJordan.Brown@Sun.COM 	}
161310122SJordan.Brown@Sun.COM 
161410122SJordan.Brown@Sun.COM 	param->status = ERROR_INTERNAL_ERROR;
16158474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
16168474SJose.Borrego@Sun.COM }
16178474SJose.Borrego@Sun.COM 
16188474SJose.Borrego@Sun.COM /*
16198474SJose.Borrego@Sun.COM  * SRVSVC NetServerGetInfo
16208474SJose.Borrego@Sun.COM  *
16218474SJose.Borrego@Sun.COM  *	IN	LPTSTR servername,
16228474SJose.Borrego@Sun.COM  *	IN	DWORD level,
16238474SJose.Borrego@Sun.COM  *	OUT	union switch(level) {
16248474SJose.Borrego@Sun.COM  *		case 100:	mslm_SERVER_INFO_100 *p100;
16258474SJose.Borrego@Sun.COM  *		case 101:	mslm_SERVER_INFO_101 *p101;
16268474SJose.Borrego@Sun.COM  *		case 102:	mslm_SERVER_INFO_102 *p102;
16279832Samw@Sun.COM  *		...
16288474SJose.Borrego@Sun.COM  *		default:	char *nullptr;
16298474SJose.Borrego@Sun.COM  *		} bufptr,
16308474SJose.Borrego@Sun.COM  *	OUT	DWORD status
16318474SJose.Borrego@Sun.COM  */
16328474SJose.Borrego@Sun.COM static int
16338474SJose.Borrego@Sun.COM srvsvc_s_NetServerGetInfo(void *arg, ndr_xa_t *mxa)
16348474SJose.Borrego@Sun.COM {
16358474SJose.Borrego@Sun.COM 	struct mslm_NetServerGetInfo *param = arg;
16368474SJose.Borrego@Sun.COM 	struct mslm_SERVER_INFO_100 *info100;
16378474SJose.Borrego@Sun.COM 	struct mslm_SERVER_INFO_101 *info101;
16388474SJose.Borrego@Sun.COM 	struct mslm_SERVER_INFO_102 *info102;
16399832Samw@Sun.COM 	struct mslm_SERVER_INFO_502 *info502;
16409832Samw@Sun.COM 	struct mslm_SERVER_INFO_503 *info503;
16418474SJose.Borrego@Sun.COM 	char sys_comment[SMB_PI_MAX_COMMENT];
16428474SJose.Borrego@Sun.COM 	char hostname[NETBIOS_NAME_SZ];
16438474SJose.Borrego@Sun.COM 
16448474SJose.Borrego@Sun.COM 	if (smb_getnetbiosname(hostname, sizeof (hostname)) != 0) {
16458474SJose.Borrego@Sun.COM netservergetinfo_no_memory:
16468474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetServerGetInfo));
16478474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
16488474SJose.Borrego@Sun.COM 	}
16498474SJose.Borrego@Sun.COM 
16508474SJose.Borrego@Sun.COM 	(void) smb_config_getstr(SMB_CI_SYS_CMNT, sys_comment,
16518474SJose.Borrego@Sun.COM 	    sizeof (sys_comment));
16528474SJose.Borrego@Sun.COM 	if (*sys_comment == '\0')
16538474SJose.Borrego@Sun.COM 		(void) strcpy(sys_comment, " ");
16548474SJose.Borrego@Sun.COM 
16558474SJose.Borrego@Sun.COM 	switch (param->level) {
16568474SJose.Borrego@Sun.COM 	case 100:
16578474SJose.Borrego@Sun.COM 		info100 = NDR_NEW(mxa, struct mslm_SERVER_INFO_100);
16588474SJose.Borrego@Sun.COM 		if (info100 == NULL)
16598474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
16608474SJose.Borrego@Sun.COM 
16618474SJose.Borrego@Sun.COM 		bzero(info100, sizeof (struct mslm_SERVER_INFO_100));
16628474SJose.Borrego@Sun.COM 		info100->sv100_platform_id = SV_PLATFORM_ID_NT;
16638474SJose.Borrego@Sun.COM 		info100->sv100_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
16648474SJose.Borrego@Sun.COM 		if (info100->sv100_name == NULL)
16658474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
16668474SJose.Borrego@Sun.COM 
16678474SJose.Borrego@Sun.COM 		param->result.bufptr.bufptr100 = info100;
16688474SJose.Borrego@Sun.COM 		break;
16698474SJose.Borrego@Sun.COM 
16708474SJose.Borrego@Sun.COM 	case 101:
16718474SJose.Borrego@Sun.COM 		info101 = NDR_NEW(mxa, struct mslm_SERVER_INFO_101);
16728474SJose.Borrego@Sun.COM 		if (info101 == NULL)
16738474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
16748474SJose.Borrego@Sun.COM 
16758474SJose.Borrego@Sun.COM 		bzero(info101, sizeof (struct mslm_SERVER_INFO_101));
16768474SJose.Borrego@Sun.COM 		info101->sv101_platform_id = SV_PLATFORM_ID_NT;
16778474SJose.Borrego@Sun.COM 		info101->sv101_version_major = 4;
16788474SJose.Borrego@Sun.COM 		info101->sv101_version_minor = 0;
1679*11337SWilliam.Krier@Sun.COM 		info101->sv101_type = SV_TYPE_DEFAULT;
16808474SJose.Borrego@Sun.COM 		info101->sv101_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
16818474SJose.Borrego@Sun.COM 		info101->sv101_comment
16828474SJose.Borrego@Sun.COM 		    = (uint8_t *)NDR_STRDUP(mxa, sys_comment);
16838474SJose.Borrego@Sun.COM 
16848474SJose.Borrego@Sun.COM 		if (info101->sv101_name == NULL ||
16858474SJose.Borrego@Sun.COM 		    info101->sv101_comment == NULL)
16868474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
16878474SJose.Borrego@Sun.COM 
16888474SJose.Borrego@Sun.COM 		param->result.bufptr.bufptr101 = info101;
16898474SJose.Borrego@Sun.COM 		break;
16908474SJose.Borrego@Sun.COM 
16918474SJose.Borrego@Sun.COM 	case 102:
16928474SJose.Borrego@Sun.COM 		info102 = NDR_NEW(mxa, struct mslm_SERVER_INFO_102);
16938474SJose.Borrego@Sun.COM 		if (info102 == NULL)
16948474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
16958474SJose.Borrego@Sun.COM 
16968474SJose.Borrego@Sun.COM 		bzero(info102, sizeof (struct mslm_SERVER_INFO_102));
16978474SJose.Borrego@Sun.COM 		info102->sv102_platform_id = SV_PLATFORM_ID_NT;
16988474SJose.Borrego@Sun.COM 		info102->sv102_version_major = 4;
16998474SJose.Borrego@Sun.COM 		info102->sv102_version_minor = 0;
1700*11337SWilliam.Krier@Sun.COM 		info102->sv102_type = SV_TYPE_DEFAULT;
17018474SJose.Borrego@Sun.COM 		info102->sv102_name = (uint8_t *)NDR_STRDUP(mxa, hostname);
17028474SJose.Borrego@Sun.COM 		info102->sv102_comment
17038474SJose.Borrego@Sun.COM 		    = (uint8_t *)NDR_STRDUP(mxa, sys_comment);
17048474SJose.Borrego@Sun.COM 
17058474SJose.Borrego@Sun.COM 		/*
17068474SJose.Borrego@Sun.COM 		 * The following level 102 fields are defaulted to zero
17078474SJose.Borrego@Sun.COM 		 * by virtue of the call to bzero above.
17088474SJose.Borrego@Sun.COM 		 *
17098474SJose.Borrego@Sun.COM 		 * sv102_users
17108474SJose.Borrego@Sun.COM 		 * sv102_disc
17118474SJose.Borrego@Sun.COM 		 * sv102_hidden
17128474SJose.Borrego@Sun.COM 		 * sv102_announce
17138474SJose.Borrego@Sun.COM 		 * sv102_anndelta
17148474SJose.Borrego@Sun.COM 		 * sv102_licenses
17158474SJose.Borrego@Sun.COM 		 * sv102_userpath
17168474SJose.Borrego@Sun.COM 		 */
17178474SJose.Borrego@Sun.COM 		if (info102->sv102_name == NULL ||
17188474SJose.Borrego@Sun.COM 		    info102->sv102_comment == NULL)
17198474SJose.Borrego@Sun.COM 			goto netservergetinfo_no_memory;
17208474SJose.Borrego@Sun.COM 
17218474SJose.Borrego@Sun.COM 		param->result.bufptr.bufptr102 = info102;
17228474SJose.Borrego@Sun.COM 		break;
17238474SJose.Borrego@Sun.COM 
17249832Samw@Sun.COM 	case 502:
17259832Samw@Sun.COM 		info502 = NDR_NEW(mxa, struct mslm_SERVER_INFO_502);
17269832Samw@Sun.COM 		if (info502 == NULL)
17279832Samw@Sun.COM 			goto netservergetinfo_no_memory;
17289832Samw@Sun.COM 
17299832Samw@Sun.COM 		bzero(info502, sizeof (struct mslm_SERVER_INFO_502));
17309832Samw@Sun.COM 		param->result.bufptr.bufptr502 = info502;
17319832Samw@Sun.COM #ifdef SRVSVC_SATISFY_SMBTORTURE
17329832Samw@Sun.COM 		break;
17339832Samw@Sun.COM #else
17349832Samw@Sun.COM 		param->result.level = param->level;
17359832Samw@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
17369832Samw@Sun.COM 		return (NDR_DRC_OK);
17379832Samw@Sun.COM #endif /* SRVSVC_SATISFY_SMBTORTURE */
17389832Samw@Sun.COM 
17399832Samw@Sun.COM 	case 503:
17409832Samw@Sun.COM 		info503 = NDR_NEW(mxa, struct mslm_SERVER_INFO_503);
17419832Samw@Sun.COM 		if (info503 == NULL)
17429832Samw@Sun.COM 			goto netservergetinfo_no_memory;
17439832Samw@Sun.COM 
17449832Samw@Sun.COM 		bzero(info503, sizeof (struct mslm_SERVER_INFO_503));
17459832Samw@Sun.COM 		param->result.bufptr.bufptr503 = info503;
17469832Samw@Sun.COM #ifdef SRVSVC_SATISFY_SMBTORTURE
17479832Samw@Sun.COM 		break;
17489832Samw@Sun.COM #else
17499832Samw@Sun.COM 		param->result.level = param->level;
17509832Samw@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
17519832Samw@Sun.COM 		return (NDR_DRC_OK);
17529832Samw@Sun.COM #endif /* SRVSVC_SATISFY_SMBTORTURE */
17539832Samw@Sun.COM 
17548474SJose.Borrego@Sun.COM 	default:
17558474SJose.Borrego@Sun.COM 		bzero(&param->result,
17568474SJose.Borrego@Sun.COM 		    sizeof (struct mslm_NetServerGetInfo_result));
17578474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
17588474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
17598474SJose.Borrego@Sun.COM 	}
17608474SJose.Borrego@Sun.COM 
17618474SJose.Borrego@Sun.COM 	param->result.level = param->level;
17629832Samw@Sun.COM 	param->status = ERROR_SUCCESS;
17638474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
17648474SJose.Borrego@Sun.COM }
17658474SJose.Borrego@Sun.COM 
17668474SJose.Borrego@Sun.COM /*
17678474SJose.Borrego@Sun.COM  * NetRemoteTOD
17688474SJose.Borrego@Sun.COM  *
17698474SJose.Borrego@Sun.COM  * Returns information about the time of day on this server.
17708474SJose.Borrego@Sun.COM  *
17718474SJose.Borrego@Sun.COM  * typedef struct _TIME_OF_DAY_INFO {
17728474SJose.Borrego@Sun.COM  *	DWORD tod_elapsedt;  // seconds since 00:00:00 January 1 1970 GMT
17738474SJose.Borrego@Sun.COM  *	DWORD tod_msecs;     // arbitrary milliseconds (since reset)
17748474SJose.Borrego@Sun.COM  *	DWORD tod_hours;     // current hour [0-23]
17758474SJose.Borrego@Sun.COM  *	DWORD tod_mins;      // current minute [0-59]
17768474SJose.Borrego@Sun.COM  *	DWORD tod_secs;      // current second [0-59]
17778474SJose.Borrego@Sun.COM  *	DWORD tod_hunds;     // current hundredth (0.01) second [0-99]
17788474SJose.Borrego@Sun.COM  *	LONG tod_timezone;   // time zone of the server
17798474SJose.Borrego@Sun.COM  *	DWORD tod_tinterval; // clock tick time interval
17808474SJose.Borrego@Sun.COM  *	DWORD tod_day;       // day of the month [1-31]
17818474SJose.Borrego@Sun.COM  *	DWORD tod_month;     // month of the year [1-12]
17828474SJose.Borrego@Sun.COM  *	DWORD tod_year;      // current year
17838474SJose.Borrego@Sun.COM  *	DWORD tod_weekday;   // day of the week since Sunday [0-6]
17848474SJose.Borrego@Sun.COM  * } TIME_OF_DAY_INFO;
17858474SJose.Borrego@Sun.COM  *
17868474SJose.Borrego@Sun.COM  * The time zone of the server is calculated in minutes from Greenwich
17878474SJose.Borrego@Sun.COM  * Mean Time (GMT). For time zones west of Greenwich, the value is
17888474SJose.Borrego@Sun.COM  * positive; for time zones east of Greenwich, the value is negative.
17898474SJose.Borrego@Sun.COM  * A value of -1 indicates that the time zone is undefined.
17908474SJose.Borrego@Sun.COM  *
179110966SJordan.Brown@Sun.COM  * Determine offset from GMT. If daylight saving time use altzone,
179210966SJordan.Brown@Sun.COM  * otherwise use timezone.
179310966SJordan.Brown@Sun.COM  *
17948474SJose.Borrego@Sun.COM  * The clock tick value represents a resolution of one ten-thousandth
17958474SJose.Borrego@Sun.COM  * (0.0001) second.
17968474SJose.Borrego@Sun.COM  */
17978474SJose.Borrego@Sun.COM static int
17988474SJose.Borrego@Sun.COM srvsvc_s_NetRemoteTOD(void *arg, ndr_xa_t *mxa)
17998474SJose.Borrego@Sun.COM {
18008474SJose.Borrego@Sun.COM 	struct mslm_NetRemoteTOD *param = arg;
18018474SJose.Borrego@Sun.COM 	struct mslm_TIME_OF_DAY_INFO *tod;
18028474SJose.Borrego@Sun.COM 	struct timeval		time_val;
18038474SJose.Borrego@Sun.COM 	struct tm		tm;
180410966SJordan.Brown@Sun.COM 	time_t			gmtoff;
180510966SJordan.Brown@Sun.COM 
18068474SJose.Borrego@Sun.COM 
18078474SJose.Borrego@Sun.COM 	(void) gettimeofday(&time_val, 0);
18088474SJose.Borrego@Sun.COM 	(void) gmtime_r(&time_val.tv_sec, &tm);
18098474SJose.Borrego@Sun.COM 
18108474SJose.Borrego@Sun.COM 	tod = NDR_NEW(mxa, struct mslm_TIME_OF_DAY_INFO);
18118474SJose.Borrego@Sun.COM 	if (tod == NULL) {
18128474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetRemoteTOD));
18138474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
18148474SJose.Borrego@Sun.COM 	}
18158474SJose.Borrego@Sun.COM 
181610966SJordan.Brown@Sun.COM 	bzero(tod, sizeof (struct mslm_TIME_OF_DAY_INFO));
181710966SJordan.Brown@Sun.COM 
18188474SJose.Borrego@Sun.COM 	tod->tod_elapsedt = time_val.tv_sec;
18198474SJose.Borrego@Sun.COM 	tod->tod_msecs = time_val.tv_usec;
18208474SJose.Borrego@Sun.COM 	tod->tod_hours = tm.tm_hour;
18218474SJose.Borrego@Sun.COM 	tod->tod_mins = tm.tm_min;
18228474SJose.Borrego@Sun.COM 	tod->tod_secs = tm.tm_sec;
18238474SJose.Borrego@Sun.COM 	tod->tod_hunds = 0;
18248474SJose.Borrego@Sun.COM 	tod->tod_tinterval = 1000;
18258474SJose.Borrego@Sun.COM 	tod->tod_day = tm.tm_mday;
18268474SJose.Borrego@Sun.COM 	tod->tod_month = tm.tm_mon+1;
18278474SJose.Borrego@Sun.COM 	tod->tod_year = tm.tm_year+1900;
18288474SJose.Borrego@Sun.COM 	tod->tod_weekday = tm.tm_wday;
18298474SJose.Borrego@Sun.COM 
18308474SJose.Borrego@Sun.COM 	(void) localtime_r(&time_val.tv_sec, &tm);
183110966SJordan.Brown@Sun.COM 	gmtoff = (tm.tm_isdst) ? altzone : timezone;
183210966SJordan.Brown@Sun.COM 	tod->tod_timezone = gmtoff / SECSPERMIN;
18338474SJose.Borrego@Sun.COM 
18348474SJose.Borrego@Sun.COM 	param->bufptr = tod;
18358474SJose.Borrego@Sun.COM 	param->status = ERROR_SUCCESS;
18368474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
18378474SJose.Borrego@Sun.COM }
18388474SJose.Borrego@Sun.COM 
18398474SJose.Borrego@Sun.COM /*
18408474SJose.Borrego@Sun.COM  * srvsvc_s_NetNameValidate
18418474SJose.Borrego@Sun.COM  *
18428474SJose.Borrego@Sun.COM  * Perform name validation.
18438474SJose.Borrego@Sun.COM  *
18448474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
18458474SJose.Borrego@Sun.COM  */
18468474SJose.Borrego@Sun.COM /*ARGSUSED*/
18478474SJose.Borrego@Sun.COM static int
18488474SJose.Borrego@Sun.COM srvsvc_s_NetNameValidate(void *arg, ndr_xa_t *mxa)
18498474SJose.Borrego@Sun.COM {
18508474SJose.Borrego@Sun.COM 	struct mslm_NetNameValidate *param = arg;
18518474SJose.Borrego@Sun.COM 	char *name;
1852*11337SWilliam.Krier@Sun.COM 	int maxlen;
18538474SJose.Borrego@Sun.COM 	int len;
18548474SJose.Borrego@Sun.COM 
18558474SJose.Borrego@Sun.COM 	if ((name = (char *)param->pathname) == NULL) {
18568474SJose.Borrego@Sun.COM 		param->status = ERROR_INVALID_PARAMETER;
18578474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
18588474SJose.Borrego@Sun.COM 	}
18598474SJose.Borrego@Sun.COM 
18608474SJose.Borrego@Sun.COM 	switch (param->type) {
18618474SJose.Borrego@Sun.COM 	case NAMETYPE_SHARE:
1862*11337SWilliam.Krier@Sun.COM 		len = strlen(name);
1863*11337SWilliam.Krier@Sun.COM 		maxlen = (param->flags & NAMEFLAG_LM2) ?
1864*11337SWilliam.Krier@Sun.COM 		    SMB_SHARE_OEMNAME_MAX : SMB_SHARE_NTNAME_MAX;
1865*11337SWilliam.Krier@Sun.COM 
1866*11337SWilliam.Krier@Sun.COM 		if (len > maxlen) {
18678474SJose.Borrego@Sun.COM 			param->status = ERROR_INVALID_NAME;
1868*11337SWilliam.Krier@Sun.COM 			return (NDR_DRC_OK);
1869*11337SWilliam.Krier@Sun.COM 		}
1870*11337SWilliam.Krier@Sun.COM 
1871*11337SWilliam.Krier@Sun.COM 		param->status = smb_name_validate_share(name);
18728474SJose.Borrego@Sun.COM 		break;
18738474SJose.Borrego@Sun.COM 
18748474SJose.Borrego@Sun.COM 	case NAMETYPE_USER:
1875*11337SWilliam.Krier@Sun.COM 	case NAMETYPE_GROUP:
1876*11337SWilliam.Krier@Sun.COM 		param->status = smb_name_validate_account(name);
1877*11337SWilliam.Krier@Sun.COM 		break;
1878*11337SWilliam.Krier@Sun.COM 
1879*11337SWilliam.Krier@Sun.COM 	case NAMETYPE_DOMAIN:	/* NetBIOS domain name */
1880*11337SWilliam.Krier@Sun.COM 		param->status = smb_name_validate_nbdomain(name);
1881*11337SWilliam.Krier@Sun.COM 		break;
1882*11337SWilliam.Krier@Sun.COM 
1883*11337SWilliam.Krier@Sun.COM 	case NAMETYPE_WORKGROUP:
1884*11337SWilliam.Krier@Sun.COM 		param->status = smb_name_validate_workgroup(name);
1885*11337SWilliam.Krier@Sun.COM 		break;
1886*11337SWilliam.Krier@Sun.COM 
18878474SJose.Borrego@Sun.COM 	case NAMETYPE_PASSWORD:
18888474SJose.Borrego@Sun.COM 	case NAMETYPE_COMPUTER:
18898474SJose.Borrego@Sun.COM 	case NAMETYPE_EVENT:
18908474SJose.Borrego@Sun.COM 	case NAMETYPE_SERVICE:
18918474SJose.Borrego@Sun.COM 	case NAMETYPE_NET:
18928474SJose.Borrego@Sun.COM 	case NAMETYPE_MESSAGE:
18938474SJose.Borrego@Sun.COM 	case NAMETYPE_MESSAGEDEST:
18948474SJose.Borrego@Sun.COM 	case NAMETYPE_SHAREPASSWORD:
18958474SJose.Borrego@Sun.COM 		param->status = ERROR_NOT_SUPPORTED;
18968474SJose.Borrego@Sun.COM 		break;
18978474SJose.Borrego@Sun.COM 
18988474SJose.Borrego@Sun.COM 	default:
18998474SJose.Borrego@Sun.COM 		param->status = ERROR_INVALID_PARAMETER;
19008474SJose.Borrego@Sun.COM 		break;
19018474SJose.Borrego@Sun.COM 	}
19028474SJose.Borrego@Sun.COM 
19038474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
19048474SJose.Borrego@Sun.COM }
19058474SJose.Borrego@Sun.COM 
19068474SJose.Borrego@Sun.COM /*
19078474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareAdd
19088474SJose.Borrego@Sun.COM  *
19099832Samw@Sun.COM  * Add a new share. Only power users groups can manage shares.
19108474SJose.Borrego@Sun.COM  *
19118474SJose.Borrego@Sun.COM  * This interface is used by the rmtshare command from the NT resource
19128474SJose.Borrego@Sun.COM  * kit. Rmtshare allows a client to add or remove shares on a server
19138474SJose.Borrego@Sun.COM  * from the client's command line.
19148474SJose.Borrego@Sun.COM  *
19158474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
19168474SJose.Borrego@Sun.COM  */
19178474SJose.Borrego@Sun.COM static int
19188474SJose.Borrego@Sun.COM srvsvc_s_NetShareAdd(void *arg, ndr_xa_t *mxa)
19198474SJose.Borrego@Sun.COM {
19208474SJose.Borrego@Sun.COM 	static DWORD parm_err = 0;
19218474SJose.Borrego@Sun.COM 	DWORD parm_stat;
19228474SJose.Borrego@Sun.COM 	struct mslm_NetShareAdd *param = arg;
19239343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
19249832Samw@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
19258474SJose.Borrego@Sun.COM 	char realpath[MAXPATHLEN];
19268474SJose.Borrego@Sun.COM 	int32_t native_os;
19279832Samw@Sun.COM 	uint8_t *sdbuf = NULL;
19289832Samw@Sun.COM 	uint32_t status;
19299832Samw@Sun.COM 	smb_share_t si;
19308474SJose.Borrego@Sun.COM 
19318474SJose.Borrego@Sun.COM 	native_os = ndr_native_os(mxa);
19328474SJose.Borrego@Sun.COM 
19338474SJose.Borrego@Sun.COM 	if (!ndr_is_poweruser(mxa)) {
19348474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
19358474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
19368474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
19378474SJose.Borrego@Sun.COM 	}
19388474SJose.Borrego@Sun.COM 
19398474SJose.Borrego@Sun.COM 	switch (param->level) {
19408474SJose.Borrego@Sun.COM 	case 2:
19419832Samw@Sun.COM 		info2 = (struct mslm_NetShareInfo_2 *)param->info.un.info2;
19428474SJose.Borrego@Sun.COM 		break;
19438474SJose.Borrego@Sun.COM 
19448474SJose.Borrego@Sun.COM 	case 502:
19459832Samw@Sun.COM 		info502 = (struct mslm_NetShareInfo_502 *)
19469832Samw@Sun.COM 		    param->info.un.info502;
19479832Samw@Sun.COM 		sdbuf = info502->shi502_security_descriptor;
19489832Samw@Sun.COM 		info2 = (struct mslm_NetShareInfo_2 *)info502;
19498474SJose.Borrego@Sun.COM 		break;
19508474SJose.Borrego@Sun.COM 
19518474SJose.Borrego@Sun.COM 	default:
19528474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
19538474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
19548474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
19558474SJose.Borrego@Sun.COM 	}
19568474SJose.Borrego@Sun.COM 
19578474SJose.Borrego@Sun.COM 	if (info2->shi2_netname == NULL || info2->shi2_path == NULL) {
19588474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
19598474SJose.Borrego@Sun.COM 		param->status = NERR_NetNameNotFound;
19608474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
19618474SJose.Borrego@Sun.COM 	}
19628474SJose.Borrego@Sun.COM 
19638474SJose.Borrego@Sun.COM 	if (smb_shr_is_restricted((char *)info2->shi2_netname)) {
19648474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
19658474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
19668474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
19678474SJose.Borrego@Sun.COM 	}
19688474SJose.Borrego@Sun.COM 
19699343SAfshin.Ardakani@Sun.COM 	if (info2->shi2_comment == NULL)
19709343SAfshin.Ardakani@Sun.COM 		info2->shi2_comment = (uint8_t *)"";
19718474SJose.Borrego@Sun.COM 
19728474SJose.Borrego@Sun.COM 	/*
19738474SJose.Borrego@Sun.COM 	 * Derive the real path which will be stored in the
19748474SJose.Borrego@Sun.COM 	 * directory field of the smb_share_t structure
19758474SJose.Borrego@Sun.COM 	 * from the path field in this RPC request.
19768474SJose.Borrego@Sun.COM 	 */
19778474SJose.Borrego@Sun.COM 	parm_stat = smb_shr_get_realpath((const char *)info2->shi2_path,
19788474SJose.Borrego@Sun.COM 	    realpath, MAXPATHLEN);
19798474SJose.Borrego@Sun.COM 
19808474SJose.Borrego@Sun.COM 	if (parm_stat != NERR_Success) {
19818474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareAdd));
19828474SJose.Borrego@Sun.COM 		param->status = parm_stat;
19838474SJose.Borrego@Sun.COM 		param->parm_err
19848474SJose.Borrego@Sun.COM 		    = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
19858474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
19868474SJose.Borrego@Sun.COM 	}
19878474SJose.Borrego@Sun.COM 
19888474SJose.Borrego@Sun.COM 	param->status = srvsvc_sa_add((char *)info2->shi2_netname, realpath,
19899343SAfshin.Ardakani@Sun.COM 	    (char *)info2->shi2_comment);
19908474SJose.Borrego@Sun.COM 	if (param->status == NERR_Success) {
19919832Samw@Sun.COM 		status = smb_shr_get((char *)info2->shi2_netname, &si);
19929832Samw@Sun.COM 
19939832Samw@Sun.COM 		if ((sdbuf != NULL) && (status == NERR_Success))
19949832Samw@Sun.COM 			(void) srvsvc_sd_set(&si, sdbuf);
19958474SJose.Borrego@Sun.COM 	}
19968474SJose.Borrego@Sun.COM 	param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err;
19978474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
19988474SJose.Borrego@Sun.COM }
19998474SJose.Borrego@Sun.COM 
20008474SJose.Borrego@Sun.COM /*
200110122SJordan.Brown@Sun.COM  * srvsvc_estimate_limit
20028474SJose.Borrego@Sun.COM  *
20038474SJose.Borrego@Sun.COM  * Estimate the number of objects that will fit in prefmaxlen.
200410122SJordan.Brown@Sun.COM  * nlimit is adjusted here.
20058474SJose.Borrego@Sun.COM  */
200610122SJordan.Brown@Sun.COM static void
200710122SJordan.Brown@Sun.COM srvsvc_estimate_limit(smb_svcenum_t *se, uint32_t obj_size)
20088474SJose.Borrego@Sun.COM {
20098474SJose.Borrego@Sun.COM 	DWORD max_cnt;
20108474SJose.Borrego@Sun.COM 
201110122SJordan.Brown@Sun.COM 	if (obj_size == 0) {
201210122SJordan.Brown@Sun.COM 		se->se_nlimit = 0;
201310122SJordan.Brown@Sun.COM 		return;
201410122SJordan.Brown@Sun.COM 	}
201510122SJordan.Brown@Sun.COM 
201610122SJordan.Brown@Sun.COM 	if ((max_cnt = (se->se_prefmaxlen / obj_size)) == 0) {
201710122SJordan.Brown@Sun.COM 		se->se_nlimit = 0;
201810122SJordan.Brown@Sun.COM 		return;
201910122SJordan.Brown@Sun.COM 	}
202010122SJordan.Brown@Sun.COM 
202110122SJordan.Brown@Sun.COM 	if (se->se_ntotal > max_cnt)
202210122SJordan.Brown@Sun.COM 		se->se_nlimit = max_cnt;
202310122SJordan.Brown@Sun.COM 	else
202410122SJordan.Brown@Sun.COM 		se->se_nlimit = se->se_ntotal;
20258474SJose.Borrego@Sun.COM }
20268474SJose.Borrego@Sun.COM 
20278474SJose.Borrego@Sun.COM /*
20288474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareEnum
20298474SJose.Borrego@Sun.COM  *
20308474SJose.Borrego@Sun.COM  * Enumerate all shares (see also NetShareEnumSticky).
20318474SJose.Borrego@Sun.COM  *
20328474SJose.Borrego@Sun.COM  * Request for various levels of information about our shares.
20338474SJose.Borrego@Sun.COM  * Level 0: share names.
20348474SJose.Borrego@Sun.COM  * Level 1: share name, share type and comment field.
20358474SJose.Borrego@Sun.COM  * Level 2: everything that we know about the shares.
203610504SKeyur.Desai@Sun.COM  * Level 501: level 1 + flags.
20378474SJose.Borrego@Sun.COM  * Level 502: level 2 + security descriptor.
20388474SJose.Borrego@Sun.COM  */
20398474SJose.Borrego@Sun.COM static int
20408474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnum(void *arg, ndr_xa_t *mxa)
20418474SJose.Borrego@Sun.COM {
20428474SJose.Borrego@Sun.COM 	struct mslm_NetShareEnum *param = arg;
204310122SJordan.Brown@Sun.COM 	srvsvc_infonres_t *infonres;
204410122SJordan.Brown@Sun.COM 	smb_svcenum_t se;
20458474SJose.Borrego@Sun.COM 	DWORD status;
20468474SJose.Borrego@Sun.COM 
204710122SJordan.Brown@Sun.COM 	infonres = NDR_NEW(mxa, srvsvc_infonres_t);
20488474SJose.Borrego@Sun.COM 	if (infonres == NULL) {
20498474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareEnum));
20508474SJose.Borrego@Sun.COM 		param->status = ERROR_NOT_ENOUGH_MEMORY;
20518474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
20528474SJose.Borrego@Sun.COM 	}
20538474SJose.Borrego@Sun.COM 
20548474SJose.Borrego@Sun.COM 	infonres->entriesread = 0;
20558474SJose.Borrego@Sun.COM 	infonres->entries = NULL;
20568474SJose.Borrego@Sun.COM 	param->result.level = param->level;
20578474SJose.Borrego@Sun.COM 	param->result.bufptr.p = infonres;
20588474SJose.Borrego@Sun.COM 
205910122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
206010122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_SHARE;
20618474SJose.Borrego@Sun.COM 	se.se_level = param->level;
206210122SJordan.Brown@Sun.COM 	se.se_ntotal = smb_shr_count();
206310122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
20648474SJose.Borrego@Sun.COM 
20658474SJose.Borrego@Sun.COM 	if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN ||
20668474SJose.Borrego@Sun.COM 	    param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN)
20678474SJose.Borrego@Sun.COM 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
20688474SJose.Borrego@Sun.COM 	else
20698474SJose.Borrego@Sun.COM 		se.se_prefmaxlen = param->prefmaxlen;
20708474SJose.Borrego@Sun.COM 
20718474SJose.Borrego@Sun.COM 	if (param->resume_handle) {
207210122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
207310122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
207410122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
20758474SJose.Borrego@Sun.COM 	}
20768474SJose.Borrego@Sun.COM 
20778474SJose.Borrego@Sun.COM 	switch (param->level) {
20788474SJose.Borrego@Sun.COM 	case 0:
20798474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 0);
20808474SJose.Borrego@Sun.COM 		break;
20818474SJose.Borrego@Sun.COM 
20828474SJose.Borrego@Sun.COM 	case 1:
20838474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 0);
20848474SJose.Borrego@Sun.COM 		break;
20858474SJose.Borrego@Sun.COM 
20868474SJose.Borrego@Sun.COM 	case 2:
20878474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 0);
20888474SJose.Borrego@Sun.COM 		break;
20898474SJose.Borrego@Sun.COM 
20908474SJose.Borrego@Sun.COM 	case 501:
20918474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel501(mxa, infonres, &se, 0);
20928474SJose.Borrego@Sun.COM 		break;
20938474SJose.Borrego@Sun.COM 
20948474SJose.Borrego@Sun.COM 	case 502:
20958474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 0);
20968474SJose.Borrego@Sun.COM 		break;
20978474SJose.Borrego@Sun.COM 
20988474SJose.Borrego@Sun.COM 	default:
20999832Samw@Sun.COM 		status = ERROR_INVALID_LEVEL;
21008474SJose.Borrego@Sun.COM 		break;
21018474SJose.Borrego@Sun.COM 	}
21028474SJose.Borrego@Sun.COM 
21038474SJose.Borrego@Sun.COM 	if (status != 0) {
21048474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareEnum));
21058474SJose.Borrego@Sun.COM 		param->status = status;
21068474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
21078474SJose.Borrego@Sun.COM 	}
21088474SJose.Borrego@Sun.COM 
210910122SJordan.Brown@Sun.COM 	if (se.se_nlimit == 0) {
21108474SJose.Borrego@Sun.COM 		param->status = ERROR_SUCCESS;
21118474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
21128474SJose.Borrego@Sun.COM 	}
21138474SJose.Borrego@Sun.COM 
21148474SJose.Borrego@Sun.COM 	if (param->resume_handle &&
21158474SJose.Borrego@Sun.COM 	    param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) {
211610122SJordan.Brown@Sun.COM 		if (se.se_resume < se.se_ntotal) {
211710122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
21188474SJose.Borrego@Sun.COM 			status = ERROR_MORE_DATA;
21198474SJose.Borrego@Sun.COM 		}
21208474SJose.Borrego@Sun.COM 	}
21218474SJose.Borrego@Sun.COM 
212210122SJordan.Brown@Sun.COM 	param->totalentries = se.se_ntotal;
21238474SJose.Borrego@Sun.COM 	param->status = status;
21248474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
21258474SJose.Borrego@Sun.COM }
21268474SJose.Borrego@Sun.COM 
21278474SJose.Borrego@Sun.COM /*
21288474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareEnumSticky
21298474SJose.Borrego@Sun.COM  *
21308474SJose.Borrego@Sun.COM  * Enumerate sticky shares: all shares except those marked STYPE_SPECIAL.
21318474SJose.Borrego@Sun.COM  * Except for excluding STYPE_SPECIAL shares, NetShareEnumSticky is the
21328474SJose.Borrego@Sun.COM  * same as NetShareEnum.
21338474SJose.Borrego@Sun.COM  *
21348474SJose.Borrego@Sun.COM  * Request for various levels of information about our shares.
21358474SJose.Borrego@Sun.COM  * Level 0: share names.
21368474SJose.Borrego@Sun.COM  * Level 1: share name, share type and comment field.
21378474SJose.Borrego@Sun.COM  * Level 2: everything that we know about the shares.
21388474SJose.Borrego@Sun.COM  * Level 501: not valid for this request.
21398474SJose.Borrego@Sun.COM  * Level 502: level 2 + security descriptor.
21408474SJose.Borrego@Sun.COM  *
21418474SJose.Borrego@Sun.COM  * We set n_skip to resume_handle, which is used to find the appropriate
21428474SJose.Borrego@Sun.COM  * place to resume.  The resume_handle is similar to the readdir cookie.
21438474SJose.Borrego@Sun.COM  */
21448474SJose.Borrego@Sun.COM static int
21458474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnumSticky(void *arg, ndr_xa_t *mxa)
21468474SJose.Borrego@Sun.COM {
21478474SJose.Borrego@Sun.COM 	struct mslm_NetShareEnum *param = arg;
214810122SJordan.Brown@Sun.COM 	srvsvc_infonres_t *infonres;
214910122SJordan.Brown@Sun.COM 	smb_svcenum_t se;
21508474SJose.Borrego@Sun.COM 	DWORD status;
21518474SJose.Borrego@Sun.COM 
215210122SJordan.Brown@Sun.COM 	infonres = NDR_NEW(mxa, srvsvc_infonres_t);
21538474SJose.Borrego@Sun.COM 	if (infonres == NULL) {
21548474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareEnum));
21558474SJose.Borrego@Sun.COM 		param->status = ERROR_NOT_ENOUGH_MEMORY;
21568474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
21578474SJose.Borrego@Sun.COM 	}
21588474SJose.Borrego@Sun.COM 
21598474SJose.Borrego@Sun.COM 	infonres->entriesread = 0;
21608474SJose.Borrego@Sun.COM 	infonres->entries = NULL;
21618474SJose.Borrego@Sun.COM 	param->result.level = param->level;
21628474SJose.Borrego@Sun.COM 	param->result.bufptr.p = infonres;
21638474SJose.Borrego@Sun.COM 
216410122SJordan.Brown@Sun.COM 	bzero(&se, sizeof (smb_svcenum_t));
216510122SJordan.Brown@Sun.COM 	se.se_type = SMB_SVCENUM_TYPE_SHARE;
21668474SJose.Borrego@Sun.COM 	se.se_level = param->level;
216710122SJordan.Brown@Sun.COM 	se.se_ntotal = smb_shr_count();
216810122SJordan.Brown@Sun.COM 	se.se_nlimit = se.se_ntotal;
21698474SJose.Borrego@Sun.COM 
21708474SJose.Borrego@Sun.COM 	if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN ||
21718474SJose.Borrego@Sun.COM 	    param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN)
21728474SJose.Borrego@Sun.COM 		se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN;
21738474SJose.Borrego@Sun.COM 	else
21748474SJose.Borrego@Sun.COM 		se.se_prefmaxlen = param->prefmaxlen;
21758474SJose.Borrego@Sun.COM 
21768474SJose.Borrego@Sun.COM 	if (param->resume_handle) {
217710122SJordan.Brown@Sun.COM 		se.se_resume = *param->resume_handle;
217810122SJordan.Brown@Sun.COM 		se.se_nskip = se.se_resume;
217910122SJordan.Brown@Sun.COM 		*param->resume_handle = 0;
21808474SJose.Borrego@Sun.COM 	}
21818474SJose.Borrego@Sun.COM 
21828474SJose.Borrego@Sun.COM 	switch (param->level) {
21838474SJose.Borrego@Sun.COM 	case 0:
21848474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 1);
21858474SJose.Borrego@Sun.COM 		break;
21868474SJose.Borrego@Sun.COM 
21878474SJose.Borrego@Sun.COM 	case 1:
21888474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 1);
21898474SJose.Borrego@Sun.COM 		break;
21908474SJose.Borrego@Sun.COM 
21918474SJose.Borrego@Sun.COM 	case 2:
21928474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 1);
21938474SJose.Borrego@Sun.COM 		break;
21948474SJose.Borrego@Sun.COM 
21958474SJose.Borrego@Sun.COM 	case 502:
21968474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 1);
21978474SJose.Borrego@Sun.COM 		break;
21988474SJose.Borrego@Sun.COM 
21999832Samw@Sun.COM 	case 501:
22008474SJose.Borrego@Sun.COM 	default:
22018474SJose.Borrego@Sun.COM 		status = ERROR_INVALID_LEVEL;
22028474SJose.Borrego@Sun.COM 		break;
22038474SJose.Borrego@Sun.COM 	}
22048474SJose.Borrego@Sun.COM 
22058474SJose.Borrego@Sun.COM 	if (status != ERROR_SUCCESS) {
22068474SJose.Borrego@Sun.COM 		bzero(param, sizeof (struct mslm_NetShareEnum));
22078474SJose.Borrego@Sun.COM 		param->status = status;
22088474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
22098474SJose.Borrego@Sun.COM 	}
22108474SJose.Borrego@Sun.COM 
221110122SJordan.Brown@Sun.COM 	if (se.se_nlimit == 0) {
22128474SJose.Borrego@Sun.COM 		param->status = ERROR_SUCCESS;
22138474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
22148474SJose.Borrego@Sun.COM 	}
22158474SJose.Borrego@Sun.COM 
22168474SJose.Borrego@Sun.COM 	if (param->resume_handle &&
22178474SJose.Borrego@Sun.COM 	    param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) {
221810122SJordan.Brown@Sun.COM 		if (se.se_resume < se.se_ntotal) {
221910122SJordan.Brown@Sun.COM 			*param->resume_handle = se.se_resume;
22208474SJose.Borrego@Sun.COM 			status = ERROR_MORE_DATA;
22218474SJose.Borrego@Sun.COM 		}
22228474SJose.Borrego@Sun.COM 	}
22238474SJose.Borrego@Sun.COM 
222410122SJordan.Brown@Sun.COM 	param->totalentries = se.se_ntotal;
22258474SJose.Borrego@Sun.COM 	param->status = status;
22268474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
22278474SJose.Borrego@Sun.COM }
22288474SJose.Borrego@Sun.COM 
22298474SJose.Borrego@Sun.COM /*
22308474SJose.Borrego@Sun.COM  * NetShareEnum Level 0
22318474SJose.Borrego@Sun.COM  */
22328474SJose.Borrego@Sun.COM static DWORD
223310122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel0(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
223410122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
22358474SJose.Borrego@Sun.COM {
22369343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_0 *info0;
22378474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
22388474SJose.Borrego@Sun.COM 	smb_share_t *si;
22398474SJose.Borrego@Sun.COM 	DWORD status;
22408474SJose.Borrego@Sun.COM 
224110122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
224210122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_0) + MAXNAMELEN);
224310122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
22448474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
22458474SJose.Borrego@Sun.COM 
224610122SJordan.Brown@Sun.COM 	info0 = NDR_NEWN(mxa, struct mslm_NetShareInfo_0, se->se_nlimit);
22478474SJose.Borrego@Sun.COM 	if (info0 == NULL)
22488474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
22498474SJose.Borrego@Sun.COM 
22508474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
22518474SJose.Borrego@Sun.COM 
225210122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
22538474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
225410122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
225510122SJordan.Brown@Sun.COM 			--se->se_nskip;
22568474SJose.Borrego@Sun.COM 			continue;
22578474SJose.Borrego@Sun.COM 		}
22588474SJose.Borrego@Sun.COM 
225910122SJordan.Brown@Sun.COM 		++se->se_resume;
22608474SJose.Borrego@Sun.COM 
22618474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
22628474SJose.Borrego@Sun.COM 			continue;
22638474SJose.Borrego@Sun.COM 
22648474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
22658474SJose.Borrego@Sun.COM 			continue;
22668474SJose.Borrego@Sun.COM 
226710122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
226810122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
22698474SJose.Borrego@Sun.COM 			break;
22708474SJose.Borrego@Sun.COM 		}
22718474SJose.Borrego@Sun.COM 
22728474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info0);
22738474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
22748474SJose.Borrego@Sun.COM 			break;
22758474SJose.Borrego@Sun.COM 
227610122SJordan.Brown@Sun.COM 		++se->se_nitems;
22778474SJose.Borrego@Sun.COM 	}
22788474SJose.Borrego@Sun.COM 
227910122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
22808474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info0))
228110122SJordan.Brown@Sun.COM 			++se->se_nitems;
22828474SJose.Borrego@Sun.COM 	}
22838474SJose.Borrego@Sun.COM 
228410122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
22858474SJose.Borrego@Sun.COM 	infonres->entries = info0;
22868474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
22878474SJose.Borrego@Sun.COM }
22888474SJose.Borrego@Sun.COM 
22898474SJose.Borrego@Sun.COM /*
22908474SJose.Borrego@Sun.COM  * NetShareEnum Level 1
22918474SJose.Borrego@Sun.COM  */
22928474SJose.Borrego@Sun.COM static DWORD
229310122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel1(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
229410122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
22958474SJose.Borrego@Sun.COM {
22969343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1 *info1;
22978474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
22988474SJose.Borrego@Sun.COM 	smb_share_t *si;
22998474SJose.Borrego@Sun.COM 	DWORD status;
23008474SJose.Borrego@Sun.COM 
230110122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
230210122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_1) + MAXNAMELEN);
230310122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
23048474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
23058474SJose.Borrego@Sun.COM 
230610122SJordan.Brown@Sun.COM 	info1 = NDR_NEWN(mxa, struct mslm_NetShareInfo_1, se->se_nlimit);
23078474SJose.Borrego@Sun.COM 	if (info1 == NULL)
23088474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
23098474SJose.Borrego@Sun.COM 
23108474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
23118474SJose.Borrego@Sun.COM 
231210122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
23138474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != 0) {
231410122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
231510122SJordan.Brown@Sun.COM 			--se->se_nskip;
23168474SJose.Borrego@Sun.COM 			continue;
23178474SJose.Borrego@Sun.COM 		}
23188474SJose.Borrego@Sun.COM 
231910122SJordan.Brown@Sun.COM 		++se->se_resume;
23208474SJose.Borrego@Sun.COM 
23218474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
23228474SJose.Borrego@Sun.COM 			continue;
23238474SJose.Borrego@Sun.COM 
23248474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
23258474SJose.Borrego@Sun.COM 			continue;
23268474SJose.Borrego@Sun.COM 
232710122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
232810122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
23298474SJose.Borrego@Sun.COM 			break;
23308474SJose.Borrego@Sun.COM 		}
23318474SJose.Borrego@Sun.COM 
23328474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info1);
23338474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
23348474SJose.Borrego@Sun.COM 			break;
23358474SJose.Borrego@Sun.COM 
233610122SJordan.Brown@Sun.COM 		++se->se_nitems;
23378474SJose.Borrego@Sun.COM 	}
23388474SJose.Borrego@Sun.COM 
233910122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
23408474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info1))
234110122SJordan.Brown@Sun.COM 			++se->se_nitems;
23428474SJose.Borrego@Sun.COM 	}
23438474SJose.Borrego@Sun.COM 
234410122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
23458474SJose.Borrego@Sun.COM 	infonres->entries = info1;
23468474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
23478474SJose.Borrego@Sun.COM }
23488474SJose.Borrego@Sun.COM 
23498474SJose.Borrego@Sun.COM /*
23508474SJose.Borrego@Sun.COM  * NetShareEnum Level 2
23518474SJose.Borrego@Sun.COM  */
23528474SJose.Borrego@Sun.COM static DWORD
235310122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel2(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
235410122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
23558474SJose.Borrego@Sun.COM {
23569343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
23578474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
23588474SJose.Borrego@Sun.COM 	smb_share_t *si;
23598474SJose.Borrego@Sun.COM 	DWORD status;
23608474SJose.Borrego@Sun.COM 
236110122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
236210122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_2) + MAXNAMELEN);
236310122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
23648474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
23658474SJose.Borrego@Sun.COM 
236610122SJordan.Brown@Sun.COM 	info2 = NDR_NEWN(mxa, struct mslm_NetShareInfo_2, se->se_nlimit);
23678474SJose.Borrego@Sun.COM 	if (info2 == NULL)
23688474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
23698474SJose.Borrego@Sun.COM 
23708474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
23718474SJose.Borrego@Sun.COM 
237210122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
23738474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != 0) {
237410122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
237510122SJordan.Brown@Sun.COM 			--se->se_nskip;
23768474SJose.Borrego@Sun.COM 			continue;
23778474SJose.Borrego@Sun.COM 		}
23788474SJose.Borrego@Sun.COM 
237910122SJordan.Brown@Sun.COM 		++se->se_resume;
23808474SJose.Borrego@Sun.COM 
23818474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
23828474SJose.Borrego@Sun.COM 			continue;
23838474SJose.Borrego@Sun.COM 
23848474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
23858474SJose.Borrego@Sun.COM 			continue;
23868474SJose.Borrego@Sun.COM 
238710122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
238810122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
23898474SJose.Borrego@Sun.COM 			break;
23908474SJose.Borrego@Sun.COM 		}
23918474SJose.Borrego@Sun.COM 
23928474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info2);
23938474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
23948474SJose.Borrego@Sun.COM 			break;
23958474SJose.Borrego@Sun.COM 
239610122SJordan.Brown@Sun.COM 		++se->se_nitems;
23978474SJose.Borrego@Sun.COM 	}
23988474SJose.Borrego@Sun.COM 
239910122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
24008474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info2))
240110122SJordan.Brown@Sun.COM 			++se->se_nitems;
24028474SJose.Borrego@Sun.COM 	}
24038474SJose.Borrego@Sun.COM 
240410122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
24058474SJose.Borrego@Sun.COM 	infonres->entries = info2;
24068474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
24078474SJose.Borrego@Sun.COM }
24088474SJose.Borrego@Sun.COM 
24098474SJose.Borrego@Sun.COM /*
24108474SJose.Borrego@Sun.COM  * NetShareEnum Level 501
24118474SJose.Borrego@Sun.COM  */
24128474SJose.Borrego@Sun.COM static DWORD
241310122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel501(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
241410122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
24158474SJose.Borrego@Sun.COM {
24169343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_501 *info501;
24178474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
24188474SJose.Borrego@Sun.COM 	smb_share_t *si;
24198474SJose.Borrego@Sun.COM 	DWORD status;
24208474SJose.Borrego@Sun.COM 
242110122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
242210122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_501) + MAXNAMELEN);
242310122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
24248474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
24258474SJose.Borrego@Sun.COM 
24269343SAfshin.Ardakani@Sun.COM 	info501 = NDR_NEWN(mxa, struct mslm_NetShareInfo_501,
242710122SJordan.Brown@Sun.COM 	    se->se_nlimit);
24288474SJose.Borrego@Sun.COM 	if (info501 == NULL)
24298474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
24308474SJose.Borrego@Sun.COM 
24318474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
24328474SJose.Borrego@Sun.COM 
243310122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
24348474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != 0) {
243510122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
243610122SJordan.Brown@Sun.COM 			--se->se_nskip;
24378474SJose.Borrego@Sun.COM 			continue;
24388474SJose.Borrego@Sun.COM 		}
24398474SJose.Borrego@Sun.COM 
244010122SJordan.Brown@Sun.COM 		++se->se_resume;
24418474SJose.Borrego@Sun.COM 
24428474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
24438474SJose.Borrego@Sun.COM 			continue;
24448474SJose.Borrego@Sun.COM 
24458474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
24468474SJose.Borrego@Sun.COM 			continue;
24478474SJose.Borrego@Sun.COM 
244810122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
244910122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
24508474SJose.Borrego@Sun.COM 			break;
24518474SJose.Borrego@Sun.COM 		}
24528474SJose.Borrego@Sun.COM 
24538474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info501);
24548474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
24558474SJose.Borrego@Sun.COM 			break;
24568474SJose.Borrego@Sun.COM 
245710122SJordan.Brown@Sun.COM 		++se->se_nitems;
24588474SJose.Borrego@Sun.COM 	}
24598474SJose.Borrego@Sun.COM 
246010122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
24618474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info501))
246210122SJordan.Brown@Sun.COM 			++se->se_nitems;
24638474SJose.Borrego@Sun.COM 	}
24648474SJose.Borrego@Sun.COM 
246510122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
24668474SJose.Borrego@Sun.COM 	infonres->entries = info501;
24678474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
24688474SJose.Borrego@Sun.COM }
24698474SJose.Borrego@Sun.COM 
24708474SJose.Borrego@Sun.COM /*
24718474SJose.Borrego@Sun.COM  * NetShareEnum Level 502
24728474SJose.Borrego@Sun.COM  */
24738474SJose.Borrego@Sun.COM static DWORD
247410122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel502(ndr_xa_t *mxa, srvsvc_infonres_t *infonres,
247510122SJordan.Brown@Sun.COM     smb_svcenum_t *se, int sticky)
24768474SJose.Borrego@Sun.COM {
24779343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
24788474SJose.Borrego@Sun.COM 	smb_shriter_t iterator;
24798474SJose.Borrego@Sun.COM 	smb_share_t *si;
24808474SJose.Borrego@Sun.COM 	DWORD status;
24818474SJose.Borrego@Sun.COM 
248210122SJordan.Brown@Sun.COM 	srvsvc_estimate_limit(se,
248310122SJordan.Brown@Sun.COM 	    sizeof (struct mslm_NetShareInfo_502) + MAXNAMELEN);
248410122SJordan.Brown@Sun.COM 	if (se->se_nlimit == 0)
24858474SJose.Borrego@Sun.COM 		return (ERROR_SUCCESS);
24868474SJose.Borrego@Sun.COM 
24879343SAfshin.Ardakani@Sun.COM 	info502 = NDR_NEWN(mxa, struct mslm_NetShareInfo_502,
248810122SJordan.Brown@Sun.COM 	    se->se_nlimit);
24898474SJose.Borrego@Sun.COM 	if (info502 == NULL)
24908474SJose.Borrego@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
24918474SJose.Borrego@Sun.COM 
24928474SJose.Borrego@Sun.COM 	smb_shr_iterinit(&iterator);
24938474SJose.Borrego@Sun.COM 
249410122SJordan.Brown@Sun.COM 	se->se_nitems = 0;
24958474SJose.Borrego@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
249610122SJordan.Brown@Sun.COM 		if (se->se_nskip > 0) {
249710122SJordan.Brown@Sun.COM 			--se->se_nskip;
24988474SJose.Borrego@Sun.COM 			continue;
24998474SJose.Borrego@Sun.COM 		}
25008474SJose.Borrego@Sun.COM 
250110122SJordan.Brown@Sun.COM 		++se->se_resume;
25028474SJose.Borrego@Sun.COM 
25038474SJose.Borrego@Sun.COM 		if (sticky && (si->shr_flags & SMB_SHRF_TRANS))
25048474SJose.Borrego@Sun.COM 			continue;
25058474SJose.Borrego@Sun.COM 
25068474SJose.Borrego@Sun.COM 		if (si->shr_flags & SMB_SHRF_AUTOHOME)
25078474SJose.Borrego@Sun.COM 			continue;
25088474SJose.Borrego@Sun.COM 
250910122SJordan.Brown@Sun.COM 		if (se->se_nitems >= se->se_nlimit) {
251010122SJordan.Brown@Sun.COM 			se->se_nitems = se->se_nlimit;
25118474SJose.Borrego@Sun.COM 			break;
25128474SJose.Borrego@Sun.COM 		}
25138474SJose.Borrego@Sun.COM 
25148474SJose.Borrego@Sun.COM 		status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info502);
25158474SJose.Borrego@Sun.COM 		if (status != ERROR_SUCCESS)
25168474SJose.Borrego@Sun.COM 			break;
25178474SJose.Borrego@Sun.COM 
251810122SJordan.Brown@Sun.COM 		++se->se_nitems;
25198474SJose.Borrego@Sun.COM 	}
25208474SJose.Borrego@Sun.COM 
252110122SJordan.Brown@Sun.COM 	if (se->se_nitems < se->se_nlimit) {
25228474SJose.Borrego@Sun.COM 		if (srvsvc_add_autohome(mxa, se, (void *)info502))
252310122SJordan.Brown@Sun.COM 			++se->se_nitems;
25248474SJose.Borrego@Sun.COM 	}
25258474SJose.Borrego@Sun.COM 
252610122SJordan.Brown@Sun.COM 	infonres->entriesread = se->se_nitems;
25278474SJose.Borrego@Sun.COM 	infonres->entries = info502;
25288474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
25298474SJose.Borrego@Sun.COM }
25308474SJose.Borrego@Sun.COM 
25318474SJose.Borrego@Sun.COM /*
25328474SJose.Borrego@Sun.COM  * mlsvc_NetShareEnumCommon
25338474SJose.Borrego@Sun.COM  *
25348474SJose.Borrego@Sun.COM  * Build the levels 0, 1, 2, 501 and 502 share information. This function
25358474SJose.Borrego@Sun.COM  * is called by the various NetShareEnum levels for each share. If
25368474SJose.Borrego@Sun.COM  * we cannot build the share data for some reason, we return an error
25378474SJose.Borrego@Sun.COM  * but the actual value of the error is not important to the caller.
25388474SJose.Borrego@Sun.COM  * The caller just needs to know not to include this info in the RPC
25398474SJose.Borrego@Sun.COM  * response.
25408474SJose.Borrego@Sun.COM  *
25418474SJose.Borrego@Sun.COM  * Returns:
25428474SJose.Borrego@Sun.COM  *	ERROR_SUCCESS
25438474SJose.Borrego@Sun.COM  *	ERROR_NOT_ENOUGH_MEMORY
25448474SJose.Borrego@Sun.COM  *	ERROR_INVALID_LEVEL
25458474SJose.Borrego@Sun.COM  */
25468474SJose.Borrego@Sun.COM static DWORD
254710122SJordan.Brown@Sun.COM mlsvc_NetShareEnumCommon(ndr_xa_t *mxa, smb_svcenum_t *se,
25488474SJose.Borrego@Sun.COM     smb_share_t *si, void *infop)
25498474SJose.Borrego@Sun.COM {
25509343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_0 *info0;
25519343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_1 *info1;
25529343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_2 *info2;
25539343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_501 *info501;
25549343SAfshin.Ardakani@Sun.COM 	struct mslm_NetShareInfo_502 *info502;
25559832Samw@Sun.COM 	srvsvc_sd_t sd;
25569832Samw@Sun.COM 	uint8_t *netname;
25579832Samw@Sun.COM 	uint8_t *comment;
25589832Samw@Sun.COM 	uint8_t *passwd;
25599832Samw@Sun.COM 	uint8_t *path;
256010122SJordan.Brown@Sun.COM 	int i = se->se_nitems;
25618474SJose.Borrego@Sun.COM 
25629832Samw@Sun.COM 	netname = (uint8_t *)NDR_STRDUP(mxa, si->shr_name);
25639832Samw@Sun.COM 	comment = (uint8_t *)NDR_STRDUP(mxa, si->shr_cmnt);
25649832Samw@Sun.COM 	passwd = (uint8_t *)NDR_STRDUP(mxa, empty_string);
25659832Samw@Sun.COM 	path = (uint8_t *)srvsvc_share_mkpath(mxa, si->shr_path);
25669832Samw@Sun.COM 
25679832Samw@Sun.COM 	if (!netname || !comment || !passwd || !path)
25689832Samw@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
25699832Samw@Sun.COM 
25708474SJose.Borrego@Sun.COM 	switch (se->se_level) {
25718474SJose.Borrego@Sun.COM 	case 0:
25729343SAfshin.Ardakani@Sun.COM 		info0 = (struct mslm_NetShareInfo_0 *)infop;
25739832Samw@Sun.COM 		info0[i].shi0_netname = netname;
25748474SJose.Borrego@Sun.COM 		break;
25758474SJose.Borrego@Sun.COM 
25768474SJose.Borrego@Sun.COM 	case 1:
25779343SAfshin.Ardakani@Sun.COM 		info1 = (struct mslm_NetShareInfo_1 *)infop;
25789832Samw@Sun.COM 		info1[i].shi1_netname = netname;
25799832Samw@Sun.COM 		info1[i].shi1_comment = comment;
25808474SJose.Borrego@Sun.COM 		info1[i].shi1_type = si->shr_type;
25818474SJose.Borrego@Sun.COM 		break;
25828474SJose.Borrego@Sun.COM 
25838474SJose.Borrego@Sun.COM 	case 2:
25849343SAfshin.Ardakani@Sun.COM 		info2 = (struct mslm_NetShareInfo_2 *)infop;
25859832Samw@Sun.COM 		info2[i].shi2_netname = netname;
25869832Samw@Sun.COM 		info2[i].shi2_comment = comment;
25879832Samw@Sun.COM 		info2[i].shi2_path = path;
25888474SJose.Borrego@Sun.COM 		info2[i].shi2_type = si->shr_type;
25898474SJose.Borrego@Sun.COM 		info2[i].shi2_permissions = 0;
25908474SJose.Borrego@Sun.COM 		info2[i].shi2_max_uses = SHI_USES_UNLIMITED;
25918474SJose.Borrego@Sun.COM 		info2[i].shi2_current_uses = 0;
25929832Samw@Sun.COM 		info2[i].shi2_passwd = passwd;
25938474SJose.Borrego@Sun.COM 		break;
25948474SJose.Borrego@Sun.COM 
25958474SJose.Borrego@Sun.COM 	case 501:
25969343SAfshin.Ardakani@Sun.COM 		info501 = (struct mslm_NetShareInfo_501 *)infop;
25979832Samw@Sun.COM 		info501[i].shi501_netname = netname;
25989832Samw@Sun.COM 		info501[i].shi501_comment = comment;
25998474SJose.Borrego@Sun.COM 		info501[i].shi501_type = si->shr_type;
260010504SKeyur.Desai@Sun.COM 		info501[i].shi501_flags = srvsvc_get_share_flags(si);
26018474SJose.Borrego@Sun.COM 		break;
26028474SJose.Borrego@Sun.COM 
26038474SJose.Borrego@Sun.COM 	case 502:
26049343SAfshin.Ardakani@Sun.COM 		info502 = (struct mslm_NetShareInfo_502 *)infop;
26059832Samw@Sun.COM 		info502[i].shi502_netname = netname;
26069832Samw@Sun.COM 		info502[i].shi502_comment = comment;
26079832Samw@Sun.COM 		info502[i].shi502_path = path;
26088474SJose.Borrego@Sun.COM 		info502[i].shi502_type = si->shr_type;
26098474SJose.Borrego@Sun.COM 		info502[i].shi502_permissions = 0;
26108474SJose.Borrego@Sun.COM 		info502[i].shi502_max_uses = SHI_USES_UNLIMITED;
26118474SJose.Borrego@Sun.COM 		info502[i].shi502_current_uses = 0;
26129832Samw@Sun.COM 		info502[i].shi502_passwd = passwd;
26139832Samw@Sun.COM 
26149832Samw@Sun.COM 		if (srvsvc_share_getsd(mxa, si, &sd) == ERROR_SUCCESS) {
26159832Samw@Sun.COM 			info502[i].shi502_reserved = sd.sd_size;
26169832Samw@Sun.COM 			info502[i].shi502_security_descriptor = sd.sd_buf;
26179832Samw@Sun.COM 		} else {
26189832Samw@Sun.COM 			info502[i].shi502_reserved = 0;
26199832Samw@Sun.COM 			info502[i].shi502_security_descriptor = NULL;
26209832Samw@Sun.COM 		}
26219832Samw@Sun.COM 
26228474SJose.Borrego@Sun.COM 		break;
26238474SJose.Borrego@Sun.COM 
26248474SJose.Borrego@Sun.COM 	default:
26258474SJose.Borrego@Sun.COM 		return (ERROR_INVALID_LEVEL);
26268474SJose.Borrego@Sun.COM 	}
26278474SJose.Borrego@Sun.COM 
26288474SJose.Borrego@Sun.COM 	return (ERROR_SUCCESS);
26298474SJose.Borrego@Sun.COM }
26308474SJose.Borrego@Sun.COM 
26318474SJose.Borrego@Sun.COM /*
26328474SJose.Borrego@Sun.COM  * srvsvc_add_autohome
26338474SJose.Borrego@Sun.COM  *
26348474SJose.Borrego@Sun.COM  * Add the autohome share for the user. The share must not be a permanent
26358474SJose.Borrego@Sun.COM  * share to avoid duplicates.
26368474SJose.Borrego@Sun.COM  */
26378474SJose.Borrego@Sun.COM static boolean_t
263810122SJordan.Brown@Sun.COM srvsvc_add_autohome(ndr_xa_t *mxa, smb_svcenum_t *se, void *infop)
26398474SJose.Borrego@Sun.COM {
264010122SJordan.Brown@Sun.COM 	smb_netuserinfo_t *user = &mxa->pipe->np_user;
264110122SJordan.Brown@Sun.COM 	char *username = user->ui_account;
26428474SJose.Borrego@Sun.COM 	smb_share_t si;
26438474SJose.Borrego@Sun.COM 	DWORD status;
26448474SJose.Borrego@Sun.COM 
26458474SJose.Borrego@Sun.COM 	if (smb_shr_get(username, &si) != NERR_Success)
26468474SJose.Borrego@Sun.COM 		return (B_FALSE);
26478474SJose.Borrego@Sun.COM 
26488474SJose.Borrego@Sun.COM 	if ((si.shr_flags & SMB_SHRF_AUTOHOME) == 0)
26498474SJose.Borrego@Sun.COM 		return (B_FALSE);
26508474SJose.Borrego@Sun.COM 
26518474SJose.Borrego@Sun.COM 	status = mlsvc_NetShareEnumCommon(mxa, se, &si, infop);
26528474SJose.Borrego@Sun.COM 	return (status == ERROR_SUCCESS);
26538474SJose.Borrego@Sun.COM }
26548474SJose.Borrego@Sun.COM 
26558474SJose.Borrego@Sun.COM /*
26568474SJose.Borrego@Sun.COM  * srvsvc_share_mkpath
26578474SJose.Borrego@Sun.COM  *
26588474SJose.Borrego@Sun.COM  * Create the share path required by the share enum calls. The path
26598474SJose.Borrego@Sun.COM  * is created in a heap buffer ready for use by the caller.
26608474SJose.Borrego@Sun.COM  *
26618474SJose.Borrego@Sun.COM  * Some Windows over-the-wire backup applications do not work unless a
26628474SJose.Borrego@Sun.COM  * drive letter is present in the share path.  We don't care about the
26638474SJose.Borrego@Sun.COM  * drive letter since the path is fully qualified with the volume name.
26648474SJose.Borrego@Sun.COM  *
26658474SJose.Borrego@Sun.COM  * Windows clients seem to be mostly okay with forward slashes in
26668474SJose.Borrego@Sun.COM  * share paths but they cannot handle one immediately after the drive
26678474SJose.Borrego@Sun.COM  * letter, i.e. B:/.  For consistency we convert all the slashes in
26688474SJose.Borrego@Sun.COM  * the path.
26698474SJose.Borrego@Sun.COM  *
26708474SJose.Borrego@Sun.COM  * Returns a pointer to a heap buffer containing the share path, which
26718474SJose.Borrego@Sun.COM  * could be a null pointer if the heap allocation fails.
26728474SJose.Borrego@Sun.COM  */
26738474SJose.Borrego@Sun.COM static char *
26748474SJose.Borrego@Sun.COM srvsvc_share_mkpath(ndr_xa_t *mxa, char *path)
26758474SJose.Borrego@Sun.COM {
26768474SJose.Borrego@Sun.COM 	char tmpbuf[MAXPATHLEN];
26778474SJose.Borrego@Sun.COM 	char *p;
26788474SJose.Borrego@Sun.COM 
26798474SJose.Borrego@Sun.COM 	if (strlen(path) == 0)
26808474SJose.Borrego@Sun.COM 		return (NDR_STRDUP(mxa, path));
26818474SJose.Borrego@Sun.COM 
26828474SJose.Borrego@Sun.COM 	/*
26838474SJose.Borrego@Sun.COM 	 * Strip the volume name from the path (/vol1/home -> /home).
26848474SJose.Borrego@Sun.COM 	 */
26858474SJose.Borrego@Sun.COM 	p = path;
26868474SJose.Borrego@Sun.COM 	p += strspn(p, "/");
26878474SJose.Borrego@Sun.COM 	p += strcspn(p, "/");
26888474SJose.Borrego@Sun.COM 	p += strspn(p, "/");
26898474SJose.Borrego@Sun.COM 	(void) snprintf(tmpbuf, MAXPATHLEN, "%c:/%s", 'B', p);
26908474SJose.Borrego@Sun.COM 	(void) strsubst(tmpbuf, '/', '\\');
26918474SJose.Borrego@Sun.COM 
26928474SJose.Borrego@Sun.COM 	return (NDR_STRDUP(mxa, tmpbuf));
26938474SJose.Borrego@Sun.COM }
26948474SJose.Borrego@Sun.COM 
26959832Samw@Sun.COM static int
26969832Samw@Sun.COM srvsvc_s_NetShareCheck(void *arg, ndr_xa_t *mxa)
26979832Samw@Sun.COM {
26989832Samw@Sun.COM 	struct mslm_NetShareCheck *param = arg;
26999832Samw@Sun.COM 	smb_shriter_t iterator;
27009832Samw@Sun.COM 	smb_share_t *si;
27019832Samw@Sun.COM 	char *path;
27029832Samw@Sun.COM 
27039832Samw@Sun.COM 	if (param->path == NULL) {
27049832Samw@Sun.COM 		param->stype = STYPE_DISKTREE;
27059832Samw@Sun.COM 		param->status = NERR_NetNameNotFound;
27069832Samw@Sun.COM 		return (NDR_DRC_OK);
27079832Samw@Sun.COM 	}
27089832Samw@Sun.COM 
27099832Samw@Sun.COM 	(void) strsubst((char *)param->path, '/', '\\');
27109832Samw@Sun.COM 
27119832Samw@Sun.COM 	smb_shr_iterinit(&iterator);
27129832Samw@Sun.COM 
27139832Samw@Sun.COM 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
27149832Samw@Sun.COM 		path = srvsvc_share_mkpath(mxa, si->shr_path);
27159832Samw@Sun.COM 
271610966SJordan.Brown@Sun.COM 		if (smb_strcasecmp(path, (char *)param->path, 0) == 0) {
27179832Samw@Sun.COM 			param->stype = (si->shr_type & STYPE_MASK);
27189832Samw@Sun.COM 			param->status = NERR_Success;
27199832Samw@Sun.COM 			return (NDR_DRC_OK);
27209832Samw@Sun.COM 		}
27219832Samw@Sun.COM 	}
27229832Samw@Sun.COM 
27239832Samw@Sun.COM 	param->stype = STYPE_DISKTREE;
27249832Samw@Sun.COM 	param->status = NERR_NetNameNotFound;
27259832Samw@Sun.COM 	return (NDR_DRC_OK);
27269832Samw@Sun.COM }
27279832Samw@Sun.COM 
27288474SJose.Borrego@Sun.COM /*
27298474SJose.Borrego@Sun.COM  * srvsvc_s_NetShareDel
27308474SJose.Borrego@Sun.COM  *
273110122SJordan.Brown@Sun.COM  * Delete a share.  Only members of the Administrators, Server Operators
273210122SJordan.Brown@Sun.COM  * or Power Users local groups are allowed to delete shares.
27338474SJose.Borrego@Sun.COM  *
27348474SJose.Borrego@Sun.COM  * This interface is used by the rmtshare command from the NT resource
27358474SJose.Borrego@Sun.COM  * kit. Rmtshare allows a client to add or remove shares on a server
27368474SJose.Borrego@Sun.COM  * from the client's command line.
27378474SJose.Borrego@Sun.COM  *
27388474SJose.Borrego@Sun.COM  * Returns Win32 error codes.
27398474SJose.Borrego@Sun.COM  */
27408474SJose.Borrego@Sun.COM static int
27418474SJose.Borrego@Sun.COM srvsvc_s_NetShareDel(void *arg, ndr_xa_t *mxa)
27428474SJose.Borrego@Sun.COM {
27438474SJose.Borrego@Sun.COM 	struct mslm_NetShareDel *param = arg;
27448474SJose.Borrego@Sun.COM 
27458474SJose.Borrego@Sun.COM 	if (!ndr_is_poweruser(mxa) ||
27468474SJose.Borrego@Sun.COM 	    smb_shr_is_restricted((char *)param->netname)) {
27478474SJose.Borrego@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
27488474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
27498474SJose.Borrego@Sun.COM 	}
27508474SJose.Borrego@Sun.COM 
27518474SJose.Borrego@Sun.COM 	param->status = srvsvc_sa_delete((char *)param->netname);
27528474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
27538474SJose.Borrego@Sun.COM }
27548474SJose.Borrego@Sun.COM 
27558474SJose.Borrego@Sun.COM /*
27568474SJose.Borrego@Sun.COM  * srvsvc_s_NetGetFileSecurity
27578474SJose.Borrego@Sun.COM  *
27588474SJose.Borrego@Sun.COM  * Get security descriptor of the requested file/folder
27598474SJose.Borrego@Sun.COM  *
27608474SJose.Borrego@Sun.COM  * Right now, just returns ERROR_ACCESS_DENIED, because we cannot
27618474SJose.Borrego@Sun.COM  * get the requested SD here in RPC code.
27628474SJose.Borrego@Sun.COM  */
27638474SJose.Borrego@Sun.COM /*ARGSUSED*/
27648474SJose.Borrego@Sun.COM static int
27658474SJose.Borrego@Sun.COM srvsvc_s_NetGetFileSecurity(void *arg, ndr_xa_t *mxa)
27668474SJose.Borrego@Sun.COM {
27678474SJose.Borrego@Sun.COM 	struct mslm_NetGetFileSecurity *param = arg;
27688474SJose.Borrego@Sun.COM 
27698474SJose.Borrego@Sun.COM 	param->length = 0;
27708474SJose.Borrego@Sun.COM 	param->status = ERROR_ACCESS_DENIED;
27718474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
27728474SJose.Borrego@Sun.COM }
27738474SJose.Borrego@Sun.COM 
27748474SJose.Borrego@Sun.COM /*
27758474SJose.Borrego@Sun.COM  * srvsvc_s_NetSetFileSecurity
27768474SJose.Borrego@Sun.COM  *
27778474SJose.Borrego@Sun.COM  * Set the given security descriptor for the requested file/folder
27788474SJose.Borrego@Sun.COM  *
27798474SJose.Borrego@Sun.COM  * Right now, just returns ERROR_ACCESS_DENIED, because we cannot
27808474SJose.Borrego@Sun.COM  * set the requested SD here in RPC code.
27818474SJose.Borrego@Sun.COM  */
27828474SJose.Borrego@Sun.COM /*ARGSUSED*/
27838474SJose.Borrego@Sun.COM static int
27848474SJose.Borrego@Sun.COM srvsvc_s_NetSetFileSecurity(void *arg, ndr_xa_t *mxa)
27858474SJose.Borrego@Sun.COM {
27868474SJose.Borrego@Sun.COM 	struct mslm_NetSetFileSecurity *param = arg;
27878474SJose.Borrego@Sun.COM 
27888474SJose.Borrego@Sun.COM 	param->status = ERROR_ACCESS_DENIED;
27898474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
27908474SJose.Borrego@Sun.COM }
27918474SJose.Borrego@Sun.COM 
27928474SJose.Borrego@Sun.COM /*
27938474SJose.Borrego@Sun.COM  * If the default "smb" share group exists then return the group
27948474SJose.Borrego@Sun.COM  * handle, otherwise create the group and return the handle.
27958474SJose.Borrego@Sun.COM  *
27968474SJose.Borrego@Sun.COM  * All shares created via the srvsvc will be added to the "smb"
27978474SJose.Borrego@Sun.COM  * group.
27988474SJose.Borrego@Sun.COM  */
27998474SJose.Borrego@Sun.COM static sa_group_t
28008474SJose.Borrego@Sun.COM srvsvc_sa_get_smbgrp(sa_handle_t handle)
28018474SJose.Borrego@Sun.COM {
28028474SJose.Borrego@Sun.COM 	sa_group_t group = NULL;
28038474SJose.Borrego@Sun.COM 	int err;
28048474SJose.Borrego@Sun.COM 
28058474SJose.Borrego@Sun.COM 	group = sa_get_group(handle, SMB_DEFAULT_SHARE_GROUP);
28068474SJose.Borrego@Sun.COM 	if (group != NULL)
28078474SJose.Borrego@Sun.COM 		return (group);
28088474SJose.Borrego@Sun.COM 
28098474SJose.Borrego@Sun.COM 	group = sa_create_group(handle, SMB_DEFAULT_SHARE_GROUP, &err);
28108474SJose.Borrego@Sun.COM 	if (group == NULL)
28118474SJose.Borrego@Sun.COM 		return (NULL);
28128474SJose.Borrego@Sun.COM 
28138474SJose.Borrego@Sun.COM 	if (sa_create_optionset(group, SMB_DEFAULT_SHARE_GROUP) == NULL) {
28148474SJose.Borrego@Sun.COM 		(void) sa_remove_group(group);
28158474SJose.Borrego@Sun.COM 		group = NULL;
28168474SJose.Borrego@Sun.COM 	}
28178474SJose.Borrego@Sun.COM 
28188474SJose.Borrego@Sun.COM 	return (group);
28198474SJose.Borrego@Sun.COM }
28208474SJose.Borrego@Sun.COM 
28218474SJose.Borrego@Sun.COM /*
28228474SJose.Borrego@Sun.COM  * Stores the given share in sharemgr
28238474SJose.Borrego@Sun.COM  */
28248474SJose.Borrego@Sun.COM static uint32_t
28258474SJose.Borrego@Sun.COM srvsvc_sa_add(char *sharename, char *path, char *cmnt)
28268474SJose.Borrego@Sun.COM {
28278474SJose.Borrego@Sun.COM 	sa_handle_t handle;
28288474SJose.Borrego@Sun.COM 	sa_share_t share;
28298474SJose.Borrego@Sun.COM 	sa_group_t group;
28308474SJose.Borrego@Sun.COM 	sa_resource_t resource;
28318474SJose.Borrego@Sun.COM 	boolean_t new_share = B_FALSE;
28328474SJose.Borrego@Sun.COM 	uint32_t status = NERR_Success;
28338474SJose.Borrego@Sun.COM 	int err;
28348474SJose.Borrego@Sun.COM 
28358474SJose.Borrego@Sun.COM 	if ((handle = smb_shr_sa_enter()) == NULL)
28368474SJose.Borrego@Sun.COM 		return (NERR_InternalError);
28378474SJose.Borrego@Sun.COM 
28388474SJose.Borrego@Sun.COM 	share = sa_find_share(handle, path);
28398474SJose.Borrego@Sun.COM 	if (share == NULL) {
28408474SJose.Borrego@Sun.COM 		group = srvsvc_sa_get_smbgrp(handle);
28418474SJose.Borrego@Sun.COM 		if (group == NULL) {
28428474SJose.Borrego@Sun.COM 			smb_shr_sa_exit();
28438474SJose.Borrego@Sun.COM 			return (NERR_InternalError);
28448474SJose.Borrego@Sun.COM 		}
28458474SJose.Borrego@Sun.COM 
28468474SJose.Borrego@Sun.COM 		share = sa_add_share(group, path, SA_SHARE_PERMANENT, &err);
28478474SJose.Borrego@Sun.COM 		if (share == NULL) {
28488474SJose.Borrego@Sun.COM 			smb_shr_sa_exit();
28498474SJose.Borrego@Sun.COM 			return (NERR_InternalError);
28508474SJose.Borrego@Sun.COM 		}
28518474SJose.Borrego@Sun.COM 		new_share = B_TRUE;
28528474SJose.Borrego@Sun.COM 	}
28538474SJose.Borrego@Sun.COM 
28548474SJose.Borrego@Sun.COM 	resource = sa_get_share_resource(share, sharename);
28558474SJose.Borrego@Sun.COM 	if (resource == NULL) {
28568474SJose.Borrego@Sun.COM 		resource = sa_add_resource(share, sharename,
28578474SJose.Borrego@Sun.COM 		    SA_SHARE_PERMANENT, &err);
28588474SJose.Borrego@Sun.COM 		if (resource == NULL) {
28598474SJose.Borrego@Sun.COM 			if (new_share)
28608474SJose.Borrego@Sun.COM 				(void) sa_remove_share(share);
28618474SJose.Borrego@Sun.COM 			smb_shr_sa_exit();
28628474SJose.Borrego@Sun.COM 			return (NERR_InternalError);
28638474SJose.Borrego@Sun.COM 		}
28648474SJose.Borrego@Sun.COM 	}
28658474SJose.Borrego@Sun.COM 
28668474SJose.Borrego@Sun.COM 	(void) sa_set_resource_description(resource, cmnt);
28678474SJose.Borrego@Sun.COM 
28688474SJose.Borrego@Sun.COM 	smb_shr_sa_exit();
28698474SJose.Borrego@Sun.COM 	return (status);
28708474SJose.Borrego@Sun.COM }
28718474SJose.Borrego@Sun.COM 
28728474SJose.Borrego@Sun.COM /*
28738474SJose.Borrego@Sun.COM  * Removes the share from sharemgr
28748474SJose.Borrego@Sun.COM  */
28758474SJose.Borrego@Sun.COM static uint32_t
28768474SJose.Borrego@Sun.COM srvsvc_sa_delete(char *sharename)
28778474SJose.Borrego@Sun.COM {
28788474SJose.Borrego@Sun.COM 	sa_handle_t handle;
28798474SJose.Borrego@Sun.COM 	sa_resource_t resource;
28808474SJose.Borrego@Sun.COM 	uint32_t status;
28818474SJose.Borrego@Sun.COM 
28828474SJose.Borrego@Sun.COM 	if ((handle = smb_shr_sa_enter()) == NULL)
28838474SJose.Borrego@Sun.COM 		return (NERR_InternalError);
28848474SJose.Borrego@Sun.COM 
28858474SJose.Borrego@Sun.COM 	status = NERR_InternalError;
28868474SJose.Borrego@Sun.COM 	if ((resource = sa_find_resource(handle, sharename)) != NULL) {
28878474SJose.Borrego@Sun.COM 		if (sa_remove_resource(resource) == SA_OK)
28888474SJose.Borrego@Sun.COM 			status = NERR_Success;
28898474SJose.Borrego@Sun.COM 	}
28908474SJose.Borrego@Sun.COM 
28918474SJose.Borrego@Sun.COM 	smb_shr_sa_exit();
28928474SJose.Borrego@Sun.COM 	return (status);
28938474SJose.Borrego@Sun.COM }
28948474SJose.Borrego@Sun.COM 
28959832Samw@Sun.COM /*
28969832Samw@Sun.COM  * Update the share information.
28979832Samw@Sun.COM  */
28989832Samw@Sun.COM static uint32_t
28999832Samw@Sun.COM srvsvc_sa_modify(smb_share_t *si, srvsvc_netshare_setinfo_t *info)
29009832Samw@Sun.COM {
29019832Samw@Sun.COM 	sa_handle_t handle;
29029832Samw@Sun.COM 	sa_share_t share;
29039832Samw@Sun.COM 	sa_resource_t resource;
29049832Samw@Sun.COM 	boolean_t renamed = B_FALSE;
29059832Samw@Sun.COM 	uint32_t nerr = NERR_Success;
29069832Samw@Sun.COM 
29079832Samw@Sun.COM 	if ((handle = smb_shr_sa_enter()) == NULL)
29089832Samw@Sun.COM 		return (NERR_InternalError);
29099832Samw@Sun.COM 
29109832Samw@Sun.COM 	if ((share = sa_find_share(handle, si->shr_path)) == NULL) {
29119832Samw@Sun.COM 		smb_shr_sa_exit();
29129832Samw@Sun.COM 		return (NERR_InternalError);
29139832Samw@Sun.COM 	}
29149832Samw@Sun.COM 
29159832Samw@Sun.COM 	if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) {
29169832Samw@Sun.COM 		smb_shr_sa_exit();
29179832Samw@Sun.COM 		return (NERR_InternalError);
29189832Samw@Sun.COM 	}
29199832Samw@Sun.COM 
29209832Samw@Sun.COM 	if (info->nss_netname != NULL && info->nss_netname[0] != '\0' &&
292110966SJordan.Brown@Sun.COM 	    smb_strcasecmp(info->nss_netname, si->shr_name, 0) != 0) {
29229832Samw@Sun.COM 		(void) sa_set_resource_attr(resource, SHOPT_NAME,
29239832Samw@Sun.COM 		    info->nss_netname);
29249832Samw@Sun.COM 		renamed = B_TRUE;
29259832Samw@Sun.COM 	}
29269832Samw@Sun.COM 
29279832Samw@Sun.COM 	if ((info->nss_comment != NULL) &&
29289832Samw@Sun.COM 	    (strcmp(info->nss_comment, si->shr_cmnt) != 0)) {
29299832Samw@Sun.COM 		(void) sa_set_resource_description(resource, info->nss_comment);
29309832Samw@Sun.COM 		(void) strlcpy(si->shr_cmnt, info->nss_comment,
29319832Samw@Sun.COM 		    SMB_SHARE_CMNT_MAX);
29329832Samw@Sun.COM 	}
29339832Samw@Sun.COM 
29349832Samw@Sun.COM 	smb_shr_sa_exit();
29359832Samw@Sun.COM 
29369832Samw@Sun.COM 	if (renamed) {
29379832Samw@Sun.COM 		nerr = smb_shr_rename(si->shr_name, info->nss_netname);
29389832Samw@Sun.COM 		if (nerr != NERR_Success)
29399832Samw@Sun.COM 			return (nerr);
29409832Samw@Sun.COM 
29419832Samw@Sun.COM 		(void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN);
29429832Samw@Sun.COM 	}
29439832Samw@Sun.COM 
29449832Samw@Sun.COM 	return (nerr);
29459832Samw@Sun.COM }
29469832Samw@Sun.COM 
29479832Samw@Sun.COM /*
294810504SKeyur.Desai@Sun.COM  * Update the share properties.
294910504SKeyur.Desai@Sun.COM  *
295010504SKeyur.Desai@Sun.COM  * Updates the optionset properties of the share resource.
295110504SKeyur.Desai@Sun.COM  * The properties are given as a list of name-value pair.
295210504SKeyur.Desai@Sun.COM  * The name argument should be the optionset property name and the value
295310504SKeyur.Desai@Sun.COM  * should be a valid value for the specified property.
29549832Samw@Sun.COM  */
29559832Samw@Sun.COM static uint32_t
295610504SKeyur.Desai@Sun.COM srvsvc_sa_setprop(smb_share_t *si, nvlist_t *nvl)
29579832Samw@Sun.COM {
29589832Samw@Sun.COM 	sa_handle_t handle;
29599832Samw@Sun.COM 	sa_share_t share;
29609832Samw@Sun.COM 	sa_resource_t resource;
296110504SKeyur.Desai@Sun.COM 	sa_property_t prop;
296210504SKeyur.Desai@Sun.COM 	sa_optionset_t opts;
296310504SKeyur.Desai@Sun.COM 	uint32_t nerr = NERR_Success;
296410504SKeyur.Desai@Sun.COM 	nvpair_t *cur;
296510504SKeyur.Desai@Sun.COM 	int err = 0;
296610504SKeyur.Desai@Sun.COM 	char *name, *val;
29679832Samw@Sun.COM 
29689832Samw@Sun.COM 	if ((handle = smb_shr_sa_enter()) == NULL)
29699832Samw@Sun.COM 		return (NERR_InternalError);
29709832Samw@Sun.COM 
29719832Samw@Sun.COM 	if ((share = sa_find_share(handle, si->shr_path)) == NULL) {
29729832Samw@Sun.COM 		smb_shr_sa_exit();
29739832Samw@Sun.COM 		return (NERR_InternalError);
29749832Samw@Sun.COM 	}
29759832Samw@Sun.COM 
29769832Samw@Sun.COM 	if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) {
29779832Samw@Sun.COM 		smb_shr_sa_exit();
29789832Samw@Sun.COM 		return (NERR_InternalError);
29799832Samw@Sun.COM 	}
29809832Samw@Sun.COM 
298110504SKeyur.Desai@Sun.COM 	if ((opts = sa_get_optionset(resource, SMB_PROTOCOL_NAME)) == NULL) {
298210504SKeyur.Desai@Sun.COM 		opts = sa_create_optionset(resource, SMB_PROTOCOL_NAME);
298310504SKeyur.Desai@Sun.COM 		if (opts == NULL) {
298410504SKeyur.Desai@Sun.COM 			smb_shr_sa_exit();
298510504SKeyur.Desai@Sun.COM 			return (NERR_InternalError);
298610504SKeyur.Desai@Sun.COM 		}
29879832Samw@Sun.COM 	}
29889832Samw@Sun.COM 
298910504SKeyur.Desai@Sun.COM 	cur = nvlist_next_nvpair(nvl, NULL);
299010504SKeyur.Desai@Sun.COM 	while (cur != NULL) {
299110504SKeyur.Desai@Sun.COM 		name = nvpair_name(cur);
299210504SKeyur.Desai@Sun.COM 		err = nvpair_value_string(cur, &val);
299310504SKeyur.Desai@Sun.COM 		if ((err != 0) || (name == NULL) || (val == NULL)) {
299410504SKeyur.Desai@Sun.COM 			nerr = NERR_InternalError;
299510504SKeyur.Desai@Sun.COM 			break;
299610504SKeyur.Desai@Sun.COM 		}
299710504SKeyur.Desai@Sun.COM 
299810504SKeyur.Desai@Sun.COM 		prop = NULL;
299910504SKeyur.Desai@Sun.COM 		if ((prop = sa_get_property(opts, name)) == NULL) {
300010504SKeyur.Desai@Sun.COM 			prop = sa_create_property(name, val);
300110504SKeyur.Desai@Sun.COM 			if (prop != NULL) {
300210504SKeyur.Desai@Sun.COM 				nerr = sa_valid_property(handle, opts,
300310504SKeyur.Desai@Sun.COM 				    SMB_PROTOCOL_NAME, prop);
300410504SKeyur.Desai@Sun.COM 				if (nerr != NERR_Success) {
300510504SKeyur.Desai@Sun.COM 					(void) sa_remove_property(prop);
300610504SKeyur.Desai@Sun.COM 					break;
300710504SKeyur.Desai@Sun.COM 				}
300810504SKeyur.Desai@Sun.COM 			}
300910504SKeyur.Desai@Sun.COM 			nerr = sa_add_property(opts, prop);
301010504SKeyur.Desai@Sun.COM 			if (nerr != NERR_Success)
301110504SKeyur.Desai@Sun.COM 				break;
301210504SKeyur.Desai@Sun.COM 		} else {
301310504SKeyur.Desai@Sun.COM 			nerr = sa_update_property(prop, val);
301410504SKeyur.Desai@Sun.COM 			if (nerr != NERR_Success)
301510504SKeyur.Desai@Sun.COM 				break;
301610504SKeyur.Desai@Sun.COM 		}
301710504SKeyur.Desai@Sun.COM 
301810504SKeyur.Desai@Sun.COM 		cur = nvlist_next_nvpair(nvl, cur);
301910504SKeyur.Desai@Sun.COM 	}
302010504SKeyur.Desai@Sun.COM 
302110504SKeyur.Desai@Sun.COM 	if (nerr == NERR_Success)
302210504SKeyur.Desai@Sun.COM 		nerr = sa_commit_properties(opts, 0);
302310504SKeyur.Desai@Sun.COM 
30249832Samw@Sun.COM 	smb_shr_sa_exit();
302510504SKeyur.Desai@Sun.COM 	return (nerr);
30269832Samw@Sun.COM }
30279832Samw@Sun.COM 
302810504SKeyur.Desai@Sun.COM 
30298474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[] = {
30308474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetConnectEnum,	SRVSVC_OPNUM_NetConnectEnum },
30318474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetFileEnum,		SRVSVC_OPNUM_NetFileEnum },
30328474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetFileClose,	SRVSVC_OPNUM_NetFileClose },
30338474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareGetInfo,	SRVSVC_OPNUM_NetShareGetInfo },
30348474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareSetInfo,	SRVSVC_OPNUM_NetShareSetInfo },
30358474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetSessionEnum,	SRVSVC_OPNUM_NetSessionEnum },
30368474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetSessionDel,	SRVSVC_OPNUM_NetSessionDel },
30378474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetServerGetInfo,	SRVSVC_OPNUM_NetServerGetInfo },
30388474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetRemoteTOD,	SRVSVC_OPNUM_NetRemoteTOD },
30398474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetNameValidate,	SRVSVC_OPNUM_NetNameValidate },
30408474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareAdd,		SRVSVC_OPNUM_NetShareAdd },
30418474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareDel,		SRVSVC_OPNUM_NetShareDel },
30428474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareEnum,	SRVSVC_OPNUM_NetShareEnum },
30438474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetShareEnumSticky,	SRVSVC_OPNUM_NetShareEnumSticky },
30449832Samw@Sun.COM 	{ srvsvc_s_NetShareCheck,	SRVSVC_OPNUM_NetShareCheck },
30458474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetGetFileSecurity,	SRVSVC_OPNUM_NetGetFileSecurity },
30468474SJose.Borrego@Sun.COM 	{ srvsvc_s_NetSetFileSecurity,	SRVSVC_OPNUM_NetSetFileSecurity },
30478474SJose.Borrego@Sun.COM 	{0}
30488474SJose.Borrego@Sun.COM };
3049