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 498474SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h> 508474SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h> 518474SJose.Borrego@Sun.COM #include <smbsrv/lmerr.h> 528474SJose.Borrego@Sun.COM #include <smbsrv/nterror.h> 538474SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h> 548474SJose.Borrego@Sun.COM #include <smbsrv/cifs.h> 558474SJose.Borrego@Sun.COM #include <smbsrv/netrauth.h> 568474SJose.Borrego@Sun.COM #include <smbsrv/ndl/srvsvc.ndl> 578474SJose.Borrego@Sun.COM #include <smbsrv/smb_common_door.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 898474SJose.Borrego@Sun.COM static DWORD srvsvc_s_NetConnectEnumLevel0(ndr_xa_t *, 908474SJose.Borrego@Sun.COM srvsvc_NetConnectInfo0_t *); 918474SJose.Borrego@Sun.COM static DWORD srvsvc_s_NetConnectEnumLevel1(ndr_xa_t *, 928474SJose.Borrego@Sun.COM srvsvc_NetConnectInfo1_t *); 938474SJose.Borrego@Sun.COM 948474SJose.Borrego@Sun.COM static DWORD srvsvc_NetFileEnum2(ndr_xa_t *, 958474SJose.Borrego@Sun.COM struct mslm_NetFileEnum *); 968474SJose.Borrego@Sun.COM static DWORD srvsvc_NetFileEnum3(ndr_xa_t *, 978474SJose.Borrego@Sun.COM struct mslm_NetFileEnum *); 988474SJose.Borrego@Sun.COM 998474SJose.Borrego@Sun.COM static DWORD mlsvc_NetSessionEnumLevel0(struct mslm_infonres *, DWORD, 1008474SJose.Borrego@Sun.COM ndr_xa_t *); 1018474SJose.Borrego@Sun.COM static DWORD mlsvc_NetSessionEnumLevel1(struct mslm_infonres *, DWORD, 1028474SJose.Borrego@Sun.COM ndr_xa_t *); 1038474SJose.Borrego@Sun.COM 1048474SJose.Borrego@Sun.COM static DWORD mlsvc_NetShareEnumLevel0(ndr_xa_t *, 1058474SJose.Borrego@Sun.COM struct mslm_infonres *, srvsvc_enum_t *, int); 1068474SJose.Borrego@Sun.COM static DWORD mlsvc_NetShareEnumLevel1(ndr_xa_t *, 1078474SJose.Borrego@Sun.COM struct mslm_infonres *, srvsvc_enum_t *, int); 1088474SJose.Borrego@Sun.COM static DWORD mlsvc_NetShareEnumLevel2(ndr_xa_t *, 1098474SJose.Borrego@Sun.COM struct mslm_infonres *, srvsvc_enum_t *, int); 1108474SJose.Borrego@Sun.COM static DWORD mlsvc_NetShareEnumLevel501(ndr_xa_t *, 1118474SJose.Borrego@Sun.COM struct mslm_infonres *, srvsvc_enum_t *, int); 1128474SJose.Borrego@Sun.COM static DWORD mlsvc_NetShareEnumLevel502(ndr_xa_t *, 1138474SJose.Borrego@Sun.COM struct mslm_infonres *, srvsvc_enum_t *, int); 1148474SJose.Borrego@Sun.COM static DWORD mlsvc_NetShareEnumCommon(ndr_xa_t *, 1158474SJose.Borrego@Sun.COM srvsvc_enum_t *, smb_share_t *, void *); 1168474SJose.Borrego@Sun.COM static boolean_t srvsvc_add_autohome(ndr_xa_t *, srvsvc_enum_t *, 1178474SJose.Borrego@Sun.COM void *); 1188474SJose.Borrego@Sun.COM static char *srvsvc_share_mkpath(ndr_xa_t *, char *); 1198474SJose.Borrego@Sun.COM 1208474SJose.Borrego@Sun.COM static int srvsvc_netconnect_qualifier(const char *); 1218474SJose.Borrego@Sun.COM static uint32_t srvsvc_estimate_objcnt(uint32_t, uint32_t, uint32_t); 1228474SJose.Borrego@Sun.COM 1238474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_add(char *, char *, char *); 1248474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_delete(char *); 1258474SJose.Borrego@Sun.COM 1268474SJose.Borrego@Sun.COM static char empty_string[1]; 1278474SJose.Borrego@Sun.COM 1288474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[]; 1298474SJose.Borrego@Sun.COM 1308474SJose.Borrego@Sun.COM static ndr_service_t srvsvc_service = { 1318474SJose.Borrego@Sun.COM "SRVSVC", /* name */ 1328474SJose.Borrego@Sun.COM "Server services", /* desc */ 1338474SJose.Borrego@Sun.COM "\\srvsvc", /* endpoint */ 1348474SJose.Borrego@Sun.COM PIPE_NTSVCS, /* sec_addr_port */ 1358474SJose.Borrego@Sun.COM "4b324fc8-1670-01d3-1278-5a47bf6ee188", 3, /* abstract */ 1368474SJose.Borrego@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 1378474SJose.Borrego@Sun.COM 0, /* no bind_instance_size */ 1388474SJose.Borrego@Sun.COM 0, /* no bind_req() */ 1398474SJose.Borrego@Sun.COM 0, /* no unbind_and_close() */ 1408474SJose.Borrego@Sun.COM 0, /* use generic_call_stub() */ 1418474SJose.Borrego@Sun.COM &TYPEINFO(srvsvc_interface), /* interface ti */ 1428474SJose.Borrego@Sun.COM srvsvc_stub_table /* stub_table */ 1438474SJose.Borrego@Sun.COM }; 1448474SJose.Borrego@Sun.COM 1458474SJose.Borrego@Sun.COM /* 1468474SJose.Borrego@Sun.COM * srvsvc_initialize 1478474SJose.Borrego@Sun.COM * 1488474SJose.Borrego@Sun.COM * This function registers the SRVSVC RPC interface with the RPC runtime 1498474SJose.Borrego@Sun.COM * library. It must be called in order to use either the client side 1508474SJose.Borrego@Sun.COM * or the server side functions. 1518474SJose.Borrego@Sun.COM */ 1528474SJose.Borrego@Sun.COM void 1538474SJose.Borrego@Sun.COM srvsvc_initialize(void) 1548474SJose.Borrego@Sun.COM { 1558474SJose.Borrego@Sun.COM (void) ndr_svc_register(&srvsvc_service); 1568474SJose.Borrego@Sun.COM } 1578474SJose.Borrego@Sun.COM 1588474SJose.Borrego@Sun.COM /* 1598474SJose.Borrego@Sun.COM * srvsvc_s_NetConnectEnum 1608474SJose.Borrego@Sun.COM * 1618474SJose.Borrego@Sun.COM * List tree connections made to a share on this server or all tree 1628474SJose.Borrego@Sun.COM * connections established from a specific client. Administrator, 1638474SJose.Borrego@Sun.COM * Server Operator, Print Operator or Power User group membership 1648474SJose.Borrego@Sun.COM * is required to use this interface. 1658474SJose.Borrego@Sun.COM * 1668474SJose.Borrego@Sun.COM * There are three information levels: 0, 1, and 50. We don't support 1678474SJose.Borrego@Sun.COM * level 50, which is only used by Windows 9x clients. 1688474SJose.Borrego@Sun.COM * 1698474SJose.Borrego@Sun.COM * It seems Server Manger (srvmgr) only sends workstation as the qualifier 1708474SJose.Borrego@Sun.COM * and the Computer Management Interface on Windows 2000 doesn't request 1718474SJose.Borrego@Sun.COM * a list of connections. 1728474SJose.Borrego@Sun.COM * 1738474SJose.Borrego@Sun.COM * Return Values: 1748474SJose.Borrego@Sun.COM * ERROR_SUCCESS Success 1758474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED Caller does not have access to this call. 1768474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER One of the parameters is invalid. 1778474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL Unknown information level specified. 1788474SJose.Borrego@Sun.COM * ERROR_MORE_DATA Partial date returned, more entries available. 1798474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 1808474SJose.Borrego@Sun.COM * NERR_NetNameNotFound The share qualifier cannot be found. 1818474SJose.Borrego@Sun.COM * NERR_BufTooSmall The supplied buffer is too small. 1828474SJose.Borrego@Sun.COM */ 1838474SJose.Borrego@Sun.COM static int 1848474SJose.Borrego@Sun.COM srvsvc_s_NetConnectEnum(void *arg, ndr_xa_t *mxa) 1858474SJose.Borrego@Sun.COM { 1868474SJose.Borrego@Sun.COM struct mslm_NetConnectEnum *param = arg; 1878474SJose.Borrego@Sun.COM srvsvc_NetConnectInfo0_t *info0; 1888474SJose.Borrego@Sun.COM srvsvc_NetConnectInfo1_t *info1; 1898474SJose.Borrego@Sun.COM char *qualifier; 1908474SJose.Borrego@Sun.COM int qualtype; 1918474SJose.Borrego@Sun.COM DWORD status = ERROR_SUCCESS; 1928474SJose.Borrego@Sun.COM 1938474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa)) { 1948474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetConnectEnum)); 1958474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 1968474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 1978474SJose.Borrego@Sun.COM } 1988474SJose.Borrego@Sun.COM 1998474SJose.Borrego@Sun.COM qualifier = (char *)param->qualifier; 2008474SJose.Borrego@Sun.COM qualtype = srvsvc_netconnect_qualifier(qualifier); 2018474SJose.Borrego@Sun.COM 2028474SJose.Borrego@Sun.COM if (qualtype == SRVSVC_CONNECT_ENUM_NULL) { 2038474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetConnectEnum)); 2048474SJose.Borrego@Sun.COM param->status = NERR_NetNameNotFound; 2058474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 2068474SJose.Borrego@Sun.COM } 2078474SJose.Borrego@Sun.COM 2088474SJose.Borrego@Sun.COM switch (param->info.level) { 2098474SJose.Borrego@Sun.COM case 0: 2108474SJose.Borrego@Sun.COM info0 = NDR_NEW(mxa, srvsvc_NetConnectInfo0_t); 2118474SJose.Borrego@Sun.COM if (info0 == NULL) { 2128474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 2138474SJose.Borrego@Sun.COM break; 2148474SJose.Borrego@Sun.COM } 2158474SJose.Borrego@Sun.COM 2168474SJose.Borrego@Sun.COM bzero(info0, sizeof (srvsvc_NetConnectInfo0_t)); 2178474SJose.Borrego@Sun.COM param->info.ru.info0 = info0; 2188474SJose.Borrego@Sun.COM 2198474SJose.Borrego@Sun.COM status = srvsvc_s_NetConnectEnumLevel0(mxa, info0); 2208474SJose.Borrego@Sun.COM 2218474SJose.Borrego@Sun.COM param->total_entries = info0->entries_read; 2228474SJose.Borrego@Sun.COM param->resume_handle = NULL; 2238474SJose.Borrego@Sun.COM break; 2248474SJose.Borrego@Sun.COM 2258474SJose.Borrego@Sun.COM case 1: 2268474SJose.Borrego@Sun.COM info1 = NDR_NEW(mxa, srvsvc_NetConnectInfo1_t); 2278474SJose.Borrego@Sun.COM if (info1 == NULL) { 2288474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 2298474SJose.Borrego@Sun.COM break; 2308474SJose.Borrego@Sun.COM } 2318474SJose.Borrego@Sun.COM 2328474SJose.Borrego@Sun.COM bzero(info1, sizeof (srvsvc_NetConnectInfo1_t)); 2338474SJose.Borrego@Sun.COM param->info.ru.info1 = info1; 2348474SJose.Borrego@Sun.COM 2358474SJose.Borrego@Sun.COM status = srvsvc_s_NetConnectEnumLevel1(mxa, info1); 2368474SJose.Borrego@Sun.COM 2378474SJose.Borrego@Sun.COM param->total_entries = info1->entries_read; 2388474SJose.Borrego@Sun.COM param->resume_handle = NULL; 2398474SJose.Borrego@Sun.COM break; 2408474SJose.Borrego@Sun.COM 2418474SJose.Borrego@Sun.COM case 50: 2428474SJose.Borrego@Sun.COM status = ERROR_NOT_SUPPORTED; 2438474SJose.Borrego@Sun.COM break; 2448474SJose.Borrego@Sun.COM 2458474SJose.Borrego@Sun.COM default: 2468474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 2478474SJose.Borrego@Sun.COM break; 2488474SJose.Borrego@Sun.COM } 2498474SJose.Borrego@Sun.COM 2508474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 2518474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetConnectEnum)); 2528474SJose.Borrego@Sun.COM 2538474SJose.Borrego@Sun.COM param->status = status; 2548474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 2558474SJose.Borrego@Sun.COM } 2568474SJose.Borrego@Sun.COM 2578474SJose.Borrego@Sun.COM static DWORD 2588474SJose.Borrego@Sun.COM srvsvc_s_NetConnectEnumLevel0(ndr_xa_t *mxa, srvsvc_NetConnectInfo0_t *info0) 2598474SJose.Borrego@Sun.COM { 2608474SJose.Borrego@Sun.COM srvsvc_NetConnectInfoBuf0_t *ci0; 2618474SJose.Borrego@Sun.COM 2628474SJose.Borrego@Sun.COM ci0 = NDR_NEW(mxa, srvsvc_NetConnectInfoBuf0_t); 2638474SJose.Borrego@Sun.COM if (ci0 == NULL) 2648474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 2658474SJose.Borrego@Sun.COM 2668474SJose.Borrego@Sun.COM ci0->coni0_id = 0x17; 2678474SJose.Borrego@Sun.COM 2688474SJose.Borrego@Sun.COM info0->ci0 = ci0; 2698474SJose.Borrego@Sun.COM info0->entries_read = 1; 2708474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 2718474SJose.Borrego@Sun.COM } 2728474SJose.Borrego@Sun.COM 2738474SJose.Borrego@Sun.COM static DWORD 2748474SJose.Borrego@Sun.COM srvsvc_s_NetConnectEnumLevel1(ndr_xa_t *mxa, srvsvc_NetConnectInfo1_t *info1) 2758474SJose.Borrego@Sun.COM { 2768474SJose.Borrego@Sun.COM srvsvc_NetConnectInfoBuf1_t *ci1; 2778474SJose.Borrego@Sun.COM 2788474SJose.Borrego@Sun.COM ci1 = NDR_NEW(mxa, srvsvc_NetConnectInfoBuf1_t); 2798474SJose.Borrego@Sun.COM if (ci1 == NULL) 2808474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 2818474SJose.Borrego@Sun.COM 2828474SJose.Borrego@Sun.COM ci1->coni1_id = 0x17; 2838474SJose.Borrego@Sun.COM ci1->coni1_type = STYPE_IPC; 2848474SJose.Borrego@Sun.COM ci1->coni1_num_opens = 1; 2858474SJose.Borrego@Sun.COM ci1->coni1_num_users = 1; 2868474SJose.Borrego@Sun.COM ci1->coni1_time = 16; 2878474SJose.Borrego@Sun.COM ci1->coni1_username = (uint8_t *)NDR_STRDUP(mxa, "Administrator"); 2888474SJose.Borrego@Sun.COM ci1->coni1_netname = (uint8_t *)NDR_STRDUP(mxa, "IPC$"); 2898474SJose.Borrego@Sun.COM 2908474SJose.Borrego@Sun.COM info1->ci1 = ci1; 2918474SJose.Borrego@Sun.COM info1->entries_read = 1; 2928474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 2938474SJose.Borrego@Sun.COM } 2948474SJose.Borrego@Sun.COM 2958474SJose.Borrego@Sun.COM /* 2968474SJose.Borrego@Sun.COM * srvsvc_netconnect_qualifier 2978474SJose.Borrego@Sun.COM * 2988474SJose.Borrego@Sun.COM * The qualifier is a string that specifies a share name or computer name 2998474SJose.Borrego@Sun.COM * for the connections of interest. If it is a share name then all the 3008474SJose.Borrego@Sun.COM * connections made to that share name are listed. If it is a computer 3018474SJose.Borrego@Sun.COM * name (it starts with two backslash characters), then NetConnectEnum 3028474SJose.Borrego@Sun.COM * lists all connections made from that computer to the specified server. 3038474SJose.Borrego@Sun.COM */ 3048474SJose.Borrego@Sun.COM static int 3058474SJose.Borrego@Sun.COM srvsvc_netconnect_qualifier(const char *qualifier) 3068474SJose.Borrego@Sun.COM { 3078474SJose.Borrego@Sun.COM if (qualifier == NULL || *qualifier == '\0') 3088474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_NULL); 3098474SJose.Borrego@Sun.COM 3108474SJose.Borrego@Sun.COM if (strlen(qualifier) > MAXHOSTNAMELEN) 3118474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_NULL); 3128474SJose.Borrego@Sun.COM 3138474SJose.Borrego@Sun.COM if (qualifier[0] == '\\' && qualifier[1] == '\\') { 3148474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_WKSTN); 3158474SJose.Borrego@Sun.COM } else { 3168474SJose.Borrego@Sun.COM if (!smb_shr_exists((char *)qualifier)) 3178474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_NULL); 3188474SJose.Borrego@Sun.COM 3198474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_SHARE); 3208474SJose.Borrego@Sun.COM } 3218474SJose.Borrego@Sun.COM } 3228474SJose.Borrego@Sun.COM 3238474SJose.Borrego@Sun.COM /* 3248474SJose.Borrego@Sun.COM * srvsvc_s_NetFileEnum 3258474SJose.Borrego@Sun.COM * 3268474SJose.Borrego@Sun.COM * Return information on open files or named pipes. Only members of the 3278474SJose.Borrego@Sun.COM * Administrators or Server Operators local groups are allowed to make 3288474SJose.Borrego@Sun.COM * this call. Currently, we only support Administrators. 3298474SJose.Borrego@Sun.COM * 3308474SJose.Borrego@Sun.COM * If basepath is null, all open resources are enumerated. If basepath 3318474SJose.Borrego@Sun.COM * is non-null, only resources that have basepath as a prefix should 3328474SJose.Borrego@Sun.COM * be returned. 3338474SJose.Borrego@Sun.COM * 3348474SJose.Borrego@Sun.COM * If username is specified (non-null), only files opened by username 3358474SJose.Borrego@Sun.COM * should be returned. 3368474SJose.Borrego@Sun.COM * 3378474SJose.Borrego@Sun.COM * Notes: 3388474SJose.Borrego@Sun.COM * 1. We don't validate the servername because we would have to check 3398474SJose.Borrego@Sun.COM * all primary IPs and the ROI seems unlikely to be worth it. 3408474SJose.Borrego@Sun.COM * 2. Both basepath and username are currently ignored because both 3418474SJose.Borrego@Sun.COM * Server Manger (NT 4.0) and CMI (Windows 2000) always set them to null. 3428474SJose.Borrego@Sun.COM * 3438474SJose.Borrego@Sun.COM * The level of information requested may be one of: 3448474SJose.Borrego@Sun.COM * 3458474SJose.Borrego@Sun.COM * 2 Return the file identification number. 3468474SJose.Borrego@Sun.COM * This level is not supported on Windows Me/98/95. 3478474SJose.Borrego@Sun.COM * 3488474SJose.Borrego@Sun.COM * 3 Return information about the file. 3498474SJose.Borrego@Sun.COM * This level is not supported on Windows Me/98/95. 3508474SJose.Borrego@Sun.COM * 3518474SJose.Borrego@Sun.COM * 50 Windows Me/98/95: Return information about the file. 3528474SJose.Borrego@Sun.COM * 3538474SJose.Borrego@Sun.COM * Note: 3548474SJose.Borrego@Sun.COM * If pref_max_len is unlimited and resume_handle is null, the client 3558474SJose.Borrego@Sun.COM * expects to receive all data in a single call. 3568474SJose.Borrego@Sun.COM * If we are unable to do fit all data in a single response, we would 3578474SJose.Borrego@Sun.COM * normally return ERROR_MORE_DATA with a partial list. 3588474SJose.Borrego@Sun.COM * 3598474SJose.Borrego@Sun.COM * Unfortunately, when both of these conditions occur, Server Manager 3608474SJose.Borrego@Sun.COM * pops up an error box with the message "more data available" and 3618474SJose.Borrego@Sun.COM * doesn't display any of the returned data. In this case, it is 3628474SJose.Borrego@Sun.COM * probably better to return ERROR_SUCCESS with the partial list. 3638474SJose.Borrego@Sun.COM * Windows 2000 doesn't have this problem because it always sends a 3648474SJose.Borrego@Sun.COM * non-null resume_handle. 3658474SJose.Borrego@Sun.COM * 3668474SJose.Borrego@Sun.COM * Return Values: 3678474SJose.Borrego@Sun.COM * ERROR_SUCCESS Success 3688474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED Caller does not have access to this call. 3698474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER One of the parameters is invalid. 3708474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL Unknown information level specified. 3718474SJose.Borrego@Sun.COM * ERROR_MORE_DATA Partial date returned, more entries available. 3728474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 3738474SJose.Borrego@Sun.COM * NERR_BufTooSmall The supplied buffer is too small. 3748474SJose.Borrego@Sun.COM */ 3758474SJose.Borrego@Sun.COM static int 3768474SJose.Borrego@Sun.COM srvsvc_s_NetFileEnum(void *arg, ndr_xa_t *mxa) 3778474SJose.Borrego@Sun.COM { 3788474SJose.Borrego@Sun.COM struct mslm_NetFileEnum *param = arg; 3798474SJose.Borrego@Sun.COM DWORD status; 3808474SJose.Borrego@Sun.COM 3818474SJose.Borrego@Sun.COM if (!ndr_is_admin(mxa)) { 3828474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetFileEnum)); 3838474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 3848474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 3858474SJose.Borrego@Sun.COM } 3868474SJose.Borrego@Sun.COM 3878474SJose.Borrego@Sun.COM switch (param->info.switch_value) { 3888474SJose.Borrego@Sun.COM case 2: 3898474SJose.Borrego@Sun.COM status = srvsvc_NetFileEnum2(mxa, param); 3908474SJose.Borrego@Sun.COM break; 3918474SJose.Borrego@Sun.COM 3928474SJose.Borrego@Sun.COM case 3: 3938474SJose.Borrego@Sun.COM status = srvsvc_NetFileEnum3(mxa, param); 3948474SJose.Borrego@Sun.COM break; 3958474SJose.Borrego@Sun.COM 3968474SJose.Borrego@Sun.COM case 50: 3978474SJose.Borrego@Sun.COM status = ERROR_NOT_SUPPORTED; 3988474SJose.Borrego@Sun.COM break; 3998474SJose.Borrego@Sun.COM 4008474SJose.Borrego@Sun.COM default: 4018474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 4028474SJose.Borrego@Sun.COM break; 4038474SJose.Borrego@Sun.COM } 4048474SJose.Borrego@Sun.COM 4058474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) { 4068474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetFileEnum)); 4078474SJose.Borrego@Sun.COM param->status = status; 4088474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 4098474SJose.Borrego@Sun.COM } 4108474SJose.Borrego@Sun.COM 4118474SJose.Borrego@Sun.COM if (param->resume_handle) 4128474SJose.Borrego@Sun.COM *param->resume_handle = 0; 4138474SJose.Borrego@Sun.COM 4148474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 4158474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 4168474SJose.Borrego@Sun.COM } 4178474SJose.Borrego@Sun.COM 4188474SJose.Borrego@Sun.COM /* 4198474SJose.Borrego@Sun.COM * Build level 2 file information. 4208474SJose.Borrego@Sun.COM * 4218474SJose.Borrego@Sun.COM * On success, the caller expects that the info2, fi2 and entries_read 4228474SJose.Borrego@Sun.COM * fields have been set up. 4238474SJose.Borrego@Sun.COM */ 4248474SJose.Borrego@Sun.COM static DWORD 4258474SJose.Borrego@Sun.COM srvsvc_NetFileEnum2(ndr_xa_t *mxa, struct mslm_NetFileEnum *param) 4268474SJose.Borrego@Sun.COM { 4278474SJose.Borrego@Sun.COM struct mslm_NetFileInfoBuf2 *fi2; 4288474SJose.Borrego@Sun.COM ndr_pipe_info_t pi; 4298474SJose.Borrego@Sun.COM uint32_t entries_read = 0; 4308474SJose.Borrego@Sun.COM int i; 4318474SJose.Borrego@Sun.COM 4328474SJose.Borrego@Sun.COM param->info.ru.info2 = NDR_NEW(mxa, struct mslm_NetFileInfo2); 4338474SJose.Borrego@Sun.COM if (param->info.ru.info3 == NULL) 4348474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 4358474SJose.Borrego@Sun.COM 4368474SJose.Borrego@Sun.COM fi2 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf2, 128); 4378474SJose.Borrego@Sun.COM if (fi2 == NULL) 4388474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 4398474SJose.Borrego@Sun.COM 4408474SJose.Borrego@Sun.COM param->info.ru.info2->fi2 = fi2; 4418474SJose.Borrego@Sun.COM 4428474SJose.Borrego@Sun.COM for (i = 0; i < 128; ++i) { 4438474SJose.Borrego@Sun.COM if (ndr_pipe_getinfo(i, &pi) == -1) 4448474SJose.Borrego@Sun.COM continue; 4458474SJose.Borrego@Sun.COM 4468474SJose.Borrego@Sun.COM fi2->fi2_id = pi.npi_fid; 4478474SJose.Borrego@Sun.COM 4488474SJose.Borrego@Sun.COM ++entries_read; 4498474SJose.Borrego@Sun.COM ++fi2; 4508474SJose.Borrego@Sun.COM } 4518474SJose.Borrego@Sun.COM 4528474SJose.Borrego@Sun.COM param->info.ru.info2->entries_read = entries_read; 4538474SJose.Borrego@Sun.COM param->total_entries = entries_read; 4548474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 4558474SJose.Borrego@Sun.COM } 4568474SJose.Borrego@Sun.COM 4578474SJose.Borrego@Sun.COM /* 4588474SJose.Borrego@Sun.COM * Build level 3 file information. 4598474SJose.Borrego@Sun.COM * 4608474SJose.Borrego@Sun.COM * On success, the caller expects that the info3, fi3 and entries_read 4618474SJose.Borrego@Sun.COM * fields have been set up. 4628474SJose.Borrego@Sun.COM */ 4638474SJose.Borrego@Sun.COM static DWORD 4648474SJose.Borrego@Sun.COM srvsvc_NetFileEnum3(ndr_xa_t *mxa, struct mslm_NetFileEnum *param) 4658474SJose.Borrego@Sun.COM { 4668474SJose.Borrego@Sun.COM struct mslm_NetFileInfoBuf3 *fi3; 4678474SJose.Borrego@Sun.COM ndr_pipe_info_t pi; 4688474SJose.Borrego@Sun.COM uint32_t entries_read = 0; 4698474SJose.Borrego@Sun.COM int i; 4708474SJose.Borrego@Sun.COM 4718474SJose.Borrego@Sun.COM param->info.ru.info3 = NDR_NEW(mxa, struct mslm_NetFileInfo3); 4728474SJose.Borrego@Sun.COM if (param->info.ru.info3 == NULL) 4738474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 4748474SJose.Borrego@Sun.COM 4758474SJose.Borrego@Sun.COM fi3 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf3, 128); 4768474SJose.Borrego@Sun.COM if (fi3 == NULL) 4778474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 4788474SJose.Borrego@Sun.COM 4798474SJose.Borrego@Sun.COM param->info.ru.info3->fi3 = fi3; 4808474SJose.Borrego@Sun.COM 4818474SJose.Borrego@Sun.COM for (i = 0; i < 128; ++i) { 4828474SJose.Borrego@Sun.COM if (ndr_pipe_getinfo(i, &pi) == -1) 4838474SJose.Borrego@Sun.COM continue; 4848474SJose.Borrego@Sun.COM 4858474SJose.Borrego@Sun.COM fi3->fi3_id = pi.npi_fid; 4868474SJose.Borrego@Sun.COM fi3->fi3_permissions = pi.npi_permissions; 4878474SJose.Borrego@Sun.COM fi3->fi3_num_locks = pi.npi_num_locks; 4888474SJose.Borrego@Sun.COM fi3->fi3_pathname = (uint8_t *) 4898474SJose.Borrego@Sun.COM NDR_STRDUP(mxa, pi.npi_pathname); 4908474SJose.Borrego@Sun.COM fi3->fi3_username = (uint8_t *) 4918474SJose.Borrego@Sun.COM NDR_STRDUP(mxa, pi.npi_username); 4928474SJose.Borrego@Sun.COM 4938474SJose.Borrego@Sun.COM ++entries_read; 4948474SJose.Borrego@Sun.COM ++fi3; 4958474SJose.Borrego@Sun.COM } 4968474SJose.Borrego@Sun.COM 4978474SJose.Borrego@Sun.COM param->info.ru.info3->entries_read = entries_read; 4988474SJose.Borrego@Sun.COM param->total_entries = entries_read; 4998474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 5008474SJose.Borrego@Sun.COM } 5018474SJose.Borrego@Sun.COM 5028474SJose.Borrego@Sun.COM /* 5038474SJose.Borrego@Sun.COM * srvsvc_s_NetFileClose 5048474SJose.Borrego@Sun.COM * 5058474SJose.Borrego@Sun.COM * NetFileClose forces a file to close. This function can be used when 5068474SJose.Borrego@Sun.COM * an error prevents closure by any other means. Use NetFileClose with 5078474SJose.Borrego@Sun.COM * caution because it does not flush data, cached on a client, to the 5088474SJose.Borrego@Sun.COM * file before closing the file. 5098474SJose.Borrego@Sun.COM * 5108474SJose.Borrego@Sun.COM * Return Values 5118474SJose.Borrego@Sun.COM * ERROR_SUCCESS Operation succeeded. 5128474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED Operation denied. 5138474SJose.Borrego@Sun.COM * NERR_FileIdNotFound No open file with the specified id. 5148474SJose.Borrego@Sun.COM * 5158474SJose.Borrego@Sun.COM * Note: MSDN suggests that the error code should be ERROR_FILE_NOT_FOUND 5168474SJose.Borrego@Sun.COM * but network captures using NT show NERR_FileIdNotFound. 5178474SJose.Borrego@Sun.COM * The NetFileClose2 MSDN page has the right error code. 5188474SJose.Borrego@Sun.COM */ 5198474SJose.Borrego@Sun.COM static int 5208474SJose.Borrego@Sun.COM srvsvc_s_NetFileClose(void *arg, ndr_xa_t *mxa) 5218474SJose.Borrego@Sun.COM { 5228474SJose.Borrego@Sun.COM struct mslm_NetFileClose *param = arg; 5238474SJose.Borrego@Sun.COM 5248474SJose.Borrego@Sun.COM if (!ndr_is_admin(mxa)) { 5258474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetFileClose)); 5268474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 5278474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5288474SJose.Borrego@Sun.COM } 5298474SJose.Borrego@Sun.COM 5308474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetFileClose)); 5318474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 5328474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5338474SJose.Borrego@Sun.COM } 5348474SJose.Borrego@Sun.COM 5358474SJose.Borrego@Sun.COM 5368474SJose.Borrego@Sun.COM /* 5378474SJose.Borrego@Sun.COM * srvsvc_s_NetShareGetInfo 5388474SJose.Borrego@Sun.COM * 5398474SJose.Borrego@Sun.COM * Returns Win32 error codes. 5408474SJose.Borrego@Sun.COM */ 5418474SJose.Borrego@Sun.COM static int 5428474SJose.Borrego@Sun.COM srvsvc_s_NetShareGetInfo(void *arg, ndr_xa_t *mxa) 5438474SJose.Borrego@Sun.COM { 5448474SJose.Borrego@Sun.COM struct mlsm_NetShareGetInfo *param = arg; 5458474SJose.Borrego@Sun.COM struct mslm_NetShareGetInfo0 *info0; 5468474SJose.Borrego@Sun.COM struct mslm_NetShareGetInfo1 *info1; 5478474SJose.Borrego@Sun.COM struct mslm_NetShareGetInfo2 *info2; 5488474SJose.Borrego@Sun.COM struct mslm_NetShareGetInfo501 *info501; 5498474SJose.Borrego@Sun.COM struct mslm_NetShareGetInfo502 *info502; 5508474SJose.Borrego@Sun.COM struct mslm_NetShareGetInfo1004 *info1004; 5518474SJose.Borrego@Sun.COM struct mslm_NetShareGetInfo1005 *info1005; 5528474SJose.Borrego@Sun.COM struct mslm_NetShareGetInfo1006 *info1006; 5538474SJose.Borrego@Sun.COM smb_share_t si; 5548474SJose.Borrego@Sun.COM DWORD status; 5558474SJose.Borrego@Sun.COM 5568474SJose.Borrego@Sun.COM status = smb_shr_get((char *)param->netname, &si); 5578474SJose.Borrego@Sun.COM if (status != NERR_Success) { 5588474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mlsm_NetShareGetInfo)); 5598474SJose.Borrego@Sun.COM param->status = status; 5608474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5618474SJose.Borrego@Sun.COM } 5628474SJose.Borrego@Sun.COM 5638474SJose.Borrego@Sun.COM switch (param->level) { 5648474SJose.Borrego@Sun.COM case 0: 5658474SJose.Borrego@Sun.COM info0 = NDR_NEW(mxa, struct mslm_NetShareGetInfo0); 5668474SJose.Borrego@Sun.COM if (info0 == NULL) { 5678474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 5688474SJose.Borrego@Sun.COM break; 5698474SJose.Borrego@Sun.COM } 5708474SJose.Borrego@Sun.COM 5718474SJose.Borrego@Sun.COM info0->shi0_netname 5728474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, si.shr_name); 5738474SJose.Borrego@Sun.COM if (info0->shi0_netname == NULL) { 5748474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 5758474SJose.Borrego@Sun.COM break; 5768474SJose.Borrego@Sun.COM } 5778474SJose.Borrego@Sun.COM 5788474SJose.Borrego@Sun.COM param->result.ru.info0 = info0; 5798474SJose.Borrego@Sun.COM break; 5808474SJose.Borrego@Sun.COM 5818474SJose.Borrego@Sun.COM case 1: 5828474SJose.Borrego@Sun.COM info1 = NDR_NEW(mxa, struct mslm_NetShareGetInfo1); 5838474SJose.Borrego@Sun.COM if (info1 == NULL) { 5848474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 5858474SJose.Borrego@Sun.COM break; 5868474SJose.Borrego@Sun.COM } 5878474SJose.Borrego@Sun.COM 5888474SJose.Borrego@Sun.COM info1->shi1_netname = (uint8_t *)NDR_STRDUP(mxa, si.shr_name); 5898474SJose.Borrego@Sun.COM info1->shi1_comment = (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt); 5908474SJose.Borrego@Sun.COM if (info1->shi1_netname == NULL || 5918474SJose.Borrego@Sun.COM info1->shi1_comment == NULL) { 5928474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 5938474SJose.Borrego@Sun.COM break; 5948474SJose.Borrego@Sun.COM } 5958474SJose.Borrego@Sun.COM 5968474SJose.Borrego@Sun.COM info1->shi1_type = si.shr_type; 5978474SJose.Borrego@Sun.COM param->result.ru.info1 = info1; 5988474SJose.Borrego@Sun.COM break; 5998474SJose.Borrego@Sun.COM 6008474SJose.Borrego@Sun.COM case 2: 6018474SJose.Borrego@Sun.COM info2 = NDR_NEW(mxa, struct mslm_NetShareGetInfo2); 6028474SJose.Borrego@Sun.COM if (info2 == NULL) { 6038474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 6048474SJose.Borrego@Sun.COM break; 6058474SJose.Borrego@Sun.COM } 6068474SJose.Borrego@Sun.COM 6078474SJose.Borrego@Sun.COM info2->shi2_netname = (uint8_t *)NDR_STRDUP(mxa, si.shr_name); 6088474SJose.Borrego@Sun.COM info2->shi2_comment = (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt); 6098474SJose.Borrego@Sun.COM if (info2->shi2_netname == NULL || 6108474SJose.Borrego@Sun.COM info2->shi2_comment == NULL) { 6118474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 6128474SJose.Borrego@Sun.COM break; 6138474SJose.Borrego@Sun.COM } 6148474SJose.Borrego@Sun.COM 6158474SJose.Borrego@Sun.COM info2->shi2_path = 6168474SJose.Borrego@Sun.COM (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path); 6178474SJose.Borrego@Sun.COM info2->shi2_passwd = 0; 6188474SJose.Borrego@Sun.COM info2->shi2_type = si.shr_type; 6198474SJose.Borrego@Sun.COM info2->shi2_permissions = 0; 6208474SJose.Borrego@Sun.COM info2->shi2_max_uses = SHI_USES_UNLIMITED; 6218474SJose.Borrego@Sun.COM info2->shi2_current_uses = 0; 6228474SJose.Borrego@Sun.COM param->result.ru.info2 = info2; 6238474SJose.Borrego@Sun.COM break; 6248474SJose.Borrego@Sun.COM 6258474SJose.Borrego@Sun.COM case 1004: 6268474SJose.Borrego@Sun.COM info1004 = NDR_NEW(mxa, struct mslm_NetShareGetInfo1004); 6278474SJose.Borrego@Sun.COM if (info1004 == NULL) { 6288474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 6298474SJose.Borrego@Sun.COM break; 6308474SJose.Borrego@Sun.COM } 6318474SJose.Borrego@Sun.COM 6328474SJose.Borrego@Sun.COM info1004->shi1004_comment = 6338474SJose.Borrego@Sun.COM (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt); 6348474SJose.Borrego@Sun.COM if (info1004->shi1004_comment == NULL) 6358474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 6368474SJose.Borrego@Sun.COM break; 6378474SJose.Borrego@Sun.COM 6388474SJose.Borrego@Sun.COM case 1005: 6398474SJose.Borrego@Sun.COM info1005 = NDR_NEW(mxa, struct mslm_NetShareGetInfo1005); 6408474SJose.Borrego@Sun.COM if (info1005 == NULL) { 6418474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 6428474SJose.Borrego@Sun.COM break; 6438474SJose.Borrego@Sun.COM } 6448474SJose.Borrego@Sun.COM 6458474SJose.Borrego@Sun.COM info1005->shi1005_flags = 0; 6468474SJose.Borrego@Sun.COM 6478474SJose.Borrego@Sun.COM switch (si.shr_flags & SMB_SHRF_CSC_MASK) { 6488474SJose.Borrego@Sun.COM case SMB_SHRF_CSC_DISABLED: 6498474SJose.Borrego@Sun.COM info1005->shi1005_flags |= CSC_CACHE_NONE; 6508474SJose.Borrego@Sun.COM break; 6518474SJose.Borrego@Sun.COM case SMB_SHRF_CSC_AUTO: 6528474SJose.Borrego@Sun.COM info1005->shi1005_flags |= CSC_CACHE_AUTO_REINT; 6538474SJose.Borrego@Sun.COM break; 6548474SJose.Borrego@Sun.COM case SMB_SHRF_CSC_VDO: 6558474SJose.Borrego@Sun.COM info1005->shi1005_flags |= CSC_CACHE_VDO; 6568474SJose.Borrego@Sun.COM break; 6578474SJose.Borrego@Sun.COM case SMB_SHRF_CSC_MANUAL: 6588474SJose.Borrego@Sun.COM default: 6598474SJose.Borrego@Sun.COM /* 6608474SJose.Borrego@Sun.COM * Default to CSC_CACHE_MANUAL_REINT. 6618474SJose.Borrego@Sun.COM */ 6628474SJose.Borrego@Sun.COM break; 6638474SJose.Borrego@Sun.COM } 6648474SJose.Borrego@Sun.COM 6658474SJose.Borrego@Sun.COM param->result.ru.info1005 = info1005; 6668474SJose.Borrego@Sun.COM break; 6678474SJose.Borrego@Sun.COM 6688474SJose.Borrego@Sun.COM case 1006: 6698474SJose.Borrego@Sun.COM info1006 = NDR_NEW(mxa, struct mslm_NetShareGetInfo1006); 6708474SJose.Borrego@Sun.COM if (info1006 == NULL) { 6718474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 6728474SJose.Borrego@Sun.COM break; 6738474SJose.Borrego@Sun.COM } 6748474SJose.Borrego@Sun.COM info1006->shi1006_max_uses = SHI_USES_UNLIMITED; 6758474SJose.Borrego@Sun.COM param->result.ru.info1006 = info1006; 6768474SJose.Borrego@Sun.COM break; 6778474SJose.Borrego@Sun.COM 6788474SJose.Borrego@Sun.COM case 501: 6798474SJose.Borrego@Sun.COM /* 6808474SJose.Borrego@Sun.COM * Level 501 provides level 1 information. 6818474SJose.Borrego@Sun.COM */ 6828474SJose.Borrego@Sun.COM info501 = NDR_NEW(mxa, struct mslm_NetShareGetInfo501); 6838474SJose.Borrego@Sun.COM if (info501 == NULL) { 6848474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 6858474SJose.Borrego@Sun.COM break; 6868474SJose.Borrego@Sun.COM } 6878474SJose.Borrego@Sun.COM 6888474SJose.Borrego@Sun.COM info501->shi501_netname = 6898474SJose.Borrego@Sun.COM (uint8_t *)NDR_STRDUP(mxa, si.shr_name); 6908474SJose.Borrego@Sun.COM info501->shi501_comment = 6918474SJose.Borrego@Sun.COM (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt); 6928474SJose.Borrego@Sun.COM if (info501->shi501_netname == NULL || 6938474SJose.Borrego@Sun.COM info501->shi501_comment == NULL) { 6948474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 6958474SJose.Borrego@Sun.COM break; 6968474SJose.Borrego@Sun.COM } 6978474SJose.Borrego@Sun.COM 6988474SJose.Borrego@Sun.COM info501->shi501_type = si.shr_type; 6998474SJose.Borrego@Sun.COM info501->shi501_reserved = 0; 7008474SJose.Borrego@Sun.COM param->result.ru.info501 = info501; 7018474SJose.Borrego@Sun.COM break; 7028474SJose.Borrego@Sun.COM 7038474SJose.Borrego@Sun.COM case 502: 7048474SJose.Borrego@Sun.COM /* 7058474SJose.Borrego@Sun.COM * Level 502 provides level 2 information plus a 7068474SJose.Borrego@Sun.COM * security descriptor. We don't support security 7078474SJose.Borrego@Sun.COM * descriptors on shares yet. 7088474SJose.Borrego@Sun.COM */ 7098474SJose.Borrego@Sun.COM info502 = NDR_NEW(mxa, struct mslm_NetShareGetInfo502); 7108474SJose.Borrego@Sun.COM if (info502 == NULL) { 7118474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 7128474SJose.Borrego@Sun.COM break; 7138474SJose.Borrego@Sun.COM } 7148474SJose.Borrego@Sun.COM 7158474SJose.Borrego@Sun.COM info502->shi502_netname = 7168474SJose.Borrego@Sun.COM (uint8_t *)NDR_STRDUP(mxa, si.shr_name); 7178474SJose.Borrego@Sun.COM info502->shi502_comment = 7188474SJose.Borrego@Sun.COM (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt); 7198474SJose.Borrego@Sun.COM if (info502->shi502_netname == NULL || 7208474SJose.Borrego@Sun.COM info502->shi502_comment == NULL) { 7218474SJose.Borrego@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 7228474SJose.Borrego@Sun.COM break; 7238474SJose.Borrego@Sun.COM } 7248474SJose.Borrego@Sun.COM 7258474SJose.Borrego@Sun.COM info502->shi502_path = 7268474SJose.Borrego@Sun.COM (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path); 7278474SJose.Borrego@Sun.COM info502->shi502_passwd = 0; 7288474SJose.Borrego@Sun.COM info502->shi502_type = si.shr_type; 7298474SJose.Borrego@Sun.COM info502->shi502_permissions = 0; 7308474SJose.Borrego@Sun.COM info502->shi502_max_uses = SHI_USES_UNLIMITED; 7318474SJose.Borrego@Sun.COM info502->shi502_current_uses = 0; 7328474SJose.Borrego@Sun.COM info502->shi502_reserved = 0; 7338474SJose.Borrego@Sun.COM info502->shi502_security_descriptor = 0; 7348474SJose.Borrego@Sun.COM param->result.ru.info502 = info502; 7358474SJose.Borrego@Sun.COM break; 7368474SJose.Borrego@Sun.COM 7378474SJose.Borrego@Sun.COM default: 7388474SJose.Borrego@Sun.COM status = ERROR_ACCESS_DENIED; 7398474SJose.Borrego@Sun.COM break; 7408474SJose.Borrego@Sun.COM } 7418474SJose.Borrego@Sun.COM 7428474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 7438474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mlsm_NetShareGetInfo)); 7448474SJose.Borrego@Sun.COM else 7458474SJose.Borrego@Sun.COM param->result.switch_value = param->level; 7468474SJose.Borrego@Sun.COM 7478474SJose.Borrego@Sun.COM param->status = status; 7488474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 7498474SJose.Borrego@Sun.COM } 7508474SJose.Borrego@Sun.COM 7518474SJose.Borrego@Sun.COM 7528474SJose.Borrego@Sun.COM /* 7538474SJose.Borrego@Sun.COM * srvsvc_s_NetShareSetInfo 7548474SJose.Borrego@Sun.COM * 7558474SJose.Borrego@Sun.COM * This call is made by SrvMgr to set share information. 7568474SJose.Borrego@Sun.COM * Always returns ERROR_ACCESS_DENIED for now. 7578474SJose.Borrego@Sun.COM * 7588474SJose.Borrego@Sun.COM * Returns Win32 error codes. 7598474SJose.Borrego@Sun.COM */ 7608474SJose.Borrego@Sun.COM static int 7618474SJose.Borrego@Sun.COM srvsvc_s_NetShareSetInfo(void *arg, ndr_xa_t *mxa) 7628474SJose.Borrego@Sun.COM { 7638474SJose.Borrego@Sun.COM struct mlsm_NetShareSetInfo *param = arg; 7648474SJose.Borrego@Sun.COM 7658474SJose.Borrego@Sun.COM (void) memset(param, 0, sizeof (struct mlsm_NetShareSetInfo)); 7668474SJose.Borrego@Sun.COM param->parm_err_ptr = (DWORD)(uintptr_t)NDR_MALLOC(mxa, 7678474SJose.Borrego@Sun.COM sizeof (DWORD)); 7688474SJose.Borrego@Sun.COM param->parm_err = 0; 7698474SJose.Borrego@Sun.COM 7708474SJose.Borrego@Sun.COM if (!smb_config_getbool(SMB_CI_SRVSVC_SHRSET_ENABLE)) 7718474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 7728474SJose.Borrego@Sun.COM else 7738474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 7748474SJose.Borrego@Sun.COM 7758474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 7768474SJose.Borrego@Sun.COM } 7778474SJose.Borrego@Sun.COM 7788474SJose.Borrego@Sun.COM /* 7798474SJose.Borrego@Sun.COM * srvsvc_s_NetSessionEnum 7808474SJose.Borrego@Sun.COM * 7818474SJose.Borrego@Sun.COM * Level 1 request is made by (Server Manager (srvmgr) on NT Server when 7828474SJose.Borrego@Sun.COM * the user info icon is selected. 7838474SJose.Borrego@Sun.COM * 7848474SJose.Borrego@Sun.COM * On success, the return value is NERR_Success. 7858474SJose.Borrego@Sun.COM * On error, the return value can be one of the following error codes: 7868474SJose.Borrego@Sun.COM * 7878474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED The user does not have access to the requested 7888474SJose.Borrego@Sun.COM * information. 7898474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL The value specified for the level is invalid. 7908474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER The specified parameter is invalid. 7918474SJose.Borrego@Sun.COM * ERROR_MORE_DATA More entries are available. Specify a large 7928474SJose.Borrego@Sun.COM * enough buffer to receive all entries. 7938474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 7948474SJose.Borrego@Sun.COM * NERR_ClientNameNotFound A session does not exist with the computer name. 7958474SJose.Borrego@Sun.COM * NERR_InvalidComputer The computer name is invalid. 7968474SJose.Borrego@Sun.COM * NERR_UserNotFound The user name could not be found. 7978474SJose.Borrego@Sun.COM */ 7988474SJose.Borrego@Sun.COM static int 7998474SJose.Borrego@Sun.COM srvsvc_s_NetSessionEnum(void *arg, ndr_xa_t *mxa) 8008474SJose.Borrego@Sun.COM { 8018474SJose.Borrego@Sun.COM struct mslm_NetSessionEnum *param = arg; 8028474SJose.Borrego@Sun.COM struct mslm_infonres *infonres; 8038474SJose.Borrego@Sun.COM DWORD status; 8048474SJose.Borrego@Sun.COM DWORD n_sessions; 8058474SJose.Borrego@Sun.COM 8068474SJose.Borrego@Sun.COM infonres = NDR_NEW(mxa, struct mslm_infonres); 8078474SJose.Borrego@Sun.COM if (infonres == NULL) { 8088474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetSessionEnum)); 8098474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 8108474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8118474SJose.Borrego@Sun.COM } 8128474SJose.Borrego@Sun.COM 8138474SJose.Borrego@Sun.COM infonres->entriesread = 0; 8148474SJose.Borrego@Sun.COM infonres->entries = NULL; 8158474SJose.Borrego@Sun.COM param->result.level = param->level; 8168474SJose.Borrego@Sun.COM param->result.bufptr.p = infonres; 8178474SJose.Borrego@Sun.COM param->total_entries = 0; 8188474SJose.Borrego@Sun.COM param->resume_handle = NULL; 8198474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 8208474SJose.Borrego@Sun.COM 8218474SJose.Borrego@Sun.COM if ((n_sessions = (DWORD) mlsvc_get_num_users()) == 0) 8228474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8238474SJose.Borrego@Sun.COM 8248474SJose.Borrego@Sun.COM switch (param->level) { 8258474SJose.Borrego@Sun.COM case 0: 8268474SJose.Borrego@Sun.COM status = mlsvc_NetSessionEnumLevel0(infonres, n_sessions, mxa); 8278474SJose.Borrego@Sun.COM break; 8288474SJose.Borrego@Sun.COM 8298474SJose.Borrego@Sun.COM case 1: 8308474SJose.Borrego@Sun.COM status = mlsvc_NetSessionEnumLevel1(infonres, n_sessions, mxa); 8318474SJose.Borrego@Sun.COM break; 8328474SJose.Borrego@Sun.COM 8338474SJose.Borrego@Sun.COM default: 8348474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 8358474SJose.Borrego@Sun.COM break; 8368474SJose.Borrego@Sun.COM } 8378474SJose.Borrego@Sun.COM 8388474SJose.Borrego@Sun.COM if (status != 0) { 8398474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetSessionEnum)); 8408474SJose.Borrego@Sun.COM param->status = status; 8418474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8428474SJose.Borrego@Sun.COM } 8438474SJose.Borrego@Sun.COM 8448474SJose.Borrego@Sun.COM param->total_entries = infonres->entriesread; 8458474SJose.Borrego@Sun.COM param->status = status; 8468474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8478474SJose.Borrego@Sun.COM } 8488474SJose.Borrego@Sun.COM 8498474SJose.Borrego@Sun.COM /* 8508474SJose.Borrego@Sun.COM * mlsvc_NetSessionEnumLevel0 8518474SJose.Borrego@Sun.COM * 8528474SJose.Borrego@Sun.COM * Build the level 0 session information. 8538474SJose.Borrego@Sun.COM */ 8548474SJose.Borrego@Sun.COM static DWORD 8558474SJose.Borrego@Sun.COM mlsvc_NetSessionEnumLevel0(struct mslm_infonres *infonres, DWORD n_sessions, 8568474SJose.Borrego@Sun.COM ndr_xa_t *mxa) 8578474SJose.Borrego@Sun.COM { 8588474SJose.Borrego@Sun.COM struct mslm_SESSION_INFO_0 *info0; 8598474SJose.Borrego@Sun.COM smb_dr_ulist_t *ulist; 8608474SJose.Borrego@Sun.COM smb_opipe_context_t *user; 8618474SJose.Borrego@Sun.COM char *workstation; 862*8670SJose.Borrego@Sun.COM char ipaddr_buf[INET6_ADDRSTRLEN]; 8638474SJose.Borrego@Sun.COM int n_users; 8648474SJose.Borrego@Sun.COM int offset = 0; 8658474SJose.Borrego@Sun.COM int i; 8668474SJose.Borrego@Sun.COM 8678474SJose.Borrego@Sun.COM if ((ulist = malloc(sizeof (smb_dr_ulist_t))) == NULL) 8688474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 8698474SJose.Borrego@Sun.COM 8708474SJose.Borrego@Sun.COM if ((n_users = mlsvc_get_user_list(offset, ulist)) == 0) { 8718474SJose.Borrego@Sun.COM smb_dr_ulist_free(ulist); 8728474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 8738474SJose.Borrego@Sun.COM } 8748474SJose.Borrego@Sun.COM 8758474SJose.Borrego@Sun.COM if (n_users < n_sessions) 8768474SJose.Borrego@Sun.COM n_sessions = n_users; 8778474SJose.Borrego@Sun.COM 8788474SJose.Borrego@Sun.COM info0 = NDR_NEWN(mxa, struct mslm_SESSION_INFO_0, n_sessions); 8798474SJose.Borrego@Sun.COM if (info0 == NULL) { 8808474SJose.Borrego@Sun.COM smb_dr_ulist_free(ulist); 8818474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 8828474SJose.Borrego@Sun.COM } 8838474SJose.Borrego@Sun.COM 8848474SJose.Borrego@Sun.COM for (i = 0; i < n_sessions; ++i) { 8858474SJose.Borrego@Sun.COM user = &ulist->dul_users[i]; 8868474SJose.Borrego@Sun.COM 8878474SJose.Borrego@Sun.COM workstation = user->oc_workstation; 8888474SJose.Borrego@Sun.COM if (workstation == NULL || *workstation == '\0') { 889*8670SJose.Borrego@Sun.COM (void) smb_inet_ntop(&user->oc_ipaddr, 890*8670SJose.Borrego@Sun.COM ipaddr_buf, SMB_IPSTRLEN(user->oc_ipaddr.a_family)); 8918474SJose.Borrego@Sun.COM workstation = ipaddr_buf; 8928474SJose.Borrego@Sun.COM } 8938474SJose.Borrego@Sun.COM 8948474SJose.Borrego@Sun.COM info0[i].sesi0_cname = NDR_STRDUP(mxa, workstation); 8958474SJose.Borrego@Sun.COM if (info0[i].sesi0_cname == NULL) { 8968474SJose.Borrego@Sun.COM smb_dr_ulist_free(ulist); 8978474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 8988474SJose.Borrego@Sun.COM } 8998474SJose.Borrego@Sun.COM } 9008474SJose.Borrego@Sun.COM 9018474SJose.Borrego@Sun.COM smb_dr_ulist_free(ulist); 9028474SJose.Borrego@Sun.COM infonres->entriesread = n_sessions; 9038474SJose.Borrego@Sun.COM infonres->entries = info0; 9048474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 9058474SJose.Borrego@Sun.COM } 9068474SJose.Borrego@Sun.COM 9078474SJose.Borrego@Sun.COM /* 9088474SJose.Borrego@Sun.COM * mlsvc_NetSessionEnumLevel1 9098474SJose.Borrego@Sun.COM * 9108474SJose.Borrego@Sun.COM * Build the level 1 session information. 9118474SJose.Borrego@Sun.COM */ 9128474SJose.Borrego@Sun.COM static DWORD 9138474SJose.Borrego@Sun.COM mlsvc_NetSessionEnumLevel1(struct mslm_infonres *infonres, DWORD n_sessions, 9148474SJose.Borrego@Sun.COM ndr_xa_t *mxa) 9158474SJose.Borrego@Sun.COM { 9168474SJose.Borrego@Sun.COM struct mslm_SESSION_INFO_1 *info1; 9178474SJose.Borrego@Sun.COM smb_dr_ulist_t *ulist; 9188474SJose.Borrego@Sun.COM smb_opipe_context_t *user; 9198474SJose.Borrego@Sun.COM char *workstation; 9208474SJose.Borrego@Sun.COM char account[MAXNAMELEN]; 921*8670SJose.Borrego@Sun.COM char ipaddr_buf[INET6_ADDRSTRLEN]; 9228474SJose.Borrego@Sun.COM int n_users; 9238474SJose.Borrego@Sun.COM int offset = 0; 9248474SJose.Borrego@Sun.COM int i; 9258474SJose.Borrego@Sun.COM 9268474SJose.Borrego@Sun.COM if ((ulist = malloc(sizeof (smb_dr_ulist_t))) == NULL) 9278474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 9288474SJose.Borrego@Sun.COM 9298474SJose.Borrego@Sun.COM if ((n_users = mlsvc_get_user_list(offset, ulist)) == 0) { 9308474SJose.Borrego@Sun.COM smb_dr_ulist_free(ulist); 9318474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 9328474SJose.Borrego@Sun.COM } 9338474SJose.Borrego@Sun.COM 9348474SJose.Borrego@Sun.COM if (n_users < n_sessions) 9358474SJose.Borrego@Sun.COM n_sessions = n_users; 9368474SJose.Borrego@Sun.COM 9378474SJose.Borrego@Sun.COM info1 = NDR_NEWN(mxa, struct mslm_SESSION_INFO_1, n_sessions); 9388474SJose.Borrego@Sun.COM if (info1 == NULL) { 9398474SJose.Borrego@Sun.COM smb_dr_ulist_free(ulist); 9408474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 9418474SJose.Borrego@Sun.COM } 9428474SJose.Borrego@Sun.COM 9438474SJose.Borrego@Sun.COM for (i = 0; i < n_sessions; ++i) { 9448474SJose.Borrego@Sun.COM user = &ulist->dul_users[i]; 9458474SJose.Borrego@Sun.COM 9468474SJose.Borrego@Sun.COM workstation = user->oc_workstation; 9478474SJose.Borrego@Sun.COM if (workstation == NULL || *workstation == '\0') { 948*8670SJose.Borrego@Sun.COM (void) smb_inet_ntop(&user->oc_ipaddr, 949*8670SJose.Borrego@Sun.COM ipaddr_buf, SMB_IPSTRLEN(user->oc_ipaddr.a_family)); 9508474SJose.Borrego@Sun.COM workstation = ipaddr_buf; 9518474SJose.Borrego@Sun.COM } 9528474SJose.Borrego@Sun.COM 9538474SJose.Borrego@Sun.COM (void) snprintf(account, MAXNAMELEN, "%s\\%s", 9548474SJose.Borrego@Sun.COM user->oc_domain, user->oc_account); 9558474SJose.Borrego@Sun.COM 9568474SJose.Borrego@Sun.COM info1[i].sesi1_cname = NDR_STRDUP(mxa, workstation); 9578474SJose.Borrego@Sun.COM info1[i].sesi1_uname = NDR_STRDUP(mxa, account); 9588474SJose.Borrego@Sun.COM 9598474SJose.Borrego@Sun.COM if (info1[i].sesi1_cname == NULL || 9608474SJose.Borrego@Sun.COM info1[i].sesi1_uname == NULL) { 9618474SJose.Borrego@Sun.COM smb_dr_ulist_free(ulist); 9628474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 9638474SJose.Borrego@Sun.COM } 9648474SJose.Borrego@Sun.COM 9658474SJose.Borrego@Sun.COM info1[i].sesi1_nopens = 1; 9668474SJose.Borrego@Sun.COM info1[i].sesi1_time = time(0) - user->oc_logon_time; 9678474SJose.Borrego@Sun.COM info1[i].sesi1_itime = 0; 9688474SJose.Borrego@Sun.COM info1[i].sesi1_uflags = 9698474SJose.Borrego@Sun.COM (user->oc_flags & SMB_ATF_GUEST) ? SESS_GUEST : 0; 9708474SJose.Borrego@Sun.COM } 9718474SJose.Borrego@Sun.COM 9728474SJose.Borrego@Sun.COM smb_dr_ulist_free(ulist); 9738474SJose.Borrego@Sun.COM infonres->entriesread = n_sessions; 9748474SJose.Borrego@Sun.COM infonres->entries = info1; 9758474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 9768474SJose.Borrego@Sun.COM } 9778474SJose.Borrego@Sun.COM 9788474SJose.Borrego@Sun.COM /* 9798474SJose.Borrego@Sun.COM * srvsvc_s_NetSessionDel 9808474SJose.Borrego@Sun.COM * 9818474SJose.Borrego@Sun.COM * Ends a network session between a server and a workstation. 9828474SJose.Borrego@Sun.COM * On NT only members of the Administrators or Account Operators 9838474SJose.Borrego@Sun.COM * local groups are permitted to use NetSessionDel. 9848474SJose.Borrego@Sun.COM * 9858474SJose.Borrego@Sun.COM * Return Values 9868474SJose.Borrego@Sun.COM * If the function succeeds, the return value is NERR_Success/ 9878474SJose.Borrego@Sun.COM * ERROR_SUCCESS. If the function fails, the return value can be 9888474SJose.Borrego@Sun.COM * one of the following error codes: 9898474SJose.Borrego@Sun.COM * 9908474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED The user does not have access to the 9918474SJose.Borrego@Sun.COM * requested information. 9928474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER The specified parameter is invalid. 9938474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 9948474SJose.Borrego@Sun.COM * NERR_ClientNameNotFound A session does not exist with that 9958474SJose.Borrego@Sun.COM * computer name. 9968474SJose.Borrego@Sun.COM */ 9978474SJose.Borrego@Sun.COM static int 9988474SJose.Borrego@Sun.COM srvsvc_s_NetSessionDel(void *arg, ndr_xa_t *mxa) 9998474SJose.Borrego@Sun.COM { 10008474SJose.Borrego@Sun.COM struct mslm_NetSessionDel *param = arg; 10018474SJose.Borrego@Sun.COM 10028474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa)) { 10038474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 10048474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 10058474SJose.Borrego@Sun.COM } 10068474SJose.Borrego@Sun.COM 10078474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 10088474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 10098474SJose.Borrego@Sun.COM } 10108474SJose.Borrego@Sun.COM 10118474SJose.Borrego@Sun.COM /* 10128474SJose.Borrego@Sun.COM * SRVSVC NetServerGetInfo 10138474SJose.Borrego@Sun.COM * 10148474SJose.Borrego@Sun.COM * IN LPTSTR servername, 10158474SJose.Borrego@Sun.COM * IN DWORD level, 10168474SJose.Borrego@Sun.COM * OUT union switch(level) { 10178474SJose.Borrego@Sun.COM * case 100: mslm_SERVER_INFO_100 *p100; 10188474SJose.Borrego@Sun.COM * case 101: mslm_SERVER_INFO_101 *p101; 10198474SJose.Borrego@Sun.COM * case 102: mslm_SERVER_INFO_102 *p102; 10208474SJose.Borrego@Sun.COM * default: char *nullptr; 10218474SJose.Borrego@Sun.COM * } bufptr, 10228474SJose.Borrego@Sun.COM * OUT DWORD status 10238474SJose.Borrego@Sun.COM */ 10248474SJose.Borrego@Sun.COM static int 10258474SJose.Borrego@Sun.COM srvsvc_s_NetServerGetInfo(void *arg, ndr_xa_t *mxa) 10268474SJose.Borrego@Sun.COM { 10278474SJose.Borrego@Sun.COM struct mslm_NetServerGetInfo *param = arg; 10288474SJose.Borrego@Sun.COM struct mslm_SERVER_INFO_100 *info100; 10298474SJose.Borrego@Sun.COM struct mslm_SERVER_INFO_101 *info101; 10308474SJose.Borrego@Sun.COM struct mslm_SERVER_INFO_102 *info102; 10318474SJose.Borrego@Sun.COM char sys_comment[SMB_PI_MAX_COMMENT]; 10328474SJose.Borrego@Sun.COM char hostname[NETBIOS_NAME_SZ]; 10338474SJose.Borrego@Sun.COM 10348474SJose.Borrego@Sun.COM if (smb_getnetbiosname(hostname, sizeof (hostname)) != 0) { 10358474SJose.Borrego@Sun.COM netservergetinfo_no_memory: 10368474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetServerGetInfo)); 10378474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 10388474SJose.Borrego@Sun.COM } 10398474SJose.Borrego@Sun.COM 10408474SJose.Borrego@Sun.COM (void) smb_config_getstr(SMB_CI_SYS_CMNT, sys_comment, 10418474SJose.Borrego@Sun.COM sizeof (sys_comment)); 10428474SJose.Borrego@Sun.COM if (*sys_comment == '\0') 10438474SJose.Borrego@Sun.COM (void) strcpy(sys_comment, " "); 10448474SJose.Borrego@Sun.COM 10458474SJose.Borrego@Sun.COM switch (param->level) { 10468474SJose.Borrego@Sun.COM case 100: 10478474SJose.Borrego@Sun.COM info100 = NDR_NEW(mxa, struct mslm_SERVER_INFO_100); 10488474SJose.Borrego@Sun.COM if (info100 == NULL) 10498474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 10508474SJose.Borrego@Sun.COM 10518474SJose.Borrego@Sun.COM bzero(info100, sizeof (struct mslm_SERVER_INFO_100)); 10528474SJose.Borrego@Sun.COM info100->sv100_platform_id = SV_PLATFORM_ID_NT; 10538474SJose.Borrego@Sun.COM info100->sv100_name = (uint8_t *)NDR_STRDUP(mxa, hostname); 10548474SJose.Borrego@Sun.COM if (info100->sv100_name == NULL) 10558474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 10568474SJose.Borrego@Sun.COM 10578474SJose.Borrego@Sun.COM param->result.bufptr.bufptr100 = info100; 10588474SJose.Borrego@Sun.COM break; 10598474SJose.Borrego@Sun.COM 10608474SJose.Borrego@Sun.COM case 101: 10618474SJose.Borrego@Sun.COM info101 = NDR_NEW(mxa, struct mslm_SERVER_INFO_101); 10628474SJose.Borrego@Sun.COM if (info101 == NULL) 10638474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 10648474SJose.Borrego@Sun.COM 10658474SJose.Borrego@Sun.COM bzero(info101, sizeof (struct mslm_SERVER_INFO_101)); 10668474SJose.Borrego@Sun.COM info101->sv101_platform_id = SV_PLATFORM_ID_NT; 10678474SJose.Borrego@Sun.COM info101->sv101_version_major = 4; 10688474SJose.Borrego@Sun.COM info101->sv101_version_minor = 0; 10698474SJose.Borrego@Sun.COM info101->sv101_type = SV_TYPE_SENT_BY_ME; 10708474SJose.Borrego@Sun.COM info101->sv101_name = (uint8_t *)NDR_STRDUP(mxa, hostname); 10718474SJose.Borrego@Sun.COM info101->sv101_comment 10728474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, sys_comment); 10738474SJose.Borrego@Sun.COM 10748474SJose.Borrego@Sun.COM if (info101->sv101_name == NULL || 10758474SJose.Borrego@Sun.COM info101->sv101_comment == NULL) 10768474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 10778474SJose.Borrego@Sun.COM 10788474SJose.Borrego@Sun.COM param->result.bufptr.bufptr101 = info101; 10798474SJose.Borrego@Sun.COM break; 10808474SJose.Borrego@Sun.COM 10818474SJose.Borrego@Sun.COM case 102: 10828474SJose.Borrego@Sun.COM info102 = NDR_NEW(mxa, struct mslm_SERVER_INFO_102); 10838474SJose.Borrego@Sun.COM if (info102 == NULL) 10848474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 10858474SJose.Borrego@Sun.COM 10868474SJose.Borrego@Sun.COM bzero(info102, sizeof (struct mslm_SERVER_INFO_102)); 10878474SJose.Borrego@Sun.COM info102->sv102_platform_id = SV_PLATFORM_ID_NT; 10888474SJose.Borrego@Sun.COM info102->sv102_version_major = 4; 10898474SJose.Borrego@Sun.COM info102->sv102_version_minor = 0; 10908474SJose.Borrego@Sun.COM info102->sv102_type = SV_TYPE_SENT_BY_ME; 10918474SJose.Borrego@Sun.COM info102->sv102_name = (uint8_t *)NDR_STRDUP(mxa, hostname); 10928474SJose.Borrego@Sun.COM info102->sv102_comment 10938474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, sys_comment); 10948474SJose.Borrego@Sun.COM 10958474SJose.Borrego@Sun.COM /* 10968474SJose.Borrego@Sun.COM * The following level 102 fields are defaulted to zero 10978474SJose.Borrego@Sun.COM * by virtue of the call to bzero above. 10988474SJose.Borrego@Sun.COM * 10998474SJose.Borrego@Sun.COM * sv102_users 11008474SJose.Borrego@Sun.COM * sv102_disc 11018474SJose.Borrego@Sun.COM * sv102_hidden 11028474SJose.Borrego@Sun.COM * sv102_announce 11038474SJose.Borrego@Sun.COM * sv102_anndelta 11048474SJose.Borrego@Sun.COM * sv102_licenses 11058474SJose.Borrego@Sun.COM * sv102_userpath 11068474SJose.Borrego@Sun.COM */ 11078474SJose.Borrego@Sun.COM if (info102->sv102_name == NULL || 11088474SJose.Borrego@Sun.COM info102->sv102_comment == NULL) 11098474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 11108474SJose.Borrego@Sun.COM 11118474SJose.Borrego@Sun.COM param->result.bufptr.bufptr102 = info102; 11128474SJose.Borrego@Sun.COM break; 11138474SJose.Borrego@Sun.COM 11148474SJose.Borrego@Sun.COM default: 11158474SJose.Borrego@Sun.COM bzero(¶m->result, 11168474SJose.Borrego@Sun.COM sizeof (struct mslm_NetServerGetInfo_result)); 11178474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 11188474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 11198474SJose.Borrego@Sun.COM } 11208474SJose.Borrego@Sun.COM 11218474SJose.Borrego@Sun.COM param->result.level = param->level; 11228474SJose.Borrego@Sun.COM param->status = (ERROR_SUCCESS); 11238474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 11248474SJose.Borrego@Sun.COM } 11258474SJose.Borrego@Sun.COM 11268474SJose.Borrego@Sun.COM /* 11278474SJose.Borrego@Sun.COM * NetRemoteTOD 11288474SJose.Borrego@Sun.COM * 11298474SJose.Borrego@Sun.COM * Returns information about the time of day on this server. 11308474SJose.Borrego@Sun.COM * 11318474SJose.Borrego@Sun.COM * typedef struct _TIME_OF_DAY_INFO { 11328474SJose.Borrego@Sun.COM * DWORD tod_elapsedt; // seconds since 00:00:00 January 1 1970 GMT 11338474SJose.Borrego@Sun.COM * DWORD tod_msecs; // arbitrary milliseconds (since reset) 11348474SJose.Borrego@Sun.COM * DWORD tod_hours; // current hour [0-23] 11358474SJose.Borrego@Sun.COM * DWORD tod_mins; // current minute [0-59] 11368474SJose.Borrego@Sun.COM * DWORD tod_secs; // current second [0-59] 11378474SJose.Borrego@Sun.COM * DWORD tod_hunds; // current hundredth (0.01) second [0-99] 11388474SJose.Borrego@Sun.COM * LONG tod_timezone; // time zone of the server 11398474SJose.Borrego@Sun.COM * DWORD tod_tinterval; // clock tick time interval 11408474SJose.Borrego@Sun.COM * DWORD tod_day; // day of the month [1-31] 11418474SJose.Borrego@Sun.COM * DWORD tod_month; // month of the year [1-12] 11428474SJose.Borrego@Sun.COM * DWORD tod_year; // current year 11438474SJose.Borrego@Sun.COM * DWORD tod_weekday; // day of the week since Sunday [0-6] 11448474SJose.Borrego@Sun.COM * } TIME_OF_DAY_INFO; 11458474SJose.Borrego@Sun.COM * 11468474SJose.Borrego@Sun.COM * The time zone of the server is calculated in minutes from Greenwich 11478474SJose.Borrego@Sun.COM * Mean Time (GMT). For time zones west of Greenwich, the value is 11488474SJose.Borrego@Sun.COM * positive; for time zones east of Greenwich, the value is negative. 11498474SJose.Borrego@Sun.COM * A value of -1 indicates that the time zone is undefined. 11508474SJose.Borrego@Sun.COM * 11518474SJose.Borrego@Sun.COM * The clock tick value represents a resolution of one ten-thousandth 11528474SJose.Borrego@Sun.COM * (0.0001) second. 11538474SJose.Borrego@Sun.COM */ 11548474SJose.Borrego@Sun.COM static int 11558474SJose.Borrego@Sun.COM srvsvc_s_NetRemoteTOD(void *arg, ndr_xa_t *mxa) 11568474SJose.Borrego@Sun.COM { 11578474SJose.Borrego@Sun.COM struct mslm_NetRemoteTOD *param = arg; 11588474SJose.Borrego@Sun.COM struct mslm_TIME_OF_DAY_INFO *tod; 11598474SJose.Borrego@Sun.COM struct timeval time_val; 11608474SJose.Borrego@Sun.COM struct tm tm; 11618474SJose.Borrego@Sun.COM 11628474SJose.Borrego@Sun.COM (void) gettimeofday(&time_val, 0); 11638474SJose.Borrego@Sun.COM (void) gmtime_r(&time_val.tv_sec, &tm); 11648474SJose.Borrego@Sun.COM 11658474SJose.Borrego@Sun.COM tod = NDR_NEW(mxa, struct mslm_TIME_OF_DAY_INFO); 11668474SJose.Borrego@Sun.COM if (tod == NULL) { 11678474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetRemoteTOD)); 11688474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 11698474SJose.Borrego@Sun.COM } 11708474SJose.Borrego@Sun.COM 11718474SJose.Borrego@Sun.COM tod->tod_elapsedt = time_val.tv_sec; 11728474SJose.Borrego@Sun.COM tod->tod_msecs = time_val.tv_usec; 11738474SJose.Borrego@Sun.COM tod->tod_hours = tm.tm_hour; 11748474SJose.Borrego@Sun.COM tod->tod_mins = tm.tm_min; 11758474SJose.Borrego@Sun.COM tod->tod_secs = tm.tm_sec; 11768474SJose.Borrego@Sun.COM tod->tod_hunds = 0; 11778474SJose.Borrego@Sun.COM tod->tod_tinterval = 1000; 11788474SJose.Borrego@Sun.COM tod->tod_day = tm.tm_mday; 11798474SJose.Borrego@Sun.COM tod->tod_month = tm.tm_mon+1; 11808474SJose.Borrego@Sun.COM tod->tod_year = tm.tm_year+1900; 11818474SJose.Borrego@Sun.COM tod->tod_weekday = tm.tm_wday; 11828474SJose.Borrego@Sun.COM 11838474SJose.Borrego@Sun.COM (void) localtime_r(&time_val.tv_sec, &tm); 11848474SJose.Borrego@Sun.COM 11858474SJose.Borrego@Sun.COM param->bufptr = tod; 11868474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 11878474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 11888474SJose.Borrego@Sun.COM } 11898474SJose.Borrego@Sun.COM 11908474SJose.Borrego@Sun.COM /* 11918474SJose.Borrego@Sun.COM * srvsvc_s_NetNameValidate 11928474SJose.Borrego@Sun.COM * 11938474SJose.Borrego@Sun.COM * Perform name validation. 11948474SJose.Borrego@Sun.COM * 11958474SJose.Borrego@Sun.COM * The share name is considered invalid if it contains any of the 11968474SJose.Borrego@Sun.COM * following character (MSDN 236388). 11978474SJose.Borrego@Sun.COM * 11988474SJose.Borrego@Sun.COM * " / \ [ ] : | < > + ; , ? * = 11998474SJose.Borrego@Sun.COM * 12008474SJose.Borrego@Sun.COM * Returns Win32 error codes. 12018474SJose.Borrego@Sun.COM */ 12028474SJose.Borrego@Sun.COM /*ARGSUSED*/ 12038474SJose.Borrego@Sun.COM static int 12048474SJose.Borrego@Sun.COM srvsvc_s_NetNameValidate(void *arg, ndr_xa_t *mxa) 12058474SJose.Borrego@Sun.COM { 12068474SJose.Borrego@Sun.COM struct mslm_NetNameValidate *param = arg; 12078474SJose.Borrego@Sun.COM char *name; 12088474SJose.Borrego@Sun.COM int len; 12098474SJose.Borrego@Sun.COM 12108474SJose.Borrego@Sun.COM if ((name = (char *)param->pathname) == NULL) { 12118474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_PARAMETER; 12128474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12138474SJose.Borrego@Sun.COM } 12148474SJose.Borrego@Sun.COM 12158474SJose.Borrego@Sun.COM len = strlen(name); 12168474SJose.Borrego@Sun.COM 12178474SJose.Borrego@Sun.COM if ((param->flags == 0 && len > 81) || 12188474SJose.Borrego@Sun.COM (param->flags == 0x80000000 && len > 13)) { 12198474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_NAME; 12208474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12218474SJose.Borrego@Sun.COM } 12228474SJose.Borrego@Sun.COM 12238474SJose.Borrego@Sun.COM switch (param->type) { 12248474SJose.Borrego@Sun.COM case NAMETYPE_SHARE: 12258474SJose.Borrego@Sun.COM if (smb_shr_chkname(name)) 12268474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 12278474SJose.Borrego@Sun.COM else 12288474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_NAME; 12298474SJose.Borrego@Sun.COM break; 12308474SJose.Borrego@Sun.COM 12318474SJose.Borrego@Sun.COM case NAMETYPE_USER: 12328474SJose.Borrego@Sun.COM case NAMETYPE_PASSWORD: 12338474SJose.Borrego@Sun.COM case NAMETYPE_GROUP: 12348474SJose.Borrego@Sun.COM case NAMETYPE_COMPUTER: 12358474SJose.Borrego@Sun.COM case NAMETYPE_EVENT: 12368474SJose.Borrego@Sun.COM case NAMETYPE_DOMAIN: 12378474SJose.Borrego@Sun.COM case NAMETYPE_SERVICE: 12388474SJose.Borrego@Sun.COM case NAMETYPE_NET: 12398474SJose.Borrego@Sun.COM case NAMETYPE_MESSAGE: 12408474SJose.Borrego@Sun.COM case NAMETYPE_MESSAGEDEST: 12418474SJose.Borrego@Sun.COM case NAMETYPE_SHAREPASSWORD: 12428474SJose.Borrego@Sun.COM case NAMETYPE_WORKGROUP: 12438474SJose.Borrego@Sun.COM param->status = ERROR_NOT_SUPPORTED; 12448474SJose.Borrego@Sun.COM break; 12458474SJose.Borrego@Sun.COM 12468474SJose.Borrego@Sun.COM default: 12478474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_PARAMETER; 12488474SJose.Borrego@Sun.COM break; 12498474SJose.Borrego@Sun.COM } 12508474SJose.Borrego@Sun.COM 12518474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12528474SJose.Borrego@Sun.COM } 12538474SJose.Borrego@Sun.COM 12548474SJose.Borrego@Sun.COM /* 12558474SJose.Borrego@Sun.COM * srvsvc_s_NetShareAdd 12568474SJose.Borrego@Sun.COM * 12578474SJose.Borrego@Sun.COM * Add a new share. We support info levels 2 and 502 but ignore the 12588474SJose.Borrego@Sun.COM * security descriptor in level 502 requests. Only the administrator, 12598474SJose.Borrego@Sun.COM * or a member of the domain administrators group, is allowed to add 12608474SJose.Borrego@Sun.COM * shares. 12618474SJose.Borrego@Sun.COM * 12628474SJose.Borrego@Sun.COM * This interface is used by the rmtshare command from the NT resource 12638474SJose.Borrego@Sun.COM * kit. Rmtshare allows a client to add or remove shares on a server 12648474SJose.Borrego@Sun.COM * from the client's command line. 12658474SJose.Borrego@Sun.COM * 12668474SJose.Borrego@Sun.COM * Note that we don't support security descriptors on a share. If the 12678474SJose.Borrego@Sun.COM * /grant is used, the share will be created but the subsequent attempt 12688474SJose.Borrego@Sun.COM * to manipulate the security descriptor (NetShareGetInfo) will fail. 12698474SJose.Borrego@Sun.COM * Similarly for the /remove option. 12708474SJose.Borrego@Sun.COM * 12718474SJose.Borrego@Sun.COM * Returns Win32 error codes. 12728474SJose.Borrego@Sun.COM */ 12738474SJose.Borrego@Sun.COM static int 12748474SJose.Borrego@Sun.COM srvsvc_s_NetShareAdd(void *arg, ndr_xa_t *mxa) 12758474SJose.Borrego@Sun.COM { 12768474SJose.Borrego@Sun.COM static DWORD parm_err = 0; 12778474SJose.Borrego@Sun.COM DWORD parm_stat; 12788474SJose.Borrego@Sun.COM struct mslm_NetShareAdd *param = arg; 12798474SJose.Borrego@Sun.COM struct mslm_SHARE_INFO_2 *info2; 12808474SJose.Borrego@Sun.COM char realpath[MAXPATHLEN]; 12818474SJose.Borrego@Sun.COM int32_t native_os; 12828474SJose.Borrego@Sun.COM 12838474SJose.Borrego@Sun.COM native_os = ndr_native_os(mxa); 12848474SJose.Borrego@Sun.COM 12858474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa)) { 12868474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 12878474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 12888474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12898474SJose.Borrego@Sun.COM } 12908474SJose.Borrego@Sun.COM 12918474SJose.Borrego@Sun.COM switch (param->level) { 12928474SJose.Borrego@Sun.COM case 2: 12938474SJose.Borrego@Sun.COM info2 = param->info.un.info2; 12948474SJose.Borrego@Sun.COM break; 12958474SJose.Borrego@Sun.COM 12968474SJose.Borrego@Sun.COM case 502: 12978474SJose.Borrego@Sun.COM info2 = (struct mslm_SHARE_INFO_2 *)param->info.un.info502; 12988474SJose.Borrego@Sun.COM break; 12998474SJose.Borrego@Sun.COM 13008474SJose.Borrego@Sun.COM default: 13018474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 13028474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 13038474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 13048474SJose.Borrego@Sun.COM } 13058474SJose.Borrego@Sun.COM 13068474SJose.Borrego@Sun.COM if (info2->shi2_netname == NULL || info2->shi2_path == NULL) { 13078474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 13088474SJose.Borrego@Sun.COM param->status = NERR_NetNameNotFound; 13098474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 13108474SJose.Borrego@Sun.COM } 13118474SJose.Borrego@Sun.COM 13128474SJose.Borrego@Sun.COM if (smb_shr_is_restricted((char *)info2->shi2_netname)) { 13138474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 13148474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 13158474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 13168474SJose.Borrego@Sun.COM } 13178474SJose.Borrego@Sun.COM 13188474SJose.Borrego@Sun.COM if (info2->shi2_remark == NULL) 13198474SJose.Borrego@Sun.COM info2->shi2_remark = (uint8_t *)""; 13208474SJose.Borrego@Sun.COM 13218474SJose.Borrego@Sun.COM /* 13228474SJose.Borrego@Sun.COM * Derive the real path which will be stored in the 13238474SJose.Borrego@Sun.COM * directory field of the smb_share_t structure 13248474SJose.Borrego@Sun.COM * from the path field in this RPC request. 13258474SJose.Borrego@Sun.COM */ 13268474SJose.Borrego@Sun.COM parm_stat = smb_shr_get_realpath((const char *)info2->shi2_path, 13278474SJose.Borrego@Sun.COM realpath, MAXPATHLEN); 13288474SJose.Borrego@Sun.COM 13298474SJose.Borrego@Sun.COM if (parm_stat != NERR_Success) { 13308474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 13318474SJose.Borrego@Sun.COM param->status = parm_stat; 13328474SJose.Borrego@Sun.COM param->parm_err 13338474SJose.Borrego@Sun.COM = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; 13348474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 13358474SJose.Borrego@Sun.COM } 13368474SJose.Borrego@Sun.COM 13378474SJose.Borrego@Sun.COM param->status = srvsvc_sa_add((char *)info2->shi2_netname, realpath, 13388474SJose.Borrego@Sun.COM (char *)info2->shi2_remark); 13398474SJose.Borrego@Sun.COM if (param->status == NERR_Success) { 13408474SJose.Borrego@Sun.COM smb_share_t si; 13418474SJose.Borrego@Sun.COM /* 13428474SJose.Borrego@Sun.COM * Lookup the share, which will bring it into the cache. 13438474SJose.Borrego@Sun.COM */ 13448474SJose.Borrego@Sun.COM (void) smb_shr_get((char *)info2->shi2_netname, &si); 13458474SJose.Borrego@Sun.COM } 13468474SJose.Borrego@Sun.COM param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; 13478474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 13488474SJose.Borrego@Sun.COM } 13498474SJose.Borrego@Sun.COM 13508474SJose.Borrego@Sun.COM /* 13518474SJose.Borrego@Sun.COM * srvsvc_estimate_objcnt 13528474SJose.Borrego@Sun.COM * 13538474SJose.Borrego@Sun.COM * Estimate the number of objects that will fit in prefmaxlen. 13548474SJose.Borrego@Sun.COM */ 13558474SJose.Borrego@Sun.COM static uint32_t 13568474SJose.Borrego@Sun.COM srvsvc_estimate_objcnt(uint32_t prefmaxlen, uint32_t n_obj, uint32_t obj_size) 13578474SJose.Borrego@Sun.COM { 13588474SJose.Borrego@Sun.COM DWORD max_cnt; 13598474SJose.Borrego@Sun.COM 13608474SJose.Borrego@Sun.COM if (obj_size == 0) 13618474SJose.Borrego@Sun.COM return (0); 13628474SJose.Borrego@Sun.COM 13638474SJose.Borrego@Sun.COM if ((max_cnt = (prefmaxlen / obj_size)) == 0) 13648474SJose.Borrego@Sun.COM return (0); 13658474SJose.Borrego@Sun.COM 13668474SJose.Borrego@Sun.COM if (n_obj > max_cnt) 13678474SJose.Borrego@Sun.COM n_obj = max_cnt; 13688474SJose.Borrego@Sun.COM 13698474SJose.Borrego@Sun.COM return (n_obj); 13708474SJose.Borrego@Sun.COM } 13718474SJose.Borrego@Sun.COM 13728474SJose.Borrego@Sun.COM /* 13738474SJose.Borrego@Sun.COM * srvsvc_s_NetShareEnum 13748474SJose.Borrego@Sun.COM * 13758474SJose.Borrego@Sun.COM * Enumerate all shares (see also NetShareEnumSticky). 13768474SJose.Borrego@Sun.COM * 13778474SJose.Borrego@Sun.COM * Request for various levels of information about our shares. 13788474SJose.Borrego@Sun.COM * Level 0: share names. 13798474SJose.Borrego@Sun.COM * Level 1: share name, share type and comment field. 13808474SJose.Borrego@Sun.COM * Level 2: everything that we know about the shares. 13818474SJose.Borrego@Sun.COM * Level 501: level 1 + flags (flags must be zero). 13828474SJose.Borrego@Sun.COM * Level 502: level 2 + security descriptor. 13838474SJose.Borrego@Sun.COM */ 13848474SJose.Borrego@Sun.COM static int 13858474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnum(void *arg, ndr_xa_t *mxa) 13868474SJose.Borrego@Sun.COM { 13878474SJose.Borrego@Sun.COM struct mslm_NetShareEnum *param = arg; 13888474SJose.Borrego@Sun.COM struct mslm_infonres *infonres; 13898474SJose.Borrego@Sun.COM srvsvc_enum_t se; 13908474SJose.Borrego@Sun.COM DWORD status; 13918474SJose.Borrego@Sun.COM 13928474SJose.Borrego@Sun.COM infonres = NDR_NEW(mxa, struct mslm_infonres); 13938474SJose.Borrego@Sun.COM if (infonres == NULL) { 13948474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 13958474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 13968474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 13978474SJose.Borrego@Sun.COM } 13988474SJose.Borrego@Sun.COM 13998474SJose.Borrego@Sun.COM infonres->entriesread = 0; 14008474SJose.Borrego@Sun.COM infonres->entries = NULL; 14018474SJose.Borrego@Sun.COM param->result.level = param->level; 14028474SJose.Borrego@Sun.COM param->result.bufptr.p = infonres; 14038474SJose.Borrego@Sun.COM 14048474SJose.Borrego@Sun.COM bzero(&se, sizeof (srvsvc_enum_t)); 14058474SJose.Borrego@Sun.COM se.se_level = param->level; 14068474SJose.Borrego@Sun.COM se.se_n_total = smb_shr_count(); 14078474SJose.Borrego@Sun.COM 14088474SJose.Borrego@Sun.COM if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN || 14098474SJose.Borrego@Sun.COM param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN) 14108474SJose.Borrego@Sun.COM se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN; 14118474SJose.Borrego@Sun.COM else 14128474SJose.Borrego@Sun.COM se.se_prefmaxlen = param->prefmaxlen; 14138474SJose.Borrego@Sun.COM 14148474SJose.Borrego@Sun.COM if (param->resume_handle) { 14158474SJose.Borrego@Sun.COM se.se_resume_handle = *param->resume_handle; 14168474SJose.Borrego@Sun.COM se.se_n_skip = se.se_resume_handle; 14178474SJose.Borrego@Sun.COM } 14188474SJose.Borrego@Sun.COM 14198474SJose.Borrego@Sun.COM switch (param->level) { 14208474SJose.Borrego@Sun.COM case 0: 14218474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 0); 14228474SJose.Borrego@Sun.COM break; 14238474SJose.Borrego@Sun.COM 14248474SJose.Borrego@Sun.COM case 1: 14258474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 0); 14268474SJose.Borrego@Sun.COM break; 14278474SJose.Borrego@Sun.COM 14288474SJose.Borrego@Sun.COM case 2: 14298474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 0); 14308474SJose.Borrego@Sun.COM break; 14318474SJose.Borrego@Sun.COM 14328474SJose.Borrego@Sun.COM case 501: 14338474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel501(mxa, infonres, &se, 0); 14348474SJose.Borrego@Sun.COM break; 14358474SJose.Borrego@Sun.COM 14368474SJose.Borrego@Sun.COM case 502: 14378474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 0); 14388474SJose.Borrego@Sun.COM break; 14398474SJose.Borrego@Sun.COM 14408474SJose.Borrego@Sun.COM default: 14418474SJose.Borrego@Sun.COM status = ERROR_INVALID_PARAMETER; 14428474SJose.Borrego@Sun.COM break; 14438474SJose.Borrego@Sun.COM } 14448474SJose.Borrego@Sun.COM 14458474SJose.Borrego@Sun.COM if (status != 0) { 14468474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 14478474SJose.Borrego@Sun.COM param->status = status; 14488474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 14498474SJose.Borrego@Sun.COM } 14508474SJose.Borrego@Sun.COM 14518474SJose.Borrego@Sun.COM if (se.se_n_enum == 0) { 14528474SJose.Borrego@Sun.COM if (param->resume_handle) 14538474SJose.Borrego@Sun.COM *param->resume_handle = 0; 14548474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 14558474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 14568474SJose.Borrego@Sun.COM } 14578474SJose.Borrego@Sun.COM 14588474SJose.Borrego@Sun.COM if (param->resume_handle && 14598474SJose.Borrego@Sun.COM param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) { 14608474SJose.Borrego@Sun.COM if (se.se_resume_handle < se.se_n_total) { 14618474SJose.Borrego@Sun.COM *param->resume_handle = se.se_resume_handle; 14628474SJose.Borrego@Sun.COM status = ERROR_MORE_DATA; 14638474SJose.Borrego@Sun.COM } else { 14648474SJose.Borrego@Sun.COM *param->resume_handle = 0; 14658474SJose.Borrego@Sun.COM } 14668474SJose.Borrego@Sun.COM } 14678474SJose.Borrego@Sun.COM 14688474SJose.Borrego@Sun.COM param->totalentries = se.se_n_total; 14698474SJose.Borrego@Sun.COM param->status = status; 14708474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 14718474SJose.Borrego@Sun.COM } 14728474SJose.Borrego@Sun.COM 14738474SJose.Borrego@Sun.COM /* 14748474SJose.Borrego@Sun.COM * srvsvc_s_NetShareEnumSticky 14758474SJose.Borrego@Sun.COM * 14768474SJose.Borrego@Sun.COM * Enumerate sticky shares: all shares except those marked STYPE_SPECIAL. 14778474SJose.Borrego@Sun.COM * Except for excluding STYPE_SPECIAL shares, NetShareEnumSticky is the 14788474SJose.Borrego@Sun.COM * same as NetShareEnum. 14798474SJose.Borrego@Sun.COM * 14808474SJose.Borrego@Sun.COM * Request for various levels of information about our shares. 14818474SJose.Borrego@Sun.COM * Level 0: share names. 14828474SJose.Borrego@Sun.COM * Level 1: share name, share type and comment field. 14838474SJose.Borrego@Sun.COM * Level 2: everything that we know about the shares. 14848474SJose.Borrego@Sun.COM * Level 501: not valid for this request. 14858474SJose.Borrego@Sun.COM * Level 502: level 2 + security descriptor. 14868474SJose.Borrego@Sun.COM * 14878474SJose.Borrego@Sun.COM * We set n_skip to resume_handle, which is used to find the appropriate 14888474SJose.Borrego@Sun.COM * place to resume. The resume_handle is similar to the readdir cookie. 14898474SJose.Borrego@Sun.COM */ 14908474SJose.Borrego@Sun.COM static int 14918474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnumSticky(void *arg, ndr_xa_t *mxa) 14928474SJose.Borrego@Sun.COM { 14938474SJose.Borrego@Sun.COM struct mslm_NetShareEnum *param = arg; 14948474SJose.Borrego@Sun.COM struct mslm_infonres *infonres; 14958474SJose.Borrego@Sun.COM srvsvc_enum_t se; 14968474SJose.Borrego@Sun.COM DWORD status; 14978474SJose.Borrego@Sun.COM 14988474SJose.Borrego@Sun.COM infonres = NDR_NEW(mxa, struct mslm_infonres); 14998474SJose.Borrego@Sun.COM if (infonres == NULL) { 15008474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 15018474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 15028474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 15038474SJose.Borrego@Sun.COM } 15048474SJose.Borrego@Sun.COM 15058474SJose.Borrego@Sun.COM infonres->entriesread = 0; 15068474SJose.Borrego@Sun.COM infonres->entries = NULL; 15078474SJose.Borrego@Sun.COM param->result.level = param->level; 15088474SJose.Borrego@Sun.COM param->result.bufptr.p = infonres; 15098474SJose.Borrego@Sun.COM 15108474SJose.Borrego@Sun.COM bzero(&se, sizeof (srvsvc_enum_t)); 15118474SJose.Borrego@Sun.COM se.se_level = param->level; 15128474SJose.Borrego@Sun.COM se.se_n_total = smb_shr_count(); 15138474SJose.Borrego@Sun.COM 15148474SJose.Borrego@Sun.COM if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN || 15158474SJose.Borrego@Sun.COM param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN) 15168474SJose.Borrego@Sun.COM se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN; 15178474SJose.Borrego@Sun.COM else 15188474SJose.Borrego@Sun.COM se.se_prefmaxlen = param->prefmaxlen; 15198474SJose.Borrego@Sun.COM 15208474SJose.Borrego@Sun.COM if (param->resume_handle) { 15218474SJose.Borrego@Sun.COM se.se_resume_handle = *param->resume_handle; 15228474SJose.Borrego@Sun.COM se.se_n_skip = se.se_resume_handle; 15238474SJose.Borrego@Sun.COM } 15248474SJose.Borrego@Sun.COM 15258474SJose.Borrego@Sun.COM switch (param->level) { 15268474SJose.Borrego@Sun.COM case 0: 15278474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 1); 15288474SJose.Borrego@Sun.COM break; 15298474SJose.Borrego@Sun.COM 15308474SJose.Borrego@Sun.COM case 1: 15318474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 1); 15328474SJose.Borrego@Sun.COM break; 15338474SJose.Borrego@Sun.COM 15348474SJose.Borrego@Sun.COM case 2: 15358474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 1); 15368474SJose.Borrego@Sun.COM break; 15378474SJose.Borrego@Sun.COM 15388474SJose.Borrego@Sun.COM case 502: 15398474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 1); 15408474SJose.Borrego@Sun.COM break; 15418474SJose.Borrego@Sun.COM 15428474SJose.Borrego@Sun.COM default: 15438474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 15448474SJose.Borrego@Sun.COM break; 15458474SJose.Borrego@Sun.COM } 15468474SJose.Borrego@Sun.COM 15478474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) { 15488474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 15498474SJose.Borrego@Sun.COM param->status = status; 15508474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 15518474SJose.Borrego@Sun.COM } 15528474SJose.Borrego@Sun.COM 15538474SJose.Borrego@Sun.COM if (se.se_n_enum == 0) { 15548474SJose.Borrego@Sun.COM if (param->resume_handle) 15558474SJose.Borrego@Sun.COM *param->resume_handle = 0; 15568474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 15578474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 15588474SJose.Borrego@Sun.COM } 15598474SJose.Borrego@Sun.COM 15608474SJose.Borrego@Sun.COM if (param->resume_handle && 15618474SJose.Borrego@Sun.COM param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) { 15628474SJose.Borrego@Sun.COM if (se.se_resume_handle < se.se_n_total) { 15638474SJose.Borrego@Sun.COM *param->resume_handle = se.se_resume_handle; 15648474SJose.Borrego@Sun.COM status = ERROR_MORE_DATA; 15658474SJose.Borrego@Sun.COM } else { 15668474SJose.Borrego@Sun.COM *param->resume_handle = 0; 15678474SJose.Borrego@Sun.COM } 15688474SJose.Borrego@Sun.COM } 15698474SJose.Borrego@Sun.COM 15708474SJose.Borrego@Sun.COM param->totalentries = se.se_n_total; 15718474SJose.Borrego@Sun.COM param->status = status; 15728474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 15738474SJose.Borrego@Sun.COM } 15748474SJose.Borrego@Sun.COM 15758474SJose.Borrego@Sun.COM /* 15768474SJose.Borrego@Sun.COM * NetShareEnum Level 0 15778474SJose.Borrego@Sun.COM */ 15788474SJose.Borrego@Sun.COM static DWORD 15798474SJose.Borrego@Sun.COM mlsvc_NetShareEnumLevel0(ndr_xa_t *mxa, 15808474SJose.Borrego@Sun.COM struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) 15818474SJose.Borrego@Sun.COM { 15828474SJose.Borrego@Sun.COM struct mslm_SHARE_INFO_0 *info0; 15838474SJose.Borrego@Sun.COM smb_shriter_t iterator; 15848474SJose.Borrego@Sun.COM smb_share_t *si; 15858474SJose.Borrego@Sun.COM DWORD status; 15868474SJose.Borrego@Sun.COM 15878474SJose.Borrego@Sun.COM se->se_n_enum = srvsvc_estimate_objcnt(se->se_prefmaxlen, 15888474SJose.Borrego@Sun.COM se->se_n_total, sizeof (struct mslm_SHARE_INFO_0) + MAXNAMELEN); 15898474SJose.Borrego@Sun.COM if (se->se_n_enum == 0) 15908474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 15918474SJose.Borrego@Sun.COM 15928474SJose.Borrego@Sun.COM info0 = NDR_NEWN(mxa, struct mslm_SHARE_INFO_0, se->se_n_enum); 15938474SJose.Borrego@Sun.COM if (info0 == NULL) 15948474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 15958474SJose.Borrego@Sun.COM 15968474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 15978474SJose.Borrego@Sun.COM 15988474SJose.Borrego@Sun.COM se->se_n_read = 0; 15998474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != NULL) { 16008474SJose.Borrego@Sun.COM if (se->se_n_skip > 0) { 16018474SJose.Borrego@Sun.COM --se->se_n_skip; 16028474SJose.Borrego@Sun.COM continue; 16038474SJose.Borrego@Sun.COM } 16048474SJose.Borrego@Sun.COM 16058474SJose.Borrego@Sun.COM ++se->se_resume_handle; 16068474SJose.Borrego@Sun.COM 16078474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 16088474SJose.Borrego@Sun.COM continue; 16098474SJose.Borrego@Sun.COM 16108474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 16118474SJose.Borrego@Sun.COM continue; 16128474SJose.Borrego@Sun.COM 16138474SJose.Borrego@Sun.COM if (se->se_n_read >= se->se_n_enum) { 16148474SJose.Borrego@Sun.COM se->se_n_read = se->se_n_enum; 16158474SJose.Borrego@Sun.COM break; 16168474SJose.Borrego@Sun.COM } 16178474SJose.Borrego@Sun.COM 16188474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info0); 16198474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 16208474SJose.Borrego@Sun.COM break; 16218474SJose.Borrego@Sun.COM 16228474SJose.Borrego@Sun.COM ++se->se_n_read; 16238474SJose.Borrego@Sun.COM } 16248474SJose.Borrego@Sun.COM 16258474SJose.Borrego@Sun.COM if (se->se_n_read < se->se_n_enum) { 16268474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info0)) 16278474SJose.Borrego@Sun.COM ++se->se_n_read; 16288474SJose.Borrego@Sun.COM } 16298474SJose.Borrego@Sun.COM 16308474SJose.Borrego@Sun.COM infonres->entriesread = se->se_n_read; 16318474SJose.Borrego@Sun.COM infonres->entries = info0; 16328474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 16338474SJose.Borrego@Sun.COM } 16348474SJose.Borrego@Sun.COM 16358474SJose.Borrego@Sun.COM /* 16368474SJose.Borrego@Sun.COM * NetShareEnum Level 1 16378474SJose.Borrego@Sun.COM */ 16388474SJose.Borrego@Sun.COM static DWORD 16398474SJose.Borrego@Sun.COM mlsvc_NetShareEnumLevel1(ndr_xa_t *mxa, 16408474SJose.Borrego@Sun.COM struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) 16418474SJose.Borrego@Sun.COM { 16428474SJose.Borrego@Sun.COM struct mslm_SHARE_INFO_1 *info1; 16438474SJose.Borrego@Sun.COM smb_shriter_t iterator; 16448474SJose.Borrego@Sun.COM smb_share_t *si; 16458474SJose.Borrego@Sun.COM DWORD status; 16468474SJose.Borrego@Sun.COM 16478474SJose.Borrego@Sun.COM se->se_n_enum = srvsvc_estimate_objcnt(se->se_prefmaxlen, 16488474SJose.Borrego@Sun.COM se->se_n_total, sizeof (struct mslm_SHARE_INFO_1) + MAXNAMELEN); 16498474SJose.Borrego@Sun.COM if (se->se_n_enum == 0) 16508474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 16518474SJose.Borrego@Sun.COM 16528474SJose.Borrego@Sun.COM info1 = NDR_NEWN(mxa, struct mslm_SHARE_INFO_1, se->se_n_enum); 16538474SJose.Borrego@Sun.COM if (info1 == NULL) 16548474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 16558474SJose.Borrego@Sun.COM 16568474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 16578474SJose.Borrego@Sun.COM 16588474SJose.Borrego@Sun.COM se->se_n_read = 0; 16598474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != 0) { 16608474SJose.Borrego@Sun.COM if (se->se_n_skip > 0) { 16618474SJose.Borrego@Sun.COM --se->se_n_skip; 16628474SJose.Borrego@Sun.COM continue; 16638474SJose.Borrego@Sun.COM } 16648474SJose.Borrego@Sun.COM 16658474SJose.Borrego@Sun.COM ++se->se_resume_handle; 16668474SJose.Borrego@Sun.COM 16678474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 16688474SJose.Borrego@Sun.COM continue; 16698474SJose.Borrego@Sun.COM 16708474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 16718474SJose.Borrego@Sun.COM continue; 16728474SJose.Borrego@Sun.COM 16738474SJose.Borrego@Sun.COM if (se->se_n_read >= se->se_n_enum) { 16748474SJose.Borrego@Sun.COM se->se_n_read = se->se_n_enum; 16758474SJose.Borrego@Sun.COM break; 16768474SJose.Borrego@Sun.COM } 16778474SJose.Borrego@Sun.COM 16788474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info1); 16798474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 16808474SJose.Borrego@Sun.COM break; 16818474SJose.Borrego@Sun.COM 16828474SJose.Borrego@Sun.COM ++se->se_n_read; 16838474SJose.Borrego@Sun.COM } 16848474SJose.Borrego@Sun.COM 16858474SJose.Borrego@Sun.COM if (se->se_n_read < se->se_n_enum) { 16868474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info1)) 16878474SJose.Borrego@Sun.COM ++se->se_n_read; 16888474SJose.Borrego@Sun.COM } 16898474SJose.Borrego@Sun.COM 16908474SJose.Borrego@Sun.COM infonres->entriesread = se->se_n_read; 16918474SJose.Borrego@Sun.COM infonres->entries = info1; 16928474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 16938474SJose.Borrego@Sun.COM } 16948474SJose.Borrego@Sun.COM 16958474SJose.Borrego@Sun.COM /* 16968474SJose.Borrego@Sun.COM * NetShareEnum Level 2 16978474SJose.Borrego@Sun.COM */ 16988474SJose.Borrego@Sun.COM static DWORD 16998474SJose.Borrego@Sun.COM mlsvc_NetShareEnumLevel2(ndr_xa_t *mxa, 17008474SJose.Borrego@Sun.COM struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) 17018474SJose.Borrego@Sun.COM { 17028474SJose.Borrego@Sun.COM struct mslm_SHARE_INFO_2 *info2; 17038474SJose.Borrego@Sun.COM smb_shriter_t iterator; 17048474SJose.Borrego@Sun.COM smb_share_t *si; 17058474SJose.Borrego@Sun.COM DWORD status; 17068474SJose.Borrego@Sun.COM 17078474SJose.Borrego@Sun.COM se->se_n_enum = srvsvc_estimate_objcnt(se->se_prefmaxlen, 17088474SJose.Borrego@Sun.COM se->se_n_total, sizeof (struct mslm_SHARE_INFO_2) + MAXNAMELEN); 17098474SJose.Borrego@Sun.COM if (se->se_n_enum == 0) 17108474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 17118474SJose.Borrego@Sun.COM 17128474SJose.Borrego@Sun.COM info2 = NDR_NEWN(mxa, struct mslm_SHARE_INFO_2, se->se_n_enum); 17138474SJose.Borrego@Sun.COM if (info2 == NULL) 17148474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 17158474SJose.Borrego@Sun.COM 17168474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 17178474SJose.Borrego@Sun.COM 17188474SJose.Borrego@Sun.COM se->se_n_read = 0; 17198474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != 0) { 17208474SJose.Borrego@Sun.COM if (se->se_n_skip > 0) { 17218474SJose.Borrego@Sun.COM --se->se_n_skip; 17228474SJose.Borrego@Sun.COM continue; 17238474SJose.Borrego@Sun.COM } 17248474SJose.Borrego@Sun.COM 17258474SJose.Borrego@Sun.COM ++se->se_resume_handle; 17268474SJose.Borrego@Sun.COM 17278474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 17288474SJose.Borrego@Sun.COM continue; 17298474SJose.Borrego@Sun.COM 17308474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 17318474SJose.Borrego@Sun.COM continue; 17328474SJose.Borrego@Sun.COM 17338474SJose.Borrego@Sun.COM if (se->se_n_read >= se->se_n_enum) { 17348474SJose.Borrego@Sun.COM se->se_n_read = se->se_n_enum; 17358474SJose.Borrego@Sun.COM break; 17368474SJose.Borrego@Sun.COM } 17378474SJose.Borrego@Sun.COM 17388474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info2); 17398474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 17408474SJose.Borrego@Sun.COM break; 17418474SJose.Borrego@Sun.COM 17428474SJose.Borrego@Sun.COM ++se->se_n_read; 17438474SJose.Borrego@Sun.COM } 17448474SJose.Borrego@Sun.COM 17458474SJose.Borrego@Sun.COM if (se->se_n_read < se->se_n_enum) { 17468474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info2)) 17478474SJose.Borrego@Sun.COM ++se->se_n_read; 17488474SJose.Borrego@Sun.COM } 17498474SJose.Borrego@Sun.COM 17508474SJose.Borrego@Sun.COM infonres->entriesread = se->se_n_read; 17518474SJose.Borrego@Sun.COM infonres->entries = info2; 17528474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 17538474SJose.Borrego@Sun.COM } 17548474SJose.Borrego@Sun.COM 17558474SJose.Borrego@Sun.COM /* 17568474SJose.Borrego@Sun.COM * NetShareEnum Level 501 17578474SJose.Borrego@Sun.COM */ 17588474SJose.Borrego@Sun.COM static DWORD 17598474SJose.Borrego@Sun.COM mlsvc_NetShareEnumLevel501(ndr_xa_t *mxa, 17608474SJose.Borrego@Sun.COM struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) 17618474SJose.Borrego@Sun.COM { 17628474SJose.Borrego@Sun.COM struct mslm_SHARE_INFO_501 *info501; 17638474SJose.Borrego@Sun.COM smb_shriter_t iterator; 17648474SJose.Borrego@Sun.COM smb_share_t *si; 17658474SJose.Borrego@Sun.COM DWORD status; 17668474SJose.Borrego@Sun.COM 17678474SJose.Borrego@Sun.COM se->se_n_enum = srvsvc_estimate_objcnt(se->se_prefmaxlen, 17688474SJose.Borrego@Sun.COM se->se_n_total, sizeof (struct mslm_SHARE_INFO_501) + MAXNAMELEN); 17698474SJose.Borrego@Sun.COM if (se->se_n_enum == 0) 17708474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 17718474SJose.Borrego@Sun.COM 17728474SJose.Borrego@Sun.COM info501 = NDR_NEWN(mxa, struct mslm_SHARE_INFO_501, 17738474SJose.Borrego@Sun.COM se->se_n_enum); 17748474SJose.Borrego@Sun.COM if (info501 == NULL) 17758474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 17768474SJose.Borrego@Sun.COM 17778474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 17788474SJose.Borrego@Sun.COM 17798474SJose.Borrego@Sun.COM se->se_n_read = 0; 17808474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != 0) { 17818474SJose.Borrego@Sun.COM if (se->se_n_skip > 0) { 17828474SJose.Borrego@Sun.COM --se->se_n_skip; 17838474SJose.Borrego@Sun.COM continue; 17848474SJose.Borrego@Sun.COM } 17858474SJose.Borrego@Sun.COM 17868474SJose.Borrego@Sun.COM ++se->se_resume_handle; 17878474SJose.Borrego@Sun.COM 17888474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 17898474SJose.Borrego@Sun.COM continue; 17908474SJose.Borrego@Sun.COM 17918474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 17928474SJose.Borrego@Sun.COM continue; 17938474SJose.Borrego@Sun.COM 17948474SJose.Borrego@Sun.COM if (se->se_n_read >= se->se_n_enum) { 17958474SJose.Borrego@Sun.COM se->se_n_read = se->se_n_enum; 17968474SJose.Borrego@Sun.COM break; 17978474SJose.Borrego@Sun.COM } 17988474SJose.Borrego@Sun.COM 17998474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info501); 18008474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 18018474SJose.Borrego@Sun.COM break; 18028474SJose.Borrego@Sun.COM 18038474SJose.Borrego@Sun.COM ++se->se_n_read; 18048474SJose.Borrego@Sun.COM } 18058474SJose.Borrego@Sun.COM 18068474SJose.Borrego@Sun.COM if (se->se_n_read < se->se_n_enum) { 18078474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info501)) 18088474SJose.Borrego@Sun.COM ++se->se_n_read; 18098474SJose.Borrego@Sun.COM } 18108474SJose.Borrego@Sun.COM 18118474SJose.Borrego@Sun.COM infonres->entriesread = se->se_n_read; 18128474SJose.Borrego@Sun.COM infonres->entries = info501; 18138474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 18148474SJose.Borrego@Sun.COM } 18158474SJose.Borrego@Sun.COM 18168474SJose.Borrego@Sun.COM /* 18178474SJose.Borrego@Sun.COM * NetShareEnum Level 502 18188474SJose.Borrego@Sun.COM */ 18198474SJose.Borrego@Sun.COM static DWORD 18208474SJose.Borrego@Sun.COM mlsvc_NetShareEnumLevel502(ndr_xa_t *mxa, 18218474SJose.Borrego@Sun.COM struct mslm_infonres *infonres, srvsvc_enum_t *se, int sticky) 18228474SJose.Borrego@Sun.COM { 18238474SJose.Borrego@Sun.COM struct mslm_SHARE_INFO_502 *info502; 18248474SJose.Borrego@Sun.COM smb_shriter_t iterator; 18258474SJose.Borrego@Sun.COM smb_share_t *si; 18268474SJose.Borrego@Sun.COM DWORD status; 18278474SJose.Borrego@Sun.COM 18288474SJose.Borrego@Sun.COM se->se_n_enum = srvsvc_estimate_objcnt(se->se_prefmaxlen, 18298474SJose.Borrego@Sun.COM se->se_n_total, sizeof (struct mslm_SHARE_INFO_502) + MAXNAMELEN); 18308474SJose.Borrego@Sun.COM if (se->se_n_enum == 0) 18318474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 18328474SJose.Borrego@Sun.COM 18338474SJose.Borrego@Sun.COM info502 = NDR_NEWN(mxa, struct mslm_SHARE_INFO_502, 18348474SJose.Borrego@Sun.COM se->se_n_enum); 18358474SJose.Borrego@Sun.COM if (info502 == NULL) 18368474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 18378474SJose.Borrego@Sun.COM 18388474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 18398474SJose.Borrego@Sun.COM 18408474SJose.Borrego@Sun.COM se->se_n_read = 0; 18418474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != NULL) { 18428474SJose.Borrego@Sun.COM if (se->se_n_skip > 0) { 18438474SJose.Borrego@Sun.COM --se->se_n_skip; 18448474SJose.Borrego@Sun.COM continue; 18458474SJose.Borrego@Sun.COM } 18468474SJose.Borrego@Sun.COM 18478474SJose.Borrego@Sun.COM ++se->se_resume_handle; 18488474SJose.Borrego@Sun.COM 18498474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 18508474SJose.Borrego@Sun.COM continue; 18518474SJose.Borrego@Sun.COM 18528474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 18538474SJose.Borrego@Sun.COM continue; 18548474SJose.Borrego@Sun.COM 18558474SJose.Borrego@Sun.COM if (se->se_n_read >= se->se_n_enum) { 18568474SJose.Borrego@Sun.COM se->se_n_read = se->se_n_enum; 18578474SJose.Borrego@Sun.COM break; 18588474SJose.Borrego@Sun.COM } 18598474SJose.Borrego@Sun.COM 18608474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info502); 18618474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 18628474SJose.Borrego@Sun.COM break; 18638474SJose.Borrego@Sun.COM 18648474SJose.Borrego@Sun.COM ++se->se_n_read; 18658474SJose.Borrego@Sun.COM } 18668474SJose.Borrego@Sun.COM 18678474SJose.Borrego@Sun.COM if (se->se_n_read < se->se_n_enum) { 18688474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info502)) 18698474SJose.Borrego@Sun.COM ++se->se_n_read; 18708474SJose.Borrego@Sun.COM } 18718474SJose.Borrego@Sun.COM 18728474SJose.Borrego@Sun.COM infonres->entriesread = se->se_n_read; 18738474SJose.Borrego@Sun.COM infonres->entries = info502; 18748474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 18758474SJose.Borrego@Sun.COM } 18768474SJose.Borrego@Sun.COM 18778474SJose.Borrego@Sun.COM /* 18788474SJose.Borrego@Sun.COM * mlsvc_NetShareEnumCommon 18798474SJose.Borrego@Sun.COM * 18808474SJose.Borrego@Sun.COM * Build the levels 0, 1, 2, 501 and 502 share information. This function 18818474SJose.Borrego@Sun.COM * is called by the various NetShareEnum levels for each share. If 18828474SJose.Borrego@Sun.COM * we cannot build the share data for some reason, we return an error 18838474SJose.Borrego@Sun.COM * but the actual value of the error is not important to the caller. 18848474SJose.Borrego@Sun.COM * The caller just needs to know not to include this info in the RPC 18858474SJose.Borrego@Sun.COM * response. 18868474SJose.Borrego@Sun.COM * 18878474SJose.Borrego@Sun.COM * Returns: 18888474SJose.Borrego@Sun.COM * ERROR_SUCCESS 18898474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY 18908474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL 18918474SJose.Borrego@Sun.COM */ 18928474SJose.Borrego@Sun.COM static DWORD 18938474SJose.Borrego@Sun.COM mlsvc_NetShareEnumCommon(ndr_xa_t *mxa, srvsvc_enum_t *se, 18948474SJose.Borrego@Sun.COM smb_share_t *si, void *infop) 18958474SJose.Borrego@Sun.COM { 18968474SJose.Borrego@Sun.COM struct mslm_SHARE_INFO_0 *info0; 18978474SJose.Borrego@Sun.COM struct mslm_SHARE_INFO_1 *info1; 18988474SJose.Borrego@Sun.COM struct mslm_SHARE_INFO_2 *info2; 18998474SJose.Borrego@Sun.COM struct mslm_SHARE_INFO_501 *info501; 19008474SJose.Borrego@Sun.COM struct mslm_SHARE_INFO_502 *info502; 19018474SJose.Borrego@Sun.COM int i = se->se_n_read; 19028474SJose.Borrego@Sun.COM 19038474SJose.Borrego@Sun.COM switch (se->se_level) { 19048474SJose.Borrego@Sun.COM case 0: 19058474SJose.Borrego@Sun.COM info0 = (struct mslm_SHARE_INFO_0 *)infop; 19068474SJose.Borrego@Sun.COM info0[i].shi0_netname 19078474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, si->shr_name); 19088474SJose.Borrego@Sun.COM 19098474SJose.Borrego@Sun.COM if (info0[i].shi0_netname == NULL) 19108474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 19118474SJose.Borrego@Sun.COM break; 19128474SJose.Borrego@Sun.COM 19138474SJose.Borrego@Sun.COM case 1: 19148474SJose.Borrego@Sun.COM info1 = (struct mslm_SHARE_INFO_1 *)infop; 19158474SJose.Borrego@Sun.COM info1[i].shi1_netname 19168474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, si->shr_name); 19178474SJose.Borrego@Sun.COM info1[i].shi1_remark 19188474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, si->shr_cmnt); 19198474SJose.Borrego@Sun.COM 19208474SJose.Borrego@Sun.COM info1[i].shi1_type = si->shr_type; 19218474SJose.Borrego@Sun.COM 19228474SJose.Borrego@Sun.COM if (!info1[i].shi1_netname || !info1[i].shi1_remark) 19238474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 19248474SJose.Borrego@Sun.COM break; 19258474SJose.Borrego@Sun.COM 19268474SJose.Borrego@Sun.COM case 2: 19278474SJose.Borrego@Sun.COM info2 = (struct mslm_SHARE_INFO_2 *)infop; 19288474SJose.Borrego@Sun.COM info2[i].shi2_netname 19298474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, si->shr_name); 19308474SJose.Borrego@Sun.COM info2[i].shi2_remark 19318474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, si->shr_cmnt); 19328474SJose.Borrego@Sun.COM 19338474SJose.Borrego@Sun.COM info2[i].shi2_path 19348474SJose.Borrego@Sun.COM = (uint8_t *)srvsvc_share_mkpath(mxa, si->shr_path); 19358474SJose.Borrego@Sun.COM 19368474SJose.Borrego@Sun.COM info2[i].shi2_type = si->shr_type; 19378474SJose.Borrego@Sun.COM info2[i].shi2_permissions = 0; 19388474SJose.Borrego@Sun.COM info2[i].shi2_max_uses = SHI_USES_UNLIMITED; 19398474SJose.Borrego@Sun.COM info2[i].shi2_current_uses = 0; 19408474SJose.Borrego@Sun.COM info2[i].shi2_passwd 19418474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, empty_string); 19428474SJose.Borrego@Sun.COM 19438474SJose.Borrego@Sun.COM if (!info2[i].shi2_netname || !info2[i].shi2_remark || 19448474SJose.Borrego@Sun.COM !info2[i].shi2_passwd || !info2[i].shi2_path) 19458474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 19468474SJose.Borrego@Sun.COM 19478474SJose.Borrego@Sun.COM break; 19488474SJose.Borrego@Sun.COM 19498474SJose.Borrego@Sun.COM case 501: 19508474SJose.Borrego@Sun.COM info501 = (struct mslm_SHARE_INFO_501 *)infop; 19518474SJose.Borrego@Sun.COM info501[i].shi501_netname 19528474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, si->shr_name); 19538474SJose.Borrego@Sun.COM info501[i].shi501_remark 19548474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, si->shr_cmnt); 19558474SJose.Borrego@Sun.COM 19568474SJose.Borrego@Sun.COM info501[i].shi501_type = si->shr_type; 19578474SJose.Borrego@Sun.COM info501[i].shi501_flags = 0; 19588474SJose.Borrego@Sun.COM 19598474SJose.Borrego@Sun.COM if (!info501[i].shi501_netname || !info501[i].shi501_remark) 19608474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 19618474SJose.Borrego@Sun.COM break; 19628474SJose.Borrego@Sun.COM 19638474SJose.Borrego@Sun.COM case 502: 19648474SJose.Borrego@Sun.COM info502 = (struct mslm_SHARE_INFO_502 *)infop; 19658474SJose.Borrego@Sun.COM info502[i].shi502_netname 19668474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, si->shr_name); 19678474SJose.Borrego@Sun.COM info502[i].shi502_remark 19688474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, si->shr_cmnt); 19698474SJose.Borrego@Sun.COM 19708474SJose.Borrego@Sun.COM info502[i].shi502_path 19718474SJose.Borrego@Sun.COM = (uint8_t *)srvsvc_share_mkpath(mxa, si->shr_path); 19728474SJose.Borrego@Sun.COM 19738474SJose.Borrego@Sun.COM info502[i].shi502_type = si->shr_type; 19748474SJose.Borrego@Sun.COM info502[i].shi502_permissions = 0; 19758474SJose.Borrego@Sun.COM info502[i].shi502_max_uses = SHI_USES_UNLIMITED; 19768474SJose.Borrego@Sun.COM info502[i].shi502_current_uses = 0; 19778474SJose.Borrego@Sun.COM info502[i].shi502_passwd 19788474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, empty_string); 19798474SJose.Borrego@Sun.COM 19808474SJose.Borrego@Sun.COM info502[i].shi502_reserved = 0; 19818474SJose.Borrego@Sun.COM info502[i].shi502_security_descriptor = 0; 19828474SJose.Borrego@Sun.COM 19838474SJose.Borrego@Sun.COM if (!info502[i].shi502_netname || !info502[i].shi502_remark || 19848474SJose.Borrego@Sun.COM !info502[i].shi502_passwd || !info502[i].shi502_path) 19858474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 19868474SJose.Borrego@Sun.COM break; 19878474SJose.Borrego@Sun.COM 19888474SJose.Borrego@Sun.COM default: 19898474SJose.Borrego@Sun.COM return (ERROR_INVALID_LEVEL); 19908474SJose.Borrego@Sun.COM } 19918474SJose.Borrego@Sun.COM 19928474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 19938474SJose.Borrego@Sun.COM } 19948474SJose.Borrego@Sun.COM 19958474SJose.Borrego@Sun.COM /* 19968474SJose.Borrego@Sun.COM * srvsvc_add_autohome 19978474SJose.Borrego@Sun.COM * 19988474SJose.Borrego@Sun.COM * Add the autohome share for the user. The share must not be a permanent 19998474SJose.Borrego@Sun.COM * share to avoid duplicates. 20008474SJose.Borrego@Sun.COM */ 20018474SJose.Borrego@Sun.COM static boolean_t 20028474SJose.Borrego@Sun.COM srvsvc_add_autohome(ndr_xa_t *mxa, srvsvc_enum_t *se, void *infop) 20038474SJose.Borrego@Sun.COM { 20048474SJose.Borrego@Sun.COM smb_opipe_context_t *ctx = &mxa->pipe->np_ctx; 20058474SJose.Borrego@Sun.COM char *username = ctx->oc_account; 20068474SJose.Borrego@Sun.COM smb_share_t si; 20078474SJose.Borrego@Sun.COM DWORD status; 20088474SJose.Borrego@Sun.COM 20098474SJose.Borrego@Sun.COM if (smb_shr_get(username, &si) != NERR_Success) 20108474SJose.Borrego@Sun.COM return (B_FALSE); 20118474SJose.Borrego@Sun.COM 20128474SJose.Borrego@Sun.COM if ((si.shr_flags & SMB_SHRF_AUTOHOME) == 0) 20138474SJose.Borrego@Sun.COM return (B_FALSE); 20148474SJose.Borrego@Sun.COM 20158474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, &si, infop); 20168474SJose.Borrego@Sun.COM return (status == ERROR_SUCCESS); 20178474SJose.Borrego@Sun.COM } 20188474SJose.Borrego@Sun.COM 20198474SJose.Borrego@Sun.COM /* 20208474SJose.Borrego@Sun.COM * srvsvc_share_mkpath 20218474SJose.Borrego@Sun.COM * 20228474SJose.Borrego@Sun.COM * Create the share path required by the share enum calls. The path 20238474SJose.Borrego@Sun.COM * is created in a heap buffer ready for use by the caller. 20248474SJose.Borrego@Sun.COM * 20258474SJose.Borrego@Sun.COM * Some Windows over-the-wire backup applications do not work unless a 20268474SJose.Borrego@Sun.COM * drive letter is present in the share path. We don't care about the 20278474SJose.Borrego@Sun.COM * drive letter since the path is fully qualified with the volume name. 20288474SJose.Borrego@Sun.COM * 20298474SJose.Borrego@Sun.COM * Windows clients seem to be mostly okay with forward slashes in 20308474SJose.Borrego@Sun.COM * share paths but they cannot handle one immediately after the drive 20318474SJose.Borrego@Sun.COM * letter, i.e. B:/. For consistency we convert all the slashes in 20328474SJose.Borrego@Sun.COM * the path. 20338474SJose.Borrego@Sun.COM * 20348474SJose.Borrego@Sun.COM * Returns a pointer to a heap buffer containing the share path, which 20358474SJose.Borrego@Sun.COM * could be a null pointer if the heap allocation fails. 20368474SJose.Borrego@Sun.COM */ 20378474SJose.Borrego@Sun.COM static char * 20388474SJose.Borrego@Sun.COM srvsvc_share_mkpath(ndr_xa_t *mxa, char *path) 20398474SJose.Borrego@Sun.COM { 20408474SJose.Borrego@Sun.COM char tmpbuf[MAXPATHLEN]; 20418474SJose.Borrego@Sun.COM char *p; 20428474SJose.Borrego@Sun.COM 20438474SJose.Borrego@Sun.COM if (strlen(path) == 0) 20448474SJose.Borrego@Sun.COM return (NDR_STRDUP(mxa, path)); 20458474SJose.Borrego@Sun.COM 20468474SJose.Borrego@Sun.COM /* 20478474SJose.Borrego@Sun.COM * Strip the volume name from the path (/vol1/home -> /home). 20488474SJose.Borrego@Sun.COM */ 20498474SJose.Borrego@Sun.COM p = path; 20508474SJose.Borrego@Sun.COM p += strspn(p, "/"); 20518474SJose.Borrego@Sun.COM p += strcspn(p, "/"); 20528474SJose.Borrego@Sun.COM p += strspn(p, "/"); 20538474SJose.Borrego@Sun.COM (void) snprintf(tmpbuf, MAXPATHLEN, "%c:/%s", 'B', p); 20548474SJose.Borrego@Sun.COM (void) strsubst(tmpbuf, '/', '\\'); 20558474SJose.Borrego@Sun.COM 20568474SJose.Borrego@Sun.COM return (NDR_STRDUP(mxa, tmpbuf)); 20578474SJose.Borrego@Sun.COM } 20588474SJose.Borrego@Sun.COM 20598474SJose.Borrego@Sun.COM /* 20608474SJose.Borrego@Sun.COM * srvsvc_s_NetShareDel 20618474SJose.Borrego@Sun.COM * 20628474SJose.Borrego@Sun.COM * Delete a share. Only the administrator, or a member of the domain 20638474SJose.Borrego@Sun.COM * administrators group, is allowed to delete shares. 20648474SJose.Borrego@Sun.COM * 20658474SJose.Borrego@Sun.COM * This interface is used by the rmtshare command from the NT resource 20668474SJose.Borrego@Sun.COM * kit. Rmtshare allows a client to add or remove shares on a server 20678474SJose.Borrego@Sun.COM * from the client's command line. 20688474SJose.Borrego@Sun.COM * 20698474SJose.Borrego@Sun.COM * Returns Win32 error codes. 20708474SJose.Borrego@Sun.COM */ 20718474SJose.Borrego@Sun.COM static int 20728474SJose.Borrego@Sun.COM srvsvc_s_NetShareDel(void *arg, ndr_xa_t *mxa) 20738474SJose.Borrego@Sun.COM { 20748474SJose.Borrego@Sun.COM struct mslm_NetShareDel *param = arg; 20758474SJose.Borrego@Sun.COM 20768474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa) || 20778474SJose.Borrego@Sun.COM smb_shr_is_restricted((char *)param->netname)) { 20788474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 20798474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20808474SJose.Borrego@Sun.COM } 20818474SJose.Borrego@Sun.COM 20828474SJose.Borrego@Sun.COM param->status = srvsvc_sa_delete((char *)param->netname); 20838474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20848474SJose.Borrego@Sun.COM } 20858474SJose.Borrego@Sun.COM 20868474SJose.Borrego@Sun.COM /* 20878474SJose.Borrego@Sun.COM * srvsvc_s_NetGetFileSecurity 20888474SJose.Borrego@Sun.COM * 20898474SJose.Borrego@Sun.COM * Get security descriptor of the requested file/folder 20908474SJose.Borrego@Sun.COM * 20918474SJose.Borrego@Sun.COM * Right now, just returns ERROR_ACCESS_DENIED, because we cannot 20928474SJose.Borrego@Sun.COM * get the requested SD here in RPC code. 20938474SJose.Borrego@Sun.COM */ 20948474SJose.Borrego@Sun.COM /*ARGSUSED*/ 20958474SJose.Borrego@Sun.COM static int 20968474SJose.Borrego@Sun.COM srvsvc_s_NetGetFileSecurity(void *arg, ndr_xa_t *mxa) 20978474SJose.Borrego@Sun.COM { 20988474SJose.Borrego@Sun.COM struct mslm_NetGetFileSecurity *param = arg; 20998474SJose.Borrego@Sun.COM 21008474SJose.Borrego@Sun.COM param->length = 0; 21018474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 21028474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 21038474SJose.Borrego@Sun.COM } 21048474SJose.Borrego@Sun.COM 21058474SJose.Borrego@Sun.COM /* 21068474SJose.Borrego@Sun.COM * srvsvc_s_NetSetFileSecurity 21078474SJose.Borrego@Sun.COM * 21088474SJose.Borrego@Sun.COM * Set the given security descriptor for the requested file/folder 21098474SJose.Borrego@Sun.COM * 21108474SJose.Borrego@Sun.COM * Right now, just returns ERROR_ACCESS_DENIED, because we cannot 21118474SJose.Borrego@Sun.COM * set the requested SD here in RPC code. 21128474SJose.Borrego@Sun.COM */ 21138474SJose.Borrego@Sun.COM /*ARGSUSED*/ 21148474SJose.Borrego@Sun.COM static int 21158474SJose.Borrego@Sun.COM srvsvc_s_NetSetFileSecurity(void *arg, ndr_xa_t *mxa) 21168474SJose.Borrego@Sun.COM { 21178474SJose.Borrego@Sun.COM struct mslm_NetSetFileSecurity *param = arg; 21188474SJose.Borrego@Sun.COM 21198474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 21208474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 21218474SJose.Borrego@Sun.COM } 21228474SJose.Borrego@Sun.COM 21238474SJose.Borrego@Sun.COM /* 21248474SJose.Borrego@Sun.COM * If the default "smb" share group exists then return the group 21258474SJose.Borrego@Sun.COM * handle, otherwise create the group and return the handle. 21268474SJose.Borrego@Sun.COM * 21278474SJose.Borrego@Sun.COM * All shares created via the srvsvc will be added to the "smb" 21288474SJose.Borrego@Sun.COM * group. 21298474SJose.Borrego@Sun.COM */ 21308474SJose.Borrego@Sun.COM static sa_group_t 21318474SJose.Borrego@Sun.COM srvsvc_sa_get_smbgrp(sa_handle_t handle) 21328474SJose.Borrego@Sun.COM { 21338474SJose.Borrego@Sun.COM sa_group_t group = NULL; 21348474SJose.Borrego@Sun.COM int err; 21358474SJose.Borrego@Sun.COM 21368474SJose.Borrego@Sun.COM group = sa_get_group(handle, SMB_DEFAULT_SHARE_GROUP); 21378474SJose.Borrego@Sun.COM if (group != NULL) 21388474SJose.Borrego@Sun.COM return (group); 21398474SJose.Borrego@Sun.COM 21408474SJose.Borrego@Sun.COM group = sa_create_group(handle, SMB_DEFAULT_SHARE_GROUP, &err); 21418474SJose.Borrego@Sun.COM if (group == NULL) 21428474SJose.Borrego@Sun.COM return (NULL); 21438474SJose.Borrego@Sun.COM 21448474SJose.Borrego@Sun.COM if (sa_create_optionset(group, SMB_DEFAULT_SHARE_GROUP) == NULL) { 21458474SJose.Borrego@Sun.COM (void) sa_remove_group(group); 21468474SJose.Borrego@Sun.COM group = NULL; 21478474SJose.Borrego@Sun.COM } 21488474SJose.Borrego@Sun.COM 21498474SJose.Borrego@Sun.COM return (group); 21508474SJose.Borrego@Sun.COM } 21518474SJose.Borrego@Sun.COM 21528474SJose.Borrego@Sun.COM /* 21538474SJose.Borrego@Sun.COM * Stores the given share in sharemgr 21548474SJose.Borrego@Sun.COM */ 21558474SJose.Borrego@Sun.COM static uint32_t 21568474SJose.Borrego@Sun.COM srvsvc_sa_add(char *sharename, char *path, char *cmnt) 21578474SJose.Borrego@Sun.COM { 21588474SJose.Borrego@Sun.COM sa_handle_t handle; 21598474SJose.Borrego@Sun.COM sa_share_t share; 21608474SJose.Borrego@Sun.COM sa_group_t group; 21618474SJose.Borrego@Sun.COM sa_resource_t resource; 21628474SJose.Borrego@Sun.COM boolean_t new_share = B_FALSE; 21638474SJose.Borrego@Sun.COM uint32_t status = NERR_Success; 21648474SJose.Borrego@Sun.COM int err; 21658474SJose.Borrego@Sun.COM 21668474SJose.Borrego@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 21678474SJose.Borrego@Sun.COM return (NERR_InternalError); 21688474SJose.Borrego@Sun.COM 21698474SJose.Borrego@Sun.COM share = sa_find_share(handle, path); 21708474SJose.Borrego@Sun.COM if (share == NULL) { 21718474SJose.Borrego@Sun.COM group = srvsvc_sa_get_smbgrp(handle); 21728474SJose.Borrego@Sun.COM if (group == NULL) { 21738474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 21748474SJose.Borrego@Sun.COM return (NERR_InternalError); 21758474SJose.Borrego@Sun.COM } 21768474SJose.Borrego@Sun.COM 21778474SJose.Borrego@Sun.COM share = sa_add_share(group, path, SA_SHARE_PERMANENT, &err); 21788474SJose.Borrego@Sun.COM if (share == NULL) { 21798474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 21808474SJose.Borrego@Sun.COM return (NERR_InternalError); 21818474SJose.Borrego@Sun.COM } 21828474SJose.Borrego@Sun.COM new_share = B_TRUE; 21838474SJose.Borrego@Sun.COM } 21848474SJose.Borrego@Sun.COM 21858474SJose.Borrego@Sun.COM resource = sa_get_share_resource(share, sharename); 21868474SJose.Borrego@Sun.COM if (resource == NULL) { 21878474SJose.Borrego@Sun.COM resource = sa_add_resource(share, sharename, 21888474SJose.Borrego@Sun.COM SA_SHARE_PERMANENT, &err); 21898474SJose.Borrego@Sun.COM if (resource == NULL) { 21908474SJose.Borrego@Sun.COM if (new_share) 21918474SJose.Borrego@Sun.COM (void) sa_remove_share(share); 21928474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 21938474SJose.Borrego@Sun.COM return (NERR_InternalError); 21948474SJose.Borrego@Sun.COM } 21958474SJose.Borrego@Sun.COM } 21968474SJose.Borrego@Sun.COM 21978474SJose.Borrego@Sun.COM (void) sa_set_resource_description(resource, cmnt); 21988474SJose.Borrego@Sun.COM 21998474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 22008474SJose.Borrego@Sun.COM return (status); 22018474SJose.Borrego@Sun.COM } 22028474SJose.Borrego@Sun.COM 22038474SJose.Borrego@Sun.COM /* 22048474SJose.Borrego@Sun.COM * Removes the share from sharemgr 22058474SJose.Borrego@Sun.COM */ 22068474SJose.Borrego@Sun.COM static uint32_t 22078474SJose.Borrego@Sun.COM srvsvc_sa_delete(char *sharename) 22088474SJose.Borrego@Sun.COM { 22098474SJose.Borrego@Sun.COM sa_handle_t handle; 22108474SJose.Borrego@Sun.COM sa_resource_t resource; 22118474SJose.Borrego@Sun.COM uint32_t status; 22128474SJose.Borrego@Sun.COM 22138474SJose.Borrego@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 22148474SJose.Borrego@Sun.COM return (NERR_InternalError); 22158474SJose.Borrego@Sun.COM 22168474SJose.Borrego@Sun.COM status = NERR_InternalError; 22178474SJose.Borrego@Sun.COM if ((resource = sa_find_resource(handle, sharename)) != NULL) { 22188474SJose.Borrego@Sun.COM if (sa_remove_resource(resource) == SA_OK) 22198474SJose.Borrego@Sun.COM status = NERR_Success; 22208474SJose.Borrego@Sun.COM } 22218474SJose.Borrego@Sun.COM 22228474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 22238474SJose.Borrego@Sun.COM return (status); 22248474SJose.Borrego@Sun.COM } 22258474SJose.Borrego@Sun.COM 22268474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[] = { 22278474SJose.Borrego@Sun.COM { srvsvc_s_NetConnectEnum, SRVSVC_OPNUM_NetConnectEnum }, 22288474SJose.Borrego@Sun.COM { srvsvc_s_NetFileEnum, SRVSVC_OPNUM_NetFileEnum }, 22298474SJose.Borrego@Sun.COM { srvsvc_s_NetFileClose, SRVSVC_OPNUM_NetFileClose }, 22308474SJose.Borrego@Sun.COM { srvsvc_s_NetShareGetInfo, SRVSVC_OPNUM_NetShareGetInfo }, 22318474SJose.Borrego@Sun.COM { srvsvc_s_NetShareSetInfo, SRVSVC_OPNUM_NetShareSetInfo }, 22328474SJose.Borrego@Sun.COM { srvsvc_s_NetSessionEnum, SRVSVC_OPNUM_NetSessionEnum }, 22338474SJose.Borrego@Sun.COM { srvsvc_s_NetSessionDel, SRVSVC_OPNUM_NetSessionDel }, 22348474SJose.Borrego@Sun.COM { srvsvc_s_NetServerGetInfo, SRVSVC_OPNUM_NetServerGetInfo }, 22358474SJose.Borrego@Sun.COM { srvsvc_s_NetRemoteTOD, SRVSVC_OPNUM_NetRemoteTOD }, 22368474SJose.Borrego@Sun.COM { srvsvc_s_NetNameValidate, SRVSVC_OPNUM_NetNameValidate }, 22378474SJose.Borrego@Sun.COM { srvsvc_s_NetShareAdd, SRVSVC_OPNUM_NetShareAdd }, 22388474SJose.Borrego@Sun.COM { srvsvc_s_NetShareDel, SRVSVC_OPNUM_NetShareDel }, 22398474SJose.Borrego@Sun.COM { srvsvc_s_NetShareEnum, SRVSVC_OPNUM_NetShareEnum }, 22408474SJose.Borrego@Sun.COM { srvsvc_s_NetShareEnumSticky, SRVSVC_OPNUM_NetShareEnumSticky }, 22418474SJose.Borrego@Sun.COM { srvsvc_s_NetGetFileSecurity, SRVSVC_OPNUM_NetGetFileSecurity }, 22428474SJose.Borrego@Sun.COM { srvsvc_s_NetSetFileSecurity, SRVSVC_OPNUM_NetSetFileSecurity }, 22438474SJose.Borrego@Sun.COM {0} 22448474SJose.Borrego@Sun.COM }; 2245