xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/netdfs.c (revision 12890:16985853e3aa)
15331Samw /*
25331Samw  * CDDL HEADER START
35331Samw  *
45331Samw  * The contents of this file are subject to the terms of the
55331Samw  * Common Development and Distribution License (the "License").
65331Samw  * You may not use this file except in compliance with the License.
75331Samw  *
85331Samw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95331Samw  * or http://www.opensolaris.org/os/licensing.
105331Samw  * See the License for the specific language governing permissions
115331Samw  * and limitations under the License.
125331Samw  *
135331Samw  * When distributing Covered Code, include this CDDL HEADER in each
145331Samw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155331Samw  * If applicable, add the following below this CDDL HEADER, with the
165331Samw  * fields enclosed by brackets "[]" replaced with your own identifying
175331Samw  * information: Portions Copyright [yyyy] [name of copyright owner]
185331Samw  *
195331Samw  * CDDL HEADER END
205331Samw  */
2112508Samw@Sun.COM 
225331Samw /*
2312508Samw@Sun.COM  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
245331Samw  */
255331Samw 
265331Samw /*
2711963SAfshin.Ardakani@Sun.COM  * Net DFS server side RPC service for managing DFS namespaces.
2811963SAfshin.Ardakani@Sun.COM  *
2911963SAfshin.Ardakani@Sun.COM  * For more details refer to following Microsoft specification:
3011963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]
3111963SAfshin.Ardakani@Sun.COM  *    Distributed File System (DFS): Namespace Management Protocol Specification
325331Samw  */
335331Samw 
3411963SAfshin.Ardakani@Sun.COM #include <unistd.h>
3511963SAfshin.Ardakani@Sun.COM #include <libgen.h>
365331Samw #include <strings.h>
3711963SAfshin.Ardakani@Sun.COM #include <sys/sysmacros.h>
385331Samw 
3912508Samw@Sun.COM #include <smbsrv/libmlsvc.h>
405331Samw #include <smbsrv/nmpipes.h>
4112508Samw@Sun.COM #include <smbsrv/ndl/netdfs.ndl>
4211963SAfshin.Ardakani@Sun.COM #include <dfs.h>
435331Samw 
4411963SAfshin.Ardakani@Sun.COM /*
4511963SAfshin.Ardakani@Sun.COM  * Depends on the information level requested around 4000 or more links
4611963SAfshin.Ardakani@Sun.COM  * can be provided with this buffer size. The limitation here is due
4711963SAfshin.Ardakani@Sun.COM  * to some problem in NDR and/or opipe layer so:
4811963SAfshin.Ardakani@Sun.COM  *
4911963SAfshin.Ardakani@Sun.COM  * - Do NOT increase the buffer size until that problem is fixed
5011963SAfshin.Ardakani@Sun.COM  * - The buffer size should be increased when the problem is fixed
5111963SAfshin.Ardakani@Sun.COM  *   so the 4000 link limitation is removed.
5211963SAfshin.Ardakani@Sun.COM  */
5311963SAfshin.Ardakani@Sun.COM #define	NETDFS_MAXBUFLEN	(800 * 1024)
5411963SAfshin.Ardakani@Sun.COM #define	NETDFS_MAXPREFLEN	((uint32_t)(-1))
555331Samw 
5611963SAfshin.Ardakani@Sun.COM typedef struct netdfs_enumhandle_t {
5711963SAfshin.Ardakani@Sun.COM 	uint32_t	de_level;	/* level of detail being requested */
5811963SAfshin.Ardakani@Sun.COM 	uint32_t	de_prefmaxlen;	/* client MAX size buffer preference */
5911963SAfshin.Ardakani@Sun.COM 	uint32_t	de_resume;	/* client resume handle */
6011963SAfshin.Ardakani@Sun.COM 	uint32_t	de_bavail;	/* remaining buffer space in bytes */
6111963SAfshin.Ardakani@Sun.COM 	uint32_t	de_ntotal;	/* total number of objects */
6211963SAfshin.Ardakani@Sun.COM 	uint32_t	de_nmax;	/* MAX number of objects to return */
6311963SAfshin.Ardakani@Sun.COM 	uint32_t	de_nitems;	/* number of objects in buf */
6411963SAfshin.Ardakani@Sun.COM 	uint32_t	de_nskip;	/* number of objects to skip */
6511963SAfshin.Ardakani@Sun.COM 	void		*de_entries;	/* ndr buffer */
6611963SAfshin.Ardakani@Sun.COM } netdfs_enumhandle_t;
675331Samw 
688334SJose.Borrego@Sun.COM static int netdfs_s_getver(void *, ndr_xa_t *);
698334SJose.Borrego@Sun.COM static int netdfs_s_add(void *, ndr_xa_t *);
708334SJose.Borrego@Sun.COM static int netdfs_s_remove(void *, ndr_xa_t *);
718334SJose.Borrego@Sun.COM static int netdfs_s_setinfo(void *, ndr_xa_t *);
728334SJose.Borrego@Sun.COM static int netdfs_s_getinfo(void *, ndr_xa_t *);
738334SJose.Borrego@Sun.COM static int netdfs_s_enum(void *, ndr_xa_t *);
748334SJose.Borrego@Sun.COM static int netdfs_s_move(void *, ndr_xa_t *);
758334SJose.Borrego@Sun.COM static int netdfs_s_rename(void *, ndr_xa_t *);
768334SJose.Borrego@Sun.COM static int netdfs_s_addstdroot(void *, ndr_xa_t *);
778334SJose.Borrego@Sun.COM static int netdfs_s_remstdroot(void *, ndr_xa_t *);
788334SJose.Borrego@Sun.COM static int netdfs_s_enumex(void *, ndr_xa_t *);
795331Samw 
8011963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_setinfo_100(dfs_path_t *, netdfs_info100_t *);
8111963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_setinfo_101(dfs_path_t *, netdfs_info101_t *,
8211963SAfshin.Ardakani@Sun.COM     const char *, const char *);
8311963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_setinfo_102(dfs_path_t *, netdfs_info102_t *);
8411963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_setinfo_103(dfs_path_t *, netdfs_info103_t *);
8511963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_setinfo_104(dfs_path_t *, netdfs_info104_t *,
8611963SAfshin.Ardakani@Sun.COM     const char *, const char *);
8711963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_setinfo_105(dfs_path_t *, netdfs_info105_t *);
8811963SAfshin.Ardakani@Sun.COM 
8911963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_1(netdfs_info1_t *, dfs_info_t *, ndr_xa_t *,
9011963SAfshin.Ardakani@Sun.COM     uint32_t *);
9111963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_2(netdfs_info2_t *, dfs_info_t *, ndr_xa_t *,
9211963SAfshin.Ardakani@Sun.COM     uint32_t *);
9311963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_3(netdfs_info3_t *, dfs_info_t *, ndr_xa_t *,
9411963SAfshin.Ardakani@Sun.COM     uint32_t *);
9511963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_4(netdfs_info4_t *, dfs_info_t *, ndr_xa_t *,
9611963SAfshin.Ardakani@Sun.COM     uint32_t *);
9711963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_5(netdfs_info5_t *, dfs_info_t *, ndr_xa_t *,
9811963SAfshin.Ardakani@Sun.COM     uint32_t *);
9911963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_6(netdfs_info6_t *, dfs_info_t *, ndr_xa_t *,
10011963SAfshin.Ardakani@Sun.COM     uint32_t *);
10111963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_100(netdfs_info100_t *, dfs_info_t *, ndr_xa_t *,
10211963SAfshin.Ardakani@Sun.COM     uint32_t *);
10311963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_300(netdfs_info300_t *, dfs_info_t *, ndr_xa_t *,
10411963SAfshin.Ardakani@Sun.COM     uint32_t *);
10511963SAfshin.Ardakani@Sun.COM 
10611963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_enum_common(netdfs_enumhandle_t *, ndr_xa_t *);
10711963SAfshin.Ardakani@Sun.COM 
10811963SAfshin.Ardakani@Sun.COM static void netdfs_path_create(const char *);
10911963SAfshin.Ardakani@Sun.COM static void netdfs_path_remove(smb_unc_t *);
11011963SAfshin.Ardakani@Sun.COM static boolean_t netdfs_guid_fromstr(char *, netdfs_uuid_t *);
11111963SAfshin.Ardakani@Sun.COM 
1128334SJose.Borrego@Sun.COM static ndr_stub_table_t netdfs_stub_table[] = {
1135331Samw 	{ netdfs_s_getver,	NETDFS_OPNUM_GETVER },
1145331Samw 	{ netdfs_s_add,		NETDFS_OPNUM_ADD },
1155331Samw 	{ netdfs_s_remove,	NETDFS_OPNUM_REMOVE },
1165331Samw 	{ netdfs_s_setinfo,	NETDFS_OPNUM_SETINFO },
1175331Samw 	{ netdfs_s_getinfo,	NETDFS_OPNUM_GETINFO },
1185331Samw 	{ netdfs_s_enum,	NETDFS_OPNUM_ENUM },
1195331Samw 	{ netdfs_s_rename,	NETDFS_OPNUM_RENAME },
1205331Samw 	{ netdfs_s_move,	NETDFS_OPNUM_MOVE },
1215331Samw 	{ netdfs_s_addstdroot,	NETDFS_OPNUM_ADDSTDROOT },
1225331Samw 	{ netdfs_s_remstdroot,	NETDFS_OPNUM_REMSTDROOT },
1235331Samw 	{ netdfs_s_enumex,	NETDFS_OPNUM_ENUMEX },
1245331Samw 	{0}
1255331Samw };
1265331Samw 
1278334SJose.Borrego@Sun.COM static ndr_service_t netdfs_service = {
1285331Samw 	"NETDFS",			/* name */
1295331Samw 	"DFS",				/* desc */
13011963SAfshin.Ardakani@Sun.COM 	"\\netdfs",			/* endpoint */
13111963SAfshin.Ardakani@Sun.COM 	PIPE_NETDFS,			/* sec_addr_port */
1325331Samw 	NETDFS_ABSTRACT_UUID,	NETDFS_ABSTRACT_VERS,
1335331Samw 	NETDFS_TRANSFER_UUID,	NETDFS_TRANSFER_VERS,
1345331Samw 
1355331Samw 	0,				/* no bind_instance_size */
1365331Samw 	0,				/* no bind_req() */
1375331Samw 	0,				/* no unbind_and_close() */
1385331Samw 	0,				/* use generic_call_stub() */
1395331Samw 
1405331Samw 	&TYPEINFO(netdfs_interface),	/* interface ti */
1415331Samw 	netdfs_stub_table		/* stub_table */
1425331Samw };
1435331Samw 
1445331Samw /*
1455331Samw  * Register the NETDFS RPC interface with the RPC runtime library.
1465331Samw  * The service must be registered in order to use either the client
1475331Samw  * side or the server side functions.
1485331Samw  */
1495331Samw void
netdfs_initialize(void)1505331Samw netdfs_initialize(void)
1515331Samw {
1528334SJose.Borrego@Sun.COM 	(void) ndr_svc_register(&netdfs_service);
15311963SAfshin.Ardakani@Sun.COM 	dfs_init();
15411963SAfshin.Ardakani@Sun.COM }
15511963SAfshin.Ardakani@Sun.COM 
15611963SAfshin.Ardakani@Sun.COM void
netdfs_finalize(void)15711963SAfshin.Ardakani@Sun.COM netdfs_finalize(void)
15811963SAfshin.Ardakani@Sun.COM {
15911963SAfshin.Ardakani@Sun.COM 	dfs_fini();
1605331Samw }
1615331Samw 
1625331Samw /*
16311963SAfshin.Ardakani@Sun.COM  * Returns the version number of the DFS server in use on the server.
1645331Samw  *
16511963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsManagerGetVersion (Opnum 0)
1665331Samw  */
1675331Samw /*ARGSUSED*/
1685331Samw static int
netdfs_s_getver(void * arg,ndr_xa_t * mxa)1698334SJose.Borrego@Sun.COM netdfs_s_getver(void *arg, ndr_xa_t *mxa)
1705331Samw {
1715331Samw 	struct netdfs_getver *param = arg;
1725331Samw 
17311963SAfshin.Ardakani@Sun.COM 	param->version = DFS_MANAGER_VERSION_NT4;
1748334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
1755331Samw }
1765331Samw 
1775331Samw /*
17811963SAfshin.Ardakani@Sun.COM  * Creates a new DFS link or adds a new target to an existing link of a
17911963SAfshin.Ardakani@Sun.COM  * DFS namespace.
18011963SAfshin.Ardakani@Sun.COM  *
18111963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsAdd (Opnum 1)
1825331Samw  */
1835331Samw static int
netdfs_s_add(void * arg,ndr_xa_t * mxa)1848334SJose.Borrego@Sun.COM netdfs_s_add(void *arg, ndr_xa_t *mxa)
1855331Samw {
18611963SAfshin.Ardakani@Sun.COM 	netdfs_add_t *param = arg;
18711963SAfshin.Ardakani@Sun.COM 	dfs_path_t path;
18811963SAfshin.Ardakani@Sun.COM 	uint32_t status;
18911963SAfshin.Ardakani@Sun.COM 	const char *uncpath = (const char *)param->dfs_path;
19011963SAfshin.Ardakani@Sun.COM 	const char *fspath = (const char *)path.p_fspath;
19111963SAfshin.Ardakani@Sun.COM 	boolean_t newlink;
19211963SAfshin.Ardakani@Sun.COM 
19311963SAfshin.Ardakani@Sun.COM 	if (!ndr_is_admin(mxa)) {
19411963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
19511963SAfshin.Ardakani@Sun.COM 		return (NDR_DRC_OK);
19611963SAfshin.Ardakani@Sun.COM 	}
1975331Samw 
19811963SAfshin.Ardakani@Sun.COM 	if (param->server == NULL || param->share == NULL) {
19911963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_INVALID_PARAMETER;
20011963SAfshin.Ardakani@Sun.COM 		return (NDR_DRC_OK);
20111963SAfshin.Ardakani@Sun.COM 	}
20211963SAfshin.Ardakani@Sun.COM 
20311963SAfshin.Ardakani@Sun.COM 	switch (param->flags) {
20411963SAfshin.Ardakani@Sun.COM 	case DFS_CREATE_VOLUME:
20511963SAfshin.Ardakani@Sun.COM 	case DFS_ADD_VOLUME:
20611963SAfshin.Ardakani@Sun.COM 	case DFS_RESTORE_VOLUME:
20711963SAfshin.Ardakani@Sun.COM 	case (DFS_ADD_VOLUME | DFS_RESTORE_VOLUME):
20811963SAfshin.Ardakani@Sun.COM 		break;
20911963SAfshin.Ardakani@Sun.COM 	default:
2105331Samw 		param->status = ERROR_INVALID_PARAMETER;
2118334SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
2125331Samw 	}
2135331Samw 
21411963SAfshin.Ardakani@Sun.COM 	status = dfs_path_parse(&path, uncpath, DFS_OBJECT_LINK);
21511963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS) {
21611963SAfshin.Ardakani@Sun.COM 		param->status = status;
21711963SAfshin.Ardakani@Sun.COM 		return (NDR_DRC_OK);
2185331Samw 	}
2195331Samw 
22011963SAfshin.Ardakani@Sun.COM 	status = smb_name_validate_rpath(path.p_unc.unc_path);
22111963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS) {
22211963SAfshin.Ardakani@Sun.COM 		dfs_path_free(&path);
2235331Samw 		param->status = status;
2248334SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
2255331Samw 	}
2265331Samw 
22711963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
22811963SAfshin.Ardakani@Sun.COM 
22911963SAfshin.Ardakani@Sun.COM 	netdfs_path_create(fspath);
23011963SAfshin.Ardakani@Sun.COM 
23111963SAfshin.Ardakani@Sun.COM 	status = dfs_link_add(fspath, (const char *)param->server,
23211963SAfshin.Ardakani@Sun.COM 	    (const char *)param->share, (const char *)param->comment,
23311963SAfshin.Ardakani@Sun.COM 	    param->flags, &newlink);
23411963SAfshin.Ardakani@Sun.COM 
23511963SAfshin.Ardakani@Sun.COM 	if (newlink)
23611963SAfshin.Ardakani@Sun.COM 		(void) dfs_cache_add_byname(path.p_unc.unc_share,
23711963SAfshin.Ardakani@Sun.COM 		    path.p_unc.unc_path, DFS_OBJECT_LINK);
23811963SAfshin.Ardakani@Sun.COM 
23911963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS)
24011963SAfshin.Ardakani@Sun.COM 		netdfs_path_remove(&path.p_unc);
24111963SAfshin.Ardakani@Sun.COM 
24211963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
24311963SAfshin.Ardakani@Sun.COM 
24411963SAfshin.Ardakani@Sun.COM 	dfs_path_free(&path);
24511963SAfshin.Ardakani@Sun.COM 	param->status = status;
2468334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
2475331Samw }
2485331Samw 
2495331Samw /*
25011963SAfshin.Ardakani@Sun.COM  * Removes a link or a link target from a DFS namespace. A link can be
25111963SAfshin.Ardakani@Sun.COM  * removed regardless of the number of targets associated with it.
2525331Samw  *
25311963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsRemove (Opnum 2)
2545331Samw  */
2555331Samw static int
netdfs_s_remove(void * arg,ndr_xa_t * mxa)2568334SJose.Borrego@Sun.COM netdfs_s_remove(void *arg, ndr_xa_t *mxa)
2575331Samw {
2585331Samw 	struct netdfs_remove *param = arg;
25911963SAfshin.Ardakani@Sun.COM 	dfs_path_t path;
26011963SAfshin.Ardakani@Sun.COM 	uint32_t status, stat;
26111963SAfshin.Ardakani@Sun.COM 	const char *uncpath = (const char *)param->dfs_path;
26211963SAfshin.Ardakani@Sun.COM 	const char *fspath = (const char *)path.p_fspath;
2635331Samw 
26411963SAfshin.Ardakani@Sun.COM 	if (!ndr_is_admin(mxa)) {
26511963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
26611963SAfshin.Ardakani@Sun.COM 		return (NDR_DRC_OK);
26711963SAfshin.Ardakani@Sun.COM 	}
26811963SAfshin.Ardakani@Sun.COM 
26911963SAfshin.Ardakani@Sun.COM 	/* both server and share must be NULL or non-NULL */
27011963SAfshin.Ardakani@Sun.COM 	if ((param->server == NULL && param->share != NULL) ||
27111963SAfshin.Ardakani@Sun.COM 	    (param->server != NULL && param->share == NULL)) {
2725331Samw 		param->status = ERROR_INVALID_PARAMETER;
2738334SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
2745331Samw 	}
2755331Samw 
27611963SAfshin.Ardakani@Sun.COM 	status = dfs_path_parse(&path, uncpath, DFS_OBJECT_LINK);
27711963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS) {
2785331Samw 		param->status = status;
2798334SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
2805331Samw 	}
2815331Samw 
28211963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
28311963SAfshin.Ardakani@Sun.COM 
28411963SAfshin.Ardakani@Sun.COM 	status = dfs_link_remove(fspath, (const char *)param->server,
28511963SAfshin.Ardakani@Sun.COM 	    (const char *)param->share);
28611963SAfshin.Ardakani@Sun.COM 
28711963SAfshin.Ardakani@Sun.COM 	if (status == ERROR_SUCCESS) {
28811963SAfshin.Ardakani@Sun.COM 		if (dfs_link_stat(fspath, &stat) == ERROR_SUCCESS) {
28911963SAfshin.Ardakani@Sun.COM 			if (stat != DFS_STAT_ISDFS)
29011963SAfshin.Ardakani@Sun.COM 				dfs_cache_remove(path.p_unc.unc_share,
29111963SAfshin.Ardakani@Sun.COM 				    path.p_unc.unc_path);
29211963SAfshin.Ardakani@Sun.COM 			/*
29311963SAfshin.Ardakani@Sun.COM 			 * if link is removed then try to remove its
29411963SAfshin.Ardakani@Sun.COM 			 * empty parent directories if any
29511963SAfshin.Ardakani@Sun.COM 			 */
29611963SAfshin.Ardakani@Sun.COM 			if (stat == DFS_STAT_NOTFOUND)
29711963SAfshin.Ardakani@Sun.COM 				netdfs_path_remove(&path.p_unc);
29811963SAfshin.Ardakani@Sun.COM 		}
29911963SAfshin.Ardakani@Sun.COM 	}
30011963SAfshin.Ardakani@Sun.COM 
30111963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
30211963SAfshin.Ardakani@Sun.COM 
30311963SAfshin.Ardakani@Sun.COM 	dfs_path_free(&path);
30411963SAfshin.Ardakani@Sun.COM 	param->status = status;
3058334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
3065331Samw }
3075331Samw 
3085331Samw /*
30911963SAfshin.Ardakani@Sun.COM  * Sets or modifies information relevant to a specific DFS root, DFS root
31011963SAfshin.Ardakani@Sun.COM  * target, DFS link, or DFS link target
3115331Samw  *
31211963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsSetInfo (Opnum 3)
3135331Samw  */
3145331Samw /*ARGSUSED*/
3155331Samw static int
netdfs_s_setinfo(void * arg,ndr_xa_t * mxa)3168334SJose.Borrego@Sun.COM netdfs_s_setinfo(void *arg, ndr_xa_t *mxa)
3175331Samw {
31811963SAfshin.Ardakani@Sun.COM 	netdfs_setinfo_t *param = arg;
31911963SAfshin.Ardakani@Sun.COM 	dfs_path_t path;
32011963SAfshin.Ardakani@Sun.COM 	uint32_t status, stat;
3215331Samw 
32211963SAfshin.Ardakani@Sun.COM 	/* both server and share must be NULL or non-NULL */
32311963SAfshin.Ardakani@Sun.COM 	if ((param->server == NULL && param->share != NULL) ||
32411963SAfshin.Ardakani@Sun.COM 	    (param->server != NULL && param->share == NULL)) {
3255331Samw 		param->status = ERROR_INVALID_PARAMETER;
3268334SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
3275331Samw 	}
3285331Samw 
32911963SAfshin.Ardakani@Sun.COM 	status = dfs_path_parse(&path, (const char *)param->dfs_path,
33011963SAfshin.Ardakani@Sun.COM 	    DFS_OBJECT_ANY);
33111963SAfshin.Ardakani@Sun.COM 
33211963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS) {
33311963SAfshin.Ardakani@Sun.COM 		param->status = status;
33411963SAfshin.Ardakani@Sun.COM 		return (NDR_DRC_OK);
3355331Samw 	}
3365331Samw 
33711963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
33811963SAfshin.Ardakani@Sun.COM 	status = dfs_link_stat((const char *)path.p_fspath, &stat);
33911963SAfshin.Ardakani@Sun.COM 
34011963SAfshin.Ardakani@Sun.COM 	if ((path.p_type == DFS_OBJECT_LINK) && (stat != DFS_STAT_ISDFS)) {
34111963SAfshin.Ardakani@Sun.COM 		dfs_setpriv(PRIV_OFF);
34211963SAfshin.Ardakani@Sun.COM 		dfs_path_free(&path);
34311963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_NOT_FOUND;
3448334SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
3455331Samw 	}
3465331Samw 
3475331Samw 	switch (param->info.level) {
3485331Samw 	case 100:
34911963SAfshin.Ardakani@Sun.COM 		status = netdfs_setinfo_100(&path, param->info.iu.info100);
35011963SAfshin.Ardakani@Sun.COM 		break;
3515331Samw 	case 101:
35211963SAfshin.Ardakani@Sun.COM 		status = netdfs_setinfo_101(&path, param->info.iu.info101,
35311963SAfshin.Ardakani@Sun.COM 		    (const char *)param->server, (const char *)param->share);
35411963SAfshin.Ardakani@Sun.COM 		break;
3555331Samw 	case 102:
35611963SAfshin.Ardakani@Sun.COM 		status = netdfs_setinfo_102(&path, param->info.iu.info102);
3575331Samw 		break;
35811963SAfshin.Ardakani@Sun.COM 	case 103:
35911963SAfshin.Ardakani@Sun.COM 		status = netdfs_setinfo_103(&path, param->info.iu.info103);
36011963SAfshin.Ardakani@Sun.COM 		break;
36111963SAfshin.Ardakani@Sun.COM 	case 104:
36211963SAfshin.Ardakani@Sun.COM 		status = netdfs_setinfo_104(&path, param->info.iu.info104,
36311963SAfshin.Ardakani@Sun.COM 		    (const char *)param->server, (const char *)param->share);
36411963SAfshin.Ardakani@Sun.COM 		break;
36511963SAfshin.Ardakani@Sun.COM 	case 105:
36611963SAfshin.Ardakani@Sun.COM 		status = netdfs_setinfo_105(&path, param->info.iu.info105);
36711963SAfshin.Ardakani@Sun.COM 		break;
3685331Samw 	default:
36911963SAfshin.Ardakani@Sun.COM 		status = ERROR_INVALID_LEVEL;
37011963SAfshin.Ardakani@Sun.COM 		break;
3715331Samw 	}
3725331Samw 
37311963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
37411963SAfshin.Ardakani@Sun.COM 	dfs_path_free(&path);
37511963SAfshin.Ardakani@Sun.COM 	param->status = status;
3768334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
3775331Samw }
3785331Samw 
3795331Samw /*
38011963SAfshin.Ardakani@Sun.COM  * Returns information about a DFS root or a DFS link of the specified
38111963SAfshin.Ardakani@Sun.COM  * DFS namespace.
3825331Samw  *
38311963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsGetInfo (Opnum 4)
3845331Samw  */
3855331Samw static int
netdfs_s_getinfo(void * arg,ndr_xa_t * mxa)3868334SJose.Borrego@Sun.COM netdfs_s_getinfo(void *arg, ndr_xa_t *mxa)
3875331Samw {
38811963SAfshin.Ardakani@Sun.COM 	netdfs_getinfo_t *param = arg;
38911963SAfshin.Ardakani@Sun.COM 	netdfs_info1_t *info1;
39011963SAfshin.Ardakani@Sun.COM 	netdfs_info2_t *info2;
39111963SAfshin.Ardakani@Sun.COM 	netdfs_info3_t *info3;
39211963SAfshin.Ardakani@Sun.COM 	netdfs_info4_t *info4;
39311963SAfshin.Ardakani@Sun.COM 	netdfs_info5_t *info5;
39411963SAfshin.Ardakani@Sun.COM 	netdfs_info6_t *info6;
39511963SAfshin.Ardakani@Sun.COM 	netdfs_info100_t *info100;
39611963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
39711963SAfshin.Ardakani@Sun.COM 	dfs_path_t path;
39811963SAfshin.Ardakani@Sun.COM 	uint32_t status, stat;
39911963SAfshin.Ardakani@Sun.COM 	const char *fspath;
40011963SAfshin.Ardakani@Sun.COM 	uint32_t level = param->level;
40111963SAfshin.Ardakani@Sun.COM 
40211963SAfshin.Ardakani@Sun.COM 	status = dfs_path_parse(&path, (const char *)param->dfs_path,
40311963SAfshin.Ardakani@Sun.COM 	    DFS_OBJECT_ANY);
4045331Samw 
40511963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS)
40611963SAfshin.Ardakani@Sun.COM 		goto getinfo_error;
40711963SAfshin.Ardakani@Sun.COM 
40811963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
4095331Samw 
41011963SAfshin.Ardakani@Sun.COM 	fspath = path.p_fspath;
41111963SAfshin.Ardakani@Sun.COM 	if (path.p_type == DFS_OBJECT_LINK) {
41211963SAfshin.Ardakani@Sun.COM 		status = dfs_link_stat(fspath, &stat);
41311963SAfshin.Ardakani@Sun.COM 		if ((status != ERROR_SUCCESS) || (stat != DFS_STAT_ISDFS)) {
41411963SAfshin.Ardakani@Sun.COM 			status = ERROR_NOT_FOUND;
41511963SAfshin.Ardakani@Sun.COM 			goto getinfo_error;
41611963SAfshin.Ardakani@Sun.COM 		}
41711963SAfshin.Ardakani@Sun.COM 
41811963SAfshin.Ardakani@Sun.COM 		status = dfs_link_getinfo(fspath, &info, param->level);
4195331Samw 	} else {
42011963SAfshin.Ardakani@Sun.COM 		status = dfs_root_getinfo(fspath, &info, param->level);
4215331Samw 	}
4225331Samw 
42311963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS)
42411963SAfshin.Ardakani@Sun.COM 		goto getinfo_error;
42511963SAfshin.Ardakani@Sun.COM 
42611963SAfshin.Ardakani@Sun.COM 	(void) strlcpy(info.i_uncpath, (char *)param->dfs_path,
42711963SAfshin.Ardakani@Sun.COM 	    sizeof (info.i_uncpath));
4285331Samw 
42911963SAfshin.Ardakani@Sun.COM 	dfs_info_trace("netdfs_s_getinfo", &info);
43011963SAfshin.Ardakani@Sun.COM 
43111963SAfshin.Ardakani@Sun.COM 	status = ERROR_NOT_ENOUGH_MEMORY;
43211963SAfshin.Ardakani@Sun.COM 
43311963SAfshin.Ardakani@Sun.COM 	switch (level) {
4345331Samw 	case 1:
43511963SAfshin.Ardakani@Sun.COM 		if ((info1 = NDR_NEW(mxa, netdfs_info1_t)) != NULL) {
43611963SAfshin.Ardakani@Sun.COM 			param->info.iu.info1 = info1;
43711963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_1(info1, &info, mxa, NULL);
43811963SAfshin.Ardakani@Sun.COM 		}
43911963SAfshin.Ardakani@Sun.COM 		break;
4405331Samw 	case 2:
44111963SAfshin.Ardakani@Sun.COM 		if ((info2 = NDR_NEW(mxa, netdfs_info2_t)) != NULL) {
44211963SAfshin.Ardakani@Sun.COM 			param->info.iu.info2 = info2;
44311963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_2(info2, &info, mxa, NULL);
44411963SAfshin.Ardakani@Sun.COM 		}
44511963SAfshin.Ardakani@Sun.COM 		break;
4465331Samw 	case 3:
44711963SAfshin.Ardakani@Sun.COM 		if ((info3 = NDR_NEW(mxa, netdfs_info3_t)) != NULL) {
44811963SAfshin.Ardakani@Sun.COM 			param->info.iu.info3 = info3;
44911963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_3(info3, &info, mxa, NULL);
45011963SAfshin.Ardakani@Sun.COM 		}
45111963SAfshin.Ardakani@Sun.COM 		break;
4525331Samw 	case 4:
45311963SAfshin.Ardakani@Sun.COM 		if ((info4 = NDR_NEW(mxa, netdfs_info4_t)) != NULL) {
45411963SAfshin.Ardakani@Sun.COM 			param->info.iu.info4 = info4;
45511963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_4(info4, &info, mxa, NULL);
45611963SAfshin.Ardakani@Sun.COM 		}
45711963SAfshin.Ardakani@Sun.COM 		break;
45811963SAfshin.Ardakani@Sun.COM 	case 5:
45911963SAfshin.Ardakani@Sun.COM 		if ((info5 = NDR_NEW(mxa, netdfs_info5_t)) != NULL) {
46011963SAfshin.Ardakani@Sun.COM 			param->info.iu.info5 = info5;
46111963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_5(info5, &info, mxa, NULL);
46211963SAfshin.Ardakani@Sun.COM 		}
46311963SAfshin.Ardakani@Sun.COM 		break;
46411963SAfshin.Ardakani@Sun.COM 	case 6:
46511963SAfshin.Ardakani@Sun.COM 		if ((info6 = NDR_NEW(mxa, netdfs_info6_t)) != NULL) {
46611963SAfshin.Ardakani@Sun.COM 			param->info.iu.info6 = info6;
46711963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_6(info6, &info, mxa, NULL);
46811963SAfshin.Ardakani@Sun.COM 		}
46911963SAfshin.Ardakani@Sun.COM 		break;
4705331Samw 	case 100:
47111963SAfshin.Ardakani@Sun.COM 		if ((info100 = NDR_NEW(mxa, netdfs_info100_t)) != NULL) {
47211963SAfshin.Ardakani@Sun.COM 			param->info.iu.info100 = info100;
47311963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_100(info100, &info, mxa, NULL);
47411963SAfshin.Ardakani@Sun.COM 		}
4755331Samw 		break;
4765331Samw 
4775331Samw 	default:
47811963SAfshin.Ardakani@Sun.COM 		status = ERROR_INVALID_LEVEL;
47911963SAfshin.Ardakani@Sun.COM 		break;
4805331Samw 	}
4815331Samw 
48211963SAfshin.Ardakani@Sun.COM 	dfs_info_free(&info);
48311963SAfshin.Ardakani@Sun.COM 
48411963SAfshin.Ardakani@Sun.COM getinfo_error:
48511963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
48611963SAfshin.Ardakani@Sun.COM 	dfs_path_free(&path);
48711963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS)
48811963SAfshin.Ardakani@Sun.COM 		bzero(param, sizeof (netdfs_getinfo_t));
48911963SAfshin.Ardakani@Sun.COM 
49011963SAfshin.Ardakani@Sun.COM 	param->info.level = level;
49111963SAfshin.Ardakani@Sun.COM 	param->status = status;
4928334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
4935331Samw }
4945331Samw 
4955331Samw /*
49611963SAfshin.Ardakani@Sun.COM  * Enumerates the DFS root hosted on a server or the DFS links of the
49711963SAfshin.Ardakani@Sun.COM  * namespace hosted by a server. Depending on the information level,
49811963SAfshin.Ardakani@Sun.COM  * the targets of the root and links are also displayed.
4995331Samw  *
50011963SAfshin.Ardakani@Sun.COM  * For unsupported levels, it should return ERROR_INVALID_LEVEL as
50111963SAfshin.Ardakani@Sun.COM  * Microsoft does for DFS server on Win2000 and NT.
50211963SAfshin.Ardakani@Sun.COM  *
50311963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsEnum (Opnum 5)
5045331Samw  */
5055331Samw /*ARGSUSED*/
5065331Samw static int
netdfs_s_enum(void * arg,ndr_xa_t * mxa)5078334SJose.Borrego@Sun.COM netdfs_s_enum(void *arg, ndr_xa_t *mxa)
5085331Samw {
50911963SAfshin.Ardakani@Sun.COM 	netdfs_enum_t *param = arg;
51011963SAfshin.Ardakani@Sun.COM 	netdfs_enumhandle_t de;
51111963SAfshin.Ardakani@Sun.COM 	uint32_t level = param->level;
51211963SAfshin.Ardakani@Sun.COM 	uint32_t status = ERROR_SUCCESS;
51311963SAfshin.Ardakani@Sun.COM 	uint32_t nroot;
51411963SAfshin.Ardakani@Sun.COM 	size_t entsize;
51511963SAfshin.Ardakani@Sun.COM 
51611963SAfshin.Ardakani@Sun.COM 	if (param->info == NULL) {
51711963SAfshin.Ardakani@Sun.COM 		status = ERROR_INVALID_PARAMETER;
51811963SAfshin.Ardakani@Sun.COM 		goto enum_error;
51911963SAfshin.Ardakani@Sun.COM 	}
52011963SAfshin.Ardakani@Sun.COM 
52111963SAfshin.Ardakani@Sun.COM 	if ((nroot = dfs_namespace_count()) == 0)
52211963SAfshin.Ardakani@Sun.COM 		status = ERROR_NOT_FOUND;
52311963SAfshin.Ardakani@Sun.COM 	else if (nroot > 1)
52411963SAfshin.Ardakani@Sun.COM 		status = ERROR_DEVICE_NOT_AVAILABLE;
52511963SAfshin.Ardakani@Sun.COM 
52611963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS)
52711963SAfshin.Ardakani@Sun.COM 		goto enum_error;
52811963SAfshin.Ardakani@Sun.COM 
52911963SAfshin.Ardakani@Sun.COM 	bzero(&de, sizeof (netdfs_enumhandle_t));
53011963SAfshin.Ardakani@Sun.COM 	de.de_level = level;
53111963SAfshin.Ardakani@Sun.COM 	de.de_ntotal = dfs_cache_num();
53211963SAfshin.Ardakani@Sun.COM 
53311963SAfshin.Ardakani@Sun.COM 	if (param->pref_max_len == NETDFS_MAXPREFLEN ||
53411963SAfshin.Ardakani@Sun.COM 	    param->pref_max_len > NETDFS_MAXBUFLEN)
53511963SAfshin.Ardakani@Sun.COM 		de.de_prefmaxlen = NETDFS_MAXBUFLEN;
53611963SAfshin.Ardakani@Sun.COM 	else
53711963SAfshin.Ardakani@Sun.COM 		de.de_prefmaxlen = param->pref_max_len;
53811963SAfshin.Ardakani@Sun.COM 
53911963SAfshin.Ardakani@Sun.COM 	de.de_bavail = de.de_prefmaxlen;
54011963SAfshin.Ardakani@Sun.COM 
54111963SAfshin.Ardakani@Sun.COM 	if (param->resume_handle != NULL) {
54211963SAfshin.Ardakani@Sun.COM 		if (*param->resume_handle >= de.de_ntotal) {
54311963SAfshin.Ardakani@Sun.COM 			status = ERROR_NO_MORE_ITEMS;
54411963SAfshin.Ardakani@Sun.COM 			goto enum_error;
54511963SAfshin.Ardakani@Sun.COM 		}
54611963SAfshin.Ardakani@Sun.COM 		de.de_resume = *param->resume_handle;
54711963SAfshin.Ardakani@Sun.COM 		de.de_nskip = de.de_resume;
54811963SAfshin.Ardakani@Sun.COM 		*param->resume_handle = 0;
54911963SAfshin.Ardakani@Sun.COM 	}
55011963SAfshin.Ardakani@Sun.COM 
55111963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
55211963SAfshin.Ardakani@Sun.COM 
55311963SAfshin.Ardakani@Sun.COM 	status = ERROR_NOT_ENOUGH_MEMORY;
55411963SAfshin.Ardakani@Sun.COM 
55511963SAfshin.Ardakani@Sun.COM 	switch (level) {
55611963SAfshin.Ardakani@Sun.COM 	case 1:
55711963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info1_t);
55811963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
55911963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info1_t, de.de_nmax);
56011963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
56111963SAfshin.Ardakani@Sun.COM 			goto enum_error;
56211963SAfshin.Ardakani@Sun.COM 
56311963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
56411963SAfshin.Ardakani@Sun.COM 			param->info->iu.info1->info1 = de.de_entries;
56511963SAfshin.Ardakani@Sun.COM 			param->info->iu.info1->count = de.de_nitems;
56611963SAfshin.Ardakani@Sun.COM 		}
56711963SAfshin.Ardakani@Sun.COM 		break;
56811963SAfshin.Ardakani@Sun.COM 	case 2:
56911963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info2_t);
57011963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
57111963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info2_t, de.de_nmax);
57211963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
57311963SAfshin.Ardakani@Sun.COM 			goto enum_error;
5745331Samw 
57511963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
57611963SAfshin.Ardakani@Sun.COM 			param->info->iu.info2->info2 = de.de_entries;
57711963SAfshin.Ardakani@Sun.COM 			param->info->iu.info2->count = de.de_nitems;
57811963SAfshin.Ardakani@Sun.COM 		}
57911963SAfshin.Ardakani@Sun.COM 		break;
5805331Samw 	case 3:
58111963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info3_t) +
58211963SAfshin.Ardakani@Sun.COM 		    sizeof (netdfs_storage_info_t);
58311963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
58411963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info3_t, de.de_nmax);
58511963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
58611963SAfshin.Ardakani@Sun.COM 			goto enum_error;
58711963SAfshin.Ardakani@Sun.COM 
58811963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
58911963SAfshin.Ardakani@Sun.COM 			param->info->iu.info3->info3 = de.de_entries;
59011963SAfshin.Ardakani@Sun.COM 			param->info->iu.info3->count = de.de_nitems;
59111963SAfshin.Ardakani@Sun.COM 		}
59211963SAfshin.Ardakani@Sun.COM 		break;
59311963SAfshin.Ardakani@Sun.COM 	case 4:
59411963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info4_t) +
59511963SAfshin.Ardakani@Sun.COM 		    sizeof (netdfs_storage_info_t);
59611963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
59711963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info4_t, de.de_nmax);
59811963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
59911963SAfshin.Ardakani@Sun.COM 			goto enum_error;
60011963SAfshin.Ardakani@Sun.COM 
60111963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
60211963SAfshin.Ardakani@Sun.COM 			param->info->iu.info4->info4 = de.de_entries;
60311963SAfshin.Ardakani@Sun.COM 			param->info->iu.info4->count = de.de_nitems;
60411963SAfshin.Ardakani@Sun.COM 		}
60511963SAfshin.Ardakani@Sun.COM 		break;
60611963SAfshin.Ardakani@Sun.COM 
60711963SAfshin.Ardakani@Sun.COM 	case 5:
60811963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info5_t);
60911963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
61011963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info5_t, de.de_nmax);
61111963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
61211963SAfshin.Ardakani@Sun.COM 			goto enum_error;
61311963SAfshin.Ardakani@Sun.COM 
61411963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
61511963SAfshin.Ardakani@Sun.COM 			param->info->iu.info5->info5 = de.de_entries;
61611963SAfshin.Ardakani@Sun.COM 			param->info->iu.info5->count = de.de_nitems;
61711963SAfshin.Ardakani@Sun.COM 		}
61811963SAfshin.Ardakani@Sun.COM 		break;
61911963SAfshin.Ardakani@Sun.COM 
62011963SAfshin.Ardakani@Sun.COM 	case 6:
62111963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info6_t) +
62211963SAfshin.Ardakani@Sun.COM 		    sizeof (netdfs_storage_info1_t);
62311963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
62411963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info6_t, de.de_nmax);
62511963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
62611963SAfshin.Ardakani@Sun.COM 			goto enum_error;
62711963SAfshin.Ardakani@Sun.COM 
62811963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
62911963SAfshin.Ardakani@Sun.COM 			param->info->iu.info6->info6 = de.de_entries;
63011963SAfshin.Ardakani@Sun.COM 			param->info->iu.info6->count = de.de_nitems;
63111963SAfshin.Ardakani@Sun.COM 		}
63211963SAfshin.Ardakani@Sun.COM 		break;
63311963SAfshin.Ardakani@Sun.COM 
63411963SAfshin.Ardakani@Sun.COM 	case 300:
63511963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info300_t);
63611963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
63711963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info300_t, de.de_nmax);
63811963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
63911963SAfshin.Ardakani@Sun.COM 			goto enum_error;
64011963SAfshin.Ardakani@Sun.COM 
64111963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
64211963SAfshin.Ardakani@Sun.COM 			param->info->iu.info300->info300 = de.de_entries;
64311963SAfshin.Ardakani@Sun.COM 			param->info->iu.info300->count = de.de_nitems;
64411963SAfshin.Ardakani@Sun.COM 		}
6455331Samw 		break;
6465331Samw 
6475331Samw 	default:
64811963SAfshin.Ardakani@Sun.COM 		status = ERROR_INVALID_PARAMETER;
64911963SAfshin.Ardakani@Sun.COM 		break;
6505331Samw 	}
6515331Samw 
65211963SAfshin.Ardakani@Sun.COM 	if ((status == ERROR_SUCCESS) && (param->resume_handle != NULL))
65311963SAfshin.Ardakani@Sun.COM 		*param->resume_handle = de.de_resume;
65411963SAfshin.Ardakani@Sun.COM 
65511963SAfshin.Ardakani@Sun.COM enum_error:
65611963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
65711963SAfshin.Ardakani@Sun.COM 	param->status = status;
6588334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
6595331Samw }
6605331Samw 
6615331Samw /*
66211963SAfshin.Ardakani@Sun.COM  * Renames or moves a DFS link
66311963SAfshin.Ardakani@Sun.COM  *
66411963SAfshin.Ardakani@Sun.COM  * Does not need to be supported for DFS version 1
66511963SAfshin.Ardakani@Sun.COM  *
66611963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsMove (Opnum 6)
6675331Samw  */
6685331Samw /*ARGSUSED*/
6695331Samw static int
netdfs_s_move(void * arg,ndr_xa_t * mxa)6708334SJose.Borrego@Sun.COM netdfs_s_move(void *arg, ndr_xa_t *mxa)
6715331Samw {
6725331Samw 	struct netdfs_move *param = arg;
6735331Samw 
67411963SAfshin.Ardakani@Sun.COM 	param->status = ERROR_NOT_SUPPORTED;
6758334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
6765331Samw }
6775331Samw 
6785331Samw /*
67911963SAfshin.Ardakani@Sun.COM  * According to [MS-DFSNM] spec this operation (opnum 7) is not
68011963SAfshin.Ardakani@Sun.COM  * used over the wire.
6815331Samw  */
6825331Samw /*ARGSUSED*/
6835331Samw static int
netdfs_s_rename(void * arg,ndr_xa_t * mxa)6848334SJose.Borrego@Sun.COM netdfs_s_rename(void *arg, ndr_xa_t *mxa)
6855331Samw {
6865331Samw 	struct netdfs_rename *param = arg;
6875331Samw 
68811963SAfshin.Ardakani@Sun.COM 	param->status = ERROR_NOT_SUPPORTED;
6898334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
6905331Samw }
6915331Samw 
6925331Samw /*
69311963SAfshin.Ardakani@Sun.COM  * Creates a new standalone DFS namespace
69411963SAfshin.Ardakani@Sun.COM  *
69511963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsAddStdRoot (Opnum 12)
6965331Samw  */
6975331Samw /*ARGSUSED*/
6985331Samw static int
netdfs_s_addstdroot(void * arg,ndr_xa_t * mxa)6998334SJose.Borrego@Sun.COM netdfs_s_addstdroot(void *arg, ndr_xa_t *mxa)
7005331Samw {
7015331Samw 	struct netdfs_addstdroot *param = arg;
70211963SAfshin.Ardakani@Sun.COM 	const char *share = (const char *)param->share;
70311963SAfshin.Ardakani@Sun.COM 	const char *comment = (const char *)param->comment;
7045331Samw 
70511963SAfshin.Ardakani@Sun.COM 	if (!ndr_is_admin(mxa)) {
70611963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
70711963SAfshin.Ardakani@Sun.COM 		return (NDR_DRC_OK);
70811963SAfshin.Ardakani@Sun.COM 	}
70911963SAfshin.Ardakani@Sun.COM 
71011963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
71111963SAfshin.Ardakani@Sun.COM 	/* For now only allow a single standalone namespace */
712*12890SJoyce.McIntosh@Sun.COM 	if (dfs_namespace_count() == 0)
71311963SAfshin.Ardakani@Sun.COM 		param->status = dfs_namespace_add(share, comment);
714*12890SJoyce.McIntosh@Sun.COM 	else
71511963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_NOT_SUPPORTED;
716*12890SJoyce.McIntosh@Sun.COM 	dfs_setpriv(PRIV_OFF);
71711963SAfshin.Ardakani@Sun.COM 
7188334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
7195331Samw }
7205331Samw 
7215331Samw /*
72211963SAfshin.Ardakani@Sun.COM  * Deletes the specified stand-alone DFS namespace. The DFS namespace can be
72311963SAfshin.Ardakani@Sun.COM  * removed without first removing all of the links in it.
72411963SAfshin.Ardakani@Sun.COM  *
72511963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsRemoveStdRoot (Opnum 13)
7265331Samw  */
7275331Samw /*ARGSUSED*/
7285331Samw static int
netdfs_s_remstdroot(void * arg,ndr_xa_t * mxa)7298334SJose.Borrego@Sun.COM netdfs_s_remstdroot(void *arg, ndr_xa_t *mxa)
7305331Samw {
7315331Samw 	struct netdfs_remstdroot *param = arg;
73211963SAfshin.Ardakani@Sun.COM 	const char *share = (const char *)param->share;
7335331Samw 
73411963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
73511963SAfshin.Ardakani@Sun.COM 
736*12890SJoyce.McIntosh@Sun.COM 	if (ndr_is_admin(mxa))
73711963SAfshin.Ardakani@Sun.COM 		param->status = dfs_namespace_remove(share);
738*12890SJoyce.McIntosh@Sun.COM 	else
73911963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
74011963SAfshin.Ardakani@Sun.COM 
74111963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
7428334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
7435331Samw }
7445331Samw 
7455331Samw /*
74611963SAfshin.Ardakani@Sun.COM  * Enumerates the DFS roots hosted on a server, or DFS links of a namespace
74711963SAfshin.Ardakani@Sun.COM  * hosted by the server. Depending on the information level, the targets
74811963SAfshin.Ardakani@Sun.COM  * associated with the roots and links are also displayed
7495331Samw  *
75011963SAfshin.Ardakani@Sun.COM  * Does not need to be supported for DFS version 1
75111963SAfshin.Ardakani@Sun.COM  *
75211963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM] NetrDfsEnumEx (Opnum 21)
7535331Samw  */
75411963SAfshin.Ardakani@Sun.COM /*ARGSUSED*/
7555331Samw static int
netdfs_s_enumex(void * arg,ndr_xa_t * mxa)7568334SJose.Borrego@Sun.COM netdfs_s_enumex(void *arg, ndr_xa_t *mxa)
7575331Samw {
7585331Samw 	struct netdfs_enumex *param = arg;
7595331Samw 
7605331Samw 	bzero(param->info, sizeof (struct netdfs_enumex));
76111963SAfshin.Ardakani@Sun.COM 	param->status = ERROR_NOT_SUPPORTED;
7628334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
7635331Samw }
7645331Samw 
7655331Samw /*
76611963SAfshin.Ardakani@Sun.COM  * Sets the comment for the DFS link/root.
76711963SAfshin.Ardakani@Sun.COM  */
76811963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_setinfo_100(dfs_path_t * path,netdfs_info100_t * netinfo)76911963SAfshin.Ardakani@Sun.COM netdfs_setinfo_100(dfs_path_t *path, netdfs_info100_t *netinfo)
77011963SAfshin.Ardakani@Sun.COM {
77111963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
77211963SAfshin.Ardakani@Sun.COM 	uint32_t status;
77311963SAfshin.Ardakani@Sun.COM 	char *cmnt = (char *)netinfo->comment;
77411963SAfshin.Ardakani@Sun.COM 
77511963SAfshin.Ardakani@Sun.COM 	bzero(&info, sizeof (dfs_info_t));
77611963SAfshin.Ardakani@Sun.COM 	if (cmnt != NULL)
77711963SAfshin.Ardakani@Sun.COM 		(void) strlcpy(info.i_comment, cmnt, sizeof (info.i_comment));
77811963SAfshin.Ardakani@Sun.COM 
77911963SAfshin.Ardakani@Sun.COM 	if (path->p_type == DFS_OBJECT_LINK)
78011963SAfshin.Ardakani@Sun.COM 		status = dfs_link_setinfo(path->p_fspath, &info, 100);
78111963SAfshin.Ardakani@Sun.COM 	else
78211963SAfshin.Ardakani@Sun.COM 		status = dfs_root_setinfo(path->p_fspath, &info, 100);
78311963SAfshin.Ardakani@Sun.COM 
78411963SAfshin.Ardakani@Sun.COM 	return (status);
78511963SAfshin.Ardakani@Sun.COM }
78611963SAfshin.Ardakani@Sun.COM 
78711963SAfshin.Ardakani@Sun.COM /*
78811963SAfshin.Ardakani@Sun.COM  * Sets the state for the DFS root/link or its target.
78911963SAfshin.Ardakani@Sun.COM  */
79011963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_setinfo_101(dfs_path_t * path,netdfs_info101_t * netinfo,const char * t_server,const char * t_share)79111963SAfshin.Ardakani@Sun.COM netdfs_setinfo_101(dfs_path_t *path, netdfs_info101_t *netinfo,
79211963SAfshin.Ardakani@Sun.COM     const char *t_server, const char *t_share)
79311963SAfshin.Ardakani@Sun.COM {
79411963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
79511963SAfshin.Ardakani@Sun.COM 	dfs_target_t target;
79611963SAfshin.Ardakani@Sun.COM 	uint32_t status;
79711963SAfshin.Ardakani@Sun.COM 
79811963SAfshin.Ardakani@Sun.COM 	bzero(&info, sizeof (dfs_info_t));
79911963SAfshin.Ardakani@Sun.COM 	bzero(&target, sizeof (dfs_target_t));
80011963SAfshin.Ardakani@Sun.COM 
80111963SAfshin.Ardakani@Sun.COM 	if (t_server == NULL && t_share == NULL) {
80211963SAfshin.Ardakani@Sun.COM 		info.i_state = netinfo->state;
80311963SAfshin.Ardakani@Sun.COM 	} else {
80411963SAfshin.Ardakani@Sun.COM 		target.t_state = netinfo->state;
80511963SAfshin.Ardakani@Sun.COM 		(void) strlcpy(target.t_server, t_server,
80611963SAfshin.Ardakani@Sun.COM 		    sizeof (target.t_server));
80711963SAfshin.Ardakani@Sun.COM 		(void) strlcpy(target.t_share, t_share,
80811963SAfshin.Ardakani@Sun.COM 		    sizeof (target.t_share));
80911963SAfshin.Ardakani@Sun.COM 		info.i_targets = &target;
81011963SAfshin.Ardakani@Sun.COM 	}
81111963SAfshin.Ardakani@Sun.COM 
81211963SAfshin.Ardakani@Sun.COM 	if (path->p_type == DFS_OBJECT_LINK)
81311963SAfshin.Ardakani@Sun.COM 		status = dfs_link_setinfo(path->p_fspath, &info, 101);
81411963SAfshin.Ardakani@Sun.COM 	else
81511963SAfshin.Ardakani@Sun.COM 		status = dfs_root_setinfo(path->p_fspath, &info, 101);
81611963SAfshin.Ardakani@Sun.COM 
81711963SAfshin.Ardakani@Sun.COM 	return (status);
81811963SAfshin.Ardakani@Sun.COM }
81911963SAfshin.Ardakani@Sun.COM 
82011963SAfshin.Ardakani@Sun.COM /*
82111963SAfshin.Ardakani@Sun.COM  * Sets the timeout value of the DFS link/root.
82211963SAfshin.Ardakani@Sun.COM  */
82311963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_setinfo_102(dfs_path_t * path,netdfs_info102_t * netinfo)82411963SAfshin.Ardakani@Sun.COM netdfs_setinfo_102(dfs_path_t *path, netdfs_info102_t *netinfo)
82511963SAfshin.Ardakani@Sun.COM {
82611963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
82711963SAfshin.Ardakani@Sun.COM 	uint32_t status;
82811963SAfshin.Ardakani@Sun.COM 
82911963SAfshin.Ardakani@Sun.COM 	bzero(&info, sizeof (dfs_info_t));
83011963SAfshin.Ardakani@Sun.COM 	info.i_timeout = netinfo->timeout;
83111963SAfshin.Ardakani@Sun.COM 
83211963SAfshin.Ardakani@Sun.COM 	if (path->p_type == DFS_OBJECT_LINK)
83311963SAfshin.Ardakani@Sun.COM 		status = dfs_link_setinfo(path->p_fspath, &info, 102);
83411963SAfshin.Ardakani@Sun.COM 	else
83511963SAfshin.Ardakani@Sun.COM 		status = dfs_root_setinfo(path->p_fspath, &info, 102);
83611963SAfshin.Ardakani@Sun.COM 
83711963SAfshin.Ardakani@Sun.COM 	return (status);
83811963SAfshin.Ardakani@Sun.COM }
83911963SAfshin.Ardakani@Sun.COM 
84011963SAfshin.Ardakani@Sun.COM /*
84111963SAfshin.Ardakani@Sun.COM  * Sets the property flags for the root or link.
84211963SAfshin.Ardakani@Sun.COM  */
84311963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_setinfo_103(dfs_path_t * path,netdfs_info103_t * netinfo)84411963SAfshin.Ardakani@Sun.COM netdfs_setinfo_103(dfs_path_t *path, netdfs_info103_t *netinfo)
84511963SAfshin.Ardakani@Sun.COM {
84611963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
84711963SAfshin.Ardakani@Sun.COM 	uint32_t status;
84811963SAfshin.Ardakani@Sun.COM 
84911963SAfshin.Ardakani@Sun.COM 	bzero(&info, sizeof (dfs_info_t));
85011963SAfshin.Ardakani@Sun.COM 	info.i_propflags =
85111963SAfshin.Ardakani@Sun.COM 	    netinfo->property_flags & netinfo->property_flag_mask;
85211963SAfshin.Ardakani@Sun.COM 
85311963SAfshin.Ardakani@Sun.COM 	if (path->p_type == DFS_OBJECT_LINK)
85411963SAfshin.Ardakani@Sun.COM 		status = dfs_link_setinfo(path->p_fspath, &info, 103);
85511963SAfshin.Ardakani@Sun.COM 	else
85611963SAfshin.Ardakani@Sun.COM 		status = dfs_root_setinfo(path->p_fspath, &info, 103);
85711963SAfshin.Ardakani@Sun.COM 
85811963SAfshin.Ardakani@Sun.COM 	return (status);
85911963SAfshin.Ardakani@Sun.COM }
86011963SAfshin.Ardakani@Sun.COM 
86111963SAfshin.Ardakani@Sun.COM /*
86211963SAfshin.Ardakani@Sun.COM  * Sets the target priority rank and class for the root target or link target
86311963SAfshin.Ardakani@Sun.COM  */
86411963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_setinfo_104(dfs_path_t * path,netdfs_info104_t * netinfo,const char * t_server,const char * t_share)86511963SAfshin.Ardakani@Sun.COM netdfs_setinfo_104(dfs_path_t *path, netdfs_info104_t *netinfo,
86611963SAfshin.Ardakani@Sun.COM     const char *t_server, const char *t_share)
86711963SAfshin.Ardakani@Sun.COM {
86811963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
86911963SAfshin.Ardakani@Sun.COM 	dfs_target_t target;
87011963SAfshin.Ardakani@Sun.COM 	uint32_t status;
87111963SAfshin.Ardakani@Sun.COM 
87211963SAfshin.Ardakani@Sun.COM 	if ((t_server == NULL) || (t_share == NULL))
87311963SAfshin.Ardakani@Sun.COM 		return (ERROR_INVALID_PARAMETER);
87411963SAfshin.Ardakani@Sun.COM 
875*12890SJoyce.McIntosh@Sun.COM 	if (netinfo->priority_class > DfsGlobalLowPriorityClass)
876*12890SJoyce.McIntosh@Sun.COM 		return (ERROR_INVALID_PARAMETER);
877*12890SJoyce.McIntosh@Sun.COM 
878*12890SJoyce.McIntosh@Sun.COM 	if (netinfo->priority_rank > DFS_PRIORITY_RANK_MAX)
879*12890SJoyce.McIntosh@Sun.COM 		return (ERROR_INVALID_PARAMETER);
880*12890SJoyce.McIntosh@Sun.COM 
88111963SAfshin.Ardakani@Sun.COM 	bzero(&info, sizeof (dfs_info_t));
88211963SAfshin.Ardakani@Sun.COM 	bzero(&target, sizeof (dfs_target_t));
88311963SAfshin.Ardakani@Sun.COM 
88411963SAfshin.Ardakani@Sun.COM 	target.t_priority.p_class = netinfo->priority_class;
88511963SAfshin.Ardakani@Sun.COM 	target.t_priority.p_rank = netinfo->priority_rank;
88611963SAfshin.Ardakani@Sun.COM 	(void) strlcpy(target.t_server, t_server, sizeof (target.t_server));
88711963SAfshin.Ardakani@Sun.COM 	(void) strlcpy(target.t_share, t_share, sizeof (target.t_share));
88811963SAfshin.Ardakani@Sun.COM 	info.i_targets = &target;
88911963SAfshin.Ardakani@Sun.COM 
89011963SAfshin.Ardakani@Sun.COM 	if (path->p_type == DFS_OBJECT_LINK)
89111963SAfshin.Ardakani@Sun.COM 		status = dfs_link_setinfo(path->p_fspath, &info, 104);
89211963SAfshin.Ardakani@Sun.COM 	else
89311963SAfshin.Ardakani@Sun.COM 		status = dfs_root_setinfo(path->p_fspath, &info, 104);
89411963SAfshin.Ardakani@Sun.COM 
89511963SAfshin.Ardakani@Sun.COM 	return (status);
89611963SAfshin.Ardakani@Sun.COM }
89711963SAfshin.Ardakani@Sun.COM 
89811963SAfshin.Ardakani@Sun.COM /*
89911963SAfshin.Ardakani@Sun.COM  * Sets the comment, state, time-out information, and property flags for the
90011963SAfshin.Ardakani@Sun.COM  * namespace root or link specified in DfsInfo. Does not apply to a root target
90111963SAfshin.Ardakani@Sun.COM  * or link target.
90211963SAfshin.Ardakani@Sun.COM  */
90311963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_setinfo_105(dfs_path_t * path,netdfs_info105_t * netinfo)90411963SAfshin.Ardakani@Sun.COM netdfs_setinfo_105(dfs_path_t *path, netdfs_info105_t *netinfo)
90511963SAfshin.Ardakani@Sun.COM {
90611963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
907*12890SJoyce.McIntosh@Sun.COM 	uint32_t status, flavor;
90811963SAfshin.Ardakani@Sun.COM 	char *cmnt = (char *)netinfo->comment;
90911963SAfshin.Ardakani@Sun.COM 
91011963SAfshin.Ardakani@Sun.COM 	bzero(&info, sizeof (dfs_info_t));
91111963SAfshin.Ardakani@Sun.COM 
912*12890SJoyce.McIntosh@Sun.COM 	flavor = dfs_namespace_getflavor(path->p_unc.unc_share);
913*12890SJoyce.McIntosh@Sun.COM 	if (flavor == 0)
914*12890SJoyce.McIntosh@Sun.COM 		return (ERROR_INTERNAL_ERROR);
915*12890SJoyce.McIntosh@Sun.COM 	info.i_flavor = flavor;
916*12890SJoyce.McIntosh@Sun.COM 
91711963SAfshin.Ardakani@Sun.COM 	if (cmnt != NULL)
91811963SAfshin.Ardakani@Sun.COM 		(void) strlcpy(info.i_comment, cmnt, sizeof (info.i_comment));
91911963SAfshin.Ardakani@Sun.COM 	info.i_state = netinfo->state;
92011963SAfshin.Ardakani@Sun.COM 	info.i_timeout = netinfo->timeout;
921*12890SJoyce.McIntosh@Sun.COM 	info.i_propflag_mask = netinfo->property_flag_mask;
92211963SAfshin.Ardakani@Sun.COM 	info.i_propflags =
92311963SAfshin.Ardakani@Sun.COM 	    netinfo->property_flags & netinfo->property_flag_mask;
92411963SAfshin.Ardakani@Sun.COM 
92511963SAfshin.Ardakani@Sun.COM 	if (path->p_type == DFS_OBJECT_LINK)
92611963SAfshin.Ardakani@Sun.COM 		status = dfs_link_setinfo(path->p_fspath, &info, 105);
92711963SAfshin.Ardakani@Sun.COM 	else
92811963SAfshin.Ardakani@Sun.COM 		status = dfs_root_setinfo(path->p_fspath, &info, 105);
92911963SAfshin.Ardakani@Sun.COM 
93011963SAfshin.Ardakani@Sun.COM 	return (status);
93111963SAfshin.Ardakani@Sun.COM }
93211963SAfshin.Ardakani@Sun.COM 
93311963SAfshin.Ardakani@Sun.COM /*
93411963SAfshin.Ardakani@Sun.COM  * DFS_STORAGE_INFO: target information
93511963SAfshin.Ardakani@Sun.COM  */
93611963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_info_storage(netdfs_storage_info_t ** sinfo,dfs_info_t * info,ndr_xa_t * mxa,uint32_t * size)93711963SAfshin.Ardakani@Sun.COM netdfs_info_storage(netdfs_storage_info_t **sinfo, dfs_info_t *info,
93811963SAfshin.Ardakani@Sun.COM     ndr_xa_t *mxa, uint32_t *size)
93911963SAfshin.Ardakani@Sun.COM {
94011963SAfshin.Ardakani@Sun.COM 	netdfs_storage_info_t *storage;
94111963SAfshin.Ardakani@Sun.COM 	dfs_target_t *target;
94211963SAfshin.Ardakani@Sun.COM 	int i;
94311963SAfshin.Ardakani@Sun.COM 
94411963SAfshin.Ardakani@Sun.COM 	*sinfo = NULL;
94511963SAfshin.Ardakani@Sun.COM 	if (info->i_ntargets == 0)
94611963SAfshin.Ardakani@Sun.COM 		return (ERROR_SUCCESS);
94711963SAfshin.Ardakani@Sun.COM 
94811963SAfshin.Ardakani@Sun.COM 	*sinfo = NDR_NEWN(mxa, netdfs_storage_info_t, info->i_ntargets);
94911963SAfshin.Ardakani@Sun.COM 	if (*sinfo == NULL)
95011963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
95111963SAfshin.Ardakani@Sun.COM 
95211963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
95311963SAfshin.Ardakani@Sun.COM 		*size += info->i_ntargets * sizeof (netdfs_storage_info_t);
95411963SAfshin.Ardakani@Sun.COM 
95511963SAfshin.Ardakani@Sun.COM 	target = info->i_targets;
95611963SAfshin.Ardakani@Sun.COM 	storage = *sinfo;
95711963SAfshin.Ardakani@Sun.COM 	for (i = 0; i < info->i_ntargets; i++, target++, storage++) {
95811963SAfshin.Ardakani@Sun.COM 		storage->state = target->t_state;
95911963SAfshin.Ardakani@Sun.COM 		storage->server = NDR_STRDUP(mxa, target->t_server);
96011963SAfshin.Ardakani@Sun.COM 		storage->share = NDR_STRDUP(mxa, target->t_share);
96111963SAfshin.Ardakani@Sun.COM 
96211963SAfshin.Ardakani@Sun.COM 		if (storage->server == NULL || storage->share == NULL)
96311963SAfshin.Ardakani@Sun.COM 			return (ERROR_NOT_ENOUGH_MEMORY);
96411963SAfshin.Ardakani@Sun.COM 
96511963SAfshin.Ardakani@Sun.COM 		if (size != NULL)
96611963SAfshin.Ardakani@Sun.COM 			*size += smb_wcequiv_strlen(target->t_server) +
96711963SAfshin.Ardakani@Sun.COM 			    smb_wcequiv_strlen(target->t_share);
96811963SAfshin.Ardakani@Sun.COM 	}
96911963SAfshin.Ardakani@Sun.COM 
97011963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
97111963SAfshin.Ardakani@Sun.COM }
97211963SAfshin.Ardakani@Sun.COM 
97311963SAfshin.Ardakani@Sun.COM /*
97411963SAfshin.Ardakani@Sun.COM  * DFS_STORAGE_INFO_1: target information
97511963SAfshin.Ardakani@Sun.COM  */
97611963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_info_storage1(netdfs_storage_info1_t ** sinfo,dfs_info_t * info,ndr_xa_t * mxa,uint32_t * size)97711963SAfshin.Ardakani@Sun.COM netdfs_info_storage1(netdfs_storage_info1_t **sinfo, dfs_info_t *info,
97811963SAfshin.Ardakani@Sun.COM     ndr_xa_t *mxa, uint32_t *size)
97911963SAfshin.Ardakani@Sun.COM {
98011963SAfshin.Ardakani@Sun.COM 	netdfs_storage_info1_t *storage;
98111963SAfshin.Ardakani@Sun.COM 	dfs_target_t *target;
98211963SAfshin.Ardakani@Sun.COM 	int i;
98311963SAfshin.Ardakani@Sun.COM 
98411963SAfshin.Ardakani@Sun.COM 	*sinfo = NULL;
98511963SAfshin.Ardakani@Sun.COM 	if (info->i_ntargets == 0)
98611963SAfshin.Ardakani@Sun.COM 		return (ERROR_SUCCESS);
98711963SAfshin.Ardakani@Sun.COM 
98811963SAfshin.Ardakani@Sun.COM 	*sinfo = NDR_NEWN(mxa, netdfs_storage_info1_t, info->i_ntargets);
98911963SAfshin.Ardakani@Sun.COM 	if (*sinfo == NULL)
99011963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
99111963SAfshin.Ardakani@Sun.COM 
99211963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
99311963SAfshin.Ardakani@Sun.COM 		*size += info->i_ntargets * sizeof (netdfs_storage_info1_t);
99411963SAfshin.Ardakani@Sun.COM 
99511963SAfshin.Ardakani@Sun.COM 	target = info->i_targets;
99611963SAfshin.Ardakani@Sun.COM 	storage = *sinfo;
99711963SAfshin.Ardakani@Sun.COM 	for (i = 0; i < info->i_ntargets; i++, target++, storage++) {
99811963SAfshin.Ardakani@Sun.COM 		storage->state = target->t_state;
99911963SAfshin.Ardakani@Sun.COM 		storage->server = NDR_STRDUP(mxa, target->t_server);
100011963SAfshin.Ardakani@Sun.COM 		storage->share = NDR_STRDUP(mxa, target->t_share);
100111963SAfshin.Ardakani@Sun.COM 		storage->p_class = target->t_priority.p_class;
100211963SAfshin.Ardakani@Sun.COM 		storage->p_rank = target->t_priority.p_rank;
100311963SAfshin.Ardakani@Sun.COM 		storage->p_reserved = 0;
100411963SAfshin.Ardakani@Sun.COM 
100511963SAfshin.Ardakani@Sun.COM 		if (storage->server == NULL || storage->share == NULL)
100611963SAfshin.Ardakani@Sun.COM 			return (ERROR_NOT_ENOUGH_MEMORY);
100711963SAfshin.Ardakani@Sun.COM 
100811963SAfshin.Ardakani@Sun.COM 		if (size != NULL)
100911963SAfshin.Ardakani@Sun.COM 			*size += smb_wcequiv_strlen(target->t_server) +
101011963SAfshin.Ardakani@Sun.COM 			    smb_wcequiv_strlen(target->t_share);
101111963SAfshin.Ardakani@Sun.COM 	}
101211963SAfshin.Ardakani@Sun.COM 
101311963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
101411963SAfshin.Ardakani@Sun.COM }
101511963SAfshin.Ardakani@Sun.COM 
101611963SAfshin.Ardakani@Sun.COM /*
101711963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_1 for get/enum response
101811963SAfshin.Ardakani@Sun.COM  */
101911963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_info_1(netdfs_info1_t * info1,dfs_info_t * info,ndr_xa_t * mxa,uint32_t * size)102011963SAfshin.Ardakani@Sun.COM netdfs_info_1(netdfs_info1_t *info1, dfs_info_t *info, ndr_xa_t *mxa,
102111963SAfshin.Ardakani@Sun.COM     uint32_t *size)
102211963SAfshin.Ardakani@Sun.COM {
102311963SAfshin.Ardakani@Sun.COM 	info1->entry_path = NDR_STRDUP(mxa, info->i_uncpath);
102411963SAfshin.Ardakani@Sun.COM 	if (info1->entry_path == NULL)
102511963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
102611963SAfshin.Ardakani@Sun.COM 
102711963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
102811963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info1_t) +
102911963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath);
103011963SAfshin.Ardakani@Sun.COM 
103111963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
103211963SAfshin.Ardakani@Sun.COM }
103311963SAfshin.Ardakani@Sun.COM 
103411963SAfshin.Ardakani@Sun.COM /*
103511963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_2 for get/enum response
103611963SAfshin.Ardakani@Sun.COM  */
103711963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_info_2(netdfs_info2_t * info2,dfs_info_t * info,ndr_xa_t * mxa,uint32_t * size)103811963SAfshin.Ardakani@Sun.COM netdfs_info_2(netdfs_info2_t *info2, dfs_info_t *info, ndr_xa_t *mxa,
103911963SAfshin.Ardakani@Sun.COM     uint32_t *size)
104011963SAfshin.Ardakani@Sun.COM {
104111963SAfshin.Ardakani@Sun.COM 	void *entry_path;
104211963SAfshin.Ardakani@Sun.COM 	void *comment;
104311963SAfshin.Ardakani@Sun.COM 
104411963SAfshin.Ardakani@Sun.COM 	entry_path = NDR_STRDUP(mxa, info->i_uncpath);
104511963SAfshin.Ardakani@Sun.COM 	comment = NDR_STRDUP(mxa, info->i_comment);
104611963SAfshin.Ardakani@Sun.COM 
104711963SAfshin.Ardakani@Sun.COM 	if (entry_path == NULL || comment == NULL)
104811963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
104911963SAfshin.Ardakani@Sun.COM 
105011963SAfshin.Ardakani@Sun.COM 	info2->entry_path = entry_path;
105111963SAfshin.Ardakani@Sun.COM 	info2->comment = comment;
105211963SAfshin.Ardakani@Sun.COM 	info2->state = info->i_state;
105311963SAfshin.Ardakani@Sun.COM 	info2->n_store = info->i_ntargets;
105411963SAfshin.Ardakani@Sun.COM 
105511963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
105611963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info2_t) +
105711963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath) +
105811963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_comment);
105911963SAfshin.Ardakani@Sun.COM 
106011963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
106111963SAfshin.Ardakani@Sun.COM }
106211963SAfshin.Ardakani@Sun.COM 
106311963SAfshin.Ardakani@Sun.COM /*
106411963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_3 for get/enum response
106511963SAfshin.Ardakani@Sun.COM  */
106611963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_info_3(netdfs_info3_t * info3,dfs_info_t * info,ndr_xa_t * mxa,uint32_t * size)106711963SAfshin.Ardakani@Sun.COM netdfs_info_3(netdfs_info3_t *info3, dfs_info_t *info, ndr_xa_t *mxa,
106811963SAfshin.Ardakani@Sun.COM     uint32_t *size)
106911963SAfshin.Ardakani@Sun.COM {
107011963SAfshin.Ardakani@Sun.COM 	void *entry_path;
107111963SAfshin.Ardakani@Sun.COM 	void *comment;
107211963SAfshin.Ardakani@Sun.COM 
107311963SAfshin.Ardakani@Sun.COM 	entry_path = NDR_STRDUP(mxa, info->i_uncpath);
107411963SAfshin.Ardakani@Sun.COM 	comment = NDR_STRDUP(mxa, info->i_comment);
107511963SAfshin.Ardakani@Sun.COM 
107611963SAfshin.Ardakani@Sun.COM 	if (entry_path == NULL || comment == NULL)
107711963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
107811963SAfshin.Ardakani@Sun.COM 
107911963SAfshin.Ardakani@Sun.COM 	info3->entry_path = entry_path;
108011963SAfshin.Ardakani@Sun.COM 	info3->comment = comment;
108111963SAfshin.Ardakani@Sun.COM 	info3->state = info->i_state;
108211963SAfshin.Ardakani@Sun.COM 	info3->n_store = info->i_ntargets;
108311963SAfshin.Ardakani@Sun.COM 
108411963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
108511963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info3_t) +
108611963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath) +
108711963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_comment);
108811963SAfshin.Ardakani@Sun.COM 
108911963SAfshin.Ardakani@Sun.COM 	return (netdfs_info_storage(&info3->si, info, mxa, size));
109011963SAfshin.Ardakani@Sun.COM }
109111963SAfshin.Ardakani@Sun.COM 
109211963SAfshin.Ardakani@Sun.COM /*
109311963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_4 for get/enum response
109411963SAfshin.Ardakani@Sun.COM  */
109511963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_info_4(netdfs_info4_t * info4,dfs_info_t * info,ndr_xa_t * mxa,uint32_t * size)109611963SAfshin.Ardakani@Sun.COM netdfs_info_4(netdfs_info4_t *info4, dfs_info_t *info, ndr_xa_t *mxa,
109711963SAfshin.Ardakani@Sun.COM     uint32_t *size)
109811963SAfshin.Ardakani@Sun.COM {
109911963SAfshin.Ardakani@Sun.COM 	void *entry_path;
110011963SAfshin.Ardakani@Sun.COM 	void *comment;
110111963SAfshin.Ardakani@Sun.COM 
110211963SAfshin.Ardakani@Sun.COM 	entry_path = NDR_STRDUP(mxa, info->i_uncpath);
110311963SAfshin.Ardakani@Sun.COM 	comment = NDR_STRDUP(mxa, info->i_comment);
110411963SAfshin.Ardakani@Sun.COM 
110511963SAfshin.Ardakani@Sun.COM 	if (entry_path == NULL || comment == NULL)
110611963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
110711963SAfshin.Ardakani@Sun.COM 
110811963SAfshin.Ardakani@Sun.COM 	if (!netdfs_guid_fromstr(info->i_guid, &info4->guid))
110911963SAfshin.Ardakani@Sun.COM 		return (ERROR_INVALID_DATA);
111011963SAfshin.Ardakani@Sun.COM 
111111963SAfshin.Ardakani@Sun.COM 	info4->entry_path = entry_path;
111211963SAfshin.Ardakani@Sun.COM 	info4->comment = comment;
111311963SAfshin.Ardakani@Sun.COM 	info4->state = info->i_state;
111411963SAfshin.Ardakani@Sun.COM 	info4->timeout = info->i_timeout;
111511963SAfshin.Ardakani@Sun.COM 	info4->n_store = info->i_ntargets;
111611963SAfshin.Ardakani@Sun.COM 
111711963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
111811963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info4_t) +
111911963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath) +
112011963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_comment);
112111963SAfshin.Ardakani@Sun.COM 
112211963SAfshin.Ardakani@Sun.COM 	return (netdfs_info_storage(&info4->si, info, mxa, size));
112311963SAfshin.Ardakani@Sun.COM }
112411963SAfshin.Ardakani@Sun.COM 
112511963SAfshin.Ardakani@Sun.COM /*
112611963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_5 for get/enum response
112711963SAfshin.Ardakani@Sun.COM  */
112811963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_info_5(netdfs_info5_t * info5,dfs_info_t * info,ndr_xa_t * mxa,uint32_t * size)112911963SAfshin.Ardakani@Sun.COM netdfs_info_5(netdfs_info5_t *info5, dfs_info_t *info, ndr_xa_t *mxa,
113011963SAfshin.Ardakani@Sun.COM     uint32_t *size)
113111963SAfshin.Ardakani@Sun.COM {
113211963SAfshin.Ardakani@Sun.COM 	void *entry_path;
113311963SAfshin.Ardakani@Sun.COM 	void *comment;
113411963SAfshin.Ardakani@Sun.COM 
113511963SAfshin.Ardakani@Sun.COM 	entry_path = NDR_STRDUP(mxa, info->i_uncpath);
113611963SAfshin.Ardakani@Sun.COM 	comment = NDR_STRDUP(mxa, info->i_comment);
113711963SAfshin.Ardakani@Sun.COM 
113811963SAfshin.Ardakani@Sun.COM 	if (entry_path == NULL || comment == NULL)
113911963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
114011963SAfshin.Ardakani@Sun.COM 
114111963SAfshin.Ardakani@Sun.COM 	if (!netdfs_guid_fromstr(info->i_guid, &info5->guid))
114211963SAfshin.Ardakani@Sun.COM 		return (ERROR_INVALID_DATA);
114311963SAfshin.Ardakani@Sun.COM 
114411963SAfshin.Ardakani@Sun.COM 	info5->entry_path = entry_path;
114511963SAfshin.Ardakani@Sun.COM 	info5->comment = comment;
114611963SAfshin.Ardakani@Sun.COM 	info5->state = info->i_state;
114711963SAfshin.Ardakani@Sun.COM 	info5->timeout = info->i_timeout;
114811963SAfshin.Ardakani@Sun.COM 	info5->flags = info->i_propflags;
114911963SAfshin.Ardakani@Sun.COM 	info5->metadata_sz = 0;
115011963SAfshin.Ardakani@Sun.COM 	info5->n_store = info->i_ntargets;
115111963SAfshin.Ardakani@Sun.COM 
115211963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
115311963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info5_t) +
115411963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath) +
115511963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_comment);
115611963SAfshin.Ardakani@Sun.COM 
115711963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
115811963SAfshin.Ardakani@Sun.COM }
115911963SAfshin.Ardakani@Sun.COM 
116011963SAfshin.Ardakani@Sun.COM /*
116111963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_6 for get/enum response
116211963SAfshin.Ardakani@Sun.COM  */
116311963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_info_6(netdfs_info6_t * info6,dfs_info_t * info,ndr_xa_t * mxa,uint32_t * size)116411963SAfshin.Ardakani@Sun.COM netdfs_info_6(netdfs_info6_t *info6, dfs_info_t *info, ndr_xa_t *mxa,
116511963SAfshin.Ardakani@Sun.COM     uint32_t *size)
116611963SAfshin.Ardakani@Sun.COM {
116711963SAfshin.Ardakani@Sun.COM 	void *entry_path;
116811963SAfshin.Ardakani@Sun.COM 	void *comment;
116911963SAfshin.Ardakani@Sun.COM 
117011963SAfshin.Ardakani@Sun.COM 	entry_path = NDR_STRDUP(mxa, info->i_uncpath);
117111963SAfshin.Ardakani@Sun.COM 	comment = NDR_STRDUP(mxa, info->i_comment);
117211963SAfshin.Ardakani@Sun.COM 
117311963SAfshin.Ardakani@Sun.COM 	if (entry_path == NULL || comment == NULL)
117411963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
117511963SAfshin.Ardakani@Sun.COM 
117611963SAfshin.Ardakani@Sun.COM 	if (!netdfs_guid_fromstr(info->i_guid, &info6->guid))
117711963SAfshin.Ardakani@Sun.COM 		return (ERROR_INVALID_DATA);
117811963SAfshin.Ardakani@Sun.COM 
117911963SAfshin.Ardakani@Sun.COM 	info6->entry_path = entry_path;
118011963SAfshin.Ardakani@Sun.COM 	info6->comment = comment;
118111963SAfshin.Ardakani@Sun.COM 	info6->state = info->i_state;
118211963SAfshin.Ardakani@Sun.COM 	info6->timeout = info->i_timeout;
118311963SAfshin.Ardakani@Sun.COM 	info6->flags = info->i_propflags;
118411963SAfshin.Ardakani@Sun.COM 	info6->metadata_sz = 0;
118511963SAfshin.Ardakani@Sun.COM 	info6->n_store = info->i_ntargets;
118611963SAfshin.Ardakani@Sun.COM 
118711963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
118811963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info6_t) +
118911963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath) +
119011963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_comment);
119111963SAfshin.Ardakani@Sun.COM 
119211963SAfshin.Ardakani@Sun.COM 	return (netdfs_info_storage1(&info6->si, info, mxa, size));
119311963SAfshin.Ardakani@Sun.COM }
119411963SAfshin.Ardakani@Sun.COM 
119511963SAfshin.Ardakani@Sun.COM /*
119611963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_100 for Get response
119711963SAfshin.Ardakani@Sun.COM  */
119811963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_info_100(netdfs_info100_t * info100,dfs_info_t * info,ndr_xa_t * mxa,uint32_t * size)119911963SAfshin.Ardakani@Sun.COM netdfs_info_100(netdfs_info100_t *info100, dfs_info_t *info, ndr_xa_t *mxa,
120011963SAfshin.Ardakani@Sun.COM     uint32_t *size)
120111963SAfshin.Ardakani@Sun.COM {
120211963SAfshin.Ardakani@Sun.COM 	info100->comment = NDR_STRDUP(mxa, info->i_comment);
120311963SAfshin.Ardakani@Sun.COM 	if (info100->comment == NULL)
120411963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
120511963SAfshin.Ardakani@Sun.COM 
120611963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
120711963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info100_t) +
120811963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_comment);
120911963SAfshin.Ardakani@Sun.COM 
121011963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
121111963SAfshin.Ardakani@Sun.COM }
121211963SAfshin.Ardakani@Sun.COM 
121311963SAfshin.Ardakani@Sun.COM /*
121411963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_300 for Enum response
121511963SAfshin.Ardakani@Sun.COM  */
121611963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_info_300(netdfs_info300_t * info300,dfs_info_t * info,ndr_xa_t * mxa,uint32_t * size)121711963SAfshin.Ardakani@Sun.COM netdfs_info_300(netdfs_info300_t *info300, dfs_info_t *info, ndr_xa_t *mxa,
121811963SAfshin.Ardakani@Sun.COM     uint32_t *size)
121911963SAfshin.Ardakani@Sun.COM {
122011963SAfshin.Ardakani@Sun.COM 	info300->dfsname = NDR_STRDUP(mxa, info->i_uncpath);
122111963SAfshin.Ardakani@Sun.COM 	if (info300->dfsname == NULL)
122211963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
122311963SAfshin.Ardakani@Sun.COM 
122411963SAfshin.Ardakani@Sun.COM 	info300->flavor = DFS_VOLUME_FLAVOR_STANDALONE;
122511963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
122611963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info300_t) +
122711963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath);
122811963SAfshin.Ardakani@Sun.COM 
122911963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
123011963SAfshin.Ardakani@Sun.COM }
123111963SAfshin.Ardakani@Sun.COM 
123211963SAfshin.Ardakani@Sun.COM /*
123311963SAfshin.Ardakani@Sun.COM  * Common enumeration function
123411963SAfshin.Ardakani@Sun.COM  */
123511963SAfshin.Ardakani@Sun.COM static uint32_t
netdfs_enum_common(netdfs_enumhandle_t * de,ndr_xa_t * mxa)123611963SAfshin.Ardakani@Sun.COM netdfs_enum_common(netdfs_enumhandle_t *de, ndr_xa_t *mxa)
123711963SAfshin.Ardakani@Sun.COM {
123811963SAfshin.Ardakani@Sun.COM 	netdfs_info1_t *info1 = de->de_entries;
123911963SAfshin.Ardakani@Sun.COM 	netdfs_info2_t *info2 = de->de_entries;
124011963SAfshin.Ardakani@Sun.COM 	netdfs_info3_t *info3 = de->de_entries;
124111963SAfshin.Ardakani@Sun.COM 	netdfs_info4_t *info4 = de->de_entries;
124211963SAfshin.Ardakani@Sun.COM 	netdfs_info5_t *info5 = de->de_entries;
124311963SAfshin.Ardakani@Sun.COM 	netdfs_info6_t *info6 = de->de_entries;
124411963SAfshin.Ardakani@Sun.COM 	netdfs_info300_t *info300 = de->de_entries;
124511963SAfshin.Ardakani@Sun.COM 	dfs_info_t dfsinfo;
124611963SAfshin.Ardakani@Sun.COM 	smb_cache_cursor_t cursor;
124711963SAfshin.Ardakani@Sun.COM 	dfs_nscnode_t nscnode;
124811963SAfshin.Ardakani@Sun.COM 	uint32_t status;
124911963SAfshin.Ardakani@Sun.COM 	uint32_t itemsz;
125011963SAfshin.Ardakani@Sun.COM 
125111963SAfshin.Ardakani@Sun.COM 	dfs_cache_iterinit(&cursor);
125211963SAfshin.Ardakani@Sun.COM 
125311963SAfshin.Ardakani@Sun.COM 	de->de_nitems = 0;
125411963SAfshin.Ardakani@Sun.COM 	while (dfs_cache_iterate(&cursor, &nscnode)) {
125511963SAfshin.Ardakani@Sun.COM 		if (de->de_nskip > 0) {
125611963SAfshin.Ardakani@Sun.COM 			de->de_nskip--;
125711963SAfshin.Ardakani@Sun.COM 			continue;
125811963SAfshin.Ardakani@Sun.COM 		}
125911963SAfshin.Ardakani@Sun.COM 
126011963SAfshin.Ardakani@Sun.COM 		if (de->de_nitems == de->de_nmax)
126111963SAfshin.Ardakani@Sun.COM 			break;
126211963SAfshin.Ardakani@Sun.COM 
126311963SAfshin.Ardakani@Sun.COM 		status = dfs_cache_getinfo(&nscnode, &dfsinfo, de->de_level);
126411963SAfshin.Ardakani@Sun.COM 		if (status != ERROR_SUCCESS)
126511963SAfshin.Ardakani@Sun.COM 			continue;
126611963SAfshin.Ardakani@Sun.COM 
126711963SAfshin.Ardakani@Sun.COM 		switch (de->de_level) {
126811963SAfshin.Ardakani@Sun.COM 		case 1:
126911963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_1(info1, &dfsinfo, mxa, &itemsz);
127011963SAfshin.Ardakani@Sun.COM 			info1++;
127111963SAfshin.Ardakani@Sun.COM 			break;
127211963SAfshin.Ardakani@Sun.COM 		case 2:
127311963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_2(info2, &dfsinfo, mxa, &itemsz);
127411963SAfshin.Ardakani@Sun.COM 			info2++;
127511963SAfshin.Ardakani@Sun.COM 			break;
127611963SAfshin.Ardakani@Sun.COM 		case 3:
127711963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_3(info3, &dfsinfo, mxa, &itemsz);
127811963SAfshin.Ardakani@Sun.COM 			info3++;
127911963SAfshin.Ardakani@Sun.COM 			break;
128011963SAfshin.Ardakani@Sun.COM 		case 4:
128111963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_4(info4, &dfsinfo, mxa, &itemsz);
128211963SAfshin.Ardakani@Sun.COM 			info4++;
128311963SAfshin.Ardakani@Sun.COM 			break;
128411963SAfshin.Ardakani@Sun.COM 		case 5:
128511963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_5(info5, &dfsinfo, mxa, &itemsz);
128611963SAfshin.Ardakani@Sun.COM 			info5++;
128711963SAfshin.Ardakani@Sun.COM 			break;
128811963SAfshin.Ardakani@Sun.COM 		case 6:
128911963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_6(info6, &dfsinfo, mxa, &itemsz);
129011963SAfshin.Ardakani@Sun.COM 			info6++;
129111963SAfshin.Ardakani@Sun.COM 			break;
129211963SAfshin.Ardakani@Sun.COM 		case 300:
129311963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_300(info300, &dfsinfo, mxa,
129411963SAfshin.Ardakani@Sun.COM 			    &itemsz);
129511963SAfshin.Ardakani@Sun.COM 			info300++;
129611963SAfshin.Ardakani@Sun.COM 			break;
129711963SAfshin.Ardakani@Sun.COM 		default:
129811963SAfshin.Ardakani@Sun.COM 			status = ERROR_INVALID_LEVEL;
129911963SAfshin.Ardakani@Sun.COM 		}
130011963SAfshin.Ardakani@Sun.COM 
130111963SAfshin.Ardakani@Sun.COM 		dfs_info_free(&dfsinfo);
130211963SAfshin.Ardakani@Sun.COM 
130311963SAfshin.Ardakani@Sun.COM 		if (status != ERROR_SUCCESS)
130411963SAfshin.Ardakani@Sun.COM 			return (status);
130511963SAfshin.Ardakani@Sun.COM 
130611963SAfshin.Ardakani@Sun.COM 		if (de->de_nmax == 1) {
130711963SAfshin.Ardakani@Sun.COM 			de->de_nitems = 1;
130811963SAfshin.Ardakani@Sun.COM 			break;
130911963SAfshin.Ardakani@Sun.COM 		}
131011963SAfshin.Ardakani@Sun.COM 
131111963SAfshin.Ardakani@Sun.COM 		if (itemsz > de->de_bavail)
131211963SAfshin.Ardakani@Sun.COM 			break;
131311963SAfshin.Ardakani@Sun.COM 
131411963SAfshin.Ardakani@Sun.COM 		de->de_bavail -= itemsz;
131511963SAfshin.Ardakani@Sun.COM 		de->de_nitems++;
131611963SAfshin.Ardakani@Sun.COM 	}
131711963SAfshin.Ardakani@Sun.COM 
131811963SAfshin.Ardakani@Sun.COM 	de->de_resume += de->de_nitems;
131911963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
132011963SAfshin.Ardakani@Sun.COM }
132111963SAfshin.Ardakani@Sun.COM 
132211963SAfshin.Ardakani@Sun.COM /*
132311963SAfshin.Ardakani@Sun.COM  * Creates intermediate directories of a link from the root share path.
13245331Samw  *
132511963SAfshin.Ardakani@Sun.COM  * TODO: directories should be created by smbsrv to get Windows compatible
132611963SAfshin.Ardakani@Sun.COM  * ACL inheritance.
13275331Samw  */
132811963SAfshin.Ardakani@Sun.COM static void
netdfs_path_create(const char * path)132911963SAfshin.Ardakani@Sun.COM netdfs_path_create(const char *path)
13305331Samw {
133111963SAfshin.Ardakani@Sun.COM 	char dirpath[DFS_PATH_MAX];
133211963SAfshin.Ardakani@Sun.COM 	mode_t mode;
13335331Samw 	char *p;
13345331Samw 
133511963SAfshin.Ardakani@Sun.COM 	(void) strlcpy(dirpath, path, DFS_PATH_MAX);
13365331Samw 
133711963SAfshin.Ardakani@Sun.COM 	/* drop the link itself from the path */
133811963SAfshin.Ardakani@Sun.COM 	if ((p = strrchr(dirpath, '/')) != NULL) {
13395331Samw 		*p = '\0';
134011963SAfshin.Ardakani@Sun.COM 		mode = umask(0);
134111963SAfshin.Ardakani@Sun.COM 		(void) mkdirp(dirpath, 0777);
134211963SAfshin.Ardakani@Sun.COM 		(void) umask(mode);
134311963SAfshin.Ardakani@Sun.COM 	}
134411963SAfshin.Ardakani@Sun.COM }
13455331Samw 
134611963SAfshin.Ardakani@Sun.COM /*
134711963SAfshin.Ardakani@Sun.COM  * Removes empty directories
134811963SAfshin.Ardakani@Sun.COM  */
134911963SAfshin.Ardakani@Sun.COM static void
netdfs_path_remove(smb_unc_t * unc)135011963SAfshin.Ardakani@Sun.COM netdfs_path_remove(smb_unc_t *unc)
135111963SAfshin.Ardakani@Sun.COM {
135211963SAfshin.Ardakani@Sun.COM 	char rootdir[DFS_PATH_MAX];
135311963SAfshin.Ardakani@Sun.COM 	char relpath[DFS_PATH_MAX];
135411963SAfshin.Ardakani@Sun.COM 	char dir[DFS_PATH_MAX];
135511963SAfshin.Ardakani@Sun.COM 	uint32_t status;
135611963SAfshin.Ardakani@Sun.COM 	char *p;
13575331Samw 
135811963SAfshin.Ardakani@Sun.COM 	status = dfs_namespace_path(unc->unc_share, rootdir, DFS_PATH_MAX);
135911963SAfshin.Ardakani@Sun.COM 	if ((status == ERROR_SUCCESS) && (chdir(rootdir) == 0)) {
136011963SAfshin.Ardakani@Sun.COM 		(void) strlcpy(relpath, unc->unc_path, DFS_PATH_MAX);
136111963SAfshin.Ardakani@Sun.COM 		/* drop the link itself from the path */
136211963SAfshin.Ardakani@Sun.COM 		if ((p = strrchr(relpath, '/')) != NULL) {
13635331Samw 			*p = '\0';
136411963SAfshin.Ardakani@Sun.COM 			(void) rmdirp(relpath, dir);
13655331Samw 		}
13665331Samw 	}
136711963SAfshin.Ardakani@Sun.COM }
13685331Samw 
136911963SAfshin.Ardakani@Sun.COM /*
137011963SAfshin.Ardakani@Sun.COM  * Converts the guid string into binary format in network byte order.
137111963SAfshin.Ardakani@Sun.COM  */
137211963SAfshin.Ardakani@Sun.COM static boolean_t
netdfs_guid_fromstr(char * guid_str,netdfs_uuid_t * guid)137311963SAfshin.Ardakani@Sun.COM netdfs_guid_fromstr(char *guid_str, netdfs_uuid_t *guid)
137411963SAfshin.Ardakani@Sun.COM {
137511963SAfshin.Ardakani@Sun.COM 	uuid_t uuid;
13765331Samw 
137711963SAfshin.Ardakani@Sun.COM 	if (uuid_parse(guid_str, uuid) != 0)
137811963SAfshin.Ardakani@Sun.COM 		return (B_FALSE);
137911963SAfshin.Ardakani@Sun.COM 
138011963SAfshin.Ardakani@Sun.COM 	bcopy(&uuid, guid, sizeof (uuid_t));
13815331Samw 
138211963SAfshin.Ardakani@Sun.COM 	guid->data1 = htonl(guid->data1);
138311963SAfshin.Ardakani@Sun.COM 	guid->data2 = htons(guid->data2);
138411963SAfshin.Ardakani@Sun.COM 	guid->data3 = htons(guid->data3);
138511963SAfshin.Ardakani@Sun.COM 
138611963SAfshin.Ardakani@Sun.COM 	return (B_TRUE);
13875331Samw }
1388