1*89dc44ceSjose borrego /* 2*89dc44ceSjose borrego * CDDL HEADER START 3*89dc44ceSjose borrego * 4*89dc44ceSjose borrego * The contents of this file are subject to the terms of the 5*89dc44ceSjose borrego * Common Development and Distribution License (the "License"). 6*89dc44ceSjose borrego * You may not use this file except in compliance with the License. 7*89dc44ceSjose borrego * 8*89dc44ceSjose borrego * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*89dc44ceSjose borrego * or http://www.opensolaris.org/os/licensing. 10*89dc44ceSjose borrego * See the License for the specific language governing permissions 11*89dc44ceSjose borrego * and limitations under the License. 12*89dc44ceSjose borrego * 13*89dc44ceSjose borrego * When distributing Covered Code, include this CDDL HEADER in each 14*89dc44ceSjose borrego * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*89dc44ceSjose borrego * If applicable, add the following below this CDDL HEADER, with the 16*89dc44ceSjose borrego * fields enclosed by brackets "[]" replaced with your own identifying 17*89dc44ceSjose borrego * information: Portions Copyright [yyyy] [name of copyright owner] 18*89dc44ceSjose borrego * 19*89dc44ceSjose borrego * CDDL HEADER END 20*89dc44ceSjose borrego */ 21*89dc44ceSjose borrego /* 22*89dc44ceSjose borrego * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*89dc44ceSjose borrego * Use is subject to license terms. 24*89dc44ceSjose borrego */ 25*89dc44ceSjose borrego 26*89dc44ceSjose borrego /* 27*89dc44ceSjose borrego * Windows Registry RPC (WINREG) server-side interface. 28*89dc44ceSjose borrego * 29*89dc44ceSjose borrego * The WINREG RPC interface returns Win32 error codes. 30*89dc44ceSjose borrego * 31*89dc44ceSjose borrego * HKLM Hive Key Local Machine 32*89dc44ceSjose borrego * HKU Hive Key Users 33*89dc44ceSjose borrego */ 34*89dc44ceSjose borrego 35*89dc44ceSjose borrego #include <sys/utsname.h> 36*89dc44ceSjose borrego #include <strings.h> 37*89dc44ceSjose borrego 38*89dc44ceSjose borrego #include <smbsrv/libsmb.h> 39*89dc44ceSjose borrego #include <smbsrv/ntstatus.h> 40*89dc44ceSjose borrego #include <smbsrv/nterror.h> 41*89dc44ceSjose borrego #include <smbsrv/nmpipes.h> 42*89dc44ceSjose borrego #include <smbsrv/libmlsvc.h> 43*89dc44ceSjose borrego #include <smbsrv/ndl/winreg.ndl> 44*89dc44ceSjose borrego 45*89dc44ceSjose borrego #define WINREG_LOGR_SYSTEMKEY \ 46*89dc44ceSjose borrego "System\\CurrentControlSet\\Services\\Eventlog\\System" 47*89dc44ceSjose borrego 48*89dc44ceSjose borrego /* 49*89dc44ceSjose borrego * Local handle management keys. 50*89dc44ceSjose borrego */ 51*89dc44ceSjose borrego static int winreg_hk; 52*89dc44ceSjose borrego static int winreg_hklm; 53*89dc44ceSjose borrego static int winreg_hkuser; 54*89dc44ceSjose borrego static int winreg_hkkey; 55*89dc44ceSjose borrego 56*89dc44ceSjose borrego /* 57*89dc44ceSjose borrego * List of supported registry keys (case-insensitive). 58*89dc44ceSjose borrego */ 59*89dc44ceSjose borrego static char *winreg_keys[] = { 60*89dc44ceSjose borrego "System\\CurrentControlSet\\Services\\Eventlog", 61*89dc44ceSjose borrego "System\\CurrentControlSet\\Services\\Eventlog\\System", 62*89dc44ceSjose borrego "System\\CurrentControlSet\\Control\\ProductOptions", 63*89dc44ceSjose borrego "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" 64*89dc44ceSjose borrego }; 65*89dc44ceSjose borrego 66*89dc44ceSjose borrego typedef struct winreg_subkey { 67*89dc44ceSjose borrego list_node_t sk_lnd; 68*89dc44ceSjose borrego ndr_hdid_t sk_handle; 69*89dc44ceSjose borrego char sk_name[MAXPATHLEN]; 70*89dc44ceSjose borrego boolean_t sk_predefined; 71*89dc44ceSjose borrego } winreg_subkey_t; 72*89dc44ceSjose borrego 73*89dc44ceSjose borrego typedef struct winreg_keylist { 74*89dc44ceSjose borrego list_t kl_list; 75*89dc44ceSjose borrego int kl_count; 76*89dc44ceSjose borrego } winreg_keylist_t; 77*89dc44ceSjose borrego 78*89dc44ceSjose borrego static winreg_keylist_t winreg_keylist; 79*89dc44ceSjose borrego 80*89dc44ceSjose borrego static boolean_t winreg_key_has_subkey(const char *); 81*89dc44ceSjose borrego static char *winreg_lookup_value(const char *); 82*89dc44ceSjose borrego static char *winreg_lookup_eventlog_registry(char *, char *); 83*89dc44ceSjose borrego 84*89dc44ceSjose borrego static int winreg_s_OpenHK(void *, ndr_xa_t *); 85*89dc44ceSjose borrego static int winreg_s_OpenHKLM(void *, ndr_xa_t *); 86*89dc44ceSjose borrego static int winreg_s_OpenHKUsers(void *, ndr_xa_t *); 87*89dc44ceSjose borrego static int winreg_s_Close(void *, ndr_xa_t *); 88*89dc44ceSjose borrego static int winreg_s_CreateKey(void *, ndr_xa_t *); 89*89dc44ceSjose borrego static int winreg_s_DeleteKey(void *, ndr_xa_t *); 90*89dc44ceSjose borrego static int winreg_s_DeleteValue(void *, ndr_xa_t *); 91*89dc44ceSjose borrego static int winreg_s_EnumKey(void *, ndr_xa_t *); 92*89dc44ceSjose borrego static int winreg_s_EnumValue(void *, ndr_xa_t *); 93*89dc44ceSjose borrego static int winreg_s_FlushKey(void *, ndr_xa_t *); 94*89dc44ceSjose borrego static int winreg_s_GetKeySec(void *, ndr_xa_t *); 95*89dc44ceSjose borrego static int winreg_s_NotifyChange(void *, ndr_xa_t *); 96*89dc44ceSjose borrego static int winreg_s_OpenKey(void *, ndr_xa_t *); 97*89dc44ceSjose borrego static int winreg_s_QueryKey(void *, ndr_xa_t *); 98*89dc44ceSjose borrego static int winreg_s_QueryValue(void *, ndr_xa_t *); 99*89dc44ceSjose borrego static int winreg_s_SetKeySec(void *, ndr_xa_t *); 100*89dc44ceSjose borrego static int winreg_s_CreateValue(void *, ndr_xa_t *); 101*89dc44ceSjose borrego static int winreg_s_Shutdown(void *, ndr_xa_t *); 102*89dc44ceSjose borrego static int winreg_s_AbortShutdown(void *, ndr_xa_t *); 103*89dc44ceSjose borrego static int winreg_s_GetVersion(void *, ndr_xa_t *); 104*89dc44ceSjose borrego 105*89dc44ceSjose borrego static ndr_stub_table_t winreg_stub_table[] = { 106*89dc44ceSjose borrego { winreg_s_OpenHK, WINREG_OPNUM_OpenHKCR }, 107*89dc44ceSjose borrego { winreg_s_OpenHK, WINREG_OPNUM_OpenHKCU }, 108*89dc44ceSjose borrego { winreg_s_OpenHKLM, WINREG_OPNUM_OpenHKLM }, 109*89dc44ceSjose borrego { winreg_s_OpenHK, WINREG_OPNUM_OpenHKPD }, 110*89dc44ceSjose borrego { winreg_s_OpenHKUsers, WINREG_OPNUM_OpenHKUsers }, 111*89dc44ceSjose borrego { winreg_s_Close, WINREG_OPNUM_Close }, 112*89dc44ceSjose borrego { winreg_s_CreateKey, WINREG_OPNUM_CreateKey }, 113*89dc44ceSjose borrego { winreg_s_DeleteKey, WINREG_OPNUM_DeleteKey }, 114*89dc44ceSjose borrego { winreg_s_DeleteValue, WINREG_OPNUM_DeleteValue }, 115*89dc44ceSjose borrego { winreg_s_EnumKey, WINREG_OPNUM_EnumKey }, 116*89dc44ceSjose borrego { winreg_s_EnumValue, WINREG_OPNUM_EnumValue }, 117*89dc44ceSjose borrego { winreg_s_FlushKey, WINREG_OPNUM_FlushKey }, 118*89dc44ceSjose borrego { winreg_s_GetKeySec, WINREG_OPNUM_GetKeySec }, 119*89dc44ceSjose borrego { winreg_s_NotifyChange, WINREG_OPNUM_NotifyChange }, 120*89dc44ceSjose borrego { winreg_s_OpenKey, WINREG_OPNUM_OpenKey }, 121*89dc44ceSjose borrego { winreg_s_QueryKey, WINREG_OPNUM_QueryKey }, 122*89dc44ceSjose borrego { winreg_s_QueryValue, WINREG_OPNUM_QueryValue }, 123*89dc44ceSjose borrego { winreg_s_SetKeySec, WINREG_OPNUM_SetKeySec }, 124*89dc44ceSjose borrego { winreg_s_CreateValue, WINREG_OPNUM_CreateValue }, 125*89dc44ceSjose borrego { winreg_s_Shutdown, WINREG_OPNUM_Shutdown }, 126*89dc44ceSjose borrego { winreg_s_AbortShutdown, WINREG_OPNUM_AbortShutdown }, 127*89dc44ceSjose borrego { winreg_s_GetVersion, WINREG_OPNUM_GetVersion }, 128*89dc44ceSjose borrego { winreg_s_OpenHK, WINREG_OPNUM_OpenHKCC }, 129*89dc44ceSjose borrego { winreg_s_OpenHK, WINREG_OPNUM_OpenHKDD }, 130*89dc44ceSjose borrego { winreg_s_OpenHK, WINREG_OPNUM_OpenHKPT }, 131*89dc44ceSjose borrego { winreg_s_OpenHK, WINREG_OPNUM_OpenHKPN }, 132*89dc44ceSjose borrego {0} 133*89dc44ceSjose borrego }; 134*89dc44ceSjose borrego 135*89dc44ceSjose borrego static ndr_service_t winreg_service = { 136*89dc44ceSjose borrego "Winreg", /* name */ 137*89dc44ceSjose borrego "Windows Registry", /* desc */ 138*89dc44ceSjose borrego "\\winreg", /* endpoint */ 139*89dc44ceSjose borrego PIPE_WINREG, /* sec_addr_port */ 140*89dc44ceSjose borrego "338cd001-2244-31f1-aaaa-900038001003", 1, /* abstract */ 141*89dc44ceSjose borrego NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 142*89dc44ceSjose borrego 0, /* no bind_instance_size */ 143*89dc44ceSjose borrego 0, /* no bind_req() */ 144*89dc44ceSjose borrego 0, /* no unbind_and_close() */ 145*89dc44ceSjose borrego 0, /* use generic_call_stub() */ 146*89dc44ceSjose borrego &TYPEINFO(winreg_interface), /* interface ti */ 147*89dc44ceSjose borrego winreg_stub_table /* stub_table */ 148*89dc44ceSjose borrego }; 149*89dc44ceSjose borrego 150*89dc44ceSjose borrego static char winreg_sysname[SYS_NMLN]; 151*89dc44ceSjose borrego 152*89dc44ceSjose borrego /* 153*89dc44ceSjose borrego * winreg_initialize 154*89dc44ceSjose borrego * 155*89dc44ceSjose borrego * Initialize and register the WINREG RPC interface with the RPC runtime 156*89dc44ceSjose borrego * library. It must be called in order to use either the client side 157*89dc44ceSjose borrego * or the server side functions. 158*89dc44ceSjose borrego */ 159*89dc44ceSjose borrego void 160*89dc44ceSjose borrego winreg_initialize(void) 161*89dc44ceSjose borrego { 162*89dc44ceSjose borrego winreg_subkey_t *key; 163*89dc44ceSjose borrego struct utsname name; 164*89dc44ceSjose borrego char *sysname; 165*89dc44ceSjose borrego int i; 166*89dc44ceSjose borrego 167*89dc44ceSjose borrego list_create(&winreg_keylist.kl_list, sizeof (winreg_subkey_t), 168*89dc44ceSjose borrego offsetof(winreg_subkey_t, sk_lnd)); 169*89dc44ceSjose borrego winreg_keylist.kl_count = 0; 170*89dc44ceSjose borrego 171*89dc44ceSjose borrego for (i = 0; i < sizeof (winreg_keys)/sizeof (winreg_keys[0]); ++i) { 172*89dc44ceSjose borrego if ((key = malloc(sizeof (winreg_subkey_t))) != NULL) { 173*89dc44ceSjose borrego bzero(key, sizeof (winreg_subkey_t)); 174*89dc44ceSjose borrego (void) strlcpy(key->sk_name, winreg_keys[i], 175*89dc44ceSjose borrego MAXPATHLEN); 176*89dc44ceSjose borrego key->sk_predefined = B_TRUE; 177*89dc44ceSjose borrego list_insert_tail(&winreg_keylist.kl_list, key); 178*89dc44ceSjose borrego ++winreg_keylist.kl_count; 179*89dc44ceSjose borrego } 180*89dc44ceSjose borrego } 181*89dc44ceSjose borrego 182*89dc44ceSjose borrego if (uname(&name) < 0) 183*89dc44ceSjose borrego sysname = "Solaris"; 184*89dc44ceSjose borrego else 185*89dc44ceSjose borrego sysname = name.sysname; 186*89dc44ceSjose borrego 187*89dc44ceSjose borrego (void) strlcpy(winreg_sysname, sysname, SYS_NMLN); 188*89dc44ceSjose borrego (void) ndr_svc_register(&winreg_service); 189*89dc44ceSjose borrego } 190*89dc44ceSjose borrego 191*89dc44ceSjose borrego /* 192*89dc44ceSjose borrego * winreg_s_OpenHK 193*89dc44ceSjose borrego * 194*89dc44ceSjose borrego * Stub. 195*89dc44ceSjose borrego */ 196*89dc44ceSjose borrego static int 197*89dc44ceSjose borrego winreg_s_OpenHK(void *arg, ndr_xa_t *mxa) 198*89dc44ceSjose borrego { 199*89dc44ceSjose borrego struct winreg_OpenHKCR *param = arg; 200*89dc44ceSjose borrego ndr_hdid_t *id; 201*89dc44ceSjose borrego 202*89dc44ceSjose borrego if ((id = ndr_hdalloc(mxa, &winreg_hk)) == NULL) { 203*89dc44ceSjose borrego bzero(¶m->handle, sizeof (winreg_handle_t)); 204*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 205*89dc44ceSjose borrego } else { 206*89dc44ceSjose borrego bcopy(id, ¶m->handle, sizeof (winreg_handle_t)); 207*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 208*89dc44ceSjose borrego } 209*89dc44ceSjose borrego 210*89dc44ceSjose borrego return (NDR_DRC_OK); 211*89dc44ceSjose borrego } 212*89dc44ceSjose borrego 213*89dc44ceSjose borrego /* 214*89dc44ceSjose borrego * winreg_s_OpenHKLM 215*89dc44ceSjose borrego * 216*89dc44ceSjose borrego * This is a request to open the HKLM and get a handle. 217*89dc44ceSjose borrego * The client should treat the handle as an opaque object. 218*89dc44ceSjose borrego * 219*89dc44ceSjose borrego * Status: 220*89dc44ceSjose borrego * ERROR_SUCCESS Valid handle returned. 221*89dc44ceSjose borrego * ERROR_ACCESS_DENIED Unable to allocate a handle. 222*89dc44ceSjose borrego */ 223*89dc44ceSjose borrego static int 224*89dc44ceSjose borrego winreg_s_OpenHKLM(void *arg, ndr_xa_t *mxa) 225*89dc44ceSjose borrego { 226*89dc44ceSjose borrego struct winreg_OpenHKLM *param = arg; 227*89dc44ceSjose borrego ndr_hdid_t *id; 228*89dc44ceSjose borrego 229*89dc44ceSjose borrego if ((id = ndr_hdalloc(mxa, &winreg_hklm)) == NULL) { 230*89dc44ceSjose borrego bzero(¶m->handle, sizeof (winreg_handle_t)); 231*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 232*89dc44ceSjose borrego } else { 233*89dc44ceSjose borrego bcopy(id, ¶m->handle, sizeof (winreg_handle_t)); 234*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 235*89dc44ceSjose borrego } 236*89dc44ceSjose borrego 237*89dc44ceSjose borrego return (NDR_DRC_OK); 238*89dc44ceSjose borrego } 239*89dc44ceSjose borrego 240*89dc44ceSjose borrego /* 241*89dc44ceSjose borrego * winreg_s_OpenHKUsers 242*89dc44ceSjose borrego * 243*89dc44ceSjose borrego * This is a request to get a HKUsers handle. I'm not sure we are 244*89dc44ceSjose borrego * ready to fully support this interface yet, mostly due to the need 245*89dc44ceSjose borrego * to support subsequent requests, but we may support enough now. It 246*89dc44ceSjose borrego * seems okay with regedt32. 247*89dc44ceSjose borrego */ 248*89dc44ceSjose borrego static int 249*89dc44ceSjose borrego winreg_s_OpenHKUsers(void *arg, ndr_xa_t *mxa) 250*89dc44ceSjose borrego { 251*89dc44ceSjose borrego struct winreg_OpenHKUsers *param = arg; 252*89dc44ceSjose borrego ndr_hdid_t *id; 253*89dc44ceSjose borrego 254*89dc44ceSjose borrego if ((id = ndr_hdalloc(mxa, &winreg_hkuser)) == NULL) { 255*89dc44ceSjose borrego bzero(¶m->handle, sizeof (winreg_handle_t)); 256*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 257*89dc44ceSjose borrego } else { 258*89dc44ceSjose borrego bcopy(id, ¶m->handle, sizeof (winreg_handle_t)); 259*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 260*89dc44ceSjose borrego } 261*89dc44ceSjose borrego 262*89dc44ceSjose borrego return (NDR_DRC_OK); 263*89dc44ceSjose borrego } 264*89dc44ceSjose borrego 265*89dc44ceSjose borrego /* 266*89dc44ceSjose borrego * winreg_s_Close 267*89dc44ceSjose borrego * 268*89dc44ceSjose borrego * This is a request to close the WINREG interface specified by the 269*89dc44ceSjose borrego * handle. We don't track handles (yet), so just zero out the handle 270*89dc44ceSjose borrego * and return NDR_DRC_OK. Setting the handle to zero appears to be 271*89dc44ceSjose borrego * standard behaviour. 272*89dc44ceSjose borrego */ 273*89dc44ceSjose borrego static int 274*89dc44ceSjose borrego winreg_s_Close(void *arg, ndr_xa_t *mxa) 275*89dc44ceSjose borrego { 276*89dc44ceSjose borrego struct winreg_Close *param = arg; 277*89dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 278*89dc44ceSjose borrego 279*89dc44ceSjose borrego ndr_hdfree(mxa, id); 280*89dc44ceSjose borrego 281*89dc44ceSjose borrego bzero(¶m->result_handle, sizeof (winreg_handle_t)); 282*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 283*89dc44ceSjose borrego return (NDR_DRC_OK); 284*89dc44ceSjose borrego } 285*89dc44ceSjose borrego 286*89dc44ceSjose borrego /* 287*89dc44ceSjose borrego * winreg_s_CreateKey 288*89dc44ceSjose borrego */ 289*89dc44ceSjose borrego static int 290*89dc44ceSjose borrego winreg_s_CreateKey(void *arg, ndr_xa_t *mxa) 291*89dc44ceSjose borrego { 292*89dc44ceSjose borrego struct winreg_CreateKey *param = arg; 293*89dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 294*89dc44ceSjose borrego ndr_handle_t *hd; 295*89dc44ceSjose borrego winreg_subkey_t *key; 296*89dc44ceSjose borrego char *subkey; 297*89dc44ceSjose borrego DWORD *action; 298*89dc44ceSjose borrego 299*89dc44ceSjose borrego subkey = (char *)param->subkey.str; 300*89dc44ceSjose borrego 301*89dc44ceSjose borrego if (!ndr_is_admin(mxa) || (subkey == NULL)) { 302*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey)); 303*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 304*89dc44ceSjose borrego return (NDR_DRC_OK); 305*89dc44ceSjose borrego } 306*89dc44ceSjose borrego 307*89dc44ceSjose borrego hd = ndr_hdlookup(mxa, id); 308*89dc44ceSjose borrego if (hd == NULL) { 309*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey)); 310*89dc44ceSjose borrego param->status = ERROR_INVALID_HANDLE; 311*89dc44ceSjose borrego return (NDR_DRC_OK); 312*89dc44ceSjose borrego } 313*89dc44ceSjose borrego 314*89dc44ceSjose borrego if ((action = NDR_NEW(mxa, DWORD)) == NULL) { 315*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey)); 316*89dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 317*89dc44ceSjose borrego return (NDR_DRC_OK); 318*89dc44ceSjose borrego } 319*89dc44ceSjose borrego 320*89dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list)) 321*89dc44ceSjose borrego goto new_key; 322*89dc44ceSjose borrego 323*89dc44ceSjose borrego /* 324*89dc44ceSjose borrego * Check for an existing key. 325*89dc44ceSjose borrego */ 326*89dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 327*89dc44ceSjose borrego do { 328*89dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) { 329*89dc44ceSjose borrego bcopy(&key->sk_handle, ¶m->result_handle, 330*89dc44ceSjose borrego sizeof (winreg_handle_t)); 331*89dc44ceSjose borrego *action = WINREG_ACTION_EXISTING_KEY; 332*89dc44ceSjose borrego param->action = action; 333*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 334*89dc44ceSjose borrego return (NDR_DRC_OK); 335*89dc44ceSjose borrego } 336*89dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 337*89dc44ceSjose borrego 338*89dc44ceSjose borrego new_key: 339*89dc44ceSjose borrego /* 340*89dc44ceSjose borrego * Create a new key. 341*89dc44ceSjose borrego */ 342*89dc44ceSjose borrego id = ndr_hdalloc(mxa, &winreg_hkkey); 343*89dc44ceSjose borrego key = malloc(sizeof (winreg_subkey_t)); 344*89dc44ceSjose borrego 345*89dc44ceSjose borrego if ((id == NULL) || (key == NULL)) { 346*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey)); 347*89dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 348*89dc44ceSjose borrego return (NDR_DRC_OK); 349*89dc44ceSjose borrego } 350*89dc44ceSjose borrego 351*89dc44ceSjose borrego bcopy(id, &key->sk_handle, sizeof (ndr_hdid_t)); 352*89dc44ceSjose borrego (void) strlcpy(key->sk_name, subkey, MAXPATHLEN); 353*89dc44ceSjose borrego key->sk_predefined = B_FALSE; 354*89dc44ceSjose borrego list_insert_tail(&winreg_keylist.kl_list, key); 355*89dc44ceSjose borrego ++winreg_keylist.kl_count; 356*89dc44ceSjose borrego 357*89dc44ceSjose borrego bcopy(id, ¶m->result_handle, sizeof (winreg_handle_t)); 358*89dc44ceSjose borrego *action = WINREG_ACTION_NEW_KEY; 359*89dc44ceSjose borrego param->action = action; 360*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 361*89dc44ceSjose borrego return (NDR_DRC_OK); 362*89dc44ceSjose borrego } 363*89dc44ceSjose borrego 364*89dc44ceSjose borrego /* 365*89dc44ceSjose borrego * winreg_s_DeleteKey 366*89dc44ceSjose borrego */ 367*89dc44ceSjose borrego static int 368*89dc44ceSjose borrego winreg_s_DeleteKey(void *arg, ndr_xa_t *mxa) 369*89dc44ceSjose borrego { 370*89dc44ceSjose borrego struct winreg_DeleteKey *param = arg; 371*89dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 372*89dc44ceSjose borrego winreg_subkey_t *key; 373*89dc44ceSjose borrego char *subkey; 374*89dc44ceSjose borrego 375*89dc44ceSjose borrego subkey = (char *)param->subkey.str; 376*89dc44ceSjose borrego 377*89dc44ceSjose borrego if (!ndr_is_admin(mxa) || (subkey == NULL)) { 378*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 379*89dc44ceSjose borrego return (NDR_DRC_OK); 380*89dc44ceSjose borrego } 381*89dc44ceSjose borrego 382*89dc44ceSjose borrego if ((ndr_hdlookup(mxa, id) == NULL) || 383*89dc44ceSjose borrego list_is_empty(&winreg_keylist.kl_list) || 384*89dc44ceSjose borrego winreg_key_has_subkey(subkey)) { 385*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 386*89dc44ceSjose borrego return (NDR_DRC_OK); 387*89dc44ceSjose borrego } 388*89dc44ceSjose borrego 389*89dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 390*89dc44ceSjose borrego do { 391*89dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) { 392*89dc44ceSjose borrego if (key->sk_predefined == B_TRUE) { 393*89dc44ceSjose borrego /* Predefined keys cannot be deleted */ 394*89dc44ceSjose borrego break; 395*89dc44ceSjose borrego } 396*89dc44ceSjose borrego 397*89dc44ceSjose borrego list_remove(&winreg_keylist.kl_list, key); 398*89dc44ceSjose borrego --winreg_keylist.kl_count; 399*89dc44ceSjose borrego ndr_hdfree(mxa, &key->sk_handle); 400*89dc44ceSjose borrego free(key); 401*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 402*89dc44ceSjose borrego return (NDR_DRC_OK); 403*89dc44ceSjose borrego } 404*89dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 405*89dc44ceSjose borrego 406*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 407*89dc44ceSjose borrego return (NDR_DRC_OK); 408*89dc44ceSjose borrego } 409*89dc44ceSjose borrego 410*89dc44ceSjose borrego static boolean_t 411*89dc44ceSjose borrego winreg_key_has_subkey(const char *subkey) 412*89dc44ceSjose borrego { 413*89dc44ceSjose borrego winreg_subkey_t *key; 414*89dc44ceSjose borrego int keylen; 415*89dc44ceSjose borrego 416*89dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list)) 417*89dc44ceSjose borrego return (B_FALSE); 418*89dc44ceSjose borrego 419*89dc44ceSjose borrego keylen = strlen(subkey); 420*89dc44ceSjose borrego 421*89dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 422*89dc44ceSjose borrego do { 423*89dc44ceSjose borrego if (strncasecmp(subkey, key->sk_name, keylen) == 0) { 424*89dc44ceSjose borrego /* 425*89dc44ceSjose borrego * Potential match. If sk_name is longer than 426*89dc44ceSjose borrego * subkey, then sk_name is a subkey of our key. 427*89dc44ceSjose borrego */ 428*89dc44ceSjose borrego if (keylen < strlen(key->sk_name)) 429*89dc44ceSjose borrego return (B_TRUE); 430*89dc44ceSjose borrego } 431*89dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 432*89dc44ceSjose borrego 433*89dc44ceSjose borrego return (B_FALSE); 434*89dc44ceSjose borrego } 435*89dc44ceSjose borrego 436*89dc44ceSjose borrego /* 437*89dc44ceSjose borrego * winreg_subkey_get_relative_name 438*89dc44ceSjose borrego * 439*89dc44ceSjose borrego * Each key contains one or more child keys, each called a subkey. 440*89dc44ceSjose borrego * For any specified key, its name MUST be unique for any other subkeys that 441*89dc44ceSjose borrego * have the same parent key. 442*89dc44ceSjose borrego * 443*89dc44ceSjose borrego * To accurately identify a given subkey within the key namespace, its fully 444*89dc44ceSjose borrego * qualified name (FQN) is used. The FQN MUST consist of the name of the subkey 445*89dc44ceSjose borrego * and the name of all of its parent keys all the way to the root of the tree. 446*89dc44ceSjose borrego * 447*89dc44ceSjose borrego * The "\" character MUST be used as a hierarchy separator to identify each key 448*89dc44ceSjose borrego * in the FQN and therefore MUST not be used in the name of a single key. 449*89dc44ceSjose borrego * For example, the subkey "MountedDevices" belongs to the subtree 450*89dc44ceSjose borrego * HKEY_LOCAL_MACHINE, as shown in the following example. 451*89dc44ceSjose borrego * 452*89dc44ceSjose borrego * HKEY_LOCAL_MACHINE -> SYSTEM -> MountedDevices 453*89dc44ceSjose borrego * 454*89dc44ceSjose borrego * The FQN for MountedDevices is HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices. 455*89dc44ceSjose borrego * The relative name of the subkey is "MountedDevices". The relative name 456*89dc44ceSjose borrego * MUST be used only for operations that are performed on its immediate parent 457*89dc44ceSjose borrego * key (SYSTEM in the previous example). 458*89dc44ceSjose borrego */ 459*89dc44ceSjose borrego static char * 460*89dc44ceSjose borrego winreg_subkey_get_relative_name(const char *subkey) 461*89dc44ceSjose borrego { 462*89dc44ceSjose borrego winreg_subkey_t *key; 463*89dc44ceSjose borrego char *value; 464*89dc44ceSjose borrego 465*89dc44ceSjose borrego if (subkey == NULL) 466*89dc44ceSjose borrego return (NULL); 467*89dc44ceSjose borrego 468*89dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list)) 469*89dc44ceSjose borrego return (NULL); 470*89dc44ceSjose borrego 471*89dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 472*89dc44ceSjose borrego do { 473*89dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) { 474*89dc44ceSjose borrego value = strrchr(key->sk_name, '\\'); 475*89dc44ceSjose borrego if (value != NULL) 476*89dc44ceSjose borrego return (++value); 477*89dc44ceSjose borrego } 478*89dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 479*89dc44ceSjose borrego 480*89dc44ceSjose borrego return (NULL); 481*89dc44ceSjose borrego } 482*89dc44ceSjose borrego 483*89dc44ceSjose borrego /* 484*89dc44ceSjose borrego * winreg_s_DeleteValue 485*89dc44ceSjose borrego */ 486*89dc44ceSjose borrego /*ARGSUSED*/ 487*89dc44ceSjose borrego static int 488*89dc44ceSjose borrego winreg_s_DeleteValue(void *arg, ndr_xa_t *mxa) 489*89dc44ceSjose borrego { 490*89dc44ceSjose borrego struct winreg_DeleteValue *param = arg; 491*89dc44ceSjose borrego 492*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 493*89dc44ceSjose borrego return (NDR_DRC_OK); 494*89dc44ceSjose borrego } 495*89dc44ceSjose borrego 496*89dc44ceSjose borrego /* 497*89dc44ceSjose borrego * winreg_s_EnumKey 498*89dc44ceSjose borrego */ 499*89dc44ceSjose borrego static int 500*89dc44ceSjose borrego winreg_s_EnumKey(void *arg, ndr_xa_t *mxa) 501*89dc44ceSjose borrego { 502*89dc44ceSjose borrego struct winreg_EnumKey *param = arg; 503*89dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 504*89dc44ceSjose borrego winreg_string_t *name, *class; 505*89dc44ceSjose borrego char *value, *namep = NULL, *classp = NULL; 506*89dc44ceSjose borrego int slen = 0; 507*89dc44ceSjose borrego 508*89dc44ceSjose borrego if (ndr_hdlookup(mxa, id) == NULL) { 509*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey)); 510*89dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS; 511*89dc44ceSjose borrego return (NDR_DRC_OK); 512*89dc44ceSjose borrego } 513*89dc44ceSjose borrego 514*89dc44ceSjose borrego if (param->index > 0) { 515*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey)); 516*89dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS; 517*89dc44ceSjose borrego return (NDR_DRC_OK); 518*89dc44ceSjose borrego } 519*89dc44ceSjose borrego 520*89dc44ceSjose borrego name = (winreg_string_t *)¶m->name_in; 521*89dc44ceSjose borrego class = (winreg_string_t *)¶m->class_in; 522*89dc44ceSjose borrego if (name->length != 0) 523*89dc44ceSjose borrego namep = (char *)name->str; 524*89dc44ceSjose borrego 525*89dc44ceSjose borrego if (class->length != 0) 526*89dc44ceSjose borrego classp = (char *)class->str; 527*89dc44ceSjose borrego 528*89dc44ceSjose borrego value = winreg_lookup_eventlog_registry(namep, classp); 529*89dc44ceSjose borrego if (value == NULL) { 530*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey)); 531*89dc44ceSjose borrego param->status = ERROR_CANTREAD; 532*89dc44ceSjose borrego return (NDR_DRC_OK); 533*89dc44ceSjose borrego } 534*89dc44ceSjose borrego 535*89dc44ceSjose borrego slen = mts_wcequiv_strlen(value) + sizeof (mts_wchar_t); 536*89dc44ceSjose borrego param->name_out.length = slen; 537*89dc44ceSjose borrego param->name_out.allosize = slen; 538*89dc44ceSjose borrego if ((param->name_out.str = NDR_STRDUP(mxa, value)) == NULL) { 539*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey)); 540*89dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 541*89dc44ceSjose borrego return (NDR_DRC_OK); 542*89dc44ceSjose borrego } 543*89dc44ceSjose borrego 544*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 545*89dc44ceSjose borrego return (NDR_DRC_OK); 546*89dc44ceSjose borrego } 547*89dc44ceSjose borrego 548*89dc44ceSjose borrego /* 549*89dc44ceSjose borrego * winreg_s_EnumValue 550*89dc44ceSjose borrego */ 551*89dc44ceSjose borrego static int 552*89dc44ceSjose borrego winreg_s_EnumValue(void *arg, ndr_xa_t *mxa) 553*89dc44ceSjose borrego { 554*89dc44ceSjose borrego struct winreg_EnumValue *param = arg; 555*89dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 556*89dc44ceSjose borrego 557*89dc44ceSjose borrego if (ndr_hdlookup(mxa, id) == NULL) { 558*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumValue)); 559*89dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS; 560*89dc44ceSjose borrego return (NDR_DRC_OK); 561*89dc44ceSjose borrego } 562*89dc44ceSjose borrego 563*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumValue)); 564*89dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS; 565*89dc44ceSjose borrego return (NDR_DRC_OK); 566*89dc44ceSjose borrego } 567*89dc44ceSjose borrego 568*89dc44ceSjose borrego /* 569*89dc44ceSjose borrego * winreg_s_FlushKey 570*89dc44ceSjose borrego * 571*89dc44ceSjose borrego * Flush the attributes associated with the specified open key to disk. 572*89dc44ceSjose borrego */ 573*89dc44ceSjose borrego static int 574*89dc44ceSjose borrego winreg_s_FlushKey(void *arg, ndr_xa_t *mxa) 575*89dc44ceSjose borrego { 576*89dc44ceSjose borrego struct winreg_FlushKey *param = arg; 577*89dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 578*89dc44ceSjose borrego 579*89dc44ceSjose borrego if (ndr_hdlookup(mxa, id) == NULL) 580*89dc44ceSjose borrego param->status = ERROR_INVALID_HANDLE; 581*89dc44ceSjose borrego else 582*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 583*89dc44ceSjose borrego 584*89dc44ceSjose borrego return (NDR_DRC_OK); 585*89dc44ceSjose borrego } 586*89dc44ceSjose borrego 587*89dc44ceSjose borrego /* 588*89dc44ceSjose borrego * winreg_s_GetKeySec 589*89dc44ceSjose borrego */ 590*89dc44ceSjose borrego /*ARGSUSED*/ 591*89dc44ceSjose borrego static int 592*89dc44ceSjose borrego winreg_s_GetKeySec(void *arg, ndr_xa_t *mxa) 593*89dc44ceSjose borrego { 594*89dc44ceSjose borrego struct winreg_GetKeySec *param = arg; 595*89dc44ceSjose borrego 596*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_GetKeySec)); 597*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 598*89dc44ceSjose borrego return (NDR_DRC_OK); 599*89dc44ceSjose borrego } 600*89dc44ceSjose borrego 601*89dc44ceSjose borrego /* 602*89dc44ceSjose borrego * winreg_s_NotifyChange 603*89dc44ceSjose borrego */ 604*89dc44ceSjose borrego static int 605*89dc44ceSjose borrego winreg_s_NotifyChange(void *arg, ndr_xa_t *mxa) 606*89dc44ceSjose borrego { 607*89dc44ceSjose borrego struct winreg_NotifyChange *param = arg; 608*89dc44ceSjose borrego 609*89dc44ceSjose borrego if (ndr_is_admin(mxa)) 610*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 611*89dc44ceSjose borrego else 612*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 613*89dc44ceSjose borrego 614*89dc44ceSjose borrego return (NDR_DRC_OK); 615*89dc44ceSjose borrego } 616*89dc44ceSjose borrego 617*89dc44ceSjose borrego /* 618*89dc44ceSjose borrego * winreg_s_OpenKey 619*89dc44ceSjose borrego * 620*89dc44ceSjose borrego * This is a request to open a windows registry key. 621*89dc44ceSjose borrego * If we recognize the key, we return a handle. 622*89dc44ceSjose borrego * 623*89dc44ceSjose borrego * Returns: 624*89dc44ceSjose borrego * ERROR_SUCCESS Valid handle returned. 625*89dc44ceSjose borrego * ERROR_FILE_NOT_FOUND No key or unable to allocate a handle. 626*89dc44ceSjose borrego */ 627*89dc44ceSjose borrego static int 628*89dc44ceSjose borrego winreg_s_OpenKey(void *arg, ndr_xa_t *mxa) 629*89dc44ceSjose borrego { 630*89dc44ceSjose borrego struct winreg_OpenKey *param = arg; 631*89dc44ceSjose borrego char *subkey = (char *)param->name.str; 632*89dc44ceSjose borrego ndr_hdid_t *id = NULL; 633*89dc44ceSjose borrego winreg_subkey_t *key; 634*89dc44ceSjose borrego 635*89dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list)) { 636*89dc44ceSjose borrego bzero(¶m->result_handle, sizeof (winreg_handle_t)); 637*89dc44ceSjose borrego param->status = ERROR_FILE_NOT_FOUND; 638*89dc44ceSjose borrego return (NDR_DRC_OK); 639*89dc44ceSjose borrego } 640*89dc44ceSjose borrego 641*89dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list); 642*89dc44ceSjose borrego do { 643*89dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) { 644*89dc44ceSjose borrego if (key->sk_predefined == B_TRUE) 645*89dc44ceSjose borrego id = ndr_hdalloc(mxa, &winreg_hkkey); 646*89dc44ceSjose borrego else 647*89dc44ceSjose borrego id = &key->sk_handle; 648*89dc44ceSjose borrego 649*89dc44ceSjose borrego if (id == NULL) 650*89dc44ceSjose borrego break; 651*89dc44ceSjose borrego 652*89dc44ceSjose borrego bcopy(id, ¶m->result_handle, 653*89dc44ceSjose borrego sizeof (winreg_handle_t)); 654*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 655*89dc44ceSjose borrego return (NDR_DRC_OK); 656*89dc44ceSjose borrego } 657*89dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL); 658*89dc44ceSjose borrego 659*89dc44ceSjose borrego bzero(¶m->result_handle, sizeof (winreg_handle_t)); 660*89dc44ceSjose borrego param->status = ERROR_FILE_NOT_FOUND; 661*89dc44ceSjose borrego return (NDR_DRC_OK); 662*89dc44ceSjose borrego } 663*89dc44ceSjose borrego 664*89dc44ceSjose borrego /* 665*89dc44ceSjose borrego * winreg_s_QueryKey 666*89dc44ceSjose borrego */ 667*89dc44ceSjose borrego /*ARGSUSED*/ 668*89dc44ceSjose borrego static int 669*89dc44ceSjose borrego winreg_s_QueryKey(void *arg, ndr_xa_t *mxa) 670*89dc44ceSjose borrego { 671*89dc44ceSjose borrego struct winreg_QueryKey *param = arg; 672*89dc44ceSjose borrego int rc; 673*89dc44ceSjose borrego winreg_string_t *name; 674*89dc44ceSjose borrego 675*89dc44ceSjose borrego name = (winreg_string_t *)¶m->name; 676*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_QueryKey)); 677*89dc44ceSjose borrego if ((name = NDR_NEW(mxa, winreg_string_t)) != NULL) 678*89dc44ceSjose borrego rc = NDR_MSTRING(mxa, "", (ndr_mstring_t *)name); 679*89dc44ceSjose borrego 680*89dc44ceSjose borrego if ((name == NULL) || (rc != 0)) { 681*89dc44ceSjose borrego bzero(param, sizeof (struct winreg_QueryKey)); 682*89dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY; 683*89dc44ceSjose borrego return (NDR_DRC_OK); 684*89dc44ceSjose borrego } 685*89dc44ceSjose borrego 686*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 687*89dc44ceSjose borrego return (NDR_DRC_OK); 688*89dc44ceSjose borrego } 689*89dc44ceSjose borrego 690*89dc44ceSjose borrego /* 691*89dc44ceSjose borrego * winreg_s_QueryValue 692*89dc44ceSjose borrego * 693*89dc44ceSjose borrego * This is a request to get the value associated with a specified name. 694*89dc44ceSjose borrego * 695*89dc44ceSjose borrego * Returns: 696*89dc44ceSjose borrego * ERROR_SUCCESS Value returned. 697*89dc44ceSjose borrego * ERROR_FILE_NOT_FOUND PrimaryModule is not supported. 698*89dc44ceSjose borrego * ERROR_CANTREAD No such name or memory problem. 699*89dc44ceSjose borrego */ 700*89dc44ceSjose borrego static int 701*89dc44ceSjose borrego winreg_s_QueryValue(void *arg, ndr_xa_t *mxa) 702*89dc44ceSjose borrego { 703*89dc44ceSjose borrego struct winreg_QueryValue *param = arg; 704*89dc44ceSjose borrego struct winreg_value *pv; 705*89dc44ceSjose borrego char *name; 706*89dc44ceSjose borrego char *value; 707*89dc44ceSjose borrego DWORD slen; 708*89dc44ceSjose borrego DWORD msize; 709*89dc44ceSjose borrego 710*89dc44ceSjose borrego name = (char *)param->value_name.str; 711*89dc44ceSjose borrego 712*89dc44ceSjose borrego if (strcasecmp(name, "PrimaryModule") == 0) { 713*89dc44ceSjose borrego param->status = ERROR_FILE_NOT_FOUND; 714*89dc44ceSjose borrego return (NDR_DRC_OK); 715*89dc44ceSjose borrego } 716*89dc44ceSjose borrego 717*89dc44ceSjose borrego if ((value = winreg_lookup_value(name)) == NULL) { 718*89dc44ceSjose borrego param->status = ERROR_CANTREAD; 719*89dc44ceSjose borrego return (NDR_DRC_OK); 720*89dc44ceSjose borrego } 721*89dc44ceSjose borrego 722*89dc44ceSjose borrego slen = mts_wcequiv_strlen(value) + sizeof (mts_wchar_t); 723*89dc44ceSjose borrego msize = sizeof (struct winreg_value) + slen; 724*89dc44ceSjose borrego 725*89dc44ceSjose borrego param->value = (struct winreg_value *)NDR_MALLOC(mxa, msize); 726*89dc44ceSjose borrego param->type = NDR_NEW(mxa, DWORD); 727*89dc44ceSjose borrego param->value_size = NDR_NEW(mxa, DWORD); 728*89dc44ceSjose borrego param->value_size_total = NDR_NEW(mxa, DWORD); 729*89dc44ceSjose borrego 730*89dc44ceSjose borrego if (param->value == NULL || param->type == NULL || 731*89dc44ceSjose borrego param->value_size == NULL || param->value_size_total == NULL) { 732*89dc44ceSjose borrego param->status = ERROR_CANTREAD; 733*89dc44ceSjose borrego return (NDR_DRC_OK); 734*89dc44ceSjose borrego } 735*89dc44ceSjose borrego 736*89dc44ceSjose borrego bzero(param->value, msize); 737*89dc44ceSjose borrego pv = param->value; 738*89dc44ceSjose borrego pv->vc_first_is = 0; 739*89dc44ceSjose borrego pv->vc_length_is = slen; 740*89dc44ceSjose borrego /*LINTED E_BAD_PTR_CAST_ALIGN*/ 741*89dc44ceSjose borrego (void) ndr_mbstowcs(NULL, (mts_wchar_t *)pv->value, value, slen); 742*89dc44ceSjose borrego 743*89dc44ceSjose borrego *param->type = 1; 744*89dc44ceSjose borrego *param->value_size = slen; 745*89dc44ceSjose borrego *param->value_size_total = slen; 746*89dc44ceSjose borrego 747*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 748*89dc44ceSjose borrego return (NDR_DRC_OK); 749*89dc44ceSjose borrego } 750*89dc44ceSjose borrego 751*89dc44ceSjose borrego /* 752*89dc44ceSjose borrego * Lookup a name in the registry and return the associated value. 753*89dc44ceSjose borrego * Our registry is a case-insensitive, name-value pair table. 754*89dc44ceSjose borrego * 755*89dc44ceSjose borrego * Windows ProductType: WinNT, ServerNT, LanmanNT. 756*89dc44ceSjose borrego * Windows NT4.0 workstation: WinNT 757*89dc44ceSjose borrego * Windows NT4.0 server: ServerNT 758*89dc44ceSjose borrego * 759*89dc44ceSjose borrego * If LanmanNT is used here, Windows 2000 sends LsarQueryInfoPolicy 760*89dc44ceSjose borrego * with info level 6, which we don't support. If we use ServerNT 761*89dc44ceSjose borrego * (as reported by NT4.0 Server) Windows 2000 send requests for 762*89dc44ceSjose borrego * levels 3 and 5, which are support. 763*89dc44ceSjose borrego * 764*89dc44ceSjose borrego * On success, returns a pointer to the value. Otherwise returns 765*89dc44ceSjose borrego * a null pointer. 766*89dc44ceSjose borrego */ 767*89dc44ceSjose borrego static char * 768*89dc44ceSjose borrego winreg_lookup_value(const char *name) 769*89dc44ceSjose borrego { 770*89dc44ceSjose borrego static struct registry { 771*89dc44ceSjose borrego char *name; 772*89dc44ceSjose borrego char *value; 773*89dc44ceSjose borrego } registry[] = { 774*89dc44ceSjose borrego { "ProductType", "ServerNT" }, 775*89dc44ceSjose borrego { "Sources", NULL } /* product name */ 776*89dc44ceSjose borrego }; 777*89dc44ceSjose borrego 778*89dc44ceSjose borrego int i; 779*89dc44ceSjose borrego 780*89dc44ceSjose borrego for (i = 0; i < sizeof (registry)/sizeof (registry[0]); ++i) { 781*89dc44ceSjose borrego if (strcasecmp(registry[i].name, name) == 0) { 782*89dc44ceSjose borrego if (registry[i].value == NULL) 783*89dc44ceSjose borrego return (winreg_sysname); 784*89dc44ceSjose borrego else 785*89dc44ceSjose borrego return (registry[i].value); 786*89dc44ceSjose borrego } 787*89dc44ceSjose borrego } 788*89dc44ceSjose borrego 789*89dc44ceSjose borrego return (NULL); 790*89dc44ceSjose borrego } 791*89dc44ceSjose borrego 792*89dc44ceSjose borrego /* 793*89dc44ceSjose borrego * winreg_lookup_eventlog_registry 794*89dc44ceSjose borrego * 795*89dc44ceSjose borrego * Return the subkey of the specified EventLog key. Decoding of 796*89dc44ceSjose borrego * class paramater not yet supported. 797*89dc44ceSjose borrego */ 798*89dc44ceSjose borrego /*ARGSUSED*/ 799*89dc44ceSjose borrego static char * 800*89dc44ceSjose borrego winreg_lookup_eventlog_registry(char *name, char *class) 801*89dc44ceSjose borrego { 802*89dc44ceSjose borrego if (name == NULL) 803*89dc44ceSjose borrego return (winreg_subkey_get_relative_name(WINREG_LOGR_SYSTEMKEY)); 804*89dc44ceSjose borrego 805*89dc44ceSjose borrego return (winreg_subkey_get_relative_name(name)); 806*89dc44ceSjose borrego } 807*89dc44ceSjose borrego 808*89dc44ceSjose borrego /* 809*89dc44ceSjose borrego * winreg_s_SetKeySec 810*89dc44ceSjose borrego */ 811*89dc44ceSjose borrego /*ARGSUSED*/ 812*89dc44ceSjose borrego static int 813*89dc44ceSjose borrego winreg_s_SetKeySec(void *arg, ndr_xa_t *mxa) 814*89dc44ceSjose borrego { 815*89dc44ceSjose borrego struct winreg_SetKeySec *param = arg; 816*89dc44ceSjose borrego 817*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 818*89dc44ceSjose borrego return (NDR_DRC_OK); 819*89dc44ceSjose borrego } 820*89dc44ceSjose borrego 821*89dc44ceSjose borrego /* 822*89dc44ceSjose borrego * winreg_s_CreateValue 823*89dc44ceSjose borrego */ 824*89dc44ceSjose borrego /*ARGSUSED*/ 825*89dc44ceSjose borrego static int 826*89dc44ceSjose borrego winreg_s_CreateValue(void *arg, ndr_xa_t *mxa) 827*89dc44ceSjose borrego { 828*89dc44ceSjose borrego struct winreg_CreateValue *param = arg; 829*89dc44ceSjose borrego 830*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 831*89dc44ceSjose borrego return (NDR_DRC_OK); 832*89dc44ceSjose borrego } 833*89dc44ceSjose borrego 834*89dc44ceSjose borrego /* 835*89dc44ceSjose borrego * winreg_s_Shutdown 836*89dc44ceSjose borrego * 837*89dc44ceSjose borrego * Attempt to shutdown or reboot the system: access denied. 838*89dc44ceSjose borrego */ 839*89dc44ceSjose borrego /*ARGSUSED*/ 840*89dc44ceSjose borrego static int 841*89dc44ceSjose borrego winreg_s_Shutdown(void *arg, ndr_xa_t *mxa) 842*89dc44ceSjose borrego { 843*89dc44ceSjose borrego struct winreg_Shutdown *param = arg; 844*89dc44ceSjose borrego 845*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 846*89dc44ceSjose borrego return (NDR_DRC_OK); 847*89dc44ceSjose borrego } 848*89dc44ceSjose borrego 849*89dc44ceSjose borrego /* 850*89dc44ceSjose borrego * winreg_s_AbortShutdown 851*89dc44ceSjose borrego * 852*89dc44ceSjose borrego * Abort a shutdown request. 853*89dc44ceSjose borrego */ 854*89dc44ceSjose borrego static int 855*89dc44ceSjose borrego winreg_s_AbortShutdown(void *arg, ndr_xa_t *mxa) 856*89dc44ceSjose borrego { 857*89dc44ceSjose borrego struct winreg_AbortShutdown *param = arg; 858*89dc44ceSjose borrego 859*89dc44ceSjose borrego if (ndr_is_admin(mxa)) 860*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 861*89dc44ceSjose borrego else 862*89dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED; 863*89dc44ceSjose borrego 864*89dc44ceSjose borrego return (NDR_DRC_OK); 865*89dc44ceSjose borrego } 866*89dc44ceSjose borrego 867*89dc44ceSjose borrego /* 868*89dc44ceSjose borrego * winreg_s_GetVersion 869*89dc44ceSjose borrego * 870*89dc44ceSjose borrego * Return the windows registry version. The current version is 5. 871*89dc44ceSjose borrego * This call is usually made prior to enumerating or querying registry 872*89dc44ceSjose borrego * keys or values. 873*89dc44ceSjose borrego */ 874*89dc44ceSjose borrego /*ARGSUSED*/ 875*89dc44ceSjose borrego static int 876*89dc44ceSjose borrego winreg_s_GetVersion(void *arg, ndr_xa_t *mxa) 877*89dc44ceSjose borrego { 878*89dc44ceSjose borrego struct winreg_GetVersion *param = arg; 879*89dc44ceSjose borrego 880*89dc44ceSjose borrego param->version = 5; 881*89dc44ceSjose borrego param->status = ERROR_SUCCESS; 882*89dc44ceSjose borrego return (NDR_DRC_OK); 883*89dc44ceSjose borrego } 884