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 = ⌖
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 = ⌖
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