xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/netdfs.c (revision 11963:061945695ce1)
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  */
215331Samw /*
22*11963SAfshin.Ardakani@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
235331Samw  * Use is subject to license terms.
245331Samw  */
255331Samw 
265331Samw /*
27*11963SAfshin.Ardakani@Sun.COM  * Net DFS server side RPC service for managing DFS namespaces.
28*11963SAfshin.Ardakani@Sun.COM  *
29*11963SAfshin.Ardakani@Sun.COM  * For more details refer to following Microsoft specification:
30*11963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]
31*11963SAfshin.Ardakani@Sun.COM  *    Distributed File System (DFS): Namespace Management Protocol Specification
325331Samw  */
335331Samw 
34*11963SAfshin.Ardakani@Sun.COM #include <unistd.h>
35*11963SAfshin.Ardakani@Sun.COM #include <libgen.h>
365331Samw #include <strings.h>
37*11963SAfshin.Ardakani@Sun.COM #include <sys/sysmacros.h>
385331Samw 
39*11963SAfshin.Ardakani@Sun.COM #include <smbsrv/ndl/netdfs.ndl>
405331Samw #include <smbsrv/nmpipes.h>
415331Samw #include <smbsrv/nterror.h>
42*11963SAfshin.Ardakani@Sun.COM #include <smbsrv/libmlsvc.h>
43*11963SAfshin.Ardakani@Sun.COM #include <dfs.h>
445331Samw 
45*11963SAfshin.Ardakani@Sun.COM /*
46*11963SAfshin.Ardakani@Sun.COM  * Depends on the information level requested around 4000 or more links
47*11963SAfshin.Ardakani@Sun.COM  * can be provided with this buffer size. The limitation here is due
48*11963SAfshin.Ardakani@Sun.COM  * to some problem in NDR and/or opipe layer so:
49*11963SAfshin.Ardakani@Sun.COM  *
50*11963SAfshin.Ardakani@Sun.COM  * - Do NOT increase the buffer size until that problem is fixed
51*11963SAfshin.Ardakani@Sun.COM  * - The buffer size should be increased when the problem is fixed
52*11963SAfshin.Ardakani@Sun.COM  *   so the 4000 link limitation is removed.
53*11963SAfshin.Ardakani@Sun.COM  */
54*11963SAfshin.Ardakani@Sun.COM #define	NETDFS_MAXBUFLEN	(800 * 1024)
55*11963SAfshin.Ardakani@Sun.COM #define	NETDFS_MAXPREFLEN	((uint32_t)(-1))
565331Samw 
57*11963SAfshin.Ardakani@Sun.COM typedef struct netdfs_enumhandle_t {
58*11963SAfshin.Ardakani@Sun.COM 	uint32_t	de_level;	/* level of detail being requested */
59*11963SAfshin.Ardakani@Sun.COM 	uint32_t	de_prefmaxlen;	/* client MAX size buffer preference */
60*11963SAfshin.Ardakani@Sun.COM 	uint32_t	de_resume;	/* client resume handle */
61*11963SAfshin.Ardakani@Sun.COM 	uint32_t	de_bavail;	/* remaining buffer space in bytes */
62*11963SAfshin.Ardakani@Sun.COM 	uint32_t	de_ntotal;	/* total number of objects */
63*11963SAfshin.Ardakani@Sun.COM 	uint32_t	de_nmax;	/* MAX number of objects to return */
64*11963SAfshin.Ardakani@Sun.COM 	uint32_t	de_nitems;	/* number of objects in buf */
65*11963SAfshin.Ardakani@Sun.COM 	uint32_t	de_nskip;	/* number of objects to skip */
66*11963SAfshin.Ardakani@Sun.COM 	void		*de_entries;	/* ndr buffer */
67*11963SAfshin.Ardakani@Sun.COM } netdfs_enumhandle_t;
685331Samw 
698334SJose.Borrego@Sun.COM static int netdfs_s_getver(void *, ndr_xa_t *);
708334SJose.Borrego@Sun.COM static int netdfs_s_add(void *, ndr_xa_t *);
718334SJose.Borrego@Sun.COM static int netdfs_s_remove(void *, ndr_xa_t *);
728334SJose.Borrego@Sun.COM static int netdfs_s_setinfo(void *, ndr_xa_t *);
738334SJose.Borrego@Sun.COM static int netdfs_s_getinfo(void *, ndr_xa_t *);
748334SJose.Borrego@Sun.COM static int netdfs_s_enum(void *, ndr_xa_t *);
758334SJose.Borrego@Sun.COM static int netdfs_s_move(void *, ndr_xa_t *);
768334SJose.Borrego@Sun.COM static int netdfs_s_rename(void *, ndr_xa_t *);
778334SJose.Borrego@Sun.COM static int netdfs_s_addstdroot(void *, ndr_xa_t *);
788334SJose.Borrego@Sun.COM static int netdfs_s_remstdroot(void *, ndr_xa_t *);
798334SJose.Borrego@Sun.COM static int netdfs_s_enumex(void *, ndr_xa_t *);
805331Samw 
81*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_setinfo_100(dfs_path_t *, netdfs_info100_t *);
82*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_setinfo_101(dfs_path_t *, netdfs_info101_t *,
83*11963SAfshin.Ardakani@Sun.COM     const char *, const char *);
84*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_setinfo_102(dfs_path_t *, netdfs_info102_t *);
85*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_setinfo_103(dfs_path_t *, netdfs_info103_t *);
86*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_setinfo_104(dfs_path_t *, netdfs_info104_t *,
87*11963SAfshin.Ardakani@Sun.COM     const char *, const char *);
88*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_setinfo_105(dfs_path_t *, netdfs_info105_t *);
89*11963SAfshin.Ardakani@Sun.COM 
90*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_1(netdfs_info1_t *, dfs_info_t *, ndr_xa_t *,
91*11963SAfshin.Ardakani@Sun.COM     uint32_t *);
92*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_2(netdfs_info2_t *, dfs_info_t *, ndr_xa_t *,
93*11963SAfshin.Ardakani@Sun.COM     uint32_t *);
94*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_3(netdfs_info3_t *, dfs_info_t *, ndr_xa_t *,
95*11963SAfshin.Ardakani@Sun.COM     uint32_t *);
96*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_4(netdfs_info4_t *, dfs_info_t *, ndr_xa_t *,
97*11963SAfshin.Ardakani@Sun.COM     uint32_t *);
98*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_5(netdfs_info5_t *, dfs_info_t *, ndr_xa_t *,
99*11963SAfshin.Ardakani@Sun.COM     uint32_t *);
100*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_6(netdfs_info6_t *, dfs_info_t *, ndr_xa_t *,
101*11963SAfshin.Ardakani@Sun.COM     uint32_t *);
102*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_100(netdfs_info100_t *, dfs_info_t *, ndr_xa_t *,
103*11963SAfshin.Ardakani@Sun.COM     uint32_t *);
104*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_info_300(netdfs_info300_t *, dfs_info_t *, ndr_xa_t *,
105*11963SAfshin.Ardakani@Sun.COM     uint32_t *);
106*11963SAfshin.Ardakani@Sun.COM 
107*11963SAfshin.Ardakani@Sun.COM static uint32_t netdfs_enum_common(netdfs_enumhandle_t *, ndr_xa_t *);
108*11963SAfshin.Ardakani@Sun.COM 
109*11963SAfshin.Ardakani@Sun.COM static void netdfs_path_create(const char *);
110*11963SAfshin.Ardakani@Sun.COM static void netdfs_path_remove(smb_unc_t *);
111*11963SAfshin.Ardakani@Sun.COM static boolean_t netdfs_guid_fromstr(char *, netdfs_uuid_t *);
112*11963SAfshin.Ardakani@Sun.COM 
1138334SJose.Borrego@Sun.COM static ndr_stub_table_t netdfs_stub_table[] = {
1145331Samw 	{ netdfs_s_getver,	NETDFS_OPNUM_GETVER },
1155331Samw 	{ netdfs_s_add,		NETDFS_OPNUM_ADD },
1165331Samw 	{ netdfs_s_remove,	NETDFS_OPNUM_REMOVE },
1175331Samw 	{ netdfs_s_setinfo,	NETDFS_OPNUM_SETINFO },
1185331Samw 	{ netdfs_s_getinfo,	NETDFS_OPNUM_GETINFO },
1195331Samw 	{ netdfs_s_enum,	NETDFS_OPNUM_ENUM },
1205331Samw 	{ netdfs_s_rename,	NETDFS_OPNUM_RENAME },
1215331Samw 	{ netdfs_s_move,	NETDFS_OPNUM_MOVE },
1225331Samw 	{ netdfs_s_addstdroot,	NETDFS_OPNUM_ADDSTDROOT },
1235331Samw 	{ netdfs_s_remstdroot,	NETDFS_OPNUM_REMSTDROOT },
1245331Samw 	{ netdfs_s_enumex,	NETDFS_OPNUM_ENUMEX },
1255331Samw 	{0}
1265331Samw };
1275331Samw 
1288334SJose.Borrego@Sun.COM static ndr_service_t netdfs_service = {
1295331Samw 	"NETDFS",			/* name */
1305331Samw 	"DFS",				/* desc */
131*11963SAfshin.Ardakani@Sun.COM 	"\\netdfs",			/* endpoint */
132*11963SAfshin.Ardakani@Sun.COM 	PIPE_NETDFS,			/* sec_addr_port */
1335331Samw 	NETDFS_ABSTRACT_UUID,	NETDFS_ABSTRACT_VERS,
1345331Samw 	NETDFS_TRANSFER_UUID,	NETDFS_TRANSFER_VERS,
1355331Samw 
1365331Samw 	0,				/* no bind_instance_size */
1375331Samw 	0,				/* no bind_req() */
1385331Samw 	0,				/* no unbind_and_close() */
1395331Samw 	0,				/* use generic_call_stub() */
1405331Samw 
1415331Samw 	&TYPEINFO(netdfs_interface),	/* interface ti */
1425331Samw 	netdfs_stub_table		/* stub_table */
1435331Samw };
1445331Samw 
1455331Samw /*
1465331Samw  * Register the NETDFS RPC interface with the RPC runtime library.
1475331Samw  * The service must be registered in order to use either the client
1485331Samw  * side or the server side functions.
1495331Samw  */
1505331Samw void
1515331Samw netdfs_initialize(void)
1525331Samw {
1538334SJose.Borrego@Sun.COM 	(void) ndr_svc_register(&netdfs_service);
154*11963SAfshin.Ardakani@Sun.COM 	dfs_init();
155*11963SAfshin.Ardakani@Sun.COM }
156*11963SAfshin.Ardakani@Sun.COM 
157*11963SAfshin.Ardakani@Sun.COM void
158*11963SAfshin.Ardakani@Sun.COM netdfs_finalize(void)
159*11963SAfshin.Ardakani@Sun.COM {
160*11963SAfshin.Ardakani@Sun.COM 	dfs_fini();
1615331Samw }
1625331Samw 
1635331Samw /*
164*11963SAfshin.Ardakani@Sun.COM  * Returns the version number of the DFS server in use on the server.
1655331Samw  *
166*11963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsManagerGetVersion (Opnum 0)
1675331Samw  */
1685331Samw /*ARGSUSED*/
1695331Samw static int
1708334SJose.Borrego@Sun.COM netdfs_s_getver(void *arg, ndr_xa_t *mxa)
1715331Samw {
1725331Samw 	struct netdfs_getver *param = arg;
1735331Samw 
174*11963SAfshin.Ardakani@Sun.COM 	param->version = DFS_MANAGER_VERSION_NT4;
1758334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
1765331Samw }
1775331Samw 
1785331Samw /*
179*11963SAfshin.Ardakani@Sun.COM  * Creates a new DFS link or adds a new target to an existing link of a
180*11963SAfshin.Ardakani@Sun.COM  * DFS namespace.
181*11963SAfshin.Ardakani@Sun.COM  *
182*11963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsAdd (Opnum 1)
1835331Samw  */
1845331Samw static int
1858334SJose.Borrego@Sun.COM netdfs_s_add(void *arg, ndr_xa_t *mxa)
1865331Samw {
187*11963SAfshin.Ardakani@Sun.COM 	netdfs_add_t *param = arg;
188*11963SAfshin.Ardakani@Sun.COM 	dfs_path_t path;
189*11963SAfshin.Ardakani@Sun.COM 	uint32_t status;
190*11963SAfshin.Ardakani@Sun.COM 	const char *uncpath = (const char *)param->dfs_path;
191*11963SAfshin.Ardakani@Sun.COM 	const char *fspath = (const char *)path.p_fspath;
192*11963SAfshin.Ardakani@Sun.COM 	boolean_t newlink;
193*11963SAfshin.Ardakani@Sun.COM 
194*11963SAfshin.Ardakani@Sun.COM 	if (!ndr_is_admin(mxa)) {
195*11963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
196*11963SAfshin.Ardakani@Sun.COM 		return (NDR_DRC_OK);
197*11963SAfshin.Ardakani@Sun.COM 	}
1985331Samw 
199*11963SAfshin.Ardakani@Sun.COM 	if (param->server == NULL || param->share == NULL) {
200*11963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_INVALID_PARAMETER;
201*11963SAfshin.Ardakani@Sun.COM 		return (NDR_DRC_OK);
202*11963SAfshin.Ardakani@Sun.COM 	}
203*11963SAfshin.Ardakani@Sun.COM 
204*11963SAfshin.Ardakani@Sun.COM 	switch (param->flags) {
205*11963SAfshin.Ardakani@Sun.COM 	case DFS_CREATE_VOLUME:
206*11963SAfshin.Ardakani@Sun.COM 	case DFS_ADD_VOLUME:
207*11963SAfshin.Ardakani@Sun.COM 	case DFS_RESTORE_VOLUME:
208*11963SAfshin.Ardakani@Sun.COM 	case (DFS_ADD_VOLUME | DFS_RESTORE_VOLUME):
209*11963SAfshin.Ardakani@Sun.COM 		break;
210*11963SAfshin.Ardakani@Sun.COM 	default:
2115331Samw 		param->status = ERROR_INVALID_PARAMETER;
2128334SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
2135331Samw 	}
2145331Samw 
215*11963SAfshin.Ardakani@Sun.COM 	status = dfs_path_parse(&path, uncpath, DFS_OBJECT_LINK);
216*11963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS) {
217*11963SAfshin.Ardakani@Sun.COM 		param->status = status;
218*11963SAfshin.Ardakani@Sun.COM 		return (NDR_DRC_OK);
2195331Samw 	}
2205331Samw 
221*11963SAfshin.Ardakani@Sun.COM 	status = smb_name_validate_rpath(path.p_unc.unc_path);
222*11963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS) {
223*11963SAfshin.Ardakani@Sun.COM 		dfs_path_free(&path);
2245331Samw 		param->status = status;
2258334SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
2265331Samw 	}
2275331Samw 
228*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
229*11963SAfshin.Ardakani@Sun.COM 
230*11963SAfshin.Ardakani@Sun.COM 	netdfs_path_create(fspath);
231*11963SAfshin.Ardakani@Sun.COM 
232*11963SAfshin.Ardakani@Sun.COM 	status = dfs_link_add(fspath, (const char *)param->server,
233*11963SAfshin.Ardakani@Sun.COM 	    (const char *)param->share, (const char *)param->comment,
234*11963SAfshin.Ardakani@Sun.COM 	    param->flags, &newlink);
235*11963SAfshin.Ardakani@Sun.COM 
236*11963SAfshin.Ardakani@Sun.COM 	if (newlink)
237*11963SAfshin.Ardakani@Sun.COM 		(void) dfs_cache_add_byname(path.p_unc.unc_share,
238*11963SAfshin.Ardakani@Sun.COM 		    path.p_unc.unc_path, DFS_OBJECT_LINK);
239*11963SAfshin.Ardakani@Sun.COM 
240*11963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS)
241*11963SAfshin.Ardakani@Sun.COM 		netdfs_path_remove(&path.p_unc);
242*11963SAfshin.Ardakani@Sun.COM 
243*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
244*11963SAfshin.Ardakani@Sun.COM 
245*11963SAfshin.Ardakani@Sun.COM 	dfs_path_free(&path);
246*11963SAfshin.Ardakani@Sun.COM 	param->status = status;
2478334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
2485331Samw }
2495331Samw 
2505331Samw /*
251*11963SAfshin.Ardakani@Sun.COM  * Removes a link or a link target from a DFS namespace. A link can be
252*11963SAfshin.Ardakani@Sun.COM  * removed regardless of the number of targets associated with it.
2535331Samw  *
254*11963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsRemove (Opnum 2)
2555331Samw  */
2565331Samw static int
2578334SJose.Borrego@Sun.COM netdfs_s_remove(void *arg, ndr_xa_t *mxa)
2585331Samw {
2595331Samw 	struct netdfs_remove *param = arg;
260*11963SAfshin.Ardakani@Sun.COM 	dfs_path_t path;
261*11963SAfshin.Ardakani@Sun.COM 	uint32_t status, stat;
262*11963SAfshin.Ardakani@Sun.COM 	const char *uncpath = (const char *)param->dfs_path;
263*11963SAfshin.Ardakani@Sun.COM 	const char *fspath = (const char *)path.p_fspath;
2645331Samw 
265*11963SAfshin.Ardakani@Sun.COM 	if (!ndr_is_admin(mxa)) {
266*11963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
267*11963SAfshin.Ardakani@Sun.COM 		return (NDR_DRC_OK);
268*11963SAfshin.Ardakani@Sun.COM 	}
269*11963SAfshin.Ardakani@Sun.COM 
270*11963SAfshin.Ardakani@Sun.COM 	/* both server and share must be NULL or non-NULL */
271*11963SAfshin.Ardakani@Sun.COM 	if ((param->server == NULL && param->share != NULL) ||
272*11963SAfshin.Ardakani@Sun.COM 	    (param->server != NULL && param->share == NULL)) {
2735331Samw 		param->status = ERROR_INVALID_PARAMETER;
2748334SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
2755331Samw 	}
2765331Samw 
277*11963SAfshin.Ardakani@Sun.COM 	status = dfs_path_parse(&path, uncpath, DFS_OBJECT_LINK);
278*11963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS) {
2795331Samw 		param->status = status;
2808334SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
2815331Samw 	}
2825331Samw 
283*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
284*11963SAfshin.Ardakani@Sun.COM 
285*11963SAfshin.Ardakani@Sun.COM 	status = dfs_link_remove(fspath, (const char *)param->server,
286*11963SAfshin.Ardakani@Sun.COM 	    (const char *)param->share);
287*11963SAfshin.Ardakani@Sun.COM 
288*11963SAfshin.Ardakani@Sun.COM 	if (status == ERROR_SUCCESS) {
289*11963SAfshin.Ardakani@Sun.COM 		if (dfs_link_stat(fspath, &stat) == ERROR_SUCCESS) {
290*11963SAfshin.Ardakani@Sun.COM 			if (stat != DFS_STAT_ISDFS)
291*11963SAfshin.Ardakani@Sun.COM 				dfs_cache_remove(path.p_unc.unc_share,
292*11963SAfshin.Ardakani@Sun.COM 				    path.p_unc.unc_path);
293*11963SAfshin.Ardakani@Sun.COM 			/*
294*11963SAfshin.Ardakani@Sun.COM 			 * if link is removed then try to remove its
295*11963SAfshin.Ardakani@Sun.COM 			 * empty parent directories if any
296*11963SAfshin.Ardakani@Sun.COM 			 */
297*11963SAfshin.Ardakani@Sun.COM 			if (stat == DFS_STAT_NOTFOUND)
298*11963SAfshin.Ardakani@Sun.COM 				netdfs_path_remove(&path.p_unc);
299*11963SAfshin.Ardakani@Sun.COM 		}
300*11963SAfshin.Ardakani@Sun.COM 	}
301*11963SAfshin.Ardakani@Sun.COM 
302*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
303*11963SAfshin.Ardakani@Sun.COM 
304*11963SAfshin.Ardakani@Sun.COM 	dfs_path_free(&path);
305*11963SAfshin.Ardakani@Sun.COM 	param->status = status;
3068334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
3075331Samw }
3085331Samw 
3095331Samw /*
310*11963SAfshin.Ardakani@Sun.COM  * Sets or modifies information relevant to a specific DFS root, DFS root
311*11963SAfshin.Ardakani@Sun.COM  * target, DFS link, or DFS link target
3125331Samw  *
313*11963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsSetInfo (Opnum 3)
3145331Samw  */
3155331Samw /*ARGSUSED*/
3165331Samw static int
3178334SJose.Borrego@Sun.COM netdfs_s_setinfo(void *arg, ndr_xa_t *mxa)
3185331Samw {
319*11963SAfshin.Ardakani@Sun.COM 	netdfs_setinfo_t *param = arg;
320*11963SAfshin.Ardakani@Sun.COM 	dfs_path_t path;
321*11963SAfshin.Ardakani@Sun.COM 	uint32_t status, stat;
3225331Samw 
323*11963SAfshin.Ardakani@Sun.COM 	/* both server and share must be NULL or non-NULL */
324*11963SAfshin.Ardakani@Sun.COM 	if ((param->server == NULL && param->share != NULL) ||
325*11963SAfshin.Ardakani@Sun.COM 	    (param->server != NULL && param->share == NULL)) {
3265331Samw 		param->status = ERROR_INVALID_PARAMETER;
3278334SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
3285331Samw 	}
3295331Samw 
330*11963SAfshin.Ardakani@Sun.COM 	status = dfs_path_parse(&path, (const char *)param->dfs_path,
331*11963SAfshin.Ardakani@Sun.COM 	    DFS_OBJECT_ANY);
332*11963SAfshin.Ardakani@Sun.COM 
333*11963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS) {
334*11963SAfshin.Ardakani@Sun.COM 		param->status = status;
335*11963SAfshin.Ardakani@Sun.COM 		return (NDR_DRC_OK);
3365331Samw 	}
3375331Samw 
338*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
339*11963SAfshin.Ardakani@Sun.COM 	status = dfs_link_stat((const char *)path.p_fspath, &stat);
340*11963SAfshin.Ardakani@Sun.COM 
341*11963SAfshin.Ardakani@Sun.COM 	if ((path.p_type == DFS_OBJECT_LINK) && (stat != DFS_STAT_ISDFS)) {
342*11963SAfshin.Ardakani@Sun.COM 		dfs_setpriv(PRIV_OFF);
343*11963SAfshin.Ardakani@Sun.COM 		dfs_path_free(&path);
344*11963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_NOT_FOUND;
3458334SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
3465331Samw 	}
3475331Samw 
3485331Samw 	switch (param->info.level) {
3495331Samw 	case 100:
350*11963SAfshin.Ardakani@Sun.COM 		status = netdfs_setinfo_100(&path, param->info.iu.info100);
351*11963SAfshin.Ardakani@Sun.COM 		break;
3525331Samw 	case 101:
353*11963SAfshin.Ardakani@Sun.COM 		status = netdfs_setinfo_101(&path, param->info.iu.info101,
354*11963SAfshin.Ardakani@Sun.COM 		    (const char *)param->server, (const char *)param->share);
355*11963SAfshin.Ardakani@Sun.COM 		break;
3565331Samw 	case 102:
357*11963SAfshin.Ardakani@Sun.COM 		status = netdfs_setinfo_102(&path, param->info.iu.info102);
3585331Samw 		break;
359*11963SAfshin.Ardakani@Sun.COM 	case 103:
360*11963SAfshin.Ardakani@Sun.COM 		status = netdfs_setinfo_103(&path, param->info.iu.info103);
361*11963SAfshin.Ardakani@Sun.COM 		break;
362*11963SAfshin.Ardakani@Sun.COM 	case 104:
363*11963SAfshin.Ardakani@Sun.COM 		status = netdfs_setinfo_104(&path, param->info.iu.info104,
364*11963SAfshin.Ardakani@Sun.COM 		    (const char *)param->server, (const char *)param->share);
365*11963SAfshin.Ardakani@Sun.COM 		break;
366*11963SAfshin.Ardakani@Sun.COM 	case 105:
367*11963SAfshin.Ardakani@Sun.COM 		status = netdfs_setinfo_105(&path, param->info.iu.info105);
368*11963SAfshin.Ardakani@Sun.COM 		break;
3695331Samw 	default:
370*11963SAfshin.Ardakani@Sun.COM 		status = ERROR_INVALID_LEVEL;
371*11963SAfshin.Ardakani@Sun.COM 		break;
3725331Samw 	}
3735331Samw 
374*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
375*11963SAfshin.Ardakani@Sun.COM 	dfs_path_free(&path);
376*11963SAfshin.Ardakani@Sun.COM 	param->status = status;
3778334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
3785331Samw }
3795331Samw 
3805331Samw /*
381*11963SAfshin.Ardakani@Sun.COM  * Returns information about a DFS root or a DFS link of the specified
382*11963SAfshin.Ardakani@Sun.COM  * DFS namespace.
3835331Samw  *
384*11963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsGetInfo (Opnum 4)
3855331Samw  */
3865331Samw static int
3878334SJose.Borrego@Sun.COM netdfs_s_getinfo(void *arg, ndr_xa_t *mxa)
3885331Samw {
389*11963SAfshin.Ardakani@Sun.COM 	netdfs_getinfo_t *param = arg;
390*11963SAfshin.Ardakani@Sun.COM 	netdfs_info1_t *info1;
391*11963SAfshin.Ardakani@Sun.COM 	netdfs_info2_t *info2;
392*11963SAfshin.Ardakani@Sun.COM 	netdfs_info3_t *info3;
393*11963SAfshin.Ardakani@Sun.COM 	netdfs_info4_t *info4;
394*11963SAfshin.Ardakani@Sun.COM 	netdfs_info5_t *info5;
395*11963SAfshin.Ardakani@Sun.COM 	netdfs_info6_t *info6;
396*11963SAfshin.Ardakani@Sun.COM 	netdfs_info100_t *info100;
397*11963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
398*11963SAfshin.Ardakani@Sun.COM 	dfs_path_t path;
399*11963SAfshin.Ardakani@Sun.COM 	uint32_t status, stat;
400*11963SAfshin.Ardakani@Sun.COM 	const char *fspath;
401*11963SAfshin.Ardakani@Sun.COM 	uint32_t level = param->level;
402*11963SAfshin.Ardakani@Sun.COM 
403*11963SAfshin.Ardakani@Sun.COM 	status = dfs_path_parse(&path, (const char *)param->dfs_path,
404*11963SAfshin.Ardakani@Sun.COM 	    DFS_OBJECT_ANY);
4055331Samw 
406*11963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS)
407*11963SAfshin.Ardakani@Sun.COM 		goto getinfo_error;
408*11963SAfshin.Ardakani@Sun.COM 
409*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
4105331Samw 
411*11963SAfshin.Ardakani@Sun.COM 	fspath = path.p_fspath;
412*11963SAfshin.Ardakani@Sun.COM 	if (path.p_type == DFS_OBJECT_LINK) {
413*11963SAfshin.Ardakani@Sun.COM 		status = dfs_link_stat(fspath, &stat);
414*11963SAfshin.Ardakani@Sun.COM 		if ((status != ERROR_SUCCESS) || (stat != DFS_STAT_ISDFS)) {
415*11963SAfshin.Ardakani@Sun.COM 			status = ERROR_NOT_FOUND;
416*11963SAfshin.Ardakani@Sun.COM 			goto getinfo_error;
417*11963SAfshin.Ardakani@Sun.COM 		}
418*11963SAfshin.Ardakani@Sun.COM 
419*11963SAfshin.Ardakani@Sun.COM 		status = dfs_link_getinfo(fspath, &info, param->level);
4205331Samw 	} else {
421*11963SAfshin.Ardakani@Sun.COM 		status = dfs_root_getinfo(fspath, &info, param->level);
4225331Samw 	}
4235331Samw 
424*11963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS)
425*11963SAfshin.Ardakani@Sun.COM 		goto getinfo_error;
426*11963SAfshin.Ardakani@Sun.COM 
427*11963SAfshin.Ardakani@Sun.COM 	(void) strlcpy(info.i_uncpath, (char *)param->dfs_path,
428*11963SAfshin.Ardakani@Sun.COM 	    sizeof (info.i_uncpath));
4295331Samw 
430*11963SAfshin.Ardakani@Sun.COM 	dfs_info_trace("netdfs_s_getinfo", &info);
431*11963SAfshin.Ardakani@Sun.COM 
432*11963SAfshin.Ardakani@Sun.COM 	status = ERROR_NOT_ENOUGH_MEMORY;
433*11963SAfshin.Ardakani@Sun.COM 
434*11963SAfshin.Ardakani@Sun.COM 	switch (level) {
4355331Samw 	case 1:
436*11963SAfshin.Ardakani@Sun.COM 		if ((info1 = NDR_NEW(mxa, netdfs_info1_t)) != NULL) {
437*11963SAfshin.Ardakani@Sun.COM 			param->info.iu.info1 = info1;
438*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_1(info1, &info, mxa, NULL);
439*11963SAfshin.Ardakani@Sun.COM 		}
440*11963SAfshin.Ardakani@Sun.COM 		break;
4415331Samw 	case 2:
442*11963SAfshin.Ardakani@Sun.COM 		if ((info2 = NDR_NEW(mxa, netdfs_info2_t)) != NULL) {
443*11963SAfshin.Ardakani@Sun.COM 			param->info.iu.info2 = info2;
444*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_2(info2, &info, mxa, NULL);
445*11963SAfshin.Ardakani@Sun.COM 		}
446*11963SAfshin.Ardakani@Sun.COM 		break;
4475331Samw 	case 3:
448*11963SAfshin.Ardakani@Sun.COM 		if ((info3 = NDR_NEW(mxa, netdfs_info3_t)) != NULL) {
449*11963SAfshin.Ardakani@Sun.COM 			param->info.iu.info3 = info3;
450*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_3(info3, &info, mxa, NULL);
451*11963SAfshin.Ardakani@Sun.COM 		}
452*11963SAfshin.Ardakani@Sun.COM 		break;
4535331Samw 	case 4:
454*11963SAfshin.Ardakani@Sun.COM 		if ((info4 = NDR_NEW(mxa, netdfs_info4_t)) != NULL) {
455*11963SAfshin.Ardakani@Sun.COM 			param->info.iu.info4 = info4;
456*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_4(info4, &info, mxa, NULL);
457*11963SAfshin.Ardakani@Sun.COM 		}
458*11963SAfshin.Ardakani@Sun.COM 		break;
459*11963SAfshin.Ardakani@Sun.COM 	case 5:
460*11963SAfshin.Ardakani@Sun.COM 		if ((info5 = NDR_NEW(mxa, netdfs_info5_t)) != NULL) {
461*11963SAfshin.Ardakani@Sun.COM 			param->info.iu.info5 = info5;
462*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_5(info5, &info, mxa, NULL);
463*11963SAfshin.Ardakani@Sun.COM 		}
464*11963SAfshin.Ardakani@Sun.COM 		break;
465*11963SAfshin.Ardakani@Sun.COM 	case 6:
466*11963SAfshin.Ardakani@Sun.COM 		if ((info6 = NDR_NEW(mxa, netdfs_info6_t)) != NULL) {
467*11963SAfshin.Ardakani@Sun.COM 			param->info.iu.info6 = info6;
468*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_6(info6, &info, mxa, NULL);
469*11963SAfshin.Ardakani@Sun.COM 		}
470*11963SAfshin.Ardakani@Sun.COM 		break;
4715331Samw 	case 100:
472*11963SAfshin.Ardakani@Sun.COM 		if ((info100 = NDR_NEW(mxa, netdfs_info100_t)) != NULL) {
473*11963SAfshin.Ardakani@Sun.COM 			param->info.iu.info100 = info100;
474*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_100(info100, &info, mxa, NULL);
475*11963SAfshin.Ardakani@Sun.COM 		}
4765331Samw 		break;
4775331Samw 
4785331Samw 	default:
479*11963SAfshin.Ardakani@Sun.COM 		status = ERROR_INVALID_LEVEL;
480*11963SAfshin.Ardakani@Sun.COM 		break;
4815331Samw 	}
4825331Samw 
483*11963SAfshin.Ardakani@Sun.COM 	dfs_info_free(&info);
484*11963SAfshin.Ardakani@Sun.COM 
485*11963SAfshin.Ardakani@Sun.COM getinfo_error:
486*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
487*11963SAfshin.Ardakani@Sun.COM 	dfs_path_free(&path);
488*11963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS)
489*11963SAfshin.Ardakani@Sun.COM 		bzero(param, sizeof (netdfs_getinfo_t));
490*11963SAfshin.Ardakani@Sun.COM 
491*11963SAfshin.Ardakani@Sun.COM 	param->info.level = level;
492*11963SAfshin.Ardakani@Sun.COM 	param->status = status;
4938334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
4945331Samw }
4955331Samw 
4965331Samw /*
497*11963SAfshin.Ardakani@Sun.COM  * Enumerates the DFS root hosted on a server or the DFS links of the
498*11963SAfshin.Ardakani@Sun.COM  * namespace hosted by a server. Depending on the information level,
499*11963SAfshin.Ardakani@Sun.COM  * the targets of the root and links are also displayed.
5005331Samw  *
501*11963SAfshin.Ardakani@Sun.COM  * For unsupported levels, it should return ERROR_INVALID_LEVEL as
502*11963SAfshin.Ardakani@Sun.COM  * Microsoft does for DFS server on Win2000 and NT.
503*11963SAfshin.Ardakani@Sun.COM  *
504*11963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsEnum (Opnum 5)
5055331Samw  */
5065331Samw /*ARGSUSED*/
5075331Samw static int
5088334SJose.Borrego@Sun.COM netdfs_s_enum(void *arg, ndr_xa_t *mxa)
5095331Samw {
510*11963SAfshin.Ardakani@Sun.COM 	netdfs_enum_t *param = arg;
511*11963SAfshin.Ardakani@Sun.COM 	netdfs_enumhandle_t de;
512*11963SAfshin.Ardakani@Sun.COM 	uint32_t level = param->level;
513*11963SAfshin.Ardakani@Sun.COM 	uint32_t status = ERROR_SUCCESS;
514*11963SAfshin.Ardakani@Sun.COM 	uint32_t nroot;
515*11963SAfshin.Ardakani@Sun.COM 	size_t entsize;
516*11963SAfshin.Ardakani@Sun.COM 
517*11963SAfshin.Ardakani@Sun.COM 	if (param->info == NULL) {
518*11963SAfshin.Ardakani@Sun.COM 		status = ERROR_INVALID_PARAMETER;
519*11963SAfshin.Ardakani@Sun.COM 		goto enum_error;
520*11963SAfshin.Ardakani@Sun.COM 	}
521*11963SAfshin.Ardakani@Sun.COM 
522*11963SAfshin.Ardakani@Sun.COM 	if ((nroot = dfs_namespace_count()) == 0)
523*11963SAfshin.Ardakani@Sun.COM 		status = ERROR_NOT_FOUND;
524*11963SAfshin.Ardakani@Sun.COM 	else if (nroot > 1)
525*11963SAfshin.Ardakani@Sun.COM 		status = ERROR_DEVICE_NOT_AVAILABLE;
526*11963SAfshin.Ardakani@Sun.COM 
527*11963SAfshin.Ardakani@Sun.COM 	if (status != ERROR_SUCCESS)
528*11963SAfshin.Ardakani@Sun.COM 		goto enum_error;
529*11963SAfshin.Ardakani@Sun.COM 
530*11963SAfshin.Ardakani@Sun.COM 	bzero(&de, sizeof (netdfs_enumhandle_t));
531*11963SAfshin.Ardakani@Sun.COM 	de.de_level = level;
532*11963SAfshin.Ardakani@Sun.COM 	de.de_ntotal = dfs_cache_num();
533*11963SAfshin.Ardakani@Sun.COM 
534*11963SAfshin.Ardakani@Sun.COM 	if (param->pref_max_len == NETDFS_MAXPREFLEN ||
535*11963SAfshin.Ardakani@Sun.COM 	    param->pref_max_len > NETDFS_MAXBUFLEN)
536*11963SAfshin.Ardakani@Sun.COM 		de.de_prefmaxlen = NETDFS_MAXBUFLEN;
537*11963SAfshin.Ardakani@Sun.COM 	else
538*11963SAfshin.Ardakani@Sun.COM 		de.de_prefmaxlen = param->pref_max_len;
539*11963SAfshin.Ardakani@Sun.COM 
540*11963SAfshin.Ardakani@Sun.COM 	de.de_bavail = de.de_prefmaxlen;
541*11963SAfshin.Ardakani@Sun.COM 
542*11963SAfshin.Ardakani@Sun.COM 	if (param->resume_handle != NULL) {
543*11963SAfshin.Ardakani@Sun.COM 		if (*param->resume_handle >= de.de_ntotal) {
544*11963SAfshin.Ardakani@Sun.COM 			status = ERROR_NO_MORE_ITEMS;
545*11963SAfshin.Ardakani@Sun.COM 			goto enum_error;
546*11963SAfshin.Ardakani@Sun.COM 		}
547*11963SAfshin.Ardakani@Sun.COM 		de.de_resume = *param->resume_handle;
548*11963SAfshin.Ardakani@Sun.COM 		de.de_nskip = de.de_resume;
549*11963SAfshin.Ardakani@Sun.COM 		*param->resume_handle = 0;
550*11963SAfshin.Ardakani@Sun.COM 	}
551*11963SAfshin.Ardakani@Sun.COM 
552*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
553*11963SAfshin.Ardakani@Sun.COM 
554*11963SAfshin.Ardakani@Sun.COM 	status = ERROR_NOT_ENOUGH_MEMORY;
555*11963SAfshin.Ardakani@Sun.COM 
556*11963SAfshin.Ardakani@Sun.COM 	switch (level) {
557*11963SAfshin.Ardakani@Sun.COM 	case 1:
558*11963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info1_t);
559*11963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
560*11963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info1_t, de.de_nmax);
561*11963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
562*11963SAfshin.Ardakani@Sun.COM 			goto enum_error;
563*11963SAfshin.Ardakani@Sun.COM 
564*11963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
565*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info1->info1 = de.de_entries;
566*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info1->count = de.de_nitems;
567*11963SAfshin.Ardakani@Sun.COM 		}
568*11963SAfshin.Ardakani@Sun.COM 		break;
569*11963SAfshin.Ardakani@Sun.COM 	case 2:
570*11963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info2_t);
571*11963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
572*11963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info2_t, de.de_nmax);
573*11963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
574*11963SAfshin.Ardakani@Sun.COM 			goto enum_error;
5755331Samw 
576*11963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
577*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info2->info2 = de.de_entries;
578*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info2->count = de.de_nitems;
579*11963SAfshin.Ardakani@Sun.COM 		}
580*11963SAfshin.Ardakani@Sun.COM 		break;
5815331Samw 	case 3:
582*11963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info3_t) +
583*11963SAfshin.Ardakani@Sun.COM 		    sizeof (netdfs_storage_info_t);
584*11963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
585*11963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info3_t, de.de_nmax);
586*11963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
587*11963SAfshin.Ardakani@Sun.COM 			goto enum_error;
588*11963SAfshin.Ardakani@Sun.COM 
589*11963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
590*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info3->info3 = de.de_entries;
591*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info3->count = de.de_nitems;
592*11963SAfshin.Ardakani@Sun.COM 		}
593*11963SAfshin.Ardakani@Sun.COM 		break;
594*11963SAfshin.Ardakani@Sun.COM 	case 4:
595*11963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info4_t) +
596*11963SAfshin.Ardakani@Sun.COM 		    sizeof (netdfs_storage_info_t);
597*11963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
598*11963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info4_t, de.de_nmax);
599*11963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
600*11963SAfshin.Ardakani@Sun.COM 			goto enum_error;
601*11963SAfshin.Ardakani@Sun.COM 
602*11963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
603*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info4->info4 = de.de_entries;
604*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info4->count = de.de_nitems;
605*11963SAfshin.Ardakani@Sun.COM 		}
606*11963SAfshin.Ardakani@Sun.COM 		break;
607*11963SAfshin.Ardakani@Sun.COM 
608*11963SAfshin.Ardakani@Sun.COM 	case 5:
609*11963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info5_t);
610*11963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
611*11963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info5_t, de.de_nmax);
612*11963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
613*11963SAfshin.Ardakani@Sun.COM 			goto enum_error;
614*11963SAfshin.Ardakani@Sun.COM 
615*11963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
616*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info5->info5 = de.de_entries;
617*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info5->count = de.de_nitems;
618*11963SAfshin.Ardakani@Sun.COM 		}
619*11963SAfshin.Ardakani@Sun.COM 		break;
620*11963SAfshin.Ardakani@Sun.COM 
621*11963SAfshin.Ardakani@Sun.COM 	case 6:
622*11963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info6_t) +
623*11963SAfshin.Ardakani@Sun.COM 		    sizeof (netdfs_storage_info1_t);
624*11963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
625*11963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info6_t, de.de_nmax);
626*11963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
627*11963SAfshin.Ardakani@Sun.COM 			goto enum_error;
628*11963SAfshin.Ardakani@Sun.COM 
629*11963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
630*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info6->info6 = de.de_entries;
631*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info6->count = de.de_nitems;
632*11963SAfshin.Ardakani@Sun.COM 		}
633*11963SAfshin.Ardakani@Sun.COM 		break;
634*11963SAfshin.Ardakani@Sun.COM 
635*11963SAfshin.Ardakani@Sun.COM 	case 300:
636*11963SAfshin.Ardakani@Sun.COM 		entsize = sizeof (netdfs_info300_t);
637*11963SAfshin.Ardakani@Sun.COM 		de.de_nmax = MAX((de.de_prefmaxlen / entsize), 1);
638*11963SAfshin.Ardakani@Sun.COM 		de.de_entries = NDR_NEWN(mxa, netdfs_info300_t, de.de_nmax);
639*11963SAfshin.Ardakani@Sun.COM 		if (de.de_entries == NULL)
640*11963SAfshin.Ardakani@Sun.COM 			goto enum_error;
641*11963SAfshin.Ardakani@Sun.COM 
642*11963SAfshin.Ardakani@Sun.COM 		if ((status = netdfs_enum_common(&de, mxa)) == ERROR_SUCCESS) {
643*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info300->info300 = de.de_entries;
644*11963SAfshin.Ardakani@Sun.COM 			param->info->iu.info300->count = de.de_nitems;
645*11963SAfshin.Ardakani@Sun.COM 		}
6465331Samw 		break;
6475331Samw 
6485331Samw 	default:
649*11963SAfshin.Ardakani@Sun.COM 		status = ERROR_INVALID_PARAMETER;
650*11963SAfshin.Ardakani@Sun.COM 		break;
6515331Samw 	}
6525331Samw 
653*11963SAfshin.Ardakani@Sun.COM 	if ((status == ERROR_SUCCESS) && (param->resume_handle != NULL))
654*11963SAfshin.Ardakani@Sun.COM 		*param->resume_handle = de.de_resume;
655*11963SAfshin.Ardakani@Sun.COM 
656*11963SAfshin.Ardakani@Sun.COM enum_error:
657*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
658*11963SAfshin.Ardakani@Sun.COM 	param->status = status;
6598334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
6605331Samw }
6615331Samw 
6625331Samw /*
663*11963SAfshin.Ardakani@Sun.COM  * Renames or moves a DFS link
664*11963SAfshin.Ardakani@Sun.COM  *
665*11963SAfshin.Ardakani@Sun.COM  * Does not need to be supported for DFS version 1
666*11963SAfshin.Ardakani@Sun.COM  *
667*11963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsMove (Opnum 6)
6685331Samw  */
6695331Samw /*ARGSUSED*/
6705331Samw static int
6718334SJose.Borrego@Sun.COM netdfs_s_move(void *arg, ndr_xa_t *mxa)
6725331Samw {
6735331Samw 	struct netdfs_move *param = arg;
6745331Samw 
675*11963SAfshin.Ardakani@Sun.COM 	param->status = ERROR_NOT_SUPPORTED;
6768334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
6775331Samw }
6785331Samw 
6795331Samw /*
680*11963SAfshin.Ardakani@Sun.COM  * According to [MS-DFSNM] spec this operation (opnum 7) is not
681*11963SAfshin.Ardakani@Sun.COM  * used over the wire.
6825331Samw  */
6835331Samw /*ARGSUSED*/
6845331Samw static int
6858334SJose.Borrego@Sun.COM netdfs_s_rename(void *arg, ndr_xa_t *mxa)
6865331Samw {
6875331Samw 	struct netdfs_rename *param = arg;
6885331Samw 
689*11963SAfshin.Ardakani@Sun.COM 	param->status = ERROR_NOT_SUPPORTED;
6908334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
6915331Samw }
6925331Samw 
6935331Samw /*
694*11963SAfshin.Ardakani@Sun.COM  * Creates a new standalone DFS namespace
695*11963SAfshin.Ardakani@Sun.COM  *
696*11963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsAddStdRoot (Opnum 12)
6975331Samw  */
6985331Samw /*ARGSUSED*/
6995331Samw static int
7008334SJose.Borrego@Sun.COM netdfs_s_addstdroot(void *arg, ndr_xa_t *mxa)
7015331Samw {
7025331Samw 	struct netdfs_addstdroot *param = arg;
703*11963SAfshin.Ardakani@Sun.COM 	const char *share = (const char *)param->share;
704*11963SAfshin.Ardakani@Sun.COM 	const char *comment = (const char *)param->comment;
7055331Samw 
706*11963SAfshin.Ardakani@Sun.COM 	if (!ndr_is_admin(mxa)) {
707*11963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
708*11963SAfshin.Ardakani@Sun.COM 		return (NDR_DRC_OK);
709*11963SAfshin.Ardakani@Sun.COM 	}
710*11963SAfshin.Ardakani@Sun.COM 
711*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
712*11963SAfshin.Ardakani@Sun.COM 
713*11963SAfshin.Ardakani@Sun.COM 	/* For now only allow a single standalone namespace */
714*11963SAfshin.Ardakani@Sun.COM 	if (dfs_namespace_count() == 0)
715*11963SAfshin.Ardakani@Sun.COM 		param->status = dfs_namespace_add(share, comment);
716*11963SAfshin.Ardakani@Sun.COM 	else
717*11963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_NOT_SUPPORTED;
718*11963SAfshin.Ardakani@Sun.COM 
719*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
7208334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
7215331Samw }
7225331Samw 
7235331Samw /*
724*11963SAfshin.Ardakani@Sun.COM  * Deletes the specified stand-alone DFS namespace. The DFS namespace can be
725*11963SAfshin.Ardakani@Sun.COM  * removed without first removing all of the links in it.
726*11963SAfshin.Ardakani@Sun.COM  *
727*11963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM]: NetrDfsRemoveStdRoot (Opnum 13)
7285331Samw  */
7295331Samw /*ARGSUSED*/
7305331Samw static int
7318334SJose.Borrego@Sun.COM netdfs_s_remstdroot(void *arg, ndr_xa_t *mxa)
7325331Samw {
7335331Samw 	struct netdfs_remstdroot *param = arg;
734*11963SAfshin.Ardakani@Sun.COM 	const char *share = (const char *)param->share;
7355331Samw 
736*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_ON);
737*11963SAfshin.Ardakani@Sun.COM 
738*11963SAfshin.Ardakani@Sun.COM 	if (ndr_is_admin(mxa))
739*11963SAfshin.Ardakani@Sun.COM 		param->status = dfs_namespace_remove(share);
740*11963SAfshin.Ardakani@Sun.COM 	else
741*11963SAfshin.Ardakani@Sun.COM 		param->status = ERROR_ACCESS_DENIED;
742*11963SAfshin.Ardakani@Sun.COM 
743*11963SAfshin.Ardakani@Sun.COM 	dfs_setpriv(PRIV_OFF);
7448334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
7455331Samw }
7465331Samw 
7475331Samw /*
748*11963SAfshin.Ardakani@Sun.COM  * Enumerates the DFS roots hosted on a server, or DFS links of a namespace
749*11963SAfshin.Ardakani@Sun.COM  * hosted by the server. Depending on the information level, the targets
750*11963SAfshin.Ardakani@Sun.COM  * associated with the roots and links are also displayed
7515331Samw  *
752*11963SAfshin.Ardakani@Sun.COM  * Does not need to be supported for DFS version 1
753*11963SAfshin.Ardakani@Sun.COM  *
754*11963SAfshin.Ardakani@Sun.COM  * [MS-DFSNM] NetrDfsEnumEx (Opnum 21)
7555331Samw  */
756*11963SAfshin.Ardakani@Sun.COM /*ARGSUSED*/
7575331Samw static int
7588334SJose.Borrego@Sun.COM netdfs_s_enumex(void *arg, ndr_xa_t *mxa)
7595331Samw {
7605331Samw 	struct netdfs_enumex *param = arg;
7615331Samw 
7625331Samw 	bzero(param->info, sizeof (struct netdfs_enumex));
763*11963SAfshin.Ardakani@Sun.COM 	param->status = ERROR_NOT_SUPPORTED;
7648334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
7655331Samw }
7665331Samw 
7675331Samw /*
768*11963SAfshin.Ardakani@Sun.COM  * Sets the comment for the DFS link/root.
769*11963SAfshin.Ardakani@Sun.COM  */
770*11963SAfshin.Ardakani@Sun.COM static uint32_t
771*11963SAfshin.Ardakani@Sun.COM netdfs_setinfo_100(dfs_path_t *path, netdfs_info100_t *netinfo)
772*11963SAfshin.Ardakani@Sun.COM {
773*11963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
774*11963SAfshin.Ardakani@Sun.COM 	uint32_t status;
775*11963SAfshin.Ardakani@Sun.COM 	char *cmnt = (char *)netinfo->comment;
776*11963SAfshin.Ardakani@Sun.COM 
777*11963SAfshin.Ardakani@Sun.COM 	bzero(&info, sizeof (dfs_info_t));
778*11963SAfshin.Ardakani@Sun.COM 	if (cmnt != NULL)
779*11963SAfshin.Ardakani@Sun.COM 		(void) strlcpy(info.i_comment, cmnt, sizeof (info.i_comment));
780*11963SAfshin.Ardakani@Sun.COM 
781*11963SAfshin.Ardakani@Sun.COM 	if (path->p_type == DFS_OBJECT_LINK)
782*11963SAfshin.Ardakani@Sun.COM 		status = dfs_link_setinfo(path->p_fspath, &info, 100);
783*11963SAfshin.Ardakani@Sun.COM 	else
784*11963SAfshin.Ardakani@Sun.COM 		status = dfs_root_setinfo(path->p_fspath, &info, 100);
785*11963SAfshin.Ardakani@Sun.COM 
786*11963SAfshin.Ardakani@Sun.COM 	return (status);
787*11963SAfshin.Ardakani@Sun.COM }
788*11963SAfshin.Ardakani@Sun.COM 
789*11963SAfshin.Ardakani@Sun.COM /*
790*11963SAfshin.Ardakani@Sun.COM  * Sets the state for the DFS root/link or its target.
791*11963SAfshin.Ardakani@Sun.COM  */
792*11963SAfshin.Ardakani@Sun.COM static uint32_t
793*11963SAfshin.Ardakani@Sun.COM netdfs_setinfo_101(dfs_path_t *path, netdfs_info101_t *netinfo,
794*11963SAfshin.Ardakani@Sun.COM     const char *t_server, const char *t_share)
795*11963SAfshin.Ardakani@Sun.COM {
796*11963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
797*11963SAfshin.Ardakani@Sun.COM 	dfs_target_t target;
798*11963SAfshin.Ardakani@Sun.COM 	uint32_t status;
799*11963SAfshin.Ardakani@Sun.COM 
800*11963SAfshin.Ardakani@Sun.COM 	bzero(&info, sizeof (dfs_info_t));
801*11963SAfshin.Ardakani@Sun.COM 	bzero(&target, sizeof (dfs_target_t));
802*11963SAfshin.Ardakani@Sun.COM 
803*11963SAfshin.Ardakani@Sun.COM 	if (t_server == NULL && t_share == NULL) {
804*11963SAfshin.Ardakani@Sun.COM 		info.i_state = netinfo->state;
805*11963SAfshin.Ardakani@Sun.COM 	} else {
806*11963SAfshin.Ardakani@Sun.COM 		target.t_state = netinfo->state;
807*11963SAfshin.Ardakani@Sun.COM 		(void) strlcpy(target.t_server, t_server,
808*11963SAfshin.Ardakani@Sun.COM 		    sizeof (target.t_server));
809*11963SAfshin.Ardakani@Sun.COM 		(void) strlcpy(target.t_share, t_share,
810*11963SAfshin.Ardakani@Sun.COM 		    sizeof (target.t_share));
811*11963SAfshin.Ardakani@Sun.COM 		info.i_targets = &target;
812*11963SAfshin.Ardakani@Sun.COM 	}
813*11963SAfshin.Ardakani@Sun.COM 
814*11963SAfshin.Ardakani@Sun.COM 	if (path->p_type == DFS_OBJECT_LINK)
815*11963SAfshin.Ardakani@Sun.COM 		status = dfs_link_setinfo(path->p_fspath, &info, 101);
816*11963SAfshin.Ardakani@Sun.COM 	else
817*11963SAfshin.Ardakani@Sun.COM 		status = dfs_root_setinfo(path->p_fspath, &info, 101);
818*11963SAfshin.Ardakani@Sun.COM 
819*11963SAfshin.Ardakani@Sun.COM 	return (status);
820*11963SAfshin.Ardakani@Sun.COM }
821*11963SAfshin.Ardakani@Sun.COM 
822*11963SAfshin.Ardakani@Sun.COM /*
823*11963SAfshin.Ardakani@Sun.COM  * Sets the timeout value of the DFS link/root.
824*11963SAfshin.Ardakani@Sun.COM  */
825*11963SAfshin.Ardakani@Sun.COM static uint32_t
826*11963SAfshin.Ardakani@Sun.COM netdfs_setinfo_102(dfs_path_t *path, netdfs_info102_t *netinfo)
827*11963SAfshin.Ardakani@Sun.COM {
828*11963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
829*11963SAfshin.Ardakani@Sun.COM 	uint32_t status;
830*11963SAfshin.Ardakani@Sun.COM 
831*11963SAfshin.Ardakani@Sun.COM 	bzero(&info, sizeof (dfs_info_t));
832*11963SAfshin.Ardakani@Sun.COM 	info.i_timeout = netinfo->timeout;
833*11963SAfshin.Ardakani@Sun.COM 
834*11963SAfshin.Ardakani@Sun.COM 	if (path->p_type == DFS_OBJECT_LINK)
835*11963SAfshin.Ardakani@Sun.COM 		status = dfs_link_setinfo(path->p_fspath, &info, 102);
836*11963SAfshin.Ardakani@Sun.COM 	else
837*11963SAfshin.Ardakani@Sun.COM 		status = dfs_root_setinfo(path->p_fspath, &info, 102);
838*11963SAfshin.Ardakani@Sun.COM 
839*11963SAfshin.Ardakani@Sun.COM 	return (status);
840*11963SAfshin.Ardakani@Sun.COM }
841*11963SAfshin.Ardakani@Sun.COM 
842*11963SAfshin.Ardakani@Sun.COM /*
843*11963SAfshin.Ardakani@Sun.COM  * Sets the property flags for the root or link.
844*11963SAfshin.Ardakani@Sun.COM  */
845*11963SAfshin.Ardakani@Sun.COM static uint32_t
846*11963SAfshin.Ardakani@Sun.COM netdfs_setinfo_103(dfs_path_t *path, netdfs_info103_t *netinfo)
847*11963SAfshin.Ardakani@Sun.COM {
848*11963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
849*11963SAfshin.Ardakani@Sun.COM 	uint32_t status;
850*11963SAfshin.Ardakani@Sun.COM 
851*11963SAfshin.Ardakani@Sun.COM 	bzero(&info, sizeof (dfs_info_t));
852*11963SAfshin.Ardakani@Sun.COM 	info.i_propflags =
853*11963SAfshin.Ardakani@Sun.COM 	    netinfo->property_flags & netinfo->property_flag_mask;
854*11963SAfshin.Ardakani@Sun.COM 
855*11963SAfshin.Ardakani@Sun.COM 	if (path->p_type == DFS_OBJECT_LINK)
856*11963SAfshin.Ardakani@Sun.COM 		status = dfs_link_setinfo(path->p_fspath, &info, 103);
857*11963SAfshin.Ardakani@Sun.COM 	else
858*11963SAfshin.Ardakani@Sun.COM 		status = dfs_root_setinfo(path->p_fspath, &info, 103);
859*11963SAfshin.Ardakani@Sun.COM 
860*11963SAfshin.Ardakani@Sun.COM 	return (status);
861*11963SAfshin.Ardakani@Sun.COM }
862*11963SAfshin.Ardakani@Sun.COM 
863*11963SAfshin.Ardakani@Sun.COM /*
864*11963SAfshin.Ardakani@Sun.COM  * Sets the target priority rank and class for the root target or link target
865*11963SAfshin.Ardakani@Sun.COM  */
866*11963SAfshin.Ardakani@Sun.COM static uint32_t
867*11963SAfshin.Ardakani@Sun.COM netdfs_setinfo_104(dfs_path_t *path, netdfs_info104_t *netinfo,
868*11963SAfshin.Ardakani@Sun.COM     const char *t_server, const char *t_share)
869*11963SAfshin.Ardakani@Sun.COM {
870*11963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
871*11963SAfshin.Ardakani@Sun.COM 	dfs_target_t target;
872*11963SAfshin.Ardakani@Sun.COM 	uint32_t status;
873*11963SAfshin.Ardakani@Sun.COM 
874*11963SAfshin.Ardakani@Sun.COM 	if ((t_server == NULL) || (t_share == NULL))
875*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_INVALID_PARAMETER);
876*11963SAfshin.Ardakani@Sun.COM 
877*11963SAfshin.Ardakani@Sun.COM 	bzero(&info, sizeof (dfs_info_t));
878*11963SAfshin.Ardakani@Sun.COM 	bzero(&target, sizeof (dfs_target_t));
879*11963SAfshin.Ardakani@Sun.COM 
880*11963SAfshin.Ardakani@Sun.COM 	target.t_priority.p_class = netinfo->priority_class;
881*11963SAfshin.Ardakani@Sun.COM 	target.t_priority.p_rank = netinfo->priority_rank;
882*11963SAfshin.Ardakani@Sun.COM 	(void) strlcpy(target.t_server, t_server, sizeof (target.t_server));
883*11963SAfshin.Ardakani@Sun.COM 	(void) strlcpy(target.t_share, t_share, sizeof (target.t_share));
884*11963SAfshin.Ardakani@Sun.COM 	info.i_targets = &target;
885*11963SAfshin.Ardakani@Sun.COM 
886*11963SAfshin.Ardakani@Sun.COM 	if (path->p_type == DFS_OBJECT_LINK)
887*11963SAfshin.Ardakani@Sun.COM 		status = dfs_link_setinfo(path->p_fspath, &info, 104);
888*11963SAfshin.Ardakani@Sun.COM 	else
889*11963SAfshin.Ardakani@Sun.COM 		status = dfs_root_setinfo(path->p_fspath, &info, 104);
890*11963SAfshin.Ardakani@Sun.COM 
891*11963SAfshin.Ardakani@Sun.COM 	return (status);
892*11963SAfshin.Ardakani@Sun.COM }
893*11963SAfshin.Ardakani@Sun.COM 
894*11963SAfshin.Ardakani@Sun.COM /*
895*11963SAfshin.Ardakani@Sun.COM  * Sets the comment, state, time-out information, and property flags for the
896*11963SAfshin.Ardakani@Sun.COM  * namespace root or link specified in DfsInfo. Does not apply to a root target
897*11963SAfshin.Ardakani@Sun.COM  * or link target.
898*11963SAfshin.Ardakani@Sun.COM  */
899*11963SAfshin.Ardakani@Sun.COM static uint32_t
900*11963SAfshin.Ardakani@Sun.COM netdfs_setinfo_105(dfs_path_t *path, netdfs_info105_t *netinfo)
901*11963SAfshin.Ardakani@Sun.COM {
902*11963SAfshin.Ardakani@Sun.COM 	dfs_info_t info;
903*11963SAfshin.Ardakani@Sun.COM 	uint32_t status;
904*11963SAfshin.Ardakani@Sun.COM 	char *cmnt = (char *)netinfo->comment;
905*11963SAfshin.Ardakani@Sun.COM 
906*11963SAfshin.Ardakani@Sun.COM 	bzero(&info, sizeof (dfs_info_t));
907*11963SAfshin.Ardakani@Sun.COM 
908*11963SAfshin.Ardakani@Sun.COM 	if (cmnt != NULL)
909*11963SAfshin.Ardakani@Sun.COM 		(void) strlcpy(info.i_comment, cmnt, sizeof (info.i_comment));
910*11963SAfshin.Ardakani@Sun.COM 	info.i_state = netinfo->state;
911*11963SAfshin.Ardakani@Sun.COM 	info.i_timeout = netinfo->timeout;
912*11963SAfshin.Ardakani@Sun.COM 	info.i_propflags =
913*11963SAfshin.Ardakani@Sun.COM 	    netinfo->property_flags & netinfo->property_flag_mask;
914*11963SAfshin.Ardakani@Sun.COM 
915*11963SAfshin.Ardakani@Sun.COM 	if (path->p_type == DFS_OBJECT_LINK)
916*11963SAfshin.Ardakani@Sun.COM 		status = dfs_link_setinfo(path->p_fspath, &info, 105);
917*11963SAfshin.Ardakani@Sun.COM 	else
918*11963SAfshin.Ardakani@Sun.COM 		status = dfs_root_setinfo(path->p_fspath, &info, 105);
919*11963SAfshin.Ardakani@Sun.COM 
920*11963SAfshin.Ardakani@Sun.COM 	return (status);
921*11963SAfshin.Ardakani@Sun.COM }
922*11963SAfshin.Ardakani@Sun.COM 
923*11963SAfshin.Ardakani@Sun.COM /*
924*11963SAfshin.Ardakani@Sun.COM  * DFS_STORAGE_INFO: target information
925*11963SAfshin.Ardakani@Sun.COM  */
926*11963SAfshin.Ardakani@Sun.COM static uint32_t
927*11963SAfshin.Ardakani@Sun.COM netdfs_info_storage(netdfs_storage_info_t **sinfo, dfs_info_t *info,
928*11963SAfshin.Ardakani@Sun.COM     ndr_xa_t *mxa, uint32_t *size)
929*11963SAfshin.Ardakani@Sun.COM {
930*11963SAfshin.Ardakani@Sun.COM 	netdfs_storage_info_t *storage;
931*11963SAfshin.Ardakani@Sun.COM 	dfs_target_t *target;
932*11963SAfshin.Ardakani@Sun.COM 	int i;
933*11963SAfshin.Ardakani@Sun.COM 
934*11963SAfshin.Ardakani@Sun.COM 	*sinfo = NULL;
935*11963SAfshin.Ardakani@Sun.COM 	if (info->i_ntargets == 0)
936*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_SUCCESS);
937*11963SAfshin.Ardakani@Sun.COM 
938*11963SAfshin.Ardakani@Sun.COM 	*sinfo = NDR_NEWN(mxa, netdfs_storage_info_t, info->i_ntargets);
939*11963SAfshin.Ardakani@Sun.COM 	if (*sinfo == NULL)
940*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
941*11963SAfshin.Ardakani@Sun.COM 
942*11963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
943*11963SAfshin.Ardakani@Sun.COM 		*size += info->i_ntargets * sizeof (netdfs_storage_info_t);
944*11963SAfshin.Ardakani@Sun.COM 
945*11963SAfshin.Ardakani@Sun.COM 	target = info->i_targets;
946*11963SAfshin.Ardakani@Sun.COM 	storage = *sinfo;
947*11963SAfshin.Ardakani@Sun.COM 	for (i = 0; i < info->i_ntargets; i++, target++, storage++) {
948*11963SAfshin.Ardakani@Sun.COM 		storage->state = target->t_state;
949*11963SAfshin.Ardakani@Sun.COM 		storage->server = NDR_STRDUP(mxa, target->t_server);
950*11963SAfshin.Ardakani@Sun.COM 		storage->share = NDR_STRDUP(mxa, target->t_share);
951*11963SAfshin.Ardakani@Sun.COM 
952*11963SAfshin.Ardakani@Sun.COM 		if (storage->server == NULL || storage->share == NULL)
953*11963SAfshin.Ardakani@Sun.COM 			return (ERROR_NOT_ENOUGH_MEMORY);
954*11963SAfshin.Ardakani@Sun.COM 
955*11963SAfshin.Ardakani@Sun.COM 		if (size != NULL)
956*11963SAfshin.Ardakani@Sun.COM 			*size += smb_wcequiv_strlen(target->t_server) +
957*11963SAfshin.Ardakani@Sun.COM 			    smb_wcequiv_strlen(target->t_share);
958*11963SAfshin.Ardakani@Sun.COM 	}
959*11963SAfshin.Ardakani@Sun.COM 
960*11963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
961*11963SAfshin.Ardakani@Sun.COM }
962*11963SAfshin.Ardakani@Sun.COM 
963*11963SAfshin.Ardakani@Sun.COM /*
964*11963SAfshin.Ardakani@Sun.COM  * DFS_STORAGE_INFO_1: target information
965*11963SAfshin.Ardakani@Sun.COM  */
966*11963SAfshin.Ardakani@Sun.COM static uint32_t
967*11963SAfshin.Ardakani@Sun.COM netdfs_info_storage1(netdfs_storage_info1_t **sinfo, dfs_info_t *info,
968*11963SAfshin.Ardakani@Sun.COM     ndr_xa_t *mxa, uint32_t *size)
969*11963SAfshin.Ardakani@Sun.COM {
970*11963SAfshin.Ardakani@Sun.COM 	netdfs_storage_info1_t *storage;
971*11963SAfshin.Ardakani@Sun.COM 	dfs_target_t *target;
972*11963SAfshin.Ardakani@Sun.COM 	int i;
973*11963SAfshin.Ardakani@Sun.COM 
974*11963SAfshin.Ardakani@Sun.COM 	*sinfo = NULL;
975*11963SAfshin.Ardakani@Sun.COM 	if (info->i_ntargets == 0)
976*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_SUCCESS);
977*11963SAfshin.Ardakani@Sun.COM 
978*11963SAfshin.Ardakani@Sun.COM 	*sinfo = NDR_NEWN(mxa, netdfs_storage_info1_t, info->i_ntargets);
979*11963SAfshin.Ardakani@Sun.COM 	if (*sinfo == NULL)
980*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
981*11963SAfshin.Ardakani@Sun.COM 
982*11963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
983*11963SAfshin.Ardakani@Sun.COM 		*size += info->i_ntargets * sizeof (netdfs_storage_info1_t);
984*11963SAfshin.Ardakani@Sun.COM 
985*11963SAfshin.Ardakani@Sun.COM 	target = info->i_targets;
986*11963SAfshin.Ardakani@Sun.COM 	storage = *sinfo;
987*11963SAfshin.Ardakani@Sun.COM 	for (i = 0; i < info->i_ntargets; i++, target++, storage++) {
988*11963SAfshin.Ardakani@Sun.COM 		storage->state = target->t_state;
989*11963SAfshin.Ardakani@Sun.COM 		storage->server = NDR_STRDUP(mxa, target->t_server);
990*11963SAfshin.Ardakani@Sun.COM 		storage->share = NDR_STRDUP(mxa, target->t_share);
991*11963SAfshin.Ardakani@Sun.COM 		storage->p_class = target->t_priority.p_class;
992*11963SAfshin.Ardakani@Sun.COM 		storage->p_rank = target->t_priority.p_rank;
993*11963SAfshin.Ardakani@Sun.COM 		storage->p_reserved = 0;
994*11963SAfshin.Ardakani@Sun.COM 
995*11963SAfshin.Ardakani@Sun.COM 		if (storage->server == NULL || storage->share == NULL)
996*11963SAfshin.Ardakani@Sun.COM 			return (ERROR_NOT_ENOUGH_MEMORY);
997*11963SAfshin.Ardakani@Sun.COM 
998*11963SAfshin.Ardakani@Sun.COM 		if (size != NULL)
999*11963SAfshin.Ardakani@Sun.COM 			*size += smb_wcequiv_strlen(target->t_server) +
1000*11963SAfshin.Ardakani@Sun.COM 			    smb_wcequiv_strlen(target->t_share);
1001*11963SAfshin.Ardakani@Sun.COM 	}
1002*11963SAfshin.Ardakani@Sun.COM 
1003*11963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
1004*11963SAfshin.Ardakani@Sun.COM }
1005*11963SAfshin.Ardakani@Sun.COM 
1006*11963SAfshin.Ardakani@Sun.COM /*
1007*11963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_1 for get/enum response
1008*11963SAfshin.Ardakani@Sun.COM  */
1009*11963SAfshin.Ardakani@Sun.COM static uint32_t
1010*11963SAfshin.Ardakani@Sun.COM netdfs_info_1(netdfs_info1_t *info1, dfs_info_t *info, ndr_xa_t *mxa,
1011*11963SAfshin.Ardakani@Sun.COM     uint32_t *size)
1012*11963SAfshin.Ardakani@Sun.COM {
1013*11963SAfshin.Ardakani@Sun.COM 	info1->entry_path = NDR_STRDUP(mxa, info->i_uncpath);
1014*11963SAfshin.Ardakani@Sun.COM 	if (info1->entry_path == NULL)
1015*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
1016*11963SAfshin.Ardakani@Sun.COM 
1017*11963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
1018*11963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info1_t) +
1019*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath);
1020*11963SAfshin.Ardakani@Sun.COM 
1021*11963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
1022*11963SAfshin.Ardakani@Sun.COM }
1023*11963SAfshin.Ardakani@Sun.COM 
1024*11963SAfshin.Ardakani@Sun.COM /*
1025*11963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_2 for get/enum response
1026*11963SAfshin.Ardakani@Sun.COM  */
1027*11963SAfshin.Ardakani@Sun.COM static uint32_t
1028*11963SAfshin.Ardakani@Sun.COM netdfs_info_2(netdfs_info2_t *info2, dfs_info_t *info, ndr_xa_t *mxa,
1029*11963SAfshin.Ardakani@Sun.COM     uint32_t *size)
1030*11963SAfshin.Ardakani@Sun.COM {
1031*11963SAfshin.Ardakani@Sun.COM 	void *entry_path;
1032*11963SAfshin.Ardakani@Sun.COM 	void *comment;
1033*11963SAfshin.Ardakani@Sun.COM 
1034*11963SAfshin.Ardakani@Sun.COM 	entry_path = NDR_STRDUP(mxa, info->i_uncpath);
1035*11963SAfshin.Ardakani@Sun.COM 	comment = NDR_STRDUP(mxa, info->i_comment);
1036*11963SAfshin.Ardakani@Sun.COM 
1037*11963SAfshin.Ardakani@Sun.COM 	if (entry_path == NULL || comment == NULL)
1038*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
1039*11963SAfshin.Ardakani@Sun.COM 
1040*11963SAfshin.Ardakani@Sun.COM 	info2->entry_path = entry_path;
1041*11963SAfshin.Ardakani@Sun.COM 	info2->comment = comment;
1042*11963SAfshin.Ardakani@Sun.COM 	info2->state = info->i_state;
1043*11963SAfshin.Ardakani@Sun.COM 	info2->n_store = info->i_ntargets;
1044*11963SAfshin.Ardakani@Sun.COM 
1045*11963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
1046*11963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info2_t) +
1047*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath) +
1048*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_comment);
1049*11963SAfshin.Ardakani@Sun.COM 
1050*11963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
1051*11963SAfshin.Ardakani@Sun.COM }
1052*11963SAfshin.Ardakani@Sun.COM 
1053*11963SAfshin.Ardakani@Sun.COM /*
1054*11963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_3 for get/enum response
1055*11963SAfshin.Ardakani@Sun.COM  */
1056*11963SAfshin.Ardakani@Sun.COM static uint32_t
1057*11963SAfshin.Ardakani@Sun.COM netdfs_info_3(netdfs_info3_t *info3, dfs_info_t *info, ndr_xa_t *mxa,
1058*11963SAfshin.Ardakani@Sun.COM     uint32_t *size)
1059*11963SAfshin.Ardakani@Sun.COM {
1060*11963SAfshin.Ardakani@Sun.COM 	void *entry_path;
1061*11963SAfshin.Ardakani@Sun.COM 	void *comment;
1062*11963SAfshin.Ardakani@Sun.COM 
1063*11963SAfshin.Ardakani@Sun.COM 	entry_path = NDR_STRDUP(mxa, info->i_uncpath);
1064*11963SAfshin.Ardakani@Sun.COM 	comment = NDR_STRDUP(mxa, info->i_comment);
1065*11963SAfshin.Ardakani@Sun.COM 
1066*11963SAfshin.Ardakani@Sun.COM 	if (entry_path == NULL || comment == NULL)
1067*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
1068*11963SAfshin.Ardakani@Sun.COM 
1069*11963SAfshin.Ardakani@Sun.COM 	info3->entry_path = entry_path;
1070*11963SAfshin.Ardakani@Sun.COM 	info3->comment = comment;
1071*11963SAfshin.Ardakani@Sun.COM 	info3->state = info->i_state;
1072*11963SAfshin.Ardakani@Sun.COM 	info3->n_store = info->i_ntargets;
1073*11963SAfshin.Ardakani@Sun.COM 
1074*11963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
1075*11963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info3_t) +
1076*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath) +
1077*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_comment);
1078*11963SAfshin.Ardakani@Sun.COM 
1079*11963SAfshin.Ardakani@Sun.COM 	return (netdfs_info_storage(&info3->si, info, mxa, size));
1080*11963SAfshin.Ardakani@Sun.COM }
1081*11963SAfshin.Ardakani@Sun.COM 
1082*11963SAfshin.Ardakani@Sun.COM /*
1083*11963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_4 for get/enum response
1084*11963SAfshin.Ardakani@Sun.COM  */
1085*11963SAfshin.Ardakani@Sun.COM static uint32_t
1086*11963SAfshin.Ardakani@Sun.COM netdfs_info_4(netdfs_info4_t *info4, dfs_info_t *info, ndr_xa_t *mxa,
1087*11963SAfshin.Ardakani@Sun.COM     uint32_t *size)
1088*11963SAfshin.Ardakani@Sun.COM {
1089*11963SAfshin.Ardakani@Sun.COM 	void *entry_path;
1090*11963SAfshin.Ardakani@Sun.COM 	void *comment;
1091*11963SAfshin.Ardakani@Sun.COM 
1092*11963SAfshin.Ardakani@Sun.COM 	entry_path = NDR_STRDUP(mxa, info->i_uncpath);
1093*11963SAfshin.Ardakani@Sun.COM 	comment = NDR_STRDUP(mxa, info->i_comment);
1094*11963SAfshin.Ardakani@Sun.COM 
1095*11963SAfshin.Ardakani@Sun.COM 	if (entry_path == NULL || comment == NULL)
1096*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
1097*11963SAfshin.Ardakani@Sun.COM 
1098*11963SAfshin.Ardakani@Sun.COM 	if (!netdfs_guid_fromstr(info->i_guid, &info4->guid))
1099*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_INVALID_DATA);
1100*11963SAfshin.Ardakani@Sun.COM 
1101*11963SAfshin.Ardakani@Sun.COM 	info4->entry_path = entry_path;
1102*11963SAfshin.Ardakani@Sun.COM 	info4->comment = comment;
1103*11963SAfshin.Ardakani@Sun.COM 	info4->state = info->i_state;
1104*11963SAfshin.Ardakani@Sun.COM 	info4->timeout = info->i_timeout;
1105*11963SAfshin.Ardakani@Sun.COM 	info4->n_store = info->i_ntargets;
1106*11963SAfshin.Ardakani@Sun.COM 
1107*11963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
1108*11963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info4_t) +
1109*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath) +
1110*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_comment);
1111*11963SAfshin.Ardakani@Sun.COM 
1112*11963SAfshin.Ardakani@Sun.COM 	return (netdfs_info_storage(&info4->si, info, mxa, size));
1113*11963SAfshin.Ardakani@Sun.COM }
1114*11963SAfshin.Ardakani@Sun.COM 
1115*11963SAfshin.Ardakani@Sun.COM /*
1116*11963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_5 for get/enum response
1117*11963SAfshin.Ardakani@Sun.COM  */
1118*11963SAfshin.Ardakani@Sun.COM static uint32_t
1119*11963SAfshin.Ardakani@Sun.COM netdfs_info_5(netdfs_info5_t *info5, dfs_info_t *info, ndr_xa_t *mxa,
1120*11963SAfshin.Ardakani@Sun.COM     uint32_t *size)
1121*11963SAfshin.Ardakani@Sun.COM {
1122*11963SAfshin.Ardakani@Sun.COM 	void *entry_path;
1123*11963SAfshin.Ardakani@Sun.COM 	void *comment;
1124*11963SAfshin.Ardakani@Sun.COM 
1125*11963SAfshin.Ardakani@Sun.COM 	entry_path = NDR_STRDUP(mxa, info->i_uncpath);
1126*11963SAfshin.Ardakani@Sun.COM 	comment = NDR_STRDUP(mxa, info->i_comment);
1127*11963SAfshin.Ardakani@Sun.COM 
1128*11963SAfshin.Ardakani@Sun.COM 	if (entry_path == NULL || comment == NULL)
1129*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
1130*11963SAfshin.Ardakani@Sun.COM 
1131*11963SAfshin.Ardakani@Sun.COM 	if (!netdfs_guid_fromstr(info->i_guid, &info5->guid))
1132*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_INVALID_DATA);
1133*11963SAfshin.Ardakani@Sun.COM 
1134*11963SAfshin.Ardakani@Sun.COM 	info5->entry_path = entry_path;
1135*11963SAfshin.Ardakani@Sun.COM 	info5->comment = comment;
1136*11963SAfshin.Ardakani@Sun.COM 	info5->state = info->i_state;
1137*11963SAfshin.Ardakani@Sun.COM 	info5->timeout = info->i_timeout;
1138*11963SAfshin.Ardakani@Sun.COM 	info5->flags = info->i_propflags;
1139*11963SAfshin.Ardakani@Sun.COM 	info5->metadata_sz = 0;
1140*11963SAfshin.Ardakani@Sun.COM 	info5->n_store = info->i_ntargets;
1141*11963SAfshin.Ardakani@Sun.COM 
1142*11963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
1143*11963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info5_t) +
1144*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath) +
1145*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_comment);
1146*11963SAfshin.Ardakani@Sun.COM 
1147*11963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
1148*11963SAfshin.Ardakani@Sun.COM }
1149*11963SAfshin.Ardakani@Sun.COM 
1150*11963SAfshin.Ardakani@Sun.COM /*
1151*11963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_6 for get/enum response
1152*11963SAfshin.Ardakani@Sun.COM  */
1153*11963SAfshin.Ardakani@Sun.COM static uint32_t
1154*11963SAfshin.Ardakani@Sun.COM netdfs_info_6(netdfs_info6_t *info6, dfs_info_t *info, ndr_xa_t *mxa,
1155*11963SAfshin.Ardakani@Sun.COM     uint32_t *size)
1156*11963SAfshin.Ardakani@Sun.COM {
1157*11963SAfshin.Ardakani@Sun.COM 	void *entry_path;
1158*11963SAfshin.Ardakani@Sun.COM 	void *comment;
1159*11963SAfshin.Ardakani@Sun.COM 
1160*11963SAfshin.Ardakani@Sun.COM 	entry_path = NDR_STRDUP(mxa, info->i_uncpath);
1161*11963SAfshin.Ardakani@Sun.COM 	comment = NDR_STRDUP(mxa, info->i_comment);
1162*11963SAfshin.Ardakani@Sun.COM 
1163*11963SAfshin.Ardakani@Sun.COM 	if (entry_path == NULL || comment == NULL)
1164*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
1165*11963SAfshin.Ardakani@Sun.COM 
1166*11963SAfshin.Ardakani@Sun.COM 	if (!netdfs_guid_fromstr(info->i_guid, &info6->guid))
1167*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_INVALID_DATA);
1168*11963SAfshin.Ardakani@Sun.COM 
1169*11963SAfshin.Ardakani@Sun.COM 	info6->entry_path = entry_path;
1170*11963SAfshin.Ardakani@Sun.COM 	info6->comment = comment;
1171*11963SAfshin.Ardakani@Sun.COM 	info6->state = info->i_state;
1172*11963SAfshin.Ardakani@Sun.COM 	info6->timeout = info->i_timeout;
1173*11963SAfshin.Ardakani@Sun.COM 	info6->flags = info->i_propflags;
1174*11963SAfshin.Ardakani@Sun.COM 	info6->metadata_sz = 0;
1175*11963SAfshin.Ardakani@Sun.COM 	info6->n_store = info->i_ntargets;
1176*11963SAfshin.Ardakani@Sun.COM 
1177*11963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
1178*11963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info6_t) +
1179*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath) +
1180*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_comment);
1181*11963SAfshin.Ardakani@Sun.COM 
1182*11963SAfshin.Ardakani@Sun.COM 	return (netdfs_info_storage1(&info6->si, info, mxa, size));
1183*11963SAfshin.Ardakani@Sun.COM }
1184*11963SAfshin.Ardakani@Sun.COM 
1185*11963SAfshin.Ardakani@Sun.COM /*
1186*11963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_100 for Get response
1187*11963SAfshin.Ardakani@Sun.COM  */
1188*11963SAfshin.Ardakani@Sun.COM static uint32_t
1189*11963SAfshin.Ardakani@Sun.COM netdfs_info_100(netdfs_info100_t *info100, dfs_info_t *info, ndr_xa_t *mxa,
1190*11963SAfshin.Ardakani@Sun.COM     uint32_t *size)
1191*11963SAfshin.Ardakani@Sun.COM {
1192*11963SAfshin.Ardakani@Sun.COM 	info100->comment = NDR_STRDUP(mxa, info->i_comment);
1193*11963SAfshin.Ardakani@Sun.COM 	if (info100->comment == NULL)
1194*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
1195*11963SAfshin.Ardakani@Sun.COM 
1196*11963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
1197*11963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info100_t) +
1198*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_comment);
1199*11963SAfshin.Ardakani@Sun.COM 
1200*11963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
1201*11963SAfshin.Ardakani@Sun.COM }
1202*11963SAfshin.Ardakani@Sun.COM 
1203*11963SAfshin.Ardakani@Sun.COM /*
1204*11963SAfshin.Ardakani@Sun.COM  * Sets a DFS_INFO_300 for Enum response
1205*11963SAfshin.Ardakani@Sun.COM  */
1206*11963SAfshin.Ardakani@Sun.COM static uint32_t
1207*11963SAfshin.Ardakani@Sun.COM netdfs_info_300(netdfs_info300_t *info300, dfs_info_t *info, ndr_xa_t *mxa,
1208*11963SAfshin.Ardakani@Sun.COM     uint32_t *size)
1209*11963SAfshin.Ardakani@Sun.COM {
1210*11963SAfshin.Ardakani@Sun.COM 	info300->dfsname = NDR_STRDUP(mxa, info->i_uncpath);
1211*11963SAfshin.Ardakani@Sun.COM 	if (info300->dfsname == NULL)
1212*11963SAfshin.Ardakani@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
1213*11963SAfshin.Ardakani@Sun.COM 
1214*11963SAfshin.Ardakani@Sun.COM 	info300->flavor = DFS_VOLUME_FLAVOR_STANDALONE;
1215*11963SAfshin.Ardakani@Sun.COM 	if (size != NULL)
1216*11963SAfshin.Ardakani@Sun.COM 		*size = sizeof (netdfs_info300_t) +
1217*11963SAfshin.Ardakani@Sun.COM 		    smb_wcequiv_strlen(info->i_uncpath);
1218*11963SAfshin.Ardakani@Sun.COM 
1219*11963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
1220*11963SAfshin.Ardakani@Sun.COM }
1221*11963SAfshin.Ardakani@Sun.COM 
1222*11963SAfshin.Ardakani@Sun.COM /*
1223*11963SAfshin.Ardakani@Sun.COM  * Common enumeration function
1224*11963SAfshin.Ardakani@Sun.COM  */
1225*11963SAfshin.Ardakani@Sun.COM static uint32_t
1226*11963SAfshin.Ardakani@Sun.COM netdfs_enum_common(netdfs_enumhandle_t *de, ndr_xa_t *mxa)
1227*11963SAfshin.Ardakani@Sun.COM {
1228*11963SAfshin.Ardakani@Sun.COM 	netdfs_info1_t *info1 = de->de_entries;
1229*11963SAfshin.Ardakani@Sun.COM 	netdfs_info2_t *info2 = de->de_entries;
1230*11963SAfshin.Ardakani@Sun.COM 	netdfs_info3_t *info3 = de->de_entries;
1231*11963SAfshin.Ardakani@Sun.COM 	netdfs_info4_t *info4 = de->de_entries;
1232*11963SAfshin.Ardakani@Sun.COM 	netdfs_info5_t *info5 = de->de_entries;
1233*11963SAfshin.Ardakani@Sun.COM 	netdfs_info6_t *info6 = de->de_entries;
1234*11963SAfshin.Ardakani@Sun.COM 	netdfs_info300_t *info300 = de->de_entries;
1235*11963SAfshin.Ardakani@Sun.COM 	dfs_info_t dfsinfo;
1236*11963SAfshin.Ardakani@Sun.COM 	smb_cache_cursor_t cursor;
1237*11963SAfshin.Ardakani@Sun.COM 	dfs_nscnode_t nscnode;
1238*11963SAfshin.Ardakani@Sun.COM 	uint32_t status;
1239*11963SAfshin.Ardakani@Sun.COM 	uint32_t itemsz;
1240*11963SAfshin.Ardakani@Sun.COM 
1241*11963SAfshin.Ardakani@Sun.COM 	dfs_cache_iterinit(&cursor);
1242*11963SAfshin.Ardakani@Sun.COM 
1243*11963SAfshin.Ardakani@Sun.COM 	de->de_nitems = 0;
1244*11963SAfshin.Ardakani@Sun.COM 	while (dfs_cache_iterate(&cursor, &nscnode)) {
1245*11963SAfshin.Ardakani@Sun.COM 		if (de->de_nskip > 0) {
1246*11963SAfshin.Ardakani@Sun.COM 			de->de_nskip--;
1247*11963SAfshin.Ardakani@Sun.COM 			continue;
1248*11963SAfshin.Ardakani@Sun.COM 		}
1249*11963SAfshin.Ardakani@Sun.COM 
1250*11963SAfshin.Ardakani@Sun.COM 		if (de->de_nitems == de->de_nmax)
1251*11963SAfshin.Ardakani@Sun.COM 			break;
1252*11963SAfshin.Ardakani@Sun.COM 
1253*11963SAfshin.Ardakani@Sun.COM 		status = dfs_cache_getinfo(&nscnode, &dfsinfo, de->de_level);
1254*11963SAfshin.Ardakani@Sun.COM 		if (status != ERROR_SUCCESS)
1255*11963SAfshin.Ardakani@Sun.COM 			continue;
1256*11963SAfshin.Ardakani@Sun.COM 
1257*11963SAfshin.Ardakani@Sun.COM 		switch (de->de_level) {
1258*11963SAfshin.Ardakani@Sun.COM 		case 1:
1259*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_1(info1, &dfsinfo, mxa, &itemsz);
1260*11963SAfshin.Ardakani@Sun.COM 			info1++;
1261*11963SAfshin.Ardakani@Sun.COM 			break;
1262*11963SAfshin.Ardakani@Sun.COM 		case 2:
1263*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_2(info2, &dfsinfo, mxa, &itemsz);
1264*11963SAfshin.Ardakani@Sun.COM 			info2++;
1265*11963SAfshin.Ardakani@Sun.COM 			break;
1266*11963SAfshin.Ardakani@Sun.COM 		case 3:
1267*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_3(info3, &dfsinfo, mxa, &itemsz);
1268*11963SAfshin.Ardakani@Sun.COM 			info3++;
1269*11963SAfshin.Ardakani@Sun.COM 			break;
1270*11963SAfshin.Ardakani@Sun.COM 		case 4:
1271*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_4(info4, &dfsinfo, mxa, &itemsz);
1272*11963SAfshin.Ardakani@Sun.COM 			info4++;
1273*11963SAfshin.Ardakani@Sun.COM 			break;
1274*11963SAfshin.Ardakani@Sun.COM 		case 5:
1275*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_5(info5, &dfsinfo, mxa, &itemsz);
1276*11963SAfshin.Ardakani@Sun.COM 			info5++;
1277*11963SAfshin.Ardakani@Sun.COM 			break;
1278*11963SAfshin.Ardakani@Sun.COM 		case 6:
1279*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_6(info6, &dfsinfo, mxa, &itemsz);
1280*11963SAfshin.Ardakani@Sun.COM 			info6++;
1281*11963SAfshin.Ardakani@Sun.COM 			break;
1282*11963SAfshin.Ardakani@Sun.COM 		case 300:
1283*11963SAfshin.Ardakani@Sun.COM 			status = netdfs_info_300(info300, &dfsinfo, mxa,
1284*11963SAfshin.Ardakani@Sun.COM 			    &itemsz);
1285*11963SAfshin.Ardakani@Sun.COM 			info300++;
1286*11963SAfshin.Ardakani@Sun.COM 			break;
1287*11963SAfshin.Ardakani@Sun.COM 		default:
1288*11963SAfshin.Ardakani@Sun.COM 			status = ERROR_INVALID_LEVEL;
1289*11963SAfshin.Ardakani@Sun.COM 		}
1290*11963SAfshin.Ardakani@Sun.COM 
1291*11963SAfshin.Ardakani@Sun.COM 		dfs_info_free(&dfsinfo);
1292*11963SAfshin.Ardakani@Sun.COM 
1293*11963SAfshin.Ardakani@Sun.COM 		if (status != ERROR_SUCCESS)
1294*11963SAfshin.Ardakani@Sun.COM 			return (status);
1295*11963SAfshin.Ardakani@Sun.COM 
1296*11963SAfshin.Ardakani@Sun.COM 		if (de->de_nmax == 1) {
1297*11963SAfshin.Ardakani@Sun.COM 			de->de_nitems = 1;
1298*11963SAfshin.Ardakani@Sun.COM 			break;
1299*11963SAfshin.Ardakani@Sun.COM 		}
1300*11963SAfshin.Ardakani@Sun.COM 
1301*11963SAfshin.Ardakani@Sun.COM 		if (itemsz > de->de_bavail)
1302*11963SAfshin.Ardakani@Sun.COM 			break;
1303*11963SAfshin.Ardakani@Sun.COM 
1304*11963SAfshin.Ardakani@Sun.COM 		de->de_bavail -= itemsz;
1305*11963SAfshin.Ardakani@Sun.COM 		de->de_nitems++;
1306*11963SAfshin.Ardakani@Sun.COM 	}
1307*11963SAfshin.Ardakani@Sun.COM 
1308*11963SAfshin.Ardakani@Sun.COM 	de->de_resume += de->de_nitems;
1309*11963SAfshin.Ardakani@Sun.COM 	return (ERROR_SUCCESS);
1310*11963SAfshin.Ardakani@Sun.COM }
1311*11963SAfshin.Ardakani@Sun.COM 
1312*11963SAfshin.Ardakani@Sun.COM /*
1313*11963SAfshin.Ardakani@Sun.COM  * Creates intermediate directories of a link from the root share path.
13145331Samw  *
1315*11963SAfshin.Ardakani@Sun.COM  * TODO: directories should be created by smbsrv to get Windows compatible
1316*11963SAfshin.Ardakani@Sun.COM  * ACL inheritance.
13175331Samw  */
1318*11963SAfshin.Ardakani@Sun.COM static void
1319*11963SAfshin.Ardakani@Sun.COM netdfs_path_create(const char *path)
13205331Samw {
1321*11963SAfshin.Ardakani@Sun.COM 	char dirpath[DFS_PATH_MAX];
1322*11963SAfshin.Ardakani@Sun.COM 	mode_t mode;
13235331Samw 	char *p;
13245331Samw 
1325*11963SAfshin.Ardakani@Sun.COM 	(void) strlcpy(dirpath, path, DFS_PATH_MAX);
13265331Samw 
1327*11963SAfshin.Ardakani@Sun.COM 	/* drop the link itself from the path */
1328*11963SAfshin.Ardakani@Sun.COM 	if ((p = strrchr(dirpath, '/')) != NULL) {
13295331Samw 		*p = '\0';
1330*11963SAfshin.Ardakani@Sun.COM 		mode = umask(0);
1331*11963SAfshin.Ardakani@Sun.COM 		(void) mkdirp(dirpath, 0777);
1332*11963SAfshin.Ardakani@Sun.COM 		(void) umask(mode);
1333*11963SAfshin.Ardakani@Sun.COM 	}
1334*11963SAfshin.Ardakani@Sun.COM }
13355331Samw 
1336*11963SAfshin.Ardakani@Sun.COM /*
1337*11963SAfshin.Ardakani@Sun.COM  * Removes empty directories
1338*11963SAfshin.Ardakani@Sun.COM  */
1339*11963SAfshin.Ardakani@Sun.COM static void
1340*11963SAfshin.Ardakani@Sun.COM netdfs_path_remove(smb_unc_t *unc)
1341*11963SAfshin.Ardakani@Sun.COM {
1342*11963SAfshin.Ardakani@Sun.COM 	char rootdir[DFS_PATH_MAX];
1343*11963SAfshin.Ardakani@Sun.COM 	char relpath[DFS_PATH_MAX];
1344*11963SAfshin.Ardakani@Sun.COM 	char dir[DFS_PATH_MAX];
1345*11963SAfshin.Ardakani@Sun.COM 	uint32_t status;
1346*11963SAfshin.Ardakani@Sun.COM 	char *p;
13475331Samw 
1348*11963SAfshin.Ardakani@Sun.COM 	status = dfs_namespace_path(unc->unc_share, rootdir, DFS_PATH_MAX);
1349*11963SAfshin.Ardakani@Sun.COM 	if ((status == ERROR_SUCCESS) && (chdir(rootdir) == 0)) {
1350*11963SAfshin.Ardakani@Sun.COM 		(void) strlcpy(relpath, unc->unc_path, DFS_PATH_MAX);
1351*11963SAfshin.Ardakani@Sun.COM 		/* drop the link itself from the path */
1352*11963SAfshin.Ardakani@Sun.COM 		if ((p = strrchr(relpath, '/')) != NULL) {
13535331Samw 			*p = '\0';
1354*11963SAfshin.Ardakani@Sun.COM 			(void) rmdirp(relpath, dir);
13555331Samw 		}
13565331Samw 	}
1357*11963SAfshin.Ardakani@Sun.COM }
13585331Samw 
1359*11963SAfshin.Ardakani@Sun.COM /*
1360*11963SAfshin.Ardakani@Sun.COM  * Converts the guid string into binary format in network byte order.
1361*11963SAfshin.Ardakani@Sun.COM  */
1362*11963SAfshin.Ardakani@Sun.COM static boolean_t
1363*11963SAfshin.Ardakani@Sun.COM netdfs_guid_fromstr(char *guid_str, netdfs_uuid_t *guid)
1364*11963SAfshin.Ardakani@Sun.COM {
1365*11963SAfshin.Ardakani@Sun.COM 	uuid_t uuid;
13665331Samw 
1367*11963SAfshin.Ardakani@Sun.COM 	if (uuid_parse(guid_str, uuid) != 0)
1368*11963SAfshin.Ardakani@Sun.COM 		return (B_FALSE);
1369*11963SAfshin.Ardakani@Sun.COM 
1370*11963SAfshin.Ardakani@Sun.COM 	bcopy(&uuid, guid, sizeof (uuid_t));
13715331Samw 
1372*11963SAfshin.Ardakani@Sun.COM 	guid->data1 = htonl(guid->data1);
1373*11963SAfshin.Ardakani@Sun.COM 	guid->data2 = htons(guid->data2);
1374*11963SAfshin.Ardakani@Sun.COM 	guid->data3 = htons(guid->data3);
1375*11963SAfshin.Ardakani@Sun.COM 
1376*11963SAfshin.Ardakani@Sun.COM 	return (B_TRUE);
13775331Samw }
1378