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 */ 2189dc44ceSjose borrego /* 2289dc44ceSjose borrego * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2389dc44ceSjose borrego * Use is subject to license terms. 2489dc44ceSjose borrego */ 2589dc44ceSjose borrego 2689dc44ceSjose borrego /* 2789dc44ceSjose borrego * Windows Registry RPC (WINREG) server-side interface. 2889dc44ceSjose borrego * 29*7f667e74Sjose borrego * The registry is a database with a hierarchical structure similar to 30*7f667e74Sjose borrego * a file system, with keys in place of directories and values in place 31*7f667e74Sjose borrego * of files. The top level keys are known as root keys and each key can 32*7f667e74Sjose borrego * contain subkeys and values. As with directories and sub-directories, 33*7f667e74Sjose borrego * the terms key and subkey are used interchangeably. Values, analogous 34*7f667e74Sjose borrego * to files, contain data. 3589dc44ceSjose borrego * 36*7f667e74Sjose borrego * A specific subkey can be identifies by its fully qualified name (FQN), 37*7f667e74Sjose borrego * which is analogous to a file system path. In the registry, the key 38*7f667e74Sjose borrego * separator is the '\' character, which is reserved and cannot appear 39*7f667e74Sjose borrego * in key or value names. Registry names are case-insensitive. 40*7f667e74Sjose borrego * 41*7f667e74Sjose borrego * For example: HKEY_LOCAL_MACHINE\System\CurrentControlSet 42*7f667e74Sjose borrego * 43*7f667e74Sjose borrego * The HKEY_LOCAL_MACHINE root key contains a subkey call System, and 44*7f667e74Sjose borrego * System contains a subkey called CurrentControlSet. 45*7f667e74Sjose borrego * 46*7f667e74Sjose 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/ntstatus.h> 5489dc44ceSjose borrego #include <smbsrv/nterror.h> 5589dc44ceSjose borrego #include <smbsrv/nmpipes.h> 5689dc44ceSjose borrego #include <smbsrv/libmlsvc.h> 5789dc44ceSjose borrego #include <smbsrv/ndl/winreg.ndl> 5889dc44ceSjose borrego 5989dc44ceSjose borrego /* 6089dc44ceSjose borrego * List of supported registry keys (case-insensitive). 6189dc44ceSjose borrego */ 6289dc44ceSjose borrego static char *winreg_keys[] = { 6389dc44ceSjose borrego "System\\CurrentControlSet\\Services\\Eventlog", 64*7f667e74Sjose borrego "System\\CurrentControlSet\\Services\\Eventlog\\Application", 65*7f667e74Sjose borrego "System\\CurrentControlSet\\Services\\Eventlog\\Security", 6689dc44ceSjose borrego "System\\CurrentControlSet\\Services\\Eventlog\\System", 6789dc44ceSjose borrego "System\\CurrentControlSet\\Control\\ProductOptions", 6889dc44ceSjose borrego "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" 6989dc44ceSjose borrego }; 7089dc44ceSjose borrego 7189dc44ceSjose borrego typedef struct winreg_subkey { 7289dc44ceSjose borrego list_node_t sk_lnd; 7389dc44ceSjose borrego ndr_hdid_t sk_handle; 7489dc44ceSjose borrego char sk_name[MAXPATHLEN]; 7589dc44ceSjose borrego boolean_t sk_predefined; 7689dc44ceSjose borrego } winreg_subkey_t; 7789dc44ceSjose borrego 7889dc44ceSjose borrego typedef struct winreg_keylist { 7989dc44ceSjose borrego list_t kl_list; 8089dc44ceSjose borrego int kl_count; 8189dc44ceSjose borrego } winreg_keylist_t; 8289dc44ceSjose borrego 8389dc44ceSjose borrego static winreg_keylist_t winreg_keylist; 8489dc44ceSjose borrego 8589dc44ceSjose borrego static boolean_t winreg_key_has_subkey(const char *); 86*7f667e74Sjose borrego static char *winreg_enum_subkey(ndr_xa_t *, const char *, uint32_t); 8789dc44ceSjose borrego static char *winreg_lookup_value(const char *); 8889dc44ceSjose borrego 89*7f667e74Sjose borrego static int winreg_s_OpenHKCR(void *, ndr_xa_t *); 90*7f667e74Sjose borrego static int winreg_s_OpenHKCU(void *, ndr_xa_t *); 9189dc44ceSjose borrego static int winreg_s_OpenHKLM(void *, ndr_xa_t *); 92*7f667e74Sjose borrego static int winreg_s_OpenHKPD(void *, ndr_xa_t *); 93*7f667e74Sjose borrego static int winreg_s_OpenHKU(void *, ndr_xa_t *); 94*7f667e74Sjose borrego static int winreg_s_OpenHKCC(void *, ndr_xa_t *); 95*7f667e74Sjose borrego static int winreg_s_OpenHKDD(void *, ndr_xa_t *); 96*7f667e74Sjose borrego static int winreg_s_OpenHKPT(void *, ndr_xa_t *); 97*7f667e74Sjose borrego static int winreg_s_OpenHKPN(void *, ndr_xa_t *); 98*7f667e74Sjose borrego static int winreg_s_OpenHK(void *, ndr_xa_t *, const char *); 9989dc44ceSjose borrego static int winreg_s_Close(void *, ndr_xa_t *); 10089dc44ceSjose borrego static int winreg_s_CreateKey(void *, ndr_xa_t *); 10189dc44ceSjose borrego static int winreg_s_DeleteKey(void *, ndr_xa_t *); 10289dc44ceSjose borrego static int winreg_s_DeleteValue(void *, ndr_xa_t *); 10389dc44ceSjose borrego static int winreg_s_EnumKey(void *, ndr_xa_t *); 10489dc44ceSjose borrego static int winreg_s_EnumValue(void *, ndr_xa_t *); 10589dc44ceSjose borrego static int winreg_s_FlushKey(void *, ndr_xa_t *); 10689dc44ceSjose borrego static int winreg_s_GetKeySec(void *, ndr_xa_t *); 10789dc44ceSjose borrego static int winreg_s_NotifyChange(void *, ndr_xa_t *); 10889dc44ceSjose borrego static int winreg_s_OpenKey(void *, ndr_xa_t *); 10989dc44ceSjose borrego static int winreg_s_QueryKey(void *, ndr_xa_t *); 11089dc44ceSjose borrego static int winreg_s_QueryValue(void *, ndr_xa_t *); 11189dc44ceSjose borrego static int winreg_s_SetKeySec(void *, ndr_xa_t *); 11289dc44ceSjose borrego static int winreg_s_CreateValue(void *, ndr_xa_t *); 11389dc44ceSjose borrego static int winreg_s_Shutdown(void *, ndr_xa_t *); 11489dc44ceSjose borrego static int winreg_s_AbortShutdown(void *, ndr_xa_t *); 11589dc44ceSjose borrego static int winreg_s_GetVersion(void *, ndr_xa_t *); 11689dc44ceSjose borrego 11789dc44ceSjose borrego static ndr_stub_table_t winreg_stub_table[] = { 118*7f667e74Sjose borrego { winreg_s_OpenHKCR, WINREG_OPNUM_OpenHKCR }, 119*7f667e74Sjose borrego { winreg_s_OpenHKCU, WINREG_OPNUM_OpenHKCU }, 12089dc44ceSjose borrego { winreg_s_OpenHKLM, WINREG_OPNUM_OpenHKLM }, 121*7f667e74Sjose borrego { winreg_s_OpenHKPD, WINREG_OPNUM_OpenHKPD }, 122*7f667e74Sjose borrego { winreg_s_OpenHKU, WINREG_OPNUM_OpenHKUsers }, 12389dc44ceSjose borrego { winreg_s_Close, WINREG_OPNUM_Close }, 12489dc44ceSjose borrego { winreg_s_CreateKey, WINREG_OPNUM_CreateKey }, 12589dc44ceSjose borrego { winreg_s_DeleteKey, WINREG_OPNUM_DeleteKey }, 12689dc44ceSjose borrego { winreg_s_DeleteValue, WINREG_OPNUM_DeleteValue }, 12789dc44ceSjose borrego { winreg_s_EnumKey, WINREG_OPNUM_EnumKey }, 12889dc44ceSjose borrego { winreg_s_EnumValue, WINREG_OPNUM_EnumValue }, 12989dc44ceSjose borrego { winreg_s_FlushKey, WINREG_OPNUM_FlushKey }, 13089dc44ceSjose borrego { winreg_s_GetKeySec, WINREG_OPNUM_GetKeySec }, 13189dc44ceSjose borrego { winreg_s_NotifyChange, WINREG_OPNUM_NotifyChange }, 13289dc44ceSjose borrego { winreg_s_OpenKey, WINREG_OPNUM_OpenKey }, 13389dc44ceSjose borrego { winreg_s_QueryKey, WINREG_OPNUM_QueryKey }, 13489dc44ceSjose borrego { winreg_s_QueryValue, WINREG_OPNUM_QueryValue }, 13589dc44ceSjose borrego { winreg_s_SetKeySec, WINREG_OPNUM_SetKeySec }, 13689dc44ceSjose borrego { winreg_s_CreateValue, WINREG_OPNUM_CreateValue }, 13789dc44ceSjose borrego { winreg_s_Shutdown, WINREG_OPNUM_Shutdown }, 13889dc44ceSjose borrego { winreg_s_AbortShutdown, WINREG_OPNUM_AbortShutdown }, 13989dc44ceSjose borrego { winreg_s_GetVersion, WINREG_OPNUM_GetVersion }, 140*7f667e74Sjose borrego { winreg_s_OpenHKCC, WINREG_OPNUM_OpenHKCC }, 141*7f667e74Sjose borrego { winreg_s_OpenHKDD, WINREG_OPNUM_OpenHKDD }, 142*7f667e74Sjose borrego { winreg_s_OpenHKPT, WINREG_OPNUM_OpenHKPT }, 143*7f667e74Sjose borrego { winreg_s_OpenHKPN, WINREG_OPNUM_OpenHKPN }, 14489dc44ceSjose borrego {0} 14589dc44ceSjose borrego }; 14689dc44ceSjose borrego 14789dc44ceSjose borrego static ndr_service_t winreg_service = { 14889dc44ceSjose borrego "Winreg", /* name */ 14989dc44ceSjose borrego "Windows Registry", /* desc */ 15089dc44ceSjose borrego "\\winreg", /* endpoint */ 15189dc44ceSjose borrego PIPE_WINREG, /* sec_addr_port */ 15289dc44ceSjose borrego "338cd001-2244-31f1-aaaa-900038001003", 1, /* abstract */ 15389dc44ceSjose borrego NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 15489dc44ceSjose borrego 0, /* no bind_instance_size */ 15589dc44ceSjose borrego 0, /* no bind_req() */ 15689dc44ceSjose borrego 0, /* no unbind_and_close() */ 15789dc44ceSjose borrego 0, /* use generic_call_stub() */ 15889dc44ceSjose borrego &TYPEINFO(winreg_interface), /* interface ti */ 15989dc44ceSjose borrego winreg_stub_table /* stub_table */ 16089dc44ceSjose borrego }; 16189dc44ceSjose borrego 16289dc44ceSjose borrego static char winreg_sysname[SYS_NMLN]; 16389dc44ceSjose borrego 16489dc44ceSjose borrego /* 16589dc44ceSjose borrego * winreg_initialize 16689dc44ceSjose borrego * 16789dc44ceSjose borrego * Initialize and register the WINREG RPC interface with the RPC runtime 16889dc44ceSjose borrego * library. It must be called in order to use either the client side 16989dc44ceSjose borrego * or the server side functions. 17089dc44ceSjose borrego */ 17189dc44ceSjose borrego void 17289dc44ceSjose borrego winreg_initialize(void) 17389dc44ceSjose borrego { 17489dc44ceSjose borrego winreg_subkey_t *key; 17589dc44ceSjose borrego struct utsname name; 17689dc44ceSjose borrego char *sysname; 17789dc44ceSjose borrego int i; 17889dc44ceSjose borrego 17989dc44ceSjose borrego list_create(&winreg_keylist.kl_list, sizeof (winreg_subkey_t), 18089dc44ceSjose borrego offsetof(winreg_subkey_t, sk_lnd)); 18189dc44ceSjose borrego winreg_keylist.kl_count = 0; 18289dc44ceSjose borrego 18389dc44ceSjose borrego for (i = 0; i < sizeof (winreg_keys)/sizeof (winreg_keys[0]); ++i) { 18489dc44ceSjose borrego if ((key = malloc(sizeof (winreg_subkey_t))) != NULL) { 18589dc44ceSjose borrego bzero(key, sizeof (winreg_subkey_t)); 18689dc44ceSjose borrego (void) strlcpy(key->sk_name, winreg_keys[i], 18789dc44ceSjose borrego MAXPATHLEN); 18889dc44ceSjose borrego key->sk_predefined = B_TRUE; 18989dc44ceSjose borrego list_insert_tail(&winreg_keylist.kl_list, key); 19089dc44ceSjose borrego ++winreg_keylist.kl_count; 19189dc44ceSjose borrego } 19289dc44ceSjose borrego } 19389dc44ceSjose borrego 19489dc44ceSjose borrego if (uname(&name) < 0) 19589dc44ceSjose borrego sysname = "Solaris"; 19689dc44ceSjose borrego else 19789dc44ceSjose borrego sysname = name.sysname; 19889dc44ceSjose borrego 19989dc44ceSjose borrego (void) strlcpy(winreg_sysname, sysname, SYS_NMLN); 20089dc44ceSjose borrego (void) ndr_svc_register(&winreg_service); 20189dc44ceSjose borrego } 20289dc44ceSjose borrego 20389dc44ceSjose borrego static int 204*7f667e74Sjose borrego winreg_s_OpenHKCR(void *arg, ndr_xa_t *mxa) 20589dc44ceSjose borrego { 206*7f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKCR")); 20789dc44ceSjose borrego } 20889dc44ceSjose borrego 209*7f667e74Sjose borrego static int 210*7f667e74Sjose borrego winreg_s_OpenHKCU(void *arg, ndr_xa_t *mxa) 211*7f667e74Sjose borrego { 212*7f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKCU")); 21389dc44ceSjose borrego } 21489dc44ceSjose borrego 21589dc44ceSjose borrego static int 21689dc44ceSjose borrego winreg_s_OpenHKLM(void *arg, ndr_xa_t *mxa) 21789dc44ceSjose borrego { 218*7f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKLM")); 21989dc44ceSjose borrego } 22089dc44ceSjose borrego 221*7f667e74Sjose borrego static int 222*7f667e74Sjose borrego winreg_s_OpenHKPD(void *arg, ndr_xa_t *mxa) 223*7f667e74Sjose borrego { 224*7f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKPD")); 225*7f667e74Sjose borrego } 226*7f667e74Sjose borrego 227*7f667e74Sjose borrego static int 228*7f667e74Sjose borrego winreg_s_OpenHKU(void *arg, ndr_xa_t *mxa) 229*7f667e74Sjose borrego { 230*7f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKU")); 231*7f667e74Sjose borrego } 232*7f667e74Sjose borrego 233*7f667e74Sjose borrego static int 234*7f667e74Sjose borrego winreg_s_OpenHKCC(void *arg, ndr_xa_t *mxa) 235*7f667e74Sjose borrego { 236*7f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKCC")); 237*7f667e74Sjose borrego } 238*7f667e74Sjose borrego 239*7f667e74Sjose borrego static int 240*7f667e74Sjose borrego winreg_s_OpenHKDD(void *arg, ndr_xa_t *mxa) 241*7f667e74Sjose borrego { 242*7f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKDD")); 243*7f667e74Sjose borrego } 244*7f667e74Sjose borrego 245*7f667e74Sjose borrego static int 246*7f667e74Sjose borrego winreg_s_OpenHKPT(void *arg, ndr_xa_t *mxa) 247*7f667e74Sjose borrego { 248*7f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKPT")); 249*7f667e74Sjose borrego } 250*7f667e74Sjose borrego 251*7f667e74Sjose borrego static int 252*7f667e74Sjose borrego winreg_s_OpenHKPN(void *arg, ndr_xa_t *mxa) 253*7f667e74Sjose borrego { 254*7f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKPN")); 25589dc44ceSjose borrego } 25689dc44ceSjose borrego 25789dc44ceSjose borrego /* 258*7f667e74Sjose borrego * winreg_s_OpenHK 25989dc44ceSjose borrego * 260*7f667e74Sjose borrego * Common code to open root HKEYs. 26189dc44ceSjose borrego */ 26289dc44ceSjose borrego static int 263*7f667e74Sjose borrego winreg_s_OpenHK(void *arg, ndr_xa_t *mxa, const char *hkey) 26489dc44ceSjose borrego { 265*7f667e74Sjose borrego struct winreg_OpenHKCR *param = arg; 26689dc44ceSjose borrego ndr_hdid_t *id; 267*7f667e74Sjose borrego char *dupkey; 26889dc44ceSjose borrego 269*7f667e74Sjose borrego if ((dupkey = strdup(hkey)) == NULL) { 270*7f667e74Sjose borrego bzero(¶m->handle, sizeof (winreg_handle_t)); 271*7f667e74Sjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 272*7f667e74Sjose borrego return (NDR_DRC_OK); 273*7f667e74Sjose borrego } 274*7f667e74Sjose borrego 275*7f667e74Sjose borrego if ((id = ndr_hdalloc(mxa, dupkey)) == NULL) { 276*7f667e74Sjose borrego free(dupkey); 27789dc44ceSjose borrego bzero(¶m->handle, sizeof (winreg_handle_t)); 27889dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 27989dc44ceSjose borrego } else { 28089dc44ceSjose borrego bcopy(id, ¶m->handle, sizeof (winreg_handle_t)); 28189dc44ceSjose borrego param->status = ERROR_SUCCESS; 28289dc44ceSjose borrego } 28389dc44ceSjose borrego 28489dc44ceSjose borrego return (NDR_DRC_OK); 28589dc44ceSjose borrego } 28689dc44ceSjose borrego 28789dc44ceSjose borrego /* 28889dc44ceSjose borrego * winreg_s_Close 28989dc44ceSjose borrego * 29089dc44ceSjose borrego * This is a request to close the WINREG interface specified by the 29189dc44ceSjose borrego * handle. We don't track handles (yet), so just zero out the handle 29289dc44ceSjose borrego * and return NDR_DRC_OK. Setting the handle to zero appears to be 29389dc44ceSjose borrego * standard behaviour. 29489dc44ceSjose borrego */ 29589dc44ceSjose borrego static int 29689dc44ceSjose borrego winreg_s_Close(void *arg, ndr_xa_t *mxa) 29789dc44ceSjose borrego { 29889dc44ceSjose borrego struct winreg_Close *param = arg; 29989dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 300*7f667e74Sjose borrego ndr_handle_t *hd; 301*7f667e74Sjose borrego 302*7f667e74Sjose borrego if ((hd = ndr_hdlookup(mxa, id)) != NULL) { 303*7f667e74Sjose borrego free(hd->nh_data); 304*7f667e74Sjose borrego hd->nh_data = NULL; 305*7f667e74Sjose borrego } 30689dc44ceSjose borrego 30789dc44ceSjose borrego ndr_hdfree(mxa, id); 30889dc44ceSjose borrego 30989dc44ceSjose borrego bzero(¶m->result_handle, sizeof (winreg_handle_t)); 31089dc44ceSjose borrego param->status = ERROR_SUCCESS; 31189dc44ceSjose borrego return (NDR_DRC_OK); 31289dc44ceSjose borrego } 31389dc44ceSjose borrego 31489dc44ceSjose borrego /* 31589dc44ceSjose borrego * winreg_s_CreateKey 31689dc44ceSjose borrego */ 31789dc44ceSjose borrego static int 31889dc44ceSjose borrego winreg_s_CreateKey(void *arg, ndr_xa_t *mxa) 31989dc44ceSjose borrego { 32089dc44ceSjose borrego struct winreg_CreateKey *param = arg; 32189dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 32289dc44ceSjose borrego ndr_handle_t *hd; 32389dc44ceSjose borrego winreg_subkey_t *key; 32489dc44ceSjose borrego char *subkey; 325*7f667e74Sjose borrego char *dupkey; 32689dc44ceSjose borrego DWORD *action; 32789dc44ceSjose borrego 32889dc44ceSjose borrego subkey = (char *)param->subkey.str; 32989dc44ceSjose borrego 33089dc44ceSjose borrego if (!ndr_is_admin(mxa) || (subkey == NULL)) { 33189dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey)); 33289dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 33389dc44ceSjose borrego return (NDR_DRC_OK); 33489dc44ceSjose borrego } 33589dc44ceSjose borrego 33689dc44ceSjose borrego hd = ndr_hdlookup(mxa, id); 33789dc44ceSjose borrego if (hd == NULL) { 33889dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey)); 33989dc44ceSjose borrego param->status = ERROR_INVALID_HANDLE; 34089dc44ceSjose borrego return (NDR_DRC_OK); 34189dc44ceSjose borrego } 34289dc44ceSjose borrego 34389dc44ceSjose borrego if ((action = NDR_NEW(mxa, DWORD)) == NULL) { 34489dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey)); 34589dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 34689dc44ceSjose borrego return (NDR_DRC_OK); 34789dc44ceSjose borrego } 34889dc44ceSjose borrego 34989dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list)) 35089dc44ceSjose borrego goto new_key; 35189dc44ceSjose borrego 35289dc44ceSjose borrego /* 35389dc44ceSjose borrego * Check for an existing key. 35489dc44ceSjose borrego */ 35589dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 35689dc44ceSjose borrego do { 35789dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) { 35889dc44ceSjose borrego bcopy(&key->sk_handle, ¶m->result_handle, 35989dc44ceSjose borrego sizeof (winreg_handle_t)); 36089dc44ceSjose borrego *action = WINREG_ACTION_EXISTING_KEY; 36189dc44ceSjose borrego param->action = action; 36289dc44ceSjose borrego param->status = ERROR_SUCCESS; 36389dc44ceSjose borrego return (NDR_DRC_OK); 36489dc44ceSjose borrego } 36589dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 36689dc44ceSjose borrego 36789dc44ceSjose borrego new_key: 36889dc44ceSjose borrego /* 36989dc44ceSjose borrego * Create a new key. 37089dc44ceSjose borrego */ 371*7f667e74Sjose borrego if ((dupkey = strdup(subkey)) == NULL) { 372*7f667e74Sjose borrego bzero(param, sizeof (struct winreg_CreateKey)); 373*7f667e74Sjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 374*7f667e74Sjose borrego return (NDR_DRC_OK); 375*7f667e74Sjose borrego } 376*7f667e74Sjose borrego 377*7f667e74Sjose borrego id = ndr_hdalloc(mxa, dupkey); 37889dc44ceSjose borrego key = malloc(sizeof (winreg_subkey_t)); 37989dc44ceSjose borrego 38089dc44ceSjose borrego if ((id == NULL) || (key == NULL)) { 381*7f667e74Sjose borrego free(dupkey); 38289dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey)); 38389dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 38489dc44ceSjose borrego return (NDR_DRC_OK); 38589dc44ceSjose borrego } 38689dc44ceSjose borrego 38789dc44ceSjose borrego bcopy(id, &key->sk_handle, sizeof (ndr_hdid_t)); 38889dc44ceSjose borrego (void) strlcpy(key->sk_name, subkey, MAXPATHLEN); 38989dc44ceSjose borrego key->sk_predefined = B_FALSE; 39089dc44ceSjose borrego list_insert_tail(&winreg_keylist.kl_list, key); 39189dc44ceSjose borrego ++winreg_keylist.kl_count; 39289dc44ceSjose borrego 39389dc44ceSjose borrego bcopy(id, ¶m->result_handle, sizeof (winreg_handle_t)); 39489dc44ceSjose borrego *action = WINREG_ACTION_NEW_KEY; 39589dc44ceSjose borrego param->action = action; 39689dc44ceSjose borrego param->status = ERROR_SUCCESS; 39789dc44ceSjose borrego return (NDR_DRC_OK); 39889dc44ceSjose borrego } 39989dc44ceSjose borrego 40089dc44ceSjose borrego /* 40189dc44ceSjose borrego * winreg_s_DeleteKey 40289dc44ceSjose borrego */ 40389dc44ceSjose borrego static int 40489dc44ceSjose borrego winreg_s_DeleteKey(void *arg, ndr_xa_t *mxa) 40589dc44ceSjose borrego { 40689dc44ceSjose borrego struct winreg_DeleteKey *param = arg; 40789dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 408*7f667e74Sjose borrego ndr_handle_t *hd; 40989dc44ceSjose borrego winreg_subkey_t *key; 41089dc44ceSjose borrego char *subkey; 41189dc44ceSjose borrego 41289dc44ceSjose borrego subkey = (char *)param->subkey.str; 41389dc44ceSjose borrego 41489dc44ceSjose borrego if (!ndr_is_admin(mxa) || (subkey == NULL)) { 41589dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 41689dc44ceSjose borrego return (NDR_DRC_OK); 41789dc44ceSjose borrego } 41889dc44ceSjose borrego 41989dc44ceSjose borrego if ((ndr_hdlookup(mxa, id) == NULL) || 42089dc44ceSjose borrego list_is_empty(&winreg_keylist.kl_list) || 42189dc44ceSjose borrego winreg_key_has_subkey(subkey)) { 42289dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 42389dc44ceSjose borrego return (NDR_DRC_OK); 42489dc44ceSjose borrego } 42589dc44ceSjose borrego 42689dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 42789dc44ceSjose borrego do { 42889dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) { 42989dc44ceSjose borrego if (key->sk_predefined == B_TRUE) { 43089dc44ceSjose borrego /* Predefined keys cannot be deleted */ 43189dc44ceSjose borrego break; 43289dc44ceSjose borrego } 43389dc44ceSjose borrego 43489dc44ceSjose borrego list_remove(&winreg_keylist.kl_list, key); 43589dc44ceSjose borrego --winreg_keylist.kl_count; 436*7f667e74Sjose borrego 437*7f667e74Sjose borrego hd = ndr_hdlookup(mxa, &key->sk_handle); 438*7f667e74Sjose borrego if (hd != NULL) { 439*7f667e74Sjose borrego free(hd->nh_data); 440*7f667e74Sjose borrego hd->nh_data = NULL; 441*7f667e74Sjose borrego } 442*7f667e74Sjose borrego 44389dc44ceSjose borrego ndr_hdfree(mxa, &key->sk_handle); 44489dc44ceSjose borrego free(key); 44589dc44ceSjose borrego param->status = ERROR_SUCCESS; 44689dc44ceSjose borrego return (NDR_DRC_OK); 44789dc44ceSjose borrego } 44889dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 44989dc44ceSjose borrego 45089dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 45189dc44ceSjose borrego return (NDR_DRC_OK); 45289dc44ceSjose borrego } 45389dc44ceSjose borrego 45489dc44ceSjose borrego static boolean_t 45589dc44ceSjose borrego winreg_key_has_subkey(const char *subkey) 45689dc44ceSjose borrego { 45789dc44ceSjose borrego winreg_subkey_t *key; 45889dc44ceSjose borrego int keylen; 45989dc44ceSjose borrego 46089dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list)) 46189dc44ceSjose borrego return (B_FALSE); 46289dc44ceSjose borrego 46389dc44ceSjose borrego keylen = strlen(subkey); 46489dc44ceSjose borrego 46589dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 46689dc44ceSjose borrego do { 46789dc44ceSjose borrego if (strncasecmp(subkey, key->sk_name, keylen) == 0) { 46889dc44ceSjose borrego /* 46989dc44ceSjose borrego * Potential match. If sk_name is longer than 47089dc44ceSjose borrego * subkey, then sk_name is a subkey of our key. 47189dc44ceSjose borrego */ 47289dc44ceSjose borrego if (keylen < strlen(key->sk_name)) 47389dc44ceSjose borrego return (B_TRUE); 47489dc44ceSjose borrego } 47589dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 47689dc44ceSjose borrego 47789dc44ceSjose borrego return (B_FALSE); 47889dc44ceSjose borrego } 47989dc44ceSjose borrego 48089dc44ceSjose borrego static char * 481*7f667e74Sjose borrego winreg_enum_subkey(ndr_xa_t *mxa, const char *subkey, uint32_t index) 48289dc44ceSjose borrego { 48389dc44ceSjose borrego winreg_subkey_t *key; 484*7f667e74Sjose borrego char *entry; 485*7f667e74Sjose borrego char *p; 486*7f667e74Sjose borrego int subkeylen; 487*7f667e74Sjose borrego int count = 0; 48889dc44ceSjose borrego 48989dc44ceSjose borrego if (subkey == NULL) 49089dc44ceSjose borrego return (NULL); 49189dc44ceSjose borrego 49289dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list)) 49389dc44ceSjose borrego return (NULL); 49489dc44ceSjose borrego 495*7f667e74Sjose borrego subkeylen = strlen(subkey); 496*7f667e74Sjose borrego 497*7f667e74Sjose borrego for (key = list_head(&winreg_keylist.kl_list); 498*7f667e74Sjose borrego key != NULL; key = list_next(&winreg_keylist.kl_list, key)) { 499*7f667e74Sjose borrego if (strncasecmp(subkey, key->sk_name, subkeylen) == 0) { 500*7f667e74Sjose borrego p = key->sk_name + subkeylen; 501*7f667e74Sjose borrego 502*7f667e74Sjose borrego if ((*p != '\\') || (*p == '\0')) { 503*7f667e74Sjose borrego /* 504*7f667e74Sjose borrego * Not the same subkey or an exact match. 505*7f667e74Sjose borrego * We're looking for children of subkey. 506*7f667e74Sjose borrego */ 507*7f667e74Sjose borrego continue; 50889dc44ceSjose borrego } 509*7f667e74Sjose borrego 510*7f667e74Sjose borrego ++p; 511*7f667e74Sjose borrego 512*7f667e74Sjose borrego if (count < index) { 513*7f667e74Sjose borrego ++count; 514*7f667e74Sjose borrego continue; 515*7f667e74Sjose borrego } 516*7f667e74Sjose borrego 517*7f667e74Sjose borrego if ((entry = NDR_STRDUP(mxa, p)) == NULL) 518*7f667e74Sjose borrego return (NULL); 519*7f667e74Sjose borrego 520*7f667e74Sjose borrego if ((p = strchr(entry, '\\')) != NULL) 521*7f667e74Sjose borrego *p = '\0'; 522*7f667e74Sjose borrego 523*7f667e74Sjose borrego return (entry); 524*7f667e74Sjose borrego } 525*7f667e74Sjose borrego } 52689dc44ceSjose borrego 52789dc44ceSjose borrego return (NULL); 52889dc44ceSjose borrego } 52989dc44ceSjose borrego 53089dc44ceSjose borrego /* 53189dc44ceSjose borrego * winreg_s_DeleteValue 53289dc44ceSjose borrego */ 53389dc44ceSjose borrego /*ARGSUSED*/ 53489dc44ceSjose borrego static int 53589dc44ceSjose borrego winreg_s_DeleteValue(void *arg, ndr_xa_t *mxa) 53689dc44ceSjose borrego { 53789dc44ceSjose borrego struct winreg_DeleteValue *param = arg; 53889dc44ceSjose borrego 53989dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 54089dc44ceSjose borrego return (NDR_DRC_OK); 54189dc44ceSjose borrego } 54289dc44ceSjose borrego 54389dc44ceSjose borrego /* 54489dc44ceSjose borrego * winreg_s_EnumKey 54589dc44ceSjose borrego */ 54689dc44ceSjose borrego static int 54789dc44ceSjose borrego winreg_s_EnumKey(void *arg, ndr_xa_t *mxa) 54889dc44ceSjose borrego { 54989dc44ceSjose borrego struct winreg_EnumKey *param = arg; 55089dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 551*7f667e74Sjose borrego ndr_handle_t *hd; 552*7f667e74Sjose borrego char *subkey; 553*7f667e74Sjose borrego char *name = NULL; 55489dc44ceSjose borrego 555*7f667e74Sjose borrego if ((hd = ndr_hdlookup(mxa, id)) != NULL) 556*7f667e74Sjose borrego name = hd->nh_data; 557*7f667e74Sjose borrego 558*7f667e74Sjose borrego if (hd == NULL || name == NULL) { 55989dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey)); 56089dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS; 56189dc44ceSjose borrego return (NDR_DRC_OK); 56289dc44ceSjose borrego } 56389dc44ceSjose borrego 564*7f667e74Sjose borrego subkey = winreg_enum_subkey(mxa, name, param->index); 565*7f667e74Sjose borrego if (subkey == NULL) { 56689dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey)); 56789dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS; 56889dc44ceSjose borrego return (NDR_DRC_OK); 56989dc44ceSjose borrego } 57089dc44ceSjose borrego 571*7f667e74Sjose borrego if (NDR_MSTRING(mxa, subkey, (ndr_mstring_t *)¶m->name_out) == -1) { 57289dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey)); 57389dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 57489dc44ceSjose borrego return (NDR_DRC_OK); 57589dc44ceSjose borrego } 576*7f667e74Sjose borrego /* 577*7f667e74Sjose borrego * This request requires that the length includes the null. 578*7f667e74Sjose borrego */ 579*7f667e74Sjose borrego param->name_out.length = param->name_out.allosize; 58089dc44ceSjose borrego 58189dc44ceSjose borrego param->status = ERROR_SUCCESS; 58289dc44ceSjose borrego return (NDR_DRC_OK); 58389dc44ceSjose borrego } 58489dc44ceSjose borrego 58589dc44ceSjose borrego /* 58689dc44ceSjose borrego * winreg_s_EnumValue 58789dc44ceSjose borrego */ 58889dc44ceSjose borrego static int 58989dc44ceSjose borrego winreg_s_EnumValue(void *arg, ndr_xa_t *mxa) 59089dc44ceSjose borrego { 59189dc44ceSjose borrego struct winreg_EnumValue *param = arg; 59289dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 59389dc44ceSjose borrego 59489dc44ceSjose borrego if (ndr_hdlookup(mxa, id) == NULL) { 59589dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumValue)); 59689dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS; 59789dc44ceSjose borrego return (NDR_DRC_OK); 59889dc44ceSjose borrego } 59989dc44ceSjose borrego 60089dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumValue)); 60189dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS; 60289dc44ceSjose borrego return (NDR_DRC_OK); 60389dc44ceSjose borrego } 60489dc44ceSjose borrego 60589dc44ceSjose borrego /* 60689dc44ceSjose borrego * winreg_s_FlushKey 60789dc44ceSjose borrego * 60889dc44ceSjose borrego * Flush the attributes associated with the specified open key to disk. 60989dc44ceSjose borrego */ 61089dc44ceSjose borrego static int 61189dc44ceSjose borrego winreg_s_FlushKey(void *arg, ndr_xa_t *mxa) 61289dc44ceSjose borrego { 61389dc44ceSjose borrego struct winreg_FlushKey *param = arg; 61489dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 61589dc44ceSjose borrego 61689dc44ceSjose borrego if (ndr_hdlookup(mxa, id) == NULL) 61789dc44ceSjose borrego param->status = ERROR_INVALID_HANDLE; 61889dc44ceSjose borrego else 61989dc44ceSjose borrego param->status = ERROR_SUCCESS; 62089dc44ceSjose borrego 62189dc44ceSjose borrego return (NDR_DRC_OK); 62289dc44ceSjose borrego } 62389dc44ceSjose borrego 62489dc44ceSjose borrego /* 62589dc44ceSjose borrego * winreg_s_GetKeySec 62689dc44ceSjose borrego */ 62789dc44ceSjose borrego /*ARGSUSED*/ 62889dc44ceSjose borrego static int 62989dc44ceSjose borrego winreg_s_GetKeySec(void *arg, ndr_xa_t *mxa) 63089dc44ceSjose borrego { 63189dc44ceSjose borrego struct winreg_GetKeySec *param = arg; 63289dc44ceSjose borrego 63389dc44ceSjose borrego bzero(param, sizeof (struct winreg_GetKeySec)); 63489dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 63589dc44ceSjose borrego return (NDR_DRC_OK); 63689dc44ceSjose borrego } 63789dc44ceSjose borrego 63889dc44ceSjose borrego /* 63989dc44ceSjose borrego * winreg_s_NotifyChange 64089dc44ceSjose borrego */ 64189dc44ceSjose borrego static int 64289dc44ceSjose borrego winreg_s_NotifyChange(void *arg, ndr_xa_t *mxa) 64389dc44ceSjose borrego { 64489dc44ceSjose borrego struct winreg_NotifyChange *param = arg; 64589dc44ceSjose borrego 64689dc44ceSjose borrego if (ndr_is_admin(mxa)) 64789dc44ceSjose borrego param->status = ERROR_SUCCESS; 64889dc44ceSjose borrego else 64989dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 65089dc44ceSjose borrego 65189dc44ceSjose borrego return (NDR_DRC_OK); 65289dc44ceSjose borrego } 65389dc44ceSjose borrego 65489dc44ceSjose borrego /* 65589dc44ceSjose borrego * winreg_s_OpenKey 65689dc44ceSjose borrego * 65789dc44ceSjose borrego * This is a request to open a windows registry key. 65889dc44ceSjose borrego * If we recognize the key, we return a handle. 65989dc44ceSjose borrego * 66089dc44ceSjose borrego * Returns: 66189dc44ceSjose borrego * ERROR_SUCCESS Valid handle returned. 66289dc44ceSjose borrego * ERROR_FILE_NOT_FOUND No key or unable to allocate a handle. 66389dc44ceSjose borrego */ 66489dc44ceSjose borrego static int 66589dc44ceSjose borrego winreg_s_OpenKey(void *arg, ndr_xa_t *mxa) 66689dc44ceSjose borrego { 66789dc44ceSjose borrego struct winreg_OpenKey *param = arg; 66889dc44ceSjose borrego char *subkey = (char *)param->name.str; 66989dc44ceSjose borrego ndr_hdid_t *id = NULL; 67089dc44ceSjose borrego winreg_subkey_t *key; 671*7f667e74Sjose borrego char *dupkey; 67289dc44ceSjose borrego 673*7f667e74Sjose borrego if (subkey == NULL || list_is_empty(&winreg_keylist.kl_list)) { 67489dc44ceSjose borrego bzero(¶m->result_handle, sizeof (winreg_handle_t)); 67589dc44ceSjose borrego param->status = ERROR_FILE_NOT_FOUND; 67689dc44ceSjose borrego return (NDR_DRC_OK); 67789dc44ceSjose borrego } 67889dc44ceSjose borrego 67989dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 68089dc44ceSjose borrego do { 68189dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) { 682*7f667e74Sjose borrego if (key->sk_predefined == B_TRUE) { 683*7f667e74Sjose borrego if ((dupkey = strdup(subkey)) == NULL) 684*7f667e74Sjose borrego break; 685*7f667e74Sjose borrego 686*7f667e74Sjose borrego id = ndr_hdalloc(mxa, dupkey); 687*7f667e74Sjose borrego if (id == NULL) 688*7f667e74Sjose borrego free(dupkey); 689*7f667e74Sjose borrego } else { 69089dc44ceSjose borrego id = &key->sk_handle; 691*7f667e74Sjose borrego } 69289dc44ceSjose borrego 69389dc44ceSjose borrego if (id == NULL) 69489dc44ceSjose borrego break; 69589dc44ceSjose borrego 69689dc44ceSjose borrego bcopy(id, ¶m->result_handle, 69789dc44ceSjose borrego sizeof (winreg_handle_t)); 69889dc44ceSjose borrego param->status = ERROR_SUCCESS; 69989dc44ceSjose borrego return (NDR_DRC_OK); 70089dc44ceSjose borrego } 70189dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 70289dc44ceSjose borrego 70389dc44ceSjose borrego bzero(¶m->result_handle, sizeof (winreg_handle_t)); 70489dc44ceSjose borrego param->status = ERROR_FILE_NOT_FOUND; 70589dc44ceSjose borrego return (NDR_DRC_OK); 70689dc44ceSjose borrego } 70789dc44ceSjose borrego 70889dc44ceSjose borrego /* 70989dc44ceSjose borrego * winreg_s_QueryKey 71089dc44ceSjose borrego */ 71189dc44ceSjose borrego /*ARGSUSED*/ 71289dc44ceSjose borrego static int 71389dc44ceSjose borrego winreg_s_QueryKey(void *arg, ndr_xa_t *mxa) 71489dc44ceSjose borrego { 71589dc44ceSjose borrego struct winreg_QueryKey *param = arg; 71689dc44ceSjose borrego int rc; 71789dc44ceSjose borrego winreg_string_t *name; 71889dc44ceSjose borrego 71989dc44ceSjose borrego name = (winreg_string_t *)¶m->name; 72089dc44ceSjose borrego bzero(param, sizeof (struct winreg_QueryKey)); 72189dc44ceSjose borrego if ((name = NDR_NEW(mxa, winreg_string_t)) != NULL) 72289dc44ceSjose borrego rc = NDR_MSTRING(mxa, "", (ndr_mstring_t *)name); 72389dc44ceSjose borrego 72489dc44ceSjose borrego if ((name == NULL) || (rc != 0)) { 72589dc44ceSjose borrego bzero(param, sizeof (struct winreg_QueryKey)); 72689dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 72789dc44ceSjose borrego return (NDR_DRC_OK); 72889dc44ceSjose borrego } 72989dc44ceSjose borrego 73089dc44ceSjose borrego param->status = ERROR_SUCCESS; 73189dc44ceSjose borrego return (NDR_DRC_OK); 73289dc44ceSjose borrego } 73389dc44ceSjose borrego 73489dc44ceSjose borrego /* 73589dc44ceSjose borrego * winreg_s_QueryValue 73689dc44ceSjose borrego * 73789dc44ceSjose borrego * This is a request to get the value associated with a specified name. 73889dc44ceSjose borrego * 73989dc44ceSjose borrego * Returns: 74089dc44ceSjose borrego * ERROR_SUCCESS Value returned. 74189dc44ceSjose borrego * ERROR_FILE_NOT_FOUND PrimaryModule is not supported. 74289dc44ceSjose borrego * ERROR_CANTREAD No such name or memory problem. 74389dc44ceSjose borrego */ 74489dc44ceSjose borrego static int 74589dc44ceSjose borrego winreg_s_QueryValue(void *arg, ndr_xa_t *mxa) 74689dc44ceSjose borrego { 74789dc44ceSjose borrego struct winreg_QueryValue *param = arg; 74889dc44ceSjose borrego struct winreg_value *pv; 74989dc44ceSjose borrego char *name; 75089dc44ceSjose borrego char *value; 75189dc44ceSjose borrego DWORD slen; 75289dc44ceSjose borrego DWORD msize; 75389dc44ceSjose borrego 75489dc44ceSjose borrego name = (char *)param->value_name.str; 75589dc44ceSjose borrego 75689dc44ceSjose borrego if (strcasecmp(name, "PrimaryModule") == 0) { 75789dc44ceSjose borrego param->status = ERROR_FILE_NOT_FOUND; 75889dc44ceSjose borrego return (NDR_DRC_OK); 75989dc44ceSjose borrego } 76089dc44ceSjose borrego 76189dc44ceSjose borrego if ((value = winreg_lookup_value(name)) == NULL) { 76289dc44ceSjose borrego param->status = ERROR_CANTREAD; 76389dc44ceSjose borrego return (NDR_DRC_OK); 76489dc44ceSjose borrego } 76589dc44ceSjose borrego 76689dc44ceSjose borrego slen = mts_wcequiv_strlen(value) + sizeof (mts_wchar_t); 76789dc44ceSjose borrego msize = sizeof (struct winreg_value) + slen; 76889dc44ceSjose borrego 76989dc44ceSjose borrego param->value = (struct winreg_value *)NDR_MALLOC(mxa, msize); 77089dc44ceSjose borrego param->type = NDR_NEW(mxa, DWORD); 77189dc44ceSjose borrego param->value_size = NDR_NEW(mxa, DWORD); 77289dc44ceSjose borrego param->value_size_total = NDR_NEW(mxa, DWORD); 77389dc44ceSjose borrego 77489dc44ceSjose borrego if (param->value == NULL || param->type == NULL || 77589dc44ceSjose borrego param->value_size == NULL || param->value_size_total == NULL) { 77689dc44ceSjose borrego param->status = ERROR_CANTREAD; 77789dc44ceSjose borrego return (NDR_DRC_OK); 77889dc44ceSjose borrego } 77989dc44ceSjose borrego 78089dc44ceSjose borrego bzero(param->value, msize); 78189dc44ceSjose borrego pv = param->value; 78289dc44ceSjose borrego pv->vc_first_is = 0; 78389dc44ceSjose borrego pv->vc_length_is = slen; 78489dc44ceSjose borrego /*LINTED E_BAD_PTR_CAST_ALIGN*/ 78589dc44ceSjose borrego (void) ndr_mbstowcs(NULL, (mts_wchar_t *)pv->value, value, slen); 78689dc44ceSjose borrego 78789dc44ceSjose borrego *param->type = 1; 78889dc44ceSjose borrego *param->value_size = slen; 78989dc44ceSjose borrego *param->value_size_total = slen; 79089dc44ceSjose borrego 79189dc44ceSjose borrego param->status = ERROR_SUCCESS; 79289dc44ceSjose borrego return (NDR_DRC_OK); 79389dc44ceSjose borrego } 79489dc44ceSjose borrego 79589dc44ceSjose borrego /* 79689dc44ceSjose borrego * Lookup a name in the registry and return the associated value. 79789dc44ceSjose borrego * Our registry is a case-insensitive, name-value pair table. 79889dc44ceSjose borrego * 79989dc44ceSjose borrego * Windows ProductType: WinNT, ServerNT, LanmanNT. 80089dc44ceSjose borrego * Windows NT4.0 workstation: WinNT 80189dc44ceSjose borrego * Windows NT4.0 server: ServerNT 80289dc44ceSjose borrego * 80389dc44ceSjose borrego * If LanmanNT is used here, Windows 2000 sends LsarQueryInfoPolicy 80489dc44ceSjose borrego * with info level 6, which we don't support. If we use ServerNT 80589dc44ceSjose borrego * (as reported by NT4.0 Server) Windows 2000 send requests for 80689dc44ceSjose borrego * levels 3 and 5, which are support. 80789dc44ceSjose borrego * 80889dc44ceSjose borrego * On success, returns a pointer to the value. Otherwise returns 80989dc44ceSjose borrego * a null pointer. 81089dc44ceSjose borrego */ 81189dc44ceSjose borrego static char * 81289dc44ceSjose borrego winreg_lookup_value(const char *name) 81389dc44ceSjose borrego { 81489dc44ceSjose borrego static struct registry { 81589dc44ceSjose borrego char *name; 81689dc44ceSjose borrego char *value; 81789dc44ceSjose borrego } registry[] = { 81889dc44ceSjose borrego { "ProductType", "ServerNT" }, 81989dc44ceSjose borrego { "Sources", NULL } /* product name */ 82089dc44ceSjose borrego }; 82189dc44ceSjose borrego 82289dc44ceSjose borrego int i; 82389dc44ceSjose borrego 82489dc44ceSjose borrego for (i = 0; i < sizeof (registry)/sizeof (registry[0]); ++i) { 82589dc44ceSjose borrego if (strcasecmp(registry[i].name, name) == 0) { 82689dc44ceSjose borrego if (registry[i].value == NULL) 82789dc44ceSjose borrego return (winreg_sysname); 82889dc44ceSjose borrego else 82989dc44ceSjose borrego return (registry[i].value); 83089dc44ceSjose borrego } 83189dc44ceSjose borrego } 83289dc44ceSjose borrego 83389dc44ceSjose borrego return (NULL); 83489dc44ceSjose borrego } 83589dc44ceSjose borrego 83689dc44ceSjose borrego /* 83789dc44ceSjose borrego * winreg_s_SetKeySec 83889dc44ceSjose borrego */ 83989dc44ceSjose borrego /*ARGSUSED*/ 84089dc44ceSjose borrego static int 84189dc44ceSjose borrego winreg_s_SetKeySec(void *arg, ndr_xa_t *mxa) 84289dc44ceSjose borrego { 84389dc44ceSjose borrego struct winreg_SetKeySec *param = arg; 84489dc44ceSjose borrego 84589dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 84689dc44ceSjose borrego return (NDR_DRC_OK); 84789dc44ceSjose borrego } 84889dc44ceSjose borrego 84989dc44ceSjose borrego /* 85089dc44ceSjose borrego * winreg_s_CreateValue 85189dc44ceSjose borrego */ 85289dc44ceSjose borrego /*ARGSUSED*/ 85389dc44ceSjose borrego static int 85489dc44ceSjose borrego winreg_s_CreateValue(void *arg, ndr_xa_t *mxa) 85589dc44ceSjose borrego { 85689dc44ceSjose borrego struct winreg_CreateValue *param = arg; 85789dc44ceSjose borrego 85889dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 85989dc44ceSjose borrego return (NDR_DRC_OK); 86089dc44ceSjose borrego } 86189dc44ceSjose borrego 86289dc44ceSjose borrego /* 86389dc44ceSjose borrego * winreg_s_Shutdown 86489dc44ceSjose borrego * 86589dc44ceSjose borrego * Attempt to shutdown or reboot the system: access denied. 86689dc44ceSjose borrego */ 86789dc44ceSjose borrego /*ARGSUSED*/ 86889dc44ceSjose borrego static int 86989dc44ceSjose borrego winreg_s_Shutdown(void *arg, ndr_xa_t *mxa) 87089dc44ceSjose borrego { 87189dc44ceSjose borrego struct winreg_Shutdown *param = arg; 87289dc44ceSjose borrego 87389dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 87489dc44ceSjose borrego return (NDR_DRC_OK); 87589dc44ceSjose borrego } 87689dc44ceSjose borrego 87789dc44ceSjose borrego /* 87889dc44ceSjose borrego * winreg_s_AbortShutdown 87989dc44ceSjose borrego * 88089dc44ceSjose borrego * Abort a shutdown request. 88189dc44ceSjose borrego */ 88289dc44ceSjose borrego static int 88389dc44ceSjose borrego winreg_s_AbortShutdown(void *arg, ndr_xa_t *mxa) 88489dc44ceSjose borrego { 88589dc44ceSjose borrego struct winreg_AbortShutdown *param = arg; 88689dc44ceSjose borrego 88789dc44ceSjose borrego if (ndr_is_admin(mxa)) 88889dc44ceSjose borrego param->status = ERROR_SUCCESS; 88989dc44ceSjose borrego else 89089dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 89189dc44ceSjose borrego 89289dc44ceSjose borrego return (NDR_DRC_OK); 89389dc44ceSjose borrego } 89489dc44ceSjose borrego 89589dc44ceSjose borrego /* 89689dc44ceSjose borrego * winreg_s_GetVersion 89789dc44ceSjose borrego * 89889dc44ceSjose borrego * Return the windows registry version. The current version is 5. 89989dc44ceSjose borrego * This call is usually made prior to enumerating or querying registry 90089dc44ceSjose borrego * keys or values. 90189dc44ceSjose borrego */ 90289dc44ceSjose borrego /*ARGSUSED*/ 90389dc44ceSjose borrego static int 90489dc44ceSjose borrego winreg_s_GetVersion(void *arg, ndr_xa_t *mxa) 90589dc44ceSjose borrego { 90689dc44ceSjose borrego struct winreg_GetVersion *param = arg; 90789dc44ceSjose borrego 90889dc44ceSjose borrego param->version = 5; 90989dc44ceSjose borrego param->status = ERROR_SUCCESS; 91089dc44ceSjose borrego return (NDR_DRC_OK); 91189dc44ceSjose borrego } 912