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 */ 21*12508Samw@Sun.COM 225331Samw /* 23*12508Samw@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 39*12508Samw@Sun.COM #include <smbsrv/libmlsvc.h> 405331Samw #include <smbsrv/nmpipes.h> 41*12508Samw@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 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 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 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 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 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 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 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 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 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 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 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 71211963SAfshin.Ardakani@Sun.COM /* For now only allow a single standalone namespace */ 713*12508Samw@Sun.COM if (dfs_namespace_count() == 0) { 71411963SAfshin.Ardakani@Sun.COM param->status = dfs_namespace_add(share, comment); 715*12508Samw@Sun.COM if (param->status == ERROR_SUCCESS) 716*12508Samw@Sun.COM (void) smb_config_setnum(SMB_CI_DFS_STDROOT_NUM, 1); 717*12508Samw@Sun.COM } else { 71811963SAfshin.Ardakani@Sun.COM param->status = ERROR_NOT_SUPPORTED; 719*12508Samw@Sun.COM } 72011963SAfshin.Ardakani@Sun.COM 72111963SAfshin.Ardakani@Sun.COM dfs_setpriv(PRIV_OFF); 7228334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 7235331Samw } 7245331Samw 7255331Samw /* 72611963SAfshin.Ardakani@Sun.COM * Deletes the specified stand-alone DFS namespace. The DFS namespace can be 72711963SAfshin.Ardakani@Sun.COM * removed without first removing all of the links in it. 72811963SAfshin.Ardakani@Sun.COM * 72911963SAfshin.Ardakani@Sun.COM * [MS-DFSNM]: NetrDfsRemoveStdRoot (Opnum 13) 7305331Samw */ 7315331Samw /*ARGSUSED*/ 7325331Samw static int 7338334SJose.Borrego@Sun.COM netdfs_s_remstdroot(void *arg, ndr_xa_t *mxa) 7345331Samw { 7355331Samw struct netdfs_remstdroot *param = arg; 73611963SAfshin.Ardakani@Sun.COM const char *share = (const char *)param->share; 7375331Samw 73811963SAfshin.Ardakani@Sun.COM dfs_setpriv(PRIV_ON); 73911963SAfshin.Ardakani@Sun.COM 740*12508Samw@Sun.COM if (ndr_is_admin(mxa)) { 74111963SAfshin.Ardakani@Sun.COM param->status = dfs_namespace_remove(share); 742*12508Samw@Sun.COM if (param->status == ERROR_SUCCESS) 743*12508Samw@Sun.COM (void) smb_config_setnum(SMB_CI_DFS_STDROOT_NUM, 0); 744*12508Samw@Sun.COM } else { 74511963SAfshin.Ardakani@Sun.COM param->status = ERROR_ACCESS_DENIED; 746*12508Samw@Sun.COM } 74711963SAfshin.Ardakani@Sun.COM 74811963SAfshin.Ardakani@Sun.COM dfs_setpriv(PRIV_OFF); 7498334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 7505331Samw } 7515331Samw 7525331Samw /* 75311963SAfshin.Ardakani@Sun.COM * Enumerates the DFS roots hosted on a server, or DFS links of a namespace 75411963SAfshin.Ardakani@Sun.COM * hosted by the server. Depending on the information level, the targets 75511963SAfshin.Ardakani@Sun.COM * associated with the roots and links are also displayed 7565331Samw * 75711963SAfshin.Ardakani@Sun.COM * Does not need to be supported for DFS version 1 75811963SAfshin.Ardakani@Sun.COM * 75911963SAfshin.Ardakani@Sun.COM * [MS-DFSNM] NetrDfsEnumEx (Opnum 21) 7605331Samw */ 76111963SAfshin.Ardakani@Sun.COM /*ARGSUSED*/ 7625331Samw static int 7638334SJose.Borrego@Sun.COM netdfs_s_enumex(void *arg, ndr_xa_t *mxa) 7645331Samw { 7655331Samw struct netdfs_enumex *param = arg; 7665331Samw 7675331Samw bzero(param->info, sizeof (struct netdfs_enumex)); 76811963SAfshin.Ardakani@Sun.COM param->status = ERROR_NOT_SUPPORTED; 7698334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 7705331Samw } 7715331Samw 7725331Samw /* 77311963SAfshin.Ardakani@Sun.COM * Sets the comment for the DFS link/root. 77411963SAfshin.Ardakani@Sun.COM */ 77511963SAfshin.Ardakani@Sun.COM static uint32_t 77611963SAfshin.Ardakani@Sun.COM netdfs_setinfo_100(dfs_path_t *path, netdfs_info100_t *netinfo) 77711963SAfshin.Ardakani@Sun.COM { 77811963SAfshin.Ardakani@Sun.COM dfs_info_t info; 77911963SAfshin.Ardakani@Sun.COM uint32_t status; 78011963SAfshin.Ardakani@Sun.COM char *cmnt = (char *)netinfo->comment; 78111963SAfshin.Ardakani@Sun.COM 78211963SAfshin.Ardakani@Sun.COM bzero(&info, sizeof (dfs_info_t)); 78311963SAfshin.Ardakani@Sun.COM if (cmnt != NULL) 78411963SAfshin.Ardakani@Sun.COM (void) strlcpy(info.i_comment, cmnt, sizeof (info.i_comment)); 78511963SAfshin.Ardakani@Sun.COM 78611963SAfshin.Ardakani@Sun.COM if (path->p_type == DFS_OBJECT_LINK) 78711963SAfshin.Ardakani@Sun.COM status = dfs_link_setinfo(path->p_fspath, &info, 100); 78811963SAfshin.Ardakani@Sun.COM else 78911963SAfshin.Ardakani@Sun.COM status = dfs_root_setinfo(path->p_fspath, &info, 100); 79011963SAfshin.Ardakani@Sun.COM 79111963SAfshin.Ardakani@Sun.COM return (status); 79211963SAfshin.Ardakani@Sun.COM } 79311963SAfshin.Ardakani@Sun.COM 79411963SAfshin.Ardakani@Sun.COM /* 79511963SAfshin.Ardakani@Sun.COM * Sets the state for the DFS root/link or its target. 79611963SAfshin.Ardakani@Sun.COM */ 79711963SAfshin.Ardakani@Sun.COM static uint32_t 79811963SAfshin.Ardakani@Sun.COM netdfs_setinfo_101(dfs_path_t *path, netdfs_info101_t *netinfo, 79911963SAfshin.Ardakani@Sun.COM const char *t_server, const char *t_share) 80011963SAfshin.Ardakani@Sun.COM { 80111963SAfshin.Ardakani@Sun.COM dfs_info_t info; 80211963SAfshin.Ardakani@Sun.COM dfs_target_t target; 80311963SAfshin.Ardakani@Sun.COM uint32_t status; 80411963SAfshin.Ardakani@Sun.COM 80511963SAfshin.Ardakani@Sun.COM bzero(&info, sizeof (dfs_info_t)); 80611963SAfshin.Ardakani@Sun.COM bzero(&target, sizeof (dfs_target_t)); 80711963SAfshin.Ardakani@Sun.COM 80811963SAfshin.Ardakani@Sun.COM if (t_server == NULL && t_share == NULL) { 80911963SAfshin.Ardakani@Sun.COM info.i_state = netinfo->state; 81011963SAfshin.Ardakani@Sun.COM } else { 81111963SAfshin.Ardakani@Sun.COM target.t_state = netinfo->state; 81211963SAfshin.Ardakani@Sun.COM (void) strlcpy(target.t_server, t_server, 81311963SAfshin.Ardakani@Sun.COM sizeof (target.t_server)); 81411963SAfshin.Ardakani@Sun.COM (void) strlcpy(target.t_share, t_share, 81511963SAfshin.Ardakani@Sun.COM sizeof (target.t_share)); 81611963SAfshin.Ardakani@Sun.COM info.i_targets = ⌖ 81711963SAfshin.Ardakani@Sun.COM } 81811963SAfshin.Ardakani@Sun.COM 81911963SAfshin.Ardakani@Sun.COM if (path->p_type == DFS_OBJECT_LINK) 82011963SAfshin.Ardakani@Sun.COM status = dfs_link_setinfo(path->p_fspath, &info, 101); 82111963SAfshin.Ardakani@Sun.COM else 82211963SAfshin.Ardakani@Sun.COM status = dfs_root_setinfo(path->p_fspath, &info, 101); 82311963SAfshin.Ardakani@Sun.COM 82411963SAfshin.Ardakani@Sun.COM return (status); 82511963SAfshin.Ardakani@Sun.COM } 82611963SAfshin.Ardakani@Sun.COM 82711963SAfshin.Ardakani@Sun.COM /* 82811963SAfshin.Ardakani@Sun.COM * Sets the timeout value of the DFS link/root. 82911963SAfshin.Ardakani@Sun.COM */ 83011963SAfshin.Ardakani@Sun.COM static uint32_t 83111963SAfshin.Ardakani@Sun.COM netdfs_setinfo_102(dfs_path_t *path, netdfs_info102_t *netinfo) 83211963SAfshin.Ardakani@Sun.COM { 83311963SAfshin.Ardakani@Sun.COM dfs_info_t info; 83411963SAfshin.Ardakani@Sun.COM uint32_t status; 83511963SAfshin.Ardakani@Sun.COM 83611963SAfshin.Ardakani@Sun.COM bzero(&info, sizeof (dfs_info_t)); 83711963SAfshin.Ardakani@Sun.COM info.i_timeout = netinfo->timeout; 83811963SAfshin.Ardakani@Sun.COM 83911963SAfshin.Ardakani@Sun.COM if (path->p_type == DFS_OBJECT_LINK) 84011963SAfshin.Ardakani@Sun.COM status = dfs_link_setinfo(path->p_fspath, &info, 102); 84111963SAfshin.Ardakani@Sun.COM else 84211963SAfshin.Ardakani@Sun.COM status = dfs_root_setinfo(path->p_fspath, &info, 102); 84311963SAfshin.Ardakani@Sun.COM 84411963SAfshin.Ardakani@Sun.COM return (status); 84511963SAfshin.Ardakani@Sun.COM } 84611963SAfshin.Ardakani@Sun.COM 84711963SAfshin.Ardakani@Sun.COM /* 84811963SAfshin.Ardakani@Sun.COM * Sets the property flags for the root or link. 84911963SAfshin.Ardakani@Sun.COM */ 85011963SAfshin.Ardakani@Sun.COM static uint32_t 85111963SAfshin.Ardakani@Sun.COM netdfs_setinfo_103(dfs_path_t *path, netdfs_info103_t *netinfo) 85211963SAfshin.Ardakani@Sun.COM { 85311963SAfshin.Ardakani@Sun.COM dfs_info_t info; 85411963SAfshin.Ardakani@Sun.COM uint32_t status; 85511963SAfshin.Ardakani@Sun.COM 85611963SAfshin.Ardakani@Sun.COM bzero(&info, sizeof (dfs_info_t)); 85711963SAfshin.Ardakani@Sun.COM info.i_propflags = 85811963SAfshin.Ardakani@Sun.COM netinfo->property_flags & netinfo->property_flag_mask; 85911963SAfshin.Ardakani@Sun.COM 86011963SAfshin.Ardakani@Sun.COM if (path->p_type == DFS_OBJECT_LINK) 86111963SAfshin.Ardakani@Sun.COM status = dfs_link_setinfo(path->p_fspath, &info, 103); 86211963SAfshin.Ardakani@Sun.COM else 86311963SAfshin.Ardakani@Sun.COM status = dfs_root_setinfo(path->p_fspath, &info, 103); 86411963SAfshin.Ardakani@Sun.COM 86511963SAfshin.Ardakani@Sun.COM return (status); 86611963SAfshin.Ardakani@Sun.COM } 86711963SAfshin.Ardakani@Sun.COM 86811963SAfshin.Ardakani@Sun.COM /* 86911963SAfshin.Ardakani@Sun.COM * Sets the target priority rank and class for the root target or link target 87011963SAfshin.Ardakani@Sun.COM */ 87111963SAfshin.Ardakani@Sun.COM static uint32_t 87211963SAfshin.Ardakani@Sun.COM netdfs_setinfo_104(dfs_path_t *path, netdfs_info104_t *netinfo, 87311963SAfshin.Ardakani@Sun.COM const char *t_server, const char *t_share) 87411963SAfshin.Ardakani@Sun.COM { 87511963SAfshin.Ardakani@Sun.COM dfs_info_t info; 87611963SAfshin.Ardakani@Sun.COM dfs_target_t target; 87711963SAfshin.Ardakani@Sun.COM uint32_t status; 87811963SAfshin.Ardakani@Sun.COM 87911963SAfshin.Ardakani@Sun.COM if ((t_server == NULL) || (t_share == NULL)) 88011963SAfshin.Ardakani@Sun.COM return (ERROR_INVALID_PARAMETER); 88111963SAfshin.Ardakani@Sun.COM 88211963SAfshin.Ardakani@Sun.COM bzero(&info, sizeof (dfs_info_t)); 88311963SAfshin.Ardakani@Sun.COM bzero(&target, sizeof (dfs_target_t)); 88411963SAfshin.Ardakani@Sun.COM 88511963SAfshin.Ardakani@Sun.COM target.t_priority.p_class = netinfo->priority_class; 88611963SAfshin.Ardakani@Sun.COM target.t_priority.p_rank = netinfo->priority_rank; 88711963SAfshin.Ardakani@Sun.COM (void) strlcpy(target.t_server, t_server, sizeof (target.t_server)); 88811963SAfshin.Ardakani@Sun.COM (void) strlcpy(target.t_share, t_share, sizeof (target.t_share)); 88911963SAfshin.Ardakani@Sun.COM info.i_targets = ⌖ 89011963SAfshin.Ardakani@Sun.COM 89111963SAfshin.Ardakani@Sun.COM if (path->p_type == DFS_OBJECT_LINK) 89211963SAfshin.Ardakani@Sun.COM status = dfs_link_setinfo(path->p_fspath, &info, 104); 89311963SAfshin.Ardakani@Sun.COM else 89411963SAfshin.Ardakani@Sun.COM status = dfs_root_setinfo(path->p_fspath, &info, 104); 89511963SAfshin.Ardakani@Sun.COM 89611963SAfshin.Ardakani@Sun.COM return (status); 89711963SAfshin.Ardakani@Sun.COM } 89811963SAfshin.Ardakani@Sun.COM 89911963SAfshin.Ardakani@Sun.COM /* 90011963SAfshin.Ardakani@Sun.COM * Sets the comment, state, time-out information, and property flags for the 90111963SAfshin.Ardakani@Sun.COM * namespace root or link specified in DfsInfo. Does not apply to a root target 90211963SAfshin.Ardakani@Sun.COM * or link target. 90311963SAfshin.Ardakani@Sun.COM */ 90411963SAfshin.Ardakani@Sun.COM static uint32_t 90511963SAfshin.Ardakani@Sun.COM netdfs_setinfo_105(dfs_path_t *path, netdfs_info105_t *netinfo) 90611963SAfshin.Ardakani@Sun.COM { 90711963SAfshin.Ardakani@Sun.COM dfs_info_t info; 90811963SAfshin.Ardakani@Sun.COM uint32_t status; 90911963SAfshin.Ardakani@Sun.COM char *cmnt = (char *)netinfo->comment; 91011963SAfshin.Ardakani@Sun.COM 91111963SAfshin.Ardakani@Sun.COM bzero(&info, sizeof (dfs_info_t)); 91211963SAfshin.Ardakani@Sun.COM 91311963SAfshin.Ardakani@Sun.COM if (cmnt != NULL) 91411963SAfshin.Ardakani@Sun.COM (void) strlcpy(info.i_comment, cmnt, sizeof (info.i_comment)); 91511963SAfshin.Ardakani@Sun.COM info.i_state = netinfo->state; 91611963SAfshin.Ardakani@Sun.COM info.i_timeout = netinfo->timeout; 91711963SAfshin.Ardakani@Sun.COM info.i_propflags = 91811963SAfshin.Ardakani@Sun.COM netinfo->property_flags & netinfo->property_flag_mask; 91911963SAfshin.Ardakani@Sun.COM 92011963SAfshin.Ardakani@Sun.COM if (path->p_type == DFS_OBJECT_LINK) 92111963SAfshin.Ardakani@Sun.COM status = dfs_link_setinfo(path->p_fspath, &info, 105); 92211963SAfshin.Ardakani@Sun.COM else 92311963SAfshin.Ardakani@Sun.COM status = dfs_root_setinfo(path->p_fspath, &info, 105); 92411963SAfshin.Ardakani@Sun.COM 92511963SAfshin.Ardakani@Sun.COM return (status); 92611963SAfshin.Ardakani@Sun.COM } 92711963SAfshin.Ardakani@Sun.COM 92811963SAfshin.Ardakani@Sun.COM /* 92911963SAfshin.Ardakani@Sun.COM * DFS_STORAGE_INFO: target information 93011963SAfshin.Ardakani@Sun.COM */ 93111963SAfshin.Ardakani@Sun.COM static uint32_t 93211963SAfshin.Ardakani@Sun.COM netdfs_info_storage(netdfs_storage_info_t **sinfo, dfs_info_t *info, 93311963SAfshin.Ardakani@Sun.COM ndr_xa_t *mxa, uint32_t *size) 93411963SAfshin.Ardakani@Sun.COM { 93511963SAfshin.Ardakani@Sun.COM netdfs_storage_info_t *storage; 93611963SAfshin.Ardakani@Sun.COM dfs_target_t *target; 93711963SAfshin.Ardakani@Sun.COM int i; 93811963SAfshin.Ardakani@Sun.COM 93911963SAfshin.Ardakani@Sun.COM *sinfo = NULL; 94011963SAfshin.Ardakani@Sun.COM if (info->i_ntargets == 0) 94111963SAfshin.Ardakani@Sun.COM return (ERROR_SUCCESS); 94211963SAfshin.Ardakani@Sun.COM 94311963SAfshin.Ardakani@Sun.COM *sinfo = NDR_NEWN(mxa, netdfs_storage_info_t, info->i_ntargets); 94411963SAfshin.Ardakani@Sun.COM if (*sinfo == NULL) 94511963SAfshin.Ardakani@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 94611963SAfshin.Ardakani@Sun.COM 94711963SAfshin.Ardakani@Sun.COM if (size != NULL) 94811963SAfshin.Ardakani@Sun.COM *size += info->i_ntargets * sizeof (netdfs_storage_info_t); 94911963SAfshin.Ardakani@Sun.COM 95011963SAfshin.Ardakani@Sun.COM target = info->i_targets; 95111963SAfshin.Ardakani@Sun.COM storage = *sinfo; 95211963SAfshin.Ardakani@Sun.COM for (i = 0; i < info->i_ntargets; i++, target++, storage++) { 95311963SAfshin.Ardakani@Sun.COM storage->state = target->t_state; 95411963SAfshin.Ardakani@Sun.COM storage->server = NDR_STRDUP(mxa, target->t_server); 95511963SAfshin.Ardakani@Sun.COM storage->share = NDR_STRDUP(mxa, target->t_share); 95611963SAfshin.Ardakani@Sun.COM 95711963SAfshin.Ardakani@Sun.COM if (storage->server == NULL || storage->share == NULL) 95811963SAfshin.Ardakani@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 95911963SAfshin.Ardakani@Sun.COM 96011963SAfshin.Ardakani@Sun.COM if (size != NULL) 96111963SAfshin.Ardakani@Sun.COM *size += smb_wcequiv_strlen(target->t_server) + 96211963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(target->t_share); 96311963SAfshin.Ardakani@Sun.COM } 96411963SAfshin.Ardakani@Sun.COM 96511963SAfshin.Ardakani@Sun.COM return (ERROR_SUCCESS); 96611963SAfshin.Ardakani@Sun.COM } 96711963SAfshin.Ardakani@Sun.COM 96811963SAfshin.Ardakani@Sun.COM /* 96911963SAfshin.Ardakani@Sun.COM * DFS_STORAGE_INFO_1: target information 97011963SAfshin.Ardakani@Sun.COM */ 97111963SAfshin.Ardakani@Sun.COM static uint32_t 97211963SAfshin.Ardakani@Sun.COM netdfs_info_storage1(netdfs_storage_info1_t **sinfo, dfs_info_t *info, 97311963SAfshin.Ardakani@Sun.COM ndr_xa_t *mxa, uint32_t *size) 97411963SAfshin.Ardakani@Sun.COM { 97511963SAfshin.Ardakani@Sun.COM netdfs_storage_info1_t *storage; 97611963SAfshin.Ardakani@Sun.COM dfs_target_t *target; 97711963SAfshin.Ardakani@Sun.COM int i; 97811963SAfshin.Ardakani@Sun.COM 97911963SAfshin.Ardakani@Sun.COM *sinfo = NULL; 98011963SAfshin.Ardakani@Sun.COM if (info->i_ntargets == 0) 98111963SAfshin.Ardakani@Sun.COM return (ERROR_SUCCESS); 98211963SAfshin.Ardakani@Sun.COM 98311963SAfshin.Ardakani@Sun.COM *sinfo = NDR_NEWN(mxa, netdfs_storage_info1_t, info->i_ntargets); 98411963SAfshin.Ardakani@Sun.COM if (*sinfo == NULL) 98511963SAfshin.Ardakani@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 98611963SAfshin.Ardakani@Sun.COM 98711963SAfshin.Ardakani@Sun.COM if (size != NULL) 98811963SAfshin.Ardakani@Sun.COM *size += info->i_ntargets * sizeof (netdfs_storage_info1_t); 98911963SAfshin.Ardakani@Sun.COM 99011963SAfshin.Ardakani@Sun.COM target = info->i_targets; 99111963SAfshin.Ardakani@Sun.COM storage = *sinfo; 99211963SAfshin.Ardakani@Sun.COM for (i = 0; i < info->i_ntargets; i++, target++, storage++) { 99311963SAfshin.Ardakani@Sun.COM storage->state = target->t_state; 99411963SAfshin.Ardakani@Sun.COM storage->server = NDR_STRDUP(mxa, target->t_server); 99511963SAfshin.Ardakani@Sun.COM storage->share = NDR_STRDUP(mxa, target->t_share); 99611963SAfshin.Ardakani@Sun.COM storage->p_class = target->t_priority.p_class; 99711963SAfshin.Ardakani@Sun.COM storage->p_rank = target->t_priority.p_rank; 99811963SAfshin.Ardakani@Sun.COM storage->p_reserved = 0; 99911963SAfshin.Ardakani@Sun.COM 100011963SAfshin.Ardakani@Sun.COM if (storage->server == NULL || storage->share == NULL) 100111963SAfshin.Ardakani@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 100211963SAfshin.Ardakani@Sun.COM 100311963SAfshin.Ardakani@Sun.COM if (size != NULL) 100411963SAfshin.Ardakani@Sun.COM *size += smb_wcequiv_strlen(target->t_server) + 100511963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(target->t_share); 100611963SAfshin.Ardakani@Sun.COM } 100711963SAfshin.Ardakani@Sun.COM 100811963SAfshin.Ardakani@Sun.COM return (ERROR_SUCCESS); 100911963SAfshin.Ardakani@Sun.COM } 101011963SAfshin.Ardakani@Sun.COM 101111963SAfshin.Ardakani@Sun.COM /* 101211963SAfshin.Ardakani@Sun.COM * Sets a DFS_INFO_1 for get/enum response 101311963SAfshin.Ardakani@Sun.COM */ 101411963SAfshin.Ardakani@Sun.COM static uint32_t 101511963SAfshin.Ardakani@Sun.COM netdfs_info_1(netdfs_info1_t *info1, dfs_info_t *info, ndr_xa_t *mxa, 101611963SAfshin.Ardakani@Sun.COM uint32_t *size) 101711963SAfshin.Ardakani@Sun.COM { 101811963SAfshin.Ardakani@Sun.COM info1->entry_path = NDR_STRDUP(mxa, info->i_uncpath); 101911963SAfshin.Ardakani@Sun.COM if (info1->entry_path == NULL) 102011963SAfshin.Ardakani@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 102111963SAfshin.Ardakani@Sun.COM 102211963SAfshin.Ardakani@Sun.COM if (size != NULL) 102311963SAfshin.Ardakani@Sun.COM *size = sizeof (netdfs_info1_t) + 102411963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_uncpath); 102511963SAfshin.Ardakani@Sun.COM 102611963SAfshin.Ardakani@Sun.COM return (ERROR_SUCCESS); 102711963SAfshin.Ardakani@Sun.COM } 102811963SAfshin.Ardakani@Sun.COM 102911963SAfshin.Ardakani@Sun.COM /* 103011963SAfshin.Ardakani@Sun.COM * Sets a DFS_INFO_2 for get/enum response 103111963SAfshin.Ardakani@Sun.COM */ 103211963SAfshin.Ardakani@Sun.COM static uint32_t 103311963SAfshin.Ardakani@Sun.COM netdfs_info_2(netdfs_info2_t *info2, dfs_info_t *info, ndr_xa_t *mxa, 103411963SAfshin.Ardakani@Sun.COM uint32_t *size) 103511963SAfshin.Ardakani@Sun.COM { 103611963SAfshin.Ardakani@Sun.COM void *entry_path; 103711963SAfshin.Ardakani@Sun.COM void *comment; 103811963SAfshin.Ardakani@Sun.COM 103911963SAfshin.Ardakani@Sun.COM entry_path = NDR_STRDUP(mxa, info->i_uncpath); 104011963SAfshin.Ardakani@Sun.COM comment = NDR_STRDUP(mxa, info->i_comment); 104111963SAfshin.Ardakani@Sun.COM 104211963SAfshin.Ardakani@Sun.COM if (entry_path == NULL || comment == NULL) 104311963SAfshin.Ardakani@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 104411963SAfshin.Ardakani@Sun.COM 104511963SAfshin.Ardakani@Sun.COM info2->entry_path = entry_path; 104611963SAfshin.Ardakani@Sun.COM info2->comment = comment; 104711963SAfshin.Ardakani@Sun.COM info2->state = info->i_state; 104811963SAfshin.Ardakani@Sun.COM info2->n_store = info->i_ntargets; 104911963SAfshin.Ardakani@Sun.COM 105011963SAfshin.Ardakani@Sun.COM if (size != NULL) 105111963SAfshin.Ardakani@Sun.COM *size = sizeof (netdfs_info2_t) + 105211963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_uncpath) + 105311963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_comment); 105411963SAfshin.Ardakani@Sun.COM 105511963SAfshin.Ardakani@Sun.COM return (ERROR_SUCCESS); 105611963SAfshin.Ardakani@Sun.COM } 105711963SAfshin.Ardakani@Sun.COM 105811963SAfshin.Ardakani@Sun.COM /* 105911963SAfshin.Ardakani@Sun.COM * Sets a DFS_INFO_3 for get/enum response 106011963SAfshin.Ardakani@Sun.COM */ 106111963SAfshin.Ardakani@Sun.COM static uint32_t 106211963SAfshin.Ardakani@Sun.COM netdfs_info_3(netdfs_info3_t *info3, dfs_info_t *info, ndr_xa_t *mxa, 106311963SAfshin.Ardakani@Sun.COM uint32_t *size) 106411963SAfshin.Ardakani@Sun.COM { 106511963SAfshin.Ardakani@Sun.COM void *entry_path; 106611963SAfshin.Ardakani@Sun.COM void *comment; 106711963SAfshin.Ardakani@Sun.COM 106811963SAfshin.Ardakani@Sun.COM entry_path = NDR_STRDUP(mxa, info->i_uncpath); 106911963SAfshin.Ardakani@Sun.COM comment = NDR_STRDUP(mxa, info->i_comment); 107011963SAfshin.Ardakani@Sun.COM 107111963SAfshin.Ardakani@Sun.COM if (entry_path == NULL || comment == NULL) 107211963SAfshin.Ardakani@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 107311963SAfshin.Ardakani@Sun.COM 107411963SAfshin.Ardakani@Sun.COM info3->entry_path = entry_path; 107511963SAfshin.Ardakani@Sun.COM info3->comment = comment; 107611963SAfshin.Ardakani@Sun.COM info3->state = info->i_state; 107711963SAfshin.Ardakani@Sun.COM info3->n_store = info->i_ntargets; 107811963SAfshin.Ardakani@Sun.COM 107911963SAfshin.Ardakani@Sun.COM if (size != NULL) 108011963SAfshin.Ardakani@Sun.COM *size = sizeof (netdfs_info3_t) + 108111963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_uncpath) + 108211963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_comment); 108311963SAfshin.Ardakani@Sun.COM 108411963SAfshin.Ardakani@Sun.COM return (netdfs_info_storage(&info3->si, info, mxa, size)); 108511963SAfshin.Ardakani@Sun.COM } 108611963SAfshin.Ardakani@Sun.COM 108711963SAfshin.Ardakani@Sun.COM /* 108811963SAfshin.Ardakani@Sun.COM * Sets a DFS_INFO_4 for get/enum response 108911963SAfshin.Ardakani@Sun.COM */ 109011963SAfshin.Ardakani@Sun.COM static uint32_t 109111963SAfshin.Ardakani@Sun.COM netdfs_info_4(netdfs_info4_t *info4, dfs_info_t *info, ndr_xa_t *mxa, 109211963SAfshin.Ardakani@Sun.COM uint32_t *size) 109311963SAfshin.Ardakani@Sun.COM { 109411963SAfshin.Ardakani@Sun.COM void *entry_path; 109511963SAfshin.Ardakani@Sun.COM void *comment; 109611963SAfshin.Ardakani@Sun.COM 109711963SAfshin.Ardakani@Sun.COM entry_path = NDR_STRDUP(mxa, info->i_uncpath); 109811963SAfshin.Ardakani@Sun.COM comment = NDR_STRDUP(mxa, info->i_comment); 109911963SAfshin.Ardakani@Sun.COM 110011963SAfshin.Ardakani@Sun.COM if (entry_path == NULL || comment == NULL) 110111963SAfshin.Ardakani@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 110211963SAfshin.Ardakani@Sun.COM 110311963SAfshin.Ardakani@Sun.COM if (!netdfs_guid_fromstr(info->i_guid, &info4->guid)) 110411963SAfshin.Ardakani@Sun.COM return (ERROR_INVALID_DATA); 110511963SAfshin.Ardakani@Sun.COM 110611963SAfshin.Ardakani@Sun.COM info4->entry_path = entry_path; 110711963SAfshin.Ardakani@Sun.COM info4->comment = comment; 110811963SAfshin.Ardakani@Sun.COM info4->state = info->i_state; 110911963SAfshin.Ardakani@Sun.COM info4->timeout = info->i_timeout; 111011963SAfshin.Ardakani@Sun.COM info4->n_store = info->i_ntargets; 111111963SAfshin.Ardakani@Sun.COM 111211963SAfshin.Ardakani@Sun.COM if (size != NULL) 111311963SAfshin.Ardakani@Sun.COM *size = sizeof (netdfs_info4_t) + 111411963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_uncpath) + 111511963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_comment); 111611963SAfshin.Ardakani@Sun.COM 111711963SAfshin.Ardakani@Sun.COM return (netdfs_info_storage(&info4->si, info, mxa, size)); 111811963SAfshin.Ardakani@Sun.COM } 111911963SAfshin.Ardakani@Sun.COM 112011963SAfshin.Ardakani@Sun.COM /* 112111963SAfshin.Ardakani@Sun.COM * Sets a DFS_INFO_5 for get/enum response 112211963SAfshin.Ardakani@Sun.COM */ 112311963SAfshin.Ardakani@Sun.COM static uint32_t 112411963SAfshin.Ardakani@Sun.COM netdfs_info_5(netdfs_info5_t *info5, dfs_info_t *info, ndr_xa_t *mxa, 112511963SAfshin.Ardakani@Sun.COM uint32_t *size) 112611963SAfshin.Ardakani@Sun.COM { 112711963SAfshin.Ardakani@Sun.COM void *entry_path; 112811963SAfshin.Ardakani@Sun.COM void *comment; 112911963SAfshin.Ardakani@Sun.COM 113011963SAfshin.Ardakani@Sun.COM entry_path = NDR_STRDUP(mxa, info->i_uncpath); 113111963SAfshin.Ardakani@Sun.COM comment = NDR_STRDUP(mxa, info->i_comment); 113211963SAfshin.Ardakani@Sun.COM 113311963SAfshin.Ardakani@Sun.COM if (entry_path == NULL || comment == NULL) 113411963SAfshin.Ardakani@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 113511963SAfshin.Ardakani@Sun.COM 113611963SAfshin.Ardakani@Sun.COM if (!netdfs_guid_fromstr(info->i_guid, &info5->guid)) 113711963SAfshin.Ardakani@Sun.COM return (ERROR_INVALID_DATA); 113811963SAfshin.Ardakani@Sun.COM 113911963SAfshin.Ardakani@Sun.COM info5->entry_path = entry_path; 114011963SAfshin.Ardakani@Sun.COM info5->comment = comment; 114111963SAfshin.Ardakani@Sun.COM info5->state = info->i_state; 114211963SAfshin.Ardakani@Sun.COM info5->timeout = info->i_timeout; 114311963SAfshin.Ardakani@Sun.COM info5->flags = info->i_propflags; 114411963SAfshin.Ardakani@Sun.COM info5->metadata_sz = 0; 114511963SAfshin.Ardakani@Sun.COM info5->n_store = info->i_ntargets; 114611963SAfshin.Ardakani@Sun.COM 114711963SAfshin.Ardakani@Sun.COM if (size != NULL) 114811963SAfshin.Ardakani@Sun.COM *size = sizeof (netdfs_info5_t) + 114911963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_uncpath) + 115011963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_comment); 115111963SAfshin.Ardakani@Sun.COM 115211963SAfshin.Ardakani@Sun.COM return (ERROR_SUCCESS); 115311963SAfshin.Ardakani@Sun.COM } 115411963SAfshin.Ardakani@Sun.COM 115511963SAfshin.Ardakani@Sun.COM /* 115611963SAfshin.Ardakani@Sun.COM * Sets a DFS_INFO_6 for get/enum response 115711963SAfshin.Ardakani@Sun.COM */ 115811963SAfshin.Ardakani@Sun.COM static uint32_t 115911963SAfshin.Ardakani@Sun.COM netdfs_info_6(netdfs_info6_t *info6, dfs_info_t *info, ndr_xa_t *mxa, 116011963SAfshin.Ardakani@Sun.COM uint32_t *size) 116111963SAfshin.Ardakani@Sun.COM { 116211963SAfshin.Ardakani@Sun.COM void *entry_path; 116311963SAfshin.Ardakani@Sun.COM void *comment; 116411963SAfshin.Ardakani@Sun.COM 116511963SAfshin.Ardakani@Sun.COM entry_path = NDR_STRDUP(mxa, info->i_uncpath); 116611963SAfshin.Ardakani@Sun.COM comment = NDR_STRDUP(mxa, info->i_comment); 116711963SAfshin.Ardakani@Sun.COM 116811963SAfshin.Ardakani@Sun.COM if (entry_path == NULL || comment == NULL) 116911963SAfshin.Ardakani@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 117011963SAfshin.Ardakani@Sun.COM 117111963SAfshin.Ardakani@Sun.COM if (!netdfs_guid_fromstr(info->i_guid, &info6->guid)) 117211963SAfshin.Ardakani@Sun.COM return (ERROR_INVALID_DATA); 117311963SAfshin.Ardakani@Sun.COM 117411963SAfshin.Ardakani@Sun.COM info6->entry_path = entry_path; 117511963SAfshin.Ardakani@Sun.COM info6->comment = comment; 117611963SAfshin.Ardakani@Sun.COM info6->state = info->i_state; 117711963SAfshin.Ardakani@Sun.COM info6->timeout = info->i_timeout; 117811963SAfshin.Ardakani@Sun.COM info6->flags = info->i_propflags; 117911963SAfshin.Ardakani@Sun.COM info6->metadata_sz = 0; 118011963SAfshin.Ardakani@Sun.COM info6->n_store = info->i_ntargets; 118111963SAfshin.Ardakani@Sun.COM 118211963SAfshin.Ardakani@Sun.COM if (size != NULL) 118311963SAfshin.Ardakani@Sun.COM *size = sizeof (netdfs_info6_t) + 118411963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_uncpath) + 118511963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_comment); 118611963SAfshin.Ardakani@Sun.COM 118711963SAfshin.Ardakani@Sun.COM return (netdfs_info_storage1(&info6->si, info, mxa, size)); 118811963SAfshin.Ardakani@Sun.COM } 118911963SAfshin.Ardakani@Sun.COM 119011963SAfshin.Ardakani@Sun.COM /* 119111963SAfshin.Ardakani@Sun.COM * Sets a DFS_INFO_100 for Get response 119211963SAfshin.Ardakani@Sun.COM */ 119311963SAfshin.Ardakani@Sun.COM static uint32_t 119411963SAfshin.Ardakani@Sun.COM netdfs_info_100(netdfs_info100_t *info100, dfs_info_t *info, ndr_xa_t *mxa, 119511963SAfshin.Ardakani@Sun.COM uint32_t *size) 119611963SAfshin.Ardakani@Sun.COM { 119711963SAfshin.Ardakani@Sun.COM info100->comment = NDR_STRDUP(mxa, info->i_comment); 119811963SAfshin.Ardakani@Sun.COM if (info100->comment == NULL) 119911963SAfshin.Ardakani@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 120011963SAfshin.Ardakani@Sun.COM 120111963SAfshin.Ardakani@Sun.COM if (size != NULL) 120211963SAfshin.Ardakani@Sun.COM *size = sizeof (netdfs_info100_t) + 120311963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_comment); 120411963SAfshin.Ardakani@Sun.COM 120511963SAfshin.Ardakani@Sun.COM return (ERROR_SUCCESS); 120611963SAfshin.Ardakani@Sun.COM } 120711963SAfshin.Ardakani@Sun.COM 120811963SAfshin.Ardakani@Sun.COM /* 120911963SAfshin.Ardakani@Sun.COM * Sets a DFS_INFO_300 for Enum response 121011963SAfshin.Ardakani@Sun.COM */ 121111963SAfshin.Ardakani@Sun.COM static uint32_t 121211963SAfshin.Ardakani@Sun.COM netdfs_info_300(netdfs_info300_t *info300, dfs_info_t *info, ndr_xa_t *mxa, 121311963SAfshin.Ardakani@Sun.COM uint32_t *size) 121411963SAfshin.Ardakani@Sun.COM { 121511963SAfshin.Ardakani@Sun.COM info300->dfsname = NDR_STRDUP(mxa, info->i_uncpath); 121611963SAfshin.Ardakani@Sun.COM if (info300->dfsname == NULL) 121711963SAfshin.Ardakani@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 121811963SAfshin.Ardakani@Sun.COM 121911963SAfshin.Ardakani@Sun.COM info300->flavor = DFS_VOLUME_FLAVOR_STANDALONE; 122011963SAfshin.Ardakani@Sun.COM if (size != NULL) 122111963SAfshin.Ardakani@Sun.COM *size = sizeof (netdfs_info300_t) + 122211963SAfshin.Ardakani@Sun.COM smb_wcequiv_strlen(info->i_uncpath); 122311963SAfshin.Ardakani@Sun.COM 122411963SAfshin.Ardakani@Sun.COM return (ERROR_SUCCESS); 122511963SAfshin.Ardakani@Sun.COM } 122611963SAfshin.Ardakani@Sun.COM 122711963SAfshin.Ardakani@Sun.COM /* 122811963SAfshin.Ardakani@Sun.COM * Common enumeration function 122911963SAfshin.Ardakani@Sun.COM */ 123011963SAfshin.Ardakani@Sun.COM static uint32_t 123111963SAfshin.Ardakani@Sun.COM netdfs_enum_common(netdfs_enumhandle_t *de, ndr_xa_t *mxa) 123211963SAfshin.Ardakani@Sun.COM { 123311963SAfshin.Ardakani@Sun.COM netdfs_info1_t *info1 = de->de_entries; 123411963SAfshin.Ardakani@Sun.COM netdfs_info2_t *info2 = de->de_entries; 123511963SAfshin.Ardakani@Sun.COM netdfs_info3_t *info3 = de->de_entries; 123611963SAfshin.Ardakani@Sun.COM netdfs_info4_t *info4 = de->de_entries; 123711963SAfshin.Ardakani@Sun.COM netdfs_info5_t *info5 = de->de_entries; 123811963SAfshin.Ardakani@Sun.COM netdfs_info6_t *info6 = de->de_entries; 123911963SAfshin.Ardakani@Sun.COM netdfs_info300_t *info300 = de->de_entries; 124011963SAfshin.Ardakani@Sun.COM dfs_info_t dfsinfo; 124111963SAfshin.Ardakani@Sun.COM smb_cache_cursor_t cursor; 124211963SAfshin.Ardakani@Sun.COM dfs_nscnode_t nscnode; 124311963SAfshin.Ardakani@Sun.COM uint32_t status; 124411963SAfshin.Ardakani@Sun.COM uint32_t itemsz; 124511963SAfshin.Ardakani@Sun.COM 124611963SAfshin.Ardakani@Sun.COM dfs_cache_iterinit(&cursor); 124711963SAfshin.Ardakani@Sun.COM 124811963SAfshin.Ardakani@Sun.COM de->de_nitems = 0; 124911963SAfshin.Ardakani@Sun.COM while (dfs_cache_iterate(&cursor, &nscnode)) { 125011963SAfshin.Ardakani@Sun.COM if (de->de_nskip > 0) { 125111963SAfshin.Ardakani@Sun.COM de->de_nskip--; 125211963SAfshin.Ardakani@Sun.COM continue; 125311963SAfshin.Ardakani@Sun.COM } 125411963SAfshin.Ardakani@Sun.COM 125511963SAfshin.Ardakani@Sun.COM if (de->de_nitems == de->de_nmax) 125611963SAfshin.Ardakani@Sun.COM break; 125711963SAfshin.Ardakani@Sun.COM 125811963SAfshin.Ardakani@Sun.COM status = dfs_cache_getinfo(&nscnode, &dfsinfo, de->de_level); 125911963SAfshin.Ardakani@Sun.COM if (status != ERROR_SUCCESS) 126011963SAfshin.Ardakani@Sun.COM continue; 126111963SAfshin.Ardakani@Sun.COM 126211963SAfshin.Ardakani@Sun.COM switch (de->de_level) { 126311963SAfshin.Ardakani@Sun.COM case 1: 126411963SAfshin.Ardakani@Sun.COM status = netdfs_info_1(info1, &dfsinfo, mxa, &itemsz); 126511963SAfshin.Ardakani@Sun.COM info1++; 126611963SAfshin.Ardakani@Sun.COM break; 126711963SAfshin.Ardakani@Sun.COM case 2: 126811963SAfshin.Ardakani@Sun.COM status = netdfs_info_2(info2, &dfsinfo, mxa, &itemsz); 126911963SAfshin.Ardakani@Sun.COM info2++; 127011963SAfshin.Ardakani@Sun.COM break; 127111963SAfshin.Ardakani@Sun.COM case 3: 127211963SAfshin.Ardakani@Sun.COM status = netdfs_info_3(info3, &dfsinfo, mxa, &itemsz); 127311963SAfshin.Ardakani@Sun.COM info3++; 127411963SAfshin.Ardakani@Sun.COM break; 127511963SAfshin.Ardakani@Sun.COM case 4: 127611963SAfshin.Ardakani@Sun.COM status = netdfs_info_4(info4, &dfsinfo, mxa, &itemsz); 127711963SAfshin.Ardakani@Sun.COM info4++; 127811963SAfshin.Ardakani@Sun.COM break; 127911963SAfshin.Ardakani@Sun.COM case 5: 128011963SAfshin.Ardakani@Sun.COM status = netdfs_info_5(info5, &dfsinfo, mxa, &itemsz); 128111963SAfshin.Ardakani@Sun.COM info5++; 128211963SAfshin.Ardakani@Sun.COM break; 128311963SAfshin.Ardakani@Sun.COM case 6: 128411963SAfshin.Ardakani@Sun.COM status = netdfs_info_6(info6, &dfsinfo, mxa, &itemsz); 128511963SAfshin.Ardakani@Sun.COM info6++; 128611963SAfshin.Ardakani@Sun.COM break; 128711963SAfshin.Ardakani@Sun.COM case 300: 128811963SAfshin.Ardakani@Sun.COM status = netdfs_info_300(info300, &dfsinfo, mxa, 128911963SAfshin.Ardakani@Sun.COM &itemsz); 129011963SAfshin.Ardakani@Sun.COM info300++; 129111963SAfshin.Ardakani@Sun.COM break; 129211963SAfshin.Ardakani@Sun.COM default: 129311963SAfshin.Ardakani@Sun.COM status = ERROR_INVALID_LEVEL; 129411963SAfshin.Ardakani@Sun.COM } 129511963SAfshin.Ardakani@Sun.COM 129611963SAfshin.Ardakani@Sun.COM dfs_info_free(&dfsinfo); 129711963SAfshin.Ardakani@Sun.COM 129811963SAfshin.Ardakani@Sun.COM if (status != ERROR_SUCCESS) 129911963SAfshin.Ardakani@Sun.COM return (status); 130011963SAfshin.Ardakani@Sun.COM 130111963SAfshin.Ardakani@Sun.COM if (de->de_nmax == 1) { 130211963SAfshin.Ardakani@Sun.COM de->de_nitems = 1; 130311963SAfshin.Ardakani@Sun.COM break; 130411963SAfshin.Ardakani@Sun.COM } 130511963SAfshin.Ardakani@Sun.COM 130611963SAfshin.Ardakani@Sun.COM if (itemsz > de->de_bavail) 130711963SAfshin.Ardakani@Sun.COM break; 130811963SAfshin.Ardakani@Sun.COM 130911963SAfshin.Ardakani@Sun.COM de->de_bavail -= itemsz; 131011963SAfshin.Ardakani@Sun.COM de->de_nitems++; 131111963SAfshin.Ardakani@Sun.COM } 131211963SAfshin.Ardakani@Sun.COM 131311963SAfshin.Ardakani@Sun.COM de->de_resume += de->de_nitems; 131411963SAfshin.Ardakani@Sun.COM return (ERROR_SUCCESS); 131511963SAfshin.Ardakani@Sun.COM } 131611963SAfshin.Ardakani@Sun.COM 131711963SAfshin.Ardakani@Sun.COM /* 131811963SAfshin.Ardakani@Sun.COM * Creates intermediate directories of a link from the root share path. 13195331Samw * 132011963SAfshin.Ardakani@Sun.COM * TODO: directories should be created by smbsrv to get Windows compatible 132111963SAfshin.Ardakani@Sun.COM * ACL inheritance. 13225331Samw */ 132311963SAfshin.Ardakani@Sun.COM static void 132411963SAfshin.Ardakani@Sun.COM netdfs_path_create(const char *path) 13255331Samw { 132611963SAfshin.Ardakani@Sun.COM char dirpath[DFS_PATH_MAX]; 132711963SAfshin.Ardakani@Sun.COM mode_t mode; 13285331Samw char *p; 13295331Samw 133011963SAfshin.Ardakani@Sun.COM (void) strlcpy(dirpath, path, DFS_PATH_MAX); 13315331Samw 133211963SAfshin.Ardakani@Sun.COM /* drop the link itself from the path */ 133311963SAfshin.Ardakani@Sun.COM if ((p = strrchr(dirpath, '/')) != NULL) { 13345331Samw *p = '\0'; 133511963SAfshin.Ardakani@Sun.COM mode = umask(0); 133611963SAfshin.Ardakani@Sun.COM (void) mkdirp(dirpath, 0777); 133711963SAfshin.Ardakani@Sun.COM (void) umask(mode); 133811963SAfshin.Ardakani@Sun.COM } 133911963SAfshin.Ardakani@Sun.COM } 13405331Samw 134111963SAfshin.Ardakani@Sun.COM /* 134211963SAfshin.Ardakani@Sun.COM * Removes empty directories 134311963SAfshin.Ardakani@Sun.COM */ 134411963SAfshin.Ardakani@Sun.COM static void 134511963SAfshin.Ardakani@Sun.COM netdfs_path_remove(smb_unc_t *unc) 134611963SAfshin.Ardakani@Sun.COM { 134711963SAfshin.Ardakani@Sun.COM char rootdir[DFS_PATH_MAX]; 134811963SAfshin.Ardakani@Sun.COM char relpath[DFS_PATH_MAX]; 134911963SAfshin.Ardakani@Sun.COM char dir[DFS_PATH_MAX]; 135011963SAfshin.Ardakani@Sun.COM uint32_t status; 135111963SAfshin.Ardakani@Sun.COM char *p; 13525331Samw 135311963SAfshin.Ardakani@Sun.COM status = dfs_namespace_path(unc->unc_share, rootdir, DFS_PATH_MAX); 135411963SAfshin.Ardakani@Sun.COM if ((status == ERROR_SUCCESS) && (chdir(rootdir) == 0)) { 135511963SAfshin.Ardakani@Sun.COM (void) strlcpy(relpath, unc->unc_path, DFS_PATH_MAX); 135611963SAfshin.Ardakani@Sun.COM /* drop the link itself from the path */ 135711963SAfshin.Ardakani@Sun.COM if ((p = strrchr(relpath, '/')) != NULL) { 13585331Samw *p = '\0'; 135911963SAfshin.Ardakani@Sun.COM (void) rmdirp(relpath, dir); 13605331Samw } 13615331Samw } 136211963SAfshin.Ardakani@Sun.COM } 13635331Samw 136411963SAfshin.Ardakani@Sun.COM /* 136511963SAfshin.Ardakani@Sun.COM * Converts the guid string into binary format in network byte order. 136611963SAfshin.Ardakani@Sun.COM */ 136711963SAfshin.Ardakani@Sun.COM static boolean_t 136811963SAfshin.Ardakani@Sun.COM netdfs_guid_fromstr(char *guid_str, netdfs_uuid_t *guid) 136911963SAfshin.Ardakani@Sun.COM { 137011963SAfshin.Ardakani@Sun.COM uuid_t uuid; 13715331Samw 137211963SAfshin.Ardakani@Sun.COM if (uuid_parse(guid_str, uuid) != 0) 137311963SAfshin.Ardakani@Sun.COM return (B_FALSE); 137411963SAfshin.Ardakani@Sun.COM 137511963SAfshin.Ardakani@Sun.COM bcopy(&uuid, guid, sizeof (uuid_t)); 13765331Samw 137711963SAfshin.Ardakani@Sun.COM guid->data1 = htonl(guid->data1); 137811963SAfshin.Ardakani@Sun.COM guid->data2 = htons(guid->data2); 137911963SAfshin.Ardakani@Sun.COM guid->data3 = htons(guid->data3); 138011963SAfshin.Ardakani@Sun.COM 138111963SAfshin.Ardakani@Sun.COM return (B_TRUE); 13825331Samw } 1383