18474SJose.Borrego@Sun.COM /* 28474SJose.Borrego@Sun.COM * CDDL HEADER START 38474SJose.Borrego@Sun.COM * 48474SJose.Borrego@Sun.COM * The contents of this file are subject to the terms of the 58474SJose.Borrego@Sun.COM * Common Development and Distribution License (the "License"). 68474SJose.Borrego@Sun.COM * You may not use this file except in compliance with the License. 78474SJose.Borrego@Sun.COM * 88474SJose.Borrego@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 98474SJose.Borrego@Sun.COM * or http://www.opensolaris.org/os/licensing. 108474SJose.Borrego@Sun.COM * See the License for the specific language governing permissions 118474SJose.Borrego@Sun.COM * and limitations under the License. 128474SJose.Borrego@Sun.COM * 138474SJose.Borrego@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 148474SJose.Borrego@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 158474SJose.Borrego@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 168474SJose.Borrego@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 178474SJose.Borrego@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 188474SJose.Borrego@Sun.COM * 198474SJose.Borrego@Sun.COM * CDDL HEADER END 208474SJose.Borrego@Sun.COM */ 218474SJose.Borrego@Sun.COM /* 228474SJose.Borrego@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 238474SJose.Borrego@Sun.COM * Use is subject to license terms. 248474SJose.Borrego@Sun.COM */ 258474SJose.Borrego@Sun.COM 268474SJose.Borrego@Sun.COM /* 278474SJose.Borrego@Sun.COM * Server Service RPC (SRVSVC) server-side interface definition. 288474SJose.Borrego@Sun.COM * The server service provides a remote administration interface. 298474SJose.Borrego@Sun.COM * 308474SJose.Borrego@Sun.COM * This service uses NERR/Win32 error codes rather than NT status 318474SJose.Borrego@Sun.COM * values. 328474SJose.Borrego@Sun.COM */ 338474SJose.Borrego@Sun.COM 348474SJose.Borrego@Sun.COM #include <sys/errno.h> 358474SJose.Borrego@Sun.COM #include <unistd.h> 368474SJose.Borrego@Sun.COM #include <netdb.h> 378474SJose.Borrego@Sun.COM #include <strings.h> 388474SJose.Borrego@Sun.COM #include <time.h> 398474SJose.Borrego@Sun.COM #include <thread.h> 408474SJose.Borrego@Sun.COM #include <ctype.h> 418474SJose.Borrego@Sun.COM #include <stdlib.h> 428474SJose.Borrego@Sun.COM #include <string.h> 438474SJose.Borrego@Sun.COM #include <sys/types.h> 448474SJose.Borrego@Sun.COM #include <sys/socket.h> 458474SJose.Borrego@Sun.COM #include <netinet/in.h> 468474SJose.Borrego@Sun.COM #include <arpa/inet.h> 478474SJose.Borrego@Sun.COM #include <libshare.h> 488474SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h> 498474SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h> 508474SJose.Borrego@Sun.COM #include <smbsrv/lmerr.h> 518474SJose.Borrego@Sun.COM #include <smbsrv/nterror.h> 528474SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h> 538474SJose.Borrego@Sun.COM #include <smbsrv/cifs.h> 548474SJose.Borrego@Sun.COM #include <smbsrv/netrauth.h> 558474SJose.Borrego@Sun.COM #include <smbsrv/ndl/srvsvc.ndl> 568474SJose.Borrego@Sun.COM #include <smbsrv/smb_common_door.h> 57*9832Samw@Sun.COM #include "mlsvc.h" 588474SJose.Borrego@Sun.COM 598474SJose.Borrego@Sun.COM #define SV_TYPE_SENT_BY_ME (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | SV_TYPE_NT) 608474SJose.Borrego@Sun.COM 618474SJose.Borrego@Sun.COM /* 628474SJose.Borrego@Sun.COM * Qualifier types for NetConnectEnum. 638474SJose.Borrego@Sun.COM */ 648474SJose.Borrego@Sun.COM #define SRVSVC_CONNECT_ENUM_NULL 0 658474SJose.Borrego@Sun.COM #define SRVSVC_CONNECT_ENUM_SHARE 1 668474SJose.Borrego@Sun.COM #define SRVSVC_CONNECT_ENUM_WKSTN 2 678474SJose.Borrego@Sun.COM 688474SJose.Borrego@Sun.COM #define SMB_SRVSVC_MAXBUFLEN (8 * 1024 * 1024) 698474SJose.Borrego@Sun.COM #define SMB_SRVSVC_MAXPREFLEN ((uint32_t)(-1)) 708474SJose.Borrego@Sun.COM 718474SJose.Borrego@Sun.COM /* 728474SJose.Borrego@Sun.COM * prefmaxlen: Client specified response buffer limit. 738474SJose.Borrego@Sun.COM * resume_handle: Cookie used to track enumeration across multiple calls. 748474SJose.Borrego@Sun.COM * n_total: Total number of entries. 758474SJose.Borrego@Sun.COM * n_enum: Number of entries to enumerate (derived from prefmaxlen). 768474SJose.Borrego@Sun.COM * n_skip: Number of entries to skip (from incoming resume handle). 778474SJose.Borrego@Sun.COM * n_read: Number of objects returned for current enumeration request. 788474SJose.Borrego@Sun.COM */ 798474SJose.Borrego@Sun.COM typedef struct srvsvc_enum { 808474SJose.Borrego@Sun.COM uint32_t se_level; 818474SJose.Borrego@Sun.COM uint32_t se_prefmaxlen; 828474SJose.Borrego@Sun.COM uint32_t se_resume_handle; 838474SJose.Borrego@Sun.COM uint32_t se_n_total; 848474SJose.Borrego@Sun.COM uint32_t se_n_enum; 858474SJose.Borrego@Sun.COM uint32_t se_n_skip; 868474SJose.Borrego@Sun.COM uint32_t se_n_read; 878474SJose.Borrego@Sun.COM } srvsvc_enum_t; 888474SJose.Borrego@Sun.COM 89*9832Samw@Sun.COM typedef struct srvsvc_sd { 90*9832Samw@Sun.COM uint8_t *sd_buf; 91*9832Samw@Sun.COM uint32_t sd_size; 92*9832Samw@Sun.COM } srvsvc_sd_t; 93*9832Samw@Sun.COM 94*9832Samw@Sun.COM typedef struct srvsvc_netshare_setinfo { 95*9832Samw@Sun.COM char *nss_netname; 96*9832Samw@Sun.COM char *nss_comment; 97*9832Samw@Sun.COM char *nss_path; 98*9832Samw@Sun.COM uint32_t nss_type; 99*9832Samw@Sun.COM srvsvc_sd_t nss_sd; 100*9832Samw@Sun.COM } srvsvc_netshare_setinfo_t; 101*9832Samw@Sun.COM 102*9832Samw@Sun.COM typedef union srvsvc_netshare_getinfo { 103*9832Samw@Sun.COM struct mslm_NetShareInfo_0 nsg_info0; 104*9832Samw@Sun.COM struct mslm_NetShareInfo_1 nsg_info1; 105*9832Samw@Sun.COM struct mslm_NetShareInfo_2 nsg_info2; 106*9832Samw@Sun.COM struct mslm_NetShareInfo_501 nsg_info501; 107*9832Samw@Sun.COM struct mslm_NetShareInfo_502 nsg_info502; 108*9832Samw@Sun.COM struct mslm_NetShareInfo_503 nsg_info503; 109*9832Samw@Sun.COM struct mslm_NetShareInfo_1004 nsg_info1004; 110*9832Samw@Sun.COM struct mslm_NetShareInfo_1005 nsg_info1005; 111*9832Samw@Sun.COM struct mslm_NetShareInfo_1006 nsg_info1006; 112*9832Samw@Sun.COM struct mslm_NetShareInfo_1501 nsg_info1501; 113*9832Samw@Sun.COM } srvsvc_netshare_getinfo_t; 114*9832Samw@Sun.COM 1158474SJose.Borrego@Sun.COM static DWORD srvsvc_s_NetConnectEnumLevel0(ndr_xa_t *, 1168474SJose.Borrego@Sun.COM srvsvc_NetConnectInfo0_t *); 1178474SJose.Borrego@Sun.COM static DWORD srvsvc_s_NetConnectEnumLevel1(ndr_xa_t *, 1188474SJose.Borrego@Sun.COM srvsvc_NetConnectInfo1_t *); 1198474SJose.Borrego@Sun.COM 1208474SJose.Borrego@Sun.COM static DWORD srvsvc_NetFileEnum2(ndr_xa_t *, 1218474SJose.Borrego@Sun.COM struct mslm_NetFileEnum *); 1228474SJose.Borrego@Sun.COM static DWORD srvsvc_NetFileEnum3(ndr_xa_t *, 1238474SJose.Borrego@Sun.COM struct mslm_NetFileEnum *); 1248474SJose.Borrego@Sun.COM 1258474SJose.Borrego@Sun.COM static DWORD mlsvc_NetSessionEnumLevel0(struct mslm_infonres *, DWORD, 1268474SJose.Borrego@Sun.COM ndr_xa_t *); 1278474SJose.Borrego@Sun.COM static DWORD mlsvc_NetSessionEnumLevel1(struct mslm_infonres *, DWORD, 1288474SJose.Borrego@Sun.COM ndr_xa_t *); 129*9832Samw@Sun.COM static DWORD mlsvc_NetSessionEnumLevel2(struct mslm_infonres *, DWORD, 130*9832Samw@Sun.COM ndr_xa_t *); 131*9832Samw@Sun.COM static DWORD mlsvc_NetSessionEnumLevel10(struct mslm_infonres *, DWORD, 132*9832Samw@Sun.COM ndr_xa_t *); 133*9832Samw@Sun.COM static DWORD mlsvc_NetSessionEnumLevel502(struct mslm_infonres *, DWORD, 134*9832Samw@Sun.COM ndr_xa_t *); 1358474SJose.Borrego@Sun.COM 1368474SJose.Borrego@Sun.COM static DWORD mlsvc_NetShareEnumLevel0(ndr_xa_t *, 1378474SJose.Borrego@Sun.COM struct mslm_infonres *, srvsvc_enum_t *, int); 1388474SJose.Borrego@Sun.COM static DWORD mlsvc_NetShareEnumLevel1(ndr_xa_t *, 1398474SJose.Borrego@Sun.COM struct mslm_infonres *, srvsvc_enum_t *, int); 1408474SJose.Borrego@Sun.COM static DWORD mlsvc_NetShareEnumLevel2(ndr_xa_t *, 1418474SJose.Borrego@Sun.COM struct mslm_infonres *, srvsvc_enum_t *, int); 1428474SJose.Borrego@Sun.COM static DWORD mlsvc_NetShareEnumLevel501(ndr_xa_t *, 1438474SJose.Borrego@Sun.COM struct mslm_infonres *, srvsvc_enum_t *, int); 1448474SJose.Borrego@Sun.COM static DWORD mlsvc_NetShareEnumLevel502(ndr_xa_t *, 1458474SJose.Borrego@Sun.COM struct mslm_infonres *, srvsvc_enum_t *, int); 1468474SJose.Borrego@Sun.COM static DWORD mlsvc_NetShareEnumCommon(ndr_xa_t *, 1478474SJose.Borrego@Sun.COM srvsvc_enum_t *, smb_share_t *, void *); 1488474SJose.Borrego@Sun.COM static boolean_t srvsvc_add_autohome(ndr_xa_t *, srvsvc_enum_t *, 1498474SJose.Borrego@Sun.COM void *); 1508474SJose.Borrego@Sun.COM static char *srvsvc_share_mkpath(ndr_xa_t *, char *); 151*9832Samw@Sun.COM static uint32_t srvsvc_share_getsd(ndr_xa_t *, smb_share_t *, srvsvc_sd_t *); 1528474SJose.Borrego@Sun.COM 1538474SJose.Borrego@Sun.COM static int srvsvc_netconnect_qualifier(const char *); 1548474SJose.Borrego@Sun.COM static uint32_t srvsvc_estimate_objcnt(uint32_t, uint32_t, uint32_t); 1558474SJose.Borrego@Sun.COM 156*9832Samw@Sun.COM static uint32_t srvsvc_modify_share(smb_share_t *, 157*9832Samw@Sun.COM srvsvc_netshare_setinfo_t *); 158*9832Samw@Sun.COM static uint32_t srvsvc_modify_transient_share(smb_share_t *, 159*9832Samw@Sun.COM srvsvc_netshare_setinfo_t *); 160*9832Samw@Sun.COM static uint32_t srvsvc_update_share_flags(smb_share_t *, uint32_t); 161*9832Samw@Sun.COM 1628474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_add(char *, char *, char *); 1638474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_delete(char *); 164*9832Samw@Sun.COM static uint32_t srvsvc_sa_modify(smb_share_t *, srvsvc_netshare_setinfo_t *); 165*9832Samw@Sun.COM static uint32_t srvsvc_sa_setattr(smb_share_t *); 1668474SJose.Borrego@Sun.COM 1678474SJose.Borrego@Sun.COM static char empty_string[1]; 1688474SJose.Borrego@Sun.COM 1698474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[]; 1708474SJose.Borrego@Sun.COM 1718474SJose.Borrego@Sun.COM static ndr_service_t srvsvc_service = { 1728474SJose.Borrego@Sun.COM "SRVSVC", /* name */ 1738474SJose.Borrego@Sun.COM "Server services", /* desc */ 1748474SJose.Borrego@Sun.COM "\\srvsvc", /* endpoint */ 1758474SJose.Borrego@Sun.COM PIPE_NTSVCS, /* sec_addr_port */ 1768474SJose.Borrego@Sun.COM "4b324fc8-1670-01d3-1278-5a47bf6ee188", 3, /* abstract */ 1778474SJose.Borrego@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 1788474SJose.Borrego@Sun.COM 0, /* no bind_instance_size */ 1798474SJose.Borrego@Sun.COM 0, /* no bind_req() */ 1808474SJose.Borrego@Sun.COM 0, /* no unbind_and_close() */ 1818474SJose.Borrego@Sun.COM 0, /* use generic_call_stub() */ 1828474SJose.Borrego@Sun.COM &TYPEINFO(srvsvc_interface), /* interface ti */ 1838474SJose.Borrego@Sun.COM srvsvc_stub_table /* stub_table */ 1848474SJose.Borrego@Sun.COM }; 1858474SJose.Borrego@Sun.COM 1868474SJose.Borrego@Sun.COM /* 1878474SJose.Borrego@Sun.COM * srvsvc_initialize 1888474SJose.Borrego@Sun.COM * 1898474SJose.Borrego@Sun.COM * This function registers the SRVSVC RPC interface with the RPC runtime 1908474SJose.Borrego@Sun.COM * library. It must be called in order to use either the client side 1918474SJose.Borrego@Sun.COM * or the server side functions. 1928474SJose.Borrego@Sun.COM */ 1938474SJose.Borrego@Sun.COM void 1948474SJose.Borrego@Sun.COM srvsvc_initialize(void) 1958474SJose.Borrego@Sun.COM { 1968474SJose.Borrego@Sun.COM (void) ndr_svc_register(&srvsvc_service); 1978474SJose.Borrego@Sun.COM } 1988474SJose.Borrego@Sun.COM 1998474SJose.Borrego@Sun.COM /* 2008474SJose.Borrego@Sun.COM * srvsvc_s_NetConnectEnum 2018474SJose.Borrego@Sun.COM * 2028474SJose.Borrego@Sun.COM * List tree connections made to a share on this server or all tree 2038474SJose.Borrego@Sun.COM * connections established from a specific client. Administrator, 2048474SJose.Borrego@Sun.COM * Server Operator, Print Operator or Power User group membership 2058474SJose.Borrego@Sun.COM * is required to use this interface. 2068474SJose.Borrego@Sun.COM * 2078474SJose.Borrego@Sun.COM * There are three information levels: 0, 1, and 50. We don't support 2088474SJose.Borrego@Sun.COM * level 50, which is only used by Windows 9x clients. 2098474SJose.Borrego@Sun.COM * 2108474SJose.Borrego@Sun.COM * It seems Server Manger (srvmgr) only sends workstation as the qualifier 2118474SJose.Borrego@Sun.COM * and the Computer Management Interface on Windows 2000 doesn't request 2128474SJose.Borrego@Sun.COM * a list of connections. 2138474SJose.Borrego@Sun.COM * 2148474SJose.Borrego@Sun.COM * Return Values: 2158474SJose.Borrego@Sun.COM * ERROR_SUCCESS Success 2168474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED Caller does not have access to this call. 2178474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER One of the parameters is invalid. 2188474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL Unknown information level specified. 2198474SJose.Borrego@Sun.COM * ERROR_MORE_DATA Partial date returned, more entries available. 2208474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 2218474SJose.Borrego@Sun.COM * NERR_NetNameNotFound The share qualifier cannot be found. 2228474SJose.Borrego@Sun.COM * NERR_BufTooSmall The supplied buffer is too small. 2238474SJose.Borrego@Sun.COM */ 2248474SJose.Borrego@Sun.COM static int 2258474SJose.Borrego@Sun.COM srvsvc_s_NetConnectEnum(void *arg, ndr_xa_t *mxa) 2268474SJose.Borrego@Sun.COM { 2278474SJose.Borrego@Sun.COM struct mslm_NetConnectEnum *param = arg; 2288474SJose.Borrego@Sun.COM srvsvc_NetConnectInfo0_t *info0; 2298474SJose.Borrego@Sun.COM srvsvc_NetConnectInfo1_t *info1; 2308474SJose.Borrego@Sun.COM char *qualifier; 2318474SJose.Borrego@Sun.COM int qualtype; 2328474SJose.Borrego@Sun.COM DWORD status = ERROR_SUCCESS; 2338474SJose.Borrego@Sun.COM 2348474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa)) { 2358474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetConnectEnum)); 2368474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 2378474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 2388474SJose.Borrego@Sun.COM } 2398474SJose.Borrego@Sun.COM 2408474SJose.Borrego@Sun.COM qualifier = (char *)param->qualifier; 2418474SJose.Borrego@Sun.COM qualtype = srvsvc_netconnect_qualifier(qualifier); 2428474SJose.Borrego@Sun.COM 2438474SJose.Borrego@Sun.COM if (qualtype == SRVSVC_CONNECT_ENUM_NULL) { 2448474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetConnectEnum)); 2458474SJose.Borrego@Sun.COM param->status = NERR_NetNameNotFound; 2468474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 2478474SJose.Borrego@Sun.COM } 2488474SJose.Borrego@Sun.COM 2498474SJose.Borrego@Sun.COM switch (param->info.level) { 2508474SJose.Borrego@Sun.COM case 0: 2518474SJose.Borrego@Sun.COM info0 = NDR_NEW(mxa, srvsvc_NetConnectInfo0_t); 2528474SJose.Borrego@Sun.COM if (info0 == NULL) { 2538474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 2548474SJose.Borrego@Sun.COM break; 2558474SJose.Borrego@Sun.COM } 2568474SJose.Borrego@Sun.COM 2578474SJose.Borrego@Sun.COM bzero(info0, sizeof (srvsvc_NetConnectInfo0_t)); 2588474SJose.Borrego@Sun.COM param->info.ru.info0 = info0; 2598474SJose.Borrego@Sun.COM 2608474SJose.Borrego@Sun.COM status = srvsvc_s_NetConnectEnumLevel0(mxa, info0); 2618474SJose.Borrego@Sun.COM 2628474SJose.Borrego@Sun.COM param->total_entries = info0->entries_read; 2638474SJose.Borrego@Sun.COM param->resume_handle = NULL; 2648474SJose.Borrego@Sun.COM break; 2658474SJose.Borrego@Sun.COM 2668474SJose.Borrego@Sun.COM case 1: 2678474SJose.Borrego@Sun.COM info1 = NDR_NEW(mxa, srvsvc_NetConnectInfo1_t); 2688474SJose.Borrego@Sun.COM if (info1 == NULL) { 2698474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 2708474SJose.Borrego@Sun.COM break; 2718474SJose.Borrego@Sun.COM } 2728474SJose.Borrego@Sun.COM 2738474SJose.Borrego@Sun.COM bzero(info1, sizeof (srvsvc_NetConnectInfo1_t)); 2748474SJose.Borrego@Sun.COM param->info.ru.info1 = info1; 2758474SJose.Borrego@Sun.COM 2768474SJose.Borrego@Sun.COM status = srvsvc_s_NetConnectEnumLevel1(mxa, info1); 2778474SJose.Borrego@Sun.COM 2788474SJose.Borrego@Sun.COM param->total_entries = info1->entries_read; 2798474SJose.Borrego@Sun.COM param->resume_handle = NULL; 2808474SJose.Borrego@Sun.COM break; 2818474SJose.Borrego@Sun.COM 2828474SJose.Borrego@Sun.COM case 50: 2838474SJose.Borrego@Sun.COM status = ERROR_NOT_SUPPORTED; 2848474SJose.Borrego@Sun.COM break; 2858474SJose.Borrego@Sun.COM 2868474SJose.Borrego@Sun.COM default: 2878474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 2888474SJose.Borrego@Sun.COM break; 2898474SJose.Borrego@Sun.COM } 2908474SJose.Borrego@Sun.COM 2918474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 2928474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetConnectEnum)); 2938474SJose.Borrego@Sun.COM 2948474SJose.Borrego@Sun.COM param->status = status; 2958474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 2968474SJose.Borrego@Sun.COM } 2978474SJose.Borrego@Sun.COM 2988474SJose.Borrego@Sun.COM static DWORD 2998474SJose.Borrego@Sun.COM srvsvc_s_NetConnectEnumLevel0(ndr_xa_t *mxa, srvsvc_NetConnectInfo0_t *info0) 3008474SJose.Borrego@Sun.COM { 3018474SJose.Borrego@Sun.COM srvsvc_NetConnectInfoBuf0_t *ci0; 3028474SJose.Borrego@Sun.COM 3038474SJose.Borrego@Sun.COM ci0 = NDR_NEW(mxa, srvsvc_NetConnectInfoBuf0_t); 3048474SJose.Borrego@Sun.COM if (ci0 == NULL) 3058474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 3068474SJose.Borrego@Sun.COM 3078474SJose.Borrego@Sun.COM ci0->coni0_id = 0x17; 3088474SJose.Borrego@Sun.COM 3098474SJose.Borrego@Sun.COM info0->ci0 = ci0; 3108474SJose.Borrego@Sun.COM info0->entries_read = 1; 3118474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 3128474SJose.Borrego@Sun.COM } 3138474SJose.Borrego@Sun.COM 3148474SJose.Borrego@Sun.COM static DWORD 3158474SJose.Borrego@Sun.COM srvsvc_s_NetConnectEnumLevel1(ndr_xa_t *mxa, srvsvc_NetConnectInfo1_t *info1) 3168474SJose.Borrego@Sun.COM { 3178474SJose.Borrego@Sun.COM srvsvc_NetConnectInfoBuf1_t *ci1; 3188474SJose.Borrego@Sun.COM 3198474SJose.Borrego@Sun.COM ci1 = NDR_NEW(mxa, srvsvc_NetConnectInfoBuf1_t); 3208474SJose.Borrego@Sun.COM if (ci1 == NULL) 3218474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 3228474SJose.Borrego@Sun.COM 3238474SJose.Borrego@Sun.COM ci1->coni1_id = 0x17; 3248474SJose.Borrego@Sun.COM ci1->coni1_type = STYPE_IPC; 3258474SJose.Borrego@Sun.COM ci1->coni1_num_opens = 1; 3268474SJose.Borrego@Sun.COM ci1->coni1_num_users = 1; 3278474SJose.Borrego@Sun.COM ci1->coni1_time = 16; 3288474SJose.Borrego@Sun.COM ci1->coni1_username = (uint8_t *)NDR_STRDUP(mxa, "Administrator"); 3298474SJose.Borrego@Sun.COM ci1->coni1_netname = (uint8_t *)NDR_STRDUP(mxa, "IPC$"); 3308474SJose.Borrego@Sun.COM 3318474SJose.Borrego@Sun.COM info1->ci1 = ci1; 3328474SJose.Borrego@Sun.COM info1->entries_read = 1; 3338474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 3348474SJose.Borrego@Sun.COM } 3358474SJose.Borrego@Sun.COM 3368474SJose.Borrego@Sun.COM /* 3378474SJose.Borrego@Sun.COM * srvsvc_netconnect_qualifier 3388474SJose.Borrego@Sun.COM * 3398474SJose.Borrego@Sun.COM * The qualifier is a string that specifies a share name or computer name 3408474SJose.Borrego@Sun.COM * for the connections of interest. If it is a share name then all the 3418474SJose.Borrego@Sun.COM * connections made to that share name are listed. If it is a computer 3428474SJose.Borrego@Sun.COM * name (it starts with two backslash characters), then NetConnectEnum 3438474SJose.Borrego@Sun.COM * lists all connections made from that computer to the specified server. 3448474SJose.Borrego@Sun.COM */ 3458474SJose.Borrego@Sun.COM static int 3468474SJose.Borrego@Sun.COM srvsvc_netconnect_qualifier(const char *qualifier) 3478474SJose.Borrego@Sun.COM { 3488474SJose.Borrego@Sun.COM if (qualifier == NULL || *qualifier == '\0') 3498474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_NULL); 3508474SJose.Borrego@Sun.COM 3518474SJose.Borrego@Sun.COM if (strlen(qualifier) > MAXHOSTNAMELEN) 3528474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_NULL); 3538474SJose.Borrego@Sun.COM 3548474SJose.Borrego@Sun.COM if (qualifier[0] == '\\' && qualifier[1] == '\\') { 3558474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_WKSTN); 3568474SJose.Borrego@Sun.COM } else { 3578474SJose.Borrego@Sun.COM if (!smb_shr_exists((char *)qualifier)) 3588474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_NULL); 3598474SJose.Borrego@Sun.COM 3608474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_SHARE); 3618474SJose.Borrego@Sun.COM } 3628474SJose.Borrego@Sun.COM } 3638474SJose.Borrego@Sun.COM 3648474SJose.Borrego@Sun.COM /* 3658474SJose.Borrego@Sun.COM * srvsvc_s_NetFileEnum 3668474SJose.Borrego@Sun.COM * 3678474SJose.Borrego@Sun.COM * Return information on open files or named pipes. Only members of the 3688474SJose.Borrego@Sun.COM * Administrators or Server Operators local groups are allowed to make 3698474SJose.Borrego@Sun.COM * this call. Currently, we only support Administrators. 3708474SJose.Borrego@Sun.COM * 3718474SJose.Borrego@Sun.COM * If basepath is null, all open resources are enumerated. If basepath 3728474SJose.Borrego@Sun.COM * is non-null, only resources that have basepath as a prefix should 3738474SJose.Borrego@Sun.COM * be returned. 3748474SJose.Borrego@Sun.COM * 3758474SJose.Borrego@Sun.COM * If username is specified (non-null), only files opened by username 3768474SJose.Borrego@Sun.COM * should be returned. 3778474SJose.Borrego@Sun.COM * 3788474SJose.Borrego@Sun.COM * Notes: 3798474SJose.Borrego@Sun.COM * 1. We don't validate the servername because we would have to check 3808474SJose.Borrego@Sun.COM * all primary IPs and the ROI seems unlikely to be worth it. 3818474SJose.Borrego@Sun.COM * 2. Both basepath and username are currently ignored because both 3828474SJose.Borrego@Sun.COM * Server Manger (NT 4.0) and CMI (Windows 2000) always set them to null. 3838474SJose.Borrego@Sun.COM * 3848474SJose.Borrego@Sun.COM * The level of information requested may be one of: 3858474SJose.Borrego@Sun.COM * 3868474SJose.Borrego@Sun.COM * 2 Return the file identification number. 3878474SJose.Borrego@Sun.COM * This level is not supported on Windows Me/98/95. 3888474SJose.Borrego@Sun.COM * 3898474SJose.Borrego@Sun.COM * 3 Return information about the file. 3908474SJose.Borrego@Sun.COM * This level is not supported on Windows Me/98/95. 3918474SJose.Borrego@Sun.COM * 3928474SJose.Borrego@Sun.COM * 50 Windows Me/98/95: Return information about the file. 3938474SJose.Borrego@Sun.COM * 3948474SJose.Borrego@Sun.COM * Note: 3958474SJose.Borrego@Sun.COM * If pref_max_len is unlimited and resume_handle is null, the client 3968474SJose.Borrego@Sun.COM * expects to receive all data in a single call. 3978474SJose.Borrego@Sun.COM * If we are unable to do fit all data in a single response, we would 3988474SJose.Borrego@Sun.COM * normally return ERROR_MORE_DATA with a partial list. 3998474SJose.Borrego@Sun.COM * 4008474SJose.Borrego@Sun.COM * Unfortunately, when both of these conditions occur, Server Manager 4018474SJose.Borrego@Sun.COM * pops up an error box with the message "more data available" and 4028474SJose.Borrego@Sun.COM * doesn't display any of the returned data. In this case, it is 4038474SJose.Borrego@Sun.COM * probably better to return ERROR_SUCCESS with the partial list. 4048474SJose.Borrego@Sun.COM * Windows 2000 doesn't have this problem because it always sends a 4058474SJose.Borrego@Sun.COM * non-null resume_handle. 4068474SJose.Borrego@Sun.COM * 4078474SJose.Borrego@Sun.COM * Return Values: 4088474SJose.Borrego@Sun.COM * ERROR_SUCCESS Success 4098474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED Caller does not have access to this call. 4108474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER One of the parameters is invalid. 4118474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL Unknown information level specified. 4128474SJose.Borrego@Sun.COM * ERROR_MORE_DATA Partial date returned, more entries available. 4138474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 4148474SJose.Borrego@Sun.COM * NERR_BufTooSmall The supplied buffer is too small. 4158474SJose.Borrego@Sun.COM */ 4168474SJose.Borrego@Sun.COM static int 4178474SJose.Borrego@Sun.COM srvsvc_s_NetFileEnum(void *arg, ndr_xa_t *mxa) 4188474SJose.Borrego@Sun.COM { 4198474SJose.Borrego@Sun.COM struct mslm_NetFileEnum *param = arg; 4208474SJose.Borrego@Sun.COM DWORD status; 4218474SJose.Borrego@Sun.COM 4228474SJose.Borrego@Sun.COM if (!ndr_is_admin(mxa)) { 4238474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetFileEnum)); 4248474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 4258474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 4268474SJose.Borrego@Sun.COM } 4278474SJose.Borrego@Sun.COM 4288474SJose.Borrego@Sun.COM switch (param->info.switch_value) { 4298474SJose.Borrego@Sun.COM case 2: 4308474SJose.Borrego@Sun.COM status = srvsvc_NetFileEnum2(mxa, param); 4318474SJose.Borrego@Sun.COM break; 4328474SJose.Borrego@Sun.COM 4338474SJose.Borrego@Sun.COM case 3: 4348474SJose.Borrego@Sun.COM status = srvsvc_NetFileEnum3(mxa, param); 4358474SJose.Borrego@Sun.COM break; 4368474SJose.Borrego@Sun.COM 4378474SJose.Borrego@Sun.COM case 50: 4388474SJose.Borrego@Sun.COM status = ERROR_NOT_SUPPORTED; 4398474SJose.Borrego@Sun.COM break; 4408474SJose.Borrego@Sun.COM 4418474SJose.Borrego@Sun.COM default: 4428474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 4438474SJose.Borrego@Sun.COM break; 4448474SJose.Borrego@Sun.COM } 4458474SJose.Borrego@Sun.COM 4468474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) { 4478474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetFileEnum)); 4488474SJose.Borrego@Sun.COM param->status = status; 4498474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 4508474SJose.Borrego@Sun.COM } 4518474SJose.Borrego@Sun.COM 4528474SJose.Borrego@Sun.COM if (param->resume_handle) 4538474SJose.Borrego@Sun.COM *param->resume_handle = 0; 4548474SJose.Borrego@Sun.COM 4558474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 4568474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 4578474SJose.Borrego@Sun.COM } 4588474SJose.Borrego@Sun.COM 4598474SJose.Borrego@Sun.COM /* 4608474SJose.Borrego@Sun.COM * Build level 2 file information. 4618474SJose.Borrego@Sun.COM * 4628474SJose.Borrego@Sun.COM * On success, the caller expects that the info2, fi2 and entries_read 4638474SJose.Borrego@Sun.COM * fields have been set up. 4648474SJose.Borrego@Sun.COM */ 4658474SJose.Borrego@Sun.COM static DWORD 4668474SJose.Borrego@Sun.COM srvsvc_NetFileEnum2(ndr_xa_t *mxa, struct mslm_NetFileEnum *param) 4678474SJose.Borrego@Sun.COM { 4688474SJose.Borrego@Sun.COM struct mslm_NetFileInfoBuf2 *fi2; 4698474SJose.Borrego@Sun.COM ndr_pipe_info_t pi; 4708474SJose.Borrego@Sun.COM uint32_t entries_read = 0; 4718474SJose.Borrego@Sun.COM int i; 4728474SJose.Borrego@Sun.COM 4738474SJose.Borrego@Sun.COM param->info.ru.info2 = NDR_NEW(mxa, struct mslm_NetFileInfo2); 474*9832Samw@Sun.COM if (param->info.ru.info2 == NULL) 4758474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 4768474SJose.Borrego@Sun.COM 4778474SJose.Borrego@Sun.COM fi2 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf2, 128); 4788474SJose.Borrego@Sun.COM if (fi2 == NULL) 4798474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 4808474SJose.Borrego@Sun.COM 4818474SJose.Borrego@Sun.COM param->info.ru.info2->fi2 = fi2; 4828474SJose.Borrego@Sun.COM 4838474SJose.Borrego@Sun.COM for (i = 0; i < 128; ++i) { 4848474SJose.Borrego@Sun.COM if (ndr_pipe_getinfo(i, &pi) == -1) 4858474SJose.Borrego@Sun.COM continue; 4868474SJose.Borrego@Sun.COM 4878474SJose.Borrego@Sun.COM fi2->fi2_id = pi.npi_fid; 4888474SJose.Borrego@Sun.COM 4898474SJose.Borrego@Sun.COM ++entries_read; 4908474SJose.Borrego@Sun.COM ++fi2; 4918474SJose.Borrego@Sun.COM } 4928474SJose.Borrego@Sun.COM 4938474SJose.Borrego@Sun.COM param->info.ru.info2->entries_read = entries_read; 4948474SJose.Borrego@Sun.COM param->total_entries = entries_read; 4958474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 4968474SJose.Borrego@Sun.COM } 4978474SJose.Borrego@Sun.COM 4988474SJose.Borrego@Sun.COM /* 4998474SJose.Borrego@Sun.COM * Build level 3 file information. 5008474SJose.Borrego@Sun.COM * 5018474SJose.Borrego@Sun.COM * On success, the caller expects that the info3, fi3 and entries_read 5028474SJose.Borrego@Sun.COM * fields have been set up. 5038474SJose.Borrego@Sun.COM */ 5048474SJose.Borrego@Sun.COM static DWORD 5058474SJose.Borrego@Sun.COM srvsvc_NetFileEnum3(ndr_xa_t *mxa, struct mslm_NetFileEnum *param) 5068474SJose.Borrego@Sun.COM { 5078474SJose.Borrego@Sun.COM struct mslm_NetFileInfoBuf3 *fi3; 5088474SJose.Borrego@Sun.COM ndr_pipe_info_t pi; 5098474SJose.Borrego@Sun.COM uint32_t entries_read = 0; 5108474SJose.Borrego@Sun.COM int i; 5118474SJose.Borrego@Sun.COM 5128474SJose.Borrego@Sun.COM param->info.ru.info3 = NDR_NEW(mxa, struct mslm_NetFileInfo3); 5138474SJose.Borrego@Sun.COM if (param->info.ru.info3 == NULL) 5148474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 5158474SJose.Borrego@Sun.COM 5168474SJose.Borrego@Sun.COM fi3 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf3, 128); 5178474SJose.Borrego@Sun.COM if (fi3 == NULL) 5188474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 5198474SJose.Borrego@Sun.COM 5208474SJose.Borrego@Sun.COM param->info.ru.info3->fi3 = fi3; 5218474SJose.Borrego@Sun.COM 5228474SJose.Borrego@Sun.COM for (i = 0; i < 128; ++i) { 5238474SJose.Borrego@Sun.COM if (ndr_pipe_getinfo(i, &pi) == -1) 5248474SJose.Borrego@Sun.COM continue; 5258474SJose.Borrego@Sun.COM 5268474SJose.Borrego@Sun.COM fi3->fi3_id = pi.npi_fid; 5278474SJose.Borrego@Sun.COM fi3->fi3_permissions = pi.npi_permissions; 5288474SJose.Borrego@Sun.COM fi3->fi3_num_locks = pi.npi_num_locks; 5298474SJose.Borrego@Sun.COM fi3->fi3_pathname = (uint8_t *) 5308474SJose.Borrego@Sun.COM NDR_STRDUP(mxa, pi.npi_pathname); 5318474SJose.Borrego@Sun.COM fi3->fi3_username = (uint8_t *) 5328474SJose.Borrego@Sun.COM NDR_STRDUP(mxa, pi.npi_username); 5338474SJose.Borrego@Sun.COM 5348474SJose.Borrego@Sun.COM ++entries_read; 5358474SJose.Borrego@Sun.COM ++fi3; 5368474SJose.Borrego@Sun.COM } 5378474SJose.Borrego@Sun.COM 5388474SJose.Borrego@Sun.COM param->info.ru.info3->entries_read = entries_read; 5398474SJose.Borrego@Sun.COM param->total_entries = entries_read; 5408474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 5418474SJose.Borrego@Sun.COM } 5428474SJose.Borrego@Sun.COM 5438474SJose.Borrego@Sun.COM /* 5448474SJose.Borrego@Sun.COM * srvsvc_s_NetFileClose 5458474SJose.Borrego@Sun.COM * 5468474SJose.Borrego@Sun.COM * NetFileClose forces a file to close. This function can be used when 5478474SJose.Borrego@Sun.COM * an error prevents closure by any other means. Use NetFileClose with 5488474SJose.Borrego@Sun.COM * caution because it does not flush data, cached on a client, to the 5498474SJose.Borrego@Sun.COM * file before closing the file. 5508474SJose.Borrego@Sun.COM * 5518474SJose.Borrego@Sun.COM * Return Values 5528474SJose.Borrego@Sun.COM * ERROR_SUCCESS Operation succeeded. 5538474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED Operation denied. 5548474SJose.Borrego@Sun.COM * NERR_FileIdNotFound No open file with the specified id. 5558474SJose.Borrego@Sun.COM * 5568474SJose.Borrego@Sun.COM * Note: MSDN suggests that the error code should be ERROR_FILE_NOT_FOUND 5578474SJose.Borrego@Sun.COM * but network captures using NT show NERR_FileIdNotFound. 5588474SJose.Borrego@Sun.COM * The NetFileClose2 MSDN page has the right error code. 5598474SJose.Borrego@Sun.COM */ 5608474SJose.Borrego@Sun.COM static int 5618474SJose.Borrego@Sun.COM srvsvc_s_NetFileClose(void *arg, ndr_xa_t *mxa) 5628474SJose.Borrego@Sun.COM { 5638474SJose.Borrego@Sun.COM struct mslm_NetFileClose *param = arg; 5648474SJose.Borrego@Sun.COM 5658474SJose.Borrego@Sun.COM if (!ndr_is_admin(mxa)) { 5668474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetFileClose)); 5678474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 5688474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5698474SJose.Borrego@Sun.COM } 5708474SJose.Borrego@Sun.COM 5718474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetFileClose)); 5728474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 5738474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5748474SJose.Borrego@Sun.COM } 5758474SJose.Borrego@Sun.COM 5768474SJose.Borrego@Sun.COM /* 5778474SJose.Borrego@Sun.COM * srvsvc_s_NetShareGetInfo 5788474SJose.Borrego@Sun.COM * 5798474SJose.Borrego@Sun.COM * Returns Win32 error codes. 5808474SJose.Borrego@Sun.COM */ 5818474SJose.Borrego@Sun.COM static int 5828474SJose.Borrego@Sun.COM srvsvc_s_NetShareGetInfo(void *arg, ndr_xa_t *mxa) 5838474SJose.Borrego@Sun.COM { 5848474SJose.Borrego@Sun.COM struct mlsm_NetShareGetInfo *param = arg; 5859343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_0 *info0; 5869343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1 *info1; 5879343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_2 *info2; 5889343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_501 *info501; 5899343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_502 *info502; 590*9832Samw@Sun.COM struct mslm_NetShareInfo_503 *info503; 5919343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1004 *info1004; 5929343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1005 *info1005; 5939343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1006 *info1006; 594*9832Samw@Sun.COM struct mslm_NetShareInfo_1501 *info1501; 595*9832Samw@Sun.COM srvsvc_netshare_getinfo_t *info; 596*9832Samw@Sun.COM uint8_t *netname; 597*9832Samw@Sun.COM uint8_t *comment; 5988474SJose.Borrego@Sun.COM smb_share_t si; 599*9832Samw@Sun.COM srvsvc_sd_t sd; 6008474SJose.Borrego@Sun.COM DWORD status; 6018474SJose.Borrego@Sun.COM 6028474SJose.Borrego@Sun.COM status = smb_shr_get((char *)param->netname, &si); 6038474SJose.Borrego@Sun.COM if (status != NERR_Success) { 6048474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mlsm_NetShareGetInfo)); 6058474SJose.Borrego@Sun.COM param->status = status; 6068474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6078474SJose.Borrego@Sun.COM } 6088474SJose.Borrego@Sun.COM 609*9832Samw@Sun.COM netname = (uint8_t *)NDR_STRDUP(mxa, si.shr_name); 610*9832Samw@Sun.COM comment = (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt); 611*9832Samw@Sun.COM info = NDR_NEW(mxa, srvsvc_netshare_getinfo_t); 612*9832Samw@Sun.COM 613*9832Samw@Sun.COM if (netname == NULL || comment == NULL || info == NULL) { 614*9832Samw@Sun.COM bzero(param, sizeof (struct mlsm_NetShareGetInfo)); 615*9832Samw@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 616*9832Samw@Sun.COM return (NDR_DRC_OK); 617*9832Samw@Sun.COM } 618*9832Samw@Sun.COM 6198474SJose.Borrego@Sun.COM switch (param->level) { 6208474SJose.Borrego@Sun.COM case 0: 621*9832Samw@Sun.COM info0 = &info->nsg_info0; 622*9832Samw@Sun.COM info0->shi0_netname = netname; 6238474SJose.Borrego@Sun.COM param->result.ru.info0 = info0; 6248474SJose.Borrego@Sun.COM break; 6258474SJose.Borrego@Sun.COM 6268474SJose.Borrego@Sun.COM case 1: 627*9832Samw@Sun.COM info1 = &info->nsg_info1; 628*9832Samw@Sun.COM info1->shi1_netname = netname; 629*9832Samw@Sun.COM info1->shi1_comment = comment; 6308474SJose.Borrego@Sun.COM info1->shi1_type = si.shr_type; 6318474SJose.Borrego@Sun.COM param->result.ru.info1 = info1; 6328474SJose.Borrego@Sun.COM break; 6338474SJose.Borrego@Sun.COM 6348474SJose.Borrego@Sun.COM case 2: 635*9832Samw@Sun.COM info2 = &info->nsg_info2; 636*9832Samw@Sun.COM info2->shi2_netname = netname; 637*9832Samw@Sun.COM info2->shi2_comment = comment; 6388474SJose.Borrego@Sun.COM info2->shi2_path = 6398474SJose.Borrego@Sun.COM (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path); 6408474SJose.Borrego@Sun.COM info2->shi2_passwd = 0; 6418474SJose.Borrego@Sun.COM info2->shi2_type = si.shr_type; 6428474SJose.Borrego@Sun.COM info2->shi2_permissions = 0; 6438474SJose.Borrego@Sun.COM info2->shi2_max_uses = SHI_USES_UNLIMITED; 6448474SJose.Borrego@Sun.COM info2->shi2_current_uses = 0; 6458474SJose.Borrego@Sun.COM param->result.ru.info2 = info2; 6468474SJose.Borrego@Sun.COM break; 6478474SJose.Borrego@Sun.COM 648*9832Samw@Sun.COM case 501: 649*9832Samw@Sun.COM info501 = &info->nsg_info501; 650*9832Samw@Sun.COM info501->shi501_netname = netname; 651*9832Samw@Sun.COM info501->shi501_comment = comment; 652*9832Samw@Sun.COM info501->shi501_type = si.shr_type; 653*9832Samw@Sun.COM info501->shi501_reserved = 0; 654*9832Samw@Sun.COM param->result.ru.info501 = info501; 655*9832Samw@Sun.COM break; 656*9832Samw@Sun.COM 657*9832Samw@Sun.COM case 502: 658*9832Samw@Sun.COM info502 = &info->nsg_info502; 659*9832Samw@Sun.COM info502->shi502_netname = netname; 660*9832Samw@Sun.COM info502->shi502_comment = comment; 661*9832Samw@Sun.COM info502->shi502_path = 662*9832Samw@Sun.COM (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path); 663*9832Samw@Sun.COM info502->shi502_passwd = 0; 664*9832Samw@Sun.COM info502->shi502_type = si.shr_type; 665*9832Samw@Sun.COM info502->shi502_permissions = 0; 666*9832Samw@Sun.COM info502->shi502_max_uses = SHI_USES_UNLIMITED; 667*9832Samw@Sun.COM info502->shi502_current_uses = 0; 668*9832Samw@Sun.COM 669*9832Samw@Sun.COM status = srvsvc_share_getsd(mxa, &si, &sd); 670*9832Samw@Sun.COM if (status == ERROR_SUCCESS) { 671*9832Samw@Sun.COM info502->shi502_reserved = sd.sd_size; 672*9832Samw@Sun.COM info502->shi502_security_descriptor = sd.sd_buf; 673*9832Samw@Sun.COM } else { 674*9832Samw@Sun.COM info502->shi502_reserved = 0; 675*9832Samw@Sun.COM info502->shi502_security_descriptor = NULL; 6768474SJose.Borrego@Sun.COM } 6778474SJose.Borrego@Sun.COM 678*9832Samw@Sun.COM param->result.ru.info502 = info502; 679*9832Samw@Sun.COM break; 680*9832Samw@Sun.COM 681*9832Samw@Sun.COM case 503: 682*9832Samw@Sun.COM info503 = &info->nsg_info503; 683*9832Samw@Sun.COM info503->shi503_netname = netname; 684*9832Samw@Sun.COM info503->shi503_comment = comment; 685*9832Samw@Sun.COM info503->shi503_path = 686*9832Samw@Sun.COM (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path); 687*9832Samw@Sun.COM info503->shi503_passwd = NULL; 688*9832Samw@Sun.COM info503->shi503_type = si.shr_type; 689*9832Samw@Sun.COM info503->shi503_permissions = 0; 690*9832Samw@Sun.COM info503->shi503_max_uses = SHI_USES_UNLIMITED; 691*9832Samw@Sun.COM info503->shi503_current_uses = 0; 692*9832Samw@Sun.COM info503->shi503_servername = NULL; 693*9832Samw@Sun.COM 694*9832Samw@Sun.COM status = srvsvc_share_getsd(mxa, &si, &sd); 695*9832Samw@Sun.COM if (status == ERROR_SUCCESS) { 696*9832Samw@Sun.COM info503->shi503_reserved = sd.sd_size; 697*9832Samw@Sun.COM info503->shi503_security_descriptor = sd.sd_buf; 698*9832Samw@Sun.COM } else { 699*9832Samw@Sun.COM info503->shi503_reserved = 0; 700*9832Samw@Sun.COM info503->shi503_security_descriptor = NULL; 701*9832Samw@Sun.COM } 702*9832Samw@Sun.COM 703*9832Samw@Sun.COM param->result.ru.info503 = info503; 704*9832Samw@Sun.COM break; 705*9832Samw@Sun.COM 706*9832Samw@Sun.COM case 1004: 707*9832Samw@Sun.COM info1004 = &info->nsg_info1004; 708*9832Samw@Sun.COM info1004->shi1004_comment = comment; 709*9832Samw@Sun.COM param->result.ru.info1004 = info1004; 7108474SJose.Borrego@Sun.COM break; 7118474SJose.Borrego@Sun.COM 7128474SJose.Borrego@Sun.COM case 1005: 713*9832Samw@Sun.COM info1005 = &info->nsg_info1005; 7148474SJose.Borrego@Sun.COM info1005->shi1005_flags = 0; 7158474SJose.Borrego@Sun.COM 7168474SJose.Borrego@Sun.COM switch (si.shr_flags & SMB_SHRF_CSC_MASK) { 7178474SJose.Borrego@Sun.COM case SMB_SHRF_CSC_DISABLED: 7188474SJose.Borrego@Sun.COM info1005->shi1005_flags |= CSC_CACHE_NONE; 7198474SJose.Borrego@Sun.COM break; 7208474SJose.Borrego@Sun.COM case SMB_SHRF_CSC_AUTO: 7218474SJose.Borrego@Sun.COM info1005->shi1005_flags |= CSC_CACHE_AUTO_REINT; 7228474SJose.Borrego@Sun.COM break; 7238474SJose.Borrego@Sun.COM case SMB_SHRF_CSC_VDO: 7248474SJose.Borrego@Sun.COM info1005->shi1005_flags |= CSC_CACHE_VDO; 7258474SJose.Borrego@Sun.COM break; 7268474SJose.Borrego@Sun.COM case SMB_SHRF_CSC_MANUAL: 7278474SJose.Borrego@Sun.COM default: 7288474SJose.Borrego@Sun.COM /* 7298474SJose.Borrego@Sun.COM * Default to CSC_CACHE_MANUAL_REINT. 7308474SJose.Borrego@Sun.COM */ 7318474SJose.Borrego@Sun.COM break; 7328474SJose.Borrego@Sun.COM } 7338474SJose.Borrego@Sun.COM 7348474SJose.Borrego@Sun.COM param->result.ru.info1005 = info1005; 7358474SJose.Borrego@Sun.COM break; 7368474SJose.Borrego@Sun.COM 7378474SJose.Borrego@Sun.COM case 1006: 738*9832Samw@Sun.COM info1006 = &info->nsg_info1006; 7398474SJose.Borrego@Sun.COM info1006->shi1006_max_uses = SHI_USES_UNLIMITED; 7408474SJose.Borrego@Sun.COM param->result.ru.info1006 = info1006; 7418474SJose.Borrego@Sun.COM break; 7428474SJose.Borrego@Sun.COM 743*9832Samw@Sun.COM case 1501: 744*9832Samw@Sun.COM info1501 = &info->nsg_info1501; 745*9832Samw@Sun.COM 746*9832Samw@Sun.COM status = srvsvc_share_getsd(mxa, &si, &sd); 747*9832Samw@Sun.COM if (status == ERROR_SUCCESS) { 748*9832Samw@Sun.COM info503->shi503_reserved = sd.sd_size; 749*9832Samw@Sun.COM info503->shi503_security_descriptor = sd.sd_buf; 750*9832Samw@Sun.COM } else { 751*9832Samw@Sun.COM info503->shi503_reserved = 0; 752*9832Samw@Sun.COM info503->shi503_security_descriptor = NULL; 7538474SJose.Borrego@Sun.COM } 7548474SJose.Borrego@Sun.COM 755*9832Samw@Sun.COM param->result.ru.info1501 = info1501; 7568474SJose.Borrego@Sun.COM break; 7578474SJose.Borrego@Sun.COM 7588474SJose.Borrego@Sun.COM default: 7598474SJose.Borrego@Sun.COM status = ERROR_ACCESS_DENIED; 7608474SJose.Borrego@Sun.COM break; 7618474SJose.Borrego@Sun.COM } 7628474SJose.Borrego@Sun.COM 7638474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 7648474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mlsm_NetShareGetInfo)); 7658474SJose.Borrego@Sun.COM else 7668474SJose.Borrego@Sun.COM param->result.switch_value = param->level; 7678474SJose.Borrego@Sun.COM 7688474SJose.Borrego@Sun.COM param->status = status; 7698474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 7708474SJose.Borrego@Sun.COM } 7718474SJose.Borrego@Sun.COM 772*9832Samw@Sun.COM static uint32_t 773*9832Samw@Sun.COM srvsvc_share_getsd(ndr_xa_t *mxa, smb_share_t *si, srvsvc_sd_t *sd) 774*9832Samw@Sun.COM { 775*9832Samw@Sun.COM uint32_t status; 776*9832Samw@Sun.COM 777*9832Samw@Sun.COM status = srvsvc_sd_get(si, NULL, &sd->sd_size); 778*9832Samw@Sun.COM if (status != ERROR_SUCCESS) { 779*9832Samw@Sun.COM if (status == ERROR_PATH_NOT_FOUND) { 780*9832Samw@Sun.COM bzero(sd, sizeof (srvsvc_sd_t)); 781*9832Samw@Sun.COM status = ERROR_SUCCESS; 782*9832Samw@Sun.COM } 783*9832Samw@Sun.COM 784*9832Samw@Sun.COM return (status); 785*9832Samw@Sun.COM } 786*9832Samw@Sun.COM 787*9832Samw@Sun.COM if ((sd->sd_buf = NDR_MALLOC(mxa, sd->sd_size)) == NULL) 788*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 789*9832Samw@Sun.COM 790*9832Samw@Sun.COM status = srvsvc_sd_get(si, sd->sd_buf, NULL); 791*9832Samw@Sun.COM if (status == ERROR_PATH_NOT_FOUND) { 792*9832Samw@Sun.COM bzero(sd, sizeof (srvsvc_sd_t)); 793*9832Samw@Sun.COM status = ERROR_SUCCESS; 794*9832Samw@Sun.COM } 795*9832Samw@Sun.COM 796*9832Samw@Sun.COM return (status); 797*9832Samw@Sun.COM } 7988474SJose.Borrego@Sun.COM 7998474SJose.Borrego@Sun.COM /* 8008474SJose.Borrego@Sun.COM * srvsvc_s_NetShareSetInfo 8018474SJose.Borrego@Sun.COM * 8028474SJose.Borrego@Sun.COM * This call is made by SrvMgr to set share information. 803*9832Samw@Sun.COM * Only power users groups can manage shares. 804*9832Samw@Sun.COM * 805*9832Samw@Sun.COM * To avoid misleading errors, we don't report an error 806*9832Samw@Sun.COM * when a FS doesn't support ACLs on shares. 8078474SJose.Borrego@Sun.COM * 8088474SJose.Borrego@Sun.COM * Returns Win32 error codes. 8098474SJose.Borrego@Sun.COM */ 8108474SJose.Borrego@Sun.COM static int 8118474SJose.Borrego@Sun.COM srvsvc_s_NetShareSetInfo(void *arg, ndr_xa_t *mxa) 8128474SJose.Borrego@Sun.COM { 8138474SJose.Borrego@Sun.COM struct mlsm_NetShareSetInfo *param = arg; 814*9832Samw@Sun.COM struct mslm_NetShareInfo_0 *info0; 815*9832Samw@Sun.COM struct mslm_NetShareInfo_1 *info1; 816*9832Samw@Sun.COM struct mslm_NetShareInfo_2 *info2; 817*9832Samw@Sun.COM struct mslm_NetShareInfo_501 *info501; 818*9832Samw@Sun.COM struct mslm_NetShareInfo_502 *info502; 819*9832Samw@Sun.COM struct mslm_NetShareInfo_503 *info503; 820*9832Samw@Sun.COM struct mslm_NetShareInfo_1004 *info1004; 821*9832Samw@Sun.COM struct mslm_NetShareInfo_1005 *info1005; 822*9832Samw@Sun.COM struct mslm_NetShareInfo_1501 *info1501; 823*9832Samw@Sun.COM static DWORD parm_err = 0; 824*9832Samw@Sun.COM srvsvc_netshare_setinfo_t info; 825*9832Samw@Sun.COM smb_share_t si; 826*9832Samw@Sun.COM uint8_t *sdbuf; 827*9832Samw@Sun.COM int32_t native_os; 828*9832Samw@Sun.COM DWORD status; 829*9832Samw@Sun.COM 830*9832Samw@Sun.COM native_os = ndr_native_os(mxa); 831*9832Samw@Sun.COM 832*9832Samw@Sun.COM if (!ndr_is_poweruser(mxa)) { 833*9832Samw@Sun.COM status = ERROR_ACCESS_DENIED; 834*9832Samw@Sun.COM goto netsharesetinfo_exit; 835*9832Samw@Sun.COM } 836*9832Samw@Sun.COM 837*9832Samw@Sun.COM if (smb_shr_get((char *)param->netname, &si) != NERR_Success) { 838*9832Samw@Sun.COM status = ERROR_INVALID_NETNAME; 839*9832Samw@Sun.COM goto netsharesetinfo_exit; 840*9832Samw@Sun.COM } 841*9832Samw@Sun.COM 842*9832Samw@Sun.COM if (param->result.ru.nullptr == NULL) { 843*9832Samw@Sun.COM status = ERROR_INVALID_PARAMETER; 844*9832Samw@Sun.COM goto netsharesetinfo_exit; 845*9832Samw@Sun.COM } 846*9832Samw@Sun.COM 847*9832Samw@Sun.COM bzero(&info, sizeof (srvsvc_netshare_setinfo_t)); 848*9832Samw@Sun.COM 849*9832Samw@Sun.COM switch (param->level) { 850*9832Samw@Sun.COM case 0: 851*9832Samw@Sun.COM info0 = (struct mslm_NetShareInfo_0 *)param->result.ru.info0; 852*9832Samw@Sun.COM info.nss_netname = (char *)info0->shi0_netname; 853*9832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 854*9832Samw@Sun.COM break; 855*9832Samw@Sun.COM 856*9832Samw@Sun.COM case 1: 857*9832Samw@Sun.COM info1 = (struct mslm_NetShareInfo_1 *)param->result.ru.info1; 858*9832Samw@Sun.COM info.nss_netname = (char *)info1->shi1_netname; 859*9832Samw@Sun.COM info.nss_comment = (char *)info1->shi1_comment; 860*9832Samw@Sun.COM info.nss_type = info1->shi1_type; 861*9832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 862*9832Samw@Sun.COM break; 863*9832Samw@Sun.COM 864*9832Samw@Sun.COM case 2: 865*9832Samw@Sun.COM info2 = (struct mslm_NetShareInfo_2 *)param->result.ru.info2; 866*9832Samw@Sun.COM info.nss_netname = (char *)info2->shi2_netname; 867*9832Samw@Sun.COM info.nss_comment = (char *)info2->shi2_comment; 868*9832Samw@Sun.COM info.nss_path = (char *)info2->shi2_path; 869*9832Samw@Sun.COM info.nss_type = info2->shi2_type; 870*9832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 871*9832Samw@Sun.COM break; 872*9832Samw@Sun.COM 873*9832Samw@Sun.COM case 501: 874*9832Samw@Sun.COM info501 = (struct mslm_NetShareInfo_501 *) 875*9832Samw@Sun.COM param->result.ru.info501; 876*9832Samw@Sun.COM info.nss_netname = (char *)info501->shi501_netname; 877*9832Samw@Sun.COM info.nss_comment = (char *)info501->shi501_comment; 878*9832Samw@Sun.COM info.nss_type = info501->shi501_type; 879*9832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 880*9832Samw@Sun.COM break; 881*9832Samw@Sun.COM 882*9832Samw@Sun.COM case 502: 883*9832Samw@Sun.COM info502 = (struct mslm_NetShareInfo_502 *) 884*9832Samw@Sun.COM param->result.ru.info502; 885*9832Samw@Sun.COM info.nss_netname = (char *)info502->shi502_netname; 886*9832Samw@Sun.COM info.nss_comment = (char *)info502->shi502_comment; 887*9832Samw@Sun.COM info.nss_path = (char *)info502->shi502_path; 888*9832Samw@Sun.COM info.nss_type = info502->shi502_type; 889*9832Samw@Sun.COM info.nss_sd.sd_buf = info502->shi502_security_descriptor; 890*9832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 891*9832Samw@Sun.COM break; 892*9832Samw@Sun.COM 893*9832Samw@Sun.COM case 503: 894*9832Samw@Sun.COM info503 = (struct mslm_NetShareInfo_503 *) 895*9832Samw@Sun.COM param->result.ru.info503; 896*9832Samw@Sun.COM info.nss_netname = (char *)info503->shi503_netname; 897*9832Samw@Sun.COM info.nss_comment = (char *)info503->shi503_comment; 898*9832Samw@Sun.COM info.nss_path = (char *)info503->shi503_path; 899*9832Samw@Sun.COM info.nss_type = info503->shi503_type; 900*9832Samw@Sun.COM info.nss_sd.sd_buf = info503->shi503_security_descriptor; 901*9832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 902*9832Samw@Sun.COM break; 903*9832Samw@Sun.COM 904*9832Samw@Sun.COM case 1004: 905*9832Samw@Sun.COM info1004 = (struct mslm_NetShareInfo_1004 *) 906*9832Samw@Sun.COM param->result.ru.info1004; 907*9832Samw@Sun.COM info.nss_comment = (char *)info1004->shi1004_comment; 908*9832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 909*9832Samw@Sun.COM break; 910*9832Samw@Sun.COM 911*9832Samw@Sun.COM case 1005: 912*9832Samw@Sun.COM info1005 = (struct mslm_NetShareInfo_1005 *) 913*9832Samw@Sun.COM param->result.ru.info1005; 914*9832Samw@Sun.COM status = srvsvc_update_share_flags(&si, 915*9832Samw@Sun.COM info1005->shi1005_flags); 916*9832Samw@Sun.COM break; 917*9832Samw@Sun.COM 918*9832Samw@Sun.COM case 1006: 919*9832Samw@Sun.COM /* 920*9832Samw@Sun.COM * We don't limit the maximum number of concurrent 921*9832Samw@Sun.COM * connections to a share. 922*9832Samw@Sun.COM */ 923*9832Samw@Sun.COM status = ERROR_SUCCESS; 924*9832Samw@Sun.COM break; 925*9832Samw@Sun.COM 926*9832Samw@Sun.COM case 1501: 927*9832Samw@Sun.COM info1501 = (struct mslm_NetShareInfo_1501 *) 928*9832Samw@Sun.COM param->result.ru.info1501; 929*9832Samw@Sun.COM sdbuf = info1501->shi1501_security_descriptor; 930*9832Samw@Sun.COM status = ERROR_SUCCESS; 931*9832Samw@Sun.COM 932*9832Samw@Sun.COM if (sdbuf != NULL) { 933*9832Samw@Sun.COM status = srvsvc_sd_set(&si, sdbuf); 934*9832Samw@Sun.COM if (status == ERROR_PATH_NOT_FOUND) 935*9832Samw@Sun.COM status = ERROR_SUCCESS; 936*9832Samw@Sun.COM } 937*9832Samw@Sun.COM break; 938*9832Samw@Sun.COM 939*9832Samw@Sun.COM default: 940*9832Samw@Sun.COM status = ERROR_ACCESS_DENIED; 941*9832Samw@Sun.COM break; 942*9832Samw@Sun.COM } 943*9832Samw@Sun.COM 944*9832Samw@Sun.COM netsharesetinfo_exit: 945*9832Samw@Sun.COM if (status != ERROR_SUCCESS) 946*9832Samw@Sun.COM bzero(param, sizeof (struct mlsm_NetShareSetInfo)); 947*9832Samw@Sun.COM 948*9832Samw@Sun.COM param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; 949*9832Samw@Sun.COM param->status = status; 9508474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9518474SJose.Borrego@Sun.COM } 9528474SJose.Borrego@Sun.COM 953*9832Samw@Sun.COM static uint32_t 954*9832Samw@Sun.COM srvsvc_modify_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info) 955*9832Samw@Sun.COM { 956*9832Samw@Sun.COM uint32_t nerr = NERR_Success; 957*9832Samw@Sun.COM 958*9832Samw@Sun.COM if (si->shr_flags & SMB_SHRF_TRANS) 959*9832Samw@Sun.COM return (srvsvc_modify_transient_share(si, info)); 960*9832Samw@Sun.COM 961*9832Samw@Sun.COM if (info->nss_sd.sd_buf != NULL) { 962*9832Samw@Sun.COM nerr = srvsvc_sd_set(si, info->nss_sd.sd_buf); 963*9832Samw@Sun.COM if (nerr == ERROR_PATH_NOT_FOUND) 964*9832Samw@Sun.COM nerr = NERR_Success; 965*9832Samw@Sun.COM } 966*9832Samw@Sun.COM 967*9832Samw@Sun.COM if ((nerr = srvsvc_sa_modify(si, info)) == NERR_Success) 968*9832Samw@Sun.COM nerr = smb_shr_modify(si); 969*9832Samw@Sun.COM 970*9832Samw@Sun.COM return (nerr); 971*9832Samw@Sun.COM } 972*9832Samw@Sun.COM 973*9832Samw@Sun.COM /* 974*9832Samw@Sun.COM * Update transient shares. This includes autohome shares. 975*9832Samw@Sun.COM */ 976*9832Samw@Sun.COM static uint32_t 977*9832Samw@Sun.COM srvsvc_modify_transient_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info) 978*9832Samw@Sun.COM { 979*9832Samw@Sun.COM uint32_t nerr; 980*9832Samw@Sun.COM 981*9832Samw@Sun.COM if (info->nss_netname != NULL && info->nss_netname[0] != '\0' && 982*9832Samw@Sun.COM utf8_strcasecmp(info->nss_netname, si->shr_name) != 0) { 983*9832Samw@Sun.COM nerr = smb_shr_rename(si->shr_name, info->nss_netname); 984*9832Samw@Sun.COM if (nerr != NERR_Success) 985*9832Samw@Sun.COM return (nerr); 986*9832Samw@Sun.COM 987*9832Samw@Sun.COM (void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN); 988*9832Samw@Sun.COM } 989*9832Samw@Sun.COM 990*9832Samw@Sun.COM if ((info->nss_comment != NULL) && 991*9832Samw@Sun.COM (strcmp(info->nss_comment, si->shr_cmnt) != 0)) { 992*9832Samw@Sun.COM (void) strlcpy(si->shr_cmnt, info->nss_comment, 993*9832Samw@Sun.COM SMB_SHARE_CMNT_MAX); 994*9832Samw@Sun.COM 995*9832Samw@Sun.COM if ((nerr = smb_shr_modify(si)) != NERR_Success) 996*9832Samw@Sun.COM return (nerr); 997*9832Samw@Sun.COM } 998*9832Samw@Sun.COM 999*9832Samw@Sun.COM return (NERR_Success); 1000*9832Samw@Sun.COM } 1001*9832Samw@Sun.COM 1002*9832Samw@Sun.COM static uint32_t 1003*9832Samw@Sun.COM srvsvc_update_share_flags(smb_share_t *si, uint32_t shi_flags) 1004*9832Samw@Sun.COM { 1005*9832Samw@Sun.COM uint32_t cscflg = 0; 1006*9832Samw@Sun.COM uint32_t nerr = NERR_Success; 1007*9832Samw@Sun.COM 1008*9832Samw@Sun.COM switch ((shi_flags & CSC_MASK)) { 1009*9832Samw@Sun.COM case CSC_CACHE_AUTO_REINT: 1010*9832Samw@Sun.COM cscflg = SMB_SHRF_CSC_AUTO; 1011*9832Samw@Sun.COM break; 1012*9832Samw@Sun.COM case CSC_CACHE_VDO: 1013*9832Samw@Sun.COM cscflg = SMB_SHRF_CSC_VDO; 1014*9832Samw@Sun.COM break; 1015*9832Samw@Sun.COM case CSC_CACHE_NONE: 1016*9832Samw@Sun.COM cscflg = SMB_SHRF_CSC_DISABLED; 1017*9832Samw@Sun.COM break; 1018*9832Samw@Sun.COM case CSC_CACHE_MANUAL_REINT: 1019*9832Samw@Sun.COM cscflg = SMB_SHRF_CSC_MANUAL; 1020*9832Samw@Sun.COM break; 1021*9832Samw@Sun.COM default: 1022*9832Samw@Sun.COM return (NERR_Success); 1023*9832Samw@Sun.COM } 1024*9832Samw@Sun.COM 1025*9832Samw@Sun.COM if (cscflg == (si->shr_flags & SMB_SHRF_CSC_MASK)) 1026*9832Samw@Sun.COM return (NERR_Success); 1027*9832Samw@Sun.COM 1028*9832Samw@Sun.COM si->shr_flags &= ~SMB_SHRF_CSC_MASK; 1029*9832Samw@Sun.COM si->shr_flags |= cscflg; 1030*9832Samw@Sun.COM 1031*9832Samw@Sun.COM if ((si->shr_flags & SMB_SHRF_TRANS) == 0) { 1032*9832Samw@Sun.COM if ((nerr = srvsvc_sa_setattr(si)) != NERR_Success) 1033*9832Samw@Sun.COM return (nerr); 1034*9832Samw@Sun.COM } 1035*9832Samw@Sun.COM 1036*9832Samw@Sun.COM return (smb_shr_modify(si)); 1037*9832Samw@Sun.COM } 1038*9832Samw@Sun.COM 10398474SJose.Borrego@Sun.COM /* 10408474SJose.Borrego@Sun.COM * srvsvc_s_NetSessionEnum 10418474SJose.Borrego@Sun.COM * 10428474SJose.Borrego@Sun.COM * Level 1 request is made by (Server Manager (srvmgr) on NT Server when 10438474SJose.Borrego@Sun.COM * the user info icon is selected. 10448474SJose.Borrego@Sun.COM * 10458474SJose.Borrego@Sun.COM * On success, the return value is NERR_Success. 10468474SJose.Borrego@Sun.COM * On error, the return value can be one of the following error codes: 10478474SJose.Borrego@Sun.COM * 10488474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED The user does not have access to the requested 10498474SJose.Borrego@Sun.COM * information. 10508474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL The value specified for the level is invalid. 10518474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER The specified parameter is invalid. 10528474SJose.Borrego@Sun.COM * ERROR_MORE_DATA More entries are available. Specify a large 10538474SJose.Borrego@Sun.COM * enough buffer to receive all entries. 10548474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 10558474SJose.Borrego@Sun.COM * NERR_ClientNameNotFound A session does not exist with the computer name. 10568474SJose.Borrego@Sun.COM * NERR_InvalidComputer The computer name is invalid. 10578474SJose.Borrego@Sun.COM * NERR_UserNotFound The user name could not be found. 10588474SJose.Borrego@Sun.COM */ 10598474SJose.Borrego@Sun.COM static int 10608474SJose.Borrego@Sun.COM srvsvc_s_NetSessionEnum(void *arg, ndr_xa_t *mxa) 10618474SJose.Borrego@Sun.COM { 10628474SJose.Borrego@Sun.COM struct mslm_NetSessionEnum *param = arg; 10638474SJose.Borrego@Sun.COM struct mslm_infonres *infonres; 10648474SJose.Borrego@Sun.COM DWORD status; 10658474SJose.Borrego@Sun.COM DWORD n_sessions; 10668474SJose.Borrego@Sun.COM 10678474SJose.Borrego@Sun.COM infonres = NDR_NEW(mxa, struct mslm_infonres); 10688474SJose.Borrego@Sun.COM if (infonres == NULL) { 10698474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetSessionEnum)); 10708474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 10718474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 10728474SJose.Borrego@Sun.COM } 10738474SJose.Borrego@Sun.COM 10748474SJose.Borrego@Sun.COM infonres->entriesread = 0; 10758474SJose.Borrego@Sun.COM infonres->entries = NULL; 10768474SJose.Borrego@Sun.COM param->result.level = param->level; 10778474SJose.Borrego@Sun.COM param->result.bufptr.p = infonres; 10788474SJose.Borrego@Sun.COM param->total_entries = 0; 10798474SJose.Borrego@Sun.COM param->resume_handle = NULL; 10808474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 10818474SJose.Borrego@Sun.COM 10828474SJose.Borrego@Sun.COM if ((n_sessions = (DWORD) mlsvc_get_num_users()) == 0) 10838474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 10848474SJose.Borrego@Sun.COM 10858474SJose.Borrego@Sun.COM switch (param->level) { 10868474SJose.Borrego@Sun.COM case 0: 10878474SJose.Borrego@Sun.COM status = mlsvc_NetSessionEnumLevel0(infonres, n_sessions, mxa); 10888474SJose.Borrego@Sun.COM break; 10898474SJose.Borrego@Sun.COM 10908474SJose.Borrego@Sun.COM case 1: 10918474SJose.Borrego@Sun.COM status = mlsvc_NetSessionEnumLevel1(infonres, n_sessions, mxa); 10928474SJose.Borrego@Sun.COM break; 10938474SJose.Borrego@Sun.COM 1094*9832Samw@Sun.COM case 2: 1095*9832Samw@Sun.COM status = mlsvc_NetSessionEnumLevel2(infonres, n_sessions, mxa); 1096*9832Samw@Sun.COM break; 1097*9832Samw@Sun.COM 1098*9832Samw@Sun.COM case 10: 1099*9832Samw@Sun.COM status = mlsvc_NetSessionEnumLevel10(infonres, n_sessions, mxa); 1100*9832Samw@Sun.COM break; 1101*9832Samw@Sun.COM 1102*9832Samw@Sun.COM case 502: 1103*9832Samw@Sun.COM status = mlsvc_NetSessionEnumLevel502(infonres, n_sessions, 1104*9832Samw@Sun.COM mxa); 1105*9832Samw@Sun.COM break; 1106*9832Samw@Sun.COM 11078474SJose.Borrego@Sun.COM default: 11088474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 11098474SJose.Borrego@Sun.COM break; 11108474SJose.Borrego@Sun.COM } 11118474SJose.Borrego@Sun.COM 11128474SJose.Borrego@Sun.COM if (status != 0) { 11138474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetSessionEnum)); 11148474SJose.Borrego@Sun.COM param->status = status; 11158474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 11168474SJose.Borrego@Sun.COM } 11178474SJose.Borrego@Sun.COM 11188474SJose.Borrego@Sun.COM param->total_entries = infonres->entriesread; 11198474SJose.Borrego@Sun.COM param->status = status; 11208474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 11218474SJose.Borrego@Sun.COM } 11228474SJose.Borrego@Sun.COM 11238474SJose.Borrego@Sun.COM /* 11248474SJose.Borrego@Sun.COM * mlsvc_NetSessionEnumLevel0 11258474SJose.Borrego@Sun.COM * 11268474SJose.Borrego@Sun.COM * Build the level 0 session information. 11278474SJose.Borrego@Sun.COM */ 11288474SJose.Borrego@Sun.COM static DWORD 11298474SJose.Borrego@Sun.COM mlsvc_NetSessionEnumLevel0(struct mslm_infonres *infonres, DWORD n_sessions, 11308474SJose.Borrego@Sun.COM ndr_xa_t *mxa) 11318474SJose.Borrego@Sun.COM { 11328474SJose.Borrego@Sun.COM struct mslm_SESSION_INFO_0 *info0; 1133*9832Samw@Sun.COM smb_ulist_t *ulist; 11348474SJose.Borrego@Sun.COM smb_opipe_context_t *user; 11358474SJose.Borrego@Sun.COM char *workstation; 11368670SJose.Borrego@Sun.COM char ipaddr_buf[INET6_ADDRSTRLEN]; 11378474SJose.Borrego@Sun.COM int i; 11388474SJose.Borrego@Sun.COM 1139*9832Samw@Sun.COM ulist = smb_ulist_alloc(); 1140*9832Samw@Sun.COM if (ulist == NULL) 11418474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 11428474SJose.Borrego@Sun.COM 1143*9832Samw@Sun.COM if (mlsvc_get_user_list(ulist) != 0) { 1144*9832Samw@Sun.COM smb_ulist_free(ulist); 11458474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 11468474SJose.Borrego@Sun.COM } 11478474SJose.Borrego@Sun.COM 1148*9832Samw@Sun.COM if (ulist->ul_cnt < n_sessions) 1149*9832Samw@Sun.COM n_sessions = ulist->ul_cnt; 11508474SJose.Borrego@Sun.COM 11518474SJose.Borrego@Sun.COM info0 = NDR_NEWN(mxa, struct mslm_SESSION_INFO_0, n_sessions); 11528474SJose.Borrego@Sun.COM if (info0 == NULL) { 1153*9832Samw@Sun.COM smb_ulist_free(ulist); 11548474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 11558474SJose.Borrego@Sun.COM } 11568474SJose.Borrego@Sun.COM 1157*9832Samw@Sun.COM user = ulist->ul_users; 1158*9832Samw@Sun.COM for (i = 0; i < n_sessions; ++i, user++) { 11598474SJose.Borrego@Sun.COM workstation = user->oc_workstation; 11608474SJose.Borrego@Sun.COM if (workstation == NULL || *workstation == '\0') { 11618670SJose.Borrego@Sun.COM (void) smb_inet_ntop(&user->oc_ipaddr, 11628670SJose.Borrego@Sun.COM ipaddr_buf, SMB_IPSTRLEN(user->oc_ipaddr.a_family)); 11638474SJose.Borrego@Sun.COM workstation = ipaddr_buf; 11648474SJose.Borrego@Sun.COM } 11658474SJose.Borrego@Sun.COM 11668474SJose.Borrego@Sun.COM info0[i].sesi0_cname = NDR_STRDUP(mxa, workstation); 11678474SJose.Borrego@Sun.COM if (info0[i].sesi0_cname == NULL) { 1168*9832Samw@Sun.COM smb_ulist_free(ulist); 11698474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 11708474SJose.Borrego@Sun.COM } 11718474SJose.Borrego@Sun.COM } 11728474SJose.Borrego@Sun.COM 1173*9832Samw@Sun.COM smb_ulist_free(ulist); 11748474SJose.Borrego@Sun.COM infonres->entriesread = n_sessions; 11758474SJose.Borrego@Sun.COM infonres->entries = info0; 11768474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 11778474SJose.Borrego@Sun.COM } 11788474SJose.Borrego@Sun.COM 11798474SJose.Borrego@Sun.COM /* 11808474SJose.Borrego@Sun.COM * mlsvc_NetSessionEnumLevel1 11818474SJose.Borrego@Sun.COM * 11828474SJose.Borrego@Sun.COM * Build the level 1 session information. 11838474SJose.Borrego@Sun.COM */ 11848474SJose.Borrego@Sun.COM static DWORD 11858474SJose.Borrego@Sun.COM mlsvc_NetSessionEnumLevel1(struct mslm_infonres *infonres, DWORD n_sessions, 11868474SJose.Borrego@Sun.COM ndr_xa_t *mxa) 11878474SJose.Borrego@Sun.COM { 11888474SJose.Borrego@Sun.COM struct mslm_SESSION_INFO_1 *info1; 1189*9832Samw@Sun.COM smb_ulist_t *ulist; 11908474SJose.Borrego@Sun.COM smb_opipe_context_t *user; 11918474SJose.Borrego@Sun.COM char *workstation; 11928474SJose.Borrego@Sun.COM char account[MAXNAMELEN]; 11938670SJose.Borrego@Sun.COM char ipaddr_buf[INET6_ADDRSTRLEN]; 11948474SJose.Borrego@Sun.COM int i; 11958474SJose.Borrego@Sun.COM 1196*9832Samw@Sun.COM ulist = smb_ulist_alloc(); 1197*9832Samw@Sun.COM if (ulist == NULL) 11988474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 11998474SJose.Borrego@Sun.COM 1200*9832Samw@Sun.COM if (mlsvc_get_user_list(ulist) != 0) { 1201*9832Samw@Sun.COM smb_ulist_free(ulist); 12028474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 12038474SJose.Borrego@Sun.COM } 12048474SJose.Borrego@Sun.COM 1205*9832Samw@Sun.COM if (ulist->ul_cnt < n_sessions) 1206*9832Samw@Sun.COM n_sessions = ulist->ul_cnt; 12078474SJose.Borrego@Sun.COM 12088474SJose.Borrego@Sun.COM info1 = NDR_NEWN(mxa, struct mslm_SESSION_INFO_1, n_sessions); 12098474SJose.Borrego@Sun.COM if (info1 == NULL) { 1210*9832Samw@Sun.COM smb_ulist_free(ulist); 12118474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 12128474SJose.Borrego@Sun.COM } 12138474SJose.Borrego@Sun.COM 1214*9832Samw@Sun.COM user = ulist->ul_users; 1215*9832Samw@Sun.COM for (i = 0; i < n_sessions; ++i, user++) { 12168474SJose.Borrego@Sun.COM workstation = user->oc_workstation; 12178474SJose.Borrego@Sun.COM if (workstation == NULL || *workstation == '\0') { 12188670SJose.Borrego@Sun.COM (void) smb_inet_ntop(&user->oc_ipaddr, 12198670SJose.Borrego@Sun.COM ipaddr_buf, SMB_IPSTRLEN(user->oc_ipaddr.a_family)); 12208474SJose.Borrego@Sun.COM workstation = ipaddr_buf; 12218474SJose.Borrego@Sun.COM } 12228474SJose.Borrego@Sun.COM 12238474SJose.Borrego@Sun.COM (void) snprintf(account, MAXNAMELEN, "%s\\%s", 12248474SJose.Borrego@Sun.COM user->oc_domain, user->oc_account); 12258474SJose.Borrego@Sun.COM 12268474SJose.Borrego@Sun.COM info1[i].sesi1_cname = NDR_STRDUP(mxa, workstation); 12278474SJose.Borrego@Sun.COM info1[i].sesi1_uname = NDR_STRDUP(mxa, account); 12288474SJose.Borrego@Sun.COM 12298474SJose.Borrego@Sun.COM if (info1[i].sesi1_cname == NULL || 12308474SJose.Borrego@Sun.COM info1[i].sesi1_uname == NULL) { 1231*9832Samw@Sun.COM smb_ulist_free(ulist); 12328474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 12338474SJose.Borrego@Sun.COM } 12348474SJose.Borrego@Sun.COM 12358474SJose.Borrego@Sun.COM info1[i].sesi1_nopens = 1; 12368474SJose.Borrego@Sun.COM info1[i].sesi1_time = time(0) - user->oc_logon_time; 12378474SJose.Borrego@Sun.COM info1[i].sesi1_itime = 0; 12388474SJose.Borrego@Sun.COM info1[i].sesi1_uflags = 12398474SJose.Borrego@Sun.COM (user->oc_flags & SMB_ATF_GUEST) ? SESS_GUEST : 0; 12408474SJose.Borrego@Sun.COM } 12418474SJose.Borrego@Sun.COM 1242*9832Samw@Sun.COM smb_ulist_free(ulist); 12438474SJose.Borrego@Sun.COM infonres->entriesread = n_sessions; 12448474SJose.Borrego@Sun.COM infonres->entries = info1; 12458474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 12468474SJose.Borrego@Sun.COM } 12478474SJose.Borrego@Sun.COM 12488474SJose.Borrego@Sun.COM /* 1249*9832Samw@Sun.COM * mlsvc_NetSessionEnumLevel2 1250*9832Samw@Sun.COM * 1251*9832Samw@Sun.COM * Build the level 2 session information. 1252*9832Samw@Sun.COM */ 1253*9832Samw@Sun.COM static DWORD 1254*9832Samw@Sun.COM mlsvc_NetSessionEnumLevel2(struct mslm_infonres *infonres, DWORD n_sessions, 1255*9832Samw@Sun.COM ndr_xa_t *mxa) 1256*9832Samw@Sun.COM { 1257*9832Samw@Sun.COM struct mslm_SESSION_INFO_2 *info2; 1258*9832Samw@Sun.COM smb_ulist_t *ulist; 1259*9832Samw@Sun.COM smb_opipe_context_t *user; 1260*9832Samw@Sun.COM char *workstation; 1261*9832Samw@Sun.COM char account[MAXNAMELEN]; 1262*9832Samw@Sun.COM char ipaddr_buf[INET6_ADDRSTRLEN]; 1263*9832Samw@Sun.COM int i; 1264*9832Samw@Sun.COM 1265*9832Samw@Sun.COM if ((ulist = smb_ulist_alloc()) == NULL) 1266*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1267*9832Samw@Sun.COM 1268*9832Samw@Sun.COM if (mlsvc_get_user_list(ulist) != 0) { 1269*9832Samw@Sun.COM smb_ulist_free(ulist); 1270*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1271*9832Samw@Sun.COM } 1272*9832Samw@Sun.COM 1273*9832Samw@Sun.COM if (ulist->ul_cnt < n_sessions) 1274*9832Samw@Sun.COM n_sessions = ulist->ul_cnt; 1275*9832Samw@Sun.COM 1276*9832Samw@Sun.COM info2 = NDR_NEWN(mxa, struct mslm_SESSION_INFO_2, n_sessions); 1277*9832Samw@Sun.COM if (info2 == NULL) { 1278*9832Samw@Sun.COM smb_ulist_free(ulist); 1279*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1280*9832Samw@Sun.COM } 1281*9832Samw@Sun.COM 1282*9832Samw@Sun.COM user = ulist->ul_users; 1283*9832Samw@Sun.COM for (i = 0; i < n_sessions; ++i, user++) { 1284*9832Samw@Sun.COM workstation = user->oc_workstation; 1285*9832Samw@Sun.COM if (workstation == NULL || *workstation == '\0') { 1286*9832Samw@Sun.COM (void) smb_inet_ntop(&user->oc_ipaddr, 1287*9832Samw@Sun.COM ipaddr_buf, SMB_IPSTRLEN(user->oc_ipaddr.a_family)); 1288*9832Samw@Sun.COM workstation = ipaddr_buf; 1289*9832Samw@Sun.COM } 1290*9832Samw@Sun.COM 1291*9832Samw@Sun.COM (void) snprintf(account, MAXNAMELEN, "%s\\%s", 1292*9832Samw@Sun.COM user->oc_domain, user->oc_account); 1293*9832Samw@Sun.COM 1294*9832Samw@Sun.COM info2[i].sesi2_cname = NDR_STRDUP(mxa, workstation); 1295*9832Samw@Sun.COM info2[i].sesi2_uname = NDR_STRDUP(mxa, account); 1296*9832Samw@Sun.COM 1297*9832Samw@Sun.COM if (info2[i].sesi2_cname == NULL || 1298*9832Samw@Sun.COM info2[i].sesi2_uname == NULL) { 1299*9832Samw@Sun.COM smb_ulist_free(ulist); 1300*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1301*9832Samw@Sun.COM } 1302*9832Samw@Sun.COM 1303*9832Samw@Sun.COM info2[i].sesi2_nopens = 1; 1304*9832Samw@Sun.COM info2[i].sesi2_time = time(0) - user->oc_logon_time; 1305*9832Samw@Sun.COM info2[i].sesi2_itime = 0; 1306*9832Samw@Sun.COM info2[i].sesi2_uflags = 1307*9832Samw@Sun.COM (user->oc_flags & SMB_ATF_GUEST) ? SESS_GUEST : 0; 1308*9832Samw@Sun.COM info2[i].sesi2_cltype_name = (uint8_t *)""; 1309*9832Samw@Sun.COM } 1310*9832Samw@Sun.COM 1311*9832Samw@Sun.COM smb_ulist_free(ulist); 1312*9832Samw@Sun.COM infonres->entriesread = n_sessions; 1313*9832Samw@Sun.COM infonres->entries = info2; 1314*9832Samw@Sun.COM return (ERROR_SUCCESS); 1315*9832Samw@Sun.COM } 1316*9832Samw@Sun.COM 1317*9832Samw@Sun.COM /* 1318*9832Samw@Sun.COM * mlsvc_NetSessionEnumLevel10 1319*9832Samw@Sun.COM * 1320*9832Samw@Sun.COM * Build the level 10 session information. 1321*9832Samw@Sun.COM */ 1322*9832Samw@Sun.COM static DWORD 1323*9832Samw@Sun.COM mlsvc_NetSessionEnumLevel10(struct mslm_infonres *infonres, DWORD n_sessions, 1324*9832Samw@Sun.COM ndr_xa_t *mxa) 1325*9832Samw@Sun.COM { 1326*9832Samw@Sun.COM struct mslm_SESSION_INFO_10 *info10; 1327*9832Samw@Sun.COM smb_ulist_t *ulist; 1328*9832Samw@Sun.COM smb_opipe_context_t *user; 1329*9832Samw@Sun.COM char *workstation; 1330*9832Samw@Sun.COM char account[MAXNAMELEN]; 1331*9832Samw@Sun.COM char ipaddr_buf[INET6_ADDRSTRLEN]; 1332*9832Samw@Sun.COM int i; 1333*9832Samw@Sun.COM 1334*9832Samw@Sun.COM if ((ulist = smb_ulist_alloc()) == NULL) 1335*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1336*9832Samw@Sun.COM 1337*9832Samw@Sun.COM if (mlsvc_get_user_list(ulist) != 0) { 1338*9832Samw@Sun.COM smb_ulist_free(ulist); 1339*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1340*9832Samw@Sun.COM } 1341*9832Samw@Sun.COM 1342*9832Samw@Sun.COM if (ulist->ul_cnt < n_sessions) 1343*9832Samw@Sun.COM n_sessions = ulist->ul_cnt; 1344*9832Samw@Sun.COM 1345*9832Samw@Sun.COM info10 = NDR_NEWN(mxa, struct mslm_SESSION_INFO_10, n_sessions); 1346*9832Samw@Sun.COM if (info10 == NULL) { 1347*9832Samw@Sun.COM smb_ulist_free(ulist); 1348*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1349*9832Samw@Sun.COM } 1350*9832Samw@Sun.COM 1351*9832Samw@Sun.COM user = ulist->ul_users; 1352*9832Samw@Sun.COM for (i = 0; i < n_sessions; ++i, user++) { 1353*9832Samw@Sun.COM workstation = user->oc_workstation; 1354*9832Samw@Sun.COM if (workstation == NULL || *workstation == '\0') { 1355*9832Samw@Sun.COM (void) smb_inet_ntop(&user->oc_ipaddr, 1356*9832Samw@Sun.COM ipaddr_buf, SMB_IPSTRLEN(user->oc_ipaddr.a_family)); 1357*9832Samw@Sun.COM workstation = ipaddr_buf; 1358*9832Samw@Sun.COM } 1359*9832Samw@Sun.COM 1360*9832Samw@Sun.COM (void) snprintf(account, MAXNAMELEN, "%s\\%s", 1361*9832Samw@Sun.COM user->oc_domain, user->oc_account); 1362*9832Samw@Sun.COM 1363*9832Samw@Sun.COM info10[i].sesi10_cname = NDR_STRDUP(mxa, workstation); 1364*9832Samw@Sun.COM info10[i].sesi10_uname = NDR_STRDUP(mxa, account); 1365*9832Samw@Sun.COM 1366*9832Samw@Sun.COM if (info10[i].sesi10_cname == NULL || 1367*9832Samw@Sun.COM info10[i].sesi10_uname == NULL) { 1368*9832Samw@Sun.COM smb_ulist_free(ulist); 1369*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1370*9832Samw@Sun.COM } 1371*9832Samw@Sun.COM 1372*9832Samw@Sun.COM info10[i].sesi10_time = time(0) - user->oc_logon_time; 1373*9832Samw@Sun.COM info10[i].sesi10_itime = 0; 1374*9832Samw@Sun.COM } 1375*9832Samw@Sun.COM 1376*9832Samw@Sun.COM smb_ulist_free(ulist); 1377*9832Samw@Sun.COM infonres->entriesread = n_sessions; 1378*9832Samw@Sun.COM infonres->entries = info10; 1379*9832Samw@Sun.COM return (ERROR_SUCCESS); 1380*9832Samw@Sun.COM } 1381*9832Samw@Sun.COM 1382*9832Samw@Sun.COM /* 1383*9832Samw@Sun.COM * mlsvc_NetSessionEnumLevel502 1384*9832Samw@Sun.COM * 1385*9832Samw@Sun.COM * Build the level 502 session information. 1386*9832Samw@Sun.COM */ 1387*9832Samw@Sun.COM static DWORD 1388*9832Samw@Sun.COM mlsvc_NetSessionEnumLevel502(struct mslm_infonres *infonres, DWORD n_sessions, 1389*9832Samw@Sun.COM ndr_xa_t *mxa) 1390*9832Samw@Sun.COM { 1391*9832Samw@Sun.COM struct mslm_SESSION_INFO_502 *info502; 1392*9832Samw@Sun.COM smb_ulist_t *ulist; 1393*9832Samw@Sun.COM smb_opipe_context_t *user; 1394*9832Samw@Sun.COM char *workstation; 1395*9832Samw@Sun.COM char account[MAXNAMELEN]; 1396*9832Samw@Sun.COM char ipaddr_buf[INET6_ADDRSTRLEN]; 1397*9832Samw@Sun.COM int i; 1398*9832Samw@Sun.COM 1399*9832Samw@Sun.COM if ((ulist = smb_ulist_alloc()) == NULL) 1400*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1401*9832Samw@Sun.COM 1402*9832Samw@Sun.COM if (mlsvc_get_user_list(ulist) != 0) { 1403*9832Samw@Sun.COM smb_ulist_free(ulist); 1404*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1405*9832Samw@Sun.COM } 1406*9832Samw@Sun.COM 1407*9832Samw@Sun.COM if (ulist->ul_cnt < n_sessions) 1408*9832Samw@Sun.COM n_sessions = ulist->ul_cnt; 1409*9832Samw@Sun.COM 1410*9832Samw@Sun.COM info502 = NDR_NEWN(mxa, struct mslm_SESSION_INFO_502, n_sessions); 1411*9832Samw@Sun.COM if (info502 == NULL) { 1412*9832Samw@Sun.COM smb_ulist_free(ulist); 1413*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1414*9832Samw@Sun.COM } 1415*9832Samw@Sun.COM 1416*9832Samw@Sun.COM user = ulist->ul_users; 1417*9832Samw@Sun.COM for (i = 0; i < n_sessions; ++i, user++) { 1418*9832Samw@Sun.COM workstation = user->oc_workstation; 1419*9832Samw@Sun.COM if (workstation == NULL || *workstation == '\0') { 1420*9832Samw@Sun.COM (void) smb_inet_ntop(&user->oc_ipaddr, 1421*9832Samw@Sun.COM ipaddr_buf, SMB_IPSTRLEN(user->oc_ipaddr.a_family)); 1422*9832Samw@Sun.COM workstation = ipaddr_buf; 1423*9832Samw@Sun.COM } 1424*9832Samw@Sun.COM 1425*9832Samw@Sun.COM (void) snprintf(account, MAXNAMELEN, "%s\\%s", 1426*9832Samw@Sun.COM user->oc_domain, user->oc_account); 1427*9832Samw@Sun.COM 1428*9832Samw@Sun.COM info502[i].sesi502_cname = NDR_STRDUP(mxa, workstation); 1429*9832Samw@Sun.COM info502[i].sesi502_uname = NDR_STRDUP(mxa, account); 1430*9832Samw@Sun.COM 1431*9832Samw@Sun.COM if (info502[i].sesi502_cname == NULL || 1432*9832Samw@Sun.COM info502[i].sesi502_uname == NULL) { 1433*9832Samw@Sun.COM smb_ulist_free(ulist); 1434*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1435*9832Samw@Sun.COM } 1436*9832Samw@Sun.COM 1437*9832Samw@Sun.COM info502[i].sesi502_nopens = 1; 1438*9832Samw@Sun.COM info502[i].sesi502_time = time(0) - user->oc_logon_time; 1439*9832Samw@Sun.COM info502[i].sesi502_itime = 0; 1440*9832Samw@Sun.COM info502[i].sesi502_uflags = 1441*9832Samw@Sun.COM (user->oc_flags & SMB_ATF_GUEST) ? SESS_GUEST : 0; 1442*9832Samw@Sun.COM info502[i].sesi502_cltype_name = (uint8_t *)""; 1443*9832Samw@Sun.COM info502[i].sesi502_transport = (uint8_t *)""; 1444*9832Samw@Sun.COM } 1445*9832Samw@Sun.COM 1446*9832Samw@Sun.COM smb_ulist_free(ulist); 1447*9832Samw@Sun.COM infonres->entriesread = n_sessions; 1448*9832Samw@Sun.COM infonres->entries = info502; 1449*9832Samw@Sun.COM return (ERROR_SUCCESS); 1450*9832Samw@Sun.COM } 1451*9832Samw@Sun.COM 1452*9832Samw@Sun.COM /* 14538474SJose.Borrego@Sun.COM * srvsvc_s_NetSessionDel 14548474SJose.Borrego@Sun.COM * 14558474SJose.Borrego@Sun.COM * Ends a network session between a server and a workstation. 14568474SJose.Borrego@Sun.COM * On NT only members of the Administrators or Account Operators 14578474SJose.Borrego@Sun.COM * local groups are permitted to use NetSessionDel. 14588474SJose.Borrego@Sun.COM * 14598474SJose.Borrego@Sun.COM * Return Values 14608474SJose.Borrego@Sun.COM * If the function succeeds, the return value is NERR_Success/ 14618474SJose.Borrego@Sun.COM * ERROR_SUCCESS. If the function fails, the return value can be 14628474SJose.Borrego@Sun.COM * one of the following error codes: 14638474SJose.Borrego@Sun.COM * 14648474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED The user does not have access to the 14658474SJose.Borrego@Sun.COM * requested information. 14668474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER The specified parameter is invalid. 14678474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 14688474SJose.Borrego@Sun.COM * NERR_ClientNameNotFound A session does not exist with that 14698474SJose.Borrego@Sun.COM * computer name. 14708474SJose.Borrego@Sun.COM */ 14718474SJose.Borrego@Sun.COM static int 14728474SJose.Borrego@Sun.COM srvsvc_s_NetSessionDel(void *arg, ndr_xa_t *mxa) 14738474SJose.Borrego@Sun.COM { 14748474SJose.Borrego@Sun.COM struct mslm_NetSessionDel *param = arg; 14758474SJose.Borrego@Sun.COM 14768474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa)) { 14778474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 14788474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 14798474SJose.Borrego@Sun.COM } 14808474SJose.Borrego@Sun.COM 14818474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 14828474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 14838474SJose.Borrego@Sun.COM } 14848474SJose.Borrego@Sun.COM 14858474SJose.Borrego@Sun.COM /* 14868474SJose.Borrego@Sun.COM * SRVSVC NetServerGetInfo 14878474SJose.Borrego@Sun.COM * 14888474SJose.Borrego@Sun.COM * IN LPTSTR servername, 14898474SJose.Borrego@Sun.COM * IN DWORD level, 14908474SJose.Borrego@Sun.COM * OUT union switch(level) { 14918474SJose.Borrego@Sun.COM * case 100: mslm_SERVER_INFO_100 *p100; 14928474SJose.Borrego@Sun.COM * case 101: mslm_SERVER_INFO_101 *p101; 14938474SJose.Borrego@Sun.COM * case 102: mslm_SERVER_INFO_102 *p102; 1494*9832Samw@Sun.COM * ... 14958474SJose.Borrego@Sun.COM * default: char *nullptr; 14968474SJose.Borrego@Sun.COM * } bufptr, 14978474SJose.Borrego@Sun.COM * OUT DWORD status 14988474SJose.Borrego@Sun.COM */ 14998474SJose.Borrego@Sun.COM static int 15008474SJose.Borrego@Sun.COM srvsvc_s_NetServerGetInfo(void *arg, ndr_xa_t *mxa) 15018474SJose.Borrego@Sun.COM { 15028474SJose.Borrego@Sun.COM struct mslm_NetServerGetInfo *param = arg; 15038474SJose.Borrego@Sun.COM struct mslm_SERVER_INFO_100 *info100; 15048474SJose.Borrego@Sun.COM struct mslm_SERVER_INFO_101 *info101; 15058474SJose.Borrego@Sun.COM struct mslm_SERVER_INFO_102 *info102; 1506*9832Samw@Sun.COM struct mslm_SERVER_INFO_502 *info502; 1507*9832Samw@Sun.COM struct mslm_SERVER_INFO_503 *info503; 15088474SJose.Borrego@Sun.COM char sys_comment[SMB_PI_MAX_COMMENT]; 15098474SJose.Borrego@Sun.COM char hostname[NETBIOS_NAME_SZ]; 15108474SJose.Borrego@Sun.COM 15118474SJose.Borrego@Sun.COM if (smb_getnetbiosname(hostname, sizeof (hostname)) != 0) { 15128474SJose.Borrego@Sun.COM netservergetinfo_no_memory: 15138474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetServerGetInfo)); 15148474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 15158474SJose.Borrego@Sun.COM } 15168474SJose.Borrego@Sun.COM 15178474SJose.Borrego@Sun.COM (void) smb_config_getstr(SMB_CI_SYS_CMNT, sys_comment, 15188474SJose.Borrego@Sun.COM sizeof (sys_comment)); 15198474SJose.Borrego@Sun.COM if (*sys_comment == '\0') 15208474SJose.Borrego@Sun.COM (void) strcpy(sys_comment, " "); 15218474SJose.Borrego@Sun.COM 15228474SJose.Borrego@Sun.COM switch (param->level) { 15238474SJose.Borrego@Sun.COM case 100: 15248474SJose.Borrego@Sun.COM info100 = NDR_NEW(mxa, struct mslm_SERVER_INFO_100); 15258474SJose.Borrego@Sun.COM if (info100 == NULL) 15268474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 15278474SJose.Borrego@Sun.COM 15288474SJose.Borrego@Sun.COM bzero(info100, sizeof (struct mslm_SERVER_INFO_100)); 15298474SJose.Borrego@Sun.COM info100->sv100_platform_id = SV_PLATFORM_ID_NT; 15308474SJose.Borrego@Sun.COM info100->sv100_name = (uint8_t *)NDR_STRDUP(mxa, hostname); 15318474SJose.Borrego@Sun.COM if (info100->sv100_name == NULL) 15328474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 15338474SJose.Borrego@Sun.COM 15348474SJose.Borrego@Sun.COM param->result.bufptr.bufptr100 = info100; 15358474SJose.Borrego@Sun.COM break; 15368474SJose.Borrego@Sun.COM 15378474SJose.Borrego@Sun.COM case 101: 15388474SJose.Borrego@Sun.COM info101 = NDR_NEW(mxa, struct mslm_SERVER_INFO_101); 15398474SJose.Borrego@Sun.COM if (info101 == NULL) 15408474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 15418474SJose.Borrego@Sun.COM 15428474SJose.Borrego@Sun.COM bzero(info101, sizeof (struct mslm_SERVER_INFO_101)); 15438474SJose.Borrego@Sun.COM info101->sv101_platform_id = SV_PLATFORM_ID_NT; 15448474SJose.Borrego@Sun.COM info101->sv101_version_major = 4; 15458474SJose.Borrego@Sun.COM info101->sv101_version_minor = 0; 15468474SJose.Borrego@Sun.COM info101->sv101_type = SV_TYPE_SENT_BY_ME; 15478474SJose.Borrego@Sun.COM info101->sv101_name = (uint8_t *)NDR_STRDUP(mxa, hostname); 15488474SJose.Borrego@Sun.COM info101->sv101_comment 15498474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, sys_comment); 15508474SJose.Borrego@Sun.COM 15518474SJose.Borrego@Sun.COM if (info101->sv101_name == NULL || 15528474SJose.Borrego@Sun.COM info101->sv101_comment == NULL) 15538474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 15548474SJose.Borrego@Sun.COM 15558474SJose.Borrego@Sun.COM param->result.bufptr.bufptr101 = info101; 15568474SJose.Borrego@Sun.COM break; 15578474SJose.Borrego@Sun.COM 15588474SJose.Borrego@Sun.COM case 102: 15598474SJose.Borrego@Sun.COM info102 = NDR_NEW(mxa, struct mslm_SERVER_INFO_102); 15608474SJose.Borrego@Sun.COM if (info102 == NULL) 15618474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 15628474SJose.Borrego@Sun.COM 15638474SJose.Borrego@Sun.COM bzero(info102, sizeof (struct mslm_SERVER_INFO_102)); 15648474SJose.Borrego@Sun.COM info102->sv102_platform_id = SV_PLATFORM_ID_NT; 15658474SJose.Borrego@Sun.COM info102->sv102_version_major = 4; 15668474SJose.Borrego@Sun.COM info102->sv102_version_minor = 0; 15678474SJose.Borrego@Sun.COM info102->sv102_type = SV_TYPE_SENT_BY_ME; 15688474SJose.Borrego@Sun.COM info102->sv102_name = (uint8_t *)NDR_STRDUP(mxa, hostname); 15698474SJose.Borrego@Sun.COM info102->sv102_comment 15708474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, sys_comment); 15718474SJose.Borrego@Sun.COM 15728474SJose.Borrego@Sun.COM /* 15738474SJose.Borrego@Sun.COM * The following level 102 fields are defaulted to zero 15748474SJose.Borrego@Sun.COM * by virtue of the call to bzero above. 15758474SJose.Borrego@Sun.COM * 15768474SJose.Borrego@Sun.COM * sv102_users 15778474SJose.Borrego@Sun.COM * sv102_disc 15788474SJose.Borrego@Sun.COM * sv102_hidden 15798474SJose.Borrego@Sun.COM * sv102_announce 15808474SJose.Borrego@Sun.COM * sv102_anndelta 15818474SJose.Borrego@Sun.COM * sv102_licenses 15828474SJose.Borrego@Sun.COM * sv102_userpath 15838474SJose.Borrego@Sun.COM */ 15848474SJose.Borrego@Sun.COM if (info102->sv102_name == NULL || 15858474SJose.Borrego@Sun.COM info102->sv102_comment == NULL) 15868474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 15878474SJose.Borrego@Sun.COM 15888474SJose.Borrego@Sun.COM param->result.bufptr.bufptr102 = info102; 15898474SJose.Borrego@Sun.COM break; 15908474SJose.Borrego@Sun.COM 1591*9832Samw@Sun.COM case 502: 1592*9832Samw@Sun.COM info502 = NDR_NEW(mxa, struct mslm_SERVER_INFO_502); 1593*9832Samw@Sun.COM if (info502 == NULL) 1594*9832Samw@Sun.COM goto netservergetinfo_no_memory; 1595*9832Samw@Sun.COM 1596*9832Samw@Sun.COM bzero(info502, sizeof (struct mslm_SERVER_INFO_502)); 1597*9832Samw@Sun.COM param->result.bufptr.bufptr502 = info502; 1598*9832Samw@Sun.COM #ifdef SRVSVC_SATISFY_SMBTORTURE 1599*9832Samw@Sun.COM break; 1600*9832Samw@Sun.COM #else 1601*9832Samw@Sun.COM param->result.level = param->level; 1602*9832Samw@Sun.COM param->status = ERROR_ACCESS_DENIED; 1603*9832Samw@Sun.COM return (NDR_DRC_OK); 1604*9832Samw@Sun.COM #endif /* SRVSVC_SATISFY_SMBTORTURE */ 1605*9832Samw@Sun.COM 1606*9832Samw@Sun.COM case 503: 1607*9832Samw@Sun.COM info503 = NDR_NEW(mxa, struct mslm_SERVER_INFO_503); 1608*9832Samw@Sun.COM if (info503 == NULL) 1609*9832Samw@Sun.COM goto netservergetinfo_no_memory; 1610*9832Samw@Sun.COM 1611*9832Samw@Sun.COM bzero(info503, sizeof (struct mslm_SERVER_INFO_503)); 1612*9832Samw@Sun.COM param->result.bufptr.bufptr503 = info503; 1613*9832Samw@Sun.COM #ifdef SRVSVC_SATISFY_SMBTORTURE 1614*9832Samw@Sun.COM break; 1615*9832Samw@Sun.COM #else 1616*9832Samw@Sun.COM param->result.level = param->level; 1617*9832Samw@Sun.COM param->status = ERROR_ACCESS_DENIED; 1618*9832Samw@Sun.COM return (NDR_DRC_OK); 1619*9832Samw@Sun.COM #endif /* SRVSVC_SATISFY_SMBTORTURE */ 1620*9832Samw@Sun.COM 16218474SJose.Borrego@Sun.COM default: 16228474SJose.Borrego@Sun.COM bzero(¶m->result, 16238474SJose.Borrego@Sun.COM sizeof (struct mslm_NetServerGetInfo_result)); 16248474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 16258474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 16268474SJose.Borrego@Sun.COM } 16278474SJose.Borrego@Sun.COM 16288474SJose.Borrego@Sun.COM param->result.level = param->level; 1629*9832Samw@Sun.COM param->status = ERROR_SUCCESS; 16308474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 16318474SJose.Borrego@Sun.COM } 16328474SJose.Borrego@Sun.COM 16338474SJose.Borrego@Sun.COM /* 16348474SJose.Borrego@Sun.COM * NetRemoteTOD 16358474SJose.Borrego@Sun.COM * 16368474SJose.Borrego@Sun.COM * Returns information about the time of day on this server. 16378474SJose.Borrego@Sun.COM * 16388474SJose.Borrego@Sun.COM * typedef struct _TIME_OF_DAY_INFO { 16398474SJose.Borrego@Sun.COM * DWORD tod_elapsedt; // seconds since 00:00:00 January 1 1970 GMT 16408474SJose.Borrego@Sun.COM * DWORD tod_msecs; // arbitrary milliseconds (since reset) 16418474SJose.Borrego@Sun.COM * DWORD tod_hours; // current hour [0-23] 16428474SJose.Borrego@Sun.COM * DWORD tod_mins; // current minute [0-59] 16438474SJose.Borrego@Sun.COM * DWORD tod_secs; // current second [0-59] 16448474SJose.Borrego@Sun.COM * DWORD tod_hunds; // current hundredth (0.01) second [0-99] 16458474SJose.Borrego@Sun.COM * LONG tod_timezone; // time zone of the server 16468474SJose.Borrego@Sun.COM * DWORD tod_tinterval; // clock tick time interval 16478474SJose.Borrego@Sun.COM * DWORD tod_day; // day of the month [1-31] 16488474SJose.Borrego@Sun.COM * DWORD tod_month; // month of the year [1-12] 16498474SJose.Borrego@Sun.COM * DWORD tod_year; // current year 16508474SJose.Borrego@Sun.COM * DWORD tod_weekday; // day of the week since Sunday [0-6] 16518474SJose.Borrego@Sun.COM * } TIME_OF_DAY_INFO; 16528474SJose.Borrego@Sun.COM * 16538474SJose.Borrego@Sun.COM * The time zone of the server is calculated in minutes from Greenwich 16548474SJose.Borrego@Sun.COM * Mean Time (GMT). For time zones west of Greenwich, the value is 16558474SJose.Borrego@Sun.COM * positive; for time zones east of Greenwich, the value is negative. 16568474SJose.Borrego@Sun.COM * A value of -1 indicates that the time zone is undefined. 16578474SJose.Borrego@Sun.COM * 16588474SJose.Borrego@Sun.COM * The clock tick value represents a resolution of one ten-thousandth 16598474SJose.Borrego@Sun.COM * (0.0001) second. 16608474SJose.Borrego@Sun.COM */ 16618474SJose.Borrego@Sun.COM static int 16628474SJose.Borrego@Sun.COM srvsvc_s_NetRemoteTOD(void *arg, ndr_xa_t *mxa) 16638474SJose.Borrego@Sun.COM { 16648474SJose.Borrego@Sun.COM struct mslm_NetRemoteTOD *param = arg; 16658474SJose.Borrego@Sun.COM struct mslm_TIME_OF_DAY_INFO *tod; 16668474SJose.Borrego@Sun.COM struct timeval time_val; 16678474SJose.Borrego@Sun.COM struct tm tm; 16688474SJose.Borrego@Sun.COM 16698474SJose.Borrego@Sun.COM (void) gettimeofday(&time_val, 0); 16708474SJose.Borrego@Sun.COM (void) gmtime_r(&time_val.tv_sec, &tm); 16718474SJose.Borrego@Sun.COM 16728474SJose.Borrego@Sun.COM tod = NDR_NEW(mxa, struct mslm_TIME_OF_DAY_INFO); 16738474SJose.Borrego@Sun.COM if (tod == NULL) { 16748474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetRemoteTOD)); 16758474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 16768474SJose.Borrego@Sun.COM } 16778474SJose.Borrego@Sun.COM 16788474SJose.Borrego@Sun.COM tod->tod_elapsedt = time_val.tv_sec; 16798474SJose.Borrego@Sun.COM tod->tod_msecs = time_val.tv_usec; 16808474SJose.Borrego@Sun.COM tod->tod_hours = tm.tm_hour; 16818474SJose.Borrego@Sun.COM tod->tod_mins = tm.tm_min; 16828474SJose.Borrego@Sun.COM tod->tod_secs = tm.tm_sec; 16838474SJose.Borrego@Sun.COM tod->tod_hunds = 0; 16848474SJose.Borrego@Sun.COM tod->tod_tinterval = 1000; 16858474SJose.Borrego@Sun.COM tod->tod_day = tm.tm_mday; 16868474SJose.Borrego@Sun.COM tod->tod_month = tm.tm_mon+1; 16878474SJose.Borrego@Sun.COM tod->tod_year = tm.tm_year+1900; 16888474SJose.Borrego@Sun.COM tod->tod_weekday = tm.tm_wday; 16898474SJose.Borrego@Sun.COM 16908474SJose.Borrego@Sun.COM (void) localtime_r(&time_val.tv_sec, &tm); 16918474SJose.Borrego@Sun.COM 16928474SJose.Borrego@Sun.COM param->bufptr = tod; 16938474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 16948474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 16958474SJose.Borrego@Sun.COM } 16968474SJose.Borrego@Sun.COM 16978474SJose.Borrego@Sun.COM /* 16988474SJose.Borrego@Sun.COM * srvsvc_s_NetNameValidate 16998474SJose.Borrego@Sun.COM * 17008474SJose.Borrego@Sun.COM * Perform name validation. 17018474SJose.Borrego@Sun.COM * 17028474SJose.Borrego@Sun.COM * The share name is considered invalid if it contains any of the 17038474SJose.Borrego@Sun.COM * following character (MSDN 236388). 17048474SJose.Borrego@Sun.COM * 17058474SJose.Borrego@Sun.COM * " / \ [ ] : | < > + ; , ? * = 17068474SJose.Borrego@Sun.COM * 17078474SJose.Borrego@Sun.COM * Returns Win32 error codes. 17088474SJose.Borrego@Sun.COM */ 17098474SJose.Borrego@Sun.COM /*ARGSUSED*/ 17108474SJose.Borrego@Sun.COM static int 17118474SJose.Borrego@Sun.COM srvsvc_s_NetNameValidate(void *arg, ndr_xa_t *mxa) 17128474SJose.Borrego@Sun.COM { 17138474SJose.Borrego@Sun.COM struct mslm_NetNameValidate *param = arg; 17148474SJose.Borrego@Sun.COM char *name; 17158474SJose.Borrego@Sun.COM int len; 17168474SJose.Borrego@Sun.COM 17178474SJose.Borrego@Sun.COM if ((name = (char *)param->pathname) == NULL) { 17188474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_PARAMETER; 17198474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 17208474SJose.Borrego@Sun.COM } 17218474SJose.Borrego@Sun.COM 17228474SJose.Borrego@Sun.COM len = strlen(name); 17238474SJose.Borrego@Sun.COM 17248474SJose.Borrego@Sun.COM if ((param->flags == 0 && len > 81) || 17258474SJose.Borrego@Sun.COM (param->flags == 0x80000000 && len > 13)) { 17268474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_NAME; 17278474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 17288474SJose.Borrego@Sun.COM } 17298474SJose.Borrego@Sun.COM 17308474SJose.Borrego@Sun.COM switch (param->type) { 17318474SJose.Borrego@Sun.COM case NAMETYPE_SHARE: 17328474SJose.Borrego@Sun.COM if (smb_shr_chkname(name)) 17338474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 17348474SJose.Borrego@Sun.COM else 17358474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_NAME; 17368474SJose.Borrego@Sun.COM break; 17378474SJose.Borrego@Sun.COM 17388474SJose.Borrego@Sun.COM case NAMETYPE_USER: 17398474SJose.Borrego@Sun.COM case NAMETYPE_PASSWORD: 17408474SJose.Borrego@Sun.COM case NAMETYPE_GROUP: 17418474SJose.Borrego@Sun.COM case NAMETYPE_COMPUTER: 17428474SJose.Borrego@Sun.COM case NAMETYPE_EVENT: 17438474SJose.Borrego@Sun.COM case NAMETYPE_DOMAIN: 17448474SJose.Borrego@Sun.COM case NAMETYPE_SERVICE: 17458474SJose.Borrego@Sun.COM case NAMETYPE_NET: 17468474SJose.Borrego@Sun.COM case NAMETYPE_MESSAGE: 17478474SJose.Borrego@Sun.COM case NAMETYPE_MESSAGEDEST: 17488474SJose.Borrego@Sun.COM case NAMETYPE_SHAREPASSWORD: 17498474SJose.Borrego@Sun.COM case NAMETYPE_WORKGROUP: 17508474SJose.Borrego@Sun.COM param->status = ERROR_NOT_SUPPORTED; 17518474SJose.Borrego@Sun.COM break; 17528474SJose.Borrego@Sun.COM 17538474SJose.Borrego@Sun.COM default: 17548474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_PARAMETER; 17558474SJose.Borrego@Sun.COM break; 17568474SJose.Borrego@Sun.COM } 17578474SJose.Borrego@Sun.COM 17588474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 17598474SJose.Borrego@Sun.COM } 17608474SJose.Borrego@Sun.COM 17618474SJose.Borrego@Sun.COM /* 17628474SJose.Borrego@Sun.COM * srvsvc_s_NetShareAdd 17638474SJose.Borrego@Sun.COM * 1764*9832Samw@Sun.COM * Add a new share. Only power users groups can manage shares. 17658474SJose.Borrego@Sun.COM * 17668474SJose.Borrego@Sun.COM * This interface is used by the rmtshare command from the NT resource 17678474SJose.Borrego@Sun.COM * kit. Rmtshare allows a client to add or remove shares on a server 17688474SJose.Borrego@Sun.COM * from the client's command line. 17698474SJose.Borrego@Sun.COM * 17708474SJose.Borrego@Sun.COM * Returns Win32 error codes. 17718474SJose.Borrego@Sun.COM */ 17728474SJose.Borrego@Sun.COM static int 17738474SJose.Borrego@Sun.COM srvsvc_s_NetShareAdd(void *arg, ndr_xa_t *mxa) 17748474SJose.Borrego@Sun.COM { 17758474SJose.Borrego@Sun.COM static DWORD parm_err = 0; 17768474SJose.Borrego@Sun.COM DWORD parm_stat; 17778474SJose.Borrego@Sun.COM struct mslm_NetShareAdd *param = arg; 17789343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_2 *info2; 1779*9832Samw@Sun.COM struct mslm_NetShareInfo_502 *info502; 17808474SJose.Borrego@Sun.COM char realpath[MAXPATHLEN]; 17818474SJose.Borrego@Sun.COM int32_t native_os; 1782*9832Samw@Sun.COM uint8_t *sdbuf = NULL; 1783*9832Samw@Sun.COM uint32_t status; 1784*9832Samw@Sun.COM smb_share_t si; 17858474SJose.Borrego@Sun.COM 17868474SJose.Borrego@Sun.COM native_os = ndr_native_os(mxa); 17878474SJose.Borrego@Sun.COM 17888474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa)) { 17898474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 17908474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 17918474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 17928474SJose.Borrego@Sun.COM } 17938474SJose.Borrego@Sun.COM 17948474SJose.Borrego@Sun.COM switch (param->level) { 17958474SJose.Borrego@Sun.COM case 2: 1796*9832Samw@Sun.COM info2 = (struct mslm_NetShareInfo_2 *)param->info.un.info2; 17978474SJose.Borrego@Sun.COM break; 17988474SJose.Borrego@Sun.COM 17998474SJose.Borrego@Sun.COM case 502: 1800*9832Samw@Sun.COM info502 = (struct mslm_NetShareInfo_502 *) 1801*9832Samw@Sun.COM param->info.un.info502; 1802*9832Samw@Sun.COM sdbuf = info502->shi502_security_descriptor; 1803*9832Samw@Sun.COM info2 = (struct mslm_NetShareInfo_2 *)info502; 18048474SJose.Borrego@Sun.COM break; 18058474SJose.Borrego@Sun.COM 18068474SJose.Borrego@Sun.COM default: 18078474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 18088474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 18098474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 18108474SJose.Borrego@Sun.COM } 18118474SJose.Borrego@Sun.COM 18128474SJose.Borrego@Sun.COM if (info2->shi2_netname == NULL || info2->shi2_path == NULL) { 18138474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 18148474SJose.Borrego@Sun.COM param->status = NERR_NetNameNotFound; 18158474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 18168474SJose.Borrego@Sun.COM } 18178474SJose.Borrego@Sun.COM 18188474SJose.Borrego@Sun.COM if (smb_shr_is_restricted((char *)info2->shi2_netname)) { 18198474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 18208474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 18218474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 18228474SJose.Borrego@Sun.COM } 18238474SJose.Borrego@Sun.COM 18249343SAfshin.Ardakani@Sun.COM if (info2->shi2_comment == NULL) 18259343SAfshin.Ardakani@Sun.COM info2->shi2_comment = (uint8_t *)""; 18268474SJose.Borrego@Sun.COM 18278474SJose.Borrego@Sun.COM /* 18288474SJose.Borrego@Sun.COM * Derive the real path which will be stored in the 18298474SJose.Borrego@Sun.COM * directory field of the smb_share_t structure 18308474SJose.Borrego@Sun.COM * from the path field in this RPC request. 18318474SJose.Borrego@Sun.COM */ 18328474SJose.Borrego@Sun.COM parm_stat = smb_shr_get_realpath((const char *)info2->shi2_path, 18338474SJose.Borrego@Sun.COM realpath, MAXPATHLEN); 18348474SJose.Borrego@Sun.COM 18358474SJose.Borrego@Sun.COM if (parm_stat != NERR_Success) { 18368474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 18378474SJose.Borrego@Sun.COM param->status = parm_stat; 18388474SJose.Borrego@Sun.COM param->parm_err 18398474SJose.Borrego@Sun.COM = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; 18408474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 18418474SJose.Borrego@Sun.COM } 18428474SJose.Borrego@Sun.COM 18438474SJose.Borrego@Sun.COM param->status = srvsvc_sa_add((char *)info2->shi2_netname, realpath, 18449343SAfshin.Ardakani@Sun.COM (char *)info2->shi2_comment); 18458474SJose.Borrego@Sun.COM if (param->status == NERR_Success) { 1846*9832Samw@Sun.COM status = smb_shr_get((char *)info2->shi2_netname, &si); 1847*9832Samw@Sun.COM 1848*9832Samw@Sun.COM if ((sdbuf != NULL) && (status == NERR_Success)) 1849*9832Samw@Sun.COM (void) srvsvc_sd_set(&si, sdbuf); 18508474SJose.Borrego@Sun.COM } 18518474SJose.Borrego@Sun.COM param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; 18528474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 18538474SJose.Borrego@Sun.COM } 18548474SJose.Borrego@Sun.COM 18558474SJose.Borrego@Sun.COM /* 18568474SJose.Borrego@Sun.COM * srvsvc_estimate_objcnt 18578474SJose.Borrego@Sun.COM * 18588474SJose.Borrego@Sun.COM * Estimate the number of objects that will fit in prefmaxlen. 18598474SJose.Borrego@Sun.COM */ 18608474SJose.Borrego@Sun.COM static uint32_t 18618474SJose.Borrego@Sun.COM srvsvc_estimate_objcnt(uint32_t prefmaxlen, uint32_t n_obj, uint32_t obj_size) 18628474SJose.Borrego@Sun.COM { 18638474SJose.Borrego@Sun.COM DWORD max_cnt; 18648474SJose.Borrego@Sun.COM 18658474SJose.Borrego@Sun.COM if (obj_size == 0) 18668474SJose.Borrego@Sun.COM return (0); 18678474SJose.Borrego@Sun.COM 18688474SJose.Borrego@Sun.COM if ((max_cnt = (prefmaxlen / obj_size)) == 0) 18698474SJose.Borrego@Sun.COM return (0); 18708474SJose.Borrego@Sun.COM 18718474SJose.Borrego@Sun.COM if (n_obj > max_cnt) 18728474SJose.Borrego@Sun.COM n_obj = max_cnt; 18738474SJose.Borrego@Sun.COM 18748474SJose.Borrego@Sun.COM return (n_obj); 18758474SJose.Borrego@Sun.COM } 18768474SJose.Borrego@Sun.COM 18778474SJose.Borrego@Sun.COM /* 18788474SJose.Borrego@Sun.COM * srvsvc_s_NetShareEnum 18798474SJose.Borrego@Sun.COM * 18808474SJose.Borrego@Sun.COM * Enumerate all shares (see also NetShareEnumSticky). 18818474SJose.Borrego@Sun.COM * 18828474SJose.Borrego@Sun.COM * Request for various levels of information about our shares. 18838474SJose.Borrego@Sun.COM * Level 0: share names. 18848474SJose.Borrego@Sun.COM * Level 1: share name, share type and comment field. 18858474SJose.Borrego@Sun.COM * Level 2: everything that we know about the shares. 18868474SJose.Borrego@Sun.COM * Level 501: level 1 + flags (flags must be zero). 18878474SJose.Borrego@Sun.COM * Level 502: level 2 + security descriptor. 18888474SJose.Borrego@Sun.COM */ 18898474SJose.Borrego@Sun.COM static int 18908474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnum(void *arg, ndr_xa_t *mxa) 18918474SJose.Borrego@Sun.COM { 18928474SJose.Borrego@Sun.COM struct mslm_NetShareEnum *param = arg; 18938474SJose.Borrego@Sun.COM struct mslm_infonres *infonres; 18948474SJose.Borrego@Sun.COM srvsvc_enum_t se; 18958474SJose.Borrego@Sun.COM DWORD status; 18968474SJose.Borrego@Sun.COM 18978474SJose.Borrego@Sun.COM infonres = NDR_NEW(mxa, struct mslm_infonres); 18988474SJose.Borrego@Sun.COM if (infonres == NULL) { 18998474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 19008474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 19018474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19028474SJose.Borrego@Sun.COM } 19038474SJose.Borrego@Sun.COM 19048474SJose.Borrego@Sun.COM infonres->entriesread = 0; 19058474SJose.Borrego@Sun.COM infonres->entries = NULL; 19068474SJose.Borrego@Sun.COM param->result.level = param->level; 19078474SJose.Borrego@Sun.COM param->result.bufptr.p = infonres; 19088474SJose.Borrego@Sun.COM 19098474SJose.Borrego@Sun.COM bzero(&se, sizeof (srvsvc_enum_t)); 19108474SJose.Borrego@Sun.COM se.se_level = param->level; 19118474SJose.Borrego@Sun.COM se.se_n_total = smb_shr_count(); 19128474SJose.Borrego@Sun.COM 19138474SJose.Borrego@Sun.COM if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN || 19148474SJose.Borrego@Sun.COM param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN) 19158474SJose.Borrego@Sun.COM se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN; 19168474SJose.Borrego@Sun.COM else 19178474SJose.Borrego@Sun.COM se.se_prefmaxlen = param->prefmaxlen; 19188474SJose.Borrego@Sun.COM 19198474SJose.Borrego@Sun.COM if (param->resume_handle) { 19208474SJose.Borrego@Sun.COM se.se_resume_handle = *param->resume_handle; 19218474SJose.Borrego@Sun.COM se.se_n_skip = se.se_resume_handle; 19228474SJose.Borrego@Sun.COM } 19238474SJose.Borrego@Sun.COM 19248474SJose.Borrego@Sun.COM switch (param->level) { 19258474SJose.Borrego@Sun.COM case 0: 19268474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 0); 19278474SJose.Borrego@Sun.COM break; 19288474SJose.Borrego@Sun.COM 19298474SJose.Borrego@Sun.COM case 1: 19308474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 0); 19318474SJose.Borrego@Sun.COM break; 19328474SJose.Borrego@Sun.COM 19338474SJose.Borrego@Sun.COM case 2: 19348474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 0); 19358474SJose.Borrego@Sun.COM break; 19368474SJose.Borrego@Sun.COM 19378474SJose.Borrego@Sun.COM case 501: 19388474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel501(mxa, infonres, &se, 0); 19398474SJose.Borrego@Sun.COM break; 19408474SJose.Borrego@Sun.COM 19418474SJose.Borrego@Sun.COM case 502: 19428474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 0); 19438474SJose.Borrego@Sun.COM break; 19448474SJose.Borrego@Sun.COM 19458474SJose.Borrego@Sun.COM default: 1946*9832Samw@Sun.COM status = ERROR_INVALID_LEVEL; 19478474SJose.Borrego@Sun.COM break; 19488474SJose.Borrego@Sun.COM } 19498474SJose.Borrego@Sun.COM 19508474SJose.Borrego@Sun.COM if (status != 0) { 19518474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 19528474SJose.Borrego@Sun.COM param->status = status; 19538474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19548474SJose.Borrego@Sun.COM } 19558474SJose.Borrego@Sun.COM 19568474SJose.Borrego@Sun.COM if (se.se_n_enum == 0) { 19578474SJose.Borrego@Sun.COM if (param->resume_handle) 19588474SJose.Borrego@Sun.COM *param->resume_handle = 0; 19598474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 19608474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19618474SJose.Borrego@Sun.COM } 19628474SJose.Borrego@Sun.COM 19638474SJose.Borrego@Sun.COM if (param->resume_handle && 19648474SJose.Borrego@Sun.COM param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) { 19658474SJose.Borrego@Sun.COM if (se.se_resume_handle < se.se_n_total) { 19668474SJose.Borrego@Sun.COM *param->resume_handle = se.se_resume_handle; 19678474SJose.Borrego@Sun.COM status = ERROR_MORE_DATA; 19688474SJose.Borrego@Sun.COM } else { 19698474SJose.Borrego@Sun.COM *param->resume_handle = 0; 19708474SJose.Borrego@Sun.COM } 19718474SJose.Borrego@Sun.COM } 19728474SJose.Borrego@Sun.COM 19738474SJose.Borrego@Sun.COM param->totalentries = se.se_n_total; 19748474SJose.Borrego@Sun.COM param->status = status; 19758474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19768474SJose.Borrego@Sun.COM } 19778474SJose.Borrego@Sun.COM 19788474SJose.Borrego@Sun.COM /* 19798474SJose.Borrego@Sun.COM * srvsvc_s_NetShareEnumSticky 19808474SJose.Borrego@Sun.COM * 19818474SJose.Borrego@Sun.COM * Enumerate sticky shares: all shares except those marked STYPE_SPECIAL. 19828474SJose.Borrego@Sun.COM * Except for excluding STYPE_SPECIAL shares, NetShareEnumSticky is the 19838474SJose.Borrego@Sun.COM * same as NetShareEnum. 19848474SJose.Borrego@Sun.COM * 19858474SJose.Borrego@Sun.COM * Request for various levels of information about our shares. 19868474SJose.Borrego@Sun.COM * Level 0: share names. 19878474SJose.Borrego@Sun.COM * Level 1: share name, share type and comment field. 19888474SJose.Borrego@Sun.COM * Level 2: everything that we know about the shares. 19898474SJose.Borrego@Sun.COM * Level 501: not valid for this request. 19908474SJose.Borrego@Sun.COM * Level 502: level 2 + security descriptor. 19918474SJose.Borrego@Sun.COM * 19928474SJose.Borrego@Sun.COM * We set n_skip to resume_handle, which is used to find the appropriate 19938474SJose.Borrego@Sun.COM * place to resume. The resume_handle is similar to the readdir cookie. 19948474SJose.Borrego@Sun.COM */ 19958474SJose.Borrego@Sun.COM static int 19968474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnumSticky(void *arg, ndr_xa_t *mxa) 19978474SJose.Borrego@Sun.COM { 19988474SJose.Borrego@Sun.COM struct mslm_NetShareEnum *param = arg; 19998474SJose.Borrego@Sun.COM struct mslm_infonres *infonres; 20008474SJose.Borrego@Sun.COM srvsvc_enum_t se; 20018474SJose.Borrego@Sun.COM DWORD status; 20028474SJose.Borrego@Sun.COM 20038474SJose.Borrego@Sun.COM infonres = NDR_NEW(mxa, struct mslm_infonres); 20048474SJose.Borrego@Sun.COM if (infonres == NULL) { 20058474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 20068474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 20078474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20088474SJose.Borrego@Sun.COM } 20098474SJose.Borrego@Sun.COM 20108474SJose.Borrego@Sun.COM infonres->entriesread = 0; 20118474SJose.Borrego@Sun.COM infonres->entries = NULL; 20128474SJose.Borrego@Sun.COM param->result.level = param->level; 20138474SJose.Borrego@Sun.COM param->result.bufptr.p = infonres; 20148474SJose.Borrego@Sun.COM 20158474SJose.Borrego@Sun.COM bzero(&se, sizeof (srvsvc_enum_t)); 20168474SJose.Borrego@Sun.COM se.se_level = param->level; 20178474SJose.Borrego@Sun.COM se.se_n_total = smb_shr_count(); 20188474SJose.Borrego@Sun.COM 20198474SJose.Borrego@Sun.COM if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN || 20208474SJose.Borrego@Sun.COM param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN) 20218474SJose.Borrego@Sun.COM se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN; 20228474SJose.Borrego@Sun.COM else 20238474SJose.Borrego@Sun.COM se.se_prefmaxlen = param->prefmaxlen; 20248474SJose.Borrego@Sun.COM 20258474SJose.Borrego@Sun.COM if (param->resume_handle) { 20268474SJose.Borrego@Sun.COM se.se_resume_handle = *param->resume_handle; 20278474SJose.Borrego@Sun.COM se.se_n_skip = se.se_resume_handle; 20288474SJose.Borrego@Sun.COM } 20298474SJose.Borrego@Sun.COM 20308474SJose.Borrego@Sun.COM switch (param->level) { 20318474SJose.Borrego@Sun.COM case 0: 20328474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 1); 20338474SJose.Borrego@Sun.COM break; 20348474SJose.Borrego@Sun.COM 20358474SJose.Borrego@Sun.COM case 1: 20368474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 1); 20378474SJose.Borrego@Sun.COM break; 20388474SJose.Borrego@Sun.COM 20398474SJose.Borrego@Sun.COM case 2: 20408474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 1); 20418474SJose.Borrego@Sun.COM break; 20428474SJose.Borrego@Sun.COM 20438474SJose.Borrego@Sun.COM case 502: 20448474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 1); 20458474SJose.Borrego@Sun.COM break; 20468474SJose.Borrego@Sun.COM 2047*9832Samw@Sun.COM case 501: 20488474SJose.Borrego@Sun.COM default: 20498474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 20508474SJose.Borrego@Sun.COM break; 20518474SJose.Borrego@Sun.COM } 20528474SJose.Borrego@Sun.COM 20538474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) { 20548474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 20558474SJose.Borrego@Sun.COM param->status = status; 20568474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20578474SJose.Borrego@Sun.COM } 20588474SJose.Borrego@Sun.COM 20598474SJose.Borrego@Sun.COM if (se.se_n_enum == 0) { 20608474SJose.Borrego@Sun.COM if (param->resume_handle) 20618474SJose.Borrego@Sun.COM *param->resume_handle = 0; 20628474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 20638474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20648474SJose.Borrego@Sun.COM } 20658474SJose.Borrego@Sun.COM 20668474SJose.Borrego@Sun.COM if (param->resume_handle && 20678474SJose.Borrego@Sun.COM param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) { 20688474SJose.Borrego@Sun.COM if (se.se_resume_handle < se.se_n_total) { 20698474SJose.Borrego@Sun.COM *param->resume_handle = se.se_resume_handle; 20708474SJose.Borrego@Sun.COM status = ERROR_MORE_DATA; 20718474SJose.Borrego@Sun.COM } else { 20728474SJose.Borrego@Sun.COM *param->resume_handle = 0; 20738474SJose.Borrego@Sun.COM } 20748474SJose.Borrego@Sun.COM } 20758474SJose.Borrego@Sun.COM 20768474SJose.Borrego@Sun.COM param->totalentries = se.se_n_total; 20778474SJose.Borrego@Sun.COM param->status = status; 20788474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20798474SJose.Borrego@Sun.COM } 20808474SJose.Borrego@Sun.COM 20818474SJose.Borrego@Sun.COM /* 20828474SJose.Borrego@Sun.COM * NetShareEnum Level 0 20838474SJose.Borrego@Sun.COM */ 20848474SJose.Borrego@Sun.COM static DWORD 20858474SJose.Borrego@Sun.COM mlsvc_NetShareEnumLevel0(ndr_xa_t *mxa, 20868474SJose.Borrego@Sun.COM struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) 20878474SJose.Borrego@Sun.COM { 20889343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_0 *info0; 20898474SJose.Borrego@Sun.COM smb_shriter_t iterator; 20908474SJose.Borrego@Sun.COM smb_share_t *si; 20918474SJose.Borrego@Sun.COM DWORD status; 20928474SJose.Borrego@Sun.COM 20938474SJose.Borrego@Sun.COM se->se_n_enum = srvsvc_estimate_objcnt(se->se_prefmaxlen, 20949343SAfshin.Ardakani@Sun.COM se->se_n_total, sizeof (struct mslm_NetShareInfo_0) + MAXNAMELEN); 20958474SJose.Borrego@Sun.COM if (se->se_n_enum == 0) 20968474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 20978474SJose.Borrego@Sun.COM 20989343SAfshin.Ardakani@Sun.COM info0 = NDR_NEWN(mxa, struct mslm_NetShareInfo_0, se->se_n_enum); 20998474SJose.Borrego@Sun.COM if (info0 == NULL) 21008474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 21018474SJose.Borrego@Sun.COM 21028474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 21038474SJose.Borrego@Sun.COM 21048474SJose.Borrego@Sun.COM se->se_n_read = 0; 21058474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != NULL) { 21068474SJose.Borrego@Sun.COM if (se->se_n_skip > 0) { 21078474SJose.Borrego@Sun.COM --se->se_n_skip; 21088474SJose.Borrego@Sun.COM continue; 21098474SJose.Borrego@Sun.COM } 21108474SJose.Borrego@Sun.COM 21118474SJose.Borrego@Sun.COM ++se->se_resume_handle; 21128474SJose.Borrego@Sun.COM 21138474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 21148474SJose.Borrego@Sun.COM continue; 21158474SJose.Borrego@Sun.COM 21168474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 21178474SJose.Borrego@Sun.COM continue; 21188474SJose.Borrego@Sun.COM 21198474SJose.Borrego@Sun.COM if (se->se_n_read >= se->se_n_enum) { 21208474SJose.Borrego@Sun.COM se->se_n_read = se->se_n_enum; 21218474SJose.Borrego@Sun.COM break; 21228474SJose.Borrego@Sun.COM } 21238474SJose.Borrego@Sun.COM 21248474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info0); 21258474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 21268474SJose.Borrego@Sun.COM break; 21278474SJose.Borrego@Sun.COM 21288474SJose.Borrego@Sun.COM ++se->se_n_read; 21298474SJose.Borrego@Sun.COM } 21308474SJose.Borrego@Sun.COM 21318474SJose.Borrego@Sun.COM if (se->se_n_read < se->se_n_enum) { 21328474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info0)) 21338474SJose.Borrego@Sun.COM ++se->se_n_read; 21348474SJose.Borrego@Sun.COM } 21358474SJose.Borrego@Sun.COM 21368474SJose.Borrego@Sun.COM infonres->entriesread = se->se_n_read; 21378474SJose.Borrego@Sun.COM infonres->entries = info0; 21388474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 21398474SJose.Borrego@Sun.COM } 21408474SJose.Borrego@Sun.COM 21418474SJose.Borrego@Sun.COM /* 21428474SJose.Borrego@Sun.COM * NetShareEnum Level 1 21438474SJose.Borrego@Sun.COM */ 21448474SJose.Borrego@Sun.COM static DWORD 21458474SJose.Borrego@Sun.COM mlsvc_NetShareEnumLevel1(ndr_xa_t *mxa, 21468474SJose.Borrego@Sun.COM struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) 21478474SJose.Borrego@Sun.COM { 21489343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1 *info1; 21498474SJose.Borrego@Sun.COM smb_shriter_t iterator; 21508474SJose.Borrego@Sun.COM smb_share_t *si; 21518474SJose.Borrego@Sun.COM DWORD status; 21528474SJose.Borrego@Sun.COM 21538474SJose.Borrego@Sun.COM se->se_n_enum = srvsvc_estimate_objcnt(se->se_prefmaxlen, 21549343SAfshin.Ardakani@Sun.COM se->se_n_total, sizeof (struct mslm_NetShareInfo_1) + MAXNAMELEN); 21558474SJose.Borrego@Sun.COM if (se->se_n_enum == 0) 21568474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 21578474SJose.Borrego@Sun.COM 21589343SAfshin.Ardakani@Sun.COM info1 = NDR_NEWN(mxa, struct mslm_NetShareInfo_1, se->se_n_enum); 21598474SJose.Borrego@Sun.COM if (info1 == NULL) 21608474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 21618474SJose.Borrego@Sun.COM 21628474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 21638474SJose.Borrego@Sun.COM 21648474SJose.Borrego@Sun.COM se->se_n_read = 0; 21658474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != 0) { 21668474SJose.Borrego@Sun.COM if (se->se_n_skip > 0) { 21678474SJose.Borrego@Sun.COM --se->se_n_skip; 21688474SJose.Borrego@Sun.COM continue; 21698474SJose.Borrego@Sun.COM } 21708474SJose.Borrego@Sun.COM 21718474SJose.Borrego@Sun.COM ++se->se_resume_handle; 21728474SJose.Borrego@Sun.COM 21738474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 21748474SJose.Borrego@Sun.COM continue; 21758474SJose.Borrego@Sun.COM 21768474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 21778474SJose.Borrego@Sun.COM continue; 21788474SJose.Borrego@Sun.COM 21798474SJose.Borrego@Sun.COM if (se->se_n_read >= se->se_n_enum) { 21808474SJose.Borrego@Sun.COM se->se_n_read = se->se_n_enum; 21818474SJose.Borrego@Sun.COM break; 21828474SJose.Borrego@Sun.COM } 21838474SJose.Borrego@Sun.COM 21848474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info1); 21858474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 21868474SJose.Borrego@Sun.COM break; 21878474SJose.Borrego@Sun.COM 21888474SJose.Borrego@Sun.COM ++se->se_n_read; 21898474SJose.Borrego@Sun.COM } 21908474SJose.Borrego@Sun.COM 21918474SJose.Borrego@Sun.COM if (se->se_n_read < se->se_n_enum) { 21928474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info1)) 21938474SJose.Borrego@Sun.COM ++se->se_n_read; 21948474SJose.Borrego@Sun.COM } 21958474SJose.Borrego@Sun.COM 21968474SJose.Borrego@Sun.COM infonres->entriesread = se->se_n_read; 21978474SJose.Borrego@Sun.COM infonres->entries = info1; 21988474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 21998474SJose.Borrego@Sun.COM } 22008474SJose.Borrego@Sun.COM 22018474SJose.Borrego@Sun.COM /* 22028474SJose.Borrego@Sun.COM * NetShareEnum Level 2 22038474SJose.Borrego@Sun.COM */ 22048474SJose.Borrego@Sun.COM static DWORD 22058474SJose.Borrego@Sun.COM mlsvc_NetShareEnumLevel2(ndr_xa_t *mxa, 22068474SJose.Borrego@Sun.COM struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) 22078474SJose.Borrego@Sun.COM { 22089343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_2 *info2; 22098474SJose.Borrego@Sun.COM smb_shriter_t iterator; 22108474SJose.Borrego@Sun.COM smb_share_t *si; 22118474SJose.Borrego@Sun.COM DWORD status; 22128474SJose.Borrego@Sun.COM 22138474SJose.Borrego@Sun.COM se->se_n_enum = srvsvc_estimate_objcnt(se->se_prefmaxlen, 22149343SAfshin.Ardakani@Sun.COM se->se_n_total, sizeof (struct mslm_NetShareInfo_2) + MAXNAMELEN); 22158474SJose.Borrego@Sun.COM if (se->se_n_enum == 0) 22168474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 22178474SJose.Borrego@Sun.COM 22189343SAfshin.Ardakani@Sun.COM info2 = NDR_NEWN(mxa, struct mslm_NetShareInfo_2, se->se_n_enum); 22198474SJose.Borrego@Sun.COM if (info2 == NULL) 22208474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 22218474SJose.Borrego@Sun.COM 22228474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 22238474SJose.Borrego@Sun.COM 22248474SJose.Borrego@Sun.COM se->se_n_read = 0; 22258474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != 0) { 22268474SJose.Borrego@Sun.COM if (se->se_n_skip > 0) { 22278474SJose.Borrego@Sun.COM --se->se_n_skip; 22288474SJose.Borrego@Sun.COM continue; 22298474SJose.Borrego@Sun.COM } 22308474SJose.Borrego@Sun.COM 22318474SJose.Borrego@Sun.COM ++se->se_resume_handle; 22328474SJose.Borrego@Sun.COM 22338474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 22348474SJose.Borrego@Sun.COM continue; 22358474SJose.Borrego@Sun.COM 22368474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 22378474SJose.Borrego@Sun.COM continue; 22388474SJose.Borrego@Sun.COM 22398474SJose.Borrego@Sun.COM if (se->se_n_read >= se->se_n_enum) { 22408474SJose.Borrego@Sun.COM se->se_n_read = se->se_n_enum; 22418474SJose.Borrego@Sun.COM break; 22428474SJose.Borrego@Sun.COM } 22438474SJose.Borrego@Sun.COM 22448474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info2); 22458474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 22468474SJose.Borrego@Sun.COM break; 22478474SJose.Borrego@Sun.COM 22488474SJose.Borrego@Sun.COM ++se->se_n_read; 22498474SJose.Borrego@Sun.COM } 22508474SJose.Borrego@Sun.COM 22518474SJose.Borrego@Sun.COM if (se->se_n_read < se->se_n_enum) { 22528474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info2)) 22538474SJose.Borrego@Sun.COM ++se->se_n_read; 22548474SJose.Borrego@Sun.COM } 22558474SJose.Borrego@Sun.COM 22568474SJose.Borrego@Sun.COM infonres->entriesread = se->se_n_read; 22578474SJose.Borrego@Sun.COM infonres->entries = info2; 22588474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 22598474SJose.Borrego@Sun.COM } 22608474SJose.Borrego@Sun.COM 22618474SJose.Borrego@Sun.COM /* 22628474SJose.Borrego@Sun.COM * NetShareEnum Level 501 22638474SJose.Borrego@Sun.COM */ 22648474SJose.Borrego@Sun.COM static DWORD 22658474SJose.Borrego@Sun.COM mlsvc_NetShareEnumLevel501(ndr_xa_t *mxa, 22668474SJose.Borrego@Sun.COM struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) 22678474SJose.Borrego@Sun.COM { 22689343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_501 *info501; 22698474SJose.Borrego@Sun.COM smb_shriter_t iterator; 22708474SJose.Borrego@Sun.COM smb_share_t *si; 22718474SJose.Borrego@Sun.COM DWORD status; 22728474SJose.Borrego@Sun.COM 22738474SJose.Borrego@Sun.COM se->se_n_enum = srvsvc_estimate_objcnt(se->se_prefmaxlen, 22749343SAfshin.Ardakani@Sun.COM se->se_n_total, sizeof (struct mslm_NetShareInfo_501) + MAXNAMELEN); 22758474SJose.Borrego@Sun.COM if (se->se_n_enum == 0) 22768474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 22778474SJose.Borrego@Sun.COM 22789343SAfshin.Ardakani@Sun.COM info501 = NDR_NEWN(mxa, struct mslm_NetShareInfo_501, 22798474SJose.Borrego@Sun.COM se->se_n_enum); 22808474SJose.Borrego@Sun.COM if (info501 == NULL) 22818474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 22828474SJose.Borrego@Sun.COM 22838474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 22848474SJose.Borrego@Sun.COM 22858474SJose.Borrego@Sun.COM se->se_n_read = 0; 22868474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != 0) { 22878474SJose.Borrego@Sun.COM if (se->se_n_skip > 0) { 22888474SJose.Borrego@Sun.COM --se->se_n_skip; 22898474SJose.Borrego@Sun.COM continue; 22908474SJose.Borrego@Sun.COM } 22918474SJose.Borrego@Sun.COM 22928474SJose.Borrego@Sun.COM ++se->se_resume_handle; 22938474SJose.Borrego@Sun.COM 22948474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 22958474SJose.Borrego@Sun.COM continue; 22968474SJose.Borrego@Sun.COM 22978474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 22988474SJose.Borrego@Sun.COM continue; 22998474SJose.Borrego@Sun.COM 23008474SJose.Borrego@Sun.COM if (se->se_n_read >= se->se_n_enum) { 23018474SJose.Borrego@Sun.COM se->se_n_read = se->se_n_enum; 23028474SJose.Borrego@Sun.COM break; 23038474SJose.Borrego@Sun.COM } 23048474SJose.Borrego@Sun.COM 23058474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info501); 23068474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 23078474SJose.Borrego@Sun.COM break; 23088474SJose.Borrego@Sun.COM 23098474SJose.Borrego@Sun.COM ++se->se_n_read; 23108474SJose.Borrego@Sun.COM } 23118474SJose.Borrego@Sun.COM 23128474SJose.Borrego@Sun.COM if (se->se_n_read < se->se_n_enum) { 23138474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info501)) 23148474SJose.Borrego@Sun.COM ++se->se_n_read; 23158474SJose.Borrego@Sun.COM } 23168474SJose.Borrego@Sun.COM 23178474SJose.Borrego@Sun.COM infonres->entriesread = se->se_n_read; 23188474SJose.Borrego@Sun.COM infonres->entries = info501; 23198474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 23208474SJose.Borrego@Sun.COM } 23218474SJose.Borrego@Sun.COM 23228474SJose.Borrego@Sun.COM /* 23238474SJose.Borrego@Sun.COM * NetShareEnum Level 502 23248474SJose.Borrego@Sun.COM */ 23258474SJose.Borrego@Sun.COM static DWORD 23268474SJose.Borrego@Sun.COM mlsvc_NetShareEnumLevel502(ndr_xa_t *mxa, 23278474SJose.Borrego@Sun.COM struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) 23288474SJose.Borrego@Sun.COM { 23299343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_502 *info502; 23308474SJose.Borrego@Sun.COM smb_shriter_t iterator; 23318474SJose.Borrego@Sun.COM smb_share_t *si; 23328474SJose.Borrego@Sun.COM DWORD status; 23338474SJose.Borrego@Sun.COM 23348474SJose.Borrego@Sun.COM se->se_n_enum = srvsvc_estimate_objcnt(se->se_prefmaxlen, 23359343SAfshin.Ardakani@Sun.COM se->se_n_total, sizeof (struct mslm_NetShareInfo_502) + MAXNAMELEN); 23368474SJose.Borrego@Sun.COM if (se->se_n_enum == 0) 23378474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 23388474SJose.Borrego@Sun.COM 23399343SAfshin.Ardakani@Sun.COM info502 = NDR_NEWN(mxa, struct mslm_NetShareInfo_502, 23408474SJose.Borrego@Sun.COM se->se_n_enum); 23418474SJose.Borrego@Sun.COM if (info502 == NULL) 23428474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 23438474SJose.Borrego@Sun.COM 23448474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 23458474SJose.Borrego@Sun.COM 23468474SJose.Borrego@Sun.COM se->se_n_read = 0; 23478474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != NULL) { 23488474SJose.Borrego@Sun.COM if (se->se_n_skip > 0) { 23498474SJose.Borrego@Sun.COM --se->se_n_skip; 23508474SJose.Borrego@Sun.COM continue; 23518474SJose.Borrego@Sun.COM } 23528474SJose.Borrego@Sun.COM 23538474SJose.Borrego@Sun.COM ++se->se_resume_handle; 23548474SJose.Borrego@Sun.COM 23558474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 23568474SJose.Borrego@Sun.COM continue; 23578474SJose.Borrego@Sun.COM 23588474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 23598474SJose.Borrego@Sun.COM continue; 23608474SJose.Borrego@Sun.COM 23618474SJose.Borrego@Sun.COM if (se->se_n_read >= se->se_n_enum) { 23628474SJose.Borrego@Sun.COM se->se_n_read = se->se_n_enum; 23638474SJose.Borrego@Sun.COM break; 23648474SJose.Borrego@Sun.COM } 23658474SJose.Borrego@Sun.COM 23668474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info502); 23678474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 23688474SJose.Borrego@Sun.COM break; 23698474SJose.Borrego@Sun.COM 23708474SJose.Borrego@Sun.COM ++se->se_n_read; 23718474SJose.Borrego@Sun.COM } 23728474SJose.Borrego@Sun.COM 23738474SJose.Borrego@Sun.COM if (se->se_n_read < se->se_n_enum) { 23748474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info502)) 23758474SJose.Borrego@Sun.COM ++se->se_n_read; 23768474SJose.Borrego@Sun.COM } 23778474SJose.Borrego@Sun.COM 23788474SJose.Borrego@Sun.COM infonres->entriesread = se->se_n_read; 23798474SJose.Borrego@Sun.COM infonres->entries = info502; 23808474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 23818474SJose.Borrego@Sun.COM } 23828474SJose.Borrego@Sun.COM 23838474SJose.Borrego@Sun.COM /* 23848474SJose.Borrego@Sun.COM * mlsvc_NetShareEnumCommon 23858474SJose.Borrego@Sun.COM * 23868474SJose.Borrego@Sun.COM * Build the levels 0, 1, 2, 501 and 502 share information. This function 23878474SJose.Borrego@Sun.COM * is called by the various NetShareEnum levels for each share. If 23888474SJose.Borrego@Sun.COM * we cannot build the share data for some reason, we return an error 23898474SJose.Borrego@Sun.COM * but the actual value of the error is not important to the caller. 23908474SJose.Borrego@Sun.COM * The caller just needs to know not to include this info in the RPC 23918474SJose.Borrego@Sun.COM * response. 23928474SJose.Borrego@Sun.COM * 23938474SJose.Borrego@Sun.COM * Returns: 23948474SJose.Borrego@Sun.COM * ERROR_SUCCESS 23958474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY 23968474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL 23978474SJose.Borrego@Sun.COM */ 23988474SJose.Borrego@Sun.COM static DWORD 23998474SJose.Borrego@Sun.COM mlsvc_NetShareEnumCommon(ndr_xa_t *mxa, srvsvc_enum_t *se, 24008474SJose.Borrego@Sun.COM smb_share_t *si, void *infop) 24018474SJose.Borrego@Sun.COM { 24029343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_0 *info0; 24039343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1 *info1; 24049343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_2 *info2; 24059343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_501 *info501; 24069343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_502 *info502; 2407*9832Samw@Sun.COM srvsvc_sd_t sd; 2408*9832Samw@Sun.COM uint8_t *netname; 2409*9832Samw@Sun.COM uint8_t *comment; 2410*9832Samw@Sun.COM uint8_t *passwd; 2411*9832Samw@Sun.COM uint8_t *path; 24128474SJose.Borrego@Sun.COM int i = se->se_n_read; 24138474SJose.Borrego@Sun.COM 2414*9832Samw@Sun.COM netname = (uint8_t *)NDR_STRDUP(mxa, si->shr_name); 2415*9832Samw@Sun.COM comment = (uint8_t *)NDR_STRDUP(mxa, si->shr_cmnt); 2416*9832Samw@Sun.COM passwd = (uint8_t *)NDR_STRDUP(mxa, empty_string); 2417*9832Samw@Sun.COM path = (uint8_t *)srvsvc_share_mkpath(mxa, si->shr_path); 2418*9832Samw@Sun.COM 2419*9832Samw@Sun.COM if (!netname || !comment || !passwd || !path) 2420*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 2421*9832Samw@Sun.COM 24228474SJose.Borrego@Sun.COM switch (se->se_level) { 24238474SJose.Borrego@Sun.COM case 0: 24249343SAfshin.Ardakani@Sun.COM info0 = (struct mslm_NetShareInfo_0 *)infop; 2425*9832Samw@Sun.COM info0[i].shi0_netname = netname; 24268474SJose.Borrego@Sun.COM break; 24278474SJose.Borrego@Sun.COM 24288474SJose.Borrego@Sun.COM case 1: 24299343SAfshin.Ardakani@Sun.COM info1 = (struct mslm_NetShareInfo_1 *)infop; 2430*9832Samw@Sun.COM info1[i].shi1_netname = netname; 2431*9832Samw@Sun.COM info1[i].shi1_comment = comment; 24328474SJose.Borrego@Sun.COM info1[i].shi1_type = si->shr_type; 24338474SJose.Borrego@Sun.COM break; 24348474SJose.Borrego@Sun.COM 24358474SJose.Borrego@Sun.COM case 2: 24369343SAfshin.Ardakani@Sun.COM info2 = (struct mslm_NetShareInfo_2 *)infop; 2437*9832Samw@Sun.COM info2[i].shi2_netname = netname; 2438*9832Samw@Sun.COM info2[i].shi2_comment = comment; 2439*9832Samw@Sun.COM info2[i].shi2_path = path; 24408474SJose.Borrego@Sun.COM info2[i].shi2_type = si->shr_type; 24418474SJose.Borrego@Sun.COM info2[i].shi2_permissions = 0; 24428474SJose.Borrego@Sun.COM info2[i].shi2_max_uses = SHI_USES_UNLIMITED; 24438474SJose.Borrego@Sun.COM info2[i].shi2_current_uses = 0; 2444*9832Samw@Sun.COM info2[i].shi2_passwd = passwd; 24458474SJose.Borrego@Sun.COM break; 24468474SJose.Borrego@Sun.COM 24478474SJose.Borrego@Sun.COM case 501: 24489343SAfshin.Ardakani@Sun.COM info501 = (struct mslm_NetShareInfo_501 *)infop; 2449*9832Samw@Sun.COM info501[i].shi501_netname = netname; 2450*9832Samw@Sun.COM info501[i].shi501_comment = comment; 24518474SJose.Borrego@Sun.COM info501[i].shi501_type = si->shr_type; 24529343SAfshin.Ardakani@Sun.COM info501[i].shi501_reserved = 0; 24538474SJose.Borrego@Sun.COM break; 24548474SJose.Borrego@Sun.COM 24558474SJose.Borrego@Sun.COM case 502: 24569343SAfshin.Ardakani@Sun.COM info502 = (struct mslm_NetShareInfo_502 *)infop; 2457*9832Samw@Sun.COM info502[i].shi502_netname = netname; 2458*9832Samw@Sun.COM info502[i].shi502_comment = comment; 2459*9832Samw@Sun.COM info502[i].shi502_path = path; 24608474SJose.Borrego@Sun.COM info502[i].shi502_type = si->shr_type; 24618474SJose.Borrego@Sun.COM info502[i].shi502_permissions = 0; 24628474SJose.Borrego@Sun.COM info502[i].shi502_max_uses = SHI_USES_UNLIMITED; 24638474SJose.Borrego@Sun.COM info502[i].shi502_current_uses = 0; 2464*9832Samw@Sun.COM info502[i].shi502_passwd = passwd; 2465*9832Samw@Sun.COM 2466*9832Samw@Sun.COM if (srvsvc_share_getsd(mxa, si, &sd) == ERROR_SUCCESS) { 2467*9832Samw@Sun.COM info502[i].shi502_reserved = sd.sd_size; 2468*9832Samw@Sun.COM info502[i].shi502_security_descriptor = sd.sd_buf; 2469*9832Samw@Sun.COM } else { 2470*9832Samw@Sun.COM info502[i].shi502_reserved = 0; 2471*9832Samw@Sun.COM info502[i].shi502_security_descriptor = NULL; 2472*9832Samw@Sun.COM } 2473*9832Samw@Sun.COM 24748474SJose.Borrego@Sun.COM break; 24758474SJose.Borrego@Sun.COM 24768474SJose.Borrego@Sun.COM default: 24778474SJose.Borrego@Sun.COM return (ERROR_INVALID_LEVEL); 24788474SJose.Borrego@Sun.COM } 24798474SJose.Borrego@Sun.COM 24808474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 24818474SJose.Borrego@Sun.COM } 24828474SJose.Borrego@Sun.COM 24838474SJose.Borrego@Sun.COM /* 24848474SJose.Borrego@Sun.COM * srvsvc_add_autohome 24858474SJose.Borrego@Sun.COM * 24868474SJose.Borrego@Sun.COM * Add the autohome share for the user. The share must not be a permanent 24878474SJose.Borrego@Sun.COM * share to avoid duplicates. 24888474SJose.Borrego@Sun.COM */ 24898474SJose.Borrego@Sun.COM static boolean_t 24908474SJose.Borrego@Sun.COM srvsvc_add_autohome(ndr_xa_t *mxa, srvsvc_enum_t *se, void *infop) 24918474SJose.Borrego@Sun.COM { 24928474SJose.Borrego@Sun.COM smb_opipe_context_t *ctx = &mxa->pipe->np_ctx; 24938474SJose.Borrego@Sun.COM char *username = ctx->oc_account; 24948474SJose.Borrego@Sun.COM smb_share_t si; 24958474SJose.Borrego@Sun.COM DWORD status; 24968474SJose.Borrego@Sun.COM 24978474SJose.Borrego@Sun.COM if (smb_shr_get(username, &si) != NERR_Success) 24988474SJose.Borrego@Sun.COM return (B_FALSE); 24998474SJose.Borrego@Sun.COM 25008474SJose.Borrego@Sun.COM if ((si.shr_flags & SMB_SHRF_AUTOHOME) == 0) 25018474SJose.Borrego@Sun.COM return (B_FALSE); 25028474SJose.Borrego@Sun.COM 25038474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, &si, infop); 25048474SJose.Borrego@Sun.COM return (status == ERROR_SUCCESS); 25058474SJose.Borrego@Sun.COM } 25068474SJose.Borrego@Sun.COM 25078474SJose.Borrego@Sun.COM /* 25088474SJose.Borrego@Sun.COM * srvsvc_share_mkpath 25098474SJose.Borrego@Sun.COM * 25108474SJose.Borrego@Sun.COM * Create the share path required by the share enum calls. The path 25118474SJose.Borrego@Sun.COM * is created in a heap buffer ready for use by the caller. 25128474SJose.Borrego@Sun.COM * 25138474SJose.Borrego@Sun.COM * Some Windows over-the-wire backup applications do not work unless a 25148474SJose.Borrego@Sun.COM * drive letter is present in the share path. We don't care about the 25158474SJose.Borrego@Sun.COM * drive letter since the path is fully qualified with the volume name. 25168474SJose.Borrego@Sun.COM * 25178474SJose.Borrego@Sun.COM * Windows clients seem to be mostly okay with forward slashes in 25188474SJose.Borrego@Sun.COM * share paths but they cannot handle one immediately after the drive 25198474SJose.Borrego@Sun.COM * letter, i.e. B:/. For consistency we convert all the slashes in 25208474SJose.Borrego@Sun.COM * the path. 25218474SJose.Borrego@Sun.COM * 25228474SJose.Borrego@Sun.COM * Returns a pointer to a heap buffer containing the share path, which 25238474SJose.Borrego@Sun.COM * could be a null pointer if the heap allocation fails. 25248474SJose.Borrego@Sun.COM */ 25258474SJose.Borrego@Sun.COM static char * 25268474SJose.Borrego@Sun.COM srvsvc_share_mkpath(ndr_xa_t *mxa, char *path) 25278474SJose.Borrego@Sun.COM { 25288474SJose.Borrego@Sun.COM char tmpbuf[MAXPATHLEN]; 25298474SJose.Borrego@Sun.COM char *p; 25308474SJose.Borrego@Sun.COM 25318474SJose.Borrego@Sun.COM if (strlen(path) == 0) 25328474SJose.Borrego@Sun.COM return (NDR_STRDUP(mxa, path)); 25338474SJose.Borrego@Sun.COM 25348474SJose.Borrego@Sun.COM /* 25358474SJose.Borrego@Sun.COM * Strip the volume name from the path (/vol1/home -> /home). 25368474SJose.Borrego@Sun.COM */ 25378474SJose.Borrego@Sun.COM p = path; 25388474SJose.Borrego@Sun.COM p += strspn(p, "/"); 25398474SJose.Borrego@Sun.COM p += strcspn(p, "/"); 25408474SJose.Borrego@Sun.COM p += strspn(p, "/"); 25418474SJose.Borrego@Sun.COM (void) snprintf(tmpbuf, MAXPATHLEN, "%c:/%s", 'B', p); 25428474SJose.Borrego@Sun.COM (void) strsubst(tmpbuf, '/', '\\'); 25438474SJose.Borrego@Sun.COM 25448474SJose.Borrego@Sun.COM return (NDR_STRDUP(mxa, tmpbuf)); 25458474SJose.Borrego@Sun.COM } 25468474SJose.Borrego@Sun.COM 2547*9832Samw@Sun.COM static int 2548*9832Samw@Sun.COM srvsvc_s_NetShareCheck(void *arg, ndr_xa_t *mxa) 2549*9832Samw@Sun.COM { 2550*9832Samw@Sun.COM struct mslm_NetShareCheck *param = arg; 2551*9832Samw@Sun.COM smb_shriter_t iterator; 2552*9832Samw@Sun.COM smb_share_t *si; 2553*9832Samw@Sun.COM char *path; 2554*9832Samw@Sun.COM 2555*9832Samw@Sun.COM if (param->path == NULL) { 2556*9832Samw@Sun.COM param->stype = STYPE_DISKTREE; 2557*9832Samw@Sun.COM param->status = NERR_NetNameNotFound; 2558*9832Samw@Sun.COM return (NDR_DRC_OK); 2559*9832Samw@Sun.COM } 2560*9832Samw@Sun.COM 2561*9832Samw@Sun.COM (void) strsubst((char *)param->path, '/', '\\'); 2562*9832Samw@Sun.COM 2563*9832Samw@Sun.COM smb_shr_iterinit(&iterator); 2564*9832Samw@Sun.COM 2565*9832Samw@Sun.COM while ((si = smb_shr_iterate(&iterator)) != NULL) { 2566*9832Samw@Sun.COM path = srvsvc_share_mkpath(mxa, si->shr_path); 2567*9832Samw@Sun.COM 2568*9832Samw@Sun.COM if (utf8_strcasecmp(path, (char *)param->path) == 0) { 2569*9832Samw@Sun.COM param->stype = (si->shr_type & STYPE_MASK); 2570*9832Samw@Sun.COM param->status = NERR_Success; 2571*9832Samw@Sun.COM return (NDR_DRC_OK); 2572*9832Samw@Sun.COM } 2573*9832Samw@Sun.COM } 2574*9832Samw@Sun.COM 2575*9832Samw@Sun.COM param->stype = STYPE_DISKTREE; 2576*9832Samw@Sun.COM param->status = NERR_NetNameNotFound; 2577*9832Samw@Sun.COM return (NDR_DRC_OK); 2578*9832Samw@Sun.COM } 2579*9832Samw@Sun.COM 25808474SJose.Borrego@Sun.COM /* 25818474SJose.Borrego@Sun.COM * srvsvc_s_NetShareDel 25828474SJose.Borrego@Sun.COM * 25838474SJose.Borrego@Sun.COM * Delete a share. Only the administrator, or a member of the domain 25848474SJose.Borrego@Sun.COM * administrators group, is allowed to delete shares. 25858474SJose.Borrego@Sun.COM * 25868474SJose.Borrego@Sun.COM * This interface is used by the rmtshare command from the NT resource 25878474SJose.Borrego@Sun.COM * kit. Rmtshare allows a client to add or remove shares on a server 25888474SJose.Borrego@Sun.COM * from the client's command line. 25898474SJose.Borrego@Sun.COM * 25908474SJose.Borrego@Sun.COM * Returns Win32 error codes. 25918474SJose.Borrego@Sun.COM */ 25928474SJose.Borrego@Sun.COM static int 25938474SJose.Borrego@Sun.COM srvsvc_s_NetShareDel(void *arg, ndr_xa_t *mxa) 25948474SJose.Borrego@Sun.COM { 25958474SJose.Borrego@Sun.COM struct mslm_NetShareDel *param = arg; 25968474SJose.Borrego@Sun.COM 25978474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa) || 25988474SJose.Borrego@Sun.COM smb_shr_is_restricted((char *)param->netname)) { 25998474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 26008474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 26018474SJose.Borrego@Sun.COM } 26028474SJose.Borrego@Sun.COM 26038474SJose.Borrego@Sun.COM param->status = srvsvc_sa_delete((char *)param->netname); 26048474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 26058474SJose.Borrego@Sun.COM } 26068474SJose.Borrego@Sun.COM 26078474SJose.Borrego@Sun.COM /* 26088474SJose.Borrego@Sun.COM * srvsvc_s_NetGetFileSecurity 26098474SJose.Borrego@Sun.COM * 26108474SJose.Borrego@Sun.COM * Get security descriptor of the requested file/folder 26118474SJose.Borrego@Sun.COM * 26128474SJose.Borrego@Sun.COM * Right now, just returns ERROR_ACCESS_DENIED, because we cannot 26138474SJose.Borrego@Sun.COM * get the requested SD here in RPC code. 26148474SJose.Borrego@Sun.COM */ 26158474SJose.Borrego@Sun.COM /*ARGSUSED*/ 26168474SJose.Borrego@Sun.COM static int 26178474SJose.Borrego@Sun.COM srvsvc_s_NetGetFileSecurity(void *arg, ndr_xa_t *mxa) 26188474SJose.Borrego@Sun.COM { 26198474SJose.Borrego@Sun.COM struct mslm_NetGetFileSecurity *param = arg; 26208474SJose.Borrego@Sun.COM 26218474SJose.Borrego@Sun.COM param->length = 0; 26228474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 26238474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 26248474SJose.Borrego@Sun.COM } 26258474SJose.Borrego@Sun.COM 26268474SJose.Borrego@Sun.COM /* 26278474SJose.Borrego@Sun.COM * srvsvc_s_NetSetFileSecurity 26288474SJose.Borrego@Sun.COM * 26298474SJose.Borrego@Sun.COM * Set the given security descriptor for the requested file/folder 26308474SJose.Borrego@Sun.COM * 26318474SJose.Borrego@Sun.COM * Right now, just returns ERROR_ACCESS_DENIED, because we cannot 26328474SJose.Borrego@Sun.COM * set the requested SD here in RPC code. 26338474SJose.Borrego@Sun.COM */ 26348474SJose.Borrego@Sun.COM /*ARGSUSED*/ 26358474SJose.Borrego@Sun.COM static int 26368474SJose.Borrego@Sun.COM srvsvc_s_NetSetFileSecurity(void *arg, ndr_xa_t *mxa) 26378474SJose.Borrego@Sun.COM { 26388474SJose.Borrego@Sun.COM struct mslm_NetSetFileSecurity *param = arg; 26398474SJose.Borrego@Sun.COM 26408474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 26418474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 26428474SJose.Borrego@Sun.COM } 26438474SJose.Borrego@Sun.COM 26448474SJose.Borrego@Sun.COM /* 26458474SJose.Borrego@Sun.COM * If the default "smb" share group exists then return the group 26468474SJose.Borrego@Sun.COM * handle, otherwise create the group and return the handle. 26478474SJose.Borrego@Sun.COM * 26488474SJose.Borrego@Sun.COM * All shares created via the srvsvc will be added to the "smb" 26498474SJose.Borrego@Sun.COM * group. 26508474SJose.Borrego@Sun.COM */ 26518474SJose.Borrego@Sun.COM static sa_group_t 26528474SJose.Borrego@Sun.COM srvsvc_sa_get_smbgrp(sa_handle_t handle) 26538474SJose.Borrego@Sun.COM { 26548474SJose.Borrego@Sun.COM sa_group_t group = NULL; 26558474SJose.Borrego@Sun.COM int err; 26568474SJose.Borrego@Sun.COM 26578474SJose.Borrego@Sun.COM group = sa_get_group(handle, SMB_DEFAULT_SHARE_GROUP); 26588474SJose.Borrego@Sun.COM if (group != NULL) 26598474SJose.Borrego@Sun.COM return (group); 26608474SJose.Borrego@Sun.COM 26618474SJose.Borrego@Sun.COM group = sa_create_group(handle, SMB_DEFAULT_SHARE_GROUP, &err); 26628474SJose.Borrego@Sun.COM if (group == NULL) 26638474SJose.Borrego@Sun.COM return (NULL); 26648474SJose.Borrego@Sun.COM 26658474SJose.Borrego@Sun.COM if (sa_create_optionset(group, SMB_DEFAULT_SHARE_GROUP) == NULL) { 26668474SJose.Borrego@Sun.COM (void) sa_remove_group(group); 26678474SJose.Borrego@Sun.COM group = NULL; 26688474SJose.Borrego@Sun.COM } 26698474SJose.Borrego@Sun.COM 26708474SJose.Borrego@Sun.COM return (group); 26718474SJose.Borrego@Sun.COM } 26728474SJose.Borrego@Sun.COM 26738474SJose.Borrego@Sun.COM /* 26748474SJose.Borrego@Sun.COM * Stores the given share in sharemgr 26758474SJose.Borrego@Sun.COM */ 26768474SJose.Borrego@Sun.COM static uint32_t 26778474SJose.Borrego@Sun.COM srvsvc_sa_add(char *sharename, char *path, char *cmnt) 26788474SJose.Borrego@Sun.COM { 26798474SJose.Borrego@Sun.COM sa_handle_t handle; 26808474SJose.Borrego@Sun.COM sa_share_t share; 26818474SJose.Borrego@Sun.COM sa_group_t group; 26828474SJose.Borrego@Sun.COM sa_resource_t resource; 26838474SJose.Borrego@Sun.COM boolean_t new_share = B_FALSE; 26848474SJose.Borrego@Sun.COM uint32_t status = NERR_Success; 26858474SJose.Borrego@Sun.COM int err; 26868474SJose.Borrego@Sun.COM 26878474SJose.Borrego@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 26888474SJose.Borrego@Sun.COM return (NERR_InternalError); 26898474SJose.Borrego@Sun.COM 26908474SJose.Borrego@Sun.COM share = sa_find_share(handle, path); 26918474SJose.Borrego@Sun.COM if (share == NULL) { 26928474SJose.Borrego@Sun.COM group = srvsvc_sa_get_smbgrp(handle); 26938474SJose.Borrego@Sun.COM if (group == NULL) { 26948474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 26958474SJose.Borrego@Sun.COM return (NERR_InternalError); 26968474SJose.Borrego@Sun.COM } 26978474SJose.Borrego@Sun.COM 26988474SJose.Borrego@Sun.COM share = sa_add_share(group, path, SA_SHARE_PERMANENT, &err); 26998474SJose.Borrego@Sun.COM if (share == NULL) { 27008474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 27018474SJose.Borrego@Sun.COM return (NERR_InternalError); 27028474SJose.Borrego@Sun.COM } 27038474SJose.Borrego@Sun.COM new_share = B_TRUE; 27048474SJose.Borrego@Sun.COM } 27058474SJose.Borrego@Sun.COM 27068474SJose.Borrego@Sun.COM resource = sa_get_share_resource(share, sharename); 27078474SJose.Borrego@Sun.COM if (resource == NULL) { 27088474SJose.Borrego@Sun.COM resource = sa_add_resource(share, sharename, 27098474SJose.Borrego@Sun.COM SA_SHARE_PERMANENT, &err); 27108474SJose.Borrego@Sun.COM if (resource == NULL) { 27118474SJose.Borrego@Sun.COM if (new_share) 27128474SJose.Borrego@Sun.COM (void) sa_remove_share(share); 27138474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 27148474SJose.Borrego@Sun.COM return (NERR_InternalError); 27158474SJose.Borrego@Sun.COM } 27168474SJose.Borrego@Sun.COM } 27178474SJose.Borrego@Sun.COM 27188474SJose.Borrego@Sun.COM (void) sa_set_resource_description(resource, cmnt); 27198474SJose.Borrego@Sun.COM 27208474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 27218474SJose.Borrego@Sun.COM return (status); 27228474SJose.Borrego@Sun.COM } 27238474SJose.Borrego@Sun.COM 27248474SJose.Borrego@Sun.COM /* 27258474SJose.Borrego@Sun.COM * Removes the share from sharemgr 27268474SJose.Borrego@Sun.COM */ 27278474SJose.Borrego@Sun.COM static uint32_t 27288474SJose.Borrego@Sun.COM srvsvc_sa_delete(char *sharename) 27298474SJose.Borrego@Sun.COM { 27308474SJose.Borrego@Sun.COM sa_handle_t handle; 27318474SJose.Borrego@Sun.COM sa_resource_t resource; 27328474SJose.Borrego@Sun.COM uint32_t status; 27338474SJose.Borrego@Sun.COM 27348474SJose.Borrego@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 27358474SJose.Borrego@Sun.COM return (NERR_InternalError); 27368474SJose.Borrego@Sun.COM 27378474SJose.Borrego@Sun.COM status = NERR_InternalError; 27388474SJose.Borrego@Sun.COM if ((resource = sa_find_resource(handle, sharename)) != NULL) { 27398474SJose.Borrego@Sun.COM if (sa_remove_resource(resource) == SA_OK) 27408474SJose.Borrego@Sun.COM status = NERR_Success; 27418474SJose.Borrego@Sun.COM } 27428474SJose.Borrego@Sun.COM 27438474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 27448474SJose.Borrego@Sun.COM return (status); 27458474SJose.Borrego@Sun.COM } 27468474SJose.Borrego@Sun.COM 2747*9832Samw@Sun.COM /* 2748*9832Samw@Sun.COM * Update the share information. 2749*9832Samw@Sun.COM */ 2750*9832Samw@Sun.COM static uint32_t 2751*9832Samw@Sun.COM srvsvc_sa_modify(smb_share_t *si, srvsvc_netshare_setinfo_t *info) 2752*9832Samw@Sun.COM { 2753*9832Samw@Sun.COM sa_handle_t handle; 2754*9832Samw@Sun.COM sa_share_t share; 2755*9832Samw@Sun.COM sa_resource_t resource; 2756*9832Samw@Sun.COM boolean_t renamed = B_FALSE; 2757*9832Samw@Sun.COM uint32_t nerr = NERR_Success; 2758*9832Samw@Sun.COM 2759*9832Samw@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 2760*9832Samw@Sun.COM return (NERR_InternalError); 2761*9832Samw@Sun.COM 2762*9832Samw@Sun.COM if ((share = sa_find_share(handle, si->shr_path)) == NULL) { 2763*9832Samw@Sun.COM smb_shr_sa_exit(); 2764*9832Samw@Sun.COM return (NERR_InternalError); 2765*9832Samw@Sun.COM } 2766*9832Samw@Sun.COM 2767*9832Samw@Sun.COM if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) { 2768*9832Samw@Sun.COM smb_shr_sa_exit(); 2769*9832Samw@Sun.COM return (NERR_InternalError); 2770*9832Samw@Sun.COM } 2771*9832Samw@Sun.COM 2772*9832Samw@Sun.COM if (info->nss_netname != NULL && info->nss_netname[0] != '\0' && 2773*9832Samw@Sun.COM utf8_strcasecmp(info->nss_netname, si->shr_name) != 0) { 2774*9832Samw@Sun.COM (void) sa_set_resource_attr(resource, SHOPT_NAME, 2775*9832Samw@Sun.COM info->nss_netname); 2776*9832Samw@Sun.COM renamed = B_TRUE; 2777*9832Samw@Sun.COM } 2778*9832Samw@Sun.COM 2779*9832Samw@Sun.COM if ((info->nss_comment != NULL) && 2780*9832Samw@Sun.COM (strcmp(info->nss_comment, si->shr_cmnt) != 0)) { 2781*9832Samw@Sun.COM (void) sa_set_resource_description(resource, info->nss_comment); 2782*9832Samw@Sun.COM (void) strlcpy(si->shr_cmnt, info->nss_comment, 2783*9832Samw@Sun.COM SMB_SHARE_CMNT_MAX); 2784*9832Samw@Sun.COM } 2785*9832Samw@Sun.COM 2786*9832Samw@Sun.COM smb_shr_sa_exit(); 2787*9832Samw@Sun.COM 2788*9832Samw@Sun.COM if (renamed) { 2789*9832Samw@Sun.COM nerr = smb_shr_rename(si->shr_name, info->nss_netname); 2790*9832Samw@Sun.COM if (nerr != NERR_Success) 2791*9832Samw@Sun.COM return (nerr); 2792*9832Samw@Sun.COM 2793*9832Samw@Sun.COM (void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN); 2794*9832Samw@Sun.COM } 2795*9832Samw@Sun.COM 2796*9832Samw@Sun.COM return (nerr); 2797*9832Samw@Sun.COM } 2798*9832Samw@Sun.COM 2799*9832Samw@Sun.COM /* 2800*9832Samw@Sun.COM * Update the share flags. 2801*9832Samw@Sun.COM */ 2802*9832Samw@Sun.COM static uint32_t 2803*9832Samw@Sun.COM srvsvc_sa_setattr(smb_share_t *si) 2804*9832Samw@Sun.COM { 2805*9832Samw@Sun.COM sa_handle_t handle; 2806*9832Samw@Sun.COM sa_share_t share; 2807*9832Samw@Sun.COM sa_resource_t resource; 2808*9832Samw@Sun.COM char *value; 2809*9832Samw@Sun.COM 2810*9832Samw@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 2811*9832Samw@Sun.COM return (NERR_InternalError); 2812*9832Samw@Sun.COM 2813*9832Samw@Sun.COM if ((share = sa_find_share(handle, si->shr_path)) == NULL) { 2814*9832Samw@Sun.COM smb_shr_sa_exit(); 2815*9832Samw@Sun.COM return (NERR_InternalError); 2816*9832Samw@Sun.COM } 2817*9832Samw@Sun.COM 2818*9832Samw@Sun.COM if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) { 2819*9832Samw@Sun.COM smb_shr_sa_exit(); 2820*9832Samw@Sun.COM return (NERR_InternalError); 2821*9832Samw@Sun.COM } 2822*9832Samw@Sun.COM 2823*9832Samw@Sun.COM if ((value = smb_shr_sa_csc_name(si)) == NULL) { 2824*9832Samw@Sun.COM smb_shr_sa_exit(); 2825*9832Samw@Sun.COM return (NERR_InternalError); 2826*9832Samw@Sun.COM } 2827*9832Samw@Sun.COM 2828*9832Samw@Sun.COM (void) sa_set_resource_attr(resource, SHOPT_CSC, value); 2829*9832Samw@Sun.COM smb_shr_sa_exit(); 2830*9832Samw@Sun.COM return (NERR_Success); 2831*9832Samw@Sun.COM } 2832*9832Samw@Sun.COM 28338474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[] = { 28348474SJose.Borrego@Sun.COM { srvsvc_s_NetConnectEnum, SRVSVC_OPNUM_NetConnectEnum }, 28358474SJose.Borrego@Sun.COM { srvsvc_s_NetFileEnum, SRVSVC_OPNUM_NetFileEnum }, 28368474SJose.Borrego@Sun.COM { srvsvc_s_NetFileClose, SRVSVC_OPNUM_NetFileClose }, 28378474SJose.Borrego@Sun.COM { srvsvc_s_NetShareGetInfo, SRVSVC_OPNUM_NetShareGetInfo }, 28388474SJose.Borrego@Sun.COM { srvsvc_s_NetShareSetInfo, SRVSVC_OPNUM_NetShareSetInfo }, 28398474SJose.Borrego@Sun.COM { srvsvc_s_NetSessionEnum, SRVSVC_OPNUM_NetSessionEnum }, 28408474SJose.Borrego@Sun.COM { srvsvc_s_NetSessionDel, SRVSVC_OPNUM_NetSessionDel }, 28418474SJose.Borrego@Sun.COM { srvsvc_s_NetServerGetInfo, SRVSVC_OPNUM_NetServerGetInfo }, 28428474SJose.Borrego@Sun.COM { srvsvc_s_NetRemoteTOD, SRVSVC_OPNUM_NetRemoteTOD }, 28438474SJose.Borrego@Sun.COM { srvsvc_s_NetNameValidate, SRVSVC_OPNUM_NetNameValidate }, 28448474SJose.Borrego@Sun.COM { srvsvc_s_NetShareAdd, SRVSVC_OPNUM_NetShareAdd }, 28458474SJose.Borrego@Sun.COM { srvsvc_s_NetShareDel, SRVSVC_OPNUM_NetShareDel }, 28468474SJose.Borrego@Sun.COM { srvsvc_s_NetShareEnum, SRVSVC_OPNUM_NetShareEnum }, 28478474SJose.Borrego@Sun.COM { srvsvc_s_NetShareEnumSticky, SRVSVC_OPNUM_NetShareEnumSticky }, 2848*9832Samw@Sun.COM { srvsvc_s_NetShareCheck, SRVSVC_OPNUM_NetShareCheck }, 28498474SJose.Borrego@Sun.COM { srvsvc_s_NetGetFileSecurity, SRVSVC_OPNUM_NetGetFileSecurity }, 28508474SJose.Borrego@Sun.COM { srvsvc_s_NetSetFileSecurity, SRVSVC_OPNUM_NetSetFileSecurity }, 28518474SJose.Borrego@Sun.COM {0} 28528474SJose.Borrego@Sun.COM }; 2853