18474SJose.Borrego@Sun.COM /* 28474SJose.Borrego@Sun.COM * CDDL HEADER START 38474SJose.Borrego@Sun.COM * 48474SJose.Borrego@Sun.COM * The contents of this file are subject to the terms of the 58474SJose.Borrego@Sun.COM * Common Development and Distribution License (the "License"). 68474SJose.Borrego@Sun.COM * You may not use this file except in compliance with the License. 78474SJose.Borrego@Sun.COM * 88474SJose.Borrego@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 98474SJose.Borrego@Sun.COM * or http://www.opensolaris.org/os/licensing. 108474SJose.Borrego@Sun.COM * See the License for the specific language governing permissions 118474SJose.Borrego@Sun.COM * and limitations under the License. 128474SJose.Borrego@Sun.COM * 138474SJose.Borrego@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 148474SJose.Borrego@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 158474SJose.Borrego@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 168474SJose.Borrego@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 178474SJose.Borrego@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 188474SJose.Borrego@Sun.COM * 198474SJose.Borrego@Sun.COM * CDDL HEADER END 208474SJose.Borrego@Sun.COM */ 218474SJose.Borrego@Sun.COM /* 228474SJose.Borrego@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 238474SJose.Borrego@Sun.COM * Use is subject to license terms. 248474SJose.Borrego@Sun.COM */ 258474SJose.Borrego@Sun.COM 268474SJose.Borrego@Sun.COM /* 278474SJose.Borrego@Sun.COM * Server Service RPC (SRVSVC) server-side interface definition. 288474SJose.Borrego@Sun.COM * The server service provides a remote administration interface. 298474SJose.Borrego@Sun.COM * 308474SJose.Borrego@Sun.COM * This service uses NERR/Win32 error codes rather than NT status 318474SJose.Borrego@Sun.COM * values. 328474SJose.Borrego@Sun.COM */ 338474SJose.Borrego@Sun.COM 348474SJose.Borrego@Sun.COM #include <sys/errno.h> 358474SJose.Borrego@Sun.COM #include <unistd.h> 368474SJose.Borrego@Sun.COM #include <netdb.h> 378474SJose.Borrego@Sun.COM #include <strings.h> 388474SJose.Borrego@Sun.COM #include <time.h> 398474SJose.Borrego@Sun.COM #include <thread.h> 408474SJose.Borrego@Sun.COM #include <ctype.h> 418474SJose.Borrego@Sun.COM #include <stdlib.h> 428474SJose.Borrego@Sun.COM #include <string.h> 438474SJose.Borrego@Sun.COM #include <sys/types.h> 448474SJose.Borrego@Sun.COM #include <sys/socket.h> 458474SJose.Borrego@Sun.COM #include <netinet/in.h> 468474SJose.Borrego@Sun.COM #include <arpa/inet.h> 478474SJose.Borrego@Sun.COM #include <libshare.h> 488474SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h> 498474SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h> 508474SJose.Borrego@Sun.COM #include <smbsrv/lmerr.h> 518474SJose.Borrego@Sun.COM #include <smbsrv/nterror.h> 528474SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h> 538474SJose.Borrego@Sun.COM #include <smbsrv/cifs.h> 548474SJose.Borrego@Sun.COM #include <smbsrv/netrauth.h> 558474SJose.Borrego@Sun.COM #include <smbsrv/ndl/srvsvc.ndl> 568474SJose.Borrego@Sun.COM #include <smbsrv/smb_common_door.h> 579832Samw@Sun.COM #include "mlsvc.h" 588474SJose.Borrego@Sun.COM 598474SJose.Borrego@Sun.COM #define SV_TYPE_SENT_BY_ME (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | SV_TYPE_NT) 608474SJose.Borrego@Sun.COM 618474SJose.Borrego@Sun.COM /* 628474SJose.Borrego@Sun.COM * Qualifier types for NetConnectEnum. 638474SJose.Borrego@Sun.COM */ 648474SJose.Borrego@Sun.COM #define SRVSVC_CONNECT_ENUM_NULL 0 658474SJose.Borrego@Sun.COM #define SRVSVC_CONNECT_ENUM_SHARE 1 668474SJose.Borrego@Sun.COM #define SRVSVC_CONNECT_ENUM_WKSTN 2 678474SJose.Borrego@Sun.COM 68*10122SJordan.Brown@Sun.COM #define SMB_SRVSVC_MAXBUFLEN (8 * 1024 * 1024) 69*10122SJordan.Brown@Sun.COM #define SMB_SRVSVC_MAXPREFLEN ((uint32_t)(-1)) 708474SJose.Borrego@Sun.COM 719832Samw@Sun.COM typedef struct srvsvc_sd { 729832Samw@Sun.COM uint8_t *sd_buf; 739832Samw@Sun.COM uint32_t sd_size; 749832Samw@Sun.COM } srvsvc_sd_t; 759832Samw@Sun.COM 769832Samw@Sun.COM typedef struct srvsvc_netshare_setinfo { 779832Samw@Sun.COM char *nss_netname; 789832Samw@Sun.COM char *nss_comment; 799832Samw@Sun.COM char *nss_path; 809832Samw@Sun.COM uint32_t nss_type; 819832Samw@Sun.COM srvsvc_sd_t nss_sd; 829832Samw@Sun.COM } srvsvc_netshare_setinfo_t; 839832Samw@Sun.COM 849832Samw@Sun.COM typedef union srvsvc_netshare_getinfo { 859832Samw@Sun.COM struct mslm_NetShareInfo_0 nsg_info0; 869832Samw@Sun.COM struct mslm_NetShareInfo_1 nsg_info1; 879832Samw@Sun.COM struct mslm_NetShareInfo_2 nsg_info2; 889832Samw@Sun.COM struct mslm_NetShareInfo_501 nsg_info501; 899832Samw@Sun.COM struct mslm_NetShareInfo_502 nsg_info502; 909832Samw@Sun.COM struct mslm_NetShareInfo_503 nsg_info503; 919832Samw@Sun.COM struct mslm_NetShareInfo_1004 nsg_info1004; 929832Samw@Sun.COM struct mslm_NetShareInfo_1005 nsg_info1005; 939832Samw@Sun.COM struct mslm_NetShareInfo_1006 nsg_info1006; 949832Samw@Sun.COM struct mslm_NetShareInfo_1501 nsg_info1501; 959832Samw@Sun.COM } srvsvc_netshare_getinfo_t; 969832Samw@Sun.COM 97*10122SJordan.Brown@Sun.COM typedef struct mslm_infonres srvsvc_infonres_t; 98*10122SJordan.Brown@Sun.COM typedef struct mslm_NetConnectEnum srvsvc_NetConnectEnum_t; 99*10122SJordan.Brown@Sun.COM 100*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_level0(ndr_xa_t *, smb_svcenum_t *, 101*10122SJordan.Brown@Sun.COM srvsvc_NetConnectEnum_t *); 102*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_level1(ndr_xa_t *, smb_svcenum_t *, 103*10122SJordan.Brown@Sun.COM srvsvc_NetConnectEnum_t *); 104*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_common(ndr_xa_t *, 105*10122SJordan.Brown@Sun.COM srvsvc_NetConnectInfo_t *, smb_netsvc_t *, smb_svcenum_t *); 106*10122SJordan.Brown@Sun.COM 107*10122SJordan.Brown@Sun.COM static DWORD srvsvc_NetFileEnum2(ndr_xa_t *, struct mslm_NetFileEnum *, 108*10122SJordan.Brown@Sun.COM smb_svcenum_t *se); 109*10122SJordan.Brown@Sun.COM static DWORD srvsvc_NetFileEnum3(ndr_xa_t *, struct mslm_NetFileEnum *, 110*10122SJordan.Brown@Sun.COM smb_svcenum_t *se); 111*10122SJordan.Brown@Sun.COM 112*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_NetSessionEnumCommon(ndr_xa_t *, srvsvc_infonres_t *, 113*10122SJordan.Brown@Sun.COM smb_netsvc_t *, smb_svcenum_t *); 114*10122SJordan.Brown@Sun.COM 115*10122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel0(ndr_xa_t *, srvsvc_infonres_t *, 116*10122SJordan.Brown@Sun.COM smb_svcenum_t *, int); 117*10122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel1(ndr_xa_t *, srvsvc_infonres_t *, 118*10122SJordan.Brown@Sun.COM smb_svcenum_t *, int); 119*10122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel2(ndr_xa_t *, srvsvc_infonres_t *, 120*10122SJordan.Brown@Sun.COM smb_svcenum_t *, int); 121*10122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel501(ndr_xa_t *, srvsvc_infonres_t *, 122*10122SJordan.Brown@Sun.COM smb_svcenum_t *, int); 123*10122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel502(ndr_xa_t *, srvsvc_infonres_t *, 124*10122SJordan.Brown@Sun.COM smb_svcenum_t *, int); 125*10122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumCommon(ndr_xa_t *, smb_svcenum_t *, 126*10122SJordan.Brown@Sun.COM smb_share_t *, void *); 127*10122SJordan.Brown@Sun.COM static boolean_t srvsvc_add_autohome(ndr_xa_t *, smb_svcenum_t *, void *); 1288474SJose.Borrego@Sun.COM static char *srvsvc_share_mkpath(ndr_xa_t *, char *); 1299832Samw@Sun.COM static uint32_t srvsvc_share_getsd(ndr_xa_t *, smb_share_t *, srvsvc_sd_t *); 1308474SJose.Borrego@Sun.COM 1318474SJose.Borrego@Sun.COM static int srvsvc_netconnect_qualifier(const char *); 132*10122SJordan.Brown@Sun.COM static void srvsvc_estimate_limit(smb_svcenum_t *, uint32_t); 133*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_sessions(void); 134*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_connections(uint32_t, const char *); 135*10122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_files(void); 1368474SJose.Borrego@Sun.COM 1379832Samw@Sun.COM static uint32_t srvsvc_modify_share(smb_share_t *, 1389832Samw@Sun.COM srvsvc_netshare_setinfo_t *); 1399832Samw@Sun.COM static uint32_t srvsvc_modify_transient_share(smb_share_t *, 1409832Samw@Sun.COM srvsvc_netshare_setinfo_t *); 1419832Samw@Sun.COM static uint32_t srvsvc_update_share_flags(smb_share_t *, uint32_t); 1429832Samw@Sun.COM 1438474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_add(char *, char *, char *); 1448474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_delete(char *); 1459832Samw@Sun.COM static uint32_t srvsvc_sa_modify(smb_share_t *, srvsvc_netshare_setinfo_t *); 1469832Samw@Sun.COM static uint32_t srvsvc_sa_setattr(smb_share_t *); 1478474SJose.Borrego@Sun.COM 1488474SJose.Borrego@Sun.COM static char empty_string[1]; 1498474SJose.Borrego@Sun.COM 1508474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[]; 1518474SJose.Borrego@Sun.COM 1528474SJose.Borrego@Sun.COM static ndr_service_t srvsvc_service = { 1538474SJose.Borrego@Sun.COM "SRVSVC", /* name */ 1548474SJose.Borrego@Sun.COM "Server services", /* desc */ 1558474SJose.Borrego@Sun.COM "\\srvsvc", /* endpoint */ 1568474SJose.Borrego@Sun.COM PIPE_NTSVCS, /* sec_addr_port */ 1578474SJose.Borrego@Sun.COM "4b324fc8-1670-01d3-1278-5a47bf6ee188", 3, /* abstract */ 1588474SJose.Borrego@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 1598474SJose.Borrego@Sun.COM 0, /* no bind_instance_size */ 1608474SJose.Borrego@Sun.COM 0, /* no bind_req() */ 1618474SJose.Borrego@Sun.COM 0, /* no unbind_and_close() */ 1628474SJose.Borrego@Sun.COM 0, /* use generic_call_stub() */ 1638474SJose.Borrego@Sun.COM &TYPEINFO(srvsvc_interface), /* interface ti */ 1648474SJose.Borrego@Sun.COM srvsvc_stub_table /* stub_table */ 1658474SJose.Borrego@Sun.COM }; 1668474SJose.Borrego@Sun.COM 1678474SJose.Borrego@Sun.COM /* 1688474SJose.Borrego@Sun.COM * srvsvc_initialize 1698474SJose.Borrego@Sun.COM * 1708474SJose.Borrego@Sun.COM * This function registers the SRVSVC RPC interface with the RPC runtime 1718474SJose.Borrego@Sun.COM * library. It must be called in order to use either the client side 1728474SJose.Borrego@Sun.COM * or the server side functions. 1738474SJose.Borrego@Sun.COM */ 1748474SJose.Borrego@Sun.COM void 1758474SJose.Borrego@Sun.COM srvsvc_initialize(void) 1768474SJose.Borrego@Sun.COM { 1778474SJose.Borrego@Sun.COM (void) ndr_svc_register(&srvsvc_service); 1788474SJose.Borrego@Sun.COM } 1798474SJose.Borrego@Sun.COM 1808474SJose.Borrego@Sun.COM /* 1818474SJose.Borrego@Sun.COM * srvsvc_s_NetConnectEnum 1828474SJose.Borrego@Sun.COM * 1838474SJose.Borrego@Sun.COM * List tree connections made to a share on this server or all tree 1848474SJose.Borrego@Sun.COM * connections established from a specific client. Administrator, 1858474SJose.Borrego@Sun.COM * Server Operator, Print Operator or Power User group membership 1868474SJose.Borrego@Sun.COM * is required to use this interface. 1878474SJose.Borrego@Sun.COM * 1888474SJose.Borrego@Sun.COM * There are three information levels: 0, 1, and 50. We don't support 1898474SJose.Borrego@Sun.COM * level 50, which is only used by Windows 9x clients. 1908474SJose.Borrego@Sun.COM * 1918474SJose.Borrego@Sun.COM * It seems Server Manger (srvmgr) only sends workstation as the qualifier 1928474SJose.Borrego@Sun.COM * and the Computer Management Interface on Windows 2000 doesn't request 1938474SJose.Borrego@Sun.COM * a list of connections. 1948474SJose.Borrego@Sun.COM * 1958474SJose.Borrego@Sun.COM * Return Values: 1968474SJose.Borrego@Sun.COM * ERROR_SUCCESS Success 1978474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED Caller does not have access to this call. 1988474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER One of the parameters is invalid. 1998474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL Unknown information level specified. 2008474SJose.Borrego@Sun.COM * ERROR_MORE_DATA Partial date returned, more entries available. 2018474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 2028474SJose.Borrego@Sun.COM * NERR_NetNameNotFound The share qualifier cannot be found. 2038474SJose.Borrego@Sun.COM * NERR_BufTooSmall The supplied buffer is too small. 2048474SJose.Borrego@Sun.COM */ 2058474SJose.Borrego@Sun.COM static int 2068474SJose.Borrego@Sun.COM srvsvc_s_NetConnectEnum(void *arg, ndr_xa_t *mxa) 2078474SJose.Borrego@Sun.COM { 208*10122SJordan.Brown@Sun.COM srvsvc_NetConnectEnum_t *param = arg; 209*10122SJordan.Brown@Sun.COM smb_netsvc_t *ns; 210*10122SJordan.Brown@Sun.COM smb_svcenum_t se; 211*10122SJordan.Brown@Sun.COM char *qualifier; 212*10122SJordan.Brown@Sun.COM int qualtype; 213*10122SJordan.Brown@Sun.COM DWORD status = ERROR_SUCCESS; 2148474SJose.Borrego@Sun.COM 2158474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa)) { 216*10122SJordan.Brown@Sun.COM status = ERROR_ACCESS_DENIED; 217*10122SJordan.Brown@Sun.COM goto srvsvc_netconnectenum_error; 2188474SJose.Borrego@Sun.COM } 2198474SJose.Borrego@Sun.COM 2208474SJose.Borrego@Sun.COM qualifier = (char *)param->qualifier; 2218474SJose.Borrego@Sun.COM qualtype = srvsvc_netconnect_qualifier(qualifier); 2228474SJose.Borrego@Sun.COM if (qualtype == SRVSVC_CONNECT_ENUM_NULL) { 223*10122SJordan.Brown@Sun.COM status = NERR_NetNameNotFound; 224*10122SJordan.Brown@Sun.COM goto srvsvc_netconnectenum_error; 225*10122SJordan.Brown@Sun.COM } 226*10122SJordan.Brown@Sun.COM 227*10122SJordan.Brown@Sun.COM param->total_entries = srvsvc_open_connections(qualtype, qualifier); 228*10122SJordan.Brown@Sun.COM if (param->total_entries == 0) { 229*10122SJordan.Brown@Sun.COM bzero(param, sizeof (srvsvc_NetConnectEnum_t)); 230*10122SJordan.Brown@Sun.COM param->status = ERROR_SUCCESS; 2318474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 2328474SJose.Borrego@Sun.COM } 2338474SJose.Borrego@Sun.COM 234*10122SJordan.Brown@Sun.COM bzero(&se, sizeof (smb_svcenum_t)); 235*10122SJordan.Brown@Sun.COM se.se_type = SMB_SVCENUM_TYPE_TREE; 236*10122SJordan.Brown@Sun.COM se.se_level = param->info.level; 237*10122SJordan.Brown@Sun.COM se.se_ntotal = param->total_entries; 238*10122SJordan.Brown@Sun.COM se.se_nlimit = se.se_ntotal; 239*10122SJordan.Brown@Sun.COM 240*10122SJordan.Brown@Sun.COM if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN || 241*10122SJordan.Brown@Sun.COM param->pref_max_len > SMB_SRVSVC_MAXBUFLEN) 242*10122SJordan.Brown@Sun.COM se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN; 243*10122SJordan.Brown@Sun.COM else 244*10122SJordan.Brown@Sun.COM se.se_prefmaxlen = param->pref_max_len; 245*10122SJordan.Brown@Sun.COM 246*10122SJordan.Brown@Sun.COM if (param->resume_handle) { 247*10122SJordan.Brown@Sun.COM se.se_resume = *param->resume_handle; 248*10122SJordan.Brown@Sun.COM se.se_nskip = se.se_resume; 249*10122SJordan.Brown@Sun.COM *param->resume_handle = 0; 250*10122SJordan.Brown@Sun.COM } 251*10122SJordan.Brown@Sun.COM 2528474SJose.Borrego@Sun.COM switch (param->info.level) { 2538474SJose.Borrego@Sun.COM case 0: 254*10122SJordan.Brown@Sun.COM status = srvsvc_netconnectenum_level0(mxa, &se, param); 2558474SJose.Borrego@Sun.COM break; 2568474SJose.Borrego@Sun.COM case 1: 257*10122SJordan.Brown@Sun.COM status = srvsvc_netconnectenum_level1(mxa, &se, param); 2588474SJose.Borrego@Sun.COM break; 2598474SJose.Borrego@Sun.COM case 50: 2608474SJose.Borrego@Sun.COM status = ERROR_NOT_SUPPORTED; 2618474SJose.Borrego@Sun.COM break; 2628474SJose.Borrego@Sun.COM default: 2638474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 2648474SJose.Borrego@Sun.COM break; 2658474SJose.Borrego@Sun.COM } 2668474SJose.Borrego@Sun.COM 2678474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 268*10122SJordan.Brown@Sun.COM goto srvsvc_netconnectenum_error; 269*10122SJordan.Brown@Sun.COM 270*10122SJordan.Brown@Sun.COM if ((ns = smb_kmod_enum_init(&se)) == NULL) { 271*10122SJordan.Brown@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 272*10122SJordan.Brown@Sun.COM goto srvsvc_netconnectenum_error; 273*10122SJordan.Brown@Sun.COM } 274*10122SJordan.Brown@Sun.COM 275*10122SJordan.Brown@Sun.COM status = srvsvc_netconnectenum_common(mxa, ¶m->info, ns, &se); 276*10122SJordan.Brown@Sun.COM smb_kmod_enum_fini(ns); 277*10122SJordan.Brown@Sun.COM 278*10122SJordan.Brown@Sun.COM if (status != ERROR_SUCCESS) 279*10122SJordan.Brown@Sun.COM goto srvsvc_netconnectenum_error; 280*10122SJordan.Brown@Sun.COM 281*10122SJordan.Brown@Sun.COM if (param->resume_handle && 282*10122SJordan.Brown@Sun.COM param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) { 283*10122SJordan.Brown@Sun.COM if (se.se_resume < param->total_entries) { 284*10122SJordan.Brown@Sun.COM *param->resume_handle = se.se_resume; 285*10122SJordan.Brown@Sun.COM status = ERROR_MORE_DATA; 286*10122SJordan.Brown@Sun.COM } 287*10122SJordan.Brown@Sun.COM } 288*10122SJordan.Brown@Sun.COM 289*10122SJordan.Brown@Sun.COM param->status = status; 290*10122SJordan.Brown@Sun.COM return (NDR_DRC_OK); 291*10122SJordan.Brown@Sun.COM 292*10122SJordan.Brown@Sun.COM srvsvc_netconnectenum_error: 293*10122SJordan.Brown@Sun.COM bzero(param, sizeof (srvsvc_NetConnectEnum_t)); 2948474SJose.Borrego@Sun.COM param->status = status; 2958474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 2968474SJose.Borrego@Sun.COM } 2978474SJose.Borrego@Sun.COM 298*10122SJordan.Brown@Sun.COM /* 299*10122SJordan.Brown@Sun.COM * Allocate memory and estimate the number of objects that can 300*10122SJordan.Brown@Sun.COM * be returned for NetConnectEnum level 0. 301*10122SJordan.Brown@Sun.COM */ 302*10122SJordan.Brown@Sun.COM static uint32_t 303*10122SJordan.Brown@Sun.COM srvsvc_netconnectenum_level0(ndr_xa_t *mxa, smb_svcenum_t *se, 304*10122SJordan.Brown@Sun.COM srvsvc_NetConnectEnum_t *param) 3058474SJose.Borrego@Sun.COM { 306*10122SJordan.Brown@Sun.COM srvsvc_NetConnectInfo0_t *info0; 307*10122SJordan.Brown@Sun.COM srvsvc_NetConnectInfoBuf0_t *ci0; 308*10122SJordan.Brown@Sun.COM 309*10122SJordan.Brown@Sun.COM if ((info0 = NDR_NEW(mxa, srvsvc_NetConnectInfo0_t)) == NULL) 310*10122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 311*10122SJordan.Brown@Sun.COM 312*10122SJordan.Brown@Sun.COM bzero(info0, sizeof (srvsvc_NetConnectInfo0_t)); 313*10122SJordan.Brown@Sun.COM param->info.ru.info0 = info0; 314*10122SJordan.Brown@Sun.COM 315*10122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, sizeof (srvsvc_NetConnectInfoBuf0_t)); 316*10122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 317*10122SJordan.Brown@Sun.COM return (NERR_BufTooSmall); 318*10122SJordan.Brown@Sun.COM 319*10122SJordan.Brown@Sun.COM do { 320*10122SJordan.Brown@Sun.COM ci0 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf0_t, se->se_nlimit); 321*10122SJordan.Brown@Sun.COM if (ci0 == NULL) 322*10122SJordan.Brown@Sun.COM se->se_nlimit >>= 1; 323*10122SJordan.Brown@Sun.COM } while ((se->se_nlimit > 0) && (ci0 == NULL)); 324*10122SJordan.Brown@Sun.COM 3258474SJose.Borrego@Sun.COM if (ci0 == NULL) 3268474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 3278474SJose.Borrego@Sun.COM 3288474SJose.Borrego@Sun.COM info0->ci0 = ci0; 329*10122SJordan.Brown@Sun.COM info0->entries_read = 0; 3308474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 3318474SJose.Borrego@Sun.COM } 3328474SJose.Borrego@Sun.COM 333*10122SJordan.Brown@Sun.COM /* 334*10122SJordan.Brown@Sun.COM * Allocate memory and estimate the number of objects that can 335*10122SJordan.Brown@Sun.COM * be returned for NetConnectEnum level 1. 336*10122SJordan.Brown@Sun.COM */ 337*10122SJordan.Brown@Sun.COM static uint32_t 338*10122SJordan.Brown@Sun.COM srvsvc_netconnectenum_level1(ndr_xa_t *mxa, smb_svcenum_t *se, 339*10122SJordan.Brown@Sun.COM srvsvc_NetConnectEnum_t *param) 3408474SJose.Borrego@Sun.COM { 341*10122SJordan.Brown@Sun.COM srvsvc_NetConnectInfo1_t *info1; 342*10122SJordan.Brown@Sun.COM srvsvc_NetConnectInfoBuf1_t *ci1; 343*10122SJordan.Brown@Sun.COM 344*10122SJordan.Brown@Sun.COM if ((info1 = NDR_NEW(mxa, srvsvc_NetConnectInfo1_t)) == NULL) 345*10122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 346*10122SJordan.Brown@Sun.COM 347*10122SJordan.Brown@Sun.COM bzero(info1, sizeof (srvsvc_NetConnectInfo1_t)); 348*10122SJordan.Brown@Sun.COM param->info.ru.info1 = info1; 349*10122SJordan.Brown@Sun.COM 350*10122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 351*10122SJordan.Brown@Sun.COM sizeof (srvsvc_NetConnectInfoBuf1_t) + MAXNAMELEN); 352*10122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 353*10122SJordan.Brown@Sun.COM return (NERR_BufTooSmall); 354*10122SJordan.Brown@Sun.COM 355*10122SJordan.Brown@Sun.COM do { 356*10122SJordan.Brown@Sun.COM ci1 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf1_t, se->se_nlimit); 357*10122SJordan.Brown@Sun.COM if (ci1 == NULL) 358*10122SJordan.Brown@Sun.COM se->se_nlimit >>= 1; 359*10122SJordan.Brown@Sun.COM } while ((se->se_nlimit > 0) && (ci1 == NULL)); 360*10122SJordan.Brown@Sun.COM 3618474SJose.Borrego@Sun.COM if (ci1 == NULL) 3628474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 3638474SJose.Borrego@Sun.COM 3648474SJose.Borrego@Sun.COM info1->ci1 = ci1; 365*10122SJordan.Brown@Sun.COM info1->entries_read = 0; 366*10122SJordan.Brown@Sun.COM return (ERROR_SUCCESS); 367*10122SJordan.Brown@Sun.COM } 368*10122SJordan.Brown@Sun.COM 369*10122SJordan.Brown@Sun.COM /* 370*10122SJordan.Brown@Sun.COM * Request a list of connections from the kernel and set up 371*10122SJordan.Brown@Sun.COM * the connection information to be returned to the client. 372*10122SJordan.Brown@Sun.COM */ 373*10122SJordan.Brown@Sun.COM static uint32_t 374*10122SJordan.Brown@Sun.COM srvsvc_netconnectenum_common(ndr_xa_t *mxa, srvsvc_NetConnectInfo_t *info, 375*10122SJordan.Brown@Sun.COM smb_netsvc_t *ns, smb_svcenum_t *se) 376*10122SJordan.Brown@Sun.COM { 377*10122SJordan.Brown@Sun.COM srvsvc_NetConnectInfo0_t *info0; 378*10122SJordan.Brown@Sun.COM srvsvc_NetConnectInfo1_t *info1; 379*10122SJordan.Brown@Sun.COM srvsvc_NetConnectInfoBuf0_t *ci0; 380*10122SJordan.Brown@Sun.COM srvsvc_NetConnectInfoBuf1_t *ci1; 381*10122SJordan.Brown@Sun.COM smb_netsvcitem_t *item; 382*10122SJordan.Brown@Sun.COM smb_netconnectinfo_t *tree; 383*10122SJordan.Brown@Sun.COM 384*10122SJordan.Brown@Sun.COM if (smb_kmod_enum(ns) != 0) 385*10122SJordan.Brown@Sun.COM return (ERROR_INTERNAL_ERROR); 386*10122SJordan.Brown@Sun.COM 387*10122SJordan.Brown@Sun.COM info0 = info->ru.info0; 388*10122SJordan.Brown@Sun.COM ci0 = info0->ci0; 389*10122SJordan.Brown@Sun.COM 390*10122SJordan.Brown@Sun.COM info1 = info->ru.info1; 391*10122SJordan.Brown@Sun.COM ci1 = info1->ci1; 392*10122SJordan.Brown@Sun.COM 393*10122SJordan.Brown@Sun.COM item = list_head(&ns->ns_list); 394*10122SJordan.Brown@Sun.COM while (item != NULL) { 395*10122SJordan.Brown@Sun.COM tree = &item->nsi_un.nsi_tree; 396*10122SJordan.Brown@Sun.COM 397*10122SJordan.Brown@Sun.COM switch (se->se_level) { 398*10122SJordan.Brown@Sun.COM case 0: 399*10122SJordan.Brown@Sun.COM ci0->coni0_id = tree->ci_id; 400*10122SJordan.Brown@Sun.COM ++ci0; 401*10122SJordan.Brown@Sun.COM ++info0->entries_read; 402*10122SJordan.Brown@Sun.COM break; 403*10122SJordan.Brown@Sun.COM case 1: 404*10122SJordan.Brown@Sun.COM ci1->coni1_id = tree->ci_id; 405*10122SJordan.Brown@Sun.COM ci1->coni1_type = tree->ci_type; 406*10122SJordan.Brown@Sun.COM ci1->coni1_num_opens = tree->ci_numopens; 407*10122SJordan.Brown@Sun.COM ci1->coni1_num_users = tree->ci_numusers; 408*10122SJordan.Brown@Sun.COM ci1->coni1_time = tree->ci_time; 409*10122SJordan.Brown@Sun.COM ci1->coni1_username = (uint8_t *) 410*10122SJordan.Brown@Sun.COM NDR_STRDUP(mxa, tree->ci_username); 411*10122SJordan.Brown@Sun.COM ci1->coni1_netname = (uint8_t *) 412*10122SJordan.Brown@Sun.COM NDR_STRDUP(mxa, tree->ci_share); 413*10122SJordan.Brown@Sun.COM ++ci1; 414*10122SJordan.Brown@Sun.COM ++info1->entries_read; 415*10122SJordan.Brown@Sun.COM break; 416*10122SJordan.Brown@Sun.COM default: 417*10122SJordan.Brown@Sun.COM return (ERROR_INVALID_LEVEL); 418*10122SJordan.Brown@Sun.COM } 419*10122SJordan.Brown@Sun.COM 420*10122SJordan.Brown@Sun.COM ++se->se_resume; 421*10122SJordan.Brown@Sun.COM item = list_next(&ns->ns_list, item); 422*10122SJordan.Brown@Sun.COM } 423*10122SJordan.Brown@Sun.COM 4248474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 4258474SJose.Borrego@Sun.COM } 4268474SJose.Borrego@Sun.COM 4278474SJose.Borrego@Sun.COM /* 4288474SJose.Borrego@Sun.COM * srvsvc_netconnect_qualifier 4298474SJose.Borrego@Sun.COM * 4308474SJose.Borrego@Sun.COM * The qualifier is a string that specifies a share name or computer name 4318474SJose.Borrego@Sun.COM * for the connections of interest. If it is a share name then all the 4328474SJose.Borrego@Sun.COM * connections made to that share name are listed. If it is a computer 4338474SJose.Borrego@Sun.COM * name (it starts with two backslash characters), then NetConnectEnum 4348474SJose.Borrego@Sun.COM * lists all connections made from that computer to the specified server. 4358474SJose.Borrego@Sun.COM */ 4368474SJose.Borrego@Sun.COM static int 4378474SJose.Borrego@Sun.COM srvsvc_netconnect_qualifier(const char *qualifier) 4388474SJose.Borrego@Sun.COM { 4398474SJose.Borrego@Sun.COM if (qualifier == NULL || *qualifier == '\0') 4408474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_NULL); 4418474SJose.Borrego@Sun.COM 4428474SJose.Borrego@Sun.COM if (strlen(qualifier) > MAXHOSTNAMELEN) 4438474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_NULL); 4448474SJose.Borrego@Sun.COM 4458474SJose.Borrego@Sun.COM if (qualifier[0] == '\\' && qualifier[1] == '\\') { 4468474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_WKSTN); 4478474SJose.Borrego@Sun.COM } else { 4488474SJose.Borrego@Sun.COM if (!smb_shr_exists((char *)qualifier)) 4498474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_NULL); 4508474SJose.Borrego@Sun.COM 4518474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_SHARE); 4528474SJose.Borrego@Sun.COM } 4538474SJose.Borrego@Sun.COM } 4548474SJose.Borrego@Sun.COM 455*10122SJordan.Brown@Sun.COM static uint32_t 456*10122SJordan.Brown@Sun.COM srvsvc_open_sessions(void) 457*10122SJordan.Brown@Sun.COM { 458*10122SJordan.Brown@Sun.COM smb_opennum_t opennum; 459*10122SJordan.Brown@Sun.COM 460*10122SJordan.Brown@Sun.COM bzero(&opennum, sizeof (smb_opennum_t)); 461*10122SJordan.Brown@Sun.COM if (smb_kmod_get_open_num(&opennum) != 0) 462*10122SJordan.Brown@Sun.COM return (0); 463*10122SJordan.Brown@Sun.COM 464*10122SJordan.Brown@Sun.COM return (opennum.open_users); 465*10122SJordan.Brown@Sun.COM } 466*10122SJordan.Brown@Sun.COM 467*10122SJordan.Brown@Sun.COM static uint32_t 468*10122SJordan.Brown@Sun.COM srvsvc_open_connections(uint32_t qualtype, const char *qualifier) 469*10122SJordan.Brown@Sun.COM { 470*10122SJordan.Brown@Sun.COM smb_opennum_t opennum; 471*10122SJordan.Brown@Sun.COM 472*10122SJordan.Brown@Sun.COM bzero(&opennum, sizeof (smb_opennum_t)); 473*10122SJordan.Brown@Sun.COM opennum.qualtype = qualtype; 474*10122SJordan.Brown@Sun.COM (void) strlcpy(opennum.qualifier, qualifier, MAXNAMELEN); 475*10122SJordan.Brown@Sun.COM 476*10122SJordan.Brown@Sun.COM if (smb_kmod_get_open_num(&opennum) != 0) 477*10122SJordan.Brown@Sun.COM return (0); 478*10122SJordan.Brown@Sun.COM 479*10122SJordan.Brown@Sun.COM return (opennum.open_trees); 480*10122SJordan.Brown@Sun.COM } 481*10122SJordan.Brown@Sun.COM 482*10122SJordan.Brown@Sun.COM static uint32_t 483*10122SJordan.Brown@Sun.COM srvsvc_open_files(void) 484*10122SJordan.Brown@Sun.COM { 485*10122SJordan.Brown@Sun.COM smb_opennum_t opennum; 486*10122SJordan.Brown@Sun.COM 487*10122SJordan.Brown@Sun.COM bzero(&opennum, sizeof (smb_opennum_t)); 488*10122SJordan.Brown@Sun.COM if (smb_kmod_get_open_num(&opennum) != 0) 489*10122SJordan.Brown@Sun.COM return (0); 490*10122SJordan.Brown@Sun.COM 491*10122SJordan.Brown@Sun.COM return (opennum.open_files); 492*10122SJordan.Brown@Sun.COM } 493*10122SJordan.Brown@Sun.COM 4948474SJose.Borrego@Sun.COM /* 4958474SJose.Borrego@Sun.COM * srvsvc_s_NetFileEnum 4968474SJose.Borrego@Sun.COM * 4978474SJose.Borrego@Sun.COM * Return information on open files or named pipes. Only members of the 4988474SJose.Borrego@Sun.COM * Administrators or Server Operators local groups are allowed to make 4998474SJose.Borrego@Sun.COM * this call. Currently, we only support Administrators. 5008474SJose.Borrego@Sun.COM * 5018474SJose.Borrego@Sun.COM * If basepath is null, all open resources are enumerated. If basepath 5028474SJose.Borrego@Sun.COM * is non-null, only resources that have basepath as a prefix should 5038474SJose.Borrego@Sun.COM * be returned. 5048474SJose.Borrego@Sun.COM * 5058474SJose.Borrego@Sun.COM * If username is specified (non-null), only files opened by username 5068474SJose.Borrego@Sun.COM * should be returned. 5078474SJose.Borrego@Sun.COM * 5088474SJose.Borrego@Sun.COM * Notes: 5098474SJose.Borrego@Sun.COM * 1. We don't validate the servername because we would have to check 5108474SJose.Borrego@Sun.COM * all primary IPs and the ROI seems unlikely to be worth it. 5118474SJose.Borrego@Sun.COM * 2. Both basepath and username are currently ignored because both 5128474SJose.Borrego@Sun.COM * Server Manger (NT 4.0) and CMI (Windows 2000) always set them to null. 5138474SJose.Borrego@Sun.COM * 5148474SJose.Borrego@Sun.COM * The level of information requested may be one of: 5158474SJose.Borrego@Sun.COM * 5168474SJose.Borrego@Sun.COM * 2 Return the file identification number. 5178474SJose.Borrego@Sun.COM * This level is not supported on Windows Me/98/95. 5188474SJose.Borrego@Sun.COM * 5198474SJose.Borrego@Sun.COM * 3 Return information about the file. 5208474SJose.Borrego@Sun.COM * This level is not supported on Windows Me/98/95. 5218474SJose.Borrego@Sun.COM * 5228474SJose.Borrego@Sun.COM * 50 Windows Me/98/95: Return information about the file. 5238474SJose.Borrego@Sun.COM * 5248474SJose.Borrego@Sun.COM * Note: 5258474SJose.Borrego@Sun.COM * If pref_max_len is unlimited and resume_handle is null, the client 5268474SJose.Borrego@Sun.COM * expects to receive all data in a single call. 5278474SJose.Borrego@Sun.COM * If we are unable to do fit all data in a single response, we would 5288474SJose.Borrego@Sun.COM * normally return ERROR_MORE_DATA with a partial list. 5298474SJose.Borrego@Sun.COM * 5308474SJose.Borrego@Sun.COM * Unfortunately, when both of these conditions occur, Server Manager 5318474SJose.Borrego@Sun.COM * pops up an error box with the message "more data available" and 5328474SJose.Borrego@Sun.COM * doesn't display any of the returned data. In this case, it is 5338474SJose.Borrego@Sun.COM * probably better to return ERROR_SUCCESS with the partial list. 5348474SJose.Borrego@Sun.COM * Windows 2000 doesn't have this problem because it always sends a 5358474SJose.Borrego@Sun.COM * non-null resume_handle. 5368474SJose.Borrego@Sun.COM * 5378474SJose.Borrego@Sun.COM * Return Values: 5388474SJose.Borrego@Sun.COM * ERROR_SUCCESS Success 5398474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED Caller does not have access to this call. 5408474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER One of the parameters is invalid. 5418474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL Unknown information level specified. 5428474SJose.Borrego@Sun.COM * ERROR_MORE_DATA Partial date returned, more entries available. 5438474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 5448474SJose.Borrego@Sun.COM * NERR_BufTooSmall The supplied buffer is too small. 5458474SJose.Borrego@Sun.COM */ 5468474SJose.Borrego@Sun.COM static int 5478474SJose.Borrego@Sun.COM srvsvc_s_NetFileEnum(void *arg, ndr_xa_t *mxa) 5488474SJose.Borrego@Sun.COM { 549*10122SJordan.Brown@Sun.COM struct mslm_NetFileEnum *param = arg; 550*10122SJordan.Brown@Sun.COM smb_svcenum_t se; 551*10122SJordan.Brown@Sun.COM DWORD status; 5528474SJose.Borrego@Sun.COM 5538474SJose.Borrego@Sun.COM if (!ndr_is_admin(mxa)) { 5548474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetFileEnum)); 5558474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 5568474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5578474SJose.Borrego@Sun.COM } 5588474SJose.Borrego@Sun.COM 559*10122SJordan.Brown@Sun.COM if ((param->total_entries = srvsvc_open_files()) == 0) { 560*10122SJordan.Brown@Sun.COM bzero(param, sizeof (struct mslm_NetFileEnum)); 561*10122SJordan.Brown@Sun.COM param->status = ERROR_SUCCESS; 562*10122SJordan.Brown@Sun.COM return (NDR_DRC_OK); 563*10122SJordan.Brown@Sun.COM } 564*10122SJordan.Brown@Sun.COM 565*10122SJordan.Brown@Sun.COM bzero(&se, sizeof (smb_svcenum_t)); 566*10122SJordan.Brown@Sun.COM se.se_type = SMB_SVCENUM_TYPE_FILE; 567*10122SJordan.Brown@Sun.COM se.se_level = param->info.switch_value; 568*10122SJordan.Brown@Sun.COM se.se_ntotal = param->total_entries; 569*10122SJordan.Brown@Sun.COM se.se_nlimit = se.se_ntotal; 570*10122SJordan.Brown@Sun.COM 571*10122SJordan.Brown@Sun.COM if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN || 572*10122SJordan.Brown@Sun.COM param->pref_max_len > SMB_SRVSVC_MAXBUFLEN) 573*10122SJordan.Brown@Sun.COM se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN; 574*10122SJordan.Brown@Sun.COM else 575*10122SJordan.Brown@Sun.COM se.se_prefmaxlen = param->pref_max_len; 576*10122SJordan.Brown@Sun.COM 577*10122SJordan.Brown@Sun.COM if (param->resume_handle) { 578*10122SJordan.Brown@Sun.COM se.se_resume = *param->resume_handle; 579*10122SJordan.Brown@Sun.COM se.se_nskip = se.se_resume; 580*10122SJordan.Brown@Sun.COM *param->resume_handle = 0; 581*10122SJordan.Brown@Sun.COM } 582*10122SJordan.Brown@Sun.COM 5838474SJose.Borrego@Sun.COM switch (param->info.switch_value) { 5848474SJose.Borrego@Sun.COM case 2: 585*10122SJordan.Brown@Sun.COM status = srvsvc_NetFileEnum2(mxa, param, &se); 5868474SJose.Borrego@Sun.COM break; 5878474SJose.Borrego@Sun.COM 5888474SJose.Borrego@Sun.COM case 3: 589*10122SJordan.Brown@Sun.COM status = srvsvc_NetFileEnum3(mxa, param, &se); 5908474SJose.Borrego@Sun.COM break; 5918474SJose.Borrego@Sun.COM 5928474SJose.Borrego@Sun.COM case 50: 5938474SJose.Borrego@Sun.COM status = ERROR_NOT_SUPPORTED; 5948474SJose.Borrego@Sun.COM break; 5958474SJose.Borrego@Sun.COM 5968474SJose.Borrego@Sun.COM default: 5978474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 5988474SJose.Borrego@Sun.COM break; 5998474SJose.Borrego@Sun.COM } 6008474SJose.Borrego@Sun.COM 6018474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) { 6028474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetFileEnum)); 6038474SJose.Borrego@Sun.COM param->status = status; 6048474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6058474SJose.Borrego@Sun.COM } 6068474SJose.Borrego@Sun.COM 607*10122SJordan.Brown@Sun.COM if (param->resume_handle && 608*10122SJordan.Brown@Sun.COM param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) { 609*10122SJordan.Brown@Sun.COM if (se.se_resume < param->total_entries) { 610*10122SJordan.Brown@Sun.COM *param->resume_handle = se.se_resume; 611*10122SJordan.Brown@Sun.COM status = ERROR_MORE_DATA; 612*10122SJordan.Brown@Sun.COM } 613*10122SJordan.Brown@Sun.COM } 614*10122SJordan.Brown@Sun.COM 615*10122SJordan.Brown@Sun.COM param->status = status; 6168474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6178474SJose.Borrego@Sun.COM } 6188474SJose.Borrego@Sun.COM 6198474SJose.Borrego@Sun.COM /* 6208474SJose.Borrego@Sun.COM * Build level 2 file information. 6218474SJose.Borrego@Sun.COM * 622*10122SJordan.Brown@Sun.COM * SMB fids are 16-bit values but this interface expects 32-bit file ids. 623*10122SJordan.Brown@Sun.COM * So we use the uniqid here. 624*10122SJordan.Brown@Sun.COM * 6258474SJose.Borrego@Sun.COM * On success, the caller expects that the info2, fi2 and entries_read 6268474SJose.Borrego@Sun.COM * fields have been set up. 6278474SJose.Borrego@Sun.COM */ 6288474SJose.Borrego@Sun.COM static DWORD 629*10122SJordan.Brown@Sun.COM srvsvc_NetFileEnum2(ndr_xa_t *mxa, struct mslm_NetFileEnum *param, 630*10122SJordan.Brown@Sun.COM smb_svcenum_t *se) 6318474SJose.Borrego@Sun.COM { 632*10122SJordan.Brown@Sun.COM struct mslm_NetFileInfoBuf2 *fi2; 633*10122SJordan.Brown@Sun.COM smb_netsvc_t *ns; 634*10122SJordan.Brown@Sun.COM smb_netsvcitem_t *item; 635*10122SJordan.Brown@Sun.COM smb_netfileinfo_t *ofile; 636*10122SJordan.Brown@Sun.COM uint32_t entries_read = 0; 6378474SJose.Borrego@Sun.COM 6388474SJose.Borrego@Sun.COM param->info.ru.info2 = NDR_NEW(mxa, struct mslm_NetFileInfo2); 6399832Samw@Sun.COM if (param->info.ru.info2 == NULL) 6408474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 6418474SJose.Borrego@Sun.COM 642*10122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, sizeof (struct mslm_NetFileInfoBuf2)); 643*10122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 644*10122SJordan.Brown@Sun.COM return (NERR_BufTooSmall); 645*10122SJordan.Brown@Sun.COM 646*10122SJordan.Brown@Sun.COM do { 647*10122SJordan.Brown@Sun.COM fi2 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf2, se->se_nlimit); 648*10122SJordan.Brown@Sun.COM if (fi2 == NULL) 649*10122SJordan.Brown@Sun.COM se->se_nlimit >>= 1; 650*10122SJordan.Brown@Sun.COM } while ((se->se_nlimit > 0) && (fi2 == NULL)); 651*10122SJordan.Brown@Sun.COM 6528474SJose.Borrego@Sun.COM if (fi2 == NULL) 6538474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 6548474SJose.Borrego@Sun.COM 6558474SJose.Borrego@Sun.COM param->info.ru.info2->fi2 = fi2; 6568474SJose.Borrego@Sun.COM 657*10122SJordan.Brown@Sun.COM if ((ns = smb_kmod_enum_init(se)) == NULL) 658*10122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 659*10122SJordan.Brown@Sun.COM 660*10122SJordan.Brown@Sun.COM if (smb_kmod_enum(ns) != 0) { 661*10122SJordan.Brown@Sun.COM smb_kmod_enum_fini(ns); 662*10122SJordan.Brown@Sun.COM return (ERROR_INTERNAL_ERROR); 663*10122SJordan.Brown@Sun.COM } 664*10122SJordan.Brown@Sun.COM 665*10122SJordan.Brown@Sun.COM item = list_head(&ns->ns_list); 666*10122SJordan.Brown@Sun.COM while (item != NULL) { 667*10122SJordan.Brown@Sun.COM ofile = &item->nsi_un.nsi_ofile; 668*10122SJordan.Brown@Sun.COM fi2->fi2_id = ofile->fi_uniqid; 6698474SJose.Borrego@Sun.COM 6708474SJose.Borrego@Sun.COM ++entries_read; 6718474SJose.Borrego@Sun.COM ++fi2; 672*10122SJordan.Brown@Sun.COM item = list_next(&ns->ns_list, item); 6738474SJose.Borrego@Sun.COM } 6748474SJose.Borrego@Sun.COM 675*10122SJordan.Brown@Sun.COM se->se_resume += entries_read; 6768474SJose.Borrego@Sun.COM param->info.ru.info2->entries_read = entries_read; 677*10122SJordan.Brown@Sun.COM smb_kmod_enum_fini(ns); 6788474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 6798474SJose.Borrego@Sun.COM } 6808474SJose.Borrego@Sun.COM 6818474SJose.Borrego@Sun.COM /* 6828474SJose.Borrego@Sun.COM * Build level 3 file information. 6838474SJose.Borrego@Sun.COM * 684*10122SJordan.Brown@Sun.COM * SMB fids are 16-bit values but this interface expects 32-bit file ids. 685*10122SJordan.Brown@Sun.COM * So we use the uniqid here. 686*10122SJordan.Brown@Sun.COM * 6878474SJose.Borrego@Sun.COM * On success, the caller expects that the info3, fi3 and entries_read 6888474SJose.Borrego@Sun.COM * fields have been set up. 6898474SJose.Borrego@Sun.COM */ 6908474SJose.Borrego@Sun.COM static DWORD 691*10122SJordan.Brown@Sun.COM srvsvc_NetFileEnum3(ndr_xa_t *mxa, struct mslm_NetFileEnum *param, 692*10122SJordan.Brown@Sun.COM smb_svcenum_t *se) 6938474SJose.Borrego@Sun.COM { 694*10122SJordan.Brown@Sun.COM struct mslm_NetFileInfoBuf3 *fi3; 695*10122SJordan.Brown@Sun.COM smb_netsvc_t *ns; 696*10122SJordan.Brown@Sun.COM smb_netsvcitem_t *item; 697*10122SJordan.Brown@Sun.COM smb_netfileinfo_t *ofile; 698*10122SJordan.Brown@Sun.COM uint32_t entries_read = 0; 6998474SJose.Borrego@Sun.COM 7008474SJose.Borrego@Sun.COM param->info.ru.info3 = NDR_NEW(mxa, struct mslm_NetFileInfo3); 7018474SJose.Borrego@Sun.COM if (param->info.ru.info3 == NULL) 7028474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 7038474SJose.Borrego@Sun.COM 704*10122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 705*10122SJordan.Brown@Sun.COM sizeof (struct mslm_NetFileInfoBuf3) + MAXNAMELEN); 706*10122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 707*10122SJordan.Brown@Sun.COM return (NERR_BufTooSmall); 708*10122SJordan.Brown@Sun.COM 709*10122SJordan.Brown@Sun.COM do { 710*10122SJordan.Brown@Sun.COM fi3 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf3, se->se_nlimit); 711*10122SJordan.Brown@Sun.COM if (fi3 == NULL) 712*10122SJordan.Brown@Sun.COM se->se_nlimit >>= 1; 713*10122SJordan.Brown@Sun.COM } while ((se->se_nlimit > 0) && (fi3 == NULL)); 714*10122SJordan.Brown@Sun.COM 7158474SJose.Borrego@Sun.COM if (fi3 == NULL) 7168474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 7178474SJose.Borrego@Sun.COM 7188474SJose.Borrego@Sun.COM param->info.ru.info3->fi3 = fi3; 7198474SJose.Borrego@Sun.COM 720*10122SJordan.Brown@Sun.COM if ((ns = smb_kmod_enum_init(se)) == NULL) 721*10122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 722*10122SJordan.Brown@Sun.COM 723*10122SJordan.Brown@Sun.COM if (smb_kmod_enum(ns) != 0) { 724*10122SJordan.Brown@Sun.COM smb_kmod_enum_fini(ns); 725*10122SJordan.Brown@Sun.COM return (ERROR_INTERNAL_ERROR); 726*10122SJordan.Brown@Sun.COM } 727*10122SJordan.Brown@Sun.COM 728*10122SJordan.Brown@Sun.COM item = list_head(&ns->ns_list); 729*10122SJordan.Brown@Sun.COM while (item != NULL) { 730*10122SJordan.Brown@Sun.COM ofile = &item->nsi_un.nsi_ofile; 731*10122SJordan.Brown@Sun.COM fi3->fi3_id = ofile->fi_uniqid; 732*10122SJordan.Brown@Sun.COM fi3->fi3_permissions = ofile->fi_permissions; 733*10122SJordan.Brown@Sun.COM fi3->fi3_num_locks = ofile->fi_numlocks; 7348474SJose.Borrego@Sun.COM fi3->fi3_pathname = (uint8_t *) 735*10122SJordan.Brown@Sun.COM NDR_STRDUP(mxa, ofile->fi_path); 7368474SJose.Borrego@Sun.COM fi3->fi3_username = (uint8_t *) 737*10122SJordan.Brown@Sun.COM NDR_STRDUP(mxa, ofile->fi_username); 7388474SJose.Borrego@Sun.COM 7398474SJose.Borrego@Sun.COM ++entries_read; 7408474SJose.Borrego@Sun.COM ++fi3; 741*10122SJordan.Brown@Sun.COM item = list_next(&ns->ns_list, item); 7428474SJose.Borrego@Sun.COM } 7438474SJose.Borrego@Sun.COM 744*10122SJordan.Brown@Sun.COM se->se_resume += entries_read; 7458474SJose.Borrego@Sun.COM param->info.ru.info3->entries_read = entries_read; 7468474SJose.Borrego@Sun.COM param->total_entries = entries_read; 7478474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 7488474SJose.Borrego@Sun.COM } 7498474SJose.Borrego@Sun.COM 7508474SJose.Borrego@Sun.COM /* 7518474SJose.Borrego@Sun.COM * srvsvc_s_NetFileClose 7528474SJose.Borrego@Sun.COM * 7538474SJose.Borrego@Sun.COM * NetFileClose forces a file to close. This function can be used when 754*10122SJordan.Brown@Sun.COM * an error prevents closure by other means. Use NetFileClose with 7558474SJose.Borrego@Sun.COM * caution because it does not flush data, cached on a client, to the 7568474SJose.Borrego@Sun.COM * file before closing the file. 7578474SJose.Borrego@Sun.COM * 758*10122SJordan.Brown@Sun.COM * SMB fids are 16-bit values but this interface expects 32-bit file ids. 759*10122SJordan.Brown@Sun.COM * So we use the uniqid here. 760*10122SJordan.Brown@Sun.COM * 7618474SJose.Borrego@Sun.COM * Return Values 7628474SJose.Borrego@Sun.COM * ERROR_SUCCESS Operation succeeded. 7638474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED Operation denied. 7648474SJose.Borrego@Sun.COM * NERR_FileIdNotFound No open file with the specified id. 7658474SJose.Borrego@Sun.COM * 766*10122SJordan.Brown@Sun.COM * Note: MSDN suggests ERROR_FILE_NOT_FOUND for NetFileClose but network 767*10122SJordan.Brown@Sun.COM * captures using NT show NERR_FileIdNotFound, which is consistent with 768*10122SJordan.Brown@Sun.COM * the NetFileClose2 page on MSDN. 7698474SJose.Borrego@Sun.COM */ 7708474SJose.Borrego@Sun.COM static int 7718474SJose.Borrego@Sun.COM srvsvc_s_NetFileClose(void *arg, ndr_xa_t *mxa) 7728474SJose.Borrego@Sun.COM { 773*10122SJordan.Brown@Sun.COM static struct { 774*10122SJordan.Brown@Sun.COM int errnum; 775*10122SJordan.Brown@Sun.COM int nerr; 776*10122SJordan.Brown@Sun.COM } errmap[] = { 777*10122SJordan.Brown@Sun.COM 0, ERROR_SUCCESS, 778*10122SJordan.Brown@Sun.COM EACCES, ERROR_ACCESS_DENIED, 779*10122SJordan.Brown@Sun.COM EPERM, ERROR_ACCESS_DENIED, 780*10122SJordan.Brown@Sun.COM EINVAL, ERROR_INVALID_PARAMETER, 781*10122SJordan.Brown@Sun.COM ENOMEM, ERROR_NOT_ENOUGH_MEMORY, 782*10122SJordan.Brown@Sun.COM ENOENT, NERR_FileIdNotFound 783*10122SJordan.Brown@Sun.COM }; 784*10122SJordan.Brown@Sun.COM 7858474SJose.Borrego@Sun.COM struct mslm_NetFileClose *param = arg; 786*10122SJordan.Brown@Sun.COM int i; 787*10122SJordan.Brown@Sun.COM int rc; 7888474SJose.Borrego@Sun.COM 7898474SJose.Borrego@Sun.COM if (!ndr_is_admin(mxa)) { 7908474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 7918474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 7928474SJose.Borrego@Sun.COM } 7938474SJose.Borrego@Sun.COM 794*10122SJordan.Brown@Sun.COM rc = smb_kmod_file_close(param->file_id); 795*10122SJordan.Brown@Sun.COM 796*10122SJordan.Brown@Sun.COM for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) { 797*10122SJordan.Brown@Sun.COM if (rc == errmap[i].errnum) { 798*10122SJordan.Brown@Sun.COM param->status = errmap[i].nerr; 799*10122SJordan.Brown@Sun.COM return (NDR_DRC_OK); 800*10122SJordan.Brown@Sun.COM } 801*10122SJordan.Brown@Sun.COM } 802*10122SJordan.Brown@Sun.COM 803*10122SJordan.Brown@Sun.COM param->status = ERROR_INTERNAL_ERROR; 8048474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8058474SJose.Borrego@Sun.COM } 8068474SJose.Borrego@Sun.COM 8078474SJose.Borrego@Sun.COM /* 8088474SJose.Borrego@Sun.COM * srvsvc_s_NetShareGetInfo 8098474SJose.Borrego@Sun.COM * 8108474SJose.Borrego@Sun.COM * Returns Win32 error codes. 8118474SJose.Borrego@Sun.COM */ 8128474SJose.Borrego@Sun.COM static int 8138474SJose.Borrego@Sun.COM srvsvc_s_NetShareGetInfo(void *arg, ndr_xa_t *mxa) 8148474SJose.Borrego@Sun.COM { 8158474SJose.Borrego@Sun.COM struct mlsm_NetShareGetInfo *param = arg; 8169343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_0 *info0; 8179343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1 *info1; 8189343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_2 *info2; 8199343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_501 *info501; 8209343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_502 *info502; 8219832Samw@Sun.COM struct mslm_NetShareInfo_503 *info503; 8229343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1004 *info1004; 8239343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1005 *info1005; 8249343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1006 *info1006; 8259832Samw@Sun.COM struct mslm_NetShareInfo_1501 *info1501; 8269832Samw@Sun.COM srvsvc_netshare_getinfo_t *info; 8279832Samw@Sun.COM uint8_t *netname; 8289832Samw@Sun.COM uint8_t *comment; 8298474SJose.Borrego@Sun.COM smb_share_t si; 8309832Samw@Sun.COM srvsvc_sd_t sd; 8318474SJose.Borrego@Sun.COM DWORD status; 8328474SJose.Borrego@Sun.COM 8338474SJose.Borrego@Sun.COM status = smb_shr_get((char *)param->netname, &si); 8348474SJose.Borrego@Sun.COM if (status != NERR_Success) { 8358474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mlsm_NetShareGetInfo)); 8368474SJose.Borrego@Sun.COM param->status = status; 8378474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8388474SJose.Borrego@Sun.COM } 8398474SJose.Borrego@Sun.COM 8409832Samw@Sun.COM netname = (uint8_t *)NDR_STRDUP(mxa, si.shr_name); 8419832Samw@Sun.COM comment = (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt); 8429832Samw@Sun.COM info = NDR_NEW(mxa, srvsvc_netshare_getinfo_t); 8439832Samw@Sun.COM 8449832Samw@Sun.COM if (netname == NULL || comment == NULL || info == NULL) { 8459832Samw@Sun.COM bzero(param, sizeof (struct mlsm_NetShareGetInfo)); 8469832Samw@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 8479832Samw@Sun.COM return (NDR_DRC_OK); 8489832Samw@Sun.COM } 8499832Samw@Sun.COM 8508474SJose.Borrego@Sun.COM switch (param->level) { 8518474SJose.Borrego@Sun.COM case 0: 8529832Samw@Sun.COM info0 = &info->nsg_info0; 8539832Samw@Sun.COM info0->shi0_netname = netname; 8548474SJose.Borrego@Sun.COM param->result.ru.info0 = info0; 8558474SJose.Borrego@Sun.COM break; 8568474SJose.Borrego@Sun.COM 8578474SJose.Borrego@Sun.COM case 1: 8589832Samw@Sun.COM info1 = &info->nsg_info1; 8599832Samw@Sun.COM info1->shi1_netname = netname; 8609832Samw@Sun.COM info1->shi1_comment = comment; 8618474SJose.Borrego@Sun.COM info1->shi1_type = si.shr_type; 8628474SJose.Borrego@Sun.COM param->result.ru.info1 = info1; 8638474SJose.Borrego@Sun.COM break; 8648474SJose.Borrego@Sun.COM 8658474SJose.Borrego@Sun.COM case 2: 8669832Samw@Sun.COM info2 = &info->nsg_info2; 8679832Samw@Sun.COM info2->shi2_netname = netname; 8689832Samw@Sun.COM info2->shi2_comment = comment; 8698474SJose.Borrego@Sun.COM info2->shi2_path = 8708474SJose.Borrego@Sun.COM (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path); 8718474SJose.Borrego@Sun.COM info2->shi2_passwd = 0; 8728474SJose.Borrego@Sun.COM info2->shi2_type = si.shr_type; 8738474SJose.Borrego@Sun.COM info2->shi2_permissions = 0; 8748474SJose.Borrego@Sun.COM info2->shi2_max_uses = SHI_USES_UNLIMITED; 8758474SJose.Borrego@Sun.COM info2->shi2_current_uses = 0; 8768474SJose.Borrego@Sun.COM param->result.ru.info2 = info2; 8778474SJose.Borrego@Sun.COM break; 8788474SJose.Borrego@Sun.COM 8799832Samw@Sun.COM case 501: 8809832Samw@Sun.COM info501 = &info->nsg_info501; 8819832Samw@Sun.COM info501->shi501_netname = netname; 8829832Samw@Sun.COM info501->shi501_comment = comment; 8839832Samw@Sun.COM info501->shi501_type = si.shr_type; 8849832Samw@Sun.COM info501->shi501_reserved = 0; 8859832Samw@Sun.COM param->result.ru.info501 = info501; 8869832Samw@Sun.COM break; 8879832Samw@Sun.COM 8889832Samw@Sun.COM case 502: 8899832Samw@Sun.COM info502 = &info->nsg_info502; 8909832Samw@Sun.COM info502->shi502_netname = netname; 8919832Samw@Sun.COM info502->shi502_comment = comment; 8929832Samw@Sun.COM info502->shi502_path = 8939832Samw@Sun.COM (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path); 8949832Samw@Sun.COM info502->shi502_passwd = 0; 8959832Samw@Sun.COM info502->shi502_type = si.shr_type; 8969832Samw@Sun.COM info502->shi502_permissions = 0; 8979832Samw@Sun.COM info502->shi502_max_uses = SHI_USES_UNLIMITED; 8989832Samw@Sun.COM info502->shi502_current_uses = 0; 8999832Samw@Sun.COM 9009832Samw@Sun.COM status = srvsvc_share_getsd(mxa, &si, &sd); 9019832Samw@Sun.COM if (status == ERROR_SUCCESS) { 9029832Samw@Sun.COM info502->shi502_reserved = sd.sd_size; 9039832Samw@Sun.COM info502->shi502_security_descriptor = sd.sd_buf; 9049832Samw@Sun.COM } else { 9059832Samw@Sun.COM info502->shi502_reserved = 0; 9069832Samw@Sun.COM info502->shi502_security_descriptor = NULL; 9078474SJose.Borrego@Sun.COM } 9088474SJose.Borrego@Sun.COM 9099832Samw@Sun.COM param->result.ru.info502 = info502; 9109832Samw@Sun.COM break; 9119832Samw@Sun.COM 9129832Samw@Sun.COM case 503: 9139832Samw@Sun.COM info503 = &info->nsg_info503; 9149832Samw@Sun.COM info503->shi503_netname = netname; 9159832Samw@Sun.COM info503->shi503_comment = comment; 9169832Samw@Sun.COM info503->shi503_path = 9179832Samw@Sun.COM (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path); 9189832Samw@Sun.COM info503->shi503_passwd = NULL; 9199832Samw@Sun.COM info503->shi503_type = si.shr_type; 9209832Samw@Sun.COM info503->shi503_permissions = 0; 9219832Samw@Sun.COM info503->shi503_max_uses = SHI_USES_UNLIMITED; 9229832Samw@Sun.COM info503->shi503_current_uses = 0; 9239832Samw@Sun.COM info503->shi503_servername = NULL; 9249832Samw@Sun.COM 9259832Samw@Sun.COM status = srvsvc_share_getsd(mxa, &si, &sd); 9269832Samw@Sun.COM if (status == ERROR_SUCCESS) { 9279832Samw@Sun.COM info503->shi503_reserved = sd.sd_size; 9289832Samw@Sun.COM info503->shi503_security_descriptor = sd.sd_buf; 9299832Samw@Sun.COM } else { 9309832Samw@Sun.COM info503->shi503_reserved = 0; 9319832Samw@Sun.COM info503->shi503_security_descriptor = NULL; 9329832Samw@Sun.COM } 9339832Samw@Sun.COM 9349832Samw@Sun.COM param->result.ru.info503 = info503; 9359832Samw@Sun.COM break; 9369832Samw@Sun.COM 9379832Samw@Sun.COM case 1004: 9389832Samw@Sun.COM info1004 = &info->nsg_info1004; 9399832Samw@Sun.COM info1004->shi1004_comment = comment; 9409832Samw@Sun.COM param->result.ru.info1004 = info1004; 9418474SJose.Borrego@Sun.COM break; 9428474SJose.Borrego@Sun.COM 9438474SJose.Borrego@Sun.COM case 1005: 9449832Samw@Sun.COM info1005 = &info->nsg_info1005; 9458474SJose.Borrego@Sun.COM info1005->shi1005_flags = 0; 9468474SJose.Borrego@Sun.COM 9478474SJose.Borrego@Sun.COM switch (si.shr_flags & SMB_SHRF_CSC_MASK) { 9488474SJose.Borrego@Sun.COM case SMB_SHRF_CSC_DISABLED: 9498474SJose.Borrego@Sun.COM info1005->shi1005_flags |= CSC_CACHE_NONE; 9508474SJose.Borrego@Sun.COM break; 9518474SJose.Borrego@Sun.COM case SMB_SHRF_CSC_AUTO: 9528474SJose.Borrego@Sun.COM info1005->shi1005_flags |= CSC_CACHE_AUTO_REINT; 9538474SJose.Borrego@Sun.COM break; 9548474SJose.Borrego@Sun.COM case SMB_SHRF_CSC_VDO: 9558474SJose.Borrego@Sun.COM info1005->shi1005_flags |= CSC_CACHE_VDO; 9568474SJose.Borrego@Sun.COM break; 9578474SJose.Borrego@Sun.COM case SMB_SHRF_CSC_MANUAL: 9588474SJose.Borrego@Sun.COM default: 9598474SJose.Borrego@Sun.COM /* 9608474SJose.Borrego@Sun.COM * Default to CSC_CACHE_MANUAL_REINT. 9618474SJose.Borrego@Sun.COM */ 9628474SJose.Borrego@Sun.COM break; 9638474SJose.Borrego@Sun.COM } 9648474SJose.Borrego@Sun.COM 9658474SJose.Borrego@Sun.COM param->result.ru.info1005 = info1005; 9668474SJose.Borrego@Sun.COM break; 9678474SJose.Borrego@Sun.COM 9688474SJose.Borrego@Sun.COM case 1006: 9699832Samw@Sun.COM info1006 = &info->nsg_info1006; 9708474SJose.Borrego@Sun.COM info1006->shi1006_max_uses = SHI_USES_UNLIMITED; 9718474SJose.Borrego@Sun.COM param->result.ru.info1006 = info1006; 9728474SJose.Borrego@Sun.COM break; 9738474SJose.Borrego@Sun.COM 9749832Samw@Sun.COM case 1501: 9759832Samw@Sun.COM info1501 = &info->nsg_info1501; 9769832Samw@Sun.COM 9779832Samw@Sun.COM status = srvsvc_share_getsd(mxa, &si, &sd); 9789832Samw@Sun.COM if (status == ERROR_SUCCESS) { 9799832Samw@Sun.COM info503->shi503_reserved = sd.sd_size; 9809832Samw@Sun.COM info503->shi503_security_descriptor = sd.sd_buf; 9819832Samw@Sun.COM } else { 9829832Samw@Sun.COM info503->shi503_reserved = 0; 9839832Samw@Sun.COM info503->shi503_security_descriptor = NULL; 9848474SJose.Borrego@Sun.COM } 9858474SJose.Borrego@Sun.COM 9869832Samw@Sun.COM param->result.ru.info1501 = info1501; 9878474SJose.Borrego@Sun.COM break; 9888474SJose.Borrego@Sun.COM 9898474SJose.Borrego@Sun.COM default: 9908474SJose.Borrego@Sun.COM status = ERROR_ACCESS_DENIED; 9918474SJose.Borrego@Sun.COM break; 9928474SJose.Borrego@Sun.COM } 9938474SJose.Borrego@Sun.COM 9948474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 9958474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mlsm_NetShareGetInfo)); 9968474SJose.Borrego@Sun.COM else 9978474SJose.Borrego@Sun.COM param->result.switch_value = param->level; 9988474SJose.Borrego@Sun.COM 9998474SJose.Borrego@Sun.COM param->status = status; 10008474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 10018474SJose.Borrego@Sun.COM } 10028474SJose.Borrego@Sun.COM 10039832Samw@Sun.COM static uint32_t 10049832Samw@Sun.COM srvsvc_share_getsd(ndr_xa_t *mxa, smb_share_t *si, srvsvc_sd_t *sd) 10059832Samw@Sun.COM { 10069832Samw@Sun.COM uint32_t status; 10079832Samw@Sun.COM 10089832Samw@Sun.COM status = srvsvc_sd_get(si, NULL, &sd->sd_size); 10099832Samw@Sun.COM if (status != ERROR_SUCCESS) { 10109832Samw@Sun.COM if (status == ERROR_PATH_NOT_FOUND) { 10119832Samw@Sun.COM bzero(sd, sizeof (srvsvc_sd_t)); 10129832Samw@Sun.COM status = ERROR_SUCCESS; 10139832Samw@Sun.COM } 10149832Samw@Sun.COM 10159832Samw@Sun.COM return (status); 10169832Samw@Sun.COM } 10179832Samw@Sun.COM 10189832Samw@Sun.COM if ((sd->sd_buf = NDR_MALLOC(mxa, sd->sd_size)) == NULL) 10199832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 10209832Samw@Sun.COM 10219832Samw@Sun.COM status = srvsvc_sd_get(si, sd->sd_buf, NULL); 10229832Samw@Sun.COM if (status == ERROR_PATH_NOT_FOUND) { 10239832Samw@Sun.COM bzero(sd, sizeof (srvsvc_sd_t)); 10249832Samw@Sun.COM status = ERROR_SUCCESS; 10259832Samw@Sun.COM } 10269832Samw@Sun.COM 10279832Samw@Sun.COM return (status); 10289832Samw@Sun.COM } 10298474SJose.Borrego@Sun.COM 10308474SJose.Borrego@Sun.COM /* 10318474SJose.Borrego@Sun.COM * srvsvc_s_NetShareSetInfo 10328474SJose.Borrego@Sun.COM * 10338474SJose.Borrego@Sun.COM * This call is made by SrvMgr to set share information. 10349832Samw@Sun.COM * Only power users groups can manage shares. 10359832Samw@Sun.COM * 10369832Samw@Sun.COM * To avoid misleading errors, we don't report an error 10379832Samw@Sun.COM * when a FS doesn't support ACLs on shares. 10388474SJose.Borrego@Sun.COM * 10398474SJose.Borrego@Sun.COM * Returns Win32 error codes. 10408474SJose.Borrego@Sun.COM */ 10418474SJose.Borrego@Sun.COM static int 10428474SJose.Borrego@Sun.COM srvsvc_s_NetShareSetInfo(void *arg, ndr_xa_t *mxa) 10438474SJose.Borrego@Sun.COM { 10448474SJose.Borrego@Sun.COM struct mlsm_NetShareSetInfo *param = arg; 10459832Samw@Sun.COM struct mslm_NetShareInfo_0 *info0; 10469832Samw@Sun.COM struct mslm_NetShareInfo_1 *info1; 10479832Samw@Sun.COM struct mslm_NetShareInfo_2 *info2; 10489832Samw@Sun.COM struct mslm_NetShareInfo_501 *info501; 10499832Samw@Sun.COM struct mslm_NetShareInfo_502 *info502; 10509832Samw@Sun.COM struct mslm_NetShareInfo_503 *info503; 10519832Samw@Sun.COM struct mslm_NetShareInfo_1004 *info1004; 10529832Samw@Sun.COM struct mslm_NetShareInfo_1005 *info1005; 10539832Samw@Sun.COM struct mslm_NetShareInfo_1501 *info1501; 10549832Samw@Sun.COM static DWORD parm_err = 0; 10559832Samw@Sun.COM srvsvc_netshare_setinfo_t info; 10569832Samw@Sun.COM smb_share_t si; 10579832Samw@Sun.COM uint8_t *sdbuf; 10589832Samw@Sun.COM int32_t native_os; 10599832Samw@Sun.COM DWORD status; 10609832Samw@Sun.COM 10619832Samw@Sun.COM native_os = ndr_native_os(mxa); 10629832Samw@Sun.COM 10639832Samw@Sun.COM if (!ndr_is_poweruser(mxa)) { 10649832Samw@Sun.COM status = ERROR_ACCESS_DENIED; 10659832Samw@Sun.COM goto netsharesetinfo_exit; 10669832Samw@Sun.COM } 10679832Samw@Sun.COM 10689832Samw@Sun.COM if (smb_shr_get((char *)param->netname, &si) != NERR_Success) { 10699832Samw@Sun.COM status = ERROR_INVALID_NETNAME; 10709832Samw@Sun.COM goto netsharesetinfo_exit; 10719832Samw@Sun.COM } 10729832Samw@Sun.COM 10739832Samw@Sun.COM if (param->result.ru.nullptr == NULL) { 10749832Samw@Sun.COM status = ERROR_INVALID_PARAMETER; 10759832Samw@Sun.COM goto netsharesetinfo_exit; 10769832Samw@Sun.COM } 10779832Samw@Sun.COM 10789832Samw@Sun.COM bzero(&info, sizeof (srvsvc_netshare_setinfo_t)); 10799832Samw@Sun.COM 10809832Samw@Sun.COM switch (param->level) { 10819832Samw@Sun.COM case 0: 10829832Samw@Sun.COM info0 = (struct mslm_NetShareInfo_0 *)param->result.ru.info0; 10839832Samw@Sun.COM info.nss_netname = (char *)info0->shi0_netname; 10849832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 10859832Samw@Sun.COM break; 10869832Samw@Sun.COM 10879832Samw@Sun.COM case 1: 10889832Samw@Sun.COM info1 = (struct mslm_NetShareInfo_1 *)param->result.ru.info1; 10899832Samw@Sun.COM info.nss_netname = (char *)info1->shi1_netname; 10909832Samw@Sun.COM info.nss_comment = (char *)info1->shi1_comment; 10919832Samw@Sun.COM info.nss_type = info1->shi1_type; 10929832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 10939832Samw@Sun.COM break; 10949832Samw@Sun.COM 10959832Samw@Sun.COM case 2: 10969832Samw@Sun.COM info2 = (struct mslm_NetShareInfo_2 *)param->result.ru.info2; 10979832Samw@Sun.COM info.nss_netname = (char *)info2->shi2_netname; 10989832Samw@Sun.COM info.nss_comment = (char *)info2->shi2_comment; 10999832Samw@Sun.COM info.nss_path = (char *)info2->shi2_path; 11009832Samw@Sun.COM info.nss_type = info2->shi2_type; 11019832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 11029832Samw@Sun.COM break; 11039832Samw@Sun.COM 11049832Samw@Sun.COM case 501: 11059832Samw@Sun.COM info501 = (struct mslm_NetShareInfo_501 *) 11069832Samw@Sun.COM param->result.ru.info501; 11079832Samw@Sun.COM info.nss_netname = (char *)info501->shi501_netname; 11089832Samw@Sun.COM info.nss_comment = (char *)info501->shi501_comment; 11099832Samw@Sun.COM info.nss_type = info501->shi501_type; 11109832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 11119832Samw@Sun.COM break; 11129832Samw@Sun.COM 11139832Samw@Sun.COM case 502: 11149832Samw@Sun.COM info502 = (struct mslm_NetShareInfo_502 *) 11159832Samw@Sun.COM param->result.ru.info502; 11169832Samw@Sun.COM info.nss_netname = (char *)info502->shi502_netname; 11179832Samw@Sun.COM info.nss_comment = (char *)info502->shi502_comment; 11189832Samw@Sun.COM info.nss_path = (char *)info502->shi502_path; 11199832Samw@Sun.COM info.nss_type = info502->shi502_type; 11209832Samw@Sun.COM info.nss_sd.sd_buf = info502->shi502_security_descriptor; 11219832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 11229832Samw@Sun.COM break; 11239832Samw@Sun.COM 11249832Samw@Sun.COM case 503: 11259832Samw@Sun.COM info503 = (struct mslm_NetShareInfo_503 *) 11269832Samw@Sun.COM param->result.ru.info503; 11279832Samw@Sun.COM info.nss_netname = (char *)info503->shi503_netname; 11289832Samw@Sun.COM info.nss_comment = (char *)info503->shi503_comment; 11299832Samw@Sun.COM info.nss_path = (char *)info503->shi503_path; 11309832Samw@Sun.COM info.nss_type = info503->shi503_type; 11319832Samw@Sun.COM info.nss_sd.sd_buf = info503->shi503_security_descriptor; 11329832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 11339832Samw@Sun.COM break; 11349832Samw@Sun.COM 11359832Samw@Sun.COM case 1004: 11369832Samw@Sun.COM info1004 = (struct mslm_NetShareInfo_1004 *) 11379832Samw@Sun.COM param->result.ru.info1004; 11389832Samw@Sun.COM info.nss_comment = (char *)info1004->shi1004_comment; 11399832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 11409832Samw@Sun.COM break; 11419832Samw@Sun.COM 11429832Samw@Sun.COM case 1005: 11439832Samw@Sun.COM info1005 = (struct mslm_NetShareInfo_1005 *) 11449832Samw@Sun.COM param->result.ru.info1005; 11459832Samw@Sun.COM status = srvsvc_update_share_flags(&si, 11469832Samw@Sun.COM info1005->shi1005_flags); 11479832Samw@Sun.COM break; 11489832Samw@Sun.COM 11499832Samw@Sun.COM case 1006: 11509832Samw@Sun.COM /* 11519832Samw@Sun.COM * We don't limit the maximum number of concurrent 11529832Samw@Sun.COM * connections to a share. 11539832Samw@Sun.COM */ 11549832Samw@Sun.COM status = ERROR_SUCCESS; 11559832Samw@Sun.COM break; 11569832Samw@Sun.COM 11579832Samw@Sun.COM case 1501: 11589832Samw@Sun.COM info1501 = (struct mslm_NetShareInfo_1501 *) 11599832Samw@Sun.COM param->result.ru.info1501; 11609832Samw@Sun.COM sdbuf = info1501->shi1501_security_descriptor; 11619832Samw@Sun.COM status = ERROR_SUCCESS; 11629832Samw@Sun.COM 11639832Samw@Sun.COM if (sdbuf != NULL) { 11649832Samw@Sun.COM status = srvsvc_sd_set(&si, sdbuf); 11659832Samw@Sun.COM if (status == ERROR_PATH_NOT_FOUND) 11669832Samw@Sun.COM status = ERROR_SUCCESS; 11679832Samw@Sun.COM } 11689832Samw@Sun.COM break; 11699832Samw@Sun.COM 11709832Samw@Sun.COM default: 11719832Samw@Sun.COM status = ERROR_ACCESS_DENIED; 11729832Samw@Sun.COM break; 11739832Samw@Sun.COM } 11749832Samw@Sun.COM 11759832Samw@Sun.COM netsharesetinfo_exit: 11769832Samw@Sun.COM if (status != ERROR_SUCCESS) 11779832Samw@Sun.COM bzero(param, sizeof (struct mlsm_NetShareSetInfo)); 11789832Samw@Sun.COM 11799832Samw@Sun.COM param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; 11809832Samw@Sun.COM param->status = status; 11818474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 11828474SJose.Borrego@Sun.COM } 11838474SJose.Borrego@Sun.COM 11849832Samw@Sun.COM static uint32_t 11859832Samw@Sun.COM srvsvc_modify_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info) 11869832Samw@Sun.COM { 11879832Samw@Sun.COM uint32_t nerr = NERR_Success; 11889832Samw@Sun.COM 11899832Samw@Sun.COM if (si->shr_flags & SMB_SHRF_TRANS) 11909832Samw@Sun.COM return (srvsvc_modify_transient_share(si, info)); 11919832Samw@Sun.COM 11929832Samw@Sun.COM if (info->nss_sd.sd_buf != NULL) { 11939832Samw@Sun.COM nerr = srvsvc_sd_set(si, info->nss_sd.sd_buf); 11949832Samw@Sun.COM if (nerr == ERROR_PATH_NOT_FOUND) 11959832Samw@Sun.COM nerr = NERR_Success; 11969832Samw@Sun.COM } 11979832Samw@Sun.COM 11989832Samw@Sun.COM if ((nerr = srvsvc_sa_modify(si, info)) == NERR_Success) 11999832Samw@Sun.COM nerr = smb_shr_modify(si); 12009832Samw@Sun.COM 12019832Samw@Sun.COM return (nerr); 12029832Samw@Sun.COM } 12039832Samw@Sun.COM 12049832Samw@Sun.COM /* 12059832Samw@Sun.COM * Update transient shares. This includes autohome shares. 12069832Samw@Sun.COM */ 12079832Samw@Sun.COM static uint32_t 12089832Samw@Sun.COM srvsvc_modify_transient_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info) 12099832Samw@Sun.COM { 12109832Samw@Sun.COM uint32_t nerr; 12119832Samw@Sun.COM 12129832Samw@Sun.COM if (info->nss_netname != NULL && info->nss_netname[0] != '\0' && 12139832Samw@Sun.COM utf8_strcasecmp(info->nss_netname, si->shr_name) != 0) { 12149832Samw@Sun.COM nerr = smb_shr_rename(si->shr_name, info->nss_netname); 12159832Samw@Sun.COM if (nerr != NERR_Success) 12169832Samw@Sun.COM return (nerr); 12179832Samw@Sun.COM 12189832Samw@Sun.COM (void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN); 12199832Samw@Sun.COM } 12209832Samw@Sun.COM 12219832Samw@Sun.COM if ((info->nss_comment != NULL) && 12229832Samw@Sun.COM (strcmp(info->nss_comment, si->shr_cmnt) != 0)) { 12239832Samw@Sun.COM (void) strlcpy(si->shr_cmnt, info->nss_comment, 12249832Samw@Sun.COM SMB_SHARE_CMNT_MAX); 12259832Samw@Sun.COM 12269832Samw@Sun.COM if ((nerr = smb_shr_modify(si)) != NERR_Success) 12279832Samw@Sun.COM return (nerr); 12289832Samw@Sun.COM } 12299832Samw@Sun.COM 12309832Samw@Sun.COM return (NERR_Success); 12319832Samw@Sun.COM } 12329832Samw@Sun.COM 12339832Samw@Sun.COM static uint32_t 12349832Samw@Sun.COM srvsvc_update_share_flags(smb_share_t *si, uint32_t shi_flags) 12359832Samw@Sun.COM { 12369832Samw@Sun.COM uint32_t cscflg = 0; 12379832Samw@Sun.COM uint32_t nerr = NERR_Success; 12389832Samw@Sun.COM 12399832Samw@Sun.COM switch ((shi_flags & CSC_MASK)) { 12409832Samw@Sun.COM case CSC_CACHE_AUTO_REINT: 12419832Samw@Sun.COM cscflg = SMB_SHRF_CSC_AUTO; 12429832Samw@Sun.COM break; 12439832Samw@Sun.COM case CSC_CACHE_VDO: 12449832Samw@Sun.COM cscflg = SMB_SHRF_CSC_VDO; 12459832Samw@Sun.COM break; 12469832Samw@Sun.COM case CSC_CACHE_NONE: 12479832Samw@Sun.COM cscflg = SMB_SHRF_CSC_DISABLED; 12489832Samw@Sun.COM break; 12499832Samw@Sun.COM case CSC_CACHE_MANUAL_REINT: 12509832Samw@Sun.COM cscflg = SMB_SHRF_CSC_MANUAL; 12519832Samw@Sun.COM break; 12529832Samw@Sun.COM default: 12539832Samw@Sun.COM return (NERR_Success); 12549832Samw@Sun.COM } 12559832Samw@Sun.COM 12569832Samw@Sun.COM if (cscflg == (si->shr_flags & SMB_SHRF_CSC_MASK)) 12579832Samw@Sun.COM return (NERR_Success); 12589832Samw@Sun.COM 12599832Samw@Sun.COM si->shr_flags &= ~SMB_SHRF_CSC_MASK; 12609832Samw@Sun.COM si->shr_flags |= cscflg; 12619832Samw@Sun.COM 12629832Samw@Sun.COM if ((si->shr_flags & SMB_SHRF_TRANS) == 0) { 12639832Samw@Sun.COM if ((nerr = srvsvc_sa_setattr(si)) != NERR_Success) 12649832Samw@Sun.COM return (nerr); 12659832Samw@Sun.COM } 12669832Samw@Sun.COM 12679832Samw@Sun.COM return (smb_shr_modify(si)); 12689832Samw@Sun.COM } 12699832Samw@Sun.COM 12708474SJose.Borrego@Sun.COM /* 12718474SJose.Borrego@Sun.COM * srvsvc_s_NetSessionEnum 12728474SJose.Borrego@Sun.COM * 12738474SJose.Borrego@Sun.COM * Level 1 request is made by (Server Manager (srvmgr) on NT Server when 12748474SJose.Borrego@Sun.COM * the user info icon is selected. 12758474SJose.Borrego@Sun.COM * 12768474SJose.Borrego@Sun.COM * On success, the return value is NERR_Success. 12778474SJose.Borrego@Sun.COM * On error, the return value can be one of the following error codes: 12788474SJose.Borrego@Sun.COM * 12798474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED The user does not have access to the requested 12808474SJose.Borrego@Sun.COM * information. 12818474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL The value specified for the level is invalid. 12828474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER The specified parameter is invalid. 12838474SJose.Borrego@Sun.COM * ERROR_MORE_DATA More entries are available. Specify a large 12848474SJose.Borrego@Sun.COM * enough buffer to receive all entries. 12858474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 12868474SJose.Borrego@Sun.COM * NERR_ClientNameNotFound A session does not exist with the computer name. 12878474SJose.Borrego@Sun.COM * NERR_InvalidComputer The computer name is invalid. 12888474SJose.Borrego@Sun.COM * NERR_UserNotFound The user name could not be found. 12898474SJose.Borrego@Sun.COM */ 12908474SJose.Borrego@Sun.COM static int 12918474SJose.Borrego@Sun.COM srvsvc_s_NetSessionEnum(void *arg, ndr_xa_t *mxa) 12928474SJose.Borrego@Sun.COM { 1293*10122SJordan.Brown@Sun.COM struct mslm_NetSessionEnum *param = arg; 1294*10122SJordan.Brown@Sun.COM srvsvc_infonres_t *info; 1295*10122SJordan.Brown@Sun.COM smb_netsvc_t *ns; 1296*10122SJordan.Brown@Sun.COM smb_svcenum_t se; 1297*10122SJordan.Brown@Sun.COM DWORD status = ERROR_SUCCESS; 1298*10122SJordan.Brown@Sun.COM 1299*10122SJordan.Brown@Sun.COM if (!ndr_is_admin(mxa)) { 1300*10122SJordan.Brown@Sun.COM status = ERROR_ACCESS_DENIED; 1301*10122SJordan.Brown@Sun.COM goto srvsvc_netsessionenum_error; 1302*10122SJordan.Brown@Sun.COM } 1303*10122SJordan.Brown@Sun.COM 1304*10122SJordan.Brown@Sun.COM if ((info = NDR_NEW(mxa, srvsvc_infonres_t)) == NULL) { 1305*10122SJordan.Brown@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 1306*10122SJordan.Brown@Sun.COM goto srvsvc_netsessionenum_error; 1307*10122SJordan.Brown@Sun.COM } 1308*10122SJordan.Brown@Sun.COM 1309*10122SJordan.Brown@Sun.COM info->entriesread = 0; 1310*10122SJordan.Brown@Sun.COM info->entries = NULL; 1311*10122SJordan.Brown@Sun.COM param->result.level = param->level; 1312*10122SJordan.Brown@Sun.COM param->result.bufptr.p = info; 1313*10122SJordan.Brown@Sun.COM 1314*10122SJordan.Brown@Sun.COM if ((param->total_entries = srvsvc_open_sessions()) == 0) { 1315*10122SJordan.Brown@Sun.COM param->resume_handle = NULL; 1316*10122SJordan.Brown@Sun.COM param->status = ERROR_SUCCESS; 13178474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 13188474SJose.Borrego@Sun.COM } 13198474SJose.Borrego@Sun.COM 1320*10122SJordan.Brown@Sun.COM bzero(&se, sizeof (smb_svcenum_t)); 1321*10122SJordan.Brown@Sun.COM se.se_type = SMB_SVCENUM_TYPE_USER; 1322*10122SJordan.Brown@Sun.COM se.se_level = param->level; 1323*10122SJordan.Brown@Sun.COM se.se_ntotal = param->total_entries; 1324*10122SJordan.Brown@Sun.COM se.se_nlimit = se.se_ntotal; 1325*10122SJordan.Brown@Sun.COM 1326*10122SJordan.Brown@Sun.COM if (param->resume_handle) { 1327*10122SJordan.Brown@Sun.COM se.se_resume = *param->resume_handle; 1328*10122SJordan.Brown@Sun.COM se.se_nskip = se.se_resume; 1329*10122SJordan.Brown@Sun.COM *param->resume_handle = 0; 1330*10122SJordan.Brown@Sun.COM } 13318474SJose.Borrego@Sun.COM 13328474SJose.Borrego@Sun.COM switch (param->level) { 13338474SJose.Borrego@Sun.COM case 0: 1334*10122SJordan.Brown@Sun.COM info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_0, 1335*10122SJordan.Brown@Sun.COM se.se_nlimit); 13368474SJose.Borrego@Sun.COM break; 1337*10122SJordan.Brown@Sun.COM case 1: 1338*10122SJordan.Brown@Sun.COM info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_1, 1339*10122SJordan.Brown@Sun.COM se.se_nlimit); 13409832Samw@Sun.COM break; 1341*10122SJordan.Brown@Sun.COM case 2: 1342*10122SJordan.Brown@Sun.COM info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_2, 1343*10122SJordan.Brown@Sun.COM se.se_nlimit); 13449832Samw@Sun.COM break; 1345*10122SJordan.Brown@Sun.COM case 10: 1346*10122SJordan.Brown@Sun.COM info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_10, 1347*10122SJordan.Brown@Sun.COM se.se_nlimit); 1348*10122SJordan.Brown@Sun.COM break; 13499832Samw@Sun.COM case 502: 1350*10122SJordan.Brown@Sun.COM info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_502, 1351*10122SJordan.Brown@Sun.COM se.se_nlimit); 13529832Samw@Sun.COM break; 13538474SJose.Borrego@Sun.COM default: 13548474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetSessionEnum)); 1355*10122SJordan.Brown@Sun.COM param->status = ERROR_INVALID_LEVEL; 13568474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 13578474SJose.Borrego@Sun.COM } 13588474SJose.Borrego@Sun.COM 1359*10122SJordan.Brown@Sun.COM if (info->entries == NULL) { 1360*10122SJordan.Brown@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 1361*10122SJordan.Brown@Sun.COM goto srvsvc_netsessionenum_error; 1362*10122SJordan.Brown@Sun.COM } 1363*10122SJordan.Brown@Sun.COM 1364*10122SJordan.Brown@Sun.COM if ((ns = smb_kmod_enum_init(&se)) == NULL) { 1365*10122SJordan.Brown@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 1366*10122SJordan.Brown@Sun.COM goto srvsvc_netsessionenum_error; 1367*10122SJordan.Brown@Sun.COM } 1368*10122SJordan.Brown@Sun.COM 1369*10122SJordan.Brown@Sun.COM status = srvsvc_NetSessionEnumCommon(mxa, info, ns, &se); 1370*10122SJordan.Brown@Sun.COM smb_kmod_enum_fini(ns); 1371*10122SJordan.Brown@Sun.COM 1372*10122SJordan.Brown@Sun.COM if (status != ERROR_SUCCESS) 1373*10122SJordan.Brown@Sun.COM goto srvsvc_netsessionenum_error; 1374*10122SJordan.Brown@Sun.COM 1375*10122SJordan.Brown@Sun.COM if (param->resume_handle && 1376*10122SJordan.Brown@Sun.COM param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) { 1377*10122SJordan.Brown@Sun.COM if (se.se_resume < param->total_entries) { 1378*10122SJordan.Brown@Sun.COM *param->resume_handle = se.se_resume; 1379*10122SJordan.Brown@Sun.COM status = ERROR_MORE_DATA; 1380*10122SJordan.Brown@Sun.COM } 1381*10122SJordan.Brown@Sun.COM } 1382*10122SJordan.Brown@Sun.COM 1383*10122SJordan.Brown@Sun.COM param->total_entries = info->entriesread; 1384*10122SJordan.Brown@Sun.COM param->status = status; 1385*10122SJordan.Brown@Sun.COM return (NDR_DRC_OK); 1386*10122SJordan.Brown@Sun.COM 1387*10122SJordan.Brown@Sun.COM srvsvc_netsessionenum_error: 1388*10122SJordan.Brown@Sun.COM bzero(param, sizeof (struct mslm_NetSessionEnum)); 13898474SJose.Borrego@Sun.COM param->status = status; 13908474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 13918474SJose.Borrego@Sun.COM } 13928474SJose.Borrego@Sun.COM 1393*10122SJordan.Brown@Sun.COM static uint32_t 1394*10122SJordan.Brown@Sun.COM srvsvc_NetSessionEnumCommon(ndr_xa_t *mxa, srvsvc_infonres_t *info, 1395*10122SJordan.Brown@Sun.COM smb_netsvc_t *ns, smb_svcenum_t *se) 13968474SJose.Borrego@Sun.COM { 1397*10122SJordan.Brown@Sun.COM struct mslm_SESSION_INFO_0 *info0 = info->entries; 1398*10122SJordan.Brown@Sun.COM struct mslm_SESSION_INFO_1 *info1 = info->entries; 1399*10122SJordan.Brown@Sun.COM struct mslm_SESSION_INFO_2 *info2 = info->entries; 1400*10122SJordan.Brown@Sun.COM struct mslm_SESSION_INFO_10 *info10 = info->entries; 1401*10122SJordan.Brown@Sun.COM struct mslm_SESSION_INFO_502 *info502 = info->entries; 1402*10122SJordan.Brown@Sun.COM smb_netsvcitem_t *item; 1403*10122SJordan.Brown@Sun.COM smb_netuserinfo_t *user; 1404*10122SJordan.Brown@Sun.COM char *workstation; 1405*10122SJordan.Brown@Sun.COM char account[MAXNAMELEN]; 1406*10122SJordan.Brown@Sun.COM char ipaddr_buf[INET6_ADDRSTRLEN]; 1407*10122SJordan.Brown@Sun.COM uint32_t logon_time; 1408*10122SJordan.Brown@Sun.COM uint32_t flags; 1409*10122SJordan.Brown@Sun.COM uint32_t entries_read = 0; 1410*10122SJordan.Brown@Sun.COM 1411*10122SJordan.Brown@Sun.COM if (smb_kmod_enum(ns) != 0) 1412*10122SJordan.Brown@Sun.COM return (ERROR_INTERNAL_ERROR); 1413*10122SJordan.Brown@Sun.COM 1414*10122SJordan.Brown@Sun.COM item = list_head(&ns->ns_list); 1415*10122SJordan.Brown@Sun.COM while (item != NULL) { 1416*10122SJordan.Brown@Sun.COM user = &item->nsi_un.nsi_user; 1417*10122SJordan.Brown@Sun.COM 1418*10122SJordan.Brown@Sun.COM workstation = user->ui_workstation; 14198474SJose.Borrego@Sun.COM if (workstation == NULL || *workstation == '\0') { 1420*10122SJordan.Brown@Sun.COM (void) smb_inet_ntop(&user->ui_ipaddr, ipaddr_buf, 1421*10122SJordan.Brown@Sun.COM SMB_IPSTRLEN(user->ui_ipaddr.a_family)); 14228474SJose.Borrego@Sun.COM workstation = ipaddr_buf; 14238474SJose.Borrego@Sun.COM } 14248474SJose.Borrego@Sun.COM 14258474SJose.Borrego@Sun.COM (void) snprintf(account, MAXNAMELEN, "%s\\%s", 1426*10122SJordan.Brown@Sun.COM user->ui_domain, user->ui_account); 1427*10122SJordan.Brown@Sun.COM 1428*10122SJordan.Brown@Sun.COM logon_time = time(0) - user->ui_logon_time; 1429*10122SJordan.Brown@Sun.COM flags = (user->ui_flags & SMB_ATF_GUEST) ? SESS_GUEST : 0; 1430*10122SJordan.Brown@Sun.COM 1431*10122SJordan.Brown@Sun.COM switch (se->se_level) { 1432*10122SJordan.Brown@Sun.COM case 0: 1433*10122SJordan.Brown@Sun.COM info0->sesi0_cname = NDR_STRDUP(mxa, workstation); 1434*10122SJordan.Brown@Sun.COM if (info0->sesi0_cname == NULL) 1435*10122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1436*10122SJordan.Brown@Sun.COM ++info0; 1437*10122SJordan.Brown@Sun.COM break; 1438*10122SJordan.Brown@Sun.COM 1439*10122SJordan.Brown@Sun.COM case 1: 1440*10122SJordan.Brown@Sun.COM info1->sesi1_cname = NDR_STRDUP(mxa, workstation); 1441*10122SJordan.Brown@Sun.COM info1->sesi1_uname = NDR_STRDUP(mxa, account); 1442*10122SJordan.Brown@Sun.COM 1443*10122SJordan.Brown@Sun.COM if (info1->sesi1_cname == NULL || 1444*10122SJordan.Brown@Sun.COM info1->sesi1_uname == NULL) 1445*10122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1446*10122SJordan.Brown@Sun.COM 1447*10122SJordan.Brown@Sun.COM info1->sesi1_nopens = user->ui_numopens; 1448*10122SJordan.Brown@Sun.COM info1->sesi1_time = logon_time; 1449*10122SJordan.Brown@Sun.COM info1->sesi1_itime = 0; 1450*10122SJordan.Brown@Sun.COM info1->sesi1_uflags = flags; 1451*10122SJordan.Brown@Sun.COM ++info1; 1452*10122SJordan.Brown@Sun.COM break; 1453*10122SJordan.Brown@Sun.COM 1454*10122SJordan.Brown@Sun.COM case 2: 1455*10122SJordan.Brown@Sun.COM info2->sesi2_cname = NDR_STRDUP(mxa, workstation); 1456*10122SJordan.Brown@Sun.COM info2->sesi2_uname = NDR_STRDUP(mxa, account); 1457*10122SJordan.Brown@Sun.COM 1458*10122SJordan.Brown@Sun.COM if (info2->sesi2_cname == NULL || 1459*10122SJordan.Brown@Sun.COM info2->sesi2_uname == NULL) 1460*10122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1461*10122SJordan.Brown@Sun.COM 1462*10122SJordan.Brown@Sun.COM info2->sesi2_nopens = user->ui_numopens; 1463*10122SJordan.Brown@Sun.COM info2->sesi2_time = logon_time; 1464*10122SJordan.Brown@Sun.COM info2->sesi2_itime = 0; 1465*10122SJordan.Brown@Sun.COM info2->sesi2_uflags = flags; 1466*10122SJordan.Brown@Sun.COM info2->sesi2_cltype_name = (uint8_t *)""; 1467*10122SJordan.Brown@Sun.COM ++info2; 1468*10122SJordan.Brown@Sun.COM break; 1469*10122SJordan.Brown@Sun.COM 1470*10122SJordan.Brown@Sun.COM case 10: 1471*10122SJordan.Brown@Sun.COM info10->sesi10_cname = NDR_STRDUP(mxa, workstation); 1472*10122SJordan.Brown@Sun.COM info10->sesi10_uname = NDR_STRDUP(mxa, account); 1473*10122SJordan.Brown@Sun.COM 1474*10122SJordan.Brown@Sun.COM if (info10->sesi10_cname == NULL || 1475*10122SJordan.Brown@Sun.COM info10->sesi10_uname == NULL) 1476*10122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1477*10122SJordan.Brown@Sun.COM 1478*10122SJordan.Brown@Sun.COM info10->sesi10_time = logon_time; 1479*10122SJordan.Brown@Sun.COM info10->sesi10_itime = 0; 1480*10122SJordan.Brown@Sun.COM ++info10; 1481*10122SJordan.Brown@Sun.COM break; 1482*10122SJordan.Brown@Sun.COM 1483*10122SJordan.Brown@Sun.COM case 502: 1484*10122SJordan.Brown@Sun.COM info502->sesi502_cname = NDR_STRDUP(mxa, workstation); 1485*10122SJordan.Brown@Sun.COM info502->sesi502_uname = NDR_STRDUP(mxa, account); 1486*10122SJordan.Brown@Sun.COM 1487*10122SJordan.Brown@Sun.COM if (info502->sesi502_cname == NULL || 1488*10122SJordan.Brown@Sun.COM info502->sesi502_uname == NULL) 1489*10122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 1490*10122SJordan.Brown@Sun.COM 1491*10122SJordan.Brown@Sun.COM info502->sesi502_nopens = user->ui_numopens; 1492*10122SJordan.Brown@Sun.COM info502->sesi502_time = logon_time; 1493*10122SJordan.Brown@Sun.COM info502->sesi502_itime = 0; 1494*10122SJordan.Brown@Sun.COM info502->sesi502_uflags = flags; 1495*10122SJordan.Brown@Sun.COM info502->sesi502_cltype_name = (uint8_t *)""; 1496*10122SJordan.Brown@Sun.COM info502->sesi502_transport = (uint8_t *)""; 1497*10122SJordan.Brown@Sun.COM ++info502; 1498*10122SJordan.Brown@Sun.COM break; 1499*10122SJordan.Brown@Sun.COM 1500*10122SJordan.Brown@Sun.COM default: 1501*10122SJordan.Brown@Sun.COM return (ERROR_INVALID_LEVEL); 15028474SJose.Borrego@Sun.COM } 15038474SJose.Borrego@Sun.COM 1504*10122SJordan.Brown@Sun.COM ++entries_read; 1505*10122SJordan.Brown@Sun.COM item = list_next(&ns->ns_list, item); 15069832Samw@Sun.COM } 15079832Samw@Sun.COM 1508*10122SJordan.Brown@Sun.COM info->entriesread = entries_read; 15099832Samw@Sun.COM return (ERROR_SUCCESS); 15109832Samw@Sun.COM } 15119832Samw@Sun.COM 15129832Samw@Sun.COM /* 15138474SJose.Borrego@Sun.COM * srvsvc_s_NetSessionDel 15148474SJose.Borrego@Sun.COM * 15158474SJose.Borrego@Sun.COM * Ends a network session between a server and a workstation. 15168474SJose.Borrego@Sun.COM * On NT only members of the Administrators or Account Operators 15178474SJose.Borrego@Sun.COM * local groups are permitted to use NetSessionDel. 15188474SJose.Borrego@Sun.COM * 1519*10122SJordan.Brown@Sun.COM * If unc_clientname is NULL, all sessions associated with the 1520*10122SJordan.Brown@Sun.COM * specified user will be disconnected. 1521*10122SJordan.Brown@Sun.COM * 1522*10122SJordan.Brown@Sun.COM * If username is NULL, all sessions from the specified client 1523*10122SJordan.Brown@Sun.COM * will be disconnected. 1524*10122SJordan.Brown@Sun.COM * 15258474SJose.Borrego@Sun.COM * Return Values 1526*10122SJordan.Brown@Sun.COM * On success, the return value is NERR_Success/ERROR_SUCCESS. 1527*10122SJordan.Brown@Sun.COM * On failure, the return value can be one of the following errors: 15288474SJose.Borrego@Sun.COM * 15298474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED The user does not have access to the 1530*10122SJordan.Brown@Sun.COM * requested information. 15318474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER The specified parameter is invalid. 15328474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 15338474SJose.Borrego@Sun.COM * NERR_ClientNameNotFound A session does not exist with that 1534*10122SJordan.Brown@Sun.COM * computer name. 15358474SJose.Borrego@Sun.COM */ 15368474SJose.Borrego@Sun.COM static int 15378474SJose.Borrego@Sun.COM srvsvc_s_NetSessionDel(void *arg, ndr_xa_t *mxa) 15388474SJose.Borrego@Sun.COM { 1539*10122SJordan.Brown@Sun.COM static struct { 1540*10122SJordan.Brown@Sun.COM int errnum; 1541*10122SJordan.Brown@Sun.COM int nerr; 1542*10122SJordan.Brown@Sun.COM } errmap[] = { 1543*10122SJordan.Brown@Sun.COM 0, ERROR_SUCCESS, 1544*10122SJordan.Brown@Sun.COM EACCES, ERROR_ACCESS_DENIED, 1545*10122SJordan.Brown@Sun.COM EPERM, ERROR_ACCESS_DENIED, 1546*10122SJordan.Brown@Sun.COM EINVAL, ERROR_INVALID_PARAMETER, 1547*10122SJordan.Brown@Sun.COM ENOMEM, ERROR_NOT_ENOUGH_MEMORY, 1548*10122SJordan.Brown@Sun.COM ENOENT, NERR_ClientNameNotFound 1549*10122SJordan.Brown@Sun.COM }; 1550*10122SJordan.Brown@Sun.COM 15518474SJose.Borrego@Sun.COM struct mslm_NetSessionDel *param = arg; 1552*10122SJordan.Brown@Sun.COM int i; 1553*10122SJordan.Brown@Sun.COM int rc; 1554*10122SJordan.Brown@Sun.COM 1555*10122SJordan.Brown@Sun.COM if (!ndr_is_admin(mxa)) { 15568474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 15578474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 15588474SJose.Borrego@Sun.COM } 15598474SJose.Borrego@Sun.COM 1560*10122SJordan.Brown@Sun.COM rc = smb_kmod_session_close((char *)param->unc_clientname, 1561*10122SJordan.Brown@Sun.COM (char *)param->username); 1562*10122SJordan.Brown@Sun.COM 1563*10122SJordan.Brown@Sun.COM for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) { 1564*10122SJordan.Brown@Sun.COM if (rc == errmap[i].errnum) { 1565*10122SJordan.Brown@Sun.COM param->status = errmap[i].nerr; 1566*10122SJordan.Brown@Sun.COM return (NDR_DRC_OK); 1567*10122SJordan.Brown@Sun.COM } 1568*10122SJordan.Brown@Sun.COM } 1569*10122SJordan.Brown@Sun.COM 1570*10122SJordan.Brown@Sun.COM param->status = ERROR_INTERNAL_ERROR; 15718474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 15728474SJose.Borrego@Sun.COM } 15738474SJose.Borrego@Sun.COM 15748474SJose.Borrego@Sun.COM /* 15758474SJose.Borrego@Sun.COM * SRVSVC NetServerGetInfo 15768474SJose.Borrego@Sun.COM * 15778474SJose.Borrego@Sun.COM * IN LPTSTR servername, 15788474SJose.Borrego@Sun.COM * IN DWORD level, 15798474SJose.Borrego@Sun.COM * OUT union switch(level) { 15808474SJose.Borrego@Sun.COM * case 100: mslm_SERVER_INFO_100 *p100; 15818474SJose.Borrego@Sun.COM * case 101: mslm_SERVER_INFO_101 *p101; 15828474SJose.Borrego@Sun.COM * case 102: mslm_SERVER_INFO_102 *p102; 15839832Samw@Sun.COM * ... 15848474SJose.Borrego@Sun.COM * default: char *nullptr; 15858474SJose.Borrego@Sun.COM * } bufptr, 15868474SJose.Borrego@Sun.COM * OUT DWORD status 15878474SJose.Borrego@Sun.COM */ 15888474SJose.Borrego@Sun.COM static int 15898474SJose.Borrego@Sun.COM srvsvc_s_NetServerGetInfo(void *arg, ndr_xa_t *mxa) 15908474SJose.Borrego@Sun.COM { 15918474SJose.Borrego@Sun.COM struct mslm_NetServerGetInfo *param = arg; 15928474SJose.Borrego@Sun.COM struct mslm_SERVER_INFO_100 *info100; 15938474SJose.Borrego@Sun.COM struct mslm_SERVER_INFO_101 *info101; 15948474SJose.Borrego@Sun.COM struct mslm_SERVER_INFO_102 *info102; 15959832Samw@Sun.COM struct mslm_SERVER_INFO_502 *info502; 15969832Samw@Sun.COM struct mslm_SERVER_INFO_503 *info503; 15978474SJose.Borrego@Sun.COM char sys_comment[SMB_PI_MAX_COMMENT]; 15988474SJose.Borrego@Sun.COM char hostname[NETBIOS_NAME_SZ]; 15998474SJose.Borrego@Sun.COM 16008474SJose.Borrego@Sun.COM if (smb_getnetbiosname(hostname, sizeof (hostname)) != 0) { 16018474SJose.Borrego@Sun.COM netservergetinfo_no_memory: 16028474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetServerGetInfo)); 16038474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 16048474SJose.Borrego@Sun.COM } 16058474SJose.Borrego@Sun.COM 16068474SJose.Borrego@Sun.COM (void) smb_config_getstr(SMB_CI_SYS_CMNT, sys_comment, 16078474SJose.Borrego@Sun.COM sizeof (sys_comment)); 16088474SJose.Borrego@Sun.COM if (*sys_comment == '\0') 16098474SJose.Borrego@Sun.COM (void) strcpy(sys_comment, " "); 16108474SJose.Borrego@Sun.COM 16118474SJose.Borrego@Sun.COM switch (param->level) { 16128474SJose.Borrego@Sun.COM case 100: 16138474SJose.Borrego@Sun.COM info100 = NDR_NEW(mxa, struct mslm_SERVER_INFO_100); 16148474SJose.Borrego@Sun.COM if (info100 == NULL) 16158474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 16168474SJose.Borrego@Sun.COM 16178474SJose.Borrego@Sun.COM bzero(info100, sizeof (struct mslm_SERVER_INFO_100)); 16188474SJose.Borrego@Sun.COM info100->sv100_platform_id = SV_PLATFORM_ID_NT; 16198474SJose.Borrego@Sun.COM info100->sv100_name = (uint8_t *)NDR_STRDUP(mxa, hostname); 16208474SJose.Borrego@Sun.COM if (info100->sv100_name == NULL) 16218474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 16228474SJose.Borrego@Sun.COM 16238474SJose.Borrego@Sun.COM param->result.bufptr.bufptr100 = info100; 16248474SJose.Borrego@Sun.COM break; 16258474SJose.Borrego@Sun.COM 16268474SJose.Borrego@Sun.COM case 101: 16278474SJose.Borrego@Sun.COM info101 = NDR_NEW(mxa, struct mslm_SERVER_INFO_101); 16288474SJose.Borrego@Sun.COM if (info101 == NULL) 16298474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 16308474SJose.Borrego@Sun.COM 16318474SJose.Borrego@Sun.COM bzero(info101, sizeof (struct mslm_SERVER_INFO_101)); 16328474SJose.Borrego@Sun.COM info101->sv101_platform_id = SV_PLATFORM_ID_NT; 16338474SJose.Borrego@Sun.COM info101->sv101_version_major = 4; 16348474SJose.Borrego@Sun.COM info101->sv101_version_minor = 0; 16358474SJose.Borrego@Sun.COM info101->sv101_type = SV_TYPE_SENT_BY_ME; 16368474SJose.Borrego@Sun.COM info101->sv101_name = (uint8_t *)NDR_STRDUP(mxa, hostname); 16378474SJose.Borrego@Sun.COM info101->sv101_comment 16388474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, sys_comment); 16398474SJose.Borrego@Sun.COM 16408474SJose.Borrego@Sun.COM if (info101->sv101_name == NULL || 16418474SJose.Borrego@Sun.COM info101->sv101_comment == NULL) 16428474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 16438474SJose.Borrego@Sun.COM 16448474SJose.Borrego@Sun.COM param->result.bufptr.bufptr101 = info101; 16458474SJose.Borrego@Sun.COM break; 16468474SJose.Borrego@Sun.COM 16478474SJose.Borrego@Sun.COM case 102: 16488474SJose.Borrego@Sun.COM info102 = NDR_NEW(mxa, struct mslm_SERVER_INFO_102); 16498474SJose.Borrego@Sun.COM if (info102 == NULL) 16508474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 16518474SJose.Borrego@Sun.COM 16528474SJose.Borrego@Sun.COM bzero(info102, sizeof (struct mslm_SERVER_INFO_102)); 16538474SJose.Borrego@Sun.COM info102->sv102_platform_id = SV_PLATFORM_ID_NT; 16548474SJose.Borrego@Sun.COM info102->sv102_version_major = 4; 16558474SJose.Borrego@Sun.COM info102->sv102_version_minor = 0; 16568474SJose.Borrego@Sun.COM info102->sv102_type = SV_TYPE_SENT_BY_ME; 16578474SJose.Borrego@Sun.COM info102->sv102_name = (uint8_t *)NDR_STRDUP(mxa, hostname); 16588474SJose.Borrego@Sun.COM info102->sv102_comment 16598474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, sys_comment); 16608474SJose.Borrego@Sun.COM 16618474SJose.Borrego@Sun.COM /* 16628474SJose.Borrego@Sun.COM * The following level 102 fields are defaulted to zero 16638474SJose.Borrego@Sun.COM * by virtue of the call to bzero above. 16648474SJose.Borrego@Sun.COM * 16658474SJose.Borrego@Sun.COM * sv102_users 16668474SJose.Borrego@Sun.COM * sv102_disc 16678474SJose.Borrego@Sun.COM * sv102_hidden 16688474SJose.Borrego@Sun.COM * sv102_announce 16698474SJose.Borrego@Sun.COM * sv102_anndelta 16708474SJose.Borrego@Sun.COM * sv102_licenses 16718474SJose.Borrego@Sun.COM * sv102_userpath 16728474SJose.Borrego@Sun.COM */ 16738474SJose.Borrego@Sun.COM if (info102->sv102_name == NULL || 16748474SJose.Borrego@Sun.COM info102->sv102_comment == NULL) 16758474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 16768474SJose.Borrego@Sun.COM 16778474SJose.Borrego@Sun.COM param->result.bufptr.bufptr102 = info102; 16788474SJose.Borrego@Sun.COM break; 16798474SJose.Borrego@Sun.COM 16809832Samw@Sun.COM case 502: 16819832Samw@Sun.COM info502 = NDR_NEW(mxa, struct mslm_SERVER_INFO_502); 16829832Samw@Sun.COM if (info502 == NULL) 16839832Samw@Sun.COM goto netservergetinfo_no_memory; 16849832Samw@Sun.COM 16859832Samw@Sun.COM bzero(info502, sizeof (struct mslm_SERVER_INFO_502)); 16869832Samw@Sun.COM param->result.bufptr.bufptr502 = info502; 16879832Samw@Sun.COM #ifdef SRVSVC_SATISFY_SMBTORTURE 16889832Samw@Sun.COM break; 16899832Samw@Sun.COM #else 16909832Samw@Sun.COM param->result.level = param->level; 16919832Samw@Sun.COM param->status = ERROR_ACCESS_DENIED; 16929832Samw@Sun.COM return (NDR_DRC_OK); 16939832Samw@Sun.COM #endif /* SRVSVC_SATISFY_SMBTORTURE */ 16949832Samw@Sun.COM 16959832Samw@Sun.COM case 503: 16969832Samw@Sun.COM info503 = NDR_NEW(mxa, struct mslm_SERVER_INFO_503); 16979832Samw@Sun.COM if (info503 == NULL) 16989832Samw@Sun.COM goto netservergetinfo_no_memory; 16999832Samw@Sun.COM 17009832Samw@Sun.COM bzero(info503, sizeof (struct mslm_SERVER_INFO_503)); 17019832Samw@Sun.COM param->result.bufptr.bufptr503 = info503; 17029832Samw@Sun.COM #ifdef SRVSVC_SATISFY_SMBTORTURE 17039832Samw@Sun.COM break; 17049832Samw@Sun.COM #else 17059832Samw@Sun.COM param->result.level = param->level; 17069832Samw@Sun.COM param->status = ERROR_ACCESS_DENIED; 17079832Samw@Sun.COM return (NDR_DRC_OK); 17089832Samw@Sun.COM #endif /* SRVSVC_SATISFY_SMBTORTURE */ 17099832Samw@Sun.COM 17108474SJose.Borrego@Sun.COM default: 17118474SJose.Borrego@Sun.COM bzero(¶m->result, 17128474SJose.Borrego@Sun.COM sizeof (struct mslm_NetServerGetInfo_result)); 17138474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 17148474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 17158474SJose.Borrego@Sun.COM } 17168474SJose.Borrego@Sun.COM 17178474SJose.Borrego@Sun.COM param->result.level = param->level; 17189832Samw@Sun.COM param->status = ERROR_SUCCESS; 17198474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 17208474SJose.Borrego@Sun.COM } 17218474SJose.Borrego@Sun.COM 17228474SJose.Borrego@Sun.COM /* 17238474SJose.Borrego@Sun.COM * NetRemoteTOD 17248474SJose.Borrego@Sun.COM * 17258474SJose.Borrego@Sun.COM * Returns information about the time of day on this server. 17268474SJose.Borrego@Sun.COM * 17278474SJose.Borrego@Sun.COM * typedef struct _TIME_OF_DAY_INFO { 17288474SJose.Borrego@Sun.COM * DWORD tod_elapsedt; // seconds since 00:00:00 January 1 1970 GMT 17298474SJose.Borrego@Sun.COM * DWORD tod_msecs; // arbitrary milliseconds (since reset) 17308474SJose.Borrego@Sun.COM * DWORD tod_hours; // current hour [0-23] 17318474SJose.Borrego@Sun.COM * DWORD tod_mins; // current minute [0-59] 17328474SJose.Borrego@Sun.COM * DWORD tod_secs; // current second [0-59] 17338474SJose.Borrego@Sun.COM * DWORD tod_hunds; // current hundredth (0.01) second [0-99] 17348474SJose.Borrego@Sun.COM * LONG tod_timezone; // time zone of the server 17358474SJose.Borrego@Sun.COM * DWORD tod_tinterval; // clock tick time interval 17368474SJose.Borrego@Sun.COM * DWORD tod_day; // day of the month [1-31] 17378474SJose.Borrego@Sun.COM * DWORD tod_month; // month of the year [1-12] 17388474SJose.Borrego@Sun.COM * DWORD tod_year; // current year 17398474SJose.Borrego@Sun.COM * DWORD tod_weekday; // day of the week since Sunday [0-6] 17408474SJose.Borrego@Sun.COM * } TIME_OF_DAY_INFO; 17418474SJose.Borrego@Sun.COM * 17428474SJose.Borrego@Sun.COM * The time zone of the server is calculated in minutes from Greenwich 17438474SJose.Borrego@Sun.COM * Mean Time (GMT). For time zones west of Greenwich, the value is 17448474SJose.Borrego@Sun.COM * positive; for time zones east of Greenwich, the value is negative. 17458474SJose.Borrego@Sun.COM * A value of -1 indicates that the time zone is undefined. 17468474SJose.Borrego@Sun.COM * 17478474SJose.Borrego@Sun.COM * The clock tick value represents a resolution of one ten-thousandth 17488474SJose.Borrego@Sun.COM * (0.0001) second. 17498474SJose.Borrego@Sun.COM */ 17508474SJose.Borrego@Sun.COM static int 17518474SJose.Borrego@Sun.COM srvsvc_s_NetRemoteTOD(void *arg, ndr_xa_t *mxa) 17528474SJose.Borrego@Sun.COM { 17538474SJose.Borrego@Sun.COM struct mslm_NetRemoteTOD *param = arg; 17548474SJose.Borrego@Sun.COM struct mslm_TIME_OF_DAY_INFO *tod; 17558474SJose.Borrego@Sun.COM struct timeval time_val; 17568474SJose.Borrego@Sun.COM struct tm tm; 17578474SJose.Borrego@Sun.COM 17588474SJose.Borrego@Sun.COM (void) gettimeofday(&time_val, 0); 17598474SJose.Borrego@Sun.COM (void) gmtime_r(&time_val.tv_sec, &tm); 17608474SJose.Borrego@Sun.COM 17618474SJose.Borrego@Sun.COM tod = NDR_NEW(mxa, struct mslm_TIME_OF_DAY_INFO); 17628474SJose.Borrego@Sun.COM if (tod == NULL) { 17638474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetRemoteTOD)); 17648474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 17658474SJose.Borrego@Sun.COM } 17668474SJose.Borrego@Sun.COM 17678474SJose.Borrego@Sun.COM tod->tod_elapsedt = time_val.tv_sec; 17688474SJose.Borrego@Sun.COM tod->tod_msecs = time_val.tv_usec; 17698474SJose.Borrego@Sun.COM tod->tod_hours = tm.tm_hour; 17708474SJose.Borrego@Sun.COM tod->tod_mins = tm.tm_min; 17718474SJose.Borrego@Sun.COM tod->tod_secs = tm.tm_sec; 17728474SJose.Borrego@Sun.COM tod->tod_hunds = 0; 17738474SJose.Borrego@Sun.COM tod->tod_tinterval = 1000; 17748474SJose.Borrego@Sun.COM tod->tod_day = tm.tm_mday; 17758474SJose.Borrego@Sun.COM tod->tod_month = tm.tm_mon+1; 17768474SJose.Borrego@Sun.COM tod->tod_year = tm.tm_year+1900; 17778474SJose.Borrego@Sun.COM tod->tod_weekday = tm.tm_wday; 17788474SJose.Borrego@Sun.COM 17798474SJose.Borrego@Sun.COM (void) localtime_r(&time_val.tv_sec, &tm); 17808474SJose.Borrego@Sun.COM 17818474SJose.Borrego@Sun.COM param->bufptr = tod; 17828474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 17838474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 17848474SJose.Borrego@Sun.COM } 17858474SJose.Borrego@Sun.COM 17868474SJose.Borrego@Sun.COM /* 17878474SJose.Borrego@Sun.COM * srvsvc_s_NetNameValidate 17888474SJose.Borrego@Sun.COM * 17898474SJose.Borrego@Sun.COM * Perform name validation. 17908474SJose.Borrego@Sun.COM * 17918474SJose.Borrego@Sun.COM * The share name is considered invalid if it contains any of the 17928474SJose.Borrego@Sun.COM * following character (MSDN 236388). 17938474SJose.Borrego@Sun.COM * 17948474SJose.Borrego@Sun.COM * " / \ [ ] : | < > + ; , ? * = 17958474SJose.Borrego@Sun.COM * 17968474SJose.Borrego@Sun.COM * Returns Win32 error codes. 17978474SJose.Borrego@Sun.COM */ 17988474SJose.Borrego@Sun.COM /*ARGSUSED*/ 17998474SJose.Borrego@Sun.COM static int 18008474SJose.Borrego@Sun.COM srvsvc_s_NetNameValidate(void *arg, ndr_xa_t *mxa) 18018474SJose.Borrego@Sun.COM { 18028474SJose.Borrego@Sun.COM struct mslm_NetNameValidate *param = arg; 18038474SJose.Borrego@Sun.COM char *name; 18048474SJose.Borrego@Sun.COM int len; 18058474SJose.Borrego@Sun.COM 18068474SJose.Borrego@Sun.COM if ((name = (char *)param->pathname) == NULL) { 18078474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_PARAMETER; 18088474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 18098474SJose.Borrego@Sun.COM } 18108474SJose.Borrego@Sun.COM 18118474SJose.Borrego@Sun.COM len = strlen(name); 18128474SJose.Borrego@Sun.COM 18138474SJose.Borrego@Sun.COM if ((param->flags == 0 && len > 81) || 18148474SJose.Borrego@Sun.COM (param->flags == 0x80000000 && len > 13)) { 18158474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_NAME; 18168474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 18178474SJose.Borrego@Sun.COM } 18188474SJose.Borrego@Sun.COM 18198474SJose.Borrego@Sun.COM switch (param->type) { 18208474SJose.Borrego@Sun.COM case NAMETYPE_SHARE: 18218474SJose.Borrego@Sun.COM if (smb_shr_chkname(name)) 18228474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 18238474SJose.Borrego@Sun.COM else 18248474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_NAME; 18258474SJose.Borrego@Sun.COM break; 18268474SJose.Borrego@Sun.COM 18278474SJose.Borrego@Sun.COM case NAMETYPE_USER: 18288474SJose.Borrego@Sun.COM case NAMETYPE_PASSWORD: 18298474SJose.Borrego@Sun.COM case NAMETYPE_GROUP: 18308474SJose.Borrego@Sun.COM case NAMETYPE_COMPUTER: 18318474SJose.Borrego@Sun.COM case NAMETYPE_EVENT: 18328474SJose.Borrego@Sun.COM case NAMETYPE_DOMAIN: 18338474SJose.Borrego@Sun.COM case NAMETYPE_SERVICE: 18348474SJose.Borrego@Sun.COM case NAMETYPE_NET: 18358474SJose.Borrego@Sun.COM case NAMETYPE_MESSAGE: 18368474SJose.Borrego@Sun.COM case NAMETYPE_MESSAGEDEST: 18378474SJose.Borrego@Sun.COM case NAMETYPE_SHAREPASSWORD: 18388474SJose.Borrego@Sun.COM case NAMETYPE_WORKGROUP: 18398474SJose.Borrego@Sun.COM param->status = ERROR_NOT_SUPPORTED; 18408474SJose.Borrego@Sun.COM break; 18418474SJose.Borrego@Sun.COM 18428474SJose.Borrego@Sun.COM default: 18438474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_PARAMETER; 18448474SJose.Borrego@Sun.COM break; 18458474SJose.Borrego@Sun.COM } 18468474SJose.Borrego@Sun.COM 18478474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 18488474SJose.Borrego@Sun.COM } 18498474SJose.Borrego@Sun.COM 18508474SJose.Borrego@Sun.COM /* 18518474SJose.Borrego@Sun.COM * srvsvc_s_NetShareAdd 18528474SJose.Borrego@Sun.COM * 18539832Samw@Sun.COM * Add a new share. Only power users groups can manage shares. 18548474SJose.Borrego@Sun.COM * 18558474SJose.Borrego@Sun.COM * This interface is used by the rmtshare command from the NT resource 18568474SJose.Borrego@Sun.COM * kit. Rmtshare allows a client to add or remove shares on a server 18578474SJose.Borrego@Sun.COM * from the client's command line. 18588474SJose.Borrego@Sun.COM * 18598474SJose.Borrego@Sun.COM * Returns Win32 error codes. 18608474SJose.Borrego@Sun.COM */ 18618474SJose.Borrego@Sun.COM static int 18628474SJose.Borrego@Sun.COM srvsvc_s_NetShareAdd(void *arg, ndr_xa_t *mxa) 18638474SJose.Borrego@Sun.COM { 18648474SJose.Borrego@Sun.COM static DWORD parm_err = 0; 18658474SJose.Borrego@Sun.COM DWORD parm_stat; 18668474SJose.Borrego@Sun.COM struct mslm_NetShareAdd *param = arg; 18679343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_2 *info2; 18689832Samw@Sun.COM struct mslm_NetShareInfo_502 *info502; 18698474SJose.Borrego@Sun.COM char realpath[MAXPATHLEN]; 18708474SJose.Borrego@Sun.COM int32_t native_os; 18719832Samw@Sun.COM uint8_t *sdbuf = NULL; 18729832Samw@Sun.COM uint32_t status; 18739832Samw@Sun.COM smb_share_t si; 18748474SJose.Borrego@Sun.COM 18758474SJose.Borrego@Sun.COM native_os = ndr_native_os(mxa); 18768474SJose.Borrego@Sun.COM 18778474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa)) { 18788474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 18798474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 18808474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 18818474SJose.Borrego@Sun.COM } 18828474SJose.Borrego@Sun.COM 18838474SJose.Borrego@Sun.COM switch (param->level) { 18848474SJose.Borrego@Sun.COM case 2: 18859832Samw@Sun.COM info2 = (struct mslm_NetShareInfo_2 *)param->info.un.info2; 18868474SJose.Borrego@Sun.COM break; 18878474SJose.Borrego@Sun.COM 18888474SJose.Borrego@Sun.COM case 502: 18899832Samw@Sun.COM info502 = (struct mslm_NetShareInfo_502 *) 18909832Samw@Sun.COM param->info.un.info502; 18919832Samw@Sun.COM sdbuf = info502->shi502_security_descriptor; 18929832Samw@Sun.COM info2 = (struct mslm_NetShareInfo_2 *)info502; 18938474SJose.Borrego@Sun.COM break; 18948474SJose.Borrego@Sun.COM 18958474SJose.Borrego@Sun.COM default: 18968474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 18978474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 18988474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 18998474SJose.Borrego@Sun.COM } 19008474SJose.Borrego@Sun.COM 19018474SJose.Borrego@Sun.COM if (info2->shi2_netname == NULL || info2->shi2_path == NULL) { 19028474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 19038474SJose.Borrego@Sun.COM param->status = NERR_NetNameNotFound; 19048474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19058474SJose.Borrego@Sun.COM } 19068474SJose.Borrego@Sun.COM 19078474SJose.Borrego@Sun.COM if (smb_shr_is_restricted((char *)info2->shi2_netname)) { 19088474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 19098474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 19108474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19118474SJose.Borrego@Sun.COM } 19128474SJose.Borrego@Sun.COM 19139343SAfshin.Ardakani@Sun.COM if (info2->shi2_comment == NULL) 19149343SAfshin.Ardakani@Sun.COM info2->shi2_comment = (uint8_t *)""; 19158474SJose.Borrego@Sun.COM 19168474SJose.Borrego@Sun.COM /* 19178474SJose.Borrego@Sun.COM * Derive the real path which will be stored in the 19188474SJose.Borrego@Sun.COM * directory field of the smb_share_t structure 19198474SJose.Borrego@Sun.COM * from the path field in this RPC request. 19208474SJose.Borrego@Sun.COM */ 19218474SJose.Borrego@Sun.COM parm_stat = smb_shr_get_realpath((const char *)info2->shi2_path, 19228474SJose.Borrego@Sun.COM realpath, MAXPATHLEN); 19238474SJose.Borrego@Sun.COM 19248474SJose.Borrego@Sun.COM if (parm_stat != NERR_Success) { 19258474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 19268474SJose.Borrego@Sun.COM param->status = parm_stat; 19278474SJose.Borrego@Sun.COM param->parm_err 19288474SJose.Borrego@Sun.COM = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; 19298474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19308474SJose.Borrego@Sun.COM } 19318474SJose.Borrego@Sun.COM 19328474SJose.Borrego@Sun.COM param->status = srvsvc_sa_add((char *)info2->shi2_netname, realpath, 19339343SAfshin.Ardakani@Sun.COM (char *)info2->shi2_comment); 19348474SJose.Borrego@Sun.COM if (param->status == NERR_Success) { 19359832Samw@Sun.COM status = smb_shr_get((char *)info2->shi2_netname, &si); 19369832Samw@Sun.COM 19379832Samw@Sun.COM if ((sdbuf != NULL) && (status == NERR_Success)) 19389832Samw@Sun.COM (void) srvsvc_sd_set(&si, sdbuf); 19398474SJose.Borrego@Sun.COM } 19408474SJose.Borrego@Sun.COM param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; 19418474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19428474SJose.Borrego@Sun.COM } 19438474SJose.Borrego@Sun.COM 19448474SJose.Borrego@Sun.COM /* 1945*10122SJordan.Brown@Sun.COM * srvsvc_estimate_limit 19468474SJose.Borrego@Sun.COM * 19478474SJose.Borrego@Sun.COM * Estimate the number of objects that will fit in prefmaxlen. 1948*10122SJordan.Brown@Sun.COM * nlimit is adjusted here. 19498474SJose.Borrego@Sun.COM */ 1950*10122SJordan.Brown@Sun.COM static void 1951*10122SJordan.Brown@Sun.COM srvsvc_estimate_limit(smb_svcenum_t *se, uint32_t obj_size) 19528474SJose.Borrego@Sun.COM { 19538474SJose.Borrego@Sun.COM DWORD max_cnt; 19548474SJose.Borrego@Sun.COM 1955*10122SJordan.Brown@Sun.COM if (obj_size == 0) { 1956*10122SJordan.Brown@Sun.COM se->se_nlimit = 0; 1957*10122SJordan.Brown@Sun.COM return; 1958*10122SJordan.Brown@Sun.COM } 1959*10122SJordan.Brown@Sun.COM 1960*10122SJordan.Brown@Sun.COM if ((max_cnt = (se->se_prefmaxlen / obj_size)) == 0) { 1961*10122SJordan.Brown@Sun.COM se->se_nlimit = 0; 1962*10122SJordan.Brown@Sun.COM return; 1963*10122SJordan.Brown@Sun.COM } 1964*10122SJordan.Brown@Sun.COM 1965*10122SJordan.Brown@Sun.COM if (se->se_ntotal > max_cnt) 1966*10122SJordan.Brown@Sun.COM se->se_nlimit = max_cnt; 1967*10122SJordan.Brown@Sun.COM else 1968*10122SJordan.Brown@Sun.COM se->se_nlimit = se->se_ntotal; 19698474SJose.Borrego@Sun.COM } 19708474SJose.Borrego@Sun.COM 19718474SJose.Borrego@Sun.COM /* 19728474SJose.Borrego@Sun.COM * srvsvc_s_NetShareEnum 19738474SJose.Borrego@Sun.COM * 19748474SJose.Borrego@Sun.COM * Enumerate all shares (see also NetShareEnumSticky). 19758474SJose.Borrego@Sun.COM * 19768474SJose.Borrego@Sun.COM * Request for various levels of information about our shares. 19778474SJose.Borrego@Sun.COM * Level 0: share names. 19788474SJose.Borrego@Sun.COM * Level 1: share name, share type and comment field. 19798474SJose.Borrego@Sun.COM * Level 2: everything that we know about the shares. 19808474SJose.Borrego@Sun.COM * Level 501: level 1 + flags (flags must be zero). 19818474SJose.Borrego@Sun.COM * Level 502: level 2 + security descriptor. 19828474SJose.Borrego@Sun.COM */ 19838474SJose.Borrego@Sun.COM static int 19848474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnum(void *arg, ndr_xa_t *mxa) 19858474SJose.Borrego@Sun.COM { 19868474SJose.Borrego@Sun.COM struct mslm_NetShareEnum *param = arg; 1987*10122SJordan.Brown@Sun.COM srvsvc_infonres_t *infonres; 1988*10122SJordan.Brown@Sun.COM smb_svcenum_t se; 19898474SJose.Borrego@Sun.COM DWORD status; 19908474SJose.Borrego@Sun.COM 1991*10122SJordan.Brown@Sun.COM infonres = NDR_NEW(mxa, srvsvc_infonres_t); 19928474SJose.Borrego@Sun.COM if (infonres == NULL) { 19938474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 19948474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 19958474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19968474SJose.Borrego@Sun.COM } 19978474SJose.Borrego@Sun.COM 19988474SJose.Borrego@Sun.COM infonres->entriesread = 0; 19998474SJose.Borrego@Sun.COM infonres->entries = NULL; 20008474SJose.Borrego@Sun.COM param->result.level = param->level; 20018474SJose.Borrego@Sun.COM param->result.bufptr.p = infonres; 20028474SJose.Borrego@Sun.COM 2003*10122SJordan.Brown@Sun.COM bzero(&se, sizeof (smb_svcenum_t)); 2004*10122SJordan.Brown@Sun.COM se.se_type = SMB_SVCENUM_TYPE_SHARE; 20058474SJose.Borrego@Sun.COM se.se_level = param->level; 2006*10122SJordan.Brown@Sun.COM se.se_ntotal = smb_shr_count(); 2007*10122SJordan.Brown@Sun.COM se.se_nlimit = se.se_ntotal; 20088474SJose.Borrego@Sun.COM 20098474SJose.Borrego@Sun.COM if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN || 20108474SJose.Borrego@Sun.COM param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN) 20118474SJose.Borrego@Sun.COM se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN; 20128474SJose.Borrego@Sun.COM else 20138474SJose.Borrego@Sun.COM se.se_prefmaxlen = param->prefmaxlen; 20148474SJose.Borrego@Sun.COM 20158474SJose.Borrego@Sun.COM if (param->resume_handle) { 2016*10122SJordan.Brown@Sun.COM se.se_resume = *param->resume_handle; 2017*10122SJordan.Brown@Sun.COM se.se_nskip = se.se_resume; 2018*10122SJordan.Brown@Sun.COM *param->resume_handle = 0; 20198474SJose.Borrego@Sun.COM } 20208474SJose.Borrego@Sun.COM 20218474SJose.Borrego@Sun.COM switch (param->level) { 20228474SJose.Borrego@Sun.COM case 0: 20238474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 0); 20248474SJose.Borrego@Sun.COM break; 20258474SJose.Borrego@Sun.COM 20268474SJose.Borrego@Sun.COM case 1: 20278474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 0); 20288474SJose.Borrego@Sun.COM break; 20298474SJose.Borrego@Sun.COM 20308474SJose.Borrego@Sun.COM case 2: 20318474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 0); 20328474SJose.Borrego@Sun.COM break; 20338474SJose.Borrego@Sun.COM 20348474SJose.Borrego@Sun.COM case 501: 20358474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel501(mxa, infonres, &se, 0); 20368474SJose.Borrego@Sun.COM break; 20378474SJose.Borrego@Sun.COM 20388474SJose.Borrego@Sun.COM case 502: 20398474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 0); 20408474SJose.Borrego@Sun.COM break; 20418474SJose.Borrego@Sun.COM 20428474SJose.Borrego@Sun.COM default: 20439832Samw@Sun.COM status = ERROR_INVALID_LEVEL; 20448474SJose.Borrego@Sun.COM break; 20458474SJose.Borrego@Sun.COM } 20468474SJose.Borrego@Sun.COM 20478474SJose.Borrego@Sun.COM if (status != 0) { 20488474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 20498474SJose.Borrego@Sun.COM param->status = status; 20508474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20518474SJose.Borrego@Sun.COM } 20528474SJose.Borrego@Sun.COM 2053*10122SJordan.Brown@Sun.COM if (se.se_nlimit == 0) { 20548474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 20558474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20568474SJose.Borrego@Sun.COM } 20578474SJose.Borrego@Sun.COM 20588474SJose.Borrego@Sun.COM if (param->resume_handle && 20598474SJose.Borrego@Sun.COM param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) { 2060*10122SJordan.Brown@Sun.COM if (se.se_resume < se.se_ntotal) { 2061*10122SJordan.Brown@Sun.COM *param->resume_handle = se.se_resume; 20628474SJose.Borrego@Sun.COM status = ERROR_MORE_DATA; 20638474SJose.Borrego@Sun.COM } 20648474SJose.Borrego@Sun.COM } 20658474SJose.Borrego@Sun.COM 2066*10122SJordan.Brown@Sun.COM param->totalentries = se.se_ntotal; 20678474SJose.Borrego@Sun.COM param->status = status; 20688474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20698474SJose.Borrego@Sun.COM } 20708474SJose.Borrego@Sun.COM 20718474SJose.Borrego@Sun.COM /* 20728474SJose.Borrego@Sun.COM * srvsvc_s_NetShareEnumSticky 20738474SJose.Borrego@Sun.COM * 20748474SJose.Borrego@Sun.COM * Enumerate sticky shares: all shares except those marked STYPE_SPECIAL. 20758474SJose.Borrego@Sun.COM * Except for excluding STYPE_SPECIAL shares, NetShareEnumSticky is the 20768474SJose.Borrego@Sun.COM * same as NetShareEnum. 20778474SJose.Borrego@Sun.COM * 20788474SJose.Borrego@Sun.COM * Request for various levels of information about our shares. 20798474SJose.Borrego@Sun.COM * Level 0: share names. 20808474SJose.Borrego@Sun.COM * Level 1: share name, share type and comment field. 20818474SJose.Borrego@Sun.COM * Level 2: everything that we know about the shares. 20828474SJose.Borrego@Sun.COM * Level 501: not valid for this request. 20838474SJose.Borrego@Sun.COM * Level 502: level 2 + security descriptor. 20848474SJose.Borrego@Sun.COM * 20858474SJose.Borrego@Sun.COM * We set n_skip to resume_handle, which is used to find the appropriate 20868474SJose.Borrego@Sun.COM * place to resume. The resume_handle is similar to the readdir cookie. 20878474SJose.Borrego@Sun.COM */ 20888474SJose.Borrego@Sun.COM static int 20898474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnumSticky(void *arg, ndr_xa_t *mxa) 20908474SJose.Borrego@Sun.COM { 20918474SJose.Borrego@Sun.COM struct mslm_NetShareEnum *param = arg; 2092*10122SJordan.Brown@Sun.COM srvsvc_infonres_t *infonres; 2093*10122SJordan.Brown@Sun.COM smb_svcenum_t se; 20948474SJose.Borrego@Sun.COM DWORD status; 20958474SJose.Borrego@Sun.COM 2096*10122SJordan.Brown@Sun.COM infonres = NDR_NEW(mxa, srvsvc_infonres_t); 20978474SJose.Borrego@Sun.COM if (infonres == NULL) { 20988474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 20998474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 21008474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 21018474SJose.Borrego@Sun.COM } 21028474SJose.Borrego@Sun.COM 21038474SJose.Borrego@Sun.COM infonres->entriesread = 0; 21048474SJose.Borrego@Sun.COM infonres->entries = NULL; 21058474SJose.Borrego@Sun.COM param->result.level = param->level; 21068474SJose.Borrego@Sun.COM param->result.bufptr.p = infonres; 21078474SJose.Borrego@Sun.COM 2108*10122SJordan.Brown@Sun.COM bzero(&se, sizeof (smb_svcenum_t)); 2109*10122SJordan.Brown@Sun.COM se.se_type = SMB_SVCENUM_TYPE_SHARE; 21108474SJose.Borrego@Sun.COM se.se_level = param->level; 2111*10122SJordan.Brown@Sun.COM se.se_ntotal = smb_shr_count(); 2112*10122SJordan.Brown@Sun.COM se.se_nlimit = se.se_ntotal; 21138474SJose.Borrego@Sun.COM 21148474SJose.Borrego@Sun.COM if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN || 21158474SJose.Borrego@Sun.COM param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN) 21168474SJose.Borrego@Sun.COM se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN; 21178474SJose.Borrego@Sun.COM else 21188474SJose.Borrego@Sun.COM se.se_prefmaxlen = param->prefmaxlen; 21198474SJose.Borrego@Sun.COM 21208474SJose.Borrego@Sun.COM if (param->resume_handle) { 2121*10122SJordan.Brown@Sun.COM se.se_resume = *param->resume_handle; 2122*10122SJordan.Brown@Sun.COM se.se_nskip = se.se_resume; 2123*10122SJordan.Brown@Sun.COM *param->resume_handle = 0; 21248474SJose.Borrego@Sun.COM } 21258474SJose.Borrego@Sun.COM 21268474SJose.Borrego@Sun.COM switch (param->level) { 21278474SJose.Borrego@Sun.COM case 0: 21288474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 1); 21298474SJose.Borrego@Sun.COM break; 21308474SJose.Borrego@Sun.COM 21318474SJose.Borrego@Sun.COM case 1: 21328474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 1); 21338474SJose.Borrego@Sun.COM break; 21348474SJose.Borrego@Sun.COM 21358474SJose.Borrego@Sun.COM case 2: 21368474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 1); 21378474SJose.Borrego@Sun.COM break; 21388474SJose.Borrego@Sun.COM 21398474SJose.Borrego@Sun.COM case 502: 21408474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 1); 21418474SJose.Borrego@Sun.COM break; 21428474SJose.Borrego@Sun.COM 21439832Samw@Sun.COM case 501: 21448474SJose.Borrego@Sun.COM default: 21458474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 21468474SJose.Borrego@Sun.COM break; 21478474SJose.Borrego@Sun.COM } 21488474SJose.Borrego@Sun.COM 21498474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) { 21508474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 21518474SJose.Borrego@Sun.COM param->status = status; 21528474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 21538474SJose.Borrego@Sun.COM } 21548474SJose.Borrego@Sun.COM 2155*10122SJordan.Brown@Sun.COM if (se.se_nlimit == 0) { 21568474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 21578474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 21588474SJose.Borrego@Sun.COM } 21598474SJose.Borrego@Sun.COM 21608474SJose.Borrego@Sun.COM if (param->resume_handle && 21618474SJose.Borrego@Sun.COM param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) { 2162*10122SJordan.Brown@Sun.COM if (se.se_resume < se.se_ntotal) { 2163*10122SJordan.Brown@Sun.COM *param->resume_handle = se.se_resume; 21648474SJose.Borrego@Sun.COM status = ERROR_MORE_DATA; 21658474SJose.Borrego@Sun.COM } 21668474SJose.Borrego@Sun.COM } 21678474SJose.Borrego@Sun.COM 2168*10122SJordan.Brown@Sun.COM param->totalentries = se.se_ntotal; 21698474SJose.Borrego@Sun.COM param->status = status; 21708474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 21718474SJose.Borrego@Sun.COM } 21728474SJose.Borrego@Sun.COM 21738474SJose.Borrego@Sun.COM /* 21748474SJose.Borrego@Sun.COM * NetShareEnum Level 0 21758474SJose.Borrego@Sun.COM */ 21768474SJose.Borrego@Sun.COM static DWORD 2177*10122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel0(ndr_xa_t *mxa, srvsvc_infonres_t *infonres, 2178*10122SJordan.Brown@Sun.COM smb_svcenum_t *se, int sticky) 21798474SJose.Borrego@Sun.COM { 21809343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_0 *info0; 21818474SJose.Borrego@Sun.COM smb_shriter_t iterator; 21828474SJose.Borrego@Sun.COM smb_share_t *si; 21838474SJose.Borrego@Sun.COM DWORD status; 21848474SJose.Borrego@Sun.COM 2185*10122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 2186*10122SJordan.Brown@Sun.COM sizeof (struct mslm_NetShareInfo_0) + MAXNAMELEN); 2187*10122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 21888474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 21898474SJose.Borrego@Sun.COM 2190*10122SJordan.Brown@Sun.COM info0 = NDR_NEWN(mxa, struct mslm_NetShareInfo_0, se->se_nlimit); 21918474SJose.Borrego@Sun.COM if (info0 == NULL) 21928474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 21938474SJose.Borrego@Sun.COM 21948474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 21958474SJose.Borrego@Sun.COM 2196*10122SJordan.Brown@Sun.COM se->se_nitems = 0; 21978474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != NULL) { 2198*10122SJordan.Brown@Sun.COM if (se->se_nskip > 0) { 2199*10122SJordan.Brown@Sun.COM --se->se_nskip; 22008474SJose.Borrego@Sun.COM continue; 22018474SJose.Borrego@Sun.COM } 22028474SJose.Borrego@Sun.COM 2203*10122SJordan.Brown@Sun.COM ++se->se_resume; 22048474SJose.Borrego@Sun.COM 22058474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 22068474SJose.Borrego@Sun.COM continue; 22078474SJose.Borrego@Sun.COM 22088474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 22098474SJose.Borrego@Sun.COM continue; 22108474SJose.Borrego@Sun.COM 2211*10122SJordan.Brown@Sun.COM if (se->se_nitems >= se->se_nlimit) { 2212*10122SJordan.Brown@Sun.COM se->se_nitems = se->se_nlimit; 22138474SJose.Borrego@Sun.COM break; 22148474SJose.Borrego@Sun.COM } 22158474SJose.Borrego@Sun.COM 22168474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info0); 22178474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 22188474SJose.Borrego@Sun.COM break; 22198474SJose.Borrego@Sun.COM 2220*10122SJordan.Brown@Sun.COM ++se->se_nitems; 22218474SJose.Borrego@Sun.COM } 22228474SJose.Borrego@Sun.COM 2223*10122SJordan.Brown@Sun.COM if (se->se_nitems < se->se_nlimit) { 22248474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info0)) 2225*10122SJordan.Brown@Sun.COM ++se->se_nitems; 22268474SJose.Borrego@Sun.COM } 22278474SJose.Borrego@Sun.COM 2228*10122SJordan.Brown@Sun.COM infonres->entriesread = se->se_nitems; 22298474SJose.Borrego@Sun.COM infonres->entries = info0; 22308474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 22318474SJose.Borrego@Sun.COM } 22328474SJose.Borrego@Sun.COM 22338474SJose.Borrego@Sun.COM /* 22348474SJose.Borrego@Sun.COM * NetShareEnum Level 1 22358474SJose.Borrego@Sun.COM */ 22368474SJose.Borrego@Sun.COM static DWORD 2237*10122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel1(ndr_xa_t *mxa, srvsvc_infonres_t *infonres, 2238*10122SJordan.Brown@Sun.COM smb_svcenum_t *se, int sticky) 22398474SJose.Borrego@Sun.COM { 22409343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1 *info1; 22418474SJose.Borrego@Sun.COM smb_shriter_t iterator; 22428474SJose.Borrego@Sun.COM smb_share_t *si; 22438474SJose.Borrego@Sun.COM DWORD status; 22448474SJose.Borrego@Sun.COM 2245*10122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 2246*10122SJordan.Brown@Sun.COM sizeof (struct mslm_NetShareInfo_1) + MAXNAMELEN); 2247*10122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 22488474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 22498474SJose.Borrego@Sun.COM 2250*10122SJordan.Brown@Sun.COM info1 = NDR_NEWN(mxa, struct mslm_NetShareInfo_1, se->se_nlimit); 22518474SJose.Borrego@Sun.COM if (info1 == NULL) 22528474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 22538474SJose.Borrego@Sun.COM 22548474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 22558474SJose.Borrego@Sun.COM 2256*10122SJordan.Brown@Sun.COM se->se_nitems = 0; 22578474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != 0) { 2258*10122SJordan.Brown@Sun.COM if (se->se_nskip > 0) { 2259*10122SJordan.Brown@Sun.COM --se->se_nskip; 22608474SJose.Borrego@Sun.COM continue; 22618474SJose.Borrego@Sun.COM } 22628474SJose.Borrego@Sun.COM 2263*10122SJordan.Brown@Sun.COM ++se->se_resume; 22648474SJose.Borrego@Sun.COM 22658474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 22668474SJose.Borrego@Sun.COM continue; 22678474SJose.Borrego@Sun.COM 22688474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 22698474SJose.Borrego@Sun.COM continue; 22708474SJose.Borrego@Sun.COM 2271*10122SJordan.Brown@Sun.COM if (se->se_nitems >= se->se_nlimit) { 2272*10122SJordan.Brown@Sun.COM se->se_nitems = se->se_nlimit; 22738474SJose.Borrego@Sun.COM break; 22748474SJose.Borrego@Sun.COM } 22758474SJose.Borrego@Sun.COM 22768474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info1); 22778474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 22788474SJose.Borrego@Sun.COM break; 22798474SJose.Borrego@Sun.COM 2280*10122SJordan.Brown@Sun.COM ++se->se_nitems; 22818474SJose.Borrego@Sun.COM } 22828474SJose.Borrego@Sun.COM 2283*10122SJordan.Brown@Sun.COM if (se->se_nitems < se->se_nlimit) { 22848474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info1)) 2285*10122SJordan.Brown@Sun.COM ++se->se_nitems; 22868474SJose.Borrego@Sun.COM } 22878474SJose.Borrego@Sun.COM 2288*10122SJordan.Brown@Sun.COM infonres->entriesread = se->se_nitems; 22898474SJose.Borrego@Sun.COM infonres->entries = info1; 22908474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 22918474SJose.Borrego@Sun.COM } 22928474SJose.Borrego@Sun.COM 22938474SJose.Borrego@Sun.COM /* 22948474SJose.Borrego@Sun.COM * NetShareEnum Level 2 22958474SJose.Borrego@Sun.COM */ 22968474SJose.Borrego@Sun.COM static DWORD 2297*10122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel2(ndr_xa_t *mxa, srvsvc_infonres_t *infonres, 2298*10122SJordan.Brown@Sun.COM smb_svcenum_t *se, int sticky) 22998474SJose.Borrego@Sun.COM { 23009343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_2 *info2; 23018474SJose.Borrego@Sun.COM smb_shriter_t iterator; 23028474SJose.Borrego@Sun.COM smb_share_t *si; 23038474SJose.Borrego@Sun.COM DWORD status; 23048474SJose.Borrego@Sun.COM 2305*10122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 2306*10122SJordan.Brown@Sun.COM sizeof (struct mslm_NetShareInfo_2) + MAXNAMELEN); 2307*10122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 23088474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 23098474SJose.Borrego@Sun.COM 2310*10122SJordan.Brown@Sun.COM info2 = NDR_NEWN(mxa, struct mslm_NetShareInfo_2, se->se_nlimit); 23118474SJose.Borrego@Sun.COM if (info2 == NULL) 23128474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 23138474SJose.Borrego@Sun.COM 23148474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 23158474SJose.Borrego@Sun.COM 2316*10122SJordan.Brown@Sun.COM se->se_nitems = 0; 23178474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != 0) { 2318*10122SJordan.Brown@Sun.COM if (se->se_nskip > 0) { 2319*10122SJordan.Brown@Sun.COM --se->se_nskip; 23208474SJose.Borrego@Sun.COM continue; 23218474SJose.Borrego@Sun.COM } 23228474SJose.Borrego@Sun.COM 2323*10122SJordan.Brown@Sun.COM ++se->se_resume; 23248474SJose.Borrego@Sun.COM 23258474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 23268474SJose.Borrego@Sun.COM continue; 23278474SJose.Borrego@Sun.COM 23288474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 23298474SJose.Borrego@Sun.COM continue; 23308474SJose.Borrego@Sun.COM 2331*10122SJordan.Brown@Sun.COM if (se->se_nitems >= se->se_nlimit) { 2332*10122SJordan.Brown@Sun.COM se->se_nitems = se->se_nlimit; 23338474SJose.Borrego@Sun.COM break; 23348474SJose.Borrego@Sun.COM } 23358474SJose.Borrego@Sun.COM 23368474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info2); 23378474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 23388474SJose.Borrego@Sun.COM break; 23398474SJose.Borrego@Sun.COM 2340*10122SJordan.Brown@Sun.COM ++se->se_nitems; 23418474SJose.Borrego@Sun.COM } 23428474SJose.Borrego@Sun.COM 2343*10122SJordan.Brown@Sun.COM if (se->se_nitems < se->se_nlimit) { 23448474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info2)) 2345*10122SJordan.Brown@Sun.COM ++se->se_nitems; 23468474SJose.Borrego@Sun.COM } 23478474SJose.Borrego@Sun.COM 2348*10122SJordan.Brown@Sun.COM infonres->entriesread = se->se_nitems; 23498474SJose.Borrego@Sun.COM infonres->entries = info2; 23508474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 23518474SJose.Borrego@Sun.COM } 23528474SJose.Borrego@Sun.COM 23538474SJose.Borrego@Sun.COM /* 23548474SJose.Borrego@Sun.COM * NetShareEnum Level 501 23558474SJose.Borrego@Sun.COM */ 23568474SJose.Borrego@Sun.COM static DWORD 2357*10122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel501(ndr_xa_t *mxa, srvsvc_infonres_t *infonres, 2358*10122SJordan.Brown@Sun.COM smb_svcenum_t *se, int sticky) 23598474SJose.Borrego@Sun.COM { 23609343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_501 *info501; 23618474SJose.Borrego@Sun.COM smb_shriter_t iterator; 23628474SJose.Borrego@Sun.COM smb_share_t *si; 23638474SJose.Borrego@Sun.COM DWORD status; 23648474SJose.Borrego@Sun.COM 2365*10122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 2366*10122SJordan.Brown@Sun.COM sizeof (struct mslm_NetShareInfo_501) + MAXNAMELEN); 2367*10122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 23688474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 23698474SJose.Borrego@Sun.COM 23709343SAfshin.Ardakani@Sun.COM info501 = NDR_NEWN(mxa, struct mslm_NetShareInfo_501, 2371*10122SJordan.Brown@Sun.COM se->se_nlimit); 23728474SJose.Borrego@Sun.COM if (info501 == NULL) 23738474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 23748474SJose.Borrego@Sun.COM 23758474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 23768474SJose.Borrego@Sun.COM 2377*10122SJordan.Brown@Sun.COM se->se_nitems = 0; 23788474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != 0) { 2379*10122SJordan.Brown@Sun.COM if (se->se_nskip > 0) { 2380*10122SJordan.Brown@Sun.COM --se->se_nskip; 23818474SJose.Borrego@Sun.COM continue; 23828474SJose.Borrego@Sun.COM } 23838474SJose.Borrego@Sun.COM 2384*10122SJordan.Brown@Sun.COM ++se->se_resume; 23858474SJose.Borrego@Sun.COM 23868474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 23878474SJose.Borrego@Sun.COM continue; 23888474SJose.Borrego@Sun.COM 23898474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 23908474SJose.Borrego@Sun.COM continue; 23918474SJose.Borrego@Sun.COM 2392*10122SJordan.Brown@Sun.COM if (se->se_nitems >= se->se_nlimit) { 2393*10122SJordan.Brown@Sun.COM se->se_nitems = se->se_nlimit; 23948474SJose.Borrego@Sun.COM break; 23958474SJose.Borrego@Sun.COM } 23968474SJose.Borrego@Sun.COM 23978474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info501); 23988474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 23998474SJose.Borrego@Sun.COM break; 24008474SJose.Borrego@Sun.COM 2401*10122SJordan.Brown@Sun.COM ++se->se_nitems; 24028474SJose.Borrego@Sun.COM } 24038474SJose.Borrego@Sun.COM 2404*10122SJordan.Brown@Sun.COM if (se->se_nitems < se->se_nlimit) { 24058474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info501)) 2406*10122SJordan.Brown@Sun.COM ++se->se_nitems; 24078474SJose.Borrego@Sun.COM } 24088474SJose.Borrego@Sun.COM 2409*10122SJordan.Brown@Sun.COM infonres->entriesread = se->se_nitems; 24108474SJose.Borrego@Sun.COM infonres->entries = info501; 24118474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 24128474SJose.Borrego@Sun.COM } 24138474SJose.Borrego@Sun.COM 24148474SJose.Borrego@Sun.COM /* 24158474SJose.Borrego@Sun.COM * NetShareEnum Level 502 24168474SJose.Borrego@Sun.COM */ 24178474SJose.Borrego@Sun.COM static DWORD 2418*10122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel502(ndr_xa_t *mxa, srvsvc_infonres_t *infonres, 2419*10122SJordan.Brown@Sun.COM smb_svcenum_t *se, int sticky) 24208474SJose.Borrego@Sun.COM { 24219343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_502 *info502; 24228474SJose.Borrego@Sun.COM smb_shriter_t iterator; 24238474SJose.Borrego@Sun.COM smb_share_t *si; 24248474SJose.Borrego@Sun.COM DWORD status; 24258474SJose.Borrego@Sun.COM 2426*10122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 2427*10122SJordan.Brown@Sun.COM sizeof (struct mslm_NetShareInfo_502) + MAXNAMELEN); 2428*10122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 24298474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 24308474SJose.Borrego@Sun.COM 24319343SAfshin.Ardakani@Sun.COM info502 = NDR_NEWN(mxa, struct mslm_NetShareInfo_502, 2432*10122SJordan.Brown@Sun.COM se->se_nlimit); 24338474SJose.Borrego@Sun.COM if (info502 == NULL) 24348474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 24358474SJose.Borrego@Sun.COM 24368474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 24378474SJose.Borrego@Sun.COM 2438*10122SJordan.Brown@Sun.COM se->se_nitems = 0; 24398474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != NULL) { 2440*10122SJordan.Brown@Sun.COM if (se->se_nskip > 0) { 2441*10122SJordan.Brown@Sun.COM --se->se_nskip; 24428474SJose.Borrego@Sun.COM continue; 24438474SJose.Borrego@Sun.COM } 24448474SJose.Borrego@Sun.COM 2445*10122SJordan.Brown@Sun.COM ++se->se_resume; 24468474SJose.Borrego@Sun.COM 24478474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 24488474SJose.Borrego@Sun.COM continue; 24498474SJose.Borrego@Sun.COM 24508474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 24518474SJose.Borrego@Sun.COM continue; 24528474SJose.Borrego@Sun.COM 2453*10122SJordan.Brown@Sun.COM if (se->se_nitems >= se->se_nlimit) { 2454*10122SJordan.Brown@Sun.COM se->se_nitems = se->se_nlimit; 24558474SJose.Borrego@Sun.COM break; 24568474SJose.Borrego@Sun.COM } 24578474SJose.Borrego@Sun.COM 24588474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info502); 24598474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 24608474SJose.Borrego@Sun.COM break; 24618474SJose.Borrego@Sun.COM 2462*10122SJordan.Brown@Sun.COM ++se->se_nitems; 24638474SJose.Borrego@Sun.COM } 24648474SJose.Borrego@Sun.COM 2465*10122SJordan.Brown@Sun.COM if (se->se_nitems < se->se_nlimit) { 24668474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info502)) 2467*10122SJordan.Brown@Sun.COM ++se->se_nitems; 24688474SJose.Borrego@Sun.COM } 24698474SJose.Borrego@Sun.COM 2470*10122SJordan.Brown@Sun.COM infonres->entriesread = se->se_nitems; 24718474SJose.Borrego@Sun.COM infonres->entries = info502; 24728474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 24738474SJose.Borrego@Sun.COM } 24748474SJose.Borrego@Sun.COM 24758474SJose.Borrego@Sun.COM /* 24768474SJose.Borrego@Sun.COM * mlsvc_NetShareEnumCommon 24778474SJose.Borrego@Sun.COM * 24788474SJose.Borrego@Sun.COM * Build the levels 0, 1, 2, 501 and 502 share information. This function 24798474SJose.Borrego@Sun.COM * is called by the various NetShareEnum levels for each share. If 24808474SJose.Borrego@Sun.COM * we cannot build the share data for some reason, we return an error 24818474SJose.Borrego@Sun.COM * but the actual value of the error is not important to the caller. 24828474SJose.Borrego@Sun.COM * The caller just needs to know not to include this info in the RPC 24838474SJose.Borrego@Sun.COM * response. 24848474SJose.Borrego@Sun.COM * 24858474SJose.Borrego@Sun.COM * Returns: 24868474SJose.Borrego@Sun.COM * ERROR_SUCCESS 24878474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY 24888474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL 24898474SJose.Borrego@Sun.COM */ 24908474SJose.Borrego@Sun.COM static DWORD 2491*10122SJordan.Brown@Sun.COM mlsvc_NetShareEnumCommon(ndr_xa_t *mxa, smb_svcenum_t *se, 24928474SJose.Borrego@Sun.COM smb_share_t *si, void *infop) 24938474SJose.Borrego@Sun.COM { 24949343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_0 *info0; 24959343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1 *info1; 24969343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_2 *info2; 24979343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_501 *info501; 24989343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_502 *info502; 24999832Samw@Sun.COM srvsvc_sd_t sd; 25009832Samw@Sun.COM uint8_t *netname; 25019832Samw@Sun.COM uint8_t *comment; 25029832Samw@Sun.COM uint8_t *passwd; 25039832Samw@Sun.COM uint8_t *path; 2504*10122SJordan.Brown@Sun.COM int i = se->se_nitems; 25058474SJose.Borrego@Sun.COM 25069832Samw@Sun.COM netname = (uint8_t *)NDR_STRDUP(mxa, si->shr_name); 25079832Samw@Sun.COM comment = (uint8_t *)NDR_STRDUP(mxa, si->shr_cmnt); 25089832Samw@Sun.COM passwd = (uint8_t *)NDR_STRDUP(mxa, empty_string); 25099832Samw@Sun.COM path = (uint8_t *)srvsvc_share_mkpath(mxa, si->shr_path); 25109832Samw@Sun.COM 25119832Samw@Sun.COM if (!netname || !comment || !passwd || !path) 25129832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 25139832Samw@Sun.COM 25148474SJose.Borrego@Sun.COM switch (se->se_level) { 25158474SJose.Borrego@Sun.COM case 0: 25169343SAfshin.Ardakani@Sun.COM info0 = (struct mslm_NetShareInfo_0 *)infop; 25179832Samw@Sun.COM info0[i].shi0_netname = netname; 25188474SJose.Borrego@Sun.COM break; 25198474SJose.Borrego@Sun.COM 25208474SJose.Borrego@Sun.COM case 1: 25219343SAfshin.Ardakani@Sun.COM info1 = (struct mslm_NetShareInfo_1 *)infop; 25229832Samw@Sun.COM info1[i].shi1_netname = netname; 25239832Samw@Sun.COM info1[i].shi1_comment = comment; 25248474SJose.Borrego@Sun.COM info1[i].shi1_type = si->shr_type; 25258474SJose.Borrego@Sun.COM break; 25268474SJose.Borrego@Sun.COM 25278474SJose.Borrego@Sun.COM case 2: 25289343SAfshin.Ardakani@Sun.COM info2 = (struct mslm_NetShareInfo_2 *)infop; 25299832Samw@Sun.COM info2[i].shi2_netname = netname; 25309832Samw@Sun.COM info2[i].shi2_comment = comment; 25319832Samw@Sun.COM info2[i].shi2_path = path; 25328474SJose.Borrego@Sun.COM info2[i].shi2_type = si->shr_type; 25338474SJose.Borrego@Sun.COM info2[i].shi2_permissions = 0; 25348474SJose.Borrego@Sun.COM info2[i].shi2_max_uses = SHI_USES_UNLIMITED; 25358474SJose.Borrego@Sun.COM info2[i].shi2_current_uses = 0; 25369832Samw@Sun.COM info2[i].shi2_passwd = passwd; 25378474SJose.Borrego@Sun.COM break; 25388474SJose.Borrego@Sun.COM 25398474SJose.Borrego@Sun.COM case 501: 25409343SAfshin.Ardakani@Sun.COM info501 = (struct mslm_NetShareInfo_501 *)infop; 25419832Samw@Sun.COM info501[i].shi501_netname = netname; 25429832Samw@Sun.COM info501[i].shi501_comment = comment; 25438474SJose.Borrego@Sun.COM info501[i].shi501_type = si->shr_type; 25449343SAfshin.Ardakani@Sun.COM info501[i].shi501_reserved = 0; 25458474SJose.Borrego@Sun.COM break; 25468474SJose.Borrego@Sun.COM 25478474SJose.Borrego@Sun.COM case 502: 25489343SAfshin.Ardakani@Sun.COM info502 = (struct mslm_NetShareInfo_502 *)infop; 25499832Samw@Sun.COM info502[i].shi502_netname = netname; 25509832Samw@Sun.COM info502[i].shi502_comment = comment; 25519832Samw@Sun.COM info502[i].shi502_path = path; 25528474SJose.Borrego@Sun.COM info502[i].shi502_type = si->shr_type; 25538474SJose.Borrego@Sun.COM info502[i].shi502_permissions = 0; 25548474SJose.Borrego@Sun.COM info502[i].shi502_max_uses = SHI_USES_UNLIMITED; 25558474SJose.Borrego@Sun.COM info502[i].shi502_current_uses = 0; 25569832Samw@Sun.COM info502[i].shi502_passwd = passwd; 25579832Samw@Sun.COM 25589832Samw@Sun.COM if (srvsvc_share_getsd(mxa, si, &sd) == ERROR_SUCCESS) { 25599832Samw@Sun.COM info502[i].shi502_reserved = sd.sd_size; 25609832Samw@Sun.COM info502[i].shi502_security_descriptor = sd.sd_buf; 25619832Samw@Sun.COM } else { 25629832Samw@Sun.COM info502[i].shi502_reserved = 0; 25639832Samw@Sun.COM info502[i].shi502_security_descriptor = NULL; 25649832Samw@Sun.COM } 25659832Samw@Sun.COM 25668474SJose.Borrego@Sun.COM break; 25678474SJose.Borrego@Sun.COM 25688474SJose.Borrego@Sun.COM default: 25698474SJose.Borrego@Sun.COM return (ERROR_INVALID_LEVEL); 25708474SJose.Borrego@Sun.COM } 25718474SJose.Borrego@Sun.COM 25728474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 25738474SJose.Borrego@Sun.COM } 25748474SJose.Borrego@Sun.COM 25758474SJose.Borrego@Sun.COM /* 25768474SJose.Borrego@Sun.COM * srvsvc_add_autohome 25778474SJose.Borrego@Sun.COM * 25788474SJose.Borrego@Sun.COM * Add the autohome share for the user. The share must not be a permanent 25798474SJose.Borrego@Sun.COM * share to avoid duplicates. 25808474SJose.Borrego@Sun.COM */ 25818474SJose.Borrego@Sun.COM static boolean_t 2582*10122SJordan.Brown@Sun.COM srvsvc_add_autohome(ndr_xa_t *mxa, smb_svcenum_t *se, void *infop) 25838474SJose.Borrego@Sun.COM { 2584*10122SJordan.Brown@Sun.COM smb_netuserinfo_t *user = &mxa->pipe->np_user; 2585*10122SJordan.Brown@Sun.COM char *username = user->ui_account; 25868474SJose.Borrego@Sun.COM smb_share_t si; 25878474SJose.Borrego@Sun.COM DWORD status; 25888474SJose.Borrego@Sun.COM 25898474SJose.Borrego@Sun.COM if (smb_shr_get(username, &si) != NERR_Success) 25908474SJose.Borrego@Sun.COM return (B_FALSE); 25918474SJose.Borrego@Sun.COM 25928474SJose.Borrego@Sun.COM if ((si.shr_flags & SMB_SHRF_AUTOHOME) == 0) 25938474SJose.Borrego@Sun.COM return (B_FALSE); 25948474SJose.Borrego@Sun.COM 25958474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, &si, infop); 25968474SJose.Borrego@Sun.COM return (status == ERROR_SUCCESS); 25978474SJose.Borrego@Sun.COM } 25988474SJose.Borrego@Sun.COM 25998474SJose.Borrego@Sun.COM /* 26008474SJose.Borrego@Sun.COM * srvsvc_share_mkpath 26018474SJose.Borrego@Sun.COM * 26028474SJose.Borrego@Sun.COM * Create the share path required by the share enum calls. The path 26038474SJose.Borrego@Sun.COM * is created in a heap buffer ready for use by the caller. 26048474SJose.Borrego@Sun.COM * 26058474SJose.Borrego@Sun.COM * Some Windows over-the-wire backup applications do not work unless a 26068474SJose.Borrego@Sun.COM * drive letter is present in the share path. We don't care about the 26078474SJose.Borrego@Sun.COM * drive letter since the path is fully qualified with the volume name. 26088474SJose.Borrego@Sun.COM * 26098474SJose.Borrego@Sun.COM * Windows clients seem to be mostly okay with forward slashes in 26108474SJose.Borrego@Sun.COM * share paths but they cannot handle one immediately after the drive 26118474SJose.Borrego@Sun.COM * letter, i.e. B:/. For consistency we convert all the slashes in 26128474SJose.Borrego@Sun.COM * the path. 26138474SJose.Borrego@Sun.COM * 26148474SJose.Borrego@Sun.COM * Returns a pointer to a heap buffer containing the share path, which 26158474SJose.Borrego@Sun.COM * could be a null pointer if the heap allocation fails. 26168474SJose.Borrego@Sun.COM */ 26178474SJose.Borrego@Sun.COM static char * 26188474SJose.Borrego@Sun.COM srvsvc_share_mkpath(ndr_xa_t *mxa, char *path) 26198474SJose.Borrego@Sun.COM { 26208474SJose.Borrego@Sun.COM char tmpbuf[MAXPATHLEN]; 26218474SJose.Borrego@Sun.COM char *p; 26228474SJose.Borrego@Sun.COM 26238474SJose.Borrego@Sun.COM if (strlen(path) == 0) 26248474SJose.Borrego@Sun.COM return (NDR_STRDUP(mxa, path)); 26258474SJose.Borrego@Sun.COM 26268474SJose.Borrego@Sun.COM /* 26278474SJose.Borrego@Sun.COM * Strip the volume name from the path (/vol1/home -> /home). 26288474SJose.Borrego@Sun.COM */ 26298474SJose.Borrego@Sun.COM p = path; 26308474SJose.Borrego@Sun.COM p += strspn(p, "/"); 26318474SJose.Borrego@Sun.COM p += strcspn(p, "/"); 26328474SJose.Borrego@Sun.COM p += strspn(p, "/"); 26338474SJose.Borrego@Sun.COM (void) snprintf(tmpbuf, MAXPATHLEN, "%c:/%s", 'B', p); 26348474SJose.Borrego@Sun.COM (void) strsubst(tmpbuf, '/', '\\'); 26358474SJose.Borrego@Sun.COM 26368474SJose.Borrego@Sun.COM return (NDR_STRDUP(mxa, tmpbuf)); 26378474SJose.Borrego@Sun.COM } 26388474SJose.Borrego@Sun.COM 26399832Samw@Sun.COM static int 26409832Samw@Sun.COM srvsvc_s_NetShareCheck(void *arg, ndr_xa_t *mxa) 26419832Samw@Sun.COM { 26429832Samw@Sun.COM struct mslm_NetShareCheck *param = arg; 26439832Samw@Sun.COM smb_shriter_t iterator; 26449832Samw@Sun.COM smb_share_t *si; 26459832Samw@Sun.COM char *path; 26469832Samw@Sun.COM 26479832Samw@Sun.COM if (param->path == NULL) { 26489832Samw@Sun.COM param->stype = STYPE_DISKTREE; 26499832Samw@Sun.COM param->status = NERR_NetNameNotFound; 26509832Samw@Sun.COM return (NDR_DRC_OK); 26519832Samw@Sun.COM } 26529832Samw@Sun.COM 26539832Samw@Sun.COM (void) strsubst((char *)param->path, '/', '\\'); 26549832Samw@Sun.COM 26559832Samw@Sun.COM smb_shr_iterinit(&iterator); 26569832Samw@Sun.COM 26579832Samw@Sun.COM while ((si = smb_shr_iterate(&iterator)) != NULL) { 26589832Samw@Sun.COM path = srvsvc_share_mkpath(mxa, si->shr_path); 26599832Samw@Sun.COM 26609832Samw@Sun.COM if (utf8_strcasecmp(path, (char *)param->path) == 0) { 26619832Samw@Sun.COM param->stype = (si->shr_type & STYPE_MASK); 26629832Samw@Sun.COM param->status = NERR_Success; 26639832Samw@Sun.COM return (NDR_DRC_OK); 26649832Samw@Sun.COM } 26659832Samw@Sun.COM } 26669832Samw@Sun.COM 26679832Samw@Sun.COM param->stype = STYPE_DISKTREE; 26689832Samw@Sun.COM param->status = NERR_NetNameNotFound; 26699832Samw@Sun.COM return (NDR_DRC_OK); 26709832Samw@Sun.COM } 26719832Samw@Sun.COM 26728474SJose.Borrego@Sun.COM /* 26738474SJose.Borrego@Sun.COM * srvsvc_s_NetShareDel 26748474SJose.Borrego@Sun.COM * 2675*10122SJordan.Brown@Sun.COM * Delete a share. Only members of the Administrators, Server Operators 2676*10122SJordan.Brown@Sun.COM * or Power Users local groups are allowed to delete shares. 26778474SJose.Borrego@Sun.COM * 26788474SJose.Borrego@Sun.COM * This interface is used by the rmtshare command from the NT resource 26798474SJose.Borrego@Sun.COM * kit. Rmtshare allows a client to add or remove shares on a server 26808474SJose.Borrego@Sun.COM * from the client's command line. 26818474SJose.Borrego@Sun.COM * 26828474SJose.Borrego@Sun.COM * Returns Win32 error codes. 26838474SJose.Borrego@Sun.COM */ 26848474SJose.Borrego@Sun.COM static int 26858474SJose.Borrego@Sun.COM srvsvc_s_NetShareDel(void *arg, ndr_xa_t *mxa) 26868474SJose.Borrego@Sun.COM { 26878474SJose.Borrego@Sun.COM struct mslm_NetShareDel *param = arg; 26888474SJose.Borrego@Sun.COM 26898474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa) || 26908474SJose.Borrego@Sun.COM smb_shr_is_restricted((char *)param->netname)) { 26918474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 26928474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 26938474SJose.Borrego@Sun.COM } 26948474SJose.Borrego@Sun.COM 26958474SJose.Borrego@Sun.COM param->status = srvsvc_sa_delete((char *)param->netname); 26968474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 26978474SJose.Borrego@Sun.COM } 26988474SJose.Borrego@Sun.COM 26998474SJose.Borrego@Sun.COM /* 27008474SJose.Borrego@Sun.COM * srvsvc_s_NetGetFileSecurity 27018474SJose.Borrego@Sun.COM * 27028474SJose.Borrego@Sun.COM * Get security descriptor of the requested file/folder 27038474SJose.Borrego@Sun.COM * 27048474SJose.Borrego@Sun.COM * Right now, just returns ERROR_ACCESS_DENIED, because we cannot 27058474SJose.Borrego@Sun.COM * get the requested SD here in RPC code. 27068474SJose.Borrego@Sun.COM */ 27078474SJose.Borrego@Sun.COM /*ARGSUSED*/ 27088474SJose.Borrego@Sun.COM static int 27098474SJose.Borrego@Sun.COM srvsvc_s_NetGetFileSecurity(void *arg, ndr_xa_t *mxa) 27108474SJose.Borrego@Sun.COM { 27118474SJose.Borrego@Sun.COM struct mslm_NetGetFileSecurity *param = arg; 27128474SJose.Borrego@Sun.COM 27138474SJose.Borrego@Sun.COM param->length = 0; 27148474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 27158474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 27168474SJose.Borrego@Sun.COM } 27178474SJose.Borrego@Sun.COM 27188474SJose.Borrego@Sun.COM /* 27198474SJose.Borrego@Sun.COM * srvsvc_s_NetSetFileSecurity 27208474SJose.Borrego@Sun.COM * 27218474SJose.Borrego@Sun.COM * Set the given security descriptor for the requested file/folder 27228474SJose.Borrego@Sun.COM * 27238474SJose.Borrego@Sun.COM * Right now, just returns ERROR_ACCESS_DENIED, because we cannot 27248474SJose.Borrego@Sun.COM * set the requested SD here in RPC code. 27258474SJose.Borrego@Sun.COM */ 27268474SJose.Borrego@Sun.COM /*ARGSUSED*/ 27278474SJose.Borrego@Sun.COM static int 27288474SJose.Borrego@Sun.COM srvsvc_s_NetSetFileSecurity(void *arg, ndr_xa_t *mxa) 27298474SJose.Borrego@Sun.COM { 27308474SJose.Borrego@Sun.COM struct mslm_NetSetFileSecurity *param = arg; 27318474SJose.Borrego@Sun.COM 27328474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 27338474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 27348474SJose.Borrego@Sun.COM } 27358474SJose.Borrego@Sun.COM 27368474SJose.Borrego@Sun.COM /* 27378474SJose.Borrego@Sun.COM * If the default "smb" share group exists then return the group 27388474SJose.Borrego@Sun.COM * handle, otherwise create the group and return the handle. 27398474SJose.Borrego@Sun.COM * 27408474SJose.Borrego@Sun.COM * All shares created via the srvsvc will be added to the "smb" 27418474SJose.Borrego@Sun.COM * group. 27428474SJose.Borrego@Sun.COM */ 27438474SJose.Borrego@Sun.COM static sa_group_t 27448474SJose.Borrego@Sun.COM srvsvc_sa_get_smbgrp(sa_handle_t handle) 27458474SJose.Borrego@Sun.COM { 27468474SJose.Borrego@Sun.COM sa_group_t group = NULL; 27478474SJose.Borrego@Sun.COM int err; 27488474SJose.Borrego@Sun.COM 27498474SJose.Borrego@Sun.COM group = sa_get_group(handle, SMB_DEFAULT_SHARE_GROUP); 27508474SJose.Borrego@Sun.COM if (group != NULL) 27518474SJose.Borrego@Sun.COM return (group); 27528474SJose.Borrego@Sun.COM 27538474SJose.Borrego@Sun.COM group = sa_create_group(handle, SMB_DEFAULT_SHARE_GROUP, &err); 27548474SJose.Borrego@Sun.COM if (group == NULL) 27558474SJose.Borrego@Sun.COM return (NULL); 27568474SJose.Borrego@Sun.COM 27578474SJose.Borrego@Sun.COM if (sa_create_optionset(group, SMB_DEFAULT_SHARE_GROUP) == NULL) { 27588474SJose.Borrego@Sun.COM (void) sa_remove_group(group); 27598474SJose.Borrego@Sun.COM group = NULL; 27608474SJose.Borrego@Sun.COM } 27618474SJose.Borrego@Sun.COM 27628474SJose.Borrego@Sun.COM return (group); 27638474SJose.Borrego@Sun.COM } 27648474SJose.Borrego@Sun.COM 27658474SJose.Borrego@Sun.COM /* 27668474SJose.Borrego@Sun.COM * Stores the given share in sharemgr 27678474SJose.Borrego@Sun.COM */ 27688474SJose.Borrego@Sun.COM static uint32_t 27698474SJose.Borrego@Sun.COM srvsvc_sa_add(char *sharename, char *path, char *cmnt) 27708474SJose.Borrego@Sun.COM { 27718474SJose.Borrego@Sun.COM sa_handle_t handle; 27728474SJose.Borrego@Sun.COM sa_share_t share; 27738474SJose.Borrego@Sun.COM sa_group_t group; 27748474SJose.Borrego@Sun.COM sa_resource_t resource; 27758474SJose.Borrego@Sun.COM boolean_t new_share = B_FALSE; 27768474SJose.Borrego@Sun.COM uint32_t status = NERR_Success; 27778474SJose.Borrego@Sun.COM int err; 27788474SJose.Borrego@Sun.COM 27798474SJose.Borrego@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 27808474SJose.Borrego@Sun.COM return (NERR_InternalError); 27818474SJose.Borrego@Sun.COM 27828474SJose.Borrego@Sun.COM share = sa_find_share(handle, path); 27838474SJose.Borrego@Sun.COM if (share == NULL) { 27848474SJose.Borrego@Sun.COM group = srvsvc_sa_get_smbgrp(handle); 27858474SJose.Borrego@Sun.COM if (group == NULL) { 27868474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 27878474SJose.Borrego@Sun.COM return (NERR_InternalError); 27888474SJose.Borrego@Sun.COM } 27898474SJose.Borrego@Sun.COM 27908474SJose.Borrego@Sun.COM share = sa_add_share(group, path, SA_SHARE_PERMANENT, &err); 27918474SJose.Borrego@Sun.COM if (share == NULL) { 27928474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 27938474SJose.Borrego@Sun.COM return (NERR_InternalError); 27948474SJose.Borrego@Sun.COM } 27958474SJose.Borrego@Sun.COM new_share = B_TRUE; 27968474SJose.Borrego@Sun.COM } 27978474SJose.Borrego@Sun.COM 27988474SJose.Borrego@Sun.COM resource = sa_get_share_resource(share, sharename); 27998474SJose.Borrego@Sun.COM if (resource == NULL) { 28008474SJose.Borrego@Sun.COM resource = sa_add_resource(share, sharename, 28018474SJose.Borrego@Sun.COM SA_SHARE_PERMANENT, &err); 28028474SJose.Borrego@Sun.COM if (resource == NULL) { 28038474SJose.Borrego@Sun.COM if (new_share) 28048474SJose.Borrego@Sun.COM (void) sa_remove_share(share); 28058474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 28068474SJose.Borrego@Sun.COM return (NERR_InternalError); 28078474SJose.Borrego@Sun.COM } 28088474SJose.Borrego@Sun.COM } 28098474SJose.Borrego@Sun.COM 28108474SJose.Borrego@Sun.COM (void) sa_set_resource_description(resource, cmnt); 28118474SJose.Borrego@Sun.COM 28128474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 28138474SJose.Borrego@Sun.COM return (status); 28148474SJose.Borrego@Sun.COM } 28158474SJose.Borrego@Sun.COM 28168474SJose.Borrego@Sun.COM /* 28178474SJose.Borrego@Sun.COM * Removes the share from sharemgr 28188474SJose.Borrego@Sun.COM */ 28198474SJose.Borrego@Sun.COM static uint32_t 28208474SJose.Borrego@Sun.COM srvsvc_sa_delete(char *sharename) 28218474SJose.Borrego@Sun.COM { 28228474SJose.Borrego@Sun.COM sa_handle_t handle; 28238474SJose.Borrego@Sun.COM sa_resource_t resource; 28248474SJose.Borrego@Sun.COM uint32_t status; 28258474SJose.Borrego@Sun.COM 28268474SJose.Borrego@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 28278474SJose.Borrego@Sun.COM return (NERR_InternalError); 28288474SJose.Borrego@Sun.COM 28298474SJose.Borrego@Sun.COM status = NERR_InternalError; 28308474SJose.Borrego@Sun.COM if ((resource = sa_find_resource(handle, sharename)) != NULL) { 28318474SJose.Borrego@Sun.COM if (sa_remove_resource(resource) == SA_OK) 28328474SJose.Borrego@Sun.COM status = NERR_Success; 28338474SJose.Borrego@Sun.COM } 28348474SJose.Borrego@Sun.COM 28358474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 28368474SJose.Borrego@Sun.COM return (status); 28378474SJose.Borrego@Sun.COM } 28388474SJose.Borrego@Sun.COM 28399832Samw@Sun.COM /* 28409832Samw@Sun.COM * Update the share information. 28419832Samw@Sun.COM */ 28429832Samw@Sun.COM static uint32_t 28439832Samw@Sun.COM srvsvc_sa_modify(smb_share_t *si, srvsvc_netshare_setinfo_t *info) 28449832Samw@Sun.COM { 28459832Samw@Sun.COM sa_handle_t handle; 28469832Samw@Sun.COM sa_share_t share; 28479832Samw@Sun.COM sa_resource_t resource; 28489832Samw@Sun.COM boolean_t renamed = B_FALSE; 28499832Samw@Sun.COM uint32_t nerr = NERR_Success; 28509832Samw@Sun.COM 28519832Samw@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 28529832Samw@Sun.COM return (NERR_InternalError); 28539832Samw@Sun.COM 28549832Samw@Sun.COM if ((share = sa_find_share(handle, si->shr_path)) == NULL) { 28559832Samw@Sun.COM smb_shr_sa_exit(); 28569832Samw@Sun.COM return (NERR_InternalError); 28579832Samw@Sun.COM } 28589832Samw@Sun.COM 28599832Samw@Sun.COM if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) { 28609832Samw@Sun.COM smb_shr_sa_exit(); 28619832Samw@Sun.COM return (NERR_InternalError); 28629832Samw@Sun.COM } 28639832Samw@Sun.COM 28649832Samw@Sun.COM if (info->nss_netname != NULL && info->nss_netname[0] != '\0' && 28659832Samw@Sun.COM utf8_strcasecmp(info->nss_netname, si->shr_name) != 0) { 28669832Samw@Sun.COM (void) sa_set_resource_attr(resource, SHOPT_NAME, 28679832Samw@Sun.COM info->nss_netname); 28689832Samw@Sun.COM renamed = B_TRUE; 28699832Samw@Sun.COM } 28709832Samw@Sun.COM 28719832Samw@Sun.COM if ((info->nss_comment != NULL) && 28729832Samw@Sun.COM (strcmp(info->nss_comment, si->shr_cmnt) != 0)) { 28739832Samw@Sun.COM (void) sa_set_resource_description(resource, info->nss_comment); 28749832Samw@Sun.COM (void) strlcpy(si->shr_cmnt, info->nss_comment, 28759832Samw@Sun.COM SMB_SHARE_CMNT_MAX); 28769832Samw@Sun.COM } 28779832Samw@Sun.COM 28789832Samw@Sun.COM smb_shr_sa_exit(); 28799832Samw@Sun.COM 28809832Samw@Sun.COM if (renamed) { 28819832Samw@Sun.COM nerr = smb_shr_rename(si->shr_name, info->nss_netname); 28829832Samw@Sun.COM if (nerr != NERR_Success) 28839832Samw@Sun.COM return (nerr); 28849832Samw@Sun.COM 28859832Samw@Sun.COM (void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN); 28869832Samw@Sun.COM } 28879832Samw@Sun.COM 28889832Samw@Sun.COM return (nerr); 28899832Samw@Sun.COM } 28909832Samw@Sun.COM 28919832Samw@Sun.COM /* 28929832Samw@Sun.COM * Update the share flags. 28939832Samw@Sun.COM */ 28949832Samw@Sun.COM static uint32_t 28959832Samw@Sun.COM srvsvc_sa_setattr(smb_share_t *si) 28969832Samw@Sun.COM { 28979832Samw@Sun.COM sa_handle_t handle; 28989832Samw@Sun.COM sa_share_t share; 28999832Samw@Sun.COM sa_resource_t resource; 29009832Samw@Sun.COM char *value; 29019832Samw@Sun.COM 29029832Samw@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 29039832Samw@Sun.COM return (NERR_InternalError); 29049832Samw@Sun.COM 29059832Samw@Sun.COM if ((share = sa_find_share(handle, si->shr_path)) == NULL) { 29069832Samw@Sun.COM smb_shr_sa_exit(); 29079832Samw@Sun.COM return (NERR_InternalError); 29089832Samw@Sun.COM } 29099832Samw@Sun.COM 29109832Samw@Sun.COM if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) { 29119832Samw@Sun.COM smb_shr_sa_exit(); 29129832Samw@Sun.COM return (NERR_InternalError); 29139832Samw@Sun.COM } 29149832Samw@Sun.COM 29159832Samw@Sun.COM if ((value = smb_shr_sa_csc_name(si)) == NULL) { 29169832Samw@Sun.COM smb_shr_sa_exit(); 29179832Samw@Sun.COM return (NERR_InternalError); 29189832Samw@Sun.COM } 29199832Samw@Sun.COM 29209832Samw@Sun.COM (void) sa_set_resource_attr(resource, SHOPT_CSC, value); 29219832Samw@Sun.COM smb_shr_sa_exit(); 29229832Samw@Sun.COM return (NERR_Success); 29239832Samw@Sun.COM } 29249832Samw@Sun.COM 29258474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[] = { 29268474SJose.Borrego@Sun.COM { srvsvc_s_NetConnectEnum, SRVSVC_OPNUM_NetConnectEnum }, 29278474SJose.Borrego@Sun.COM { srvsvc_s_NetFileEnum, SRVSVC_OPNUM_NetFileEnum }, 29288474SJose.Borrego@Sun.COM { srvsvc_s_NetFileClose, SRVSVC_OPNUM_NetFileClose }, 29298474SJose.Borrego@Sun.COM { srvsvc_s_NetShareGetInfo, SRVSVC_OPNUM_NetShareGetInfo }, 29308474SJose.Borrego@Sun.COM { srvsvc_s_NetShareSetInfo, SRVSVC_OPNUM_NetShareSetInfo }, 29318474SJose.Borrego@Sun.COM { srvsvc_s_NetSessionEnum, SRVSVC_OPNUM_NetSessionEnum }, 29328474SJose.Borrego@Sun.COM { srvsvc_s_NetSessionDel, SRVSVC_OPNUM_NetSessionDel }, 29338474SJose.Borrego@Sun.COM { srvsvc_s_NetServerGetInfo, SRVSVC_OPNUM_NetServerGetInfo }, 29348474SJose.Borrego@Sun.COM { srvsvc_s_NetRemoteTOD, SRVSVC_OPNUM_NetRemoteTOD }, 29358474SJose.Borrego@Sun.COM { srvsvc_s_NetNameValidate, SRVSVC_OPNUM_NetNameValidate }, 29368474SJose.Borrego@Sun.COM { srvsvc_s_NetShareAdd, SRVSVC_OPNUM_NetShareAdd }, 29378474SJose.Borrego@Sun.COM { srvsvc_s_NetShareDel, SRVSVC_OPNUM_NetShareDel }, 29388474SJose.Borrego@Sun.COM { srvsvc_s_NetShareEnum, SRVSVC_OPNUM_NetShareEnum }, 29398474SJose.Borrego@Sun.COM { srvsvc_s_NetShareEnumSticky, SRVSVC_OPNUM_NetShareEnumSticky }, 29409832Samw@Sun.COM { srvsvc_s_NetShareCheck, SRVSVC_OPNUM_NetShareCheck }, 29418474SJose.Borrego@Sun.COM { srvsvc_s_NetGetFileSecurity, SRVSVC_OPNUM_NetGetFileSecurity }, 29428474SJose.Borrego@Sun.COM { srvsvc_s_NetSetFileSecurity, SRVSVC_OPNUM_NetSetFileSecurity }, 29438474SJose.Borrego@Sun.COM {0} 29448474SJose.Borrego@Sun.COM }; 2945