189dc44ceSjose borrego /* 289dc44ceSjose borrego * CDDL HEADER START 389dc44ceSjose borrego * 489dc44ceSjose borrego * The contents of this file are subject to the terms of the 589dc44ceSjose borrego * Common Development and Distribution License (the "License"). 689dc44ceSjose borrego * You may not use this file except in compliance with the License. 789dc44ceSjose borrego * 889dc44ceSjose borrego * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 989dc44ceSjose borrego * or http://www.opensolaris.org/os/licensing. 1089dc44ceSjose borrego * See the License for the specific language governing permissions 1189dc44ceSjose borrego * and limitations under the License. 1289dc44ceSjose borrego * 1389dc44ceSjose borrego * When distributing Covered Code, include this CDDL HEADER in each 1489dc44ceSjose borrego * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1589dc44ceSjose borrego * If applicable, add the following below this CDDL HEADER, with the 1689dc44ceSjose borrego * fields enclosed by brackets "[]" replaced with your own identifying 1789dc44ceSjose borrego * information: Portions Copyright [yyyy] [name of copyright owner] 1889dc44ceSjose borrego * 1989dc44ceSjose borrego * CDDL HEADER END 2089dc44ceSjose borrego */ 21*148c5f43SAlan Wright 2289dc44ceSjose borrego /* 23*148c5f43SAlan Wright * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 2489dc44ceSjose borrego */ 2589dc44ceSjose borrego 2689dc44ceSjose borrego /* 2789dc44ceSjose borrego * Windows Registry RPC (WINREG) server-side interface. 2889dc44ceSjose borrego * 297f667e74Sjose borrego * The registry is a database with a hierarchical structure similar to 307f667e74Sjose borrego * a file system, with keys in place of directories and values in place 317f667e74Sjose borrego * of files. The top level keys are known as root keys and each key can 327f667e74Sjose borrego * contain subkeys and values. As with directories and sub-directories, 337f667e74Sjose borrego * the terms key and subkey are used interchangeably. Values, analogous 347f667e74Sjose borrego * to files, contain data. 3589dc44ceSjose borrego * 367f667e74Sjose borrego * A specific subkey can be identifies by its fully qualified name (FQN), 377f667e74Sjose borrego * which is analogous to a file system path. In the registry, the key 387f667e74Sjose borrego * separator is the '\' character, which is reserved and cannot appear 397f667e74Sjose borrego * in key or value names. Registry names are case-insensitive. 407f667e74Sjose borrego * 417f667e74Sjose borrego * For example: HKEY_LOCAL_MACHINE\System\CurrentControlSet 427f667e74Sjose borrego * 43b1352070SAlan Wright * The HKEY_LOCAL_MACHINE root key contains a subkey called System, and 447f667e74Sjose borrego * System contains a subkey called CurrentControlSet. 457f667e74Sjose borrego * 467f667e74Sjose borrego * The WINREG RPC interface returns Win32 error codes. 4789dc44ceSjose borrego */ 4889dc44ceSjose borrego 4989dc44ceSjose borrego #include <sys/utsname.h> 5089dc44ceSjose borrego #include <strings.h> 5189dc44ceSjose borrego 5289dc44ceSjose borrego #include <smbsrv/libsmb.h> 5389dc44ceSjose borrego #include <smbsrv/nmpipes.h> 5489dc44ceSjose borrego #include <smbsrv/libmlsvc.h> 5589dc44ceSjose borrego #include <smbsrv/ndl/winreg.ndl> 5689dc44ceSjose borrego 5789dc44ceSjose borrego /* 5889dc44ceSjose borrego * List of supported registry keys (case-insensitive). 5989dc44ceSjose borrego */ 6089dc44ceSjose borrego static char *winreg_keys[] = { 61b1352070SAlan Wright "HKLM", 62b1352070SAlan Wright "HKU", 63b1352070SAlan Wright "HKLM\\SOFTWARE", 64b1352070SAlan Wright "HKLM\\SYSTEM", 65b1352070SAlan Wright "System", 66b1352070SAlan Wright "CurrentControlSet", 679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States "SunOS", 689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States "Solaris", 6989dc44ceSjose borrego "System\\CurrentControlSet\\Services\\Eventlog", 7089dc44ceSjose borrego "System\\CurrentControlSet\\Control\\ProductOptions", 71b1352070SAlan Wright "SOFTWARE", 7289dc44ceSjose borrego "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" 7389dc44ceSjose borrego }; 7489dc44ceSjose borrego 75*148c5f43SAlan Wright static char *winreg_eventlog = "System\\CurrentControlSet\\Services\\Eventlog"; 76*148c5f43SAlan Wright 77*148c5f43SAlan Wright static char *winreg_log[] = { 78*148c5f43SAlan Wright "Application", 79*148c5f43SAlan Wright "Security", 80*148c5f43SAlan Wright "System", 81*148c5f43SAlan Wright "smbd", 82*148c5f43SAlan Wright "smbrdr" 83*148c5f43SAlan Wright }; 84*148c5f43SAlan Wright 8589dc44ceSjose borrego typedef struct winreg_subkey { 8689dc44ceSjose borrego list_node_t sk_lnd; 8789dc44ceSjose borrego ndr_hdid_t sk_handle; 8889dc44ceSjose borrego char sk_name[MAXPATHLEN]; 8989dc44ceSjose borrego boolean_t sk_predefined; 9089dc44ceSjose borrego } winreg_subkey_t; 9189dc44ceSjose borrego 9289dc44ceSjose borrego typedef struct winreg_keylist { 9389dc44ceSjose borrego list_t kl_list; 9489dc44ceSjose borrego int kl_count; 9589dc44ceSjose borrego } winreg_keylist_t; 9689dc44ceSjose borrego 9789dc44ceSjose borrego static winreg_keylist_t winreg_keylist; 989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static mutex_t winreg_mutex; 9989dc44ceSjose borrego 100*148c5f43SAlan Wright static void winreg_add_predefined(const char *); 1019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static ndr_hdid_t *winreg_alloc_id(ndr_xa_t *, const char *); 1029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void winreg_dealloc_id(ndr_xa_t *, ndr_hdid_t *); 10389dc44ceSjose borrego static boolean_t winreg_key_has_subkey(const char *); 1047f667e74Sjose borrego static char *winreg_enum_subkey(ndr_xa_t *, const char *, uint32_t); 10589dc44ceSjose borrego static char *winreg_lookup_value(const char *); 106f96bd5c8SAlan Wright static uint32_t winreg_sd_format(smb_sd_t *); 107f96bd5c8SAlan Wright uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *); 10889dc44ceSjose borrego 1097f667e74Sjose borrego static int winreg_s_OpenHKCR(void *, ndr_xa_t *); 1107f667e74Sjose borrego static int winreg_s_OpenHKCU(void *, ndr_xa_t *); 11189dc44ceSjose borrego static int winreg_s_OpenHKLM(void *, ndr_xa_t *); 1127f667e74Sjose borrego static int winreg_s_OpenHKPD(void *, ndr_xa_t *); 1137f667e74Sjose borrego static int winreg_s_OpenHKU(void *, ndr_xa_t *); 1147f667e74Sjose borrego static int winreg_s_OpenHKCC(void *, ndr_xa_t *); 1157f667e74Sjose borrego static int winreg_s_OpenHKDD(void *, ndr_xa_t *); 1167f667e74Sjose borrego static int winreg_s_OpenHKPT(void *, ndr_xa_t *); 1177f667e74Sjose borrego static int winreg_s_OpenHKPN(void *, ndr_xa_t *); 1187f667e74Sjose borrego static int winreg_s_OpenHK(void *, ndr_xa_t *, const char *); 11989dc44ceSjose borrego static int winreg_s_Close(void *, ndr_xa_t *); 12089dc44ceSjose borrego static int winreg_s_CreateKey(void *, ndr_xa_t *); 12189dc44ceSjose borrego static int winreg_s_DeleteKey(void *, ndr_xa_t *); 12289dc44ceSjose borrego static int winreg_s_DeleteValue(void *, ndr_xa_t *); 12389dc44ceSjose borrego static int winreg_s_EnumKey(void *, ndr_xa_t *); 12489dc44ceSjose borrego static int winreg_s_EnumValue(void *, ndr_xa_t *); 12589dc44ceSjose borrego static int winreg_s_FlushKey(void *, ndr_xa_t *); 12689dc44ceSjose borrego static int winreg_s_GetKeySec(void *, ndr_xa_t *); 12789dc44ceSjose borrego static int winreg_s_NotifyChange(void *, ndr_xa_t *); 12889dc44ceSjose borrego static int winreg_s_OpenKey(void *, ndr_xa_t *); 12989dc44ceSjose borrego static int winreg_s_QueryKey(void *, ndr_xa_t *); 13089dc44ceSjose borrego static int winreg_s_QueryValue(void *, ndr_xa_t *); 13189dc44ceSjose borrego static int winreg_s_SetKeySec(void *, ndr_xa_t *); 13289dc44ceSjose borrego static int winreg_s_CreateValue(void *, ndr_xa_t *); 13389dc44ceSjose borrego static int winreg_s_Shutdown(void *, ndr_xa_t *); 13489dc44ceSjose borrego static int winreg_s_AbortShutdown(void *, ndr_xa_t *); 13589dc44ceSjose borrego static int winreg_s_GetVersion(void *, ndr_xa_t *); 13689dc44ceSjose borrego 13789dc44ceSjose borrego static ndr_stub_table_t winreg_stub_table[] = { 1387f667e74Sjose borrego { winreg_s_OpenHKCR, WINREG_OPNUM_OpenHKCR }, 1397f667e74Sjose borrego { winreg_s_OpenHKCU, WINREG_OPNUM_OpenHKCU }, 14089dc44ceSjose borrego { winreg_s_OpenHKLM, WINREG_OPNUM_OpenHKLM }, 1417f667e74Sjose borrego { winreg_s_OpenHKPD, WINREG_OPNUM_OpenHKPD }, 1427f667e74Sjose borrego { winreg_s_OpenHKU, WINREG_OPNUM_OpenHKUsers }, 14389dc44ceSjose borrego { winreg_s_Close, WINREG_OPNUM_Close }, 14489dc44ceSjose borrego { winreg_s_CreateKey, WINREG_OPNUM_CreateKey }, 14589dc44ceSjose borrego { winreg_s_DeleteKey, WINREG_OPNUM_DeleteKey }, 14689dc44ceSjose borrego { winreg_s_DeleteValue, WINREG_OPNUM_DeleteValue }, 14789dc44ceSjose borrego { winreg_s_EnumKey, WINREG_OPNUM_EnumKey }, 14889dc44ceSjose borrego { winreg_s_EnumValue, WINREG_OPNUM_EnumValue }, 14989dc44ceSjose borrego { winreg_s_FlushKey, WINREG_OPNUM_FlushKey }, 15089dc44ceSjose borrego { winreg_s_GetKeySec, WINREG_OPNUM_GetKeySec }, 15189dc44ceSjose borrego { winreg_s_NotifyChange, WINREG_OPNUM_NotifyChange }, 15289dc44ceSjose borrego { winreg_s_OpenKey, WINREG_OPNUM_OpenKey }, 15389dc44ceSjose borrego { winreg_s_QueryKey, WINREG_OPNUM_QueryKey }, 15489dc44ceSjose borrego { winreg_s_QueryValue, WINREG_OPNUM_QueryValue }, 15589dc44ceSjose borrego { winreg_s_SetKeySec, WINREG_OPNUM_SetKeySec }, 15689dc44ceSjose borrego { winreg_s_CreateValue, WINREG_OPNUM_CreateValue }, 15789dc44ceSjose borrego { winreg_s_Shutdown, WINREG_OPNUM_Shutdown }, 15889dc44ceSjose borrego { winreg_s_AbortShutdown, WINREG_OPNUM_AbortShutdown }, 15989dc44ceSjose borrego { winreg_s_GetVersion, WINREG_OPNUM_GetVersion }, 1607f667e74Sjose borrego { winreg_s_OpenHKCC, WINREG_OPNUM_OpenHKCC }, 1617f667e74Sjose borrego { winreg_s_OpenHKDD, WINREG_OPNUM_OpenHKDD }, 1627f667e74Sjose borrego { winreg_s_OpenHKPT, WINREG_OPNUM_OpenHKPT }, 1637f667e74Sjose borrego { winreg_s_OpenHKPN, WINREG_OPNUM_OpenHKPN }, 16489dc44ceSjose borrego {0} 16589dc44ceSjose borrego }; 16689dc44ceSjose borrego 16789dc44ceSjose borrego static ndr_service_t winreg_service = { 16889dc44ceSjose borrego "Winreg", /* name */ 16989dc44ceSjose borrego "Windows Registry", /* desc */ 17089dc44ceSjose borrego "\\winreg", /* endpoint */ 17189dc44ceSjose borrego PIPE_WINREG, /* sec_addr_port */ 17289dc44ceSjose borrego "338cd001-2244-31f1-aaaa-900038001003", 1, /* abstract */ 17389dc44ceSjose borrego NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 17489dc44ceSjose borrego 0, /* no bind_instance_size */ 17589dc44ceSjose borrego 0, /* no bind_req() */ 17689dc44ceSjose borrego 0, /* no unbind_and_close() */ 17789dc44ceSjose borrego 0, /* use generic_call_stub() */ 17889dc44ceSjose borrego &TYPEINFO(winreg_interface), /* interface ti */ 17989dc44ceSjose borrego winreg_stub_table /* stub_table */ 18089dc44ceSjose borrego }; 18189dc44ceSjose borrego 18289dc44ceSjose borrego static char winreg_sysname[SYS_NMLN]; 1839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static char winreg_sysver[SMB_VERSTR_LEN]; 18489dc44ceSjose borrego 18589dc44ceSjose borrego /* 18689dc44ceSjose borrego * winreg_initialize 18789dc44ceSjose borrego * 18889dc44ceSjose borrego * Initialize and register the WINREG RPC interface with the RPC runtime 18989dc44ceSjose borrego * library. It must be called in order to use either the client side 19089dc44ceSjose borrego * or the server side functions. 19189dc44ceSjose borrego */ 19289dc44ceSjose borrego void 19389dc44ceSjose borrego winreg_initialize(void) 19489dc44ceSjose borrego { 1959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_version_t version; 19689dc44ceSjose borrego struct utsname name; 197*148c5f43SAlan Wright char subkey[MAXPATHLEN]; 19889dc44ceSjose borrego char *sysname; 19989dc44ceSjose borrego int i; 20089dc44ceSjose borrego 2019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex); 2029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 20389dc44ceSjose borrego list_create(&winreg_keylist.kl_list, sizeof (winreg_subkey_t), 20489dc44ceSjose borrego offsetof(winreg_subkey_t, sk_lnd)); 20589dc44ceSjose borrego winreg_keylist.kl_count = 0; 20689dc44ceSjose borrego 207*148c5f43SAlan Wright for (i = 0; i < sizeof (winreg_keys)/sizeof (winreg_keys[0]); ++i) 208*148c5f43SAlan Wright winreg_add_predefined(winreg_keys[i]); 2099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 210*148c5f43SAlan Wright for (i = 0; i < sizeof (winreg_log)/sizeof (winreg_log[0]); ++i) { 211*148c5f43SAlan Wright (void) snprintf(subkey, MAXPATHLEN, "%s", winreg_log[i]); 212*148c5f43SAlan Wright winreg_add_predefined(subkey); 213*148c5f43SAlan Wright 214*148c5f43SAlan Wright (void) snprintf(subkey, MAXPATHLEN, "%s\\%s", 215*148c5f43SAlan Wright winreg_eventlog, winreg_log[i]); 216*148c5f43SAlan Wright winreg_add_predefined(subkey); 217*148c5f43SAlan Wright 218*148c5f43SAlan Wright (void) snprintf(subkey, MAXPATHLEN, "%s\\%s\\%s", 219*148c5f43SAlan Wright winreg_eventlog, winreg_log[i], winreg_log[i]); 220*148c5f43SAlan Wright winreg_add_predefined(subkey); 22189dc44ceSjose borrego } 22289dc44ceSjose borrego 2239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 2249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22589dc44ceSjose borrego if (uname(&name) < 0) 22689dc44ceSjose borrego sysname = "Solaris"; 22789dc44ceSjose borrego else 22889dc44ceSjose borrego sysname = name.sysname; 22989dc44ceSjose borrego 23089dc44ceSjose borrego (void) strlcpy(winreg_sysname, sysname, SYS_NMLN); 2319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 2329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_config_get_version(&version); 2339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) snprintf(winreg_sysver, SMB_VERSTR_LEN, "%d.%d", 2349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States version.sv_major, version.sv_minor); 2359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23689dc44ceSjose borrego (void) ndr_svc_register(&winreg_service); 23789dc44ceSjose borrego } 23889dc44ceSjose borrego 239*148c5f43SAlan Wright static void 240*148c5f43SAlan Wright winreg_add_predefined(const char *subkey) 241*148c5f43SAlan Wright { 242*148c5f43SAlan Wright winreg_subkey_t *key; 243*148c5f43SAlan Wright 244*148c5f43SAlan Wright if ((key = malloc(sizeof (winreg_subkey_t))) != NULL) { 245*148c5f43SAlan Wright bzero(key, sizeof (winreg_subkey_t)); 246*148c5f43SAlan Wright (void) strlcpy(key->sk_name, subkey, MAXPATHLEN); 247*148c5f43SAlan Wright key->sk_predefined = B_TRUE; 248*148c5f43SAlan Wright 249*148c5f43SAlan Wright list_insert_tail(&winreg_keylist.kl_list, key); 250*148c5f43SAlan Wright ++winreg_keylist.kl_count; 251*148c5f43SAlan Wright } 252*148c5f43SAlan Wright } 253*148c5f43SAlan Wright 25489dc44ceSjose borrego static int 2557f667e74Sjose borrego winreg_s_OpenHKCR(void *arg, ndr_xa_t *mxa) 25689dc44ceSjose borrego { 2577f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKCR")); 25889dc44ceSjose borrego } 25989dc44ceSjose borrego 2607f667e74Sjose borrego static int 2617f667e74Sjose borrego winreg_s_OpenHKCU(void *arg, ndr_xa_t *mxa) 2627f667e74Sjose borrego { 2637f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKCU")); 26489dc44ceSjose borrego } 26589dc44ceSjose borrego 26689dc44ceSjose borrego static int 26789dc44ceSjose borrego winreg_s_OpenHKLM(void *arg, ndr_xa_t *mxa) 26889dc44ceSjose borrego { 2697f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKLM")); 27089dc44ceSjose borrego } 27189dc44ceSjose borrego 2727f667e74Sjose borrego static int 2737f667e74Sjose borrego winreg_s_OpenHKPD(void *arg, ndr_xa_t *mxa) 2747f667e74Sjose borrego { 2757f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKPD")); 2767f667e74Sjose borrego } 2777f667e74Sjose borrego 2787f667e74Sjose borrego static int 2797f667e74Sjose borrego winreg_s_OpenHKU(void *arg, ndr_xa_t *mxa) 2807f667e74Sjose borrego { 2817f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKU")); 2827f667e74Sjose borrego } 2837f667e74Sjose borrego 2847f667e74Sjose borrego static int 2857f667e74Sjose borrego winreg_s_OpenHKCC(void *arg, ndr_xa_t *mxa) 2867f667e74Sjose borrego { 2877f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKCC")); 2887f667e74Sjose borrego } 2897f667e74Sjose borrego 2907f667e74Sjose borrego static int 2917f667e74Sjose borrego winreg_s_OpenHKDD(void *arg, ndr_xa_t *mxa) 2927f667e74Sjose borrego { 2937f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKDD")); 2947f667e74Sjose borrego } 2957f667e74Sjose borrego 2967f667e74Sjose borrego static int 2977f667e74Sjose borrego winreg_s_OpenHKPT(void *arg, ndr_xa_t *mxa) 2987f667e74Sjose borrego { 2997f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKPT")); 3007f667e74Sjose borrego } 3017f667e74Sjose borrego 3027f667e74Sjose borrego static int 3037f667e74Sjose borrego winreg_s_OpenHKPN(void *arg, ndr_xa_t *mxa) 3047f667e74Sjose borrego { 3057f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKPN")); 30689dc44ceSjose borrego } 30789dc44ceSjose borrego 30889dc44ceSjose borrego /* 3097f667e74Sjose borrego * winreg_s_OpenHK 31089dc44ceSjose borrego * 3117f667e74Sjose borrego * Common code to open root HKEYs. 31289dc44ceSjose borrego */ 31389dc44ceSjose borrego static int 3147f667e74Sjose borrego winreg_s_OpenHK(void *arg, ndr_xa_t *mxa, const char *hkey) 31589dc44ceSjose borrego { 3167f667e74Sjose borrego struct winreg_OpenHKCR *param = arg; 31789dc44ceSjose borrego ndr_hdid_t *id; 31889dc44ceSjose borrego 3199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex); 3207f667e74Sjose borrego 3219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((id = winreg_alloc_id(mxa, hkey)) == NULL) { 32289dc44ceSjose borrego bzero(¶m->handle, sizeof (winreg_handle_t)); 32389dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 32489dc44ceSjose borrego } else { 32589dc44ceSjose borrego bcopy(id, ¶m->handle, sizeof (winreg_handle_t)); 32689dc44ceSjose borrego param->status = ERROR_SUCCESS; 32789dc44ceSjose borrego } 32889dc44ceSjose borrego 3299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 33089dc44ceSjose borrego return (NDR_DRC_OK); 33189dc44ceSjose borrego } 33289dc44ceSjose borrego 33389dc44ceSjose borrego /* 33489dc44ceSjose borrego * winreg_s_Close 33589dc44ceSjose borrego * 33689dc44ceSjose borrego * This is a request to close the WINREG interface specified by the 33789dc44ceSjose borrego * handle. We don't track handles (yet), so just zero out the handle 33889dc44ceSjose borrego * and return NDR_DRC_OK. Setting the handle to zero appears to be 33989dc44ceSjose borrego * standard behaviour. 34089dc44ceSjose borrego */ 34189dc44ceSjose borrego static int 34289dc44ceSjose borrego winreg_s_Close(void *arg, ndr_xa_t *mxa) 34389dc44ceSjose borrego { 34489dc44ceSjose borrego struct winreg_Close *param = arg; 34589dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 3469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 3479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex); 3489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States winreg_dealloc_id(mxa, id); 3499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 3509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 3519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States bzero(¶m->result_handle, sizeof (winreg_handle_t)); 3529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States param->status = ERROR_SUCCESS; 3539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NDR_DRC_OK); 3549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 3559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 3569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static ndr_hdid_t * 3579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States winreg_alloc_id(ndr_xa_t *mxa, const char *key) 3589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 3599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_handle_t *hd; 3609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_hdid_t *id; 3619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char *data; 3629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 3639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((data = strdup(key)) == NULL) 3649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NULL); 3659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 3669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((id = ndr_hdalloc(mxa, data)) == NULL) { 3679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States free(data); 3689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NULL); 3699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 3709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 3719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((hd = ndr_hdlookup(mxa, id)) != NULL) 3729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States hd->nh_data_free = free; 3739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 3749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (id); 3759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 3769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 3779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void 3789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States winreg_dealloc_id(ndr_xa_t *mxa, ndr_hdid_t *id) 3799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 3807f667e74Sjose borrego ndr_handle_t *hd; 3817f667e74Sjose borrego 3827f667e74Sjose borrego if ((hd = ndr_hdlookup(mxa, id)) != NULL) { 3837f667e74Sjose borrego free(hd->nh_data); 3847f667e74Sjose borrego hd->nh_data = NULL; 3857f667e74Sjose borrego } 38689dc44ceSjose borrego 38789dc44ceSjose borrego ndr_hdfree(mxa, id); 38889dc44ceSjose borrego } 38989dc44ceSjose borrego 39089dc44ceSjose borrego /* 39189dc44ceSjose borrego * winreg_s_CreateKey 39289dc44ceSjose borrego */ 39389dc44ceSjose borrego static int 39489dc44ceSjose borrego winreg_s_CreateKey(void *arg, ndr_xa_t *mxa) 39589dc44ceSjose borrego { 39689dc44ceSjose borrego struct winreg_CreateKey *param = arg; 39789dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 39889dc44ceSjose borrego ndr_handle_t *hd; 39989dc44ceSjose borrego winreg_subkey_t *key; 40089dc44ceSjose borrego char *subkey; 40189dc44ceSjose borrego DWORD *action; 40289dc44ceSjose borrego 40389dc44ceSjose borrego subkey = (char *)param->subkey.str; 40489dc44ceSjose borrego 40589dc44ceSjose borrego if (!ndr_is_admin(mxa) || (subkey == NULL)) { 40689dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey)); 40789dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 40889dc44ceSjose borrego return (NDR_DRC_OK); 40989dc44ceSjose borrego } 41089dc44ceSjose borrego 4119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex); 4129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 41389dc44ceSjose borrego hd = ndr_hdlookup(mxa, id); 41489dc44ceSjose borrego if (hd == NULL) { 4159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 41689dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey)); 41789dc44ceSjose borrego param->status = ERROR_INVALID_HANDLE; 41889dc44ceSjose borrego return (NDR_DRC_OK); 41989dc44ceSjose borrego } 42089dc44ceSjose borrego 42189dc44ceSjose borrego if ((action = NDR_NEW(mxa, DWORD)) == NULL) { 4229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 42389dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey)); 42489dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 42589dc44ceSjose borrego return (NDR_DRC_OK); 42689dc44ceSjose borrego } 42789dc44ceSjose borrego 42889dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list)) 42989dc44ceSjose borrego goto new_key; 43089dc44ceSjose borrego 43189dc44ceSjose borrego /* 43289dc44ceSjose borrego * Check for an existing key. 43389dc44ceSjose borrego */ 43489dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 43589dc44ceSjose borrego do { 43689dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) { 43789dc44ceSjose borrego bcopy(&key->sk_handle, ¶m->result_handle, 43889dc44ceSjose borrego sizeof (winreg_handle_t)); 4399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 4409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 44189dc44ceSjose borrego *action = WINREG_ACTION_EXISTING_KEY; 44289dc44ceSjose borrego param->action = action; 44389dc44ceSjose borrego param->status = ERROR_SUCCESS; 44489dc44ceSjose borrego return (NDR_DRC_OK); 44589dc44ceSjose borrego } 44689dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 44789dc44ceSjose borrego 44889dc44ceSjose borrego new_key: 44989dc44ceSjose borrego /* 45089dc44ceSjose borrego * Create a new key. 45189dc44ceSjose borrego */ 4529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((id = winreg_alloc_id(mxa, subkey)) == NULL) 4539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States goto no_memory; 4547f667e74Sjose borrego 4559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((key = malloc(sizeof (winreg_subkey_t))) == NULL) { 4569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States winreg_dealloc_id(mxa, id); 4579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States goto no_memory; 45889dc44ceSjose borrego } 45989dc44ceSjose borrego 46089dc44ceSjose borrego bcopy(id, &key->sk_handle, sizeof (ndr_hdid_t)); 46189dc44ceSjose borrego (void) strlcpy(key->sk_name, subkey, MAXPATHLEN); 46289dc44ceSjose borrego key->sk_predefined = B_FALSE; 46389dc44ceSjose borrego list_insert_tail(&winreg_keylist.kl_list, key); 46489dc44ceSjose borrego ++winreg_keylist.kl_count; 46589dc44ceSjose borrego 46689dc44ceSjose borrego bcopy(id, ¶m->result_handle, sizeof (winreg_handle_t)); 4679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 4689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 46989dc44ceSjose borrego *action = WINREG_ACTION_NEW_KEY; 47089dc44ceSjose borrego param->action = action; 47189dc44ceSjose borrego param->status = ERROR_SUCCESS; 47289dc44ceSjose borrego return (NDR_DRC_OK); 4739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 4749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States no_memory: 4759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 4769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States bzero(param, sizeof (struct winreg_CreateKey)); 4779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States param->status = ERROR_NOT_ENOUGH_MEMORY; 4789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NDR_DRC_OK); 47989dc44ceSjose borrego } 48089dc44ceSjose borrego 48189dc44ceSjose borrego /* 48289dc44ceSjose borrego * winreg_s_DeleteKey 48389dc44ceSjose borrego */ 48489dc44ceSjose borrego static int 48589dc44ceSjose borrego winreg_s_DeleteKey(void *arg, ndr_xa_t *mxa) 48689dc44ceSjose borrego { 48789dc44ceSjose borrego struct winreg_DeleteKey *param = arg; 48889dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 48989dc44ceSjose borrego winreg_subkey_t *key; 49089dc44ceSjose borrego char *subkey; 49189dc44ceSjose borrego 49289dc44ceSjose borrego subkey = (char *)param->subkey.str; 49389dc44ceSjose borrego 49489dc44ceSjose borrego if (!ndr_is_admin(mxa) || (subkey == NULL)) { 49589dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 49689dc44ceSjose borrego return (NDR_DRC_OK); 49789dc44ceSjose borrego } 49889dc44ceSjose borrego 4999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex); 5009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 50189dc44ceSjose borrego if ((ndr_hdlookup(mxa, id) == NULL) || 50289dc44ceSjose borrego list_is_empty(&winreg_keylist.kl_list) || 50389dc44ceSjose borrego winreg_key_has_subkey(subkey)) { 5049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 50589dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 50689dc44ceSjose borrego return (NDR_DRC_OK); 50789dc44ceSjose borrego } 50889dc44ceSjose borrego 50989dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 51089dc44ceSjose borrego do { 51189dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) { 51289dc44ceSjose borrego if (key->sk_predefined == B_TRUE) { 51389dc44ceSjose borrego /* Predefined keys cannot be deleted */ 51489dc44ceSjose borrego break; 51589dc44ceSjose borrego } 51689dc44ceSjose borrego 51789dc44ceSjose borrego list_remove(&winreg_keylist.kl_list, key); 51889dc44ceSjose borrego --winreg_keylist.kl_count; 5199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States winreg_dealloc_id(mxa, &key->sk_handle); 52089dc44ceSjose borrego free(key); 5219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 5229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 52389dc44ceSjose borrego param->status = ERROR_SUCCESS; 52489dc44ceSjose borrego return (NDR_DRC_OK); 52589dc44ceSjose borrego } 52689dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 52789dc44ceSjose borrego 5289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 52989dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 53089dc44ceSjose borrego return (NDR_DRC_OK); 53189dc44ceSjose borrego } 53289dc44ceSjose borrego 5339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 5349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Call with the winreg_mutex held. 5359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 53689dc44ceSjose borrego static boolean_t 53789dc44ceSjose borrego winreg_key_has_subkey(const char *subkey) 53889dc44ceSjose borrego { 53989dc44ceSjose borrego winreg_subkey_t *key; 54089dc44ceSjose borrego int keylen; 54189dc44ceSjose borrego 54289dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list)) 54389dc44ceSjose borrego return (B_FALSE); 54489dc44ceSjose borrego 54589dc44ceSjose borrego keylen = strlen(subkey); 54689dc44ceSjose borrego 54789dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 54889dc44ceSjose borrego do { 54989dc44ceSjose borrego if (strncasecmp(subkey, key->sk_name, keylen) == 0) { 55089dc44ceSjose borrego /* 55189dc44ceSjose borrego * Potential match. If sk_name is longer than 55289dc44ceSjose borrego * subkey, then sk_name is a subkey of our key. 55389dc44ceSjose borrego */ 55489dc44ceSjose borrego if (keylen < strlen(key->sk_name)) 55589dc44ceSjose borrego return (B_TRUE); 55689dc44ceSjose borrego } 55789dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 55889dc44ceSjose borrego 55989dc44ceSjose borrego return (B_FALSE); 56089dc44ceSjose borrego } 56189dc44ceSjose borrego 5629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 5639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Call with the winreg_mutex held. 5649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 56589dc44ceSjose borrego static char * 5667f667e74Sjose borrego winreg_enum_subkey(ndr_xa_t *mxa, const char *subkey, uint32_t index) 56789dc44ceSjose borrego { 56889dc44ceSjose borrego winreg_subkey_t *key; 5697f667e74Sjose borrego char *entry; 5707f667e74Sjose borrego char *p; 5717f667e74Sjose borrego int subkeylen; 5727f667e74Sjose borrego int count = 0; 57389dc44ceSjose borrego 57489dc44ceSjose borrego if (subkey == NULL) 57589dc44ceSjose borrego return (NULL); 57689dc44ceSjose borrego 57789dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list)) 57889dc44ceSjose borrego return (NULL); 57989dc44ceSjose borrego 5807f667e74Sjose borrego subkeylen = strlen(subkey); 5817f667e74Sjose borrego 5827f667e74Sjose borrego for (key = list_head(&winreg_keylist.kl_list); 5837f667e74Sjose borrego key != NULL; key = list_next(&winreg_keylist.kl_list, key)) { 5847f667e74Sjose borrego if (strncasecmp(subkey, key->sk_name, subkeylen) == 0) { 5857f667e74Sjose borrego p = key->sk_name + subkeylen; 5867f667e74Sjose borrego 5877f667e74Sjose borrego if ((*p != '\\') || (*p == '\0')) { 5887f667e74Sjose borrego /* 5897f667e74Sjose borrego * Not the same subkey or an exact match. 5907f667e74Sjose borrego * We're looking for children of subkey. 5917f667e74Sjose borrego */ 5927f667e74Sjose borrego continue; 59389dc44ceSjose borrego } 5947f667e74Sjose borrego 5957f667e74Sjose borrego ++p; 5967f667e74Sjose borrego 5977f667e74Sjose borrego if (count < index) { 5987f667e74Sjose borrego ++count; 5997f667e74Sjose borrego continue; 6007f667e74Sjose borrego } 6017f667e74Sjose borrego 6027f667e74Sjose borrego if ((entry = NDR_STRDUP(mxa, p)) == NULL) 6037f667e74Sjose borrego return (NULL); 6047f667e74Sjose borrego 6057f667e74Sjose borrego if ((p = strchr(entry, '\\')) != NULL) 6067f667e74Sjose borrego *p = '\0'; 6077f667e74Sjose borrego 6087f667e74Sjose borrego return (entry); 6097f667e74Sjose borrego } 6107f667e74Sjose borrego } 61189dc44ceSjose borrego 61289dc44ceSjose borrego return (NULL); 61389dc44ceSjose borrego } 61489dc44ceSjose borrego 61589dc44ceSjose borrego /* 61689dc44ceSjose borrego * winreg_s_DeleteValue 61789dc44ceSjose borrego */ 61889dc44ceSjose borrego /*ARGSUSED*/ 61989dc44ceSjose borrego static int 62089dc44ceSjose borrego winreg_s_DeleteValue(void *arg, ndr_xa_t *mxa) 62189dc44ceSjose borrego { 62289dc44ceSjose borrego struct winreg_DeleteValue *param = arg; 62389dc44ceSjose borrego 62489dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 62589dc44ceSjose borrego return (NDR_DRC_OK); 62689dc44ceSjose borrego } 62789dc44ceSjose borrego 62889dc44ceSjose borrego /* 62989dc44ceSjose borrego * winreg_s_EnumKey 63089dc44ceSjose borrego */ 63189dc44ceSjose borrego static int 63289dc44ceSjose borrego winreg_s_EnumKey(void *arg, ndr_xa_t *mxa) 63389dc44ceSjose borrego { 63489dc44ceSjose borrego struct winreg_EnumKey *param = arg; 63589dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 6367f667e74Sjose borrego ndr_handle_t *hd; 6377f667e74Sjose borrego char *subkey; 6387f667e74Sjose borrego char *name = NULL; 63989dc44ceSjose borrego 6409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex); 6419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 6427f667e74Sjose borrego if ((hd = ndr_hdlookup(mxa, id)) != NULL) 6437f667e74Sjose borrego name = hd->nh_data; 6447f667e74Sjose borrego 6457f667e74Sjose borrego if (hd == NULL || name == NULL) { 6469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 64789dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey)); 64889dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS; 64989dc44ceSjose borrego return (NDR_DRC_OK); 65089dc44ceSjose borrego } 65189dc44ceSjose borrego 6527f667e74Sjose borrego subkey = winreg_enum_subkey(mxa, name, param->index); 6537f667e74Sjose borrego if (subkey == NULL) { 6549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 65589dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey)); 65689dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS; 65789dc44ceSjose borrego return (NDR_DRC_OK); 65889dc44ceSjose borrego } 65989dc44ceSjose borrego 6607f667e74Sjose borrego if (NDR_MSTRING(mxa, subkey, (ndr_mstring_t *)¶m->name_out) == -1) { 6619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 66289dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey)); 66389dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 66489dc44ceSjose borrego return (NDR_DRC_OK); 66589dc44ceSjose borrego } 6669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 6679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 6689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 6697f667e74Sjose borrego /* 6707f667e74Sjose borrego * This request requires that the length includes the null. 6717f667e74Sjose borrego */ 6727f667e74Sjose borrego param->name_out.length = param->name_out.allosize; 67389dc44ceSjose borrego param->status = ERROR_SUCCESS; 67489dc44ceSjose borrego return (NDR_DRC_OK); 67589dc44ceSjose borrego } 67689dc44ceSjose borrego 67789dc44ceSjose borrego /* 67889dc44ceSjose borrego * winreg_s_EnumValue 67989dc44ceSjose borrego */ 68089dc44ceSjose borrego static int 68189dc44ceSjose borrego winreg_s_EnumValue(void *arg, ndr_xa_t *mxa) 68289dc44ceSjose borrego { 68389dc44ceSjose borrego struct winreg_EnumValue *param = arg; 68489dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 68589dc44ceSjose borrego 68689dc44ceSjose borrego if (ndr_hdlookup(mxa, id) == NULL) { 68789dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumValue)); 68889dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS; 68989dc44ceSjose borrego return (NDR_DRC_OK); 69089dc44ceSjose borrego } 69189dc44ceSjose borrego 69289dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumValue)); 69389dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS; 69489dc44ceSjose borrego return (NDR_DRC_OK); 69589dc44ceSjose borrego } 69689dc44ceSjose borrego 69789dc44ceSjose borrego /* 69889dc44ceSjose borrego * winreg_s_FlushKey 69989dc44ceSjose borrego * 70089dc44ceSjose borrego * Flush the attributes associated with the specified open key to disk. 70189dc44ceSjose borrego */ 70289dc44ceSjose borrego static int 70389dc44ceSjose borrego winreg_s_FlushKey(void *arg, ndr_xa_t *mxa) 70489dc44ceSjose borrego { 70589dc44ceSjose borrego struct winreg_FlushKey *param = arg; 70689dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 70789dc44ceSjose borrego 70889dc44ceSjose borrego if (ndr_hdlookup(mxa, id) == NULL) 70989dc44ceSjose borrego param->status = ERROR_INVALID_HANDLE; 71089dc44ceSjose borrego else 71189dc44ceSjose borrego param->status = ERROR_SUCCESS; 71289dc44ceSjose borrego 71389dc44ceSjose borrego return (NDR_DRC_OK); 71489dc44ceSjose borrego } 71589dc44ceSjose borrego 71689dc44ceSjose borrego /* 71789dc44ceSjose borrego * winreg_s_GetKeySec 71889dc44ceSjose borrego */ 71989dc44ceSjose borrego static int 72089dc44ceSjose borrego winreg_s_GetKeySec(void *arg, ndr_xa_t *mxa) 72189dc44ceSjose borrego { 72296a62adaSjoyce mcintosh static struct winreg_secdesc error_sd; 72389dc44ceSjose borrego struct winreg_GetKeySec *param = arg; 724f96bd5c8SAlan Wright struct winreg_value *sd_buf; 725f96bd5c8SAlan Wright smb_sd_t sd; 726f96bd5c8SAlan Wright uint32_t sd_len; 727f96bd5c8SAlan Wright uint32_t status; 72889dc44ceSjose borrego 729f96bd5c8SAlan Wright bzero(&sd, sizeof (smb_sd_t)); 730f96bd5c8SAlan Wright 731f96bd5c8SAlan Wright if ((status = winreg_sd_format(&sd)) != ERROR_SUCCESS) 732f96bd5c8SAlan Wright goto winreg_getkeysec_error; 733f96bd5c8SAlan Wright 734f96bd5c8SAlan Wright sd_len = smb_sd_len(&sd, SMB_ALL_SECINFO); 73596a62adaSjoyce mcintosh sd_buf = NDR_MALLOC(mxa, sd_len + sizeof (struct winreg_value)); 736f96bd5c8SAlan Wright 737f96bd5c8SAlan Wright param->sd = NDR_MALLOC(mxa, sizeof (struct winreg_secdesc)); 73896a62adaSjoyce mcintosh if ((param->sd == NULL) || (sd_buf == NULL)) { 739f96bd5c8SAlan Wright status = ERROR_NOT_ENOUGH_MEMORY; 740f96bd5c8SAlan Wright goto winreg_getkeysec_error; 741f96bd5c8SAlan Wright } 742f96bd5c8SAlan Wright 743f96bd5c8SAlan Wright param->sd->sd_len = sd_len; 744f96bd5c8SAlan Wright param->sd->sd_size = sd_len; 745f96bd5c8SAlan Wright param->sd->sd_buf = sd_buf; 746f96bd5c8SAlan Wright 747f96bd5c8SAlan Wright sd_buf->vc_first_is = 0; 748f96bd5c8SAlan Wright sd_buf->vc_length_is = sd_len; 749f96bd5c8SAlan Wright param->status = srvsvc_sd_set_relative(&sd, sd_buf->value); 750f96bd5c8SAlan Wright 751f96bd5c8SAlan Wright smb_sd_term(&sd); 75289dc44ceSjose borrego return (NDR_DRC_OK); 753f96bd5c8SAlan Wright 754f96bd5c8SAlan Wright winreg_getkeysec_error: 755f96bd5c8SAlan Wright smb_sd_term(&sd); 756f96bd5c8SAlan Wright bzero(param, sizeof (struct winreg_GetKeySec)); 75796a62adaSjoyce mcintosh param->sd = &error_sd; 758f96bd5c8SAlan Wright param->status = status; 759f96bd5c8SAlan Wright return (NDR_DRC_OK); 760f96bd5c8SAlan Wright } 761f96bd5c8SAlan Wright 762f96bd5c8SAlan Wright static uint32_t 763f96bd5c8SAlan Wright winreg_sd_format(smb_sd_t *sd) 764f96bd5c8SAlan Wright { 765f96bd5c8SAlan Wright smb_fssd_t fs_sd; 766f96bd5c8SAlan Wright acl_t *acl; 767f96bd5c8SAlan Wright uint32_t status = ERROR_SUCCESS; 768f96bd5c8SAlan Wright 769f96bd5c8SAlan Wright if (acl_fromtext("owner@:rwxpdDaARWcCos::allow", &acl) != 0) 770f96bd5c8SAlan Wright return (ERROR_NOT_ENOUGH_MEMORY); 771f96bd5c8SAlan Wright 772f96bd5c8SAlan Wright smb_fssd_init(&fs_sd, SMB_ALL_SECINFO, SMB_FSSD_FLAGS_DIR); 773f96bd5c8SAlan Wright fs_sd.sd_uid = 0; 774f96bd5c8SAlan Wright fs_sd.sd_gid = 0; 775f96bd5c8SAlan Wright fs_sd.sd_zdacl = acl; 776f96bd5c8SAlan Wright fs_sd.sd_zsacl = NULL; 777f96bd5c8SAlan Wright 778f96bd5c8SAlan Wright if (smb_sd_fromfs(&fs_sd, sd) != NT_STATUS_SUCCESS) 779f96bd5c8SAlan Wright status = ERROR_ACCESS_DENIED; 780f96bd5c8SAlan Wright smb_fssd_term(&fs_sd); 781f96bd5c8SAlan Wright return (status); 78289dc44ceSjose borrego } 78389dc44ceSjose borrego 78489dc44ceSjose borrego /* 78589dc44ceSjose borrego * winreg_s_NotifyChange 78689dc44ceSjose borrego */ 78789dc44ceSjose borrego static int 78889dc44ceSjose borrego winreg_s_NotifyChange(void *arg, ndr_xa_t *mxa) 78989dc44ceSjose borrego { 79089dc44ceSjose borrego struct winreg_NotifyChange *param = arg; 79189dc44ceSjose borrego 79289dc44ceSjose borrego if (ndr_is_admin(mxa)) 79389dc44ceSjose borrego param->status = ERROR_SUCCESS; 79489dc44ceSjose borrego else 79589dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 79689dc44ceSjose borrego 79789dc44ceSjose borrego return (NDR_DRC_OK); 79889dc44ceSjose borrego } 79989dc44ceSjose borrego 80089dc44ceSjose borrego /* 80189dc44ceSjose borrego * winreg_s_OpenKey 80289dc44ceSjose borrego * 80389dc44ceSjose borrego * This is a request to open a windows registry key. 80489dc44ceSjose borrego * If we recognize the key, we return a handle. 80589dc44ceSjose borrego * 80689dc44ceSjose borrego * Returns: 80789dc44ceSjose borrego * ERROR_SUCCESS Valid handle returned. 80889dc44ceSjose borrego * ERROR_FILE_NOT_FOUND No key or unable to allocate a handle. 80989dc44ceSjose borrego */ 81089dc44ceSjose borrego static int 81189dc44ceSjose borrego winreg_s_OpenKey(void *arg, ndr_xa_t *mxa) 81289dc44ceSjose borrego { 81389dc44ceSjose borrego struct winreg_OpenKey *param = arg; 814b1352070SAlan Wright ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 815b1352070SAlan Wright ndr_handle_t *hd; 81689dc44ceSjose borrego char *subkey = (char *)param->name.str; 81789dc44ceSjose borrego winreg_subkey_t *key; 8189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex); 82089dc44ceSjose borrego 821b1352070SAlan Wright if (subkey == NULL || *subkey == '\0') { 822b1352070SAlan Wright if ((hd = ndr_hdlookup(mxa, id)) != NULL) 823b1352070SAlan Wright subkey = hd->nh_data; 824b1352070SAlan Wright } 825b1352070SAlan Wright 826b1352070SAlan Wright id = NULL; 827b1352070SAlan Wright 8287f667e74Sjose borrego if (subkey == NULL || list_is_empty(&winreg_keylist.kl_list)) { 8299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 83089dc44ceSjose borrego bzero(¶m->result_handle, sizeof (winreg_handle_t)); 83189dc44ceSjose borrego param->status = ERROR_FILE_NOT_FOUND; 83289dc44ceSjose borrego return (NDR_DRC_OK); 83389dc44ceSjose borrego } 83489dc44ceSjose borrego 83589dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 83689dc44ceSjose borrego do { 83789dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) { 8389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (key->sk_predefined == B_TRUE) 8399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States id = winreg_alloc_id(mxa, subkey); 8409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States else 84189dc44ceSjose borrego id = &key->sk_handle; 84289dc44ceSjose borrego 84389dc44ceSjose borrego if (id == NULL) 84489dc44ceSjose borrego break; 84589dc44ceSjose borrego 84689dc44ceSjose borrego bcopy(id, ¶m->result_handle, 84789dc44ceSjose borrego sizeof (winreg_handle_t)); 8489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 85089dc44ceSjose borrego param->status = ERROR_SUCCESS; 85189dc44ceSjose borrego return (NDR_DRC_OK); 85289dc44ceSjose borrego } 85389dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 85489dc44ceSjose borrego 8559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex); 85689dc44ceSjose borrego bzero(¶m->result_handle, sizeof (winreg_handle_t)); 85789dc44ceSjose borrego param->status = ERROR_FILE_NOT_FOUND; 85889dc44ceSjose borrego return (NDR_DRC_OK); 85989dc44ceSjose borrego } 86089dc44ceSjose borrego 86189dc44ceSjose borrego /* 86289dc44ceSjose borrego * winreg_s_QueryKey 86389dc44ceSjose borrego */ 86489dc44ceSjose borrego /*ARGSUSED*/ 86589dc44ceSjose borrego static int 86689dc44ceSjose borrego winreg_s_QueryKey(void *arg, ndr_xa_t *mxa) 86789dc44ceSjose borrego { 86889dc44ceSjose borrego struct winreg_QueryKey *param = arg; 86989dc44ceSjose borrego int rc; 87089dc44ceSjose borrego winreg_string_t *name; 87189dc44ceSjose borrego 87289dc44ceSjose borrego name = (winreg_string_t *)¶m->name; 87389dc44ceSjose borrego bzero(param, sizeof (struct winreg_QueryKey)); 8749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 87589dc44ceSjose borrego if ((name = NDR_NEW(mxa, winreg_string_t)) != NULL) 87689dc44ceSjose borrego rc = NDR_MSTRING(mxa, "", (ndr_mstring_t *)name); 87789dc44ceSjose borrego 87889dc44ceSjose borrego if ((name == NULL) || (rc != 0)) { 87989dc44ceSjose borrego bzero(param, sizeof (struct winreg_QueryKey)); 88089dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 88189dc44ceSjose borrego return (NDR_DRC_OK); 88289dc44ceSjose borrego } 88389dc44ceSjose borrego 88489dc44ceSjose borrego param->status = ERROR_SUCCESS; 88589dc44ceSjose borrego return (NDR_DRC_OK); 88689dc44ceSjose borrego } 88789dc44ceSjose borrego 88889dc44ceSjose borrego /* 88989dc44ceSjose borrego * winreg_s_QueryValue 89089dc44ceSjose borrego * 89189dc44ceSjose borrego * This is a request to get the value associated with a specified name. 89289dc44ceSjose borrego * 89389dc44ceSjose borrego * Returns: 89489dc44ceSjose borrego * ERROR_SUCCESS Value returned. 89589dc44ceSjose borrego * ERROR_FILE_NOT_FOUND PrimaryModule is not supported. 89689dc44ceSjose borrego * ERROR_CANTREAD No such name or memory problem. 89789dc44ceSjose borrego */ 89889dc44ceSjose borrego static int 89989dc44ceSjose borrego winreg_s_QueryValue(void *arg, ndr_xa_t *mxa) 90089dc44ceSjose borrego { 90189dc44ceSjose borrego struct winreg_QueryValue *param = arg; 90289dc44ceSjose borrego struct winreg_value *pv; 90389dc44ceSjose borrego char *name; 90489dc44ceSjose borrego char *value; 90589dc44ceSjose borrego DWORD slen; 90689dc44ceSjose borrego DWORD msize; 90789dc44ceSjose borrego 90889dc44ceSjose borrego name = (char *)param->value_name.str; 90989dc44ceSjose borrego 91089dc44ceSjose borrego if (strcasecmp(name, "PrimaryModule") == 0) { 91189dc44ceSjose borrego param->status = ERROR_FILE_NOT_FOUND; 91289dc44ceSjose borrego return (NDR_DRC_OK); 91389dc44ceSjose borrego } 91489dc44ceSjose borrego 91589dc44ceSjose borrego if ((value = winreg_lookup_value(name)) == NULL) { 91689dc44ceSjose borrego param->status = ERROR_CANTREAD; 91789dc44ceSjose borrego return (NDR_DRC_OK); 91889dc44ceSjose borrego } 91989dc44ceSjose borrego 920bbf6f00cSJordan Brown slen = smb_wcequiv_strlen(value) + sizeof (smb_wchar_t); 92189dc44ceSjose borrego msize = sizeof (struct winreg_value) + slen; 92289dc44ceSjose borrego 92389dc44ceSjose borrego param->value = (struct winreg_value *)NDR_MALLOC(mxa, msize); 92489dc44ceSjose borrego param->type = NDR_NEW(mxa, DWORD); 92589dc44ceSjose borrego param->value_size = NDR_NEW(mxa, DWORD); 92689dc44ceSjose borrego param->value_size_total = NDR_NEW(mxa, DWORD); 92789dc44ceSjose borrego 92889dc44ceSjose borrego if (param->value == NULL || param->type == NULL || 92989dc44ceSjose borrego param->value_size == NULL || param->value_size_total == NULL) { 93089dc44ceSjose borrego param->status = ERROR_CANTREAD; 93189dc44ceSjose borrego return (NDR_DRC_OK); 93289dc44ceSjose borrego } 93389dc44ceSjose borrego 93489dc44ceSjose borrego bzero(param->value, msize); 93589dc44ceSjose borrego pv = param->value; 93689dc44ceSjose borrego pv->vc_first_is = 0; 93789dc44ceSjose borrego pv->vc_length_is = slen; 93889dc44ceSjose borrego /*LINTED E_BAD_PTR_CAST_ALIGN*/ 939bbf6f00cSJordan Brown (void) ndr_mbstowcs(NULL, (smb_wchar_t *)pv->value, value, slen); 94089dc44ceSjose borrego 94189dc44ceSjose borrego *param->type = 1; 94289dc44ceSjose borrego *param->value_size = slen; 94389dc44ceSjose borrego *param->value_size_total = slen; 94489dc44ceSjose borrego 94589dc44ceSjose borrego param->status = ERROR_SUCCESS; 94689dc44ceSjose borrego return (NDR_DRC_OK); 94789dc44ceSjose borrego } 94889dc44ceSjose borrego 94989dc44ceSjose borrego /* 95089dc44ceSjose borrego * Lookup a name in the registry and return the associated value. 95189dc44ceSjose borrego * Our registry is a case-insensitive, name-value pair table. 95289dc44ceSjose borrego * 95389dc44ceSjose borrego * Windows ProductType: WinNT, ServerNT, LanmanNT. 95489dc44ceSjose borrego * Windows NT4.0 workstation: WinNT 95589dc44ceSjose borrego * Windows NT4.0 server: ServerNT 95689dc44ceSjose borrego * 95789dc44ceSjose borrego * If LanmanNT is used here, Windows 2000 sends LsarQueryInfoPolicy 95889dc44ceSjose borrego * with info level 6, which we don't support. If we use ServerNT 95989dc44ceSjose borrego * (as reported by NT4.0 Server) Windows 2000 send requests for 96089dc44ceSjose borrego * levels 3 and 5, which are support. 96189dc44ceSjose borrego * 96289dc44ceSjose borrego * On success, returns a pointer to the value. Otherwise returns 96389dc44ceSjose borrego * a null pointer. 96489dc44ceSjose borrego */ 96589dc44ceSjose borrego static char * 96689dc44ceSjose borrego winreg_lookup_value(const char *name) 96789dc44ceSjose borrego { 96889dc44ceSjose borrego static struct registry { 96989dc44ceSjose borrego char *name; 97089dc44ceSjose borrego char *value; 97189dc44ceSjose borrego } registry[] = { 9729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { "SystemRoot", "C:\\" }, 9739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { "CurrentVersion", winreg_sysver }, 97489dc44ceSjose borrego { "ProductType", "ServerNT" }, 9759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { "Sources", winreg_sysname }, /* product name */ 9769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { "EventMessageFile", "C:\\windows\\system32\\eventlog.dll" } 97789dc44ceSjose borrego }; 97889dc44ceSjose borrego 97989dc44ceSjose borrego int i; 98089dc44ceSjose borrego 98189dc44ceSjose borrego for (i = 0; i < sizeof (registry)/sizeof (registry[0]); ++i) { 9829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (strcasecmp(registry[i].name, name) == 0) 98389dc44ceSjose borrego return (registry[i].value); 98489dc44ceSjose borrego } 98589dc44ceSjose borrego 98689dc44ceSjose borrego return (NULL); 98789dc44ceSjose borrego } 98889dc44ceSjose borrego 98989dc44ceSjose borrego /* 99089dc44ceSjose borrego * winreg_s_SetKeySec 99189dc44ceSjose borrego */ 99289dc44ceSjose borrego /*ARGSUSED*/ 99389dc44ceSjose borrego static int 99489dc44ceSjose borrego winreg_s_SetKeySec(void *arg, ndr_xa_t *mxa) 99589dc44ceSjose borrego { 99689dc44ceSjose borrego struct winreg_SetKeySec *param = arg; 99789dc44ceSjose borrego 99889dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 99989dc44ceSjose borrego return (NDR_DRC_OK); 100089dc44ceSjose borrego } 100189dc44ceSjose borrego 100289dc44ceSjose borrego /* 100389dc44ceSjose borrego * winreg_s_CreateValue 100489dc44ceSjose borrego */ 100589dc44ceSjose borrego /*ARGSUSED*/ 100689dc44ceSjose borrego static int 100789dc44ceSjose borrego winreg_s_CreateValue(void *arg, ndr_xa_t *mxa) 100889dc44ceSjose borrego { 100989dc44ceSjose borrego struct winreg_CreateValue *param = arg; 101089dc44ceSjose borrego 101189dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 101289dc44ceSjose borrego return (NDR_DRC_OK); 101389dc44ceSjose borrego } 101489dc44ceSjose borrego 101589dc44ceSjose borrego /* 101689dc44ceSjose borrego * winreg_s_Shutdown 101789dc44ceSjose borrego * 101889dc44ceSjose borrego * Attempt to shutdown or reboot the system: access denied. 101989dc44ceSjose borrego */ 102089dc44ceSjose borrego /*ARGSUSED*/ 102189dc44ceSjose borrego static int 102289dc44ceSjose borrego winreg_s_Shutdown(void *arg, ndr_xa_t *mxa) 102389dc44ceSjose borrego { 102489dc44ceSjose borrego struct winreg_Shutdown *param = arg; 102589dc44ceSjose borrego 102689dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 102789dc44ceSjose borrego return (NDR_DRC_OK); 102889dc44ceSjose borrego } 102989dc44ceSjose borrego 103089dc44ceSjose borrego /* 103189dc44ceSjose borrego * winreg_s_AbortShutdown 103289dc44ceSjose borrego * 103389dc44ceSjose borrego * Abort a shutdown request. 103489dc44ceSjose borrego */ 103589dc44ceSjose borrego static int 103689dc44ceSjose borrego winreg_s_AbortShutdown(void *arg, ndr_xa_t *mxa) 103789dc44ceSjose borrego { 103889dc44ceSjose borrego struct winreg_AbortShutdown *param = arg; 103989dc44ceSjose borrego 104089dc44ceSjose borrego if (ndr_is_admin(mxa)) 104189dc44ceSjose borrego param->status = ERROR_SUCCESS; 104289dc44ceSjose borrego else 104389dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 104489dc44ceSjose borrego 104589dc44ceSjose borrego return (NDR_DRC_OK); 104689dc44ceSjose borrego } 104789dc44ceSjose borrego 104889dc44ceSjose borrego /* 104989dc44ceSjose borrego * winreg_s_GetVersion 105089dc44ceSjose borrego * 105189dc44ceSjose borrego * Return the windows registry version. The current version is 5. 105289dc44ceSjose borrego * This call is usually made prior to enumerating or querying registry 105389dc44ceSjose borrego * keys or values. 105489dc44ceSjose borrego */ 105589dc44ceSjose borrego /*ARGSUSED*/ 105689dc44ceSjose borrego static int 105789dc44ceSjose borrego winreg_s_GetVersion(void *arg, ndr_xa_t *mxa) 105889dc44ceSjose borrego { 105989dc44ceSjose borrego struct winreg_GetVersion *param = arg; 106089dc44ceSjose borrego 106189dc44ceSjose borrego param->version = 5; 106289dc44ceSjose borrego param->status = ERROR_SUCCESS; 106389dc44ceSjose borrego return (NDR_DRC_OK); 106489dc44ceSjose borrego } 1065