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