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 /* 22*12065SKeyur.Desai@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 238474SJose.Borrego@Sun.COM */ 248474SJose.Borrego@Sun.COM 258474SJose.Borrego@Sun.COM /* 268474SJose.Borrego@Sun.COM * Server Service RPC (SRVSVC) server-side interface definition. 278474SJose.Borrego@Sun.COM * The server service provides a remote administration interface. 288474SJose.Borrego@Sun.COM * 298474SJose.Borrego@Sun.COM * This service uses NERR/Win32 error codes rather than NT status 308474SJose.Borrego@Sun.COM * values. 318474SJose.Borrego@Sun.COM */ 328474SJose.Borrego@Sun.COM 338474SJose.Borrego@Sun.COM #include <sys/errno.h> 3410966SJordan.Brown@Sun.COM #include <sys/tzfile.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> 4810504SKeyur.Desai@Sun.COM #include <libnvpair.h> 49*12065SKeyur.Desai@Sun.COM #include <sys/idmap.h> 50*12065SKeyur.Desai@Sun.COM #include <pwd.h> 51*12065SKeyur.Desai@Sun.COM #include <nss_dbdefs.h> 528474SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h> 538474SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h> 548474SJose.Borrego@Sun.COM #include <smbsrv/lmerr.h> 558474SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h> 5610966SJordan.Brown@Sun.COM #include <smbsrv/smb.h> 578474SJose.Borrego@Sun.COM #include <smbsrv/netrauth.h> 588474SJose.Borrego@Sun.COM #include <smbsrv/ndl/srvsvc.ndl> 599832Samw@Sun.COM #include "mlsvc.h" 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 6810122SJordan.Brown@Sun.COM #define SMB_SRVSVC_MAXBUFLEN (8 * 1024 * 1024) 6910122SJordan.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 9710122SJordan.Brown@Sun.COM typedef struct mslm_infonres srvsvc_infonres_t; 9810122SJordan.Brown@Sun.COM typedef struct mslm_NetConnectEnum srvsvc_NetConnectEnum_t; 9910122SJordan.Brown@Sun.COM 10010122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_level0(ndr_xa_t *, smb_svcenum_t *, 10110122SJordan.Brown@Sun.COM srvsvc_NetConnectEnum_t *); 10210122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_level1(ndr_xa_t *, smb_svcenum_t *, 10310122SJordan.Brown@Sun.COM srvsvc_NetConnectEnum_t *); 10410122SJordan.Brown@Sun.COM static uint32_t srvsvc_netconnectenum_common(ndr_xa_t *, 10510122SJordan.Brown@Sun.COM srvsvc_NetConnectInfo_t *, smb_netsvc_t *, smb_svcenum_t *); 10610122SJordan.Brown@Sun.COM 10710122SJordan.Brown@Sun.COM static DWORD srvsvc_NetFileEnum2(ndr_xa_t *, struct mslm_NetFileEnum *, 10810122SJordan.Brown@Sun.COM smb_svcenum_t *se); 10910122SJordan.Brown@Sun.COM static DWORD srvsvc_NetFileEnum3(ndr_xa_t *, struct mslm_NetFileEnum *, 11010122SJordan.Brown@Sun.COM smb_svcenum_t *se); 11110122SJordan.Brown@Sun.COM 11210122SJordan.Brown@Sun.COM static uint32_t srvsvc_NetSessionEnumCommon(ndr_xa_t *, srvsvc_infonres_t *, 11310122SJordan.Brown@Sun.COM smb_netsvc_t *, smb_svcenum_t *); 11410122SJordan.Brown@Sun.COM 11510122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel0(ndr_xa_t *, srvsvc_infonres_t *, 11610122SJordan.Brown@Sun.COM smb_svcenum_t *, int); 11710122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel1(ndr_xa_t *, srvsvc_infonres_t *, 11810122SJordan.Brown@Sun.COM smb_svcenum_t *, int); 11910122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel2(ndr_xa_t *, srvsvc_infonres_t *, 12010122SJordan.Brown@Sun.COM smb_svcenum_t *, int); 12110122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel501(ndr_xa_t *, srvsvc_infonres_t *, 12210122SJordan.Brown@Sun.COM smb_svcenum_t *, int); 12310122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumLevel502(ndr_xa_t *, srvsvc_infonres_t *, 12410122SJordan.Brown@Sun.COM smb_svcenum_t *, int); 12510122SJordan.Brown@Sun.COM static DWORD mlsvc_NetShareEnumCommon(ndr_xa_t *, smb_svcenum_t *, 12610122SJordan.Brown@Sun.COM smb_share_t *, void *); 12710122SJordan.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 *); 13210122SJordan.Brown@Sun.COM static void srvsvc_estimate_limit(smb_svcenum_t *, uint32_t); 13310122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_sessions(void); 13410122SJordan.Brown@Sun.COM static uint32_t srvsvc_open_connections(uint32_t, const char *); 13510122SJordan.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); 14210504SKeyur.Desai@Sun.COM static uint32_t srvsvc_get_share_flags(smb_share_t *); 1439832Samw@Sun.COM 1448474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_add(char *, char *, char *); 1458474SJose.Borrego@Sun.COM static uint32_t srvsvc_sa_delete(char *); 1469832Samw@Sun.COM static uint32_t srvsvc_sa_modify(smb_share_t *, srvsvc_netshare_setinfo_t *); 14710504SKeyur.Desai@Sun.COM static uint32_t srvsvc_sa_setprop(smb_share_t *, nvlist_t *); 1488474SJose.Borrego@Sun.COM 1498474SJose.Borrego@Sun.COM static char empty_string[1]; 1508474SJose.Borrego@Sun.COM 1518474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[]; 1528474SJose.Borrego@Sun.COM 1538474SJose.Borrego@Sun.COM static ndr_service_t srvsvc_service = { 1548474SJose.Borrego@Sun.COM "SRVSVC", /* name */ 1558474SJose.Borrego@Sun.COM "Server services", /* desc */ 1568474SJose.Borrego@Sun.COM "\\srvsvc", /* endpoint */ 1578474SJose.Borrego@Sun.COM PIPE_NTSVCS, /* sec_addr_port */ 1588474SJose.Borrego@Sun.COM "4b324fc8-1670-01d3-1278-5a47bf6ee188", 3, /* abstract */ 1598474SJose.Borrego@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 1608474SJose.Borrego@Sun.COM 0, /* no bind_instance_size */ 1618474SJose.Borrego@Sun.COM 0, /* no bind_req() */ 1628474SJose.Borrego@Sun.COM 0, /* no unbind_and_close() */ 1638474SJose.Borrego@Sun.COM 0, /* use generic_call_stub() */ 1648474SJose.Borrego@Sun.COM &TYPEINFO(srvsvc_interface), /* interface ti */ 1658474SJose.Borrego@Sun.COM srvsvc_stub_table /* stub_table */ 1668474SJose.Borrego@Sun.COM }; 1678474SJose.Borrego@Sun.COM 1688474SJose.Borrego@Sun.COM /* 1698474SJose.Borrego@Sun.COM * srvsvc_initialize 1708474SJose.Borrego@Sun.COM * 1718474SJose.Borrego@Sun.COM * This function registers the SRVSVC RPC interface with the RPC runtime 1728474SJose.Borrego@Sun.COM * library. It must be called in order to use either the client side 1738474SJose.Borrego@Sun.COM * or the server side functions. 1748474SJose.Borrego@Sun.COM */ 1758474SJose.Borrego@Sun.COM void 1768474SJose.Borrego@Sun.COM srvsvc_initialize(void) 1778474SJose.Borrego@Sun.COM { 1788474SJose.Borrego@Sun.COM (void) ndr_svc_register(&srvsvc_service); 1798474SJose.Borrego@Sun.COM } 1808474SJose.Borrego@Sun.COM 1818474SJose.Borrego@Sun.COM /* 18211963SAfshin.Ardakani@Sun.COM * Turn "dfsroot" property on/off for the specified 18311963SAfshin.Ardakani@Sun.COM * share and save it. 18411963SAfshin.Ardakani@Sun.COM * 18511963SAfshin.Ardakani@Sun.COM * If the requested value is the same as what is already 18611963SAfshin.Ardakani@Sun.COM * set then no change is required and the function returns. 18711963SAfshin.Ardakani@Sun.COM */ 18811963SAfshin.Ardakani@Sun.COM uint32_t 18911963SAfshin.Ardakani@Sun.COM srvsvc_shr_setdfsroot(smb_share_t *si, boolean_t on) 19011963SAfshin.Ardakani@Sun.COM { 19111963SAfshin.Ardakani@Sun.COM char *dfs = NULL; 19211963SAfshin.Ardakani@Sun.COM nvlist_t *nvl; 19311963SAfshin.Ardakani@Sun.COM uint32_t nerr; 19411963SAfshin.Ardakani@Sun.COM 19511963SAfshin.Ardakani@Sun.COM if (on && ((si->shr_flags & SMB_SHRF_DFSROOT) == 0)) { 19611963SAfshin.Ardakani@Sun.COM si->shr_flags |= SMB_SHRF_DFSROOT; 19711963SAfshin.Ardakani@Sun.COM dfs = "true"; 19811963SAfshin.Ardakani@Sun.COM } else if (!on && (si->shr_flags & SMB_SHRF_DFSROOT)) { 19911963SAfshin.Ardakani@Sun.COM si->shr_flags &= ~SMB_SHRF_DFSROOT; 20011963SAfshin.Ardakani@Sun.COM dfs = "false"; 20111963SAfshin.Ardakani@Sun.COM } 20211963SAfshin.Ardakani@Sun.COM 20311963SAfshin.Ardakani@Sun.COM if (dfs == NULL) 20411963SAfshin.Ardakani@Sun.COM return (ERROR_SUCCESS); 20511963SAfshin.Ardakani@Sun.COM 20611963SAfshin.Ardakani@Sun.COM if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) 20711963SAfshin.Ardakani@Sun.COM return (NERR_InternalError); 20811963SAfshin.Ardakani@Sun.COM 20911963SAfshin.Ardakani@Sun.COM if (nvlist_add_string(nvl, SHOPT_DFSROOT, dfs) != 0) { 21011963SAfshin.Ardakani@Sun.COM nvlist_free(nvl); 21111963SAfshin.Ardakani@Sun.COM return (NERR_InternalError); 21211963SAfshin.Ardakani@Sun.COM } 21311963SAfshin.Ardakani@Sun.COM 21411963SAfshin.Ardakani@Sun.COM nerr = srvsvc_sa_setprop(si, nvl); 21511963SAfshin.Ardakani@Sun.COM nvlist_free(nvl); 21611963SAfshin.Ardakani@Sun.COM 21711963SAfshin.Ardakani@Sun.COM if (nerr != NERR_Success) 21811963SAfshin.Ardakani@Sun.COM return (nerr); 21911963SAfshin.Ardakani@Sun.COM 22011963SAfshin.Ardakani@Sun.COM return (smb_shr_modify(si)); 22111963SAfshin.Ardakani@Sun.COM } 22211963SAfshin.Ardakani@Sun.COM 22311963SAfshin.Ardakani@Sun.COM /* 2248474SJose.Borrego@Sun.COM * srvsvc_s_NetConnectEnum 2258474SJose.Borrego@Sun.COM * 2268474SJose.Borrego@Sun.COM * List tree connections made to a share on this server or all tree 2278474SJose.Borrego@Sun.COM * connections established from a specific client. Administrator, 2288474SJose.Borrego@Sun.COM * Server Operator, Print Operator or Power User group membership 2298474SJose.Borrego@Sun.COM * is required to use this interface. 2308474SJose.Borrego@Sun.COM * 2318474SJose.Borrego@Sun.COM * There are three information levels: 0, 1, and 50. We don't support 2328474SJose.Borrego@Sun.COM * level 50, which is only used by Windows 9x clients. 2338474SJose.Borrego@Sun.COM * 2348474SJose.Borrego@Sun.COM * It seems Server Manger (srvmgr) only sends workstation as the qualifier 2358474SJose.Borrego@Sun.COM * and the Computer Management Interface on Windows 2000 doesn't request 2368474SJose.Borrego@Sun.COM * a list of connections. 2378474SJose.Borrego@Sun.COM * 2388474SJose.Borrego@Sun.COM * Return Values: 2398474SJose.Borrego@Sun.COM * ERROR_SUCCESS Success 2408474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED Caller does not have access to this call. 2418474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER One of the parameters is invalid. 2428474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL Unknown information level specified. 2438474SJose.Borrego@Sun.COM * ERROR_MORE_DATA Partial date returned, more entries available. 2448474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 2458474SJose.Borrego@Sun.COM * NERR_NetNameNotFound The share qualifier cannot be found. 2468474SJose.Borrego@Sun.COM * NERR_BufTooSmall The supplied buffer is too small. 2478474SJose.Borrego@Sun.COM */ 2488474SJose.Borrego@Sun.COM static int 2498474SJose.Borrego@Sun.COM srvsvc_s_NetConnectEnum(void *arg, ndr_xa_t *mxa) 2508474SJose.Borrego@Sun.COM { 25110122SJordan.Brown@Sun.COM srvsvc_NetConnectEnum_t *param = arg; 25210122SJordan.Brown@Sun.COM smb_netsvc_t *ns; 25310122SJordan.Brown@Sun.COM smb_svcenum_t se; 25410122SJordan.Brown@Sun.COM char *qualifier; 25510122SJordan.Brown@Sun.COM int qualtype; 25610122SJordan.Brown@Sun.COM DWORD status = ERROR_SUCCESS; 2578474SJose.Borrego@Sun.COM 2588474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa)) { 25910122SJordan.Brown@Sun.COM status = ERROR_ACCESS_DENIED; 26010122SJordan.Brown@Sun.COM goto srvsvc_netconnectenum_error; 2618474SJose.Borrego@Sun.COM } 2628474SJose.Borrego@Sun.COM 2638474SJose.Borrego@Sun.COM qualifier = (char *)param->qualifier; 2648474SJose.Borrego@Sun.COM qualtype = srvsvc_netconnect_qualifier(qualifier); 2658474SJose.Borrego@Sun.COM if (qualtype == SRVSVC_CONNECT_ENUM_NULL) { 26610122SJordan.Brown@Sun.COM status = NERR_NetNameNotFound; 26710122SJordan.Brown@Sun.COM goto srvsvc_netconnectenum_error; 26810122SJordan.Brown@Sun.COM } 26910122SJordan.Brown@Sun.COM 27010122SJordan.Brown@Sun.COM param->total_entries = srvsvc_open_connections(qualtype, qualifier); 27110122SJordan.Brown@Sun.COM if (param->total_entries == 0) { 27210122SJordan.Brown@Sun.COM bzero(param, sizeof (srvsvc_NetConnectEnum_t)); 27310122SJordan.Brown@Sun.COM param->status = ERROR_SUCCESS; 2748474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 2758474SJose.Borrego@Sun.COM } 2768474SJose.Borrego@Sun.COM 27710122SJordan.Brown@Sun.COM bzero(&se, sizeof (smb_svcenum_t)); 27810122SJordan.Brown@Sun.COM se.se_type = SMB_SVCENUM_TYPE_TREE; 27910122SJordan.Brown@Sun.COM se.se_level = param->info.level; 28010122SJordan.Brown@Sun.COM se.se_ntotal = param->total_entries; 28110122SJordan.Brown@Sun.COM se.se_nlimit = se.se_ntotal; 28210122SJordan.Brown@Sun.COM 28310122SJordan.Brown@Sun.COM if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN || 28410122SJordan.Brown@Sun.COM param->pref_max_len > SMB_SRVSVC_MAXBUFLEN) 28510122SJordan.Brown@Sun.COM se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN; 28610122SJordan.Brown@Sun.COM else 28710122SJordan.Brown@Sun.COM se.se_prefmaxlen = param->pref_max_len; 28810122SJordan.Brown@Sun.COM 28910122SJordan.Brown@Sun.COM if (param->resume_handle) { 29010122SJordan.Brown@Sun.COM se.se_resume = *param->resume_handle; 29110122SJordan.Brown@Sun.COM se.se_nskip = se.se_resume; 29210122SJordan.Brown@Sun.COM *param->resume_handle = 0; 29310122SJordan.Brown@Sun.COM } 29410122SJordan.Brown@Sun.COM 2958474SJose.Borrego@Sun.COM switch (param->info.level) { 2968474SJose.Borrego@Sun.COM case 0: 29710122SJordan.Brown@Sun.COM status = srvsvc_netconnectenum_level0(mxa, &se, param); 2988474SJose.Borrego@Sun.COM break; 2998474SJose.Borrego@Sun.COM case 1: 30010122SJordan.Brown@Sun.COM status = srvsvc_netconnectenum_level1(mxa, &se, param); 3018474SJose.Borrego@Sun.COM break; 3028474SJose.Borrego@Sun.COM case 50: 3038474SJose.Borrego@Sun.COM status = ERROR_NOT_SUPPORTED; 3048474SJose.Borrego@Sun.COM break; 3058474SJose.Borrego@Sun.COM default: 3068474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 3078474SJose.Borrego@Sun.COM break; 3088474SJose.Borrego@Sun.COM } 3098474SJose.Borrego@Sun.COM 3108474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 31110122SJordan.Brown@Sun.COM goto srvsvc_netconnectenum_error; 31210122SJordan.Brown@Sun.COM 31310122SJordan.Brown@Sun.COM if ((ns = smb_kmod_enum_init(&se)) == NULL) { 31410122SJordan.Brown@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 31510122SJordan.Brown@Sun.COM goto srvsvc_netconnectenum_error; 31610122SJordan.Brown@Sun.COM } 31710122SJordan.Brown@Sun.COM 31810122SJordan.Brown@Sun.COM status = srvsvc_netconnectenum_common(mxa, ¶m->info, ns, &se); 31910122SJordan.Brown@Sun.COM smb_kmod_enum_fini(ns); 32010122SJordan.Brown@Sun.COM 32110122SJordan.Brown@Sun.COM if (status != ERROR_SUCCESS) 32210122SJordan.Brown@Sun.COM goto srvsvc_netconnectenum_error; 32310122SJordan.Brown@Sun.COM 32410122SJordan.Brown@Sun.COM if (param->resume_handle && 32510122SJordan.Brown@Sun.COM param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) { 32610122SJordan.Brown@Sun.COM if (se.se_resume < param->total_entries) { 32710122SJordan.Brown@Sun.COM *param->resume_handle = se.se_resume; 32810122SJordan.Brown@Sun.COM status = ERROR_MORE_DATA; 32910122SJordan.Brown@Sun.COM } 33010122SJordan.Brown@Sun.COM } 33110122SJordan.Brown@Sun.COM 33210122SJordan.Brown@Sun.COM param->status = status; 33310122SJordan.Brown@Sun.COM return (NDR_DRC_OK); 33410122SJordan.Brown@Sun.COM 33510122SJordan.Brown@Sun.COM srvsvc_netconnectenum_error: 33610122SJordan.Brown@Sun.COM bzero(param, sizeof (srvsvc_NetConnectEnum_t)); 3378474SJose.Borrego@Sun.COM param->status = status; 3388474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 3398474SJose.Borrego@Sun.COM } 3408474SJose.Borrego@Sun.COM 34110122SJordan.Brown@Sun.COM /* 34210122SJordan.Brown@Sun.COM * Allocate memory and estimate the number of objects that can 34310122SJordan.Brown@Sun.COM * be returned for NetConnectEnum level 0. 34410122SJordan.Brown@Sun.COM */ 34510122SJordan.Brown@Sun.COM static uint32_t 34610122SJordan.Brown@Sun.COM srvsvc_netconnectenum_level0(ndr_xa_t *mxa, smb_svcenum_t *se, 34710122SJordan.Brown@Sun.COM srvsvc_NetConnectEnum_t *param) 3488474SJose.Borrego@Sun.COM { 34910122SJordan.Brown@Sun.COM srvsvc_NetConnectInfo0_t *info0; 35010122SJordan.Brown@Sun.COM srvsvc_NetConnectInfoBuf0_t *ci0; 35110122SJordan.Brown@Sun.COM 35210122SJordan.Brown@Sun.COM if ((info0 = NDR_NEW(mxa, srvsvc_NetConnectInfo0_t)) == NULL) 35310122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 35410122SJordan.Brown@Sun.COM 35510122SJordan.Brown@Sun.COM bzero(info0, sizeof (srvsvc_NetConnectInfo0_t)); 35610122SJordan.Brown@Sun.COM param->info.ru.info0 = info0; 35710122SJordan.Brown@Sun.COM 35810122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, sizeof (srvsvc_NetConnectInfoBuf0_t)); 35910122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 36010122SJordan.Brown@Sun.COM return (NERR_BufTooSmall); 36110122SJordan.Brown@Sun.COM 36210122SJordan.Brown@Sun.COM do { 36310122SJordan.Brown@Sun.COM ci0 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf0_t, se->se_nlimit); 36410122SJordan.Brown@Sun.COM if (ci0 == NULL) 36510122SJordan.Brown@Sun.COM se->se_nlimit >>= 1; 36610122SJordan.Brown@Sun.COM } while ((se->se_nlimit > 0) && (ci0 == NULL)); 36710122SJordan.Brown@Sun.COM 3688474SJose.Borrego@Sun.COM if (ci0 == NULL) 3698474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 3708474SJose.Borrego@Sun.COM 3718474SJose.Borrego@Sun.COM info0->ci0 = ci0; 37210122SJordan.Brown@Sun.COM info0->entries_read = 0; 3738474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 3748474SJose.Borrego@Sun.COM } 3758474SJose.Borrego@Sun.COM 37610122SJordan.Brown@Sun.COM /* 37710122SJordan.Brown@Sun.COM * Allocate memory and estimate the number of objects that can 37810122SJordan.Brown@Sun.COM * be returned for NetConnectEnum level 1. 37910122SJordan.Brown@Sun.COM */ 38010122SJordan.Brown@Sun.COM static uint32_t 38110122SJordan.Brown@Sun.COM srvsvc_netconnectenum_level1(ndr_xa_t *mxa, smb_svcenum_t *se, 38210122SJordan.Brown@Sun.COM srvsvc_NetConnectEnum_t *param) 3838474SJose.Borrego@Sun.COM { 38410122SJordan.Brown@Sun.COM srvsvc_NetConnectInfo1_t *info1; 38510122SJordan.Brown@Sun.COM srvsvc_NetConnectInfoBuf1_t *ci1; 38610122SJordan.Brown@Sun.COM 38710122SJordan.Brown@Sun.COM if ((info1 = NDR_NEW(mxa, srvsvc_NetConnectInfo1_t)) == NULL) 38810122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 38910122SJordan.Brown@Sun.COM 39010122SJordan.Brown@Sun.COM bzero(info1, sizeof (srvsvc_NetConnectInfo1_t)); 39110122SJordan.Brown@Sun.COM param->info.ru.info1 = info1; 39210122SJordan.Brown@Sun.COM 39310122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 39410122SJordan.Brown@Sun.COM sizeof (srvsvc_NetConnectInfoBuf1_t) + MAXNAMELEN); 39510122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 39610122SJordan.Brown@Sun.COM return (NERR_BufTooSmall); 39710122SJordan.Brown@Sun.COM 39810122SJordan.Brown@Sun.COM do { 39910122SJordan.Brown@Sun.COM ci1 = NDR_NEWN(mxa, srvsvc_NetConnectInfoBuf1_t, se->se_nlimit); 40010122SJordan.Brown@Sun.COM if (ci1 == NULL) 40110122SJordan.Brown@Sun.COM se->se_nlimit >>= 1; 40210122SJordan.Brown@Sun.COM } while ((se->se_nlimit > 0) && (ci1 == NULL)); 40310122SJordan.Brown@Sun.COM 4048474SJose.Borrego@Sun.COM if (ci1 == NULL) 4058474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 4068474SJose.Borrego@Sun.COM 4078474SJose.Borrego@Sun.COM info1->ci1 = ci1; 40810122SJordan.Brown@Sun.COM info1->entries_read = 0; 40910122SJordan.Brown@Sun.COM return (ERROR_SUCCESS); 41010122SJordan.Brown@Sun.COM } 41110122SJordan.Brown@Sun.COM 41210122SJordan.Brown@Sun.COM /* 41310122SJordan.Brown@Sun.COM * Request a list of connections from the kernel and set up 41410122SJordan.Brown@Sun.COM * the connection information to be returned to the client. 41510122SJordan.Brown@Sun.COM */ 41610122SJordan.Brown@Sun.COM static uint32_t 41710122SJordan.Brown@Sun.COM srvsvc_netconnectenum_common(ndr_xa_t *mxa, srvsvc_NetConnectInfo_t *info, 41810122SJordan.Brown@Sun.COM smb_netsvc_t *ns, smb_svcenum_t *se) 41910122SJordan.Brown@Sun.COM { 42010122SJordan.Brown@Sun.COM srvsvc_NetConnectInfo0_t *info0; 42110122SJordan.Brown@Sun.COM srvsvc_NetConnectInfo1_t *info1; 42210122SJordan.Brown@Sun.COM srvsvc_NetConnectInfoBuf0_t *ci0; 42310122SJordan.Brown@Sun.COM srvsvc_NetConnectInfoBuf1_t *ci1; 42410122SJordan.Brown@Sun.COM smb_netsvcitem_t *item; 42510122SJordan.Brown@Sun.COM smb_netconnectinfo_t *tree; 42610122SJordan.Brown@Sun.COM 42710122SJordan.Brown@Sun.COM if (smb_kmod_enum(ns) != 0) 42810122SJordan.Brown@Sun.COM return (ERROR_INTERNAL_ERROR); 42910122SJordan.Brown@Sun.COM 43010122SJordan.Brown@Sun.COM info0 = info->ru.info0; 43110122SJordan.Brown@Sun.COM ci0 = info0->ci0; 43210122SJordan.Brown@Sun.COM 43310122SJordan.Brown@Sun.COM info1 = info->ru.info1; 43410122SJordan.Brown@Sun.COM ci1 = info1->ci1; 43510122SJordan.Brown@Sun.COM 43610122SJordan.Brown@Sun.COM item = list_head(&ns->ns_list); 43710122SJordan.Brown@Sun.COM while (item != NULL) { 43810122SJordan.Brown@Sun.COM tree = &item->nsi_un.nsi_tree; 43910122SJordan.Brown@Sun.COM 44010122SJordan.Brown@Sun.COM switch (se->se_level) { 44110122SJordan.Brown@Sun.COM case 0: 44210122SJordan.Brown@Sun.COM ci0->coni0_id = tree->ci_id; 44310122SJordan.Brown@Sun.COM ++ci0; 44410122SJordan.Brown@Sun.COM ++info0->entries_read; 44510122SJordan.Brown@Sun.COM break; 44610122SJordan.Brown@Sun.COM case 1: 44710122SJordan.Brown@Sun.COM ci1->coni1_id = tree->ci_id; 44810122SJordan.Brown@Sun.COM ci1->coni1_type = tree->ci_type; 44910122SJordan.Brown@Sun.COM ci1->coni1_num_opens = tree->ci_numopens; 45010122SJordan.Brown@Sun.COM ci1->coni1_num_users = tree->ci_numusers; 45110122SJordan.Brown@Sun.COM ci1->coni1_time = tree->ci_time; 45210122SJordan.Brown@Sun.COM ci1->coni1_username = (uint8_t *) 45310122SJordan.Brown@Sun.COM NDR_STRDUP(mxa, tree->ci_username); 45410122SJordan.Brown@Sun.COM ci1->coni1_netname = (uint8_t *) 45510122SJordan.Brown@Sun.COM NDR_STRDUP(mxa, tree->ci_share); 45610122SJordan.Brown@Sun.COM ++ci1; 45710122SJordan.Brown@Sun.COM ++info1->entries_read; 45810122SJordan.Brown@Sun.COM break; 45910122SJordan.Brown@Sun.COM default: 46010122SJordan.Brown@Sun.COM return (ERROR_INVALID_LEVEL); 46110122SJordan.Brown@Sun.COM } 46210122SJordan.Brown@Sun.COM 46310122SJordan.Brown@Sun.COM ++se->se_resume; 46410122SJordan.Brown@Sun.COM item = list_next(&ns->ns_list, item); 46510122SJordan.Brown@Sun.COM } 46610122SJordan.Brown@Sun.COM 4678474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 4688474SJose.Borrego@Sun.COM } 4698474SJose.Borrego@Sun.COM 4708474SJose.Borrego@Sun.COM /* 4718474SJose.Borrego@Sun.COM * srvsvc_netconnect_qualifier 4728474SJose.Borrego@Sun.COM * 4738474SJose.Borrego@Sun.COM * The qualifier is a string that specifies a share name or computer name 4748474SJose.Borrego@Sun.COM * for the connections of interest. If it is a share name then all the 4758474SJose.Borrego@Sun.COM * connections made to that share name are listed. If it is a computer 4768474SJose.Borrego@Sun.COM * name (it starts with two backslash characters), then NetConnectEnum 4778474SJose.Borrego@Sun.COM * lists all connections made from that computer to the specified server. 4788474SJose.Borrego@Sun.COM */ 4798474SJose.Borrego@Sun.COM static int 4808474SJose.Borrego@Sun.COM srvsvc_netconnect_qualifier(const char *qualifier) 4818474SJose.Borrego@Sun.COM { 4828474SJose.Borrego@Sun.COM if (qualifier == NULL || *qualifier == '\0') 4838474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_NULL); 4848474SJose.Borrego@Sun.COM 4858474SJose.Borrego@Sun.COM if (strlen(qualifier) > MAXHOSTNAMELEN) 4868474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_NULL); 4878474SJose.Borrego@Sun.COM 4888474SJose.Borrego@Sun.COM if (qualifier[0] == '\\' && qualifier[1] == '\\') { 4898474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_WKSTN); 4908474SJose.Borrego@Sun.COM } else { 4918474SJose.Borrego@Sun.COM if (!smb_shr_exists((char *)qualifier)) 4928474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_NULL); 4938474SJose.Borrego@Sun.COM 4948474SJose.Borrego@Sun.COM return (SRVSVC_CONNECT_ENUM_SHARE); 4958474SJose.Borrego@Sun.COM } 4968474SJose.Borrego@Sun.COM } 4978474SJose.Borrego@Sun.COM 49810122SJordan.Brown@Sun.COM static uint32_t 49910122SJordan.Brown@Sun.COM srvsvc_open_sessions(void) 50010122SJordan.Brown@Sun.COM { 50110122SJordan.Brown@Sun.COM smb_opennum_t opennum; 50210122SJordan.Brown@Sun.COM 50310122SJordan.Brown@Sun.COM bzero(&opennum, sizeof (smb_opennum_t)); 50410122SJordan.Brown@Sun.COM if (smb_kmod_get_open_num(&opennum) != 0) 50510122SJordan.Brown@Sun.COM return (0); 50610122SJordan.Brown@Sun.COM 50710122SJordan.Brown@Sun.COM return (opennum.open_users); 50810122SJordan.Brown@Sun.COM } 50910122SJordan.Brown@Sun.COM 51010122SJordan.Brown@Sun.COM static uint32_t 51110122SJordan.Brown@Sun.COM srvsvc_open_connections(uint32_t qualtype, const char *qualifier) 51210122SJordan.Brown@Sun.COM { 51310122SJordan.Brown@Sun.COM smb_opennum_t opennum; 51410122SJordan.Brown@Sun.COM 51510122SJordan.Brown@Sun.COM bzero(&opennum, sizeof (smb_opennum_t)); 51610122SJordan.Brown@Sun.COM opennum.qualtype = qualtype; 51710122SJordan.Brown@Sun.COM (void) strlcpy(opennum.qualifier, qualifier, MAXNAMELEN); 51810122SJordan.Brown@Sun.COM 51910122SJordan.Brown@Sun.COM if (smb_kmod_get_open_num(&opennum) != 0) 52010122SJordan.Brown@Sun.COM return (0); 52110122SJordan.Brown@Sun.COM 52210122SJordan.Brown@Sun.COM return (opennum.open_trees); 52310122SJordan.Brown@Sun.COM } 52410122SJordan.Brown@Sun.COM 52510122SJordan.Brown@Sun.COM static uint32_t 52610122SJordan.Brown@Sun.COM srvsvc_open_files(void) 52710122SJordan.Brown@Sun.COM { 52810122SJordan.Brown@Sun.COM smb_opennum_t opennum; 52910122SJordan.Brown@Sun.COM 53010122SJordan.Brown@Sun.COM bzero(&opennum, sizeof (smb_opennum_t)); 53110122SJordan.Brown@Sun.COM if (smb_kmod_get_open_num(&opennum) != 0) 53210122SJordan.Brown@Sun.COM return (0); 53310122SJordan.Brown@Sun.COM 53410122SJordan.Brown@Sun.COM return (opennum.open_files); 53510122SJordan.Brown@Sun.COM } 53610122SJordan.Brown@Sun.COM 5378474SJose.Borrego@Sun.COM /* 5388474SJose.Borrego@Sun.COM * srvsvc_s_NetFileEnum 5398474SJose.Borrego@Sun.COM * 5408474SJose.Borrego@Sun.COM * Return information on open files or named pipes. Only members of the 5418474SJose.Borrego@Sun.COM * Administrators or Server Operators local groups are allowed to make 5428474SJose.Borrego@Sun.COM * this call. Currently, we only support Administrators. 5438474SJose.Borrego@Sun.COM * 5448474SJose.Borrego@Sun.COM * If basepath is null, all open resources are enumerated. If basepath 5458474SJose.Borrego@Sun.COM * is non-null, only resources that have basepath as a prefix should 5468474SJose.Borrego@Sun.COM * be returned. 5478474SJose.Borrego@Sun.COM * 5488474SJose.Borrego@Sun.COM * If username is specified (non-null), only files opened by username 5498474SJose.Borrego@Sun.COM * should be returned. 5508474SJose.Borrego@Sun.COM * 5518474SJose.Borrego@Sun.COM * Notes: 5528474SJose.Borrego@Sun.COM * 1. We don't validate the servername because we would have to check 5538474SJose.Borrego@Sun.COM * all primary IPs and the ROI seems unlikely to be worth it. 5548474SJose.Borrego@Sun.COM * 2. Both basepath and username are currently ignored because both 5558474SJose.Borrego@Sun.COM * Server Manger (NT 4.0) and CMI (Windows 2000) always set them to null. 5568474SJose.Borrego@Sun.COM * 5578474SJose.Borrego@Sun.COM * The level of information requested may be one of: 5588474SJose.Borrego@Sun.COM * 5598474SJose.Borrego@Sun.COM * 2 Return the file identification number. 5608474SJose.Borrego@Sun.COM * This level is not supported on Windows Me/98/95. 5618474SJose.Borrego@Sun.COM * 5628474SJose.Borrego@Sun.COM * 3 Return information about the file. 5638474SJose.Borrego@Sun.COM * This level is not supported on Windows Me/98/95. 5648474SJose.Borrego@Sun.COM * 5658474SJose.Borrego@Sun.COM * 50 Windows Me/98/95: Return information about the file. 5668474SJose.Borrego@Sun.COM * 5678474SJose.Borrego@Sun.COM * Note: 5688474SJose.Borrego@Sun.COM * If pref_max_len is unlimited and resume_handle is null, the client 5698474SJose.Borrego@Sun.COM * expects to receive all data in a single call. 5708474SJose.Borrego@Sun.COM * If we are unable to do fit all data in a single response, we would 5718474SJose.Borrego@Sun.COM * normally return ERROR_MORE_DATA with a partial list. 5728474SJose.Borrego@Sun.COM * 5738474SJose.Borrego@Sun.COM * Unfortunately, when both of these conditions occur, Server Manager 5748474SJose.Borrego@Sun.COM * pops up an error box with the message "more data available" and 5758474SJose.Borrego@Sun.COM * doesn't display any of the returned data. In this case, it is 5768474SJose.Borrego@Sun.COM * probably better to return ERROR_SUCCESS with the partial list. 5778474SJose.Borrego@Sun.COM * Windows 2000 doesn't have this problem because it always sends a 5788474SJose.Borrego@Sun.COM * non-null resume_handle. 5798474SJose.Borrego@Sun.COM * 5808474SJose.Borrego@Sun.COM * Return Values: 5818474SJose.Borrego@Sun.COM * ERROR_SUCCESS Success 5828474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED Caller does not have access to this call. 5838474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER One of the parameters is invalid. 5848474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL Unknown information level specified. 5858474SJose.Borrego@Sun.COM * ERROR_MORE_DATA Partial date returned, more entries available. 5868474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 5878474SJose.Borrego@Sun.COM * NERR_BufTooSmall The supplied buffer is too small. 5888474SJose.Borrego@Sun.COM */ 5898474SJose.Borrego@Sun.COM static int 5908474SJose.Borrego@Sun.COM srvsvc_s_NetFileEnum(void *arg, ndr_xa_t *mxa) 5918474SJose.Borrego@Sun.COM { 59210122SJordan.Brown@Sun.COM struct mslm_NetFileEnum *param = arg; 59310122SJordan.Brown@Sun.COM smb_svcenum_t se; 59410122SJordan.Brown@Sun.COM DWORD status; 5958474SJose.Borrego@Sun.COM 5968474SJose.Borrego@Sun.COM if (!ndr_is_admin(mxa)) { 5978474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetFileEnum)); 5988474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 5998474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6008474SJose.Borrego@Sun.COM } 6018474SJose.Borrego@Sun.COM 60210122SJordan.Brown@Sun.COM if ((param->total_entries = srvsvc_open_files()) == 0) { 60310122SJordan.Brown@Sun.COM bzero(param, sizeof (struct mslm_NetFileEnum)); 60410122SJordan.Brown@Sun.COM param->status = ERROR_SUCCESS; 60510122SJordan.Brown@Sun.COM return (NDR_DRC_OK); 60610122SJordan.Brown@Sun.COM } 60710122SJordan.Brown@Sun.COM 60810122SJordan.Brown@Sun.COM bzero(&se, sizeof (smb_svcenum_t)); 60910122SJordan.Brown@Sun.COM se.se_type = SMB_SVCENUM_TYPE_FILE; 61010122SJordan.Brown@Sun.COM se.se_level = param->info.switch_value; 61110122SJordan.Brown@Sun.COM se.se_ntotal = param->total_entries; 61210122SJordan.Brown@Sun.COM se.se_nlimit = se.se_ntotal; 61310122SJordan.Brown@Sun.COM 61410122SJordan.Brown@Sun.COM if (param->pref_max_len == SMB_SRVSVC_MAXPREFLEN || 61510122SJordan.Brown@Sun.COM param->pref_max_len > SMB_SRVSVC_MAXBUFLEN) 61610122SJordan.Brown@Sun.COM se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN; 61710122SJordan.Brown@Sun.COM else 61810122SJordan.Brown@Sun.COM se.se_prefmaxlen = param->pref_max_len; 61910122SJordan.Brown@Sun.COM 62010122SJordan.Brown@Sun.COM if (param->resume_handle) { 62110122SJordan.Brown@Sun.COM se.se_resume = *param->resume_handle; 62210122SJordan.Brown@Sun.COM se.se_nskip = se.se_resume; 62310122SJordan.Brown@Sun.COM *param->resume_handle = 0; 62410122SJordan.Brown@Sun.COM } 62510122SJordan.Brown@Sun.COM 6268474SJose.Borrego@Sun.COM switch (param->info.switch_value) { 6278474SJose.Borrego@Sun.COM case 2: 62810122SJordan.Brown@Sun.COM status = srvsvc_NetFileEnum2(mxa, param, &se); 6298474SJose.Borrego@Sun.COM break; 6308474SJose.Borrego@Sun.COM 6318474SJose.Borrego@Sun.COM case 3: 63210122SJordan.Brown@Sun.COM status = srvsvc_NetFileEnum3(mxa, param, &se); 6338474SJose.Borrego@Sun.COM break; 6348474SJose.Borrego@Sun.COM 6358474SJose.Borrego@Sun.COM case 50: 6368474SJose.Borrego@Sun.COM status = ERROR_NOT_SUPPORTED; 6378474SJose.Borrego@Sun.COM break; 6388474SJose.Borrego@Sun.COM 6398474SJose.Borrego@Sun.COM default: 6408474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 6418474SJose.Borrego@Sun.COM break; 6428474SJose.Borrego@Sun.COM } 6438474SJose.Borrego@Sun.COM 6448474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) { 6458474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetFileEnum)); 6468474SJose.Borrego@Sun.COM param->status = status; 6478474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6488474SJose.Borrego@Sun.COM } 6498474SJose.Borrego@Sun.COM 65010122SJordan.Brown@Sun.COM if (param->resume_handle && 65110122SJordan.Brown@Sun.COM param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) { 65210122SJordan.Brown@Sun.COM if (se.se_resume < param->total_entries) { 65310122SJordan.Brown@Sun.COM *param->resume_handle = se.se_resume; 65410122SJordan.Brown@Sun.COM status = ERROR_MORE_DATA; 65510122SJordan.Brown@Sun.COM } 65610122SJordan.Brown@Sun.COM } 65710122SJordan.Brown@Sun.COM 65810122SJordan.Brown@Sun.COM param->status = status; 6598474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6608474SJose.Borrego@Sun.COM } 6618474SJose.Borrego@Sun.COM 6628474SJose.Borrego@Sun.COM /* 6638474SJose.Borrego@Sun.COM * Build level 2 file information. 6648474SJose.Borrego@Sun.COM * 66510122SJordan.Brown@Sun.COM * SMB fids are 16-bit values but this interface expects 32-bit file ids. 66610122SJordan.Brown@Sun.COM * So we use the uniqid here. 66710122SJordan.Brown@Sun.COM * 6688474SJose.Borrego@Sun.COM * On success, the caller expects that the info2, fi2 and entries_read 6698474SJose.Borrego@Sun.COM * fields have been set up. 6708474SJose.Borrego@Sun.COM */ 6718474SJose.Borrego@Sun.COM static DWORD 67210122SJordan.Brown@Sun.COM srvsvc_NetFileEnum2(ndr_xa_t *mxa, struct mslm_NetFileEnum *param, 67310122SJordan.Brown@Sun.COM smb_svcenum_t *se) 6748474SJose.Borrego@Sun.COM { 67510122SJordan.Brown@Sun.COM struct mslm_NetFileInfoBuf2 *fi2; 67610122SJordan.Brown@Sun.COM smb_netsvc_t *ns; 67710122SJordan.Brown@Sun.COM smb_netsvcitem_t *item; 67810122SJordan.Brown@Sun.COM smb_netfileinfo_t *ofile; 67910122SJordan.Brown@Sun.COM uint32_t entries_read = 0; 6808474SJose.Borrego@Sun.COM 6818474SJose.Borrego@Sun.COM param->info.ru.info2 = NDR_NEW(mxa, struct mslm_NetFileInfo2); 6829832Samw@Sun.COM if (param->info.ru.info2 == NULL) 6838474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 6848474SJose.Borrego@Sun.COM 68510122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, sizeof (struct mslm_NetFileInfoBuf2)); 68610122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 68710122SJordan.Brown@Sun.COM return (NERR_BufTooSmall); 68810122SJordan.Brown@Sun.COM 68910122SJordan.Brown@Sun.COM do { 69010122SJordan.Brown@Sun.COM fi2 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf2, se->se_nlimit); 69110122SJordan.Brown@Sun.COM if (fi2 == NULL) 69210122SJordan.Brown@Sun.COM se->se_nlimit >>= 1; 69310122SJordan.Brown@Sun.COM } while ((se->se_nlimit > 0) && (fi2 == NULL)); 69410122SJordan.Brown@Sun.COM 6958474SJose.Borrego@Sun.COM if (fi2 == NULL) 6968474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 6978474SJose.Borrego@Sun.COM 6988474SJose.Borrego@Sun.COM param->info.ru.info2->fi2 = fi2; 6998474SJose.Borrego@Sun.COM 70010122SJordan.Brown@Sun.COM if ((ns = smb_kmod_enum_init(se)) == NULL) 70110122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 70210122SJordan.Brown@Sun.COM 70310122SJordan.Brown@Sun.COM if (smb_kmod_enum(ns) != 0) { 70410122SJordan.Brown@Sun.COM smb_kmod_enum_fini(ns); 70510122SJordan.Brown@Sun.COM return (ERROR_INTERNAL_ERROR); 70610122SJordan.Brown@Sun.COM } 70710122SJordan.Brown@Sun.COM 70810122SJordan.Brown@Sun.COM item = list_head(&ns->ns_list); 70910122SJordan.Brown@Sun.COM while (item != NULL) { 71010122SJordan.Brown@Sun.COM ofile = &item->nsi_un.nsi_ofile; 71110122SJordan.Brown@Sun.COM fi2->fi2_id = ofile->fi_uniqid; 7128474SJose.Borrego@Sun.COM 7138474SJose.Borrego@Sun.COM ++entries_read; 7148474SJose.Borrego@Sun.COM ++fi2; 71510122SJordan.Brown@Sun.COM item = list_next(&ns->ns_list, item); 7168474SJose.Borrego@Sun.COM } 7178474SJose.Borrego@Sun.COM 71810122SJordan.Brown@Sun.COM se->se_resume += entries_read; 7198474SJose.Borrego@Sun.COM param->info.ru.info2->entries_read = entries_read; 72010122SJordan.Brown@Sun.COM smb_kmod_enum_fini(ns); 7218474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 7228474SJose.Borrego@Sun.COM } 7238474SJose.Borrego@Sun.COM 7248474SJose.Borrego@Sun.COM /* 7258474SJose.Borrego@Sun.COM * Build level 3 file information. 7268474SJose.Borrego@Sun.COM * 72710122SJordan.Brown@Sun.COM * SMB fids are 16-bit values but this interface expects 32-bit file ids. 72810122SJordan.Brown@Sun.COM * So we use the uniqid here. 72910122SJordan.Brown@Sun.COM * 7308474SJose.Borrego@Sun.COM * On success, the caller expects that the info3, fi3 and entries_read 7318474SJose.Borrego@Sun.COM * fields have been set up. 7328474SJose.Borrego@Sun.COM */ 7338474SJose.Borrego@Sun.COM static DWORD 73410122SJordan.Brown@Sun.COM srvsvc_NetFileEnum3(ndr_xa_t *mxa, struct mslm_NetFileEnum *param, 73510122SJordan.Brown@Sun.COM smb_svcenum_t *se) 7368474SJose.Borrego@Sun.COM { 73710122SJordan.Brown@Sun.COM struct mslm_NetFileInfoBuf3 *fi3; 73810122SJordan.Brown@Sun.COM smb_netsvc_t *ns; 73910122SJordan.Brown@Sun.COM smb_netsvcitem_t *item; 74010122SJordan.Brown@Sun.COM smb_netfileinfo_t *ofile; 74110122SJordan.Brown@Sun.COM uint32_t entries_read = 0; 7428474SJose.Borrego@Sun.COM 7438474SJose.Borrego@Sun.COM param->info.ru.info3 = NDR_NEW(mxa, struct mslm_NetFileInfo3); 7448474SJose.Borrego@Sun.COM if (param->info.ru.info3 == NULL) 7458474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 7468474SJose.Borrego@Sun.COM 74710122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 74810122SJordan.Brown@Sun.COM sizeof (struct mslm_NetFileInfoBuf3) + MAXNAMELEN); 74910122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 75010122SJordan.Brown@Sun.COM return (NERR_BufTooSmall); 75110122SJordan.Brown@Sun.COM 75210122SJordan.Brown@Sun.COM do { 75310122SJordan.Brown@Sun.COM fi3 = NDR_NEWN(mxa, struct mslm_NetFileInfoBuf3, se->se_nlimit); 75410122SJordan.Brown@Sun.COM if (fi3 == NULL) 75510122SJordan.Brown@Sun.COM se->se_nlimit >>= 1; 75610122SJordan.Brown@Sun.COM } while ((se->se_nlimit > 0) && (fi3 == NULL)); 75710122SJordan.Brown@Sun.COM 7588474SJose.Borrego@Sun.COM if (fi3 == NULL) 7598474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 7608474SJose.Borrego@Sun.COM 7618474SJose.Borrego@Sun.COM param->info.ru.info3->fi3 = fi3; 7628474SJose.Borrego@Sun.COM 76310122SJordan.Brown@Sun.COM if ((ns = smb_kmod_enum_init(se)) == NULL) 76410122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 76510122SJordan.Brown@Sun.COM 76610122SJordan.Brown@Sun.COM if (smb_kmod_enum(ns) != 0) { 76710122SJordan.Brown@Sun.COM smb_kmod_enum_fini(ns); 76810122SJordan.Brown@Sun.COM return (ERROR_INTERNAL_ERROR); 76910122SJordan.Brown@Sun.COM } 77010122SJordan.Brown@Sun.COM 77110122SJordan.Brown@Sun.COM item = list_head(&ns->ns_list); 77210122SJordan.Brown@Sun.COM while (item != NULL) { 77310122SJordan.Brown@Sun.COM ofile = &item->nsi_un.nsi_ofile; 77410122SJordan.Brown@Sun.COM fi3->fi3_id = ofile->fi_uniqid; 77510122SJordan.Brown@Sun.COM fi3->fi3_permissions = ofile->fi_permissions; 77610122SJordan.Brown@Sun.COM fi3->fi3_num_locks = ofile->fi_numlocks; 7778474SJose.Borrego@Sun.COM fi3->fi3_pathname = (uint8_t *) 77810122SJordan.Brown@Sun.COM NDR_STRDUP(mxa, ofile->fi_path); 7798474SJose.Borrego@Sun.COM fi3->fi3_username = (uint8_t *) 78010122SJordan.Brown@Sun.COM NDR_STRDUP(mxa, ofile->fi_username); 7818474SJose.Borrego@Sun.COM 7828474SJose.Borrego@Sun.COM ++entries_read; 7838474SJose.Borrego@Sun.COM ++fi3; 78410122SJordan.Brown@Sun.COM item = list_next(&ns->ns_list, item); 7858474SJose.Borrego@Sun.COM } 7868474SJose.Borrego@Sun.COM 78710122SJordan.Brown@Sun.COM se->se_resume += entries_read; 7888474SJose.Borrego@Sun.COM param->info.ru.info3->entries_read = entries_read; 7898474SJose.Borrego@Sun.COM param->total_entries = entries_read; 79011963SAfshin.Ardakani@Sun.COM smb_kmod_enum_fini(ns); 7918474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 7928474SJose.Borrego@Sun.COM } 7938474SJose.Borrego@Sun.COM 7948474SJose.Borrego@Sun.COM /* 7958474SJose.Borrego@Sun.COM * srvsvc_s_NetFileClose 7968474SJose.Borrego@Sun.COM * 7978474SJose.Borrego@Sun.COM * NetFileClose forces a file to close. This function can be used when 79810122SJordan.Brown@Sun.COM * an error prevents closure by other means. Use NetFileClose with 7998474SJose.Borrego@Sun.COM * caution because it does not flush data, cached on a client, to the 8008474SJose.Borrego@Sun.COM * file before closing the file. 8018474SJose.Borrego@Sun.COM * 80210122SJordan.Brown@Sun.COM * SMB fids are 16-bit values but this interface expects 32-bit file ids. 80310122SJordan.Brown@Sun.COM * So we use the uniqid here. 80410122SJordan.Brown@Sun.COM * 8058474SJose.Borrego@Sun.COM * Return Values 8068474SJose.Borrego@Sun.COM * ERROR_SUCCESS Operation succeeded. 8078474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED Operation denied. 8088474SJose.Borrego@Sun.COM * NERR_FileIdNotFound No open file with the specified id. 8098474SJose.Borrego@Sun.COM * 81010122SJordan.Brown@Sun.COM * Note: MSDN suggests ERROR_FILE_NOT_FOUND for NetFileClose but network 81110122SJordan.Brown@Sun.COM * captures using NT show NERR_FileIdNotFound, which is consistent with 81210122SJordan.Brown@Sun.COM * the NetFileClose2 page on MSDN. 8138474SJose.Borrego@Sun.COM */ 8148474SJose.Borrego@Sun.COM static int 8158474SJose.Borrego@Sun.COM srvsvc_s_NetFileClose(void *arg, ndr_xa_t *mxa) 8168474SJose.Borrego@Sun.COM { 81710122SJordan.Brown@Sun.COM static struct { 81810122SJordan.Brown@Sun.COM int errnum; 81910122SJordan.Brown@Sun.COM int nerr; 82010122SJordan.Brown@Sun.COM } errmap[] = { 82110122SJordan.Brown@Sun.COM 0, ERROR_SUCCESS, 82210122SJordan.Brown@Sun.COM EACCES, ERROR_ACCESS_DENIED, 82310122SJordan.Brown@Sun.COM EPERM, ERROR_ACCESS_DENIED, 82410122SJordan.Brown@Sun.COM EINVAL, ERROR_INVALID_PARAMETER, 82510122SJordan.Brown@Sun.COM ENOMEM, ERROR_NOT_ENOUGH_MEMORY, 82610122SJordan.Brown@Sun.COM ENOENT, NERR_FileIdNotFound 82710122SJordan.Brown@Sun.COM }; 82810122SJordan.Brown@Sun.COM 8298474SJose.Borrego@Sun.COM struct mslm_NetFileClose *param = arg; 83010122SJordan.Brown@Sun.COM int i; 83110122SJordan.Brown@Sun.COM int rc; 8328474SJose.Borrego@Sun.COM 8338474SJose.Borrego@Sun.COM if (!ndr_is_admin(mxa)) { 8348474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 8358474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8368474SJose.Borrego@Sun.COM } 8378474SJose.Borrego@Sun.COM 83810122SJordan.Brown@Sun.COM rc = smb_kmod_file_close(param->file_id); 83910122SJordan.Brown@Sun.COM 84010122SJordan.Brown@Sun.COM for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) { 84110122SJordan.Brown@Sun.COM if (rc == errmap[i].errnum) { 84210122SJordan.Brown@Sun.COM param->status = errmap[i].nerr; 84310122SJordan.Brown@Sun.COM return (NDR_DRC_OK); 84410122SJordan.Brown@Sun.COM } 84510122SJordan.Brown@Sun.COM } 84610122SJordan.Brown@Sun.COM 84710122SJordan.Brown@Sun.COM param->status = ERROR_INTERNAL_ERROR; 8488474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8498474SJose.Borrego@Sun.COM } 8508474SJose.Borrego@Sun.COM 8518474SJose.Borrego@Sun.COM /* 8528474SJose.Borrego@Sun.COM * srvsvc_s_NetShareGetInfo 8538474SJose.Borrego@Sun.COM * 8548474SJose.Borrego@Sun.COM * Returns Win32 error codes. 8558474SJose.Borrego@Sun.COM */ 8568474SJose.Borrego@Sun.COM static int 8578474SJose.Borrego@Sun.COM srvsvc_s_NetShareGetInfo(void *arg, ndr_xa_t *mxa) 8588474SJose.Borrego@Sun.COM { 8598474SJose.Borrego@Sun.COM struct mlsm_NetShareGetInfo *param = arg; 8609343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_0 *info0; 8619343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1 *info1; 8629343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_2 *info2; 8639343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_501 *info501; 8649343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_502 *info502; 8659832Samw@Sun.COM struct mslm_NetShareInfo_503 *info503; 8669343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1004 *info1004; 8679343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1005 *info1005; 8689343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1006 *info1006; 8699832Samw@Sun.COM struct mslm_NetShareInfo_1501 *info1501; 8709832Samw@Sun.COM srvsvc_netshare_getinfo_t *info; 8719832Samw@Sun.COM uint8_t *netname; 8729832Samw@Sun.COM uint8_t *comment; 8738474SJose.Borrego@Sun.COM smb_share_t si; 8749832Samw@Sun.COM srvsvc_sd_t sd; 8758474SJose.Borrego@Sun.COM DWORD status; 8768474SJose.Borrego@Sun.COM 8778474SJose.Borrego@Sun.COM status = smb_shr_get((char *)param->netname, &si); 8788474SJose.Borrego@Sun.COM if (status != NERR_Success) { 8798474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mlsm_NetShareGetInfo)); 8808474SJose.Borrego@Sun.COM param->status = status; 8818474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8828474SJose.Borrego@Sun.COM } 8838474SJose.Borrego@Sun.COM 8849832Samw@Sun.COM netname = (uint8_t *)NDR_STRDUP(mxa, si.shr_name); 8859832Samw@Sun.COM comment = (uint8_t *)NDR_STRDUP(mxa, si.shr_cmnt); 8869832Samw@Sun.COM info = NDR_NEW(mxa, srvsvc_netshare_getinfo_t); 8879832Samw@Sun.COM 8889832Samw@Sun.COM if (netname == NULL || comment == NULL || info == NULL) { 8899832Samw@Sun.COM bzero(param, sizeof (struct mlsm_NetShareGetInfo)); 8909832Samw@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 8919832Samw@Sun.COM return (NDR_DRC_OK); 8929832Samw@Sun.COM } 8939832Samw@Sun.COM 8948474SJose.Borrego@Sun.COM switch (param->level) { 8958474SJose.Borrego@Sun.COM case 0: 8969832Samw@Sun.COM info0 = &info->nsg_info0; 8979832Samw@Sun.COM info0->shi0_netname = netname; 8988474SJose.Borrego@Sun.COM param->result.ru.info0 = info0; 8998474SJose.Borrego@Sun.COM break; 9008474SJose.Borrego@Sun.COM 9018474SJose.Borrego@Sun.COM case 1: 9029832Samw@Sun.COM info1 = &info->nsg_info1; 9039832Samw@Sun.COM info1->shi1_netname = netname; 9049832Samw@Sun.COM info1->shi1_comment = comment; 9058474SJose.Borrego@Sun.COM info1->shi1_type = si.shr_type; 9068474SJose.Borrego@Sun.COM param->result.ru.info1 = info1; 9078474SJose.Borrego@Sun.COM break; 9088474SJose.Borrego@Sun.COM 9098474SJose.Borrego@Sun.COM case 2: 9109832Samw@Sun.COM info2 = &info->nsg_info2; 9119832Samw@Sun.COM info2->shi2_netname = netname; 9129832Samw@Sun.COM info2->shi2_comment = comment; 9138474SJose.Borrego@Sun.COM info2->shi2_path = 9148474SJose.Borrego@Sun.COM (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path); 9158474SJose.Borrego@Sun.COM info2->shi2_passwd = 0; 9168474SJose.Borrego@Sun.COM info2->shi2_type = si.shr_type; 9178474SJose.Borrego@Sun.COM info2->shi2_permissions = 0; 9188474SJose.Borrego@Sun.COM info2->shi2_max_uses = SHI_USES_UNLIMITED; 9198474SJose.Borrego@Sun.COM info2->shi2_current_uses = 0; 9208474SJose.Borrego@Sun.COM param->result.ru.info2 = info2; 9218474SJose.Borrego@Sun.COM break; 9228474SJose.Borrego@Sun.COM 9239832Samw@Sun.COM case 501: 9249832Samw@Sun.COM info501 = &info->nsg_info501; 9259832Samw@Sun.COM info501->shi501_netname = netname; 9269832Samw@Sun.COM info501->shi501_comment = comment; 9279832Samw@Sun.COM info501->shi501_type = si.shr_type; 92810504SKeyur.Desai@Sun.COM info501->shi501_flags = srvsvc_get_share_flags(&si); 9299832Samw@Sun.COM param->result.ru.info501 = info501; 9309832Samw@Sun.COM break; 9319832Samw@Sun.COM 9329832Samw@Sun.COM case 502: 9339832Samw@Sun.COM info502 = &info->nsg_info502; 9349832Samw@Sun.COM info502->shi502_netname = netname; 9359832Samw@Sun.COM info502->shi502_comment = comment; 9369832Samw@Sun.COM info502->shi502_path = 9379832Samw@Sun.COM (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path); 9389832Samw@Sun.COM info502->shi502_passwd = 0; 9399832Samw@Sun.COM info502->shi502_type = si.shr_type; 9409832Samw@Sun.COM info502->shi502_permissions = 0; 9419832Samw@Sun.COM info502->shi502_max_uses = SHI_USES_UNLIMITED; 9429832Samw@Sun.COM info502->shi502_current_uses = 0; 9439832Samw@Sun.COM 9449832Samw@Sun.COM status = srvsvc_share_getsd(mxa, &si, &sd); 9459832Samw@Sun.COM if (status == ERROR_SUCCESS) { 9469832Samw@Sun.COM info502->shi502_reserved = sd.sd_size; 9479832Samw@Sun.COM info502->shi502_security_descriptor = sd.sd_buf; 9489832Samw@Sun.COM } else { 9499832Samw@Sun.COM info502->shi502_reserved = 0; 9509832Samw@Sun.COM info502->shi502_security_descriptor = NULL; 9518474SJose.Borrego@Sun.COM } 9528474SJose.Borrego@Sun.COM 9539832Samw@Sun.COM param->result.ru.info502 = info502; 9549832Samw@Sun.COM break; 9559832Samw@Sun.COM 9569832Samw@Sun.COM case 503: 9579832Samw@Sun.COM info503 = &info->nsg_info503; 9589832Samw@Sun.COM info503->shi503_netname = netname; 9599832Samw@Sun.COM info503->shi503_comment = comment; 9609832Samw@Sun.COM info503->shi503_path = 9619832Samw@Sun.COM (uint8_t *)srvsvc_share_mkpath(mxa, si.shr_path); 9629832Samw@Sun.COM info503->shi503_passwd = NULL; 9639832Samw@Sun.COM info503->shi503_type = si.shr_type; 9649832Samw@Sun.COM info503->shi503_permissions = 0; 9659832Samw@Sun.COM info503->shi503_max_uses = SHI_USES_UNLIMITED; 9669832Samw@Sun.COM info503->shi503_current_uses = 0; 9679832Samw@Sun.COM info503->shi503_servername = NULL; 9689832Samw@Sun.COM 9699832Samw@Sun.COM status = srvsvc_share_getsd(mxa, &si, &sd); 9709832Samw@Sun.COM if (status == ERROR_SUCCESS) { 9719832Samw@Sun.COM info503->shi503_reserved = sd.sd_size; 9729832Samw@Sun.COM info503->shi503_security_descriptor = sd.sd_buf; 9739832Samw@Sun.COM } else { 9749832Samw@Sun.COM info503->shi503_reserved = 0; 9759832Samw@Sun.COM info503->shi503_security_descriptor = NULL; 9769832Samw@Sun.COM } 9779832Samw@Sun.COM 9789832Samw@Sun.COM param->result.ru.info503 = info503; 9799832Samw@Sun.COM break; 9809832Samw@Sun.COM 9819832Samw@Sun.COM case 1004: 9829832Samw@Sun.COM info1004 = &info->nsg_info1004; 9839832Samw@Sun.COM info1004->shi1004_comment = comment; 9849832Samw@Sun.COM param->result.ru.info1004 = info1004; 9858474SJose.Borrego@Sun.COM break; 9868474SJose.Borrego@Sun.COM 9878474SJose.Borrego@Sun.COM case 1005: 9889832Samw@Sun.COM info1005 = &info->nsg_info1005; 98910504SKeyur.Desai@Sun.COM info1005->shi1005_flags = srvsvc_get_share_flags(&si); 9908474SJose.Borrego@Sun.COM param->result.ru.info1005 = info1005; 9918474SJose.Borrego@Sun.COM break; 9928474SJose.Borrego@Sun.COM 9938474SJose.Borrego@Sun.COM case 1006: 9949832Samw@Sun.COM info1006 = &info->nsg_info1006; 9958474SJose.Borrego@Sun.COM info1006->shi1006_max_uses = SHI_USES_UNLIMITED; 9968474SJose.Borrego@Sun.COM param->result.ru.info1006 = info1006; 9978474SJose.Borrego@Sun.COM break; 9988474SJose.Borrego@Sun.COM 9999832Samw@Sun.COM case 1501: 10009832Samw@Sun.COM info1501 = &info->nsg_info1501; 10019832Samw@Sun.COM 10029832Samw@Sun.COM status = srvsvc_share_getsd(mxa, &si, &sd); 10039832Samw@Sun.COM if (status == ERROR_SUCCESS) { 10049832Samw@Sun.COM info503->shi503_reserved = sd.sd_size; 10059832Samw@Sun.COM info503->shi503_security_descriptor = sd.sd_buf; 10069832Samw@Sun.COM } else { 10079832Samw@Sun.COM info503->shi503_reserved = 0; 10089832Samw@Sun.COM info503->shi503_security_descriptor = NULL; 10098474SJose.Borrego@Sun.COM } 10108474SJose.Borrego@Sun.COM 10119832Samw@Sun.COM param->result.ru.info1501 = info1501; 10128474SJose.Borrego@Sun.COM break; 10138474SJose.Borrego@Sun.COM 10148474SJose.Borrego@Sun.COM default: 10158474SJose.Borrego@Sun.COM status = ERROR_ACCESS_DENIED; 10168474SJose.Borrego@Sun.COM break; 10178474SJose.Borrego@Sun.COM } 10188474SJose.Borrego@Sun.COM 10198474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 10208474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mlsm_NetShareGetInfo)); 10218474SJose.Borrego@Sun.COM else 10228474SJose.Borrego@Sun.COM param->result.switch_value = param->level; 10238474SJose.Borrego@Sun.COM 10248474SJose.Borrego@Sun.COM param->status = status; 10258474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 10268474SJose.Borrego@Sun.COM } 10278474SJose.Borrego@Sun.COM 10289832Samw@Sun.COM static uint32_t 10299832Samw@Sun.COM srvsvc_share_getsd(ndr_xa_t *mxa, smb_share_t *si, srvsvc_sd_t *sd) 10309832Samw@Sun.COM { 10319832Samw@Sun.COM uint32_t status; 10329832Samw@Sun.COM 10339832Samw@Sun.COM status = srvsvc_sd_get(si, NULL, &sd->sd_size); 10349832Samw@Sun.COM if (status != ERROR_SUCCESS) { 10359832Samw@Sun.COM if (status == ERROR_PATH_NOT_FOUND) { 10369832Samw@Sun.COM bzero(sd, sizeof (srvsvc_sd_t)); 10379832Samw@Sun.COM status = ERROR_SUCCESS; 10389832Samw@Sun.COM } 10399832Samw@Sun.COM 10409832Samw@Sun.COM return (status); 10419832Samw@Sun.COM } 10429832Samw@Sun.COM 10439832Samw@Sun.COM if ((sd->sd_buf = NDR_MALLOC(mxa, sd->sd_size)) == NULL) 10449832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 10459832Samw@Sun.COM 10469832Samw@Sun.COM status = srvsvc_sd_get(si, sd->sd_buf, NULL); 10479832Samw@Sun.COM if (status == ERROR_PATH_NOT_FOUND) { 10489832Samw@Sun.COM bzero(sd, sizeof (srvsvc_sd_t)); 10499832Samw@Sun.COM status = ERROR_SUCCESS; 10509832Samw@Sun.COM } 10519832Samw@Sun.COM 10529832Samw@Sun.COM return (status); 10539832Samw@Sun.COM } 10548474SJose.Borrego@Sun.COM 10558474SJose.Borrego@Sun.COM /* 10568474SJose.Borrego@Sun.COM * srvsvc_s_NetShareSetInfo 10578474SJose.Borrego@Sun.COM * 10588474SJose.Borrego@Sun.COM * This call is made by SrvMgr to set share information. 10599832Samw@Sun.COM * Only power users groups can manage shares. 10609832Samw@Sun.COM * 10619832Samw@Sun.COM * To avoid misleading errors, we don't report an error 10629832Samw@Sun.COM * when a FS doesn't support ACLs on shares. 10638474SJose.Borrego@Sun.COM * 10648474SJose.Borrego@Sun.COM * Returns Win32 error codes. 10658474SJose.Borrego@Sun.COM */ 10668474SJose.Borrego@Sun.COM static int 10678474SJose.Borrego@Sun.COM srvsvc_s_NetShareSetInfo(void *arg, ndr_xa_t *mxa) 10688474SJose.Borrego@Sun.COM { 10698474SJose.Borrego@Sun.COM struct mlsm_NetShareSetInfo *param = arg; 10709832Samw@Sun.COM struct mslm_NetShareInfo_0 *info0; 10719832Samw@Sun.COM struct mslm_NetShareInfo_1 *info1; 10729832Samw@Sun.COM struct mslm_NetShareInfo_2 *info2; 10739832Samw@Sun.COM struct mslm_NetShareInfo_501 *info501; 10749832Samw@Sun.COM struct mslm_NetShareInfo_502 *info502; 10759832Samw@Sun.COM struct mslm_NetShareInfo_503 *info503; 10769832Samw@Sun.COM struct mslm_NetShareInfo_1004 *info1004; 10779832Samw@Sun.COM struct mslm_NetShareInfo_1005 *info1005; 10789832Samw@Sun.COM struct mslm_NetShareInfo_1501 *info1501; 10799832Samw@Sun.COM static DWORD parm_err = 0; 10809832Samw@Sun.COM srvsvc_netshare_setinfo_t info; 10819832Samw@Sun.COM smb_share_t si; 10829832Samw@Sun.COM uint8_t *sdbuf; 10839832Samw@Sun.COM int32_t native_os; 10849832Samw@Sun.COM DWORD status; 10859832Samw@Sun.COM 10869832Samw@Sun.COM native_os = ndr_native_os(mxa); 10879832Samw@Sun.COM 10889832Samw@Sun.COM if (!ndr_is_poweruser(mxa)) { 10899832Samw@Sun.COM status = ERROR_ACCESS_DENIED; 10909832Samw@Sun.COM goto netsharesetinfo_exit; 10919832Samw@Sun.COM } 10929832Samw@Sun.COM 10939832Samw@Sun.COM if (smb_shr_get((char *)param->netname, &si) != NERR_Success) { 10949832Samw@Sun.COM status = ERROR_INVALID_NETNAME; 10959832Samw@Sun.COM goto netsharesetinfo_exit; 10969832Samw@Sun.COM } 10979832Samw@Sun.COM 10989832Samw@Sun.COM if (param->result.ru.nullptr == NULL) { 10999832Samw@Sun.COM status = ERROR_INVALID_PARAMETER; 11009832Samw@Sun.COM goto netsharesetinfo_exit; 11019832Samw@Sun.COM } 11029832Samw@Sun.COM 11039832Samw@Sun.COM bzero(&info, sizeof (srvsvc_netshare_setinfo_t)); 11049832Samw@Sun.COM 11059832Samw@Sun.COM switch (param->level) { 11069832Samw@Sun.COM case 0: 11079832Samw@Sun.COM info0 = (struct mslm_NetShareInfo_0 *)param->result.ru.info0; 11089832Samw@Sun.COM info.nss_netname = (char *)info0->shi0_netname; 11099832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 11109832Samw@Sun.COM break; 11119832Samw@Sun.COM 11129832Samw@Sun.COM case 1: 11139832Samw@Sun.COM info1 = (struct mslm_NetShareInfo_1 *)param->result.ru.info1; 11149832Samw@Sun.COM info.nss_netname = (char *)info1->shi1_netname; 11159832Samw@Sun.COM info.nss_comment = (char *)info1->shi1_comment; 11169832Samw@Sun.COM info.nss_type = info1->shi1_type; 11179832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 11189832Samw@Sun.COM break; 11199832Samw@Sun.COM 11209832Samw@Sun.COM case 2: 11219832Samw@Sun.COM info2 = (struct mslm_NetShareInfo_2 *)param->result.ru.info2; 11229832Samw@Sun.COM info.nss_netname = (char *)info2->shi2_netname; 11239832Samw@Sun.COM info.nss_comment = (char *)info2->shi2_comment; 11249832Samw@Sun.COM info.nss_path = (char *)info2->shi2_path; 11259832Samw@Sun.COM info.nss_type = info2->shi2_type; 11269832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 11279832Samw@Sun.COM break; 11289832Samw@Sun.COM 11299832Samw@Sun.COM case 501: 11309832Samw@Sun.COM info501 = (struct mslm_NetShareInfo_501 *) 11319832Samw@Sun.COM param->result.ru.info501; 11329832Samw@Sun.COM info.nss_netname = (char *)info501->shi501_netname; 11339832Samw@Sun.COM info.nss_comment = (char *)info501->shi501_comment; 11349832Samw@Sun.COM info.nss_type = info501->shi501_type; 11359832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 113610504SKeyur.Desai@Sun.COM if (status == ERROR_SUCCESS) 113710504SKeyur.Desai@Sun.COM status = srvsvc_update_share_flags(&si, 113810504SKeyur.Desai@Sun.COM info501->shi501_flags); 11399832Samw@Sun.COM break; 11409832Samw@Sun.COM 11419832Samw@Sun.COM case 502: 11429832Samw@Sun.COM info502 = (struct mslm_NetShareInfo_502 *) 11439832Samw@Sun.COM param->result.ru.info502; 11449832Samw@Sun.COM info.nss_netname = (char *)info502->shi502_netname; 11459832Samw@Sun.COM info.nss_comment = (char *)info502->shi502_comment; 11469832Samw@Sun.COM info.nss_path = (char *)info502->shi502_path; 11479832Samw@Sun.COM info.nss_type = info502->shi502_type; 11489832Samw@Sun.COM info.nss_sd.sd_buf = info502->shi502_security_descriptor; 11499832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 11509832Samw@Sun.COM break; 11519832Samw@Sun.COM 11529832Samw@Sun.COM case 503: 11539832Samw@Sun.COM info503 = (struct mslm_NetShareInfo_503 *) 11549832Samw@Sun.COM param->result.ru.info503; 11559832Samw@Sun.COM info.nss_netname = (char *)info503->shi503_netname; 11569832Samw@Sun.COM info.nss_comment = (char *)info503->shi503_comment; 11579832Samw@Sun.COM info.nss_path = (char *)info503->shi503_path; 11589832Samw@Sun.COM info.nss_type = info503->shi503_type; 11599832Samw@Sun.COM info.nss_sd.sd_buf = info503->shi503_security_descriptor; 11609832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 11619832Samw@Sun.COM break; 11629832Samw@Sun.COM 11639832Samw@Sun.COM case 1004: 11649832Samw@Sun.COM info1004 = (struct mslm_NetShareInfo_1004 *) 11659832Samw@Sun.COM param->result.ru.info1004; 11669832Samw@Sun.COM info.nss_comment = (char *)info1004->shi1004_comment; 11679832Samw@Sun.COM status = srvsvc_modify_share(&si, &info); 11689832Samw@Sun.COM break; 11699832Samw@Sun.COM 11709832Samw@Sun.COM case 1005: 11719832Samw@Sun.COM info1005 = (struct mslm_NetShareInfo_1005 *) 11729832Samw@Sun.COM param->result.ru.info1005; 11739832Samw@Sun.COM status = srvsvc_update_share_flags(&si, 11749832Samw@Sun.COM info1005->shi1005_flags); 11759832Samw@Sun.COM break; 11769832Samw@Sun.COM 11779832Samw@Sun.COM case 1006: 11789832Samw@Sun.COM /* 11799832Samw@Sun.COM * We don't limit the maximum number of concurrent 11809832Samw@Sun.COM * connections to a share. 11819832Samw@Sun.COM */ 11829832Samw@Sun.COM status = ERROR_SUCCESS; 11839832Samw@Sun.COM break; 11849832Samw@Sun.COM 11859832Samw@Sun.COM case 1501: 11869832Samw@Sun.COM info1501 = (struct mslm_NetShareInfo_1501 *) 11879832Samw@Sun.COM param->result.ru.info1501; 11889832Samw@Sun.COM sdbuf = info1501->shi1501_security_descriptor; 11899832Samw@Sun.COM status = ERROR_SUCCESS; 11909832Samw@Sun.COM 11919832Samw@Sun.COM if (sdbuf != NULL) { 11929832Samw@Sun.COM status = srvsvc_sd_set(&si, sdbuf); 11939832Samw@Sun.COM if (status == ERROR_PATH_NOT_FOUND) 11949832Samw@Sun.COM status = ERROR_SUCCESS; 11959832Samw@Sun.COM } 11969832Samw@Sun.COM break; 11979832Samw@Sun.COM 11989832Samw@Sun.COM default: 11999832Samw@Sun.COM status = ERROR_ACCESS_DENIED; 12009832Samw@Sun.COM break; 12019832Samw@Sun.COM } 12029832Samw@Sun.COM 12039832Samw@Sun.COM netsharesetinfo_exit: 12049832Samw@Sun.COM if (status != ERROR_SUCCESS) 12059832Samw@Sun.COM bzero(param, sizeof (struct mlsm_NetShareSetInfo)); 12069832Samw@Sun.COM 12079832Samw@Sun.COM param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; 12089832Samw@Sun.COM param->status = status; 12098474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12108474SJose.Borrego@Sun.COM } 12118474SJose.Borrego@Sun.COM 12129832Samw@Sun.COM static uint32_t 12139832Samw@Sun.COM srvsvc_modify_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info) 12149832Samw@Sun.COM { 12159832Samw@Sun.COM uint32_t nerr = NERR_Success; 12169832Samw@Sun.COM 12179832Samw@Sun.COM if (si->shr_flags & SMB_SHRF_TRANS) 12189832Samw@Sun.COM return (srvsvc_modify_transient_share(si, info)); 12199832Samw@Sun.COM 12209832Samw@Sun.COM if (info->nss_sd.sd_buf != NULL) { 12219832Samw@Sun.COM nerr = srvsvc_sd_set(si, info->nss_sd.sd_buf); 12229832Samw@Sun.COM if (nerr == ERROR_PATH_NOT_FOUND) 12239832Samw@Sun.COM nerr = NERR_Success; 12249832Samw@Sun.COM } 12259832Samw@Sun.COM 12269832Samw@Sun.COM if ((nerr = srvsvc_sa_modify(si, info)) == NERR_Success) 12279832Samw@Sun.COM nerr = smb_shr_modify(si); 12289832Samw@Sun.COM 12299832Samw@Sun.COM return (nerr); 12309832Samw@Sun.COM } 12319832Samw@Sun.COM 12329832Samw@Sun.COM /* 12339832Samw@Sun.COM * Update transient shares. This includes autohome shares. 12349832Samw@Sun.COM */ 12359832Samw@Sun.COM static uint32_t 12369832Samw@Sun.COM srvsvc_modify_transient_share(smb_share_t *si, srvsvc_netshare_setinfo_t *info) 12379832Samw@Sun.COM { 12389832Samw@Sun.COM uint32_t nerr; 12399832Samw@Sun.COM 12409832Samw@Sun.COM if (info->nss_netname != NULL && info->nss_netname[0] != '\0' && 124110966SJordan.Brown@Sun.COM smb_strcasecmp(info->nss_netname, si->shr_name, 0) != 0) { 12429832Samw@Sun.COM nerr = smb_shr_rename(si->shr_name, info->nss_netname); 12439832Samw@Sun.COM if (nerr != NERR_Success) 12449832Samw@Sun.COM return (nerr); 12459832Samw@Sun.COM 12469832Samw@Sun.COM (void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN); 12479832Samw@Sun.COM } 12489832Samw@Sun.COM 12499832Samw@Sun.COM if ((info->nss_comment != NULL) && 12509832Samw@Sun.COM (strcmp(info->nss_comment, si->shr_cmnt) != 0)) { 12519832Samw@Sun.COM (void) strlcpy(si->shr_cmnt, info->nss_comment, 12529832Samw@Sun.COM SMB_SHARE_CMNT_MAX); 12539832Samw@Sun.COM 12549832Samw@Sun.COM if ((nerr = smb_shr_modify(si)) != NERR_Success) 12559832Samw@Sun.COM return (nerr); 12569832Samw@Sun.COM } 12579832Samw@Sun.COM 12589832Samw@Sun.COM return (NERR_Success); 12599832Samw@Sun.COM } 12609832Samw@Sun.COM 126110504SKeyur.Desai@Sun.COM /* 126210504SKeyur.Desai@Sun.COM * srvsvc_update_share_flags 126310504SKeyur.Desai@Sun.COM * 126410504SKeyur.Desai@Sun.COM * This function updates flags for shares. 126510504SKeyur.Desai@Sun.COM * Flags for Persistent shares are updated in both libshare and the local cache. 126610504SKeyur.Desai@Sun.COM * Flags for Transient shares are updated only in the local cache. 126710504SKeyur.Desai@Sun.COM */ 12689832Samw@Sun.COM static uint32_t 12699832Samw@Sun.COM srvsvc_update_share_flags(smb_share_t *si, uint32_t shi_flags) 12709832Samw@Sun.COM { 12719832Samw@Sun.COM uint32_t nerr = NERR_Success; 127210504SKeyur.Desai@Sun.COM uint32_t flag = 0; 127310504SKeyur.Desai@Sun.COM char *csc_value; 127410504SKeyur.Desai@Sun.COM char *abe_value = "false"; 127510504SKeyur.Desai@Sun.COM nvlist_t *nvl; 127610504SKeyur.Desai@Sun.COM int err = 0; 127710504SKeyur.Desai@Sun.COM 127810504SKeyur.Desai@Sun.COM if (shi_flags & SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM) { 127910504SKeyur.Desai@Sun.COM flag = SMB_SHRF_ABE; 128010504SKeyur.Desai@Sun.COM abe_value = "true"; 128110504SKeyur.Desai@Sun.COM } 128210504SKeyur.Desai@Sun.COM 128310504SKeyur.Desai@Sun.COM si->shr_flags &= ~SMB_SHRF_ABE; 128410504SKeyur.Desai@Sun.COM si->shr_flags |= flag; 12859832Samw@Sun.COM 12869832Samw@Sun.COM switch ((shi_flags & CSC_MASK)) { 12879832Samw@Sun.COM case CSC_CACHE_AUTO_REINT: 128810504SKeyur.Desai@Sun.COM flag = SMB_SHRF_CSC_AUTO; 12899832Samw@Sun.COM break; 12909832Samw@Sun.COM case CSC_CACHE_VDO: 129110504SKeyur.Desai@Sun.COM flag = SMB_SHRF_CSC_VDO; 12929832Samw@Sun.COM break; 12939832Samw@Sun.COM case CSC_CACHE_NONE: 129410504SKeyur.Desai@Sun.COM flag = SMB_SHRF_CSC_DISABLED; 12959832Samw@Sun.COM break; 12969832Samw@Sun.COM case CSC_CACHE_MANUAL_REINT: 129710504SKeyur.Desai@Sun.COM flag = SMB_SHRF_CSC_MANUAL; 12989832Samw@Sun.COM break; 12999832Samw@Sun.COM default: 130010504SKeyur.Desai@Sun.COM return (NERR_InternalError); 13019832Samw@Sun.COM } 13029832Samw@Sun.COM 13039832Samw@Sun.COM si->shr_flags &= ~SMB_SHRF_CSC_MASK; 130410504SKeyur.Desai@Sun.COM si->shr_flags |= flag; 13059832Samw@Sun.COM 13069832Samw@Sun.COM if ((si->shr_flags & SMB_SHRF_TRANS) == 0) { 130710504SKeyur.Desai@Sun.COM csc_value = smb_shr_sa_csc_name(si); 130810504SKeyur.Desai@Sun.COM 130910504SKeyur.Desai@Sun.COM if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) 131010504SKeyur.Desai@Sun.COM return (NERR_InternalError); 131110504SKeyur.Desai@Sun.COM 131210504SKeyur.Desai@Sun.COM err |= nvlist_add_string(nvl, SHOPT_CSC, csc_value); 131310504SKeyur.Desai@Sun.COM err |= nvlist_add_string(nvl, SHOPT_ABE, abe_value); 131410504SKeyur.Desai@Sun.COM if (err) { 131510504SKeyur.Desai@Sun.COM nvlist_free(nvl); 131610504SKeyur.Desai@Sun.COM return (NERR_InternalError); 131710504SKeyur.Desai@Sun.COM } 131810504SKeyur.Desai@Sun.COM 131910504SKeyur.Desai@Sun.COM nerr = srvsvc_sa_setprop(si, nvl); 132010504SKeyur.Desai@Sun.COM nvlist_free(nvl); 132110504SKeyur.Desai@Sun.COM 132210504SKeyur.Desai@Sun.COM if (nerr != NERR_Success) 13239832Samw@Sun.COM return (nerr); 13249832Samw@Sun.COM } 13259832Samw@Sun.COM 13269832Samw@Sun.COM return (smb_shr_modify(si)); 13279832Samw@Sun.COM } 13289832Samw@Sun.COM 132910504SKeyur.Desai@Sun.COM static uint32_t 133010504SKeyur.Desai@Sun.COM srvsvc_get_share_flags(smb_share_t *si) 133110504SKeyur.Desai@Sun.COM { 133210504SKeyur.Desai@Sun.COM uint32_t flags = 0; 133310504SKeyur.Desai@Sun.COM 133410504SKeyur.Desai@Sun.COM switch (si->shr_flags & SMB_SHRF_CSC_MASK) { 133510504SKeyur.Desai@Sun.COM case SMB_SHRF_CSC_DISABLED: 133610504SKeyur.Desai@Sun.COM flags |= CSC_CACHE_NONE; 133710504SKeyur.Desai@Sun.COM break; 133810504SKeyur.Desai@Sun.COM case SMB_SHRF_CSC_AUTO: 133910504SKeyur.Desai@Sun.COM flags |= CSC_CACHE_AUTO_REINT; 134010504SKeyur.Desai@Sun.COM break; 134110504SKeyur.Desai@Sun.COM case SMB_SHRF_CSC_VDO: 134210504SKeyur.Desai@Sun.COM flags |= CSC_CACHE_VDO; 134310504SKeyur.Desai@Sun.COM break; 134410504SKeyur.Desai@Sun.COM case SMB_SHRF_CSC_MANUAL: 134510504SKeyur.Desai@Sun.COM default: 134610504SKeyur.Desai@Sun.COM /* 134710504SKeyur.Desai@Sun.COM * Default to CSC_CACHE_MANUAL_REINT. 134810504SKeyur.Desai@Sun.COM */ 134910504SKeyur.Desai@Sun.COM break; 135010504SKeyur.Desai@Sun.COM } 135110504SKeyur.Desai@Sun.COM 135210504SKeyur.Desai@Sun.COM if (si->shr_flags & SMB_SHRF_ABE) 135310504SKeyur.Desai@Sun.COM flags |= SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM; 135410504SKeyur.Desai@Sun.COM 135510504SKeyur.Desai@Sun.COM return (flags); 135610504SKeyur.Desai@Sun.COM } 135710504SKeyur.Desai@Sun.COM 13588474SJose.Borrego@Sun.COM /* 13598474SJose.Borrego@Sun.COM * srvsvc_s_NetSessionEnum 13608474SJose.Borrego@Sun.COM * 13618474SJose.Borrego@Sun.COM * Level 1 request is made by (Server Manager (srvmgr) on NT Server when 13628474SJose.Borrego@Sun.COM * the user info icon is selected. 13638474SJose.Borrego@Sun.COM * 13648474SJose.Borrego@Sun.COM * On success, the return value is NERR_Success. 13658474SJose.Borrego@Sun.COM * On error, the return value can be one of the following error codes: 13668474SJose.Borrego@Sun.COM * 13678474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED The user does not have access to the requested 13688474SJose.Borrego@Sun.COM * information. 13698474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL The value specified for the level is invalid. 13708474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER The specified parameter is invalid. 13718474SJose.Borrego@Sun.COM * ERROR_MORE_DATA More entries are available. Specify a large 13728474SJose.Borrego@Sun.COM * enough buffer to receive all entries. 13738474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 13748474SJose.Borrego@Sun.COM * NERR_ClientNameNotFound A session does not exist with the computer name. 13758474SJose.Borrego@Sun.COM * NERR_InvalidComputer The computer name is invalid. 13768474SJose.Borrego@Sun.COM * NERR_UserNotFound The user name could not be found. 13778474SJose.Borrego@Sun.COM */ 13788474SJose.Borrego@Sun.COM static int 13798474SJose.Borrego@Sun.COM srvsvc_s_NetSessionEnum(void *arg, ndr_xa_t *mxa) 13808474SJose.Borrego@Sun.COM { 138110122SJordan.Brown@Sun.COM struct mslm_NetSessionEnum *param = arg; 138210122SJordan.Brown@Sun.COM srvsvc_infonres_t *info; 138310122SJordan.Brown@Sun.COM smb_netsvc_t *ns; 138410122SJordan.Brown@Sun.COM smb_svcenum_t se; 138510122SJordan.Brown@Sun.COM DWORD status = ERROR_SUCCESS; 138610122SJordan.Brown@Sun.COM 138710122SJordan.Brown@Sun.COM if (!ndr_is_admin(mxa)) { 138810122SJordan.Brown@Sun.COM status = ERROR_ACCESS_DENIED; 138910122SJordan.Brown@Sun.COM goto srvsvc_netsessionenum_error; 139010122SJordan.Brown@Sun.COM } 139110122SJordan.Brown@Sun.COM 139210122SJordan.Brown@Sun.COM if ((info = NDR_NEW(mxa, srvsvc_infonres_t)) == NULL) { 139310122SJordan.Brown@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 139410122SJordan.Brown@Sun.COM goto srvsvc_netsessionenum_error; 139510122SJordan.Brown@Sun.COM } 139610122SJordan.Brown@Sun.COM 139710122SJordan.Brown@Sun.COM info->entriesread = 0; 139810122SJordan.Brown@Sun.COM info->entries = NULL; 139910122SJordan.Brown@Sun.COM param->result.level = param->level; 140010122SJordan.Brown@Sun.COM param->result.bufptr.p = info; 140110122SJordan.Brown@Sun.COM 140210122SJordan.Brown@Sun.COM if ((param->total_entries = srvsvc_open_sessions()) == 0) { 140310122SJordan.Brown@Sun.COM param->resume_handle = NULL; 140410122SJordan.Brown@Sun.COM param->status = ERROR_SUCCESS; 14058474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 14068474SJose.Borrego@Sun.COM } 14078474SJose.Borrego@Sun.COM 140810122SJordan.Brown@Sun.COM bzero(&se, sizeof (smb_svcenum_t)); 140910122SJordan.Brown@Sun.COM se.se_type = SMB_SVCENUM_TYPE_USER; 141010122SJordan.Brown@Sun.COM se.se_level = param->level; 141110122SJordan.Brown@Sun.COM se.se_ntotal = param->total_entries; 141210122SJordan.Brown@Sun.COM se.se_nlimit = se.se_ntotal; 141310122SJordan.Brown@Sun.COM 141410122SJordan.Brown@Sun.COM if (param->resume_handle) { 141510122SJordan.Brown@Sun.COM se.se_resume = *param->resume_handle; 141610122SJordan.Brown@Sun.COM se.se_nskip = se.se_resume; 141710122SJordan.Brown@Sun.COM *param->resume_handle = 0; 141810122SJordan.Brown@Sun.COM } 14198474SJose.Borrego@Sun.COM 14208474SJose.Borrego@Sun.COM switch (param->level) { 14218474SJose.Borrego@Sun.COM case 0: 142210122SJordan.Brown@Sun.COM info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_0, 142310122SJordan.Brown@Sun.COM se.se_nlimit); 14248474SJose.Borrego@Sun.COM break; 142510122SJordan.Brown@Sun.COM case 1: 142610122SJordan.Brown@Sun.COM info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_1, 142710122SJordan.Brown@Sun.COM se.se_nlimit); 14289832Samw@Sun.COM break; 142910122SJordan.Brown@Sun.COM case 2: 143010122SJordan.Brown@Sun.COM info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_2, 143110122SJordan.Brown@Sun.COM se.se_nlimit); 14329832Samw@Sun.COM break; 143310122SJordan.Brown@Sun.COM case 10: 143410122SJordan.Brown@Sun.COM info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_10, 143510122SJordan.Brown@Sun.COM se.se_nlimit); 143610122SJordan.Brown@Sun.COM break; 14379832Samw@Sun.COM case 502: 143810122SJordan.Brown@Sun.COM info->entries = NDR_NEWN(mxa, struct mslm_SESSION_INFO_502, 143910122SJordan.Brown@Sun.COM se.se_nlimit); 14409832Samw@Sun.COM break; 14418474SJose.Borrego@Sun.COM default: 14428474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetSessionEnum)); 144310122SJordan.Brown@Sun.COM param->status = ERROR_INVALID_LEVEL; 14448474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 14458474SJose.Borrego@Sun.COM } 14468474SJose.Borrego@Sun.COM 144710122SJordan.Brown@Sun.COM if (info->entries == NULL) { 144810122SJordan.Brown@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 144910122SJordan.Brown@Sun.COM goto srvsvc_netsessionenum_error; 145010122SJordan.Brown@Sun.COM } 145110122SJordan.Brown@Sun.COM 145210122SJordan.Brown@Sun.COM if ((ns = smb_kmod_enum_init(&se)) == NULL) { 145310122SJordan.Brown@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 145410122SJordan.Brown@Sun.COM goto srvsvc_netsessionenum_error; 145510122SJordan.Brown@Sun.COM } 145610122SJordan.Brown@Sun.COM 145710122SJordan.Brown@Sun.COM status = srvsvc_NetSessionEnumCommon(mxa, info, ns, &se); 145810122SJordan.Brown@Sun.COM smb_kmod_enum_fini(ns); 145910122SJordan.Brown@Sun.COM 146010122SJordan.Brown@Sun.COM if (status != ERROR_SUCCESS) 146110122SJordan.Brown@Sun.COM goto srvsvc_netsessionenum_error; 146210122SJordan.Brown@Sun.COM 146310122SJordan.Brown@Sun.COM if (param->resume_handle && 146410122SJordan.Brown@Sun.COM param->pref_max_len != SMB_SRVSVC_MAXPREFLEN) { 146510122SJordan.Brown@Sun.COM if (se.se_resume < param->total_entries) { 146610122SJordan.Brown@Sun.COM *param->resume_handle = se.se_resume; 146710122SJordan.Brown@Sun.COM status = ERROR_MORE_DATA; 146810122SJordan.Brown@Sun.COM } 146910122SJordan.Brown@Sun.COM } 147010122SJordan.Brown@Sun.COM 147110122SJordan.Brown@Sun.COM param->total_entries = info->entriesread; 147210122SJordan.Brown@Sun.COM param->status = status; 147310122SJordan.Brown@Sun.COM return (NDR_DRC_OK); 147410122SJordan.Brown@Sun.COM 147510122SJordan.Brown@Sun.COM srvsvc_netsessionenum_error: 147610122SJordan.Brown@Sun.COM bzero(param, sizeof (struct mslm_NetSessionEnum)); 14778474SJose.Borrego@Sun.COM param->status = status; 14788474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 14798474SJose.Borrego@Sun.COM } 14808474SJose.Borrego@Sun.COM 148110122SJordan.Brown@Sun.COM static uint32_t 148210122SJordan.Brown@Sun.COM srvsvc_NetSessionEnumCommon(ndr_xa_t *mxa, srvsvc_infonres_t *info, 148310122SJordan.Brown@Sun.COM smb_netsvc_t *ns, smb_svcenum_t *se) 14848474SJose.Borrego@Sun.COM { 148510122SJordan.Brown@Sun.COM struct mslm_SESSION_INFO_0 *info0 = info->entries; 148610122SJordan.Brown@Sun.COM struct mslm_SESSION_INFO_1 *info1 = info->entries; 148710122SJordan.Brown@Sun.COM struct mslm_SESSION_INFO_2 *info2 = info->entries; 148810122SJordan.Brown@Sun.COM struct mslm_SESSION_INFO_10 *info10 = info->entries; 148910122SJordan.Brown@Sun.COM struct mslm_SESSION_INFO_502 *info502 = info->entries; 149010122SJordan.Brown@Sun.COM smb_netsvcitem_t *item; 149110122SJordan.Brown@Sun.COM smb_netuserinfo_t *user; 149210122SJordan.Brown@Sun.COM char *workstation; 149310122SJordan.Brown@Sun.COM char account[MAXNAMELEN]; 149410122SJordan.Brown@Sun.COM char ipaddr_buf[INET6_ADDRSTRLEN]; 149510122SJordan.Brown@Sun.COM uint32_t logon_time; 149610122SJordan.Brown@Sun.COM uint32_t flags; 149710122SJordan.Brown@Sun.COM uint32_t entries_read = 0; 149810122SJordan.Brown@Sun.COM 149910122SJordan.Brown@Sun.COM if (smb_kmod_enum(ns) != 0) 150010122SJordan.Brown@Sun.COM return (ERROR_INTERNAL_ERROR); 150110122SJordan.Brown@Sun.COM 150210122SJordan.Brown@Sun.COM item = list_head(&ns->ns_list); 150310122SJordan.Brown@Sun.COM while (item != NULL) { 150410122SJordan.Brown@Sun.COM user = &item->nsi_un.nsi_user; 150510122SJordan.Brown@Sun.COM 150610122SJordan.Brown@Sun.COM workstation = user->ui_workstation; 15078474SJose.Borrego@Sun.COM if (workstation == NULL || *workstation == '\0') { 150810122SJordan.Brown@Sun.COM (void) smb_inet_ntop(&user->ui_ipaddr, ipaddr_buf, 150910122SJordan.Brown@Sun.COM SMB_IPSTRLEN(user->ui_ipaddr.a_family)); 15108474SJose.Borrego@Sun.COM workstation = ipaddr_buf; 15118474SJose.Borrego@Sun.COM } 15128474SJose.Borrego@Sun.COM 15138474SJose.Borrego@Sun.COM (void) snprintf(account, MAXNAMELEN, "%s\\%s", 151410122SJordan.Brown@Sun.COM user->ui_domain, user->ui_account); 151510122SJordan.Brown@Sun.COM 151610122SJordan.Brown@Sun.COM logon_time = time(0) - user->ui_logon_time; 151710122SJordan.Brown@Sun.COM flags = (user->ui_flags & SMB_ATF_GUEST) ? SESS_GUEST : 0; 151810122SJordan.Brown@Sun.COM 151910122SJordan.Brown@Sun.COM switch (se->se_level) { 152010122SJordan.Brown@Sun.COM case 0: 152110122SJordan.Brown@Sun.COM info0->sesi0_cname = NDR_STRDUP(mxa, workstation); 152210122SJordan.Brown@Sun.COM if (info0->sesi0_cname == NULL) 152310122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 152410122SJordan.Brown@Sun.COM ++info0; 152510122SJordan.Brown@Sun.COM break; 152610122SJordan.Brown@Sun.COM 152710122SJordan.Brown@Sun.COM case 1: 152810122SJordan.Brown@Sun.COM info1->sesi1_cname = NDR_STRDUP(mxa, workstation); 152910122SJordan.Brown@Sun.COM info1->sesi1_uname = NDR_STRDUP(mxa, account); 153010122SJordan.Brown@Sun.COM 153110122SJordan.Brown@Sun.COM if (info1->sesi1_cname == NULL || 153210122SJordan.Brown@Sun.COM info1->sesi1_uname == NULL) 153310122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 153410122SJordan.Brown@Sun.COM 153510122SJordan.Brown@Sun.COM info1->sesi1_nopens = user->ui_numopens; 153610122SJordan.Brown@Sun.COM info1->sesi1_time = logon_time; 153710122SJordan.Brown@Sun.COM info1->sesi1_itime = 0; 153810122SJordan.Brown@Sun.COM info1->sesi1_uflags = flags; 153910122SJordan.Brown@Sun.COM ++info1; 154010122SJordan.Brown@Sun.COM break; 154110122SJordan.Brown@Sun.COM 154210122SJordan.Brown@Sun.COM case 2: 154310122SJordan.Brown@Sun.COM info2->sesi2_cname = NDR_STRDUP(mxa, workstation); 154410122SJordan.Brown@Sun.COM info2->sesi2_uname = NDR_STRDUP(mxa, account); 154510122SJordan.Brown@Sun.COM 154610122SJordan.Brown@Sun.COM if (info2->sesi2_cname == NULL || 154710122SJordan.Brown@Sun.COM info2->sesi2_uname == NULL) 154810122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 154910122SJordan.Brown@Sun.COM 155010122SJordan.Brown@Sun.COM info2->sesi2_nopens = user->ui_numopens; 155110122SJordan.Brown@Sun.COM info2->sesi2_time = logon_time; 155210122SJordan.Brown@Sun.COM info2->sesi2_itime = 0; 155310122SJordan.Brown@Sun.COM info2->sesi2_uflags = flags; 155410122SJordan.Brown@Sun.COM info2->sesi2_cltype_name = (uint8_t *)""; 155510122SJordan.Brown@Sun.COM ++info2; 155610122SJordan.Brown@Sun.COM break; 155710122SJordan.Brown@Sun.COM 155810122SJordan.Brown@Sun.COM case 10: 155910122SJordan.Brown@Sun.COM info10->sesi10_cname = NDR_STRDUP(mxa, workstation); 156010122SJordan.Brown@Sun.COM info10->sesi10_uname = NDR_STRDUP(mxa, account); 156110122SJordan.Brown@Sun.COM 156210122SJordan.Brown@Sun.COM if (info10->sesi10_cname == NULL || 156310122SJordan.Brown@Sun.COM info10->sesi10_uname == NULL) 156410122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 156510122SJordan.Brown@Sun.COM 156610122SJordan.Brown@Sun.COM info10->sesi10_time = logon_time; 156710122SJordan.Brown@Sun.COM info10->sesi10_itime = 0; 156810122SJordan.Brown@Sun.COM ++info10; 156910122SJordan.Brown@Sun.COM break; 157010122SJordan.Brown@Sun.COM 157110122SJordan.Brown@Sun.COM case 502: 157210122SJordan.Brown@Sun.COM info502->sesi502_cname = NDR_STRDUP(mxa, workstation); 157310122SJordan.Brown@Sun.COM info502->sesi502_uname = NDR_STRDUP(mxa, account); 157410122SJordan.Brown@Sun.COM 157510122SJordan.Brown@Sun.COM if (info502->sesi502_cname == NULL || 157610122SJordan.Brown@Sun.COM info502->sesi502_uname == NULL) 157710122SJordan.Brown@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 157810122SJordan.Brown@Sun.COM 157910122SJordan.Brown@Sun.COM info502->sesi502_nopens = user->ui_numopens; 158010122SJordan.Brown@Sun.COM info502->sesi502_time = logon_time; 158110122SJordan.Brown@Sun.COM info502->sesi502_itime = 0; 158210122SJordan.Brown@Sun.COM info502->sesi502_uflags = flags; 158310122SJordan.Brown@Sun.COM info502->sesi502_cltype_name = (uint8_t *)""; 158410122SJordan.Brown@Sun.COM info502->sesi502_transport = (uint8_t *)""; 158510122SJordan.Brown@Sun.COM ++info502; 158610122SJordan.Brown@Sun.COM break; 158710122SJordan.Brown@Sun.COM 158810122SJordan.Brown@Sun.COM default: 158910122SJordan.Brown@Sun.COM return (ERROR_INVALID_LEVEL); 15908474SJose.Borrego@Sun.COM } 15918474SJose.Borrego@Sun.COM 159210122SJordan.Brown@Sun.COM ++entries_read; 159310122SJordan.Brown@Sun.COM item = list_next(&ns->ns_list, item); 15949832Samw@Sun.COM } 15959832Samw@Sun.COM 159610122SJordan.Brown@Sun.COM info->entriesread = entries_read; 15979832Samw@Sun.COM return (ERROR_SUCCESS); 15989832Samw@Sun.COM } 15999832Samw@Sun.COM 16009832Samw@Sun.COM /* 16018474SJose.Borrego@Sun.COM * srvsvc_s_NetSessionDel 16028474SJose.Borrego@Sun.COM * 16038474SJose.Borrego@Sun.COM * Ends a network session between a server and a workstation. 16048474SJose.Borrego@Sun.COM * On NT only members of the Administrators or Account Operators 16058474SJose.Borrego@Sun.COM * local groups are permitted to use NetSessionDel. 16068474SJose.Borrego@Sun.COM * 160710122SJordan.Brown@Sun.COM * If unc_clientname is NULL, all sessions associated with the 160810122SJordan.Brown@Sun.COM * specified user will be disconnected. 160910122SJordan.Brown@Sun.COM * 161010122SJordan.Brown@Sun.COM * If username is NULL, all sessions from the specified client 161110122SJordan.Brown@Sun.COM * will be disconnected. 161210122SJordan.Brown@Sun.COM * 16138474SJose.Borrego@Sun.COM * Return Values 161410122SJordan.Brown@Sun.COM * On success, the return value is NERR_Success/ERROR_SUCCESS. 161510122SJordan.Brown@Sun.COM * On failure, the return value can be one of the following errors: 16168474SJose.Borrego@Sun.COM * 16178474SJose.Borrego@Sun.COM * ERROR_ACCESS_DENIED The user does not have access to the 161810122SJordan.Brown@Sun.COM * requested information. 16198474SJose.Borrego@Sun.COM * ERROR_INVALID_PARAMETER The specified parameter is invalid. 16208474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY Insufficient memory is available. 16218474SJose.Borrego@Sun.COM * NERR_ClientNameNotFound A session does not exist with that 162210122SJordan.Brown@Sun.COM * computer name. 16238474SJose.Borrego@Sun.COM */ 16248474SJose.Borrego@Sun.COM static int 16258474SJose.Borrego@Sun.COM srvsvc_s_NetSessionDel(void *arg, ndr_xa_t *mxa) 16268474SJose.Borrego@Sun.COM { 162710122SJordan.Brown@Sun.COM static struct { 162810122SJordan.Brown@Sun.COM int errnum; 162910122SJordan.Brown@Sun.COM int nerr; 163010122SJordan.Brown@Sun.COM } errmap[] = { 163110122SJordan.Brown@Sun.COM 0, ERROR_SUCCESS, 163210122SJordan.Brown@Sun.COM EACCES, ERROR_ACCESS_DENIED, 163310122SJordan.Brown@Sun.COM EPERM, ERROR_ACCESS_DENIED, 163410122SJordan.Brown@Sun.COM EINVAL, ERROR_INVALID_PARAMETER, 163510122SJordan.Brown@Sun.COM ENOMEM, ERROR_NOT_ENOUGH_MEMORY, 163610122SJordan.Brown@Sun.COM ENOENT, NERR_ClientNameNotFound 163710122SJordan.Brown@Sun.COM }; 163810122SJordan.Brown@Sun.COM 16398474SJose.Borrego@Sun.COM struct mslm_NetSessionDel *param = arg; 164010122SJordan.Brown@Sun.COM int i; 164110122SJordan.Brown@Sun.COM int rc; 164210122SJordan.Brown@Sun.COM 164310122SJordan.Brown@Sun.COM if (!ndr_is_admin(mxa)) { 16448474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 16458474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 16468474SJose.Borrego@Sun.COM } 16478474SJose.Borrego@Sun.COM 164810122SJordan.Brown@Sun.COM rc = smb_kmod_session_close((char *)param->unc_clientname, 164910122SJordan.Brown@Sun.COM (char *)param->username); 165010122SJordan.Brown@Sun.COM 165110122SJordan.Brown@Sun.COM for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) { 165210122SJordan.Brown@Sun.COM if (rc == errmap[i].errnum) { 165310122SJordan.Brown@Sun.COM param->status = errmap[i].nerr; 165410122SJordan.Brown@Sun.COM return (NDR_DRC_OK); 165510122SJordan.Brown@Sun.COM } 165610122SJordan.Brown@Sun.COM } 165710122SJordan.Brown@Sun.COM 165810122SJordan.Brown@Sun.COM param->status = ERROR_INTERNAL_ERROR; 16598474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 16608474SJose.Borrego@Sun.COM } 16618474SJose.Borrego@Sun.COM 16628474SJose.Borrego@Sun.COM static int 16638474SJose.Borrego@Sun.COM srvsvc_s_NetServerGetInfo(void *arg, ndr_xa_t *mxa) 16648474SJose.Borrego@Sun.COM { 16658474SJose.Borrego@Sun.COM struct mslm_NetServerGetInfo *param = arg; 16668474SJose.Borrego@Sun.COM struct mslm_SERVER_INFO_100 *info100; 16678474SJose.Borrego@Sun.COM struct mslm_SERVER_INFO_101 *info101; 16688474SJose.Borrego@Sun.COM struct mslm_SERVER_INFO_102 *info102; 16699832Samw@Sun.COM struct mslm_SERVER_INFO_502 *info502; 16709832Samw@Sun.COM struct mslm_SERVER_INFO_503 *info503; 16718474SJose.Borrego@Sun.COM char sys_comment[SMB_PI_MAX_COMMENT]; 16728474SJose.Borrego@Sun.COM char hostname[NETBIOS_NAME_SZ]; 167311963SAfshin.Ardakani@Sun.COM smb_version_t version; 16748474SJose.Borrego@Sun.COM 16758474SJose.Borrego@Sun.COM if (smb_getnetbiosname(hostname, sizeof (hostname)) != 0) { 16768474SJose.Borrego@Sun.COM netservergetinfo_no_memory: 16778474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetServerGetInfo)); 16788474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 16798474SJose.Borrego@Sun.COM } 16808474SJose.Borrego@Sun.COM 16818474SJose.Borrego@Sun.COM (void) smb_config_getstr(SMB_CI_SYS_CMNT, sys_comment, 16828474SJose.Borrego@Sun.COM sizeof (sys_comment)); 16838474SJose.Borrego@Sun.COM if (*sys_comment == '\0') 16848474SJose.Borrego@Sun.COM (void) strcpy(sys_comment, " "); 16858474SJose.Borrego@Sun.COM 168611963SAfshin.Ardakani@Sun.COM smb_config_get_version(&version); 168711963SAfshin.Ardakani@Sun.COM 16888474SJose.Borrego@Sun.COM switch (param->level) { 16898474SJose.Borrego@Sun.COM case 100: 16908474SJose.Borrego@Sun.COM info100 = NDR_NEW(mxa, struct mslm_SERVER_INFO_100); 16918474SJose.Borrego@Sun.COM if (info100 == NULL) 16928474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 16938474SJose.Borrego@Sun.COM 16948474SJose.Borrego@Sun.COM bzero(info100, sizeof (struct mslm_SERVER_INFO_100)); 16958474SJose.Borrego@Sun.COM info100->sv100_platform_id = SV_PLATFORM_ID_NT; 16968474SJose.Borrego@Sun.COM info100->sv100_name = (uint8_t *)NDR_STRDUP(mxa, hostname); 16978474SJose.Borrego@Sun.COM if (info100->sv100_name == NULL) 16988474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 16998474SJose.Borrego@Sun.COM 17008474SJose.Borrego@Sun.COM param->result.bufptr.bufptr100 = info100; 17018474SJose.Borrego@Sun.COM break; 17028474SJose.Borrego@Sun.COM 17038474SJose.Borrego@Sun.COM case 101: 17048474SJose.Borrego@Sun.COM info101 = NDR_NEW(mxa, struct mslm_SERVER_INFO_101); 17058474SJose.Borrego@Sun.COM if (info101 == NULL) 17068474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 17078474SJose.Borrego@Sun.COM 17088474SJose.Borrego@Sun.COM bzero(info101, sizeof (struct mslm_SERVER_INFO_101)); 17098474SJose.Borrego@Sun.COM info101->sv101_platform_id = SV_PLATFORM_ID_NT; 171011963SAfshin.Ardakani@Sun.COM info101->sv101_version_major = version.sv_major; 171111963SAfshin.Ardakani@Sun.COM info101->sv101_version_minor = version.sv_minor; 171211337SWilliam.Krier@Sun.COM info101->sv101_type = SV_TYPE_DEFAULT; 17138474SJose.Borrego@Sun.COM info101->sv101_name = (uint8_t *)NDR_STRDUP(mxa, hostname); 17148474SJose.Borrego@Sun.COM info101->sv101_comment 17158474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, sys_comment); 17168474SJose.Borrego@Sun.COM 17178474SJose.Borrego@Sun.COM if (info101->sv101_name == NULL || 17188474SJose.Borrego@Sun.COM info101->sv101_comment == NULL) 17198474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 17208474SJose.Borrego@Sun.COM 17218474SJose.Borrego@Sun.COM param->result.bufptr.bufptr101 = info101; 17228474SJose.Borrego@Sun.COM break; 17238474SJose.Borrego@Sun.COM 17248474SJose.Borrego@Sun.COM case 102: 17258474SJose.Borrego@Sun.COM info102 = NDR_NEW(mxa, struct mslm_SERVER_INFO_102); 17268474SJose.Borrego@Sun.COM if (info102 == NULL) 17278474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 17288474SJose.Borrego@Sun.COM 17298474SJose.Borrego@Sun.COM bzero(info102, sizeof (struct mslm_SERVER_INFO_102)); 17308474SJose.Borrego@Sun.COM info102->sv102_platform_id = SV_PLATFORM_ID_NT; 173111963SAfshin.Ardakani@Sun.COM info102->sv102_version_major = version.sv_major; 173211963SAfshin.Ardakani@Sun.COM info102->sv102_version_minor = version.sv_minor; 173311337SWilliam.Krier@Sun.COM info102->sv102_type = SV_TYPE_DEFAULT; 17348474SJose.Borrego@Sun.COM info102->sv102_name = (uint8_t *)NDR_STRDUP(mxa, hostname); 17358474SJose.Borrego@Sun.COM info102->sv102_comment 17368474SJose.Borrego@Sun.COM = (uint8_t *)NDR_STRDUP(mxa, sys_comment); 17378474SJose.Borrego@Sun.COM 17388474SJose.Borrego@Sun.COM /* 17398474SJose.Borrego@Sun.COM * The following level 102 fields are defaulted to zero 17408474SJose.Borrego@Sun.COM * by virtue of the call to bzero above. 17418474SJose.Borrego@Sun.COM * 17428474SJose.Borrego@Sun.COM * sv102_users 17438474SJose.Borrego@Sun.COM * sv102_disc 17448474SJose.Borrego@Sun.COM * sv102_hidden 17458474SJose.Borrego@Sun.COM * sv102_announce 17468474SJose.Borrego@Sun.COM * sv102_anndelta 17478474SJose.Borrego@Sun.COM * sv102_licenses 17488474SJose.Borrego@Sun.COM * sv102_userpath 17498474SJose.Borrego@Sun.COM */ 17508474SJose.Borrego@Sun.COM if (info102->sv102_name == NULL || 17518474SJose.Borrego@Sun.COM info102->sv102_comment == NULL) 17528474SJose.Borrego@Sun.COM goto netservergetinfo_no_memory; 17538474SJose.Borrego@Sun.COM 17548474SJose.Borrego@Sun.COM param->result.bufptr.bufptr102 = info102; 17558474SJose.Borrego@Sun.COM break; 17568474SJose.Borrego@Sun.COM 17579832Samw@Sun.COM case 502: 17589832Samw@Sun.COM info502 = NDR_NEW(mxa, struct mslm_SERVER_INFO_502); 17599832Samw@Sun.COM if (info502 == NULL) 17609832Samw@Sun.COM goto netservergetinfo_no_memory; 17619832Samw@Sun.COM 17629832Samw@Sun.COM bzero(info502, sizeof (struct mslm_SERVER_INFO_502)); 17639832Samw@Sun.COM param->result.bufptr.bufptr502 = info502; 17649832Samw@Sun.COM #ifdef SRVSVC_SATISFY_SMBTORTURE 17659832Samw@Sun.COM break; 17669832Samw@Sun.COM #else 17679832Samw@Sun.COM param->result.level = param->level; 17689832Samw@Sun.COM param->status = ERROR_ACCESS_DENIED; 17699832Samw@Sun.COM return (NDR_DRC_OK); 17709832Samw@Sun.COM #endif /* SRVSVC_SATISFY_SMBTORTURE */ 17719832Samw@Sun.COM 17729832Samw@Sun.COM case 503: 17739832Samw@Sun.COM info503 = NDR_NEW(mxa, struct mslm_SERVER_INFO_503); 17749832Samw@Sun.COM if (info503 == NULL) 17759832Samw@Sun.COM goto netservergetinfo_no_memory; 17769832Samw@Sun.COM 17779832Samw@Sun.COM bzero(info503, sizeof (struct mslm_SERVER_INFO_503)); 17789832Samw@Sun.COM param->result.bufptr.bufptr503 = info503; 17799832Samw@Sun.COM #ifdef SRVSVC_SATISFY_SMBTORTURE 17809832Samw@Sun.COM break; 17819832Samw@Sun.COM #else 17829832Samw@Sun.COM param->result.level = param->level; 17839832Samw@Sun.COM param->status = ERROR_ACCESS_DENIED; 17849832Samw@Sun.COM return (NDR_DRC_OK); 17859832Samw@Sun.COM #endif /* SRVSVC_SATISFY_SMBTORTURE */ 17869832Samw@Sun.COM 17878474SJose.Borrego@Sun.COM default: 17888474SJose.Borrego@Sun.COM bzero(¶m->result, 17898474SJose.Borrego@Sun.COM sizeof (struct mslm_NetServerGetInfo_result)); 17908474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 17918474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 17928474SJose.Borrego@Sun.COM } 17938474SJose.Borrego@Sun.COM 17948474SJose.Borrego@Sun.COM param->result.level = param->level; 17959832Samw@Sun.COM param->status = ERROR_SUCCESS; 17968474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 17978474SJose.Borrego@Sun.COM } 17988474SJose.Borrego@Sun.COM 17998474SJose.Borrego@Sun.COM /* 18008474SJose.Borrego@Sun.COM * NetRemoteTOD 18018474SJose.Borrego@Sun.COM * 18028474SJose.Borrego@Sun.COM * Returns information about the time of day on this server. 18038474SJose.Borrego@Sun.COM * 18048474SJose.Borrego@Sun.COM * typedef struct _TIME_OF_DAY_INFO { 18058474SJose.Borrego@Sun.COM * DWORD tod_elapsedt; // seconds since 00:00:00 January 1 1970 GMT 18068474SJose.Borrego@Sun.COM * DWORD tod_msecs; // arbitrary milliseconds (since reset) 18078474SJose.Borrego@Sun.COM * DWORD tod_hours; // current hour [0-23] 18088474SJose.Borrego@Sun.COM * DWORD tod_mins; // current minute [0-59] 18098474SJose.Borrego@Sun.COM * DWORD tod_secs; // current second [0-59] 18108474SJose.Borrego@Sun.COM * DWORD tod_hunds; // current hundredth (0.01) second [0-99] 18118474SJose.Borrego@Sun.COM * LONG tod_timezone; // time zone of the server 18128474SJose.Borrego@Sun.COM * DWORD tod_tinterval; // clock tick time interval 18138474SJose.Borrego@Sun.COM * DWORD tod_day; // day of the month [1-31] 18148474SJose.Borrego@Sun.COM * DWORD tod_month; // month of the year [1-12] 18158474SJose.Borrego@Sun.COM * DWORD tod_year; // current year 18168474SJose.Borrego@Sun.COM * DWORD tod_weekday; // day of the week since Sunday [0-6] 18178474SJose.Borrego@Sun.COM * } TIME_OF_DAY_INFO; 18188474SJose.Borrego@Sun.COM * 18198474SJose.Borrego@Sun.COM * The time zone of the server is calculated in minutes from Greenwich 18208474SJose.Borrego@Sun.COM * Mean Time (GMT). For time zones west of Greenwich, the value is 18218474SJose.Borrego@Sun.COM * positive; for time zones east of Greenwich, the value is negative. 18228474SJose.Borrego@Sun.COM * A value of -1 indicates that the time zone is undefined. 18238474SJose.Borrego@Sun.COM * 182410966SJordan.Brown@Sun.COM * Determine offset from GMT. If daylight saving time use altzone, 182510966SJordan.Brown@Sun.COM * otherwise use timezone. 182610966SJordan.Brown@Sun.COM * 18278474SJose.Borrego@Sun.COM * The clock tick value represents a resolution of one ten-thousandth 18288474SJose.Borrego@Sun.COM * (0.0001) second. 18298474SJose.Borrego@Sun.COM */ 18308474SJose.Borrego@Sun.COM static int 18318474SJose.Borrego@Sun.COM srvsvc_s_NetRemoteTOD(void *arg, ndr_xa_t *mxa) 18328474SJose.Borrego@Sun.COM { 18338474SJose.Borrego@Sun.COM struct mslm_NetRemoteTOD *param = arg; 18348474SJose.Borrego@Sun.COM struct mslm_TIME_OF_DAY_INFO *tod; 18358474SJose.Borrego@Sun.COM struct timeval time_val; 18368474SJose.Borrego@Sun.COM struct tm tm; 183710966SJordan.Brown@Sun.COM time_t gmtoff; 183810966SJordan.Brown@Sun.COM 18398474SJose.Borrego@Sun.COM 18408474SJose.Borrego@Sun.COM (void) gettimeofday(&time_val, 0); 18418474SJose.Borrego@Sun.COM (void) gmtime_r(&time_val.tv_sec, &tm); 18428474SJose.Borrego@Sun.COM 18438474SJose.Borrego@Sun.COM tod = NDR_NEW(mxa, struct mslm_TIME_OF_DAY_INFO); 18448474SJose.Borrego@Sun.COM if (tod == NULL) { 18458474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetRemoteTOD)); 18468474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 18478474SJose.Borrego@Sun.COM } 18488474SJose.Borrego@Sun.COM 184910966SJordan.Brown@Sun.COM bzero(tod, sizeof (struct mslm_TIME_OF_DAY_INFO)); 185010966SJordan.Brown@Sun.COM 18518474SJose.Borrego@Sun.COM tod->tod_elapsedt = time_val.tv_sec; 18528474SJose.Borrego@Sun.COM tod->tod_msecs = time_val.tv_usec; 18538474SJose.Borrego@Sun.COM tod->tod_hours = tm.tm_hour; 18548474SJose.Borrego@Sun.COM tod->tod_mins = tm.tm_min; 18558474SJose.Borrego@Sun.COM tod->tod_secs = tm.tm_sec; 18568474SJose.Borrego@Sun.COM tod->tod_hunds = 0; 18578474SJose.Borrego@Sun.COM tod->tod_tinterval = 1000; 18588474SJose.Borrego@Sun.COM tod->tod_day = tm.tm_mday; 18598474SJose.Borrego@Sun.COM tod->tod_month = tm.tm_mon+1; 18608474SJose.Borrego@Sun.COM tod->tod_year = tm.tm_year+1900; 18618474SJose.Borrego@Sun.COM tod->tod_weekday = tm.tm_wday; 18628474SJose.Borrego@Sun.COM 18638474SJose.Borrego@Sun.COM (void) localtime_r(&time_val.tv_sec, &tm); 186410966SJordan.Brown@Sun.COM gmtoff = (tm.tm_isdst) ? altzone : timezone; 186510966SJordan.Brown@Sun.COM tod->tod_timezone = gmtoff / SECSPERMIN; 18668474SJose.Borrego@Sun.COM 18678474SJose.Borrego@Sun.COM param->bufptr = tod; 18688474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 18698474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 18708474SJose.Borrego@Sun.COM } 18718474SJose.Borrego@Sun.COM 18728474SJose.Borrego@Sun.COM /* 18738474SJose.Borrego@Sun.COM * srvsvc_s_NetNameValidate 18748474SJose.Borrego@Sun.COM * 18758474SJose.Borrego@Sun.COM * Perform name validation. 18768474SJose.Borrego@Sun.COM * 18778474SJose.Borrego@Sun.COM * Returns Win32 error codes. 18788474SJose.Borrego@Sun.COM */ 18798474SJose.Borrego@Sun.COM /*ARGSUSED*/ 18808474SJose.Borrego@Sun.COM static int 18818474SJose.Borrego@Sun.COM srvsvc_s_NetNameValidate(void *arg, ndr_xa_t *mxa) 18828474SJose.Borrego@Sun.COM { 18838474SJose.Borrego@Sun.COM struct mslm_NetNameValidate *param = arg; 18848474SJose.Borrego@Sun.COM char *name; 188511337SWilliam.Krier@Sun.COM int maxlen; 18868474SJose.Borrego@Sun.COM int len; 18878474SJose.Borrego@Sun.COM 18888474SJose.Borrego@Sun.COM if ((name = (char *)param->pathname) == NULL) { 18898474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_PARAMETER; 18908474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 18918474SJose.Borrego@Sun.COM } 18928474SJose.Borrego@Sun.COM 18938474SJose.Borrego@Sun.COM switch (param->type) { 18948474SJose.Borrego@Sun.COM case NAMETYPE_SHARE: 189511337SWilliam.Krier@Sun.COM len = strlen(name); 189611337SWilliam.Krier@Sun.COM maxlen = (param->flags & NAMEFLAG_LM2) ? 189711337SWilliam.Krier@Sun.COM SMB_SHARE_OEMNAME_MAX : SMB_SHARE_NTNAME_MAX; 189811337SWilliam.Krier@Sun.COM 189911337SWilliam.Krier@Sun.COM if (len > maxlen) { 19008474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_NAME; 190111337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 190211337SWilliam.Krier@Sun.COM } 190311337SWilliam.Krier@Sun.COM 190411337SWilliam.Krier@Sun.COM param->status = smb_name_validate_share(name); 19058474SJose.Borrego@Sun.COM break; 19068474SJose.Borrego@Sun.COM 19078474SJose.Borrego@Sun.COM case NAMETYPE_USER: 190811337SWilliam.Krier@Sun.COM case NAMETYPE_GROUP: 190911337SWilliam.Krier@Sun.COM param->status = smb_name_validate_account(name); 191011337SWilliam.Krier@Sun.COM break; 191111337SWilliam.Krier@Sun.COM 191211337SWilliam.Krier@Sun.COM case NAMETYPE_DOMAIN: /* NetBIOS domain name */ 191311337SWilliam.Krier@Sun.COM param->status = smb_name_validate_nbdomain(name); 191411337SWilliam.Krier@Sun.COM break; 191511337SWilliam.Krier@Sun.COM 191611337SWilliam.Krier@Sun.COM case NAMETYPE_WORKGROUP: 191711337SWilliam.Krier@Sun.COM param->status = smb_name_validate_workgroup(name); 191811337SWilliam.Krier@Sun.COM break; 191911337SWilliam.Krier@Sun.COM 19208474SJose.Borrego@Sun.COM case NAMETYPE_PASSWORD: 19218474SJose.Borrego@Sun.COM case NAMETYPE_COMPUTER: 19228474SJose.Borrego@Sun.COM case NAMETYPE_EVENT: 19238474SJose.Borrego@Sun.COM case NAMETYPE_SERVICE: 19248474SJose.Borrego@Sun.COM case NAMETYPE_NET: 19258474SJose.Borrego@Sun.COM case NAMETYPE_MESSAGE: 19268474SJose.Borrego@Sun.COM case NAMETYPE_MESSAGEDEST: 19278474SJose.Borrego@Sun.COM case NAMETYPE_SHAREPASSWORD: 19288474SJose.Borrego@Sun.COM param->status = ERROR_NOT_SUPPORTED; 19298474SJose.Borrego@Sun.COM break; 19308474SJose.Borrego@Sun.COM 19318474SJose.Borrego@Sun.COM default: 19328474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_PARAMETER; 19338474SJose.Borrego@Sun.COM break; 19348474SJose.Borrego@Sun.COM } 19358474SJose.Borrego@Sun.COM 19368474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19378474SJose.Borrego@Sun.COM } 19388474SJose.Borrego@Sun.COM 19398474SJose.Borrego@Sun.COM /* 19408474SJose.Borrego@Sun.COM * srvsvc_s_NetShareAdd 19418474SJose.Borrego@Sun.COM * 19429832Samw@Sun.COM * Add a new share. Only power users groups can manage shares. 19438474SJose.Borrego@Sun.COM * 19448474SJose.Borrego@Sun.COM * This interface is used by the rmtshare command from the NT resource 19458474SJose.Borrego@Sun.COM * kit. Rmtshare allows a client to add or remove shares on a server 19468474SJose.Borrego@Sun.COM * from the client's command line. 19478474SJose.Borrego@Sun.COM * 19488474SJose.Borrego@Sun.COM * Returns Win32 error codes. 19498474SJose.Borrego@Sun.COM */ 19508474SJose.Borrego@Sun.COM static int 19518474SJose.Borrego@Sun.COM srvsvc_s_NetShareAdd(void *arg, ndr_xa_t *mxa) 19528474SJose.Borrego@Sun.COM { 19538474SJose.Borrego@Sun.COM static DWORD parm_err = 0; 19548474SJose.Borrego@Sun.COM DWORD parm_stat; 19558474SJose.Borrego@Sun.COM struct mslm_NetShareAdd *param = arg; 19569343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_2 *info2; 19579832Samw@Sun.COM struct mslm_NetShareInfo_502 *info502; 19588474SJose.Borrego@Sun.COM char realpath[MAXPATHLEN]; 19598474SJose.Borrego@Sun.COM int32_t native_os; 19609832Samw@Sun.COM uint8_t *sdbuf = NULL; 19619832Samw@Sun.COM uint32_t status; 19629832Samw@Sun.COM smb_share_t si; 19638474SJose.Borrego@Sun.COM 19648474SJose.Borrego@Sun.COM native_os = ndr_native_os(mxa); 19658474SJose.Borrego@Sun.COM 19668474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa)) { 19678474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 19688474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 19698474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19708474SJose.Borrego@Sun.COM } 19718474SJose.Borrego@Sun.COM 19728474SJose.Borrego@Sun.COM switch (param->level) { 19738474SJose.Borrego@Sun.COM case 2: 19749832Samw@Sun.COM info2 = (struct mslm_NetShareInfo_2 *)param->info.un.info2; 19758474SJose.Borrego@Sun.COM break; 19768474SJose.Borrego@Sun.COM 19778474SJose.Borrego@Sun.COM case 502: 19789832Samw@Sun.COM info502 = (struct mslm_NetShareInfo_502 *) 19799832Samw@Sun.COM param->info.un.info502; 19809832Samw@Sun.COM sdbuf = info502->shi502_security_descriptor; 19819832Samw@Sun.COM info2 = (struct mslm_NetShareInfo_2 *)info502; 19828474SJose.Borrego@Sun.COM break; 19838474SJose.Borrego@Sun.COM 19848474SJose.Borrego@Sun.COM default: 19858474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 19868474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 19878474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19888474SJose.Borrego@Sun.COM } 19898474SJose.Borrego@Sun.COM 19908474SJose.Borrego@Sun.COM if (info2->shi2_netname == NULL || info2->shi2_path == NULL) { 19918474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 19928474SJose.Borrego@Sun.COM param->status = NERR_NetNameNotFound; 19938474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 19948474SJose.Borrego@Sun.COM } 19958474SJose.Borrego@Sun.COM 19968474SJose.Borrego@Sun.COM if (smb_shr_is_restricted((char *)info2->shi2_netname)) { 19978474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 19988474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 19998474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20008474SJose.Borrego@Sun.COM } 20018474SJose.Borrego@Sun.COM 20029343SAfshin.Ardakani@Sun.COM if (info2->shi2_comment == NULL) 20039343SAfshin.Ardakani@Sun.COM info2->shi2_comment = (uint8_t *)""; 20048474SJose.Borrego@Sun.COM 20058474SJose.Borrego@Sun.COM /* 20068474SJose.Borrego@Sun.COM * Derive the real path which will be stored in the 20078474SJose.Borrego@Sun.COM * directory field of the smb_share_t structure 20088474SJose.Borrego@Sun.COM * from the path field in this RPC request. 20098474SJose.Borrego@Sun.COM */ 20108474SJose.Borrego@Sun.COM parm_stat = smb_shr_get_realpath((const char *)info2->shi2_path, 20118474SJose.Borrego@Sun.COM realpath, MAXPATHLEN); 20128474SJose.Borrego@Sun.COM 20138474SJose.Borrego@Sun.COM if (parm_stat != NERR_Success) { 20148474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareAdd)); 20158474SJose.Borrego@Sun.COM param->status = parm_stat; 20168474SJose.Borrego@Sun.COM param->parm_err 20178474SJose.Borrego@Sun.COM = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; 20188474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20198474SJose.Borrego@Sun.COM } 20208474SJose.Borrego@Sun.COM 20218474SJose.Borrego@Sun.COM param->status = srvsvc_sa_add((char *)info2->shi2_netname, realpath, 20229343SAfshin.Ardakani@Sun.COM (char *)info2->shi2_comment); 20238474SJose.Borrego@Sun.COM if (param->status == NERR_Success) { 20249832Samw@Sun.COM status = smb_shr_get((char *)info2->shi2_netname, &si); 20259832Samw@Sun.COM 20269832Samw@Sun.COM if ((sdbuf != NULL) && (status == NERR_Success)) 20279832Samw@Sun.COM (void) srvsvc_sd_set(&si, sdbuf); 20288474SJose.Borrego@Sun.COM } 20298474SJose.Borrego@Sun.COM param->parm_err = (native_os == NATIVE_OS_WIN95) ? 0 : &parm_err; 20308474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20318474SJose.Borrego@Sun.COM } 20328474SJose.Borrego@Sun.COM 20338474SJose.Borrego@Sun.COM /* 203410122SJordan.Brown@Sun.COM * srvsvc_estimate_limit 20358474SJose.Borrego@Sun.COM * 20368474SJose.Borrego@Sun.COM * Estimate the number of objects that will fit in prefmaxlen. 203710122SJordan.Brown@Sun.COM * nlimit is adjusted here. 20388474SJose.Borrego@Sun.COM */ 203910122SJordan.Brown@Sun.COM static void 204010122SJordan.Brown@Sun.COM srvsvc_estimate_limit(smb_svcenum_t *se, uint32_t obj_size) 20418474SJose.Borrego@Sun.COM { 20428474SJose.Borrego@Sun.COM DWORD max_cnt; 20438474SJose.Borrego@Sun.COM 204410122SJordan.Brown@Sun.COM if (obj_size == 0) { 204510122SJordan.Brown@Sun.COM se->se_nlimit = 0; 204610122SJordan.Brown@Sun.COM return; 204710122SJordan.Brown@Sun.COM } 204810122SJordan.Brown@Sun.COM 204910122SJordan.Brown@Sun.COM if ((max_cnt = (se->se_prefmaxlen / obj_size)) == 0) { 205010122SJordan.Brown@Sun.COM se->se_nlimit = 0; 205110122SJordan.Brown@Sun.COM return; 205210122SJordan.Brown@Sun.COM } 205310122SJordan.Brown@Sun.COM 205410122SJordan.Brown@Sun.COM if (se->se_ntotal > max_cnt) 205510122SJordan.Brown@Sun.COM se->se_nlimit = max_cnt; 205610122SJordan.Brown@Sun.COM else 205710122SJordan.Brown@Sun.COM se->se_nlimit = se->se_ntotal; 20588474SJose.Borrego@Sun.COM } 20598474SJose.Borrego@Sun.COM 20608474SJose.Borrego@Sun.COM /* 20618474SJose.Borrego@Sun.COM * srvsvc_s_NetShareEnum 20628474SJose.Borrego@Sun.COM * 20638474SJose.Borrego@Sun.COM * Enumerate all shares (see also NetShareEnumSticky). 20648474SJose.Borrego@Sun.COM * 20658474SJose.Borrego@Sun.COM * Request for various levels of information about our shares. 20668474SJose.Borrego@Sun.COM * Level 0: share names. 20678474SJose.Borrego@Sun.COM * Level 1: share name, share type and comment field. 20688474SJose.Borrego@Sun.COM * Level 2: everything that we know about the shares. 206910504SKeyur.Desai@Sun.COM * Level 501: level 1 + flags. 20708474SJose.Borrego@Sun.COM * Level 502: level 2 + security descriptor. 20718474SJose.Borrego@Sun.COM */ 20728474SJose.Borrego@Sun.COM static int 20738474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnum(void *arg, ndr_xa_t *mxa) 20748474SJose.Borrego@Sun.COM { 20758474SJose.Borrego@Sun.COM struct mslm_NetShareEnum *param = arg; 207610122SJordan.Brown@Sun.COM srvsvc_infonres_t *infonres; 207710122SJordan.Brown@Sun.COM smb_svcenum_t se; 20788474SJose.Borrego@Sun.COM DWORD status; 20798474SJose.Borrego@Sun.COM 208010122SJordan.Brown@Sun.COM infonres = NDR_NEW(mxa, srvsvc_infonres_t); 20818474SJose.Borrego@Sun.COM if (infonres == NULL) { 20828474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 20838474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 20848474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 20858474SJose.Borrego@Sun.COM } 20868474SJose.Borrego@Sun.COM 20878474SJose.Borrego@Sun.COM infonres->entriesread = 0; 20888474SJose.Borrego@Sun.COM infonres->entries = NULL; 20898474SJose.Borrego@Sun.COM param->result.level = param->level; 20908474SJose.Borrego@Sun.COM param->result.bufptr.p = infonres; 20918474SJose.Borrego@Sun.COM 209210122SJordan.Brown@Sun.COM bzero(&se, sizeof (smb_svcenum_t)); 209310122SJordan.Brown@Sun.COM se.se_type = SMB_SVCENUM_TYPE_SHARE; 20948474SJose.Borrego@Sun.COM se.se_level = param->level; 209510122SJordan.Brown@Sun.COM se.se_ntotal = smb_shr_count(); 209610122SJordan.Brown@Sun.COM se.se_nlimit = se.se_ntotal; 20978474SJose.Borrego@Sun.COM 20988474SJose.Borrego@Sun.COM if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN || 20998474SJose.Borrego@Sun.COM param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN) 21008474SJose.Borrego@Sun.COM se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN; 21018474SJose.Borrego@Sun.COM else 21028474SJose.Borrego@Sun.COM se.se_prefmaxlen = param->prefmaxlen; 21038474SJose.Borrego@Sun.COM 21048474SJose.Borrego@Sun.COM if (param->resume_handle) { 210510122SJordan.Brown@Sun.COM se.se_resume = *param->resume_handle; 210610122SJordan.Brown@Sun.COM se.se_nskip = se.se_resume; 210710122SJordan.Brown@Sun.COM *param->resume_handle = 0; 21088474SJose.Borrego@Sun.COM } 21098474SJose.Borrego@Sun.COM 21108474SJose.Borrego@Sun.COM switch (param->level) { 21118474SJose.Borrego@Sun.COM case 0: 21128474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 0); 21138474SJose.Borrego@Sun.COM break; 21148474SJose.Borrego@Sun.COM 21158474SJose.Borrego@Sun.COM case 1: 21168474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 0); 21178474SJose.Borrego@Sun.COM break; 21188474SJose.Borrego@Sun.COM 21198474SJose.Borrego@Sun.COM case 2: 21208474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 0); 21218474SJose.Borrego@Sun.COM break; 21228474SJose.Borrego@Sun.COM 21238474SJose.Borrego@Sun.COM case 501: 21248474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel501(mxa, infonres, &se, 0); 21258474SJose.Borrego@Sun.COM break; 21268474SJose.Borrego@Sun.COM 21278474SJose.Borrego@Sun.COM case 502: 21288474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 0); 21298474SJose.Borrego@Sun.COM break; 21308474SJose.Borrego@Sun.COM 21318474SJose.Borrego@Sun.COM default: 21329832Samw@Sun.COM status = ERROR_INVALID_LEVEL; 21338474SJose.Borrego@Sun.COM break; 21348474SJose.Borrego@Sun.COM } 21358474SJose.Borrego@Sun.COM 21368474SJose.Borrego@Sun.COM if (status != 0) { 21378474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 21388474SJose.Borrego@Sun.COM param->status = status; 21398474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 21408474SJose.Borrego@Sun.COM } 21418474SJose.Borrego@Sun.COM 214210122SJordan.Brown@Sun.COM if (se.se_nlimit == 0) { 21438474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 21448474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 21458474SJose.Borrego@Sun.COM } 21468474SJose.Borrego@Sun.COM 21478474SJose.Borrego@Sun.COM if (param->resume_handle && 21488474SJose.Borrego@Sun.COM param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) { 214910122SJordan.Brown@Sun.COM if (se.se_resume < se.se_ntotal) { 215010122SJordan.Brown@Sun.COM *param->resume_handle = se.se_resume; 21518474SJose.Borrego@Sun.COM status = ERROR_MORE_DATA; 21528474SJose.Borrego@Sun.COM } 21538474SJose.Borrego@Sun.COM } 21548474SJose.Borrego@Sun.COM 215510122SJordan.Brown@Sun.COM param->totalentries = se.se_ntotal; 21568474SJose.Borrego@Sun.COM param->status = status; 21578474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 21588474SJose.Borrego@Sun.COM } 21598474SJose.Borrego@Sun.COM 21608474SJose.Borrego@Sun.COM /* 21618474SJose.Borrego@Sun.COM * srvsvc_s_NetShareEnumSticky 21628474SJose.Borrego@Sun.COM * 21638474SJose.Borrego@Sun.COM * Enumerate sticky shares: all shares except those marked STYPE_SPECIAL. 21648474SJose.Borrego@Sun.COM * Except for excluding STYPE_SPECIAL shares, NetShareEnumSticky is the 21658474SJose.Borrego@Sun.COM * same as NetShareEnum. 21668474SJose.Borrego@Sun.COM * 21678474SJose.Borrego@Sun.COM * Request for various levels of information about our shares. 21688474SJose.Borrego@Sun.COM * Level 0: share names. 21698474SJose.Borrego@Sun.COM * Level 1: share name, share type and comment field. 21708474SJose.Borrego@Sun.COM * Level 2: everything that we know about the shares. 21718474SJose.Borrego@Sun.COM * Level 501: not valid for this request. 21728474SJose.Borrego@Sun.COM * Level 502: level 2 + security descriptor. 21738474SJose.Borrego@Sun.COM * 21748474SJose.Borrego@Sun.COM * We set n_skip to resume_handle, which is used to find the appropriate 21758474SJose.Borrego@Sun.COM * place to resume. The resume_handle is similar to the readdir cookie. 21768474SJose.Borrego@Sun.COM */ 21778474SJose.Borrego@Sun.COM static int 21788474SJose.Borrego@Sun.COM srvsvc_s_NetShareEnumSticky(void *arg, ndr_xa_t *mxa) 21798474SJose.Borrego@Sun.COM { 21808474SJose.Borrego@Sun.COM struct mslm_NetShareEnum *param = arg; 218110122SJordan.Brown@Sun.COM srvsvc_infonres_t *infonres; 218210122SJordan.Brown@Sun.COM smb_svcenum_t se; 21838474SJose.Borrego@Sun.COM DWORD status; 21848474SJose.Borrego@Sun.COM 218510122SJordan.Brown@Sun.COM infonres = NDR_NEW(mxa, srvsvc_infonres_t); 21868474SJose.Borrego@Sun.COM if (infonres == NULL) { 21878474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 21888474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 21898474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 21908474SJose.Borrego@Sun.COM } 21918474SJose.Borrego@Sun.COM 21928474SJose.Borrego@Sun.COM infonres->entriesread = 0; 21938474SJose.Borrego@Sun.COM infonres->entries = NULL; 21948474SJose.Borrego@Sun.COM param->result.level = param->level; 21958474SJose.Borrego@Sun.COM param->result.bufptr.p = infonres; 21968474SJose.Borrego@Sun.COM 219710122SJordan.Brown@Sun.COM bzero(&se, sizeof (smb_svcenum_t)); 219810122SJordan.Brown@Sun.COM se.se_type = SMB_SVCENUM_TYPE_SHARE; 21998474SJose.Borrego@Sun.COM se.se_level = param->level; 220010122SJordan.Brown@Sun.COM se.se_ntotal = smb_shr_count(); 220110122SJordan.Brown@Sun.COM se.se_nlimit = se.se_ntotal; 22028474SJose.Borrego@Sun.COM 22038474SJose.Borrego@Sun.COM if (param->prefmaxlen == SMB_SRVSVC_MAXPREFLEN || 22048474SJose.Borrego@Sun.COM param->prefmaxlen > SMB_SRVSVC_MAXBUFLEN) 22058474SJose.Borrego@Sun.COM se.se_prefmaxlen = SMB_SRVSVC_MAXBUFLEN; 22068474SJose.Borrego@Sun.COM else 22078474SJose.Borrego@Sun.COM se.se_prefmaxlen = param->prefmaxlen; 22088474SJose.Borrego@Sun.COM 22098474SJose.Borrego@Sun.COM if (param->resume_handle) { 221010122SJordan.Brown@Sun.COM se.se_resume = *param->resume_handle; 221110122SJordan.Brown@Sun.COM se.se_nskip = se.se_resume; 221210122SJordan.Brown@Sun.COM *param->resume_handle = 0; 22138474SJose.Borrego@Sun.COM } 22148474SJose.Borrego@Sun.COM 22158474SJose.Borrego@Sun.COM switch (param->level) { 22168474SJose.Borrego@Sun.COM case 0: 22178474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel0(mxa, infonres, &se, 1); 22188474SJose.Borrego@Sun.COM break; 22198474SJose.Borrego@Sun.COM 22208474SJose.Borrego@Sun.COM case 1: 22218474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel1(mxa, infonres, &se, 1); 22228474SJose.Borrego@Sun.COM break; 22238474SJose.Borrego@Sun.COM 22248474SJose.Borrego@Sun.COM case 2: 22258474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel2(mxa, infonres, &se, 1); 22268474SJose.Borrego@Sun.COM break; 22278474SJose.Borrego@Sun.COM 22288474SJose.Borrego@Sun.COM case 502: 22298474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumLevel502(mxa, infonres, &se, 1); 22308474SJose.Borrego@Sun.COM break; 22318474SJose.Borrego@Sun.COM 22329832Samw@Sun.COM case 501: 22338474SJose.Borrego@Sun.COM default: 22348474SJose.Borrego@Sun.COM status = ERROR_INVALID_LEVEL; 22358474SJose.Borrego@Sun.COM break; 22368474SJose.Borrego@Sun.COM } 22378474SJose.Borrego@Sun.COM 22388474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) { 22398474SJose.Borrego@Sun.COM bzero(param, sizeof (struct mslm_NetShareEnum)); 22408474SJose.Borrego@Sun.COM param->status = status; 22418474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 22428474SJose.Borrego@Sun.COM } 22438474SJose.Borrego@Sun.COM 224410122SJordan.Brown@Sun.COM if (se.se_nlimit == 0) { 22458474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 22468474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 22478474SJose.Borrego@Sun.COM } 22488474SJose.Borrego@Sun.COM 22498474SJose.Borrego@Sun.COM if (param->resume_handle && 22508474SJose.Borrego@Sun.COM param->prefmaxlen != SMB_SRVSVC_MAXPREFLEN) { 225110122SJordan.Brown@Sun.COM if (se.se_resume < se.se_ntotal) { 225210122SJordan.Brown@Sun.COM *param->resume_handle = se.se_resume; 22538474SJose.Borrego@Sun.COM status = ERROR_MORE_DATA; 22548474SJose.Borrego@Sun.COM } 22558474SJose.Borrego@Sun.COM } 22568474SJose.Borrego@Sun.COM 225710122SJordan.Brown@Sun.COM param->totalentries = se.se_ntotal; 22588474SJose.Borrego@Sun.COM param->status = status; 22598474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 22608474SJose.Borrego@Sun.COM } 22618474SJose.Borrego@Sun.COM 22628474SJose.Borrego@Sun.COM /* 22638474SJose.Borrego@Sun.COM * NetShareEnum Level 0 22648474SJose.Borrego@Sun.COM */ 22658474SJose.Borrego@Sun.COM static DWORD 226610122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel0(ndr_xa_t *mxa, srvsvc_infonres_t *infonres, 226710122SJordan.Brown@Sun.COM smb_svcenum_t *se, int sticky) 22688474SJose.Borrego@Sun.COM { 22699343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_0 *info0; 22708474SJose.Borrego@Sun.COM smb_shriter_t iterator; 22718474SJose.Borrego@Sun.COM smb_share_t *si; 22728474SJose.Borrego@Sun.COM DWORD status; 22738474SJose.Borrego@Sun.COM 227410122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 227510122SJordan.Brown@Sun.COM sizeof (struct mslm_NetShareInfo_0) + MAXNAMELEN); 227610122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 22778474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 22788474SJose.Borrego@Sun.COM 227910122SJordan.Brown@Sun.COM info0 = NDR_NEWN(mxa, struct mslm_NetShareInfo_0, se->se_nlimit); 22808474SJose.Borrego@Sun.COM if (info0 == NULL) 22818474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 22828474SJose.Borrego@Sun.COM 22838474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 22848474SJose.Borrego@Sun.COM 228510122SJordan.Brown@Sun.COM se->se_nitems = 0; 22868474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != NULL) { 228710122SJordan.Brown@Sun.COM if (se->se_nskip > 0) { 228810122SJordan.Brown@Sun.COM --se->se_nskip; 22898474SJose.Borrego@Sun.COM continue; 22908474SJose.Borrego@Sun.COM } 22918474SJose.Borrego@Sun.COM 229210122SJordan.Brown@Sun.COM ++se->se_resume; 22938474SJose.Borrego@Sun.COM 22948474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 22958474SJose.Borrego@Sun.COM continue; 22968474SJose.Borrego@Sun.COM 22978474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 22988474SJose.Borrego@Sun.COM continue; 22998474SJose.Borrego@Sun.COM 230010122SJordan.Brown@Sun.COM if (se->se_nitems >= se->se_nlimit) { 230110122SJordan.Brown@Sun.COM se->se_nitems = se->se_nlimit; 23028474SJose.Borrego@Sun.COM break; 23038474SJose.Borrego@Sun.COM } 23048474SJose.Borrego@Sun.COM 23058474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info0); 23068474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 23078474SJose.Borrego@Sun.COM break; 23088474SJose.Borrego@Sun.COM 230910122SJordan.Brown@Sun.COM ++se->se_nitems; 23108474SJose.Borrego@Sun.COM } 23118474SJose.Borrego@Sun.COM 231210122SJordan.Brown@Sun.COM if (se->se_nitems < se->se_nlimit) { 23138474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info0)) 231410122SJordan.Brown@Sun.COM ++se->se_nitems; 23158474SJose.Borrego@Sun.COM } 23168474SJose.Borrego@Sun.COM 231710122SJordan.Brown@Sun.COM infonres->entriesread = se->se_nitems; 23188474SJose.Borrego@Sun.COM infonres->entries = info0; 23198474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 23208474SJose.Borrego@Sun.COM } 23218474SJose.Borrego@Sun.COM 23228474SJose.Borrego@Sun.COM /* 23238474SJose.Borrego@Sun.COM * NetShareEnum Level 1 23248474SJose.Borrego@Sun.COM */ 23258474SJose.Borrego@Sun.COM static DWORD 232610122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel1(ndr_xa_t *mxa, srvsvc_infonres_t *infonres, 232710122SJordan.Brown@Sun.COM smb_svcenum_t *se, int sticky) 23288474SJose.Borrego@Sun.COM { 23299343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1 *info1; 23308474SJose.Borrego@Sun.COM smb_shriter_t iterator; 23318474SJose.Borrego@Sun.COM smb_share_t *si; 23328474SJose.Borrego@Sun.COM DWORD status; 23338474SJose.Borrego@Sun.COM 233410122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 233510122SJordan.Brown@Sun.COM sizeof (struct mslm_NetShareInfo_1) + MAXNAMELEN); 233610122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 23378474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 23388474SJose.Borrego@Sun.COM 233910122SJordan.Brown@Sun.COM info1 = NDR_NEWN(mxa, struct mslm_NetShareInfo_1, se->se_nlimit); 23408474SJose.Borrego@Sun.COM if (info1 == NULL) 23418474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 23428474SJose.Borrego@Sun.COM 23438474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 23448474SJose.Borrego@Sun.COM 234510122SJordan.Brown@Sun.COM se->se_nitems = 0; 23468474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != 0) { 234710122SJordan.Brown@Sun.COM if (se->se_nskip > 0) { 234810122SJordan.Brown@Sun.COM --se->se_nskip; 23498474SJose.Borrego@Sun.COM continue; 23508474SJose.Borrego@Sun.COM } 23518474SJose.Borrego@Sun.COM 235210122SJordan.Brown@Sun.COM ++se->se_resume; 23538474SJose.Borrego@Sun.COM 23548474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 23558474SJose.Borrego@Sun.COM continue; 23568474SJose.Borrego@Sun.COM 23578474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 23588474SJose.Borrego@Sun.COM continue; 23598474SJose.Borrego@Sun.COM 236010122SJordan.Brown@Sun.COM if (se->se_nitems >= se->se_nlimit) { 236110122SJordan.Brown@Sun.COM se->se_nitems = se->se_nlimit; 23628474SJose.Borrego@Sun.COM break; 23638474SJose.Borrego@Sun.COM } 23648474SJose.Borrego@Sun.COM 23658474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info1); 23668474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 23678474SJose.Borrego@Sun.COM break; 23688474SJose.Borrego@Sun.COM 236910122SJordan.Brown@Sun.COM ++se->se_nitems; 23708474SJose.Borrego@Sun.COM } 23718474SJose.Borrego@Sun.COM 237210122SJordan.Brown@Sun.COM if (se->se_nitems < se->se_nlimit) { 23738474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info1)) 237410122SJordan.Brown@Sun.COM ++se->se_nitems; 23758474SJose.Borrego@Sun.COM } 23768474SJose.Borrego@Sun.COM 237710122SJordan.Brown@Sun.COM infonres->entriesread = se->se_nitems; 23788474SJose.Borrego@Sun.COM infonres->entries = info1; 23798474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 23808474SJose.Borrego@Sun.COM } 23818474SJose.Borrego@Sun.COM 23828474SJose.Borrego@Sun.COM /* 23838474SJose.Borrego@Sun.COM * NetShareEnum Level 2 23848474SJose.Borrego@Sun.COM */ 23858474SJose.Borrego@Sun.COM static DWORD 238610122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel2(ndr_xa_t *mxa, srvsvc_infonres_t *infonres, 238710122SJordan.Brown@Sun.COM smb_svcenum_t *se, int sticky) 23888474SJose.Borrego@Sun.COM { 23899343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_2 *info2; 23908474SJose.Borrego@Sun.COM smb_shriter_t iterator; 23918474SJose.Borrego@Sun.COM smb_share_t *si; 23928474SJose.Borrego@Sun.COM DWORD status; 23938474SJose.Borrego@Sun.COM 239410122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 239510122SJordan.Brown@Sun.COM sizeof (struct mslm_NetShareInfo_2) + MAXNAMELEN); 239610122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 23978474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 23988474SJose.Borrego@Sun.COM 239910122SJordan.Brown@Sun.COM info2 = NDR_NEWN(mxa, struct mslm_NetShareInfo_2, se->se_nlimit); 24008474SJose.Borrego@Sun.COM if (info2 == NULL) 24018474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 24028474SJose.Borrego@Sun.COM 24038474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 24048474SJose.Borrego@Sun.COM 240510122SJordan.Brown@Sun.COM se->se_nitems = 0; 24068474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != 0) { 240710122SJordan.Brown@Sun.COM if (se->se_nskip > 0) { 240810122SJordan.Brown@Sun.COM --se->se_nskip; 24098474SJose.Borrego@Sun.COM continue; 24108474SJose.Borrego@Sun.COM } 24118474SJose.Borrego@Sun.COM 241210122SJordan.Brown@Sun.COM ++se->se_resume; 24138474SJose.Borrego@Sun.COM 24148474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 24158474SJose.Borrego@Sun.COM continue; 24168474SJose.Borrego@Sun.COM 24178474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 24188474SJose.Borrego@Sun.COM continue; 24198474SJose.Borrego@Sun.COM 242010122SJordan.Brown@Sun.COM if (se->se_nitems >= se->se_nlimit) { 242110122SJordan.Brown@Sun.COM se->se_nitems = se->se_nlimit; 24228474SJose.Borrego@Sun.COM break; 24238474SJose.Borrego@Sun.COM } 24248474SJose.Borrego@Sun.COM 24258474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info2); 24268474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 24278474SJose.Borrego@Sun.COM break; 24288474SJose.Borrego@Sun.COM 242910122SJordan.Brown@Sun.COM ++se->se_nitems; 24308474SJose.Borrego@Sun.COM } 24318474SJose.Borrego@Sun.COM 243210122SJordan.Brown@Sun.COM if (se->se_nitems < se->se_nlimit) { 24338474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info2)) 243410122SJordan.Brown@Sun.COM ++se->se_nitems; 24358474SJose.Borrego@Sun.COM } 24368474SJose.Borrego@Sun.COM 243710122SJordan.Brown@Sun.COM infonres->entriesread = se->se_nitems; 24388474SJose.Borrego@Sun.COM infonres->entries = info2; 24398474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 24408474SJose.Borrego@Sun.COM } 24418474SJose.Borrego@Sun.COM 24428474SJose.Borrego@Sun.COM /* 24438474SJose.Borrego@Sun.COM * NetShareEnum Level 501 24448474SJose.Borrego@Sun.COM */ 24458474SJose.Borrego@Sun.COM static DWORD 244610122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel501(ndr_xa_t *mxa, srvsvc_infonres_t *infonres, 244710122SJordan.Brown@Sun.COM smb_svcenum_t *se, int sticky) 24488474SJose.Borrego@Sun.COM { 24499343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_501 *info501; 24508474SJose.Borrego@Sun.COM smb_shriter_t iterator; 24518474SJose.Borrego@Sun.COM smb_share_t *si; 24528474SJose.Borrego@Sun.COM DWORD status; 24538474SJose.Borrego@Sun.COM 245410122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 245510122SJordan.Brown@Sun.COM sizeof (struct mslm_NetShareInfo_501) + MAXNAMELEN); 245610122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 24578474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 24588474SJose.Borrego@Sun.COM 24599343SAfshin.Ardakani@Sun.COM info501 = NDR_NEWN(mxa, struct mslm_NetShareInfo_501, 246010122SJordan.Brown@Sun.COM se->se_nlimit); 24618474SJose.Borrego@Sun.COM if (info501 == NULL) 24628474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 24638474SJose.Borrego@Sun.COM 24648474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 24658474SJose.Borrego@Sun.COM 246610122SJordan.Brown@Sun.COM se->se_nitems = 0; 24678474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != 0) { 246810122SJordan.Brown@Sun.COM if (se->se_nskip > 0) { 246910122SJordan.Brown@Sun.COM --se->se_nskip; 24708474SJose.Borrego@Sun.COM continue; 24718474SJose.Borrego@Sun.COM } 24728474SJose.Borrego@Sun.COM 247310122SJordan.Brown@Sun.COM ++se->se_resume; 24748474SJose.Borrego@Sun.COM 24758474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 24768474SJose.Borrego@Sun.COM continue; 24778474SJose.Borrego@Sun.COM 24788474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 24798474SJose.Borrego@Sun.COM continue; 24808474SJose.Borrego@Sun.COM 248110122SJordan.Brown@Sun.COM if (se->se_nitems >= se->se_nlimit) { 248210122SJordan.Brown@Sun.COM se->se_nitems = se->se_nlimit; 24838474SJose.Borrego@Sun.COM break; 24848474SJose.Borrego@Sun.COM } 24858474SJose.Borrego@Sun.COM 24868474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info501); 24878474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 24888474SJose.Borrego@Sun.COM break; 24898474SJose.Borrego@Sun.COM 249010122SJordan.Brown@Sun.COM ++se->se_nitems; 24918474SJose.Borrego@Sun.COM } 24928474SJose.Borrego@Sun.COM 249310122SJordan.Brown@Sun.COM if (se->se_nitems < se->se_nlimit) { 24948474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info501)) 249510122SJordan.Brown@Sun.COM ++se->se_nitems; 24968474SJose.Borrego@Sun.COM } 24978474SJose.Borrego@Sun.COM 249810122SJordan.Brown@Sun.COM infonres->entriesread = se->se_nitems; 24998474SJose.Borrego@Sun.COM infonres->entries = info501; 25008474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 25018474SJose.Borrego@Sun.COM } 25028474SJose.Borrego@Sun.COM 25038474SJose.Borrego@Sun.COM /* 25048474SJose.Borrego@Sun.COM * NetShareEnum Level 502 25058474SJose.Borrego@Sun.COM */ 25068474SJose.Borrego@Sun.COM static DWORD 250710122SJordan.Brown@Sun.COM mlsvc_NetShareEnumLevel502(ndr_xa_t *mxa, srvsvc_infonres_t *infonres, 250810122SJordan.Brown@Sun.COM smb_svcenum_t *se, int sticky) 25098474SJose.Borrego@Sun.COM { 25109343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_502 *info502; 25118474SJose.Borrego@Sun.COM smb_shriter_t iterator; 25128474SJose.Borrego@Sun.COM smb_share_t *si; 25138474SJose.Borrego@Sun.COM DWORD status; 25148474SJose.Borrego@Sun.COM 251510122SJordan.Brown@Sun.COM srvsvc_estimate_limit(se, 251610122SJordan.Brown@Sun.COM sizeof (struct mslm_NetShareInfo_502) + MAXNAMELEN); 251710122SJordan.Brown@Sun.COM if (se->se_nlimit == 0) 25188474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 25198474SJose.Borrego@Sun.COM 25209343SAfshin.Ardakani@Sun.COM info502 = NDR_NEWN(mxa, struct mslm_NetShareInfo_502, 252110122SJordan.Brown@Sun.COM se->se_nlimit); 25228474SJose.Borrego@Sun.COM if (info502 == NULL) 25238474SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 25248474SJose.Borrego@Sun.COM 25258474SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 25268474SJose.Borrego@Sun.COM 252710122SJordan.Brown@Sun.COM se->se_nitems = 0; 25288474SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != NULL) { 252910122SJordan.Brown@Sun.COM if (se->se_nskip > 0) { 253010122SJordan.Brown@Sun.COM --se->se_nskip; 25318474SJose.Borrego@Sun.COM continue; 25328474SJose.Borrego@Sun.COM } 25338474SJose.Borrego@Sun.COM 253410122SJordan.Brown@Sun.COM ++se->se_resume; 25358474SJose.Borrego@Sun.COM 25368474SJose.Borrego@Sun.COM if (sticky && (si->shr_flags & SMB_SHRF_TRANS)) 25378474SJose.Borrego@Sun.COM continue; 25388474SJose.Borrego@Sun.COM 25398474SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 25408474SJose.Borrego@Sun.COM continue; 25418474SJose.Borrego@Sun.COM 254210122SJordan.Brown@Sun.COM if (se->se_nitems >= se->se_nlimit) { 254310122SJordan.Brown@Sun.COM se->se_nitems = se->se_nlimit; 25448474SJose.Borrego@Sun.COM break; 25458474SJose.Borrego@Sun.COM } 25468474SJose.Borrego@Sun.COM 25478474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, si, (void *)info502); 25488474SJose.Borrego@Sun.COM if (status != ERROR_SUCCESS) 25498474SJose.Borrego@Sun.COM break; 25508474SJose.Borrego@Sun.COM 255110122SJordan.Brown@Sun.COM ++se->se_nitems; 25528474SJose.Borrego@Sun.COM } 25538474SJose.Borrego@Sun.COM 255410122SJordan.Brown@Sun.COM if (se->se_nitems < se->se_nlimit) { 25558474SJose.Borrego@Sun.COM if (srvsvc_add_autohome(mxa, se, (void *)info502)) 255610122SJordan.Brown@Sun.COM ++se->se_nitems; 25578474SJose.Borrego@Sun.COM } 25588474SJose.Borrego@Sun.COM 255910122SJordan.Brown@Sun.COM infonres->entriesread = se->se_nitems; 25608474SJose.Borrego@Sun.COM infonres->entries = info502; 25618474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 25628474SJose.Borrego@Sun.COM } 25638474SJose.Borrego@Sun.COM 25648474SJose.Borrego@Sun.COM /* 25658474SJose.Borrego@Sun.COM * mlsvc_NetShareEnumCommon 25668474SJose.Borrego@Sun.COM * 25678474SJose.Borrego@Sun.COM * Build the levels 0, 1, 2, 501 and 502 share information. This function 25688474SJose.Borrego@Sun.COM * is called by the various NetShareEnum levels for each share. If 25698474SJose.Borrego@Sun.COM * we cannot build the share data for some reason, we return an error 25708474SJose.Borrego@Sun.COM * but the actual value of the error is not important to the caller. 25718474SJose.Borrego@Sun.COM * The caller just needs to know not to include this info in the RPC 25728474SJose.Borrego@Sun.COM * response. 25738474SJose.Borrego@Sun.COM * 25748474SJose.Borrego@Sun.COM * Returns: 25758474SJose.Borrego@Sun.COM * ERROR_SUCCESS 25768474SJose.Borrego@Sun.COM * ERROR_NOT_ENOUGH_MEMORY 25778474SJose.Borrego@Sun.COM * ERROR_INVALID_LEVEL 25788474SJose.Borrego@Sun.COM */ 25798474SJose.Borrego@Sun.COM static DWORD 258010122SJordan.Brown@Sun.COM mlsvc_NetShareEnumCommon(ndr_xa_t *mxa, smb_svcenum_t *se, 25818474SJose.Borrego@Sun.COM smb_share_t *si, void *infop) 25828474SJose.Borrego@Sun.COM { 25839343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_0 *info0; 25849343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_1 *info1; 25859343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_2 *info2; 25869343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_501 *info501; 25879343SAfshin.Ardakani@Sun.COM struct mslm_NetShareInfo_502 *info502; 25889832Samw@Sun.COM srvsvc_sd_t sd; 25899832Samw@Sun.COM uint8_t *netname; 25909832Samw@Sun.COM uint8_t *comment; 25919832Samw@Sun.COM uint8_t *passwd; 25929832Samw@Sun.COM uint8_t *path; 259310122SJordan.Brown@Sun.COM int i = se->se_nitems; 25948474SJose.Borrego@Sun.COM 25959832Samw@Sun.COM netname = (uint8_t *)NDR_STRDUP(mxa, si->shr_name); 25969832Samw@Sun.COM comment = (uint8_t *)NDR_STRDUP(mxa, si->shr_cmnt); 25979832Samw@Sun.COM passwd = (uint8_t *)NDR_STRDUP(mxa, empty_string); 25989832Samw@Sun.COM path = (uint8_t *)srvsvc_share_mkpath(mxa, si->shr_path); 25999832Samw@Sun.COM 26009832Samw@Sun.COM if (!netname || !comment || !passwd || !path) 26019832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 26029832Samw@Sun.COM 26038474SJose.Borrego@Sun.COM switch (se->se_level) { 26048474SJose.Borrego@Sun.COM case 0: 26059343SAfshin.Ardakani@Sun.COM info0 = (struct mslm_NetShareInfo_0 *)infop; 26069832Samw@Sun.COM info0[i].shi0_netname = netname; 26078474SJose.Borrego@Sun.COM break; 26088474SJose.Borrego@Sun.COM 26098474SJose.Borrego@Sun.COM case 1: 26109343SAfshin.Ardakani@Sun.COM info1 = (struct mslm_NetShareInfo_1 *)infop; 26119832Samw@Sun.COM info1[i].shi1_netname = netname; 26129832Samw@Sun.COM info1[i].shi1_comment = comment; 26138474SJose.Borrego@Sun.COM info1[i].shi1_type = si->shr_type; 26148474SJose.Borrego@Sun.COM break; 26158474SJose.Borrego@Sun.COM 26168474SJose.Borrego@Sun.COM case 2: 26179343SAfshin.Ardakani@Sun.COM info2 = (struct mslm_NetShareInfo_2 *)infop; 26189832Samw@Sun.COM info2[i].shi2_netname = netname; 26199832Samw@Sun.COM info2[i].shi2_comment = comment; 26209832Samw@Sun.COM info2[i].shi2_path = path; 26218474SJose.Borrego@Sun.COM info2[i].shi2_type = si->shr_type; 26228474SJose.Borrego@Sun.COM info2[i].shi2_permissions = 0; 26238474SJose.Borrego@Sun.COM info2[i].shi2_max_uses = SHI_USES_UNLIMITED; 26248474SJose.Borrego@Sun.COM info2[i].shi2_current_uses = 0; 26259832Samw@Sun.COM info2[i].shi2_passwd = passwd; 26268474SJose.Borrego@Sun.COM break; 26278474SJose.Borrego@Sun.COM 26288474SJose.Borrego@Sun.COM case 501: 26299343SAfshin.Ardakani@Sun.COM info501 = (struct mslm_NetShareInfo_501 *)infop; 26309832Samw@Sun.COM info501[i].shi501_netname = netname; 26319832Samw@Sun.COM info501[i].shi501_comment = comment; 26328474SJose.Borrego@Sun.COM info501[i].shi501_type = si->shr_type; 263310504SKeyur.Desai@Sun.COM info501[i].shi501_flags = srvsvc_get_share_flags(si); 26348474SJose.Borrego@Sun.COM break; 26358474SJose.Borrego@Sun.COM 26368474SJose.Borrego@Sun.COM case 502: 26379343SAfshin.Ardakani@Sun.COM info502 = (struct mslm_NetShareInfo_502 *)infop; 26389832Samw@Sun.COM info502[i].shi502_netname = netname; 26399832Samw@Sun.COM info502[i].shi502_comment = comment; 26409832Samw@Sun.COM info502[i].shi502_path = path; 26418474SJose.Borrego@Sun.COM info502[i].shi502_type = si->shr_type; 26428474SJose.Borrego@Sun.COM info502[i].shi502_permissions = 0; 26438474SJose.Borrego@Sun.COM info502[i].shi502_max_uses = SHI_USES_UNLIMITED; 26448474SJose.Borrego@Sun.COM info502[i].shi502_current_uses = 0; 26459832Samw@Sun.COM info502[i].shi502_passwd = passwd; 26469832Samw@Sun.COM 26479832Samw@Sun.COM if (srvsvc_share_getsd(mxa, si, &sd) == ERROR_SUCCESS) { 26489832Samw@Sun.COM info502[i].shi502_reserved = sd.sd_size; 26499832Samw@Sun.COM info502[i].shi502_security_descriptor = sd.sd_buf; 26509832Samw@Sun.COM } else { 26519832Samw@Sun.COM info502[i].shi502_reserved = 0; 26529832Samw@Sun.COM info502[i].shi502_security_descriptor = NULL; 26539832Samw@Sun.COM } 26549832Samw@Sun.COM 26558474SJose.Borrego@Sun.COM break; 26568474SJose.Borrego@Sun.COM 26578474SJose.Borrego@Sun.COM default: 26588474SJose.Borrego@Sun.COM return (ERROR_INVALID_LEVEL); 26598474SJose.Borrego@Sun.COM } 26608474SJose.Borrego@Sun.COM 26618474SJose.Borrego@Sun.COM return (ERROR_SUCCESS); 26628474SJose.Borrego@Sun.COM } 26638474SJose.Borrego@Sun.COM 26648474SJose.Borrego@Sun.COM /* 26658474SJose.Borrego@Sun.COM * srvsvc_add_autohome 26668474SJose.Borrego@Sun.COM * 26678474SJose.Borrego@Sun.COM * Add the autohome share for the user. The share must not be a permanent 26688474SJose.Borrego@Sun.COM * share to avoid duplicates. 26698474SJose.Borrego@Sun.COM */ 26708474SJose.Borrego@Sun.COM static boolean_t 267110122SJordan.Brown@Sun.COM srvsvc_add_autohome(ndr_xa_t *mxa, smb_svcenum_t *se, void *infop) 26728474SJose.Borrego@Sun.COM { 267310122SJordan.Brown@Sun.COM smb_netuserinfo_t *user = &mxa->pipe->np_user; 2674*12065SKeyur.Desai@Sun.COM char *username; 26758474SJose.Borrego@Sun.COM smb_share_t si; 26768474SJose.Borrego@Sun.COM DWORD status; 2677*12065SKeyur.Desai@Sun.COM struct passwd pw; 2678*12065SKeyur.Desai@Sun.COM char buf[NSS_LINELEN_PASSWD]; 2679*12065SKeyur.Desai@Sun.COM 2680*12065SKeyur.Desai@Sun.COM if (IDMAP_ID_IS_EPHEMERAL(user->ui_posix_uid)) { 2681*12065SKeyur.Desai@Sun.COM username = user->ui_account; 2682*12065SKeyur.Desai@Sun.COM } else { 2683*12065SKeyur.Desai@Sun.COM if (getpwuid_r(user->ui_posix_uid, &pw, buf, sizeof (buf)) == 2684*12065SKeyur.Desai@Sun.COM NULL) 2685*12065SKeyur.Desai@Sun.COM return (B_FALSE); 2686*12065SKeyur.Desai@Sun.COM 2687*12065SKeyur.Desai@Sun.COM username = pw.pw_name; 2688*12065SKeyur.Desai@Sun.COM } 26898474SJose.Borrego@Sun.COM 26908474SJose.Borrego@Sun.COM if (smb_shr_get(username, &si) != NERR_Success) 26918474SJose.Borrego@Sun.COM return (B_FALSE); 26928474SJose.Borrego@Sun.COM 26938474SJose.Borrego@Sun.COM if ((si.shr_flags & SMB_SHRF_AUTOHOME) == 0) 26948474SJose.Borrego@Sun.COM return (B_FALSE); 26958474SJose.Borrego@Sun.COM 26968474SJose.Borrego@Sun.COM status = mlsvc_NetShareEnumCommon(mxa, se, &si, infop); 26978474SJose.Borrego@Sun.COM return (status == ERROR_SUCCESS); 26988474SJose.Borrego@Sun.COM } 26998474SJose.Borrego@Sun.COM 27008474SJose.Borrego@Sun.COM /* 27018474SJose.Borrego@Sun.COM * srvsvc_share_mkpath 27028474SJose.Borrego@Sun.COM * 27038474SJose.Borrego@Sun.COM * Create the share path required by the share enum calls. The path 27048474SJose.Borrego@Sun.COM * is created in a heap buffer ready for use by the caller. 27058474SJose.Borrego@Sun.COM * 27068474SJose.Borrego@Sun.COM * Some Windows over-the-wire backup applications do not work unless a 27078474SJose.Borrego@Sun.COM * drive letter is present in the share path. We don't care about the 27088474SJose.Borrego@Sun.COM * drive letter since the path is fully qualified with the volume name. 27098474SJose.Borrego@Sun.COM * 27108474SJose.Borrego@Sun.COM * Windows clients seem to be mostly okay with forward slashes in 27118474SJose.Borrego@Sun.COM * share paths but they cannot handle one immediately after the drive 27128474SJose.Borrego@Sun.COM * letter, i.e. B:/. For consistency we convert all the slashes in 27138474SJose.Borrego@Sun.COM * the path. 27148474SJose.Borrego@Sun.COM * 27158474SJose.Borrego@Sun.COM * Returns a pointer to a heap buffer containing the share path, which 27168474SJose.Borrego@Sun.COM * could be a null pointer if the heap allocation fails. 27178474SJose.Borrego@Sun.COM */ 27188474SJose.Borrego@Sun.COM static char * 27198474SJose.Borrego@Sun.COM srvsvc_share_mkpath(ndr_xa_t *mxa, char *path) 27208474SJose.Borrego@Sun.COM { 27218474SJose.Borrego@Sun.COM char tmpbuf[MAXPATHLEN]; 27228474SJose.Borrego@Sun.COM char *p; 2723*12065SKeyur.Desai@Sun.COM char drive_letter; 27248474SJose.Borrego@Sun.COM 27258474SJose.Borrego@Sun.COM if (strlen(path) == 0) 27268474SJose.Borrego@Sun.COM return (NDR_STRDUP(mxa, path)); 27278474SJose.Borrego@Sun.COM 2728*12065SKeyur.Desai@Sun.COM drive_letter = smb_shr_drive_letter(path); 2729*12065SKeyur.Desai@Sun.COM if (drive_letter != '\0') { 2730*12065SKeyur.Desai@Sun.COM (void) snprintf(tmpbuf, MAXPATHLEN, "%c:\\", drive_letter); 2731*12065SKeyur.Desai@Sun.COM return (NDR_STRDUP(mxa, tmpbuf)); 2732*12065SKeyur.Desai@Sun.COM } 2733*12065SKeyur.Desai@Sun.COM 27348474SJose.Borrego@Sun.COM /* 27358474SJose.Borrego@Sun.COM * Strip the volume name from the path (/vol1/home -> /home). 27368474SJose.Borrego@Sun.COM */ 27378474SJose.Borrego@Sun.COM p = path; 27388474SJose.Borrego@Sun.COM p += strspn(p, "/"); 27398474SJose.Borrego@Sun.COM p += strcspn(p, "/"); 27408474SJose.Borrego@Sun.COM p += strspn(p, "/"); 27418474SJose.Borrego@Sun.COM (void) snprintf(tmpbuf, MAXPATHLEN, "%c:/%s", 'B', p); 27428474SJose.Borrego@Sun.COM (void) strsubst(tmpbuf, '/', '\\'); 27438474SJose.Borrego@Sun.COM 27448474SJose.Borrego@Sun.COM return (NDR_STRDUP(mxa, tmpbuf)); 27458474SJose.Borrego@Sun.COM } 27468474SJose.Borrego@Sun.COM 27479832Samw@Sun.COM static int 27489832Samw@Sun.COM srvsvc_s_NetShareCheck(void *arg, ndr_xa_t *mxa) 27499832Samw@Sun.COM { 27509832Samw@Sun.COM struct mslm_NetShareCheck *param = arg; 27519832Samw@Sun.COM smb_shriter_t iterator; 27529832Samw@Sun.COM smb_share_t *si; 27539832Samw@Sun.COM char *path; 27549832Samw@Sun.COM 27559832Samw@Sun.COM if (param->path == NULL) { 27569832Samw@Sun.COM param->stype = STYPE_DISKTREE; 27579832Samw@Sun.COM param->status = NERR_NetNameNotFound; 27589832Samw@Sun.COM return (NDR_DRC_OK); 27599832Samw@Sun.COM } 27609832Samw@Sun.COM 27619832Samw@Sun.COM (void) strsubst((char *)param->path, '/', '\\'); 27629832Samw@Sun.COM 27639832Samw@Sun.COM smb_shr_iterinit(&iterator); 27649832Samw@Sun.COM 27659832Samw@Sun.COM while ((si = smb_shr_iterate(&iterator)) != NULL) { 27669832Samw@Sun.COM path = srvsvc_share_mkpath(mxa, si->shr_path); 27679832Samw@Sun.COM 276810966SJordan.Brown@Sun.COM if (smb_strcasecmp(path, (char *)param->path, 0) == 0) { 27699832Samw@Sun.COM param->stype = (si->shr_type & STYPE_MASK); 27709832Samw@Sun.COM param->status = NERR_Success; 27719832Samw@Sun.COM return (NDR_DRC_OK); 27729832Samw@Sun.COM } 27739832Samw@Sun.COM } 27749832Samw@Sun.COM 27759832Samw@Sun.COM param->stype = STYPE_DISKTREE; 27769832Samw@Sun.COM param->status = NERR_NetNameNotFound; 27779832Samw@Sun.COM return (NDR_DRC_OK); 27789832Samw@Sun.COM } 27799832Samw@Sun.COM 27808474SJose.Borrego@Sun.COM /* 278110122SJordan.Brown@Sun.COM * Delete a share. Only members of the Administrators, Server Operators 278210122SJordan.Brown@Sun.COM * or Power Users local groups are allowed to delete shares. 27838474SJose.Borrego@Sun.COM * 27848474SJose.Borrego@Sun.COM * This interface is used by the rmtshare command from the NT resource 27858474SJose.Borrego@Sun.COM * kit. Rmtshare allows a client to add or remove shares on a server 27868474SJose.Borrego@Sun.COM * from the client's command line. 27878474SJose.Borrego@Sun.COM * 27888474SJose.Borrego@Sun.COM * Returns Win32 error codes. 27898474SJose.Borrego@Sun.COM */ 27908474SJose.Borrego@Sun.COM static int 27918474SJose.Borrego@Sun.COM srvsvc_s_NetShareDel(void *arg, ndr_xa_t *mxa) 27928474SJose.Borrego@Sun.COM { 27938474SJose.Borrego@Sun.COM struct mslm_NetShareDel *param = arg; 279411963SAfshin.Ardakani@Sun.COM smb_share_t si; 27958474SJose.Borrego@Sun.COM 27968474SJose.Borrego@Sun.COM if (!ndr_is_poweruser(mxa) || 27978474SJose.Borrego@Sun.COM smb_shr_is_restricted((char *)param->netname)) { 27988474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 27998474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 28008474SJose.Borrego@Sun.COM } 28018474SJose.Borrego@Sun.COM 280211963SAfshin.Ardakani@Sun.COM if (smb_shr_get((char *)param->netname, &si) == NERR_Success) { 280311963SAfshin.Ardakani@Sun.COM if (si.shr_flags & SMB_SHRF_DFSROOT) { 280411963SAfshin.Ardakani@Sun.COM param->status = NERR_IsDfsShare; 280511963SAfshin.Ardakani@Sun.COM return (NDR_DRC_OK); 280611963SAfshin.Ardakani@Sun.COM } 280711963SAfshin.Ardakani@Sun.COM } 280811963SAfshin.Ardakani@Sun.COM 28098474SJose.Borrego@Sun.COM param->status = srvsvc_sa_delete((char *)param->netname); 28108474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 28118474SJose.Borrego@Sun.COM } 28128474SJose.Borrego@Sun.COM 28138474SJose.Borrego@Sun.COM /* 28148474SJose.Borrego@Sun.COM * srvsvc_s_NetGetFileSecurity 28158474SJose.Borrego@Sun.COM * 28168474SJose.Borrego@Sun.COM * Get security descriptor of the requested file/folder 28178474SJose.Borrego@Sun.COM * 28188474SJose.Borrego@Sun.COM * Right now, just returns ERROR_ACCESS_DENIED, because we cannot 28198474SJose.Borrego@Sun.COM * get the requested SD here in RPC code. 28208474SJose.Borrego@Sun.COM */ 28218474SJose.Borrego@Sun.COM /*ARGSUSED*/ 28228474SJose.Borrego@Sun.COM static int 28238474SJose.Borrego@Sun.COM srvsvc_s_NetGetFileSecurity(void *arg, ndr_xa_t *mxa) 28248474SJose.Borrego@Sun.COM { 28258474SJose.Borrego@Sun.COM struct mslm_NetGetFileSecurity *param = arg; 28268474SJose.Borrego@Sun.COM 28278474SJose.Borrego@Sun.COM param->length = 0; 28288474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 28298474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 28308474SJose.Borrego@Sun.COM } 28318474SJose.Borrego@Sun.COM 28328474SJose.Borrego@Sun.COM /* 28338474SJose.Borrego@Sun.COM * srvsvc_s_NetSetFileSecurity 28348474SJose.Borrego@Sun.COM * 28358474SJose.Borrego@Sun.COM * Set the given security descriptor for the requested file/folder 28368474SJose.Borrego@Sun.COM * 28378474SJose.Borrego@Sun.COM * Right now, just returns ERROR_ACCESS_DENIED, because we cannot 28388474SJose.Borrego@Sun.COM * set the requested SD here in RPC code. 28398474SJose.Borrego@Sun.COM */ 28408474SJose.Borrego@Sun.COM /*ARGSUSED*/ 28418474SJose.Borrego@Sun.COM static int 28428474SJose.Borrego@Sun.COM srvsvc_s_NetSetFileSecurity(void *arg, ndr_xa_t *mxa) 28438474SJose.Borrego@Sun.COM { 28448474SJose.Borrego@Sun.COM struct mslm_NetSetFileSecurity *param = arg; 28458474SJose.Borrego@Sun.COM 28468474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 28478474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 28488474SJose.Borrego@Sun.COM } 28498474SJose.Borrego@Sun.COM 28508474SJose.Borrego@Sun.COM /* 28518474SJose.Borrego@Sun.COM * If the default "smb" share group exists then return the group 28528474SJose.Borrego@Sun.COM * handle, otherwise create the group and return the handle. 28538474SJose.Borrego@Sun.COM * 28548474SJose.Borrego@Sun.COM * All shares created via the srvsvc will be added to the "smb" 28558474SJose.Borrego@Sun.COM * group. 28568474SJose.Borrego@Sun.COM */ 28578474SJose.Borrego@Sun.COM static sa_group_t 28588474SJose.Borrego@Sun.COM srvsvc_sa_get_smbgrp(sa_handle_t handle) 28598474SJose.Borrego@Sun.COM { 28608474SJose.Borrego@Sun.COM sa_group_t group = NULL; 28618474SJose.Borrego@Sun.COM int err; 28628474SJose.Borrego@Sun.COM 28638474SJose.Borrego@Sun.COM group = sa_get_group(handle, SMB_DEFAULT_SHARE_GROUP); 28648474SJose.Borrego@Sun.COM if (group != NULL) 28658474SJose.Borrego@Sun.COM return (group); 28668474SJose.Borrego@Sun.COM 28678474SJose.Borrego@Sun.COM group = sa_create_group(handle, SMB_DEFAULT_SHARE_GROUP, &err); 28688474SJose.Borrego@Sun.COM if (group == NULL) 28698474SJose.Borrego@Sun.COM return (NULL); 28708474SJose.Borrego@Sun.COM 28718474SJose.Borrego@Sun.COM if (sa_create_optionset(group, SMB_DEFAULT_SHARE_GROUP) == NULL) { 28728474SJose.Borrego@Sun.COM (void) sa_remove_group(group); 28738474SJose.Borrego@Sun.COM group = NULL; 28748474SJose.Borrego@Sun.COM } 28758474SJose.Borrego@Sun.COM 28768474SJose.Borrego@Sun.COM return (group); 28778474SJose.Borrego@Sun.COM } 28788474SJose.Borrego@Sun.COM 28798474SJose.Borrego@Sun.COM /* 28808474SJose.Borrego@Sun.COM * Stores the given share in sharemgr 28818474SJose.Borrego@Sun.COM */ 28828474SJose.Borrego@Sun.COM static uint32_t 28838474SJose.Borrego@Sun.COM srvsvc_sa_add(char *sharename, char *path, char *cmnt) 28848474SJose.Borrego@Sun.COM { 28858474SJose.Borrego@Sun.COM sa_handle_t handle; 28868474SJose.Borrego@Sun.COM sa_share_t share; 28878474SJose.Borrego@Sun.COM sa_group_t group; 28888474SJose.Borrego@Sun.COM sa_resource_t resource; 28898474SJose.Borrego@Sun.COM boolean_t new_share = B_FALSE; 28908474SJose.Borrego@Sun.COM uint32_t status = NERR_Success; 28918474SJose.Borrego@Sun.COM int err; 28928474SJose.Borrego@Sun.COM 28938474SJose.Borrego@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 28948474SJose.Borrego@Sun.COM return (NERR_InternalError); 28958474SJose.Borrego@Sun.COM 28968474SJose.Borrego@Sun.COM share = sa_find_share(handle, path); 28978474SJose.Borrego@Sun.COM if (share == NULL) { 28988474SJose.Borrego@Sun.COM group = srvsvc_sa_get_smbgrp(handle); 28998474SJose.Borrego@Sun.COM if (group == NULL) { 29008474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 29018474SJose.Borrego@Sun.COM return (NERR_InternalError); 29028474SJose.Borrego@Sun.COM } 29038474SJose.Borrego@Sun.COM 29048474SJose.Borrego@Sun.COM share = sa_add_share(group, path, SA_SHARE_PERMANENT, &err); 29058474SJose.Borrego@Sun.COM if (share == NULL) { 29068474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 29078474SJose.Borrego@Sun.COM return (NERR_InternalError); 29088474SJose.Borrego@Sun.COM } 29098474SJose.Borrego@Sun.COM new_share = B_TRUE; 29108474SJose.Borrego@Sun.COM } 29118474SJose.Borrego@Sun.COM 29128474SJose.Borrego@Sun.COM resource = sa_get_share_resource(share, sharename); 29138474SJose.Borrego@Sun.COM if (resource == NULL) { 29148474SJose.Borrego@Sun.COM resource = sa_add_resource(share, sharename, 29158474SJose.Borrego@Sun.COM SA_SHARE_PERMANENT, &err); 29168474SJose.Borrego@Sun.COM if (resource == NULL) { 29178474SJose.Borrego@Sun.COM if (new_share) 29188474SJose.Borrego@Sun.COM (void) sa_remove_share(share); 29198474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 29208474SJose.Borrego@Sun.COM return (NERR_InternalError); 29218474SJose.Borrego@Sun.COM } 29228474SJose.Borrego@Sun.COM } 29238474SJose.Borrego@Sun.COM 29248474SJose.Borrego@Sun.COM (void) sa_set_resource_description(resource, cmnt); 29258474SJose.Borrego@Sun.COM 29268474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 29278474SJose.Borrego@Sun.COM return (status); 29288474SJose.Borrego@Sun.COM } 29298474SJose.Borrego@Sun.COM 29308474SJose.Borrego@Sun.COM /* 29318474SJose.Borrego@Sun.COM * Removes the share from sharemgr 29328474SJose.Borrego@Sun.COM */ 29338474SJose.Borrego@Sun.COM static uint32_t 29348474SJose.Borrego@Sun.COM srvsvc_sa_delete(char *sharename) 29358474SJose.Borrego@Sun.COM { 29368474SJose.Borrego@Sun.COM sa_handle_t handle; 29378474SJose.Borrego@Sun.COM sa_resource_t resource; 29388474SJose.Borrego@Sun.COM uint32_t status; 29398474SJose.Borrego@Sun.COM 29408474SJose.Borrego@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 29418474SJose.Borrego@Sun.COM return (NERR_InternalError); 29428474SJose.Borrego@Sun.COM 29438474SJose.Borrego@Sun.COM status = NERR_InternalError; 29448474SJose.Borrego@Sun.COM if ((resource = sa_find_resource(handle, sharename)) != NULL) { 29458474SJose.Borrego@Sun.COM if (sa_remove_resource(resource) == SA_OK) 29468474SJose.Borrego@Sun.COM status = NERR_Success; 29478474SJose.Borrego@Sun.COM } 29488474SJose.Borrego@Sun.COM 29498474SJose.Borrego@Sun.COM smb_shr_sa_exit(); 29508474SJose.Borrego@Sun.COM return (status); 29518474SJose.Borrego@Sun.COM } 29528474SJose.Borrego@Sun.COM 29539832Samw@Sun.COM /* 29549832Samw@Sun.COM * Update the share information. 29559832Samw@Sun.COM */ 29569832Samw@Sun.COM static uint32_t 29579832Samw@Sun.COM srvsvc_sa_modify(smb_share_t *si, srvsvc_netshare_setinfo_t *info) 29589832Samw@Sun.COM { 29599832Samw@Sun.COM sa_handle_t handle; 29609832Samw@Sun.COM sa_share_t share; 29619832Samw@Sun.COM sa_resource_t resource; 29629832Samw@Sun.COM boolean_t renamed = B_FALSE; 29639832Samw@Sun.COM uint32_t nerr = NERR_Success; 29649832Samw@Sun.COM 29659832Samw@Sun.COM if ((handle = smb_shr_sa_enter()) == NULL) 29669832Samw@Sun.COM return (NERR_InternalError); 29679832Samw@Sun.COM 29689832Samw@Sun.COM if ((share = sa_find_share(handle, si->shr_path)) == NULL) { 29699832Samw@Sun.COM smb_shr_sa_exit(); 29709832Samw@Sun.COM return (NERR_InternalError); 29719832Samw@Sun.COM } 29729832Samw@Sun.COM 29739832Samw@Sun.COM if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) { 29749832Samw@Sun.COM smb_shr_sa_exit(); 29759832Samw@Sun.COM return (NERR_InternalError); 29769832Samw@Sun.COM } 29779832Samw@Sun.COM 29789832Samw@Sun.COM if (info->nss_netname != NULL && info->nss_netname[0] != '\0' && 297910966SJordan.Brown@Sun.COM smb_strcasecmp(info->nss_netname, si->shr_name, 0) != 0) { 29809832Samw@Sun.COM (void) sa_set_resource_attr(resource, SHOPT_NAME, 29819832Samw@Sun.COM info->nss_netname); 29829832Samw@Sun.COM renamed = B_TRUE; 29839832Samw@Sun.COM } 29849832Samw@Sun.COM 29859832Samw@Sun.COM if ((info->nss_comment != NULL) && 29869832Samw@Sun.COM (strcmp(info->nss_comment, si->shr_cmnt) != 0)) { 29879832Samw@Sun.COM (void) sa_set_resource_description(resource, info->nss_comment); 29889832Samw@Sun.COM (void) strlcpy(si->shr_cmnt, info->nss_comment, 29899832Samw@Sun.COM SMB_SHARE_CMNT_MAX); 29909832Samw@Sun.COM } 29919832Samw@Sun.COM 29929832Samw@Sun.COM smb_shr_sa_exit(); 29939832Samw@Sun.COM 29949832Samw@Sun.COM if (renamed) { 29959832Samw@Sun.COM nerr = smb_shr_rename(si->shr_name, info->nss_netname); 29969832Samw@Sun.COM if (nerr != NERR_Success) 29979832Samw@Sun.COM return (nerr); 29989832Samw@Sun.COM 29999832Samw@Sun.COM (void) strlcpy(si->shr_name, info->nss_netname, MAXNAMELEN); 30009832Samw@Sun.COM } 30019832Samw@Sun.COM 30029832Samw@Sun.COM return (nerr); 30039832Samw@Sun.COM } 30049832Samw@Sun.COM 30059832Samw@Sun.COM /* 300610504SKeyur.Desai@Sun.COM * Update the share properties. 300710504SKeyur.Desai@Sun.COM * 300810504SKeyur.Desai@Sun.COM * Updates the optionset properties of the share resource. 300910504SKeyur.Desai@Sun.COM * The properties are given as a list of name-value pair. 301010504SKeyur.Desai@Sun.COM * The name argument should be the optionset property name and the value 301110504SKeyur.Desai@Sun.COM * should be a valid value for the specified property. 30129832Samw@Sun.COM */ 30139832Samw@Sun.COM static uint32_t 301410504SKeyur.Desai@Sun.COM srvsvc_sa_setprop(smb_share_t *si, nvlist_t *nvl) 30159832Samw@Sun.COM { 30169832Samw@Sun.COM sa_handle_t handle; 30179832Samw@Sun.COM sa_share_t share; 30189832Samw@Sun.COM sa_resource_t resource; 301910504SKeyur.Desai@Sun.COM sa_property_t prop; 302010504SKeyur.Desai@Sun.COM sa_optionset_t opts; 302110504SKeyur.Desai@Sun.COM uint32_t nerr = NERR_Success; 302210504SKeyur.Desai@Sun.COM nvpair_t *cur; 302310504SKeyur.Desai@Sun.COM int err = 0; 302410504SKeyur.Desai@Sun.COM char *name, *val; 30259832Samw@Sun.COM 302611963SAfshin.Ardakani@Sun.COM if ((handle = sa_init(SA_INIT_SHARE_API)) == NULL) 30279832Samw@Sun.COM return (NERR_InternalError); 30289832Samw@Sun.COM 30299832Samw@Sun.COM if ((share = sa_find_share(handle, si->shr_path)) == NULL) { 303011963SAfshin.Ardakani@Sun.COM sa_fini(handle); 30319832Samw@Sun.COM return (NERR_InternalError); 30329832Samw@Sun.COM } 30339832Samw@Sun.COM 30349832Samw@Sun.COM if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) { 303511963SAfshin.Ardakani@Sun.COM sa_fini(handle); 30369832Samw@Sun.COM return (NERR_InternalError); 30379832Samw@Sun.COM } 30389832Samw@Sun.COM 303910504SKeyur.Desai@Sun.COM if ((opts = sa_get_optionset(resource, SMB_PROTOCOL_NAME)) == NULL) { 304010504SKeyur.Desai@Sun.COM opts = sa_create_optionset(resource, SMB_PROTOCOL_NAME); 304110504SKeyur.Desai@Sun.COM if (opts == NULL) { 304211963SAfshin.Ardakani@Sun.COM sa_fini(handle); 304310504SKeyur.Desai@Sun.COM return (NERR_InternalError); 304410504SKeyur.Desai@Sun.COM } 30459832Samw@Sun.COM } 30469832Samw@Sun.COM 304710504SKeyur.Desai@Sun.COM cur = nvlist_next_nvpair(nvl, NULL); 304810504SKeyur.Desai@Sun.COM while (cur != NULL) { 304910504SKeyur.Desai@Sun.COM name = nvpair_name(cur); 305010504SKeyur.Desai@Sun.COM err = nvpair_value_string(cur, &val); 305110504SKeyur.Desai@Sun.COM if ((err != 0) || (name == NULL) || (val == NULL)) { 305210504SKeyur.Desai@Sun.COM nerr = NERR_InternalError; 305310504SKeyur.Desai@Sun.COM break; 305410504SKeyur.Desai@Sun.COM } 305510504SKeyur.Desai@Sun.COM 305610504SKeyur.Desai@Sun.COM prop = NULL; 305710504SKeyur.Desai@Sun.COM if ((prop = sa_get_property(opts, name)) == NULL) { 305810504SKeyur.Desai@Sun.COM prop = sa_create_property(name, val); 305910504SKeyur.Desai@Sun.COM if (prop != NULL) { 306010504SKeyur.Desai@Sun.COM nerr = sa_valid_property(handle, opts, 306110504SKeyur.Desai@Sun.COM SMB_PROTOCOL_NAME, prop); 306210504SKeyur.Desai@Sun.COM if (nerr != NERR_Success) { 306310504SKeyur.Desai@Sun.COM (void) sa_remove_property(prop); 306410504SKeyur.Desai@Sun.COM break; 306510504SKeyur.Desai@Sun.COM } 306610504SKeyur.Desai@Sun.COM } 306710504SKeyur.Desai@Sun.COM nerr = sa_add_property(opts, prop); 306810504SKeyur.Desai@Sun.COM if (nerr != NERR_Success) 306910504SKeyur.Desai@Sun.COM break; 307010504SKeyur.Desai@Sun.COM } else { 307110504SKeyur.Desai@Sun.COM nerr = sa_update_property(prop, val); 307210504SKeyur.Desai@Sun.COM if (nerr != NERR_Success) 307310504SKeyur.Desai@Sun.COM break; 307410504SKeyur.Desai@Sun.COM } 307510504SKeyur.Desai@Sun.COM 307610504SKeyur.Desai@Sun.COM cur = nvlist_next_nvpair(nvl, cur); 307710504SKeyur.Desai@Sun.COM } 307810504SKeyur.Desai@Sun.COM 307910504SKeyur.Desai@Sun.COM if (nerr == NERR_Success) 308010504SKeyur.Desai@Sun.COM nerr = sa_commit_properties(opts, 0); 308110504SKeyur.Desai@Sun.COM 308211963SAfshin.Ardakani@Sun.COM sa_fini(handle); 308310504SKeyur.Desai@Sun.COM return (nerr); 30849832Samw@Sun.COM } 30859832Samw@Sun.COM 308610504SKeyur.Desai@Sun.COM 30878474SJose.Borrego@Sun.COM static ndr_stub_table_t srvsvc_stub_table[] = { 30888474SJose.Borrego@Sun.COM { srvsvc_s_NetConnectEnum, SRVSVC_OPNUM_NetConnectEnum }, 30898474SJose.Borrego@Sun.COM { srvsvc_s_NetFileEnum, SRVSVC_OPNUM_NetFileEnum }, 30908474SJose.Borrego@Sun.COM { srvsvc_s_NetFileClose, SRVSVC_OPNUM_NetFileClose }, 30918474SJose.Borrego@Sun.COM { srvsvc_s_NetShareGetInfo, SRVSVC_OPNUM_NetShareGetInfo }, 30928474SJose.Borrego@Sun.COM { srvsvc_s_NetShareSetInfo, SRVSVC_OPNUM_NetShareSetInfo }, 30938474SJose.Borrego@Sun.COM { srvsvc_s_NetSessionEnum, SRVSVC_OPNUM_NetSessionEnum }, 30948474SJose.Borrego@Sun.COM { srvsvc_s_NetSessionDel, SRVSVC_OPNUM_NetSessionDel }, 30958474SJose.Borrego@Sun.COM { srvsvc_s_NetServerGetInfo, SRVSVC_OPNUM_NetServerGetInfo }, 30968474SJose.Borrego@Sun.COM { srvsvc_s_NetRemoteTOD, SRVSVC_OPNUM_NetRemoteTOD }, 30978474SJose.Borrego@Sun.COM { srvsvc_s_NetNameValidate, SRVSVC_OPNUM_NetNameValidate }, 30988474SJose.Borrego@Sun.COM { srvsvc_s_NetShareAdd, SRVSVC_OPNUM_NetShareAdd }, 30998474SJose.Borrego@Sun.COM { srvsvc_s_NetShareDel, SRVSVC_OPNUM_NetShareDel }, 31008474SJose.Borrego@Sun.COM { srvsvc_s_NetShareEnum, SRVSVC_OPNUM_NetShareEnum }, 31018474SJose.Borrego@Sun.COM { srvsvc_s_NetShareEnumSticky, SRVSVC_OPNUM_NetShareEnumSticky }, 31029832Samw@Sun.COM { srvsvc_s_NetShareCheck, SRVSVC_OPNUM_NetShareCheck }, 31038474SJose.Borrego@Sun.COM { srvsvc_s_NetGetFileSecurity, SRVSVC_OPNUM_NetGetFileSecurity }, 31048474SJose.Borrego@Sun.COM { srvsvc_s_NetSetFileSecurity, SRVSVC_OPNUM_NetSetFileSecurity }, 31058474SJose.Borrego@Sun.COM {0} 31068474SJose.Borrego@Sun.COM }; 3107