18474SJose.Borrego@Sun.COM /*
28474SJose.Borrego@Sun.COM * CDDL HEADER START
38474SJose.Borrego@Sun.COM *
48474SJose.Borrego@Sun.COM * The contents of this file are subject to the terms of the
58474SJose.Borrego@Sun.COM * Common Development and Distribution License (the "License").
68474SJose.Borrego@Sun.COM * You may not use this file except in compliance with the License.
78474SJose.Borrego@Sun.COM *
88474SJose.Borrego@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98474SJose.Borrego@Sun.COM * or http://www.opensolaris.org/os/licensing.
108474SJose.Borrego@Sun.COM * See the License for the specific language governing permissions
118474SJose.Borrego@Sun.COM * and limitations under the License.
128474SJose.Borrego@Sun.COM *
138474SJose.Borrego@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
148474SJose.Borrego@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158474SJose.Borrego@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
168474SJose.Borrego@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
178474SJose.Borrego@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
188474SJose.Borrego@Sun.COM *
198474SJose.Borrego@Sun.COM * CDDL HEADER END
208474SJose.Borrego@Sun.COM */
21*12508Samw@Sun.COM
228474SJose.Borrego@Sun.COM /*
23*12508Samw@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
248474SJose.Borrego@Sun.COM */
258474SJose.Borrego@Sun.COM
268474SJose.Borrego@Sun.COM /*
278474SJose.Borrego@Sun.COM * Windows Registry RPC (WINREG) server-side interface.
288474SJose.Borrego@Sun.COM *
298670SJose.Borrego@Sun.COM * The registry is a database with a hierarchical structure similar to
308670SJose.Borrego@Sun.COM * a file system, with keys in place of directories and values in place
318670SJose.Borrego@Sun.COM * of files. The top level keys are known as root keys and each key can
328670SJose.Borrego@Sun.COM * contain subkeys and values. As with directories and sub-directories,
338670SJose.Borrego@Sun.COM * the terms key and subkey are used interchangeably. Values, analogous
348670SJose.Borrego@Sun.COM * to files, contain data.
358474SJose.Borrego@Sun.COM *
368670SJose.Borrego@Sun.COM * A specific subkey can be identifies by its fully qualified name (FQN),
378670SJose.Borrego@Sun.COM * which is analogous to a file system path. In the registry, the key
388670SJose.Borrego@Sun.COM * separator is the '\' character, which is reserved and cannot appear
398670SJose.Borrego@Sun.COM * in key or value names. Registry names are case-insensitive.
408670SJose.Borrego@Sun.COM *
418670SJose.Borrego@Sun.COM * For example: HKEY_LOCAL_MACHINE\System\CurrentControlSet
428670SJose.Borrego@Sun.COM *
439914Samw@Sun.COM * The HKEY_LOCAL_MACHINE root key contains a subkey called System, and
448670SJose.Borrego@Sun.COM * System contains a subkey called CurrentControlSet.
458670SJose.Borrego@Sun.COM *
468670SJose.Borrego@Sun.COM * The WINREG RPC interface returns Win32 error codes.
478474SJose.Borrego@Sun.COM */
488474SJose.Borrego@Sun.COM
498474SJose.Borrego@Sun.COM #include <sys/utsname.h>
508474SJose.Borrego@Sun.COM #include <strings.h>
518474SJose.Borrego@Sun.COM
528474SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h>
538474SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h>
548474SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h>
558474SJose.Borrego@Sun.COM #include <smbsrv/ndl/winreg.ndl>
568474SJose.Borrego@Sun.COM
578474SJose.Borrego@Sun.COM /*
588474SJose.Borrego@Sun.COM * List of supported registry keys (case-insensitive).
598474SJose.Borrego@Sun.COM */
608474SJose.Borrego@Sun.COM static char *winreg_keys[] = {
619914Samw@Sun.COM "HKLM",
629914Samw@Sun.COM "HKU",
639914Samw@Sun.COM "HKLM\\SOFTWARE",
649914Samw@Sun.COM "HKLM\\SYSTEM",
659914Samw@Sun.COM "System",
669914Samw@Sun.COM "CurrentControlSet",
6711963SAfshin.Ardakani@Sun.COM "SunOS",
6811963SAfshin.Ardakani@Sun.COM "Solaris",
698474SJose.Borrego@Sun.COM "System\\CurrentControlSet\\Services\\Eventlog",
708474SJose.Borrego@Sun.COM "System\\CurrentControlSet\\Control\\ProductOptions",
719914Samw@Sun.COM "SOFTWARE",
728474SJose.Borrego@Sun.COM "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
738474SJose.Borrego@Sun.COM };
748474SJose.Borrego@Sun.COM
75*12508Samw@Sun.COM static char *winreg_eventlog = "System\\CurrentControlSet\\Services\\Eventlog";
76*12508Samw@Sun.COM
77*12508Samw@Sun.COM static char *winreg_log[] = {
78*12508Samw@Sun.COM "Application",
79*12508Samw@Sun.COM "Security",
80*12508Samw@Sun.COM "System",
81*12508Samw@Sun.COM "smbd",
82*12508Samw@Sun.COM "smbrdr"
83*12508Samw@Sun.COM };
84*12508Samw@Sun.COM
858474SJose.Borrego@Sun.COM typedef struct winreg_subkey {
868474SJose.Borrego@Sun.COM list_node_t sk_lnd;
878474SJose.Borrego@Sun.COM ndr_hdid_t sk_handle;
888474SJose.Borrego@Sun.COM char sk_name[MAXPATHLEN];
898474SJose.Borrego@Sun.COM boolean_t sk_predefined;
908474SJose.Borrego@Sun.COM } winreg_subkey_t;
918474SJose.Borrego@Sun.COM
928474SJose.Borrego@Sun.COM typedef struct winreg_keylist {
938474SJose.Borrego@Sun.COM list_t kl_list;
948474SJose.Borrego@Sun.COM int kl_count;
958474SJose.Borrego@Sun.COM } winreg_keylist_t;
968474SJose.Borrego@Sun.COM
978474SJose.Borrego@Sun.COM static winreg_keylist_t winreg_keylist;
9811963SAfshin.Ardakani@Sun.COM static mutex_t winreg_mutex;
998474SJose.Borrego@Sun.COM
100*12508Samw@Sun.COM static void winreg_add_predefined(const char *);
10111963SAfshin.Ardakani@Sun.COM static ndr_hdid_t *winreg_alloc_id(ndr_xa_t *, const char *);
10211963SAfshin.Ardakani@Sun.COM static void winreg_dealloc_id(ndr_xa_t *, ndr_hdid_t *);
1038474SJose.Borrego@Sun.COM static boolean_t winreg_key_has_subkey(const char *);
1048670SJose.Borrego@Sun.COM static char *winreg_enum_subkey(ndr_xa_t *, const char *, uint32_t);
1058474SJose.Borrego@Sun.COM static char *winreg_lookup_value(const char *);
10611447Samw@Sun.COM static uint32_t winreg_sd_format(smb_sd_t *);
10711447Samw@Sun.COM uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *);
1088474SJose.Borrego@Sun.COM
1098670SJose.Borrego@Sun.COM static int winreg_s_OpenHKCR(void *, ndr_xa_t *);
1108670SJose.Borrego@Sun.COM static int winreg_s_OpenHKCU(void *, ndr_xa_t *);
1118474SJose.Borrego@Sun.COM static int winreg_s_OpenHKLM(void *, ndr_xa_t *);
1128670SJose.Borrego@Sun.COM static int winreg_s_OpenHKPD(void *, ndr_xa_t *);
1138670SJose.Borrego@Sun.COM static int winreg_s_OpenHKU(void *, ndr_xa_t *);
1148670SJose.Borrego@Sun.COM static int winreg_s_OpenHKCC(void *, ndr_xa_t *);
1158670SJose.Borrego@Sun.COM static int winreg_s_OpenHKDD(void *, ndr_xa_t *);
1168670SJose.Borrego@Sun.COM static int winreg_s_OpenHKPT(void *, ndr_xa_t *);
1178670SJose.Borrego@Sun.COM static int winreg_s_OpenHKPN(void *, ndr_xa_t *);
1188670SJose.Borrego@Sun.COM static int winreg_s_OpenHK(void *, ndr_xa_t *, const char *);
1198474SJose.Borrego@Sun.COM static int winreg_s_Close(void *, ndr_xa_t *);
1208474SJose.Borrego@Sun.COM static int winreg_s_CreateKey(void *, ndr_xa_t *);
1218474SJose.Borrego@Sun.COM static int winreg_s_DeleteKey(void *, ndr_xa_t *);
1228474SJose.Borrego@Sun.COM static int winreg_s_DeleteValue(void *, ndr_xa_t *);
1238474SJose.Borrego@Sun.COM static int winreg_s_EnumKey(void *, ndr_xa_t *);
1248474SJose.Borrego@Sun.COM static int winreg_s_EnumValue(void *, ndr_xa_t *);
1258474SJose.Borrego@Sun.COM static int winreg_s_FlushKey(void *, ndr_xa_t *);
1268474SJose.Borrego@Sun.COM static int winreg_s_GetKeySec(void *, ndr_xa_t *);
1278474SJose.Borrego@Sun.COM static int winreg_s_NotifyChange(void *, ndr_xa_t *);
1288474SJose.Borrego@Sun.COM static int winreg_s_OpenKey(void *, ndr_xa_t *);
1298474SJose.Borrego@Sun.COM static int winreg_s_QueryKey(void *, ndr_xa_t *);
1308474SJose.Borrego@Sun.COM static int winreg_s_QueryValue(void *, ndr_xa_t *);
1318474SJose.Borrego@Sun.COM static int winreg_s_SetKeySec(void *, ndr_xa_t *);
1328474SJose.Borrego@Sun.COM static int winreg_s_CreateValue(void *, ndr_xa_t *);
1338474SJose.Borrego@Sun.COM static int winreg_s_Shutdown(void *, ndr_xa_t *);
1348474SJose.Borrego@Sun.COM static int winreg_s_AbortShutdown(void *, ndr_xa_t *);
1358474SJose.Borrego@Sun.COM static int winreg_s_GetVersion(void *, ndr_xa_t *);
1368474SJose.Borrego@Sun.COM
1378474SJose.Borrego@Sun.COM static ndr_stub_table_t winreg_stub_table[] = {
1388670SJose.Borrego@Sun.COM { winreg_s_OpenHKCR, WINREG_OPNUM_OpenHKCR },
1398670SJose.Borrego@Sun.COM { winreg_s_OpenHKCU, WINREG_OPNUM_OpenHKCU },
1408474SJose.Borrego@Sun.COM { winreg_s_OpenHKLM, WINREG_OPNUM_OpenHKLM },
1418670SJose.Borrego@Sun.COM { winreg_s_OpenHKPD, WINREG_OPNUM_OpenHKPD },
1428670SJose.Borrego@Sun.COM { winreg_s_OpenHKU, WINREG_OPNUM_OpenHKUsers },
1438474SJose.Borrego@Sun.COM { winreg_s_Close, WINREG_OPNUM_Close },
1448474SJose.Borrego@Sun.COM { winreg_s_CreateKey, WINREG_OPNUM_CreateKey },
1458474SJose.Borrego@Sun.COM { winreg_s_DeleteKey, WINREG_OPNUM_DeleteKey },
1468474SJose.Borrego@Sun.COM { winreg_s_DeleteValue, WINREG_OPNUM_DeleteValue },
1478474SJose.Borrego@Sun.COM { winreg_s_EnumKey, WINREG_OPNUM_EnumKey },
1488474SJose.Borrego@Sun.COM { winreg_s_EnumValue, WINREG_OPNUM_EnumValue },
1498474SJose.Borrego@Sun.COM { winreg_s_FlushKey, WINREG_OPNUM_FlushKey },
1508474SJose.Borrego@Sun.COM { winreg_s_GetKeySec, WINREG_OPNUM_GetKeySec },
1518474SJose.Borrego@Sun.COM { winreg_s_NotifyChange, WINREG_OPNUM_NotifyChange },
1528474SJose.Borrego@Sun.COM { winreg_s_OpenKey, WINREG_OPNUM_OpenKey },
1538474SJose.Borrego@Sun.COM { winreg_s_QueryKey, WINREG_OPNUM_QueryKey },
1548474SJose.Borrego@Sun.COM { winreg_s_QueryValue, WINREG_OPNUM_QueryValue },
1558474SJose.Borrego@Sun.COM { winreg_s_SetKeySec, WINREG_OPNUM_SetKeySec },
1568474SJose.Borrego@Sun.COM { winreg_s_CreateValue, WINREG_OPNUM_CreateValue },
1578474SJose.Borrego@Sun.COM { winreg_s_Shutdown, WINREG_OPNUM_Shutdown },
1588474SJose.Borrego@Sun.COM { winreg_s_AbortShutdown, WINREG_OPNUM_AbortShutdown },
1598474SJose.Borrego@Sun.COM { winreg_s_GetVersion, WINREG_OPNUM_GetVersion },
1608670SJose.Borrego@Sun.COM { winreg_s_OpenHKCC, WINREG_OPNUM_OpenHKCC },
1618670SJose.Borrego@Sun.COM { winreg_s_OpenHKDD, WINREG_OPNUM_OpenHKDD },
1628670SJose.Borrego@Sun.COM { winreg_s_OpenHKPT, WINREG_OPNUM_OpenHKPT },
1638670SJose.Borrego@Sun.COM { winreg_s_OpenHKPN, WINREG_OPNUM_OpenHKPN },
1648474SJose.Borrego@Sun.COM {0}
1658474SJose.Borrego@Sun.COM };
1668474SJose.Borrego@Sun.COM
1678474SJose.Borrego@Sun.COM static ndr_service_t winreg_service = {
1688474SJose.Borrego@Sun.COM "Winreg", /* name */
1698474SJose.Borrego@Sun.COM "Windows Registry", /* desc */
1708474SJose.Borrego@Sun.COM "\\winreg", /* endpoint */
1718474SJose.Borrego@Sun.COM PIPE_WINREG, /* sec_addr_port */
1728474SJose.Borrego@Sun.COM "338cd001-2244-31f1-aaaa-900038001003", 1, /* abstract */
1738474SJose.Borrego@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */
1748474SJose.Borrego@Sun.COM 0, /* no bind_instance_size */
1758474SJose.Borrego@Sun.COM 0, /* no bind_req() */
1768474SJose.Borrego@Sun.COM 0, /* no unbind_and_close() */
1778474SJose.Borrego@Sun.COM 0, /* use generic_call_stub() */
1788474SJose.Borrego@Sun.COM &TYPEINFO(winreg_interface), /* interface ti */
1798474SJose.Borrego@Sun.COM winreg_stub_table /* stub_table */
1808474SJose.Borrego@Sun.COM };
1818474SJose.Borrego@Sun.COM
1828474SJose.Borrego@Sun.COM static char winreg_sysname[SYS_NMLN];
18311963SAfshin.Ardakani@Sun.COM static char winreg_sysver[SMB_VERSTR_LEN];
1848474SJose.Borrego@Sun.COM
1858474SJose.Borrego@Sun.COM /*
1868474SJose.Borrego@Sun.COM * winreg_initialize
1878474SJose.Borrego@Sun.COM *
1888474SJose.Borrego@Sun.COM * Initialize and register the WINREG RPC interface with the RPC runtime
1898474SJose.Borrego@Sun.COM * library. It must be called in order to use either the client side
1908474SJose.Borrego@Sun.COM * or the server side functions.
1918474SJose.Borrego@Sun.COM */
1928474SJose.Borrego@Sun.COM void
winreg_initialize(void)1938474SJose.Borrego@Sun.COM winreg_initialize(void)
1948474SJose.Borrego@Sun.COM {
19511963SAfshin.Ardakani@Sun.COM smb_version_t version;
1968474SJose.Borrego@Sun.COM struct utsname name;
197*12508Samw@Sun.COM char subkey[MAXPATHLEN];
1988474SJose.Borrego@Sun.COM char *sysname;
1998474SJose.Borrego@Sun.COM int i;
2008474SJose.Borrego@Sun.COM
20111963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&winreg_mutex);
20211963SAfshin.Ardakani@Sun.COM
2038474SJose.Borrego@Sun.COM list_create(&winreg_keylist.kl_list, sizeof (winreg_subkey_t),
2048474SJose.Borrego@Sun.COM offsetof(winreg_subkey_t, sk_lnd));
2058474SJose.Borrego@Sun.COM winreg_keylist.kl_count = 0;
2068474SJose.Borrego@Sun.COM
207*12508Samw@Sun.COM for (i = 0; i < sizeof (winreg_keys)/sizeof (winreg_keys[0]); ++i)
208*12508Samw@Sun.COM winreg_add_predefined(winreg_keys[i]);
209*12508Samw@Sun.COM
210*12508Samw@Sun.COM for (i = 0; i < sizeof (winreg_log)/sizeof (winreg_log[0]); ++i) {
211*12508Samw@Sun.COM (void) snprintf(subkey, MAXPATHLEN, "%s", winreg_log[i]);
212*12508Samw@Sun.COM winreg_add_predefined(subkey);
21311963SAfshin.Ardakani@Sun.COM
214*12508Samw@Sun.COM (void) snprintf(subkey, MAXPATHLEN, "%s\\%s",
215*12508Samw@Sun.COM winreg_eventlog, winreg_log[i]);
216*12508Samw@Sun.COM winreg_add_predefined(subkey);
217*12508Samw@Sun.COM
218*12508Samw@Sun.COM (void) snprintf(subkey, MAXPATHLEN, "%s\\%s\\%s",
219*12508Samw@Sun.COM winreg_eventlog, winreg_log[i], winreg_log[i]);
220*12508Samw@Sun.COM winreg_add_predefined(subkey);
2218474SJose.Borrego@Sun.COM }
2228474SJose.Borrego@Sun.COM
22311963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
22411963SAfshin.Ardakani@Sun.COM
2258474SJose.Borrego@Sun.COM if (uname(&name) < 0)
2268474SJose.Borrego@Sun.COM sysname = "Solaris";
2278474SJose.Borrego@Sun.COM else
2288474SJose.Borrego@Sun.COM sysname = name.sysname;
2298474SJose.Borrego@Sun.COM
2308474SJose.Borrego@Sun.COM (void) strlcpy(winreg_sysname, sysname, SYS_NMLN);
23111963SAfshin.Ardakani@Sun.COM
23211963SAfshin.Ardakani@Sun.COM smb_config_get_version(&version);
23311963SAfshin.Ardakani@Sun.COM (void) snprintf(winreg_sysver, SMB_VERSTR_LEN, "%d.%d",
23411963SAfshin.Ardakani@Sun.COM version.sv_major, version.sv_minor);
23511963SAfshin.Ardakani@Sun.COM
2368474SJose.Borrego@Sun.COM (void) ndr_svc_register(&winreg_service);
2378474SJose.Borrego@Sun.COM }
2388474SJose.Borrego@Sun.COM
239*12508Samw@Sun.COM static void
winreg_add_predefined(const char * subkey)240*12508Samw@Sun.COM winreg_add_predefined(const char *subkey)
241*12508Samw@Sun.COM {
242*12508Samw@Sun.COM winreg_subkey_t *key;
243*12508Samw@Sun.COM
244*12508Samw@Sun.COM if ((key = malloc(sizeof (winreg_subkey_t))) != NULL) {
245*12508Samw@Sun.COM bzero(key, sizeof (winreg_subkey_t));
246*12508Samw@Sun.COM (void) strlcpy(key->sk_name, subkey, MAXPATHLEN);
247*12508Samw@Sun.COM key->sk_predefined = B_TRUE;
248*12508Samw@Sun.COM
249*12508Samw@Sun.COM list_insert_tail(&winreg_keylist.kl_list, key);
250*12508Samw@Sun.COM ++winreg_keylist.kl_count;
251*12508Samw@Sun.COM }
252*12508Samw@Sun.COM }
253*12508Samw@Sun.COM
2548670SJose.Borrego@Sun.COM static int
winreg_s_OpenHKCR(void * arg,ndr_xa_t * mxa)2558670SJose.Borrego@Sun.COM winreg_s_OpenHKCR(void *arg, ndr_xa_t *mxa)
2568670SJose.Borrego@Sun.COM {
2578670SJose.Borrego@Sun.COM return (winreg_s_OpenHK(arg, mxa, "HKCR"));
2588670SJose.Borrego@Sun.COM }
2598670SJose.Borrego@Sun.COM
2608474SJose.Borrego@Sun.COM static int
winreg_s_OpenHKCU(void * arg,ndr_xa_t * mxa)2618670SJose.Borrego@Sun.COM winreg_s_OpenHKCU(void *arg, ndr_xa_t *mxa)
2628670SJose.Borrego@Sun.COM {
2638670SJose.Borrego@Sun.COM return (winreg_s_OpenHK(arg, mxa, "HKCU"));
2648670SJose.Borrego@Sun.COM }
2658670SJose.Borrego@Sun.COM
2668670SJose.Borrego@Sun.COM static int
winreg_s_OpenHKLM(void * arg,ndr_xa_t * mxa)2678670SJose.Borrego@Sun.COM winreg_s_OpenHKLM(void *arg, ndr_xa_t *mxa)
2688670SJose.Borrego@Sun.COM {
2698670SJose.Borrego@Sun.COM return (winreg_s_OpenHK(arg, mxa, "HKLM"));
2708670SJose.Borrego@Sun.COM }
2718670SJose.Borrego@Sun.COM
2728670SJose.Borrego@Sun.COM static int
winreg_s_OpenHKPD(void * arg,ndr_xa_t * mxa)2738670SJose.Borrego@Sun.COM winreg_s_OpenHKPD(void *arg, ndr_xa_t *mxa)
2748474SJose.Borrego@Sun.COM {
2758670SJose.Borrego@Sun.COM return (winreg_s_OpenHK(arg, mxa, "HKPD"));
2768670SJose.Borrego@Sun.COM }
2778670SJose.Borrego@Sun.COM
2788670SJose.Borrego@Sun.COM static int
winreg_s_OpenHKU(void * arg,ndr_xa_t * mxa)2798670SJose.Borrego@Sun.COM winreg_s_OpenHKU(void *arg, ndr_xa_t *mxa)
2808670SJose.Borrego@Sun.COM {
2818670SJose.Borrego@Sun.COM return (winreg_s_OpenHK(arg, mxa, "HKU"));
2828670SJose.Borrego@Sun.COM }
2838670SJose.Borrego@Sun.COM
2848670SJose.Borrego@Sun.COM static int
winreg_s_OpenHKCC(void * arg,ndr_xa_t * mxa)2858670SJose.Borrego@Sun.COM winreg_s_OpenHKCC(void *arg, ndr_xa_t *mxa)
2868670SJose.Borrego@Sun.COM {
2878670SJose.Borrego@Sun.COM return (winreg_s_OpenHK(arg, mxa, "HKCC"));
2888670SJose.Borrego@Sun.COM }
2898474SJose.Borrego@Sun.COM
2908670SJose.Borrego@Sun.COM static int
winreg_s_OpenHKDD(void * arg,ndr_xa_t * mxa)2918670SJose.Borrego@Sun.COM winreg_s_OpenHKDD(void *arg, ndr_xa_t *mxa)
2928670SJose.Borrego@Sun.COM {
2938670SJose.Borrego@Sun.COM return (winreg_s_OpenHK(arg, mxa, "HKDD"));
2948670SJose.Borrego@Sun.COM }
2958474SJose.Borrego@Sun.COM
2968670SJose.Borrego@Sun.COM static int
winreg_s_OpenHKPT(void * arg,ndr_xa_t * mxa)2978670SJose.Borrego@Sun.COM winreg_s_OpenHKPT(void *arg, ndr_xa_t *mxa)
2988670SJose.Borrego@Sun.COM {
2998670SJose.Borrego@Sun.COM return (winreg_s_OpenHK(arg, mxa, "HKPT"));
3008670SJose.Borrego@Sun.COM }
3018670SJose.Borrego@Sun.COM
3028670SJose.Borrego@Sun.COM static int
winreg_s_OpenHKPN(void * arg,ndr_xa_t * mxa)3038670SJose.Borrego@Sun.COM winreg_s_OpenHKPN(void *arg, ndr_xa_t *mxa)
3048670SJose.Borrego@Sun.COM {
3058670SJose.Borrego@Sun.COM return (winreg_s_OpenHK(arg, mxa, "HKPN"));
3068474SJose.Borrego@Sun.COM }
3078474SJose.Borrego@Sun.COM
3088474SJose.Borrego@Sun.COM /*
3098670SJose.Borrego@Sun.COM * winreg_s_OpenHK
3108474SJose.Borrego@Sun.COM *
3118670SJose.Borrego@Sun.COM * Common code to open root HKEYs.
3128474SJose.Borrego@Sun.COM */
3138474SJose.Borrego@Sun.COM static int
winreg_s_OpenHK(void * arg,ndr_xa_t * mxa,const char * hkey)3148670SJose.Borrego@Sun.COM winreg_s_OpenHK(void *arg, ndr_xa_t *mxa, const char *hkey)
3158474SJose.Borrego@Sun.COM {
3168670SJose.Borrego@Sun.COM struct winreg_OpenHKCR *param = arg;
3178474SJose.Borrego@Sun.COM ndr_hdid_t *id;
3188474SJose.Borrego@Sun.COM
31911963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&winreg_mutex);
3208474SJose.Borrego@Sun.COM
32111963SAfshin.Ardakani@Sun.COM if ((id = winreg_alloc_id(mxa, hkey)) == NULL) {
3228474SJose.Borrego@Sun.COM bzero(¶m->handle, sizeof (winreg_handle_t));
3238474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED;
3248474SJose.Borrego@Sun.COM } else {
3258474SJose.Borrego@Sun.COM bcopy(id, ¶m->handle, sizeof (winreg_handle_t));
3268474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS;
3278474SJose.Borrego@Sun.COM }
3288474SJose.Borrego@Sun.COM
32911963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
3308474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
3318474SJose.Borrego@Sun.COM }
3328474SJose.Borrego@Sun.COM
3338474SJose.Borrego@Sun.COM /*
3348474SJose.Borrego@Sun.COM * winreg_s_Close
3358474SJose.Borrego@Sun.COM *
3368474SJose.Borrego@Sun.COM * This is a request to close the WINREG interface specified by the
3378474SJose.Borrego@Sun.COM * handle. We don't track handles (yet), so just zero out the handle
3388474SJose.Borrego@Sun.COM * and return NDR_DRC_OK. Setting the handle to zero appears to be
3398474SJose.Borrego@Sun.COM * standard behaviour.
3408474SJose.Borrego@Sun.COM */
3418474SJose.Borrego@Sun.COM static int
winreg_s_Close(void * arg,ndr_xa_t * mxa)3428474SJose.Borrego@Sun.COM winreg_s_Close(void *arg, ndr_xa_t *mxa)
3438474SJose.Borrego@Sun.COM {
3448474SJose.Borrego@Sun.COM struct winreg_Close *param = arg;
3458474SJose.Borrego@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
34611963SAfshin.Ardakani@Sun.COM
34711963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&winreg_mutex);
34811963SAfshin.Ardakani@Sun.COM winreg_dealloc_id(mxa, id);
34911963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
35011963SAfshin.Ardakani@Sun.COM
35111963SAfshin.Ardakani@Sun.COM bzero(¶m->result_handle, sizeof (winreg_handle_t));
35211963SAfshin.Ardakani@Sun.COM param->status = ERROR_SUCCESS;
35311963SAfshin.Ardakani@Sun.COM return (NDR_DRC_OK);
35411963SAfshin.Ardakani@Sun.COM }
35511963SAfshin.Ardakani@Sun.COM
35611963SAfshin.Ardakani@Sun.COM static ndr_hdid_t *
winreg_alloc_id(ndr_xa_t * mxa,const char * key)35711963SAfshin.Ardakani@Sun.COM winreg_alloc_id(ndr_xa_t *mxa, const char *key)
35811963SAfshin.Ardakani@Sun.COM {
35911963SAfshin.Ardakani@Sun.COM ndr_handle_t *hd;
36011963SAfshin.Ardakani@Sun.COM ndr_hdid_t *id;
36111963SAfshin.Ardakani@Sun.COM char *data;
36211963SAfshin.Ardakani@Sun.COM
36311963SAfshin.Ardakani@Sun.COM if ((data = strdup(key)) == NULL)
36411963SAfshin.Ardakani@Sun.COM return (NULL);
36511963SAfshin.Ardakani@Sun.COM
36611963SAfshin.Ardakani@Sun.COM if ((id = ndr_hdalloc(mxa, data)) == NULL) {
36711963SAfshin.Ardakani@Sun.COM free(data);
36811963SAfshin.Ardakani@Sun.COM return (NULL);
36911963SAfshin.Ardakani@Sun.COM }
37011963SAfshin.Ardakani@Sun.COM
37111963SAfshin.Ardakani@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL)
37211963SAfshin.Ardakani@Sun.COM hd->nh_data_free = free;
37311963SAfshin.Ardakani@Sun.COM
37411963SAfshin.Ardakani@Sun.COM return (id);
37511963SAfshin.Ardakani@Sun.COM }
37611963SAfshin.Ardakani@Sun.COM
37711963SAfshin.Ardakani@Sun.COM static void
winreg_dealloc_id(ndr_xa_t * mxa,ndr_hdid_t * id)37811963SAfshin.Ardakani@Sun.COM winreg_dealloc_id(ndr_xa_t *mxa, ndr_hdid_t *id)
37911963SAfshin.Ardakani@Sun.COM {
3808670SJose.Borrego@Sun.COM ndr_handle_t *hd;
3818670SJose.Borrego@Sun.COM
3828670SJose.Borrego@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
3838670SJose.Borrego@Sun.COM free(hd->nh_data);
3848670SJose.Borrego@Sun.COM hd->nh_data = NULL;
3858670SJose.Borrego@Sun.COM }
3868474SJose.Borrego@Sun.COM
3878474SJose.Borrego@Sun.COM ndr_hdfree(mxa, id);
3888474SJose.Borrego@Sun.COM }
3898474SJose.Borrego@Sun.COM
3908474SJose.Borrego@Sun.COM /*
3918474SJose.Borrego@Sun.COM * winreg_s_CreateKey
3928474SJose.Borrego@Sun.COM */
3938474SJose.Borrego@Sun.COM static int
winreg_s_CreateKey(void * arg,ndr_xa_t * mxa)3948474SJose.Borrego@Sun.COM winreg_s_CreateKey(void *arg, ndr_xa_t *mxa)
3958474SJose.Borrego@Sun.COM {
3968474SJose.Borrego@Sun.COM struct winreg_CreateKey *param = arg;
3978474SJose.Borrego@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
3988474SJose.Borrego@Sun.COM ndr_handle_t *hd;
3998474SJose.Borrego@Sun.COM winreg_subkey_t *key;
4008474SJose.Borrego@Sun.COM char *subkey;
4018474SJose.Borrego@Sun.COM DWORD *action;
4028474SJose.Borrego@Sun.COM
4038474SJose.Borrego@Sun.COM subkey = (char *)param->subkey.str;
4048474SJose.Borrego@Sun.COM
4058474SJose.Borrego@Sun.COM if (!ndr_is_admin(mxa) || (subkey == NULL)) {
4068474SJose.Borrego@Sun.COM bzero(param, sizeof (struct winreg_CreateKey));
4078474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED;
4088474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
4098474SJose.Borrego@Sun.COM }
4108474SJose.Borrego@Sun.COM
41111963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&winreg_mutex);
41211963SAfshin.Ardakani@Sun.COM
4138474SJose.Borrego@Sun.COM hd = ndr_hdlookup(mxa, id);
4148474SJose.Borrego@Sun.COM if (hd == NULL) {
41511963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
4168474SJose.Borrego@Sun.COM bzero(param, sizeof (struct winreg_CreateKey));
4178474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_HANDLE;
4188474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
4198474SJose.Borrego@Sun.COM }
4208474SJose.Borrego@Sun.COM
4218474SJose.Borrego@Sun.COM if ((action = NDR_NEW(mxa, DWORD)) == NULL) {
42211963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
4238474SJose.Borrego@Sun.COM bzero(param, sizeof (struct winreg_CreateKey));
4248474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY;
4258474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
4268474SJose.Borrego@Sun.COM }
4278474SJose.Borrego@Sun.COM
4288474SJose.Borrego@Sun.COM if (list_is_empty(&winreg_keylist.kl_list))
4298474SJose.Borrego@Sun.COM goto new_key;
4308474SJose.Borrego@Sun.COM
4318474SJose.Borrego@Sun.COM /*
4328474SJose.Borrego@Sun.COM * Check for an existing key.
4338474SJose.Borrego@Sun.COM */
4348474SJose.Borrego@Sun.COM key = list_head(&winreg_keylist.kl_list);
4358474SJose.Borrego@Sun.COM do {
4368474SJose.Borrego@Sun.COM if (strcasecmp(subkey, key->sk_name) == 0) {
4378474SJose.Borrego@Sun.COM bcopy(&key->sk_handle, ¶m->result_handle,
4388474SJose.Borrego@Sun.COM sizeof (winreg_handle_t));
43911963SAfshin.Ardakani@Sun.COM
44011963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
4418474SJose.Borrego@Sun.COM *action = WINREG_ACTION_EXISTING_KEY;
4428474SJose.Borrego@Sun.COM param->action = action;
4438474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS;
4448474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
4458474SJose.Borrego@Sun.COM }
4468474SJose.Borrego@Sun.COM } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL);
4478474SJose.Borrego@Sun.COM
4488474SJose.Borrego@Sun.COM new_key:
4498474SJose.Borrego@Sun.COM /*
4508474SJose.Borrego@Sun.COM * Create a new key.
4518474SJose.Borrego@Sun.COM */
45211963SAfshin.Ardakani@Sun.COM if ((id = winreg_alloc_id(mxa, subkey)) == NULL)
45311963SAfshin.Ardakani@Sun.COM goto no_memory;
4548670SJose.Borrego@Sun.COM
45511963SAfshin.Ardakani@Sun.COM if ((key = malloc(sizeof (winreg_subkey_t))) == NULL) {
45611963SAfshin.Ardakani@Sun.COM winreg_dealloc_id(mxa, id);
45711963SAfshin.Ardakani@Sun.COM goto no_memory;
4588474SJose.Borrego@Sun.COM }
4598474SJose.Borrego@Sun.COM
4608474SJose.Borrego@Sun.COM bcopy(id, &key->sk_handle, sizeof (ndr_hdid_t));
4618474SJose.Borrego@Sun.COM (void) strlcpy(key->sk_name, subkey, MAXPATHLEN);
4628474SJose.Borrego@Sun.COM key->sk_predefined = B_FALSE;
4638474SJose.Borrego@Sun.COM list_insert_tail(&winreg_keylist.kl_list, key);
4648474SJose.Borrego@Sun.COM ++winreg_keylist.kl_count;
4658474SJose.Borrego@Sun.COM
4668474SJose.Borrego@Sun.COM bcopy(id, ¶m->result_handle, sizeof (winreg_handle_t));
46711963SAfshin.Ardakani@Sun.COM
46811963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
4698474SJose.Borrego@Sun.COM *action = WINREG_ACTION_NEW_KEY;
4708474SJose.Borrego@Sun.COM param->action = action;
4718474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS;
4728474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
47311963SAfshin.Ardakani@Sun.COM
47411963SAfshin.Ardakani@Sun.COM no_memory:
47511963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
47611963SAfshin.Ardakani@Sun.COM bzero(param, sizeof (struct winreg_CreateKey));
47711963SAfshin.Ardakani@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY;
47811963SAfshin.Ardakani@Sun.COM return (NDR_DRC_OK);
4798474SJose.Borrego@Sun.COM }
4808474SJose.Borrego@Sun.COM
4818474SJose.Borrego@Sun.COM /*
4828474SJose.Borrego@Sun.COM * winreg_s_DeleteKey
4838474SJose.Borrego@Sun.COM */
4848474SJose.Borrego@Sun.COM static int
winreg_s_DeleteKey(void * arg,ndr_xa_t * mxa)4858474SJose.Borrego@Sun.COM winreg_s_DeleteKey(void *arg, ndr_xa_t *mxa)
4868474SJose.Borrego@Sun.COM {
4878474SJose.Borrego@Sun.COM struct winreg_DeleteKey *param = arg;
4888474SJose.Borrego@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
4898474SJose.Borrego@Sun.COM winreg_subkey_t *key;
4908474SJose.Borrego@Sun.COM char *subkey;
4918474SJose.Borrego@Sun.COM
4928474SJose.Borrego@Sun.COM subkey = (char *)param->subkey.str;
4938474SJose.Borrego@Sun.COM
4948474SJose.Borrego@Sun.COM if (!ndr_is_admin(mxa) || (subkey == NULL)) {
4958474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED;
4968474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
4978474SJose.Borrego@Sun.COM }
4988474SJose.Borrego@Sun.COM
49911963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&winreg_mutex);
50011963SAfshin.Ardakani@Sun.COM
5018474SJose.Borrego@Sun.COM if ((ndr_hdlookup(mxa, id) == NULL) ||
5028474SJose.Borrego@Sun.COM list_is_empty(&winreg_keylist.kl_list) ||
5038474SJose.Borrego@Sun.COM winreg_key_has_subkey(subkey)) {
50411963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
5058474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED;
5068474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
5078474SJose.Borrego@Sun.COM }
5088474SJose.Borrego@Sun.COM
5098474SJose.Borrego@Sun.COM key = list_head(&winreg_keylist.kl_list);
5108474SJose.Borrego@Sun.COM do {
5118474SJose.Borrego@Sun.COM if (strcasecmp(subkey, key->sk_name) == 0) {
5128474SJose.Borrego@Sun.COM if (key->sk_predefined == B_TRUE) {
5138474SJose.Borrego@Sun.COM /* Predefined keys cannot be deleted */
5148474SJose.Borrego@Sun.COM break;
5158474SJose.Borrego@Sun.COM }
5168474SJose.Borrego@Sun.COM
5178474SJose.Borrego@Sun.COM list_remove(&winreg_keylist.kl_list, key);
5188474SJose.Borrego@Sun.COM --winreg_keylist.kl_count;
51911963SAfshin.Ardakani@Sun.COM winreg_dealloc_id(mxa, &key->sk_handle);
52011963SAfshin.Ardakani@Sun.COM free(key);
5218670SJose.Borrego@Sun.COM
52211963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
5238474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS;
5248474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
5258474SJose.Borrego@Sun.COM }
5268474SJose.Borrego@Sun.COM } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL);
5278474SJose.Borrego@Sun.COM
52811963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
5298474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED;
5308474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
5318474SJose.Borrego@Sun.COM }
5328474SJose.Borrego@Sun.COM
53311963SAfshin.Ardakani@Sun.COM /*
53411963SAfshin.Ardakani@Sun.COM * Call with the winreg_mutex held.
53511963SAfshin.Ardakani@Sun.COM */
5368474SJose.Borrego@Sun.COM static boolean_t
winreg_key_has_subkey(const char * subkey)5378474SJose.Borrego@Sun.COM winreg_key_has_subkey(const char *subkey)
5388474SJose.Borrego@Sun.COM {
5398474SJose.Borrego@Sun.COM winreg_subkey_t *key;
5408474SJose.Borrego@Sun.COM int keylen;
5418474SJose.Borrego@Sun.COM
5428474SJose.Borrego@Sun.COM if (list_is_empty(&winreg_keylist.kl_list))
5438474SJose.Borrego@Sun.COM return (B_FALSE);
5448474SJose.Borrego@Sun.COM
5458474SJose.Borrego@Sun.COM keylen = strlen(subkey);
5468474SJose.Borrego@Sun.COM
5478474SJose.Borrego@Sun.COM key = list_head(&winreg_keylist.kl_list);
5488474SJose.Borrego@Sun.COM do {
5498474SJose.Borrego@Sun.COM if (strncasecmp(subkey, key->sk_name, keylen) == 0) {
5508474SJose.Borrego@Sun.COM /*
5518474SJose.Borrego@Sun.COM * Potential match. If sk_name is longer than
5528474SJose.Borrego@Sun.COM * subkey, then sk_name is a subkey of our key.
5538474SJose.Borrego@Sun.COM */
5548474SJose.Borrego@Sun.COM if (keylen < strlen(key->sk_name))
5558474SJose.Borrego@Sun.COM return (B_TRUE);
5568474SJose.Borrego@Sun.COM }
5578474SJose.Borrego@Sun.COM } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL);
5588474SJose.Borrego@Sun.COM
5598474SJose.Borrego@Sun.COM return (B_FALSE);
5608474SJose.Borrego@Sun.COM }
5618474SJose.Borrego@Sun.COM
56211963SAfshin.Ardakani@Sun.COM /*
56311963SAfshin.Ardakani@Sun.COM * Call with the winreg_mutex held.
56411963SAfshin.Ardakani@Sun.COM */
5658474SJose.Borrego@Sun.COM static char *
winreg_enum_subkey(ndr_xa_t * mxa,const char * subkey,uint32_t index)5668670SJose.Borrego@Sun.COM winreg_enum_subkey(ndr_xa_t *mxa, const char *subkey, uint32_t index)
5678474SJose.Borrego@Sun.COM {
5688474SJose.Borrego@Sun.COM winreg_subkey_t *key;
5698670SJose.Borrego@Sun.COM char *entry;
5708670SJose.Borrego@Sun.COM char *p;
5718670SJose.Borrego@Sun.COM int subkeylen;
5728670SJose.Borrego@Sun.COM int count = 0;
5738474SJose.Borrego@Sun.COM
5748474SJose.Borrego@Sun.COM if (subkey == NULL)
5758474SJose.Borrego@Sun.COM return (NULL);
5768474SJose.Borrego@Sun.COM
5778474SJose.Borrego@Sun.COM if (list_is_empty(&winreg_keylist.kl_list))
5788474SJose.Borrego@Sun.COM return (NULL);
5798474SJose.Borrego@Sun.COM
5808670SJose.Borrego@Sun.COM subkeylen = strlen(subkey);
5818670SJose.Borrego@Sun.COM
5828670SJose.Borrego@Sun.COM for (key = list_head(&winreg_keylist.kl_list);
5838670SJose.Borrego@Sun.COM key != NULL; key = list_next(&winreg_keylist.kl_list, key)) {
5848670SJose.Borrego@Sun.COM if (strncasecmp(subkey, key->sk_name, subkeylen) == 0) {
5858670SJose.Borrego@Sun.COM p = key->sk_name + subkeylen;
5868670SJose.Borrego@Sun.COM
5878670SJose.Borrego@Sun.COM if ((*p != '\\') || (*p == '\0')) {
5888670SJose.Borrego@Sun.COM /*
5898670SJose.Borrego@Sun.COM * Not the same subkey or an exact match.
5908670SJose.Borrego@Sun.COM * We're looking for children of subkey.
5918670SJose.Borrego@Sun.COM */
5928670SJose.Borrego@Sun.COM continue;
5938670SJose.Borrego@Sun.COM }
5948670SJose.Borrego@Sun.COM
5958670SJose.Borrego@Sun.COM ++p;
5968670SJose.Borrego@Sun.COM
5978670SJose.Borrego@Sun.COM if (count < index) {
5988670SJose.Borrego@Sun.COM ++count;
5998670SJose.Borrego@Sun.COM continue;
6008670SJose.Borrego@Sun.COM }
6018670SJose.Borrego@Sun.COM
6028670SJose.Borrego@Sun.COM if ((entry = NDR_STRDUP(mxa, p)) == NULL)
6038670SJose.Borrego@Sun.COM return (NULL);
6048670SJose.Borrego@Sun.COM
6058670SJose.Borrego@Sun.COM if ((p = strchr(entry, '\\')) != NULL)
6068670SJose.Borrego@Sun.COM *p = '\0';
6078670SJose.Borrego@Sun.COM
6088670SJose.Borrego@Sun.COM return (entry);
6098474SJose.Borrego@Sun.COM }
6108670SJose.Borrego@Sun.COM }
6118474SJose.Borrego@Sun.COM
6128474SJose.Borrego@Sun.COM return (NULL);
6138474SJose.Borrego@Sun.COM }
6148474SJose.Borrego@Sun.COM
6158474SJose.Borrego@Sun.COM /*
6168474SJose.Borrego@Sun.COM * winreg_s_DeleteValue
6178474SJose.Borrego@Sun.COM */
6188474SJose.Borrego@Sun.COM /*ARGSUSED*/
6198474SJose.Borrego@Sun.COM static int
winreg_s_DeleteValue(void * arg,ndr_xa_t * mxa)6208474SJose.Borrego@Sun.COM winreg_s_DeleteValue(void *arg, ndr_xa_t *mxa)
6218474SJose.Borrego@Sun.COM {
6228474SJose.Borrego@Sun.COM struct winreg_DeleteValue *param = arg;
6238474SJose.Borrego@Sun.COM
6248474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED;
6258474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
6268474SJose.Borrego@Sun.COM }
6278474SJose.Borrego@Sun.COM
6288474SJose.Borrego@Sun.COM /*
6298474SJose.Borrego@Sun.COM * winreg_s_EnumKey
6308474SJose.Borrego@Sun.COM */
6318474SJose.Borrego@Sun.COM static int
winreg_s_EnumKey(void * arg,ndr_xa_t * mxa)6328474SJose.Borrego@Sun.COM winreg_s_EnumKey(void *arg, ndr_xa_t *mxa)
6338474SJose.Borrego@Sun.COM {
6348474SJose.Borrego@Sun.COM struct winreg_EnumKey *param = arg;
6358474SJose.Borrego@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
6368670SJose.Borrego@Sun.COM ndr_handle_t *hd;
6378670SJose.Borrego@Sun.COM char *subkey;
6388670SJose.Borrego@Sun.COM char *name = NULL;
6398474SJose.Borrego@Sun.COM
64011963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&winreg_mutex);
64111963SAfshin.Ardakani@Sun.COM
6428670SJose.Borrego@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL)
6438670SJose.Borrego@Sun.COM name = hd->nh_data;
6448474SJose.Borrego@Sun.COM
6458670SJose.Borrego@Sun.COM if (hd == NULL || name == NULL) {
64611963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
6478474SJose.Borrego@Sun.COM bzero(param, sizeof (struct winreg_EnumKey));
6488474SJose.Borrego@Sun.COM param->status = ERROR_NO_MORE_ITEMS;
6498474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
6508474SJose.Borrego@Sun.COM }
6518474SJose.Borrego@Sun.COM
6528670SJose.Borrego@Sun.COM subkey = winreg_enum_subkey(mxa, name, param->index);
6538670SJose.Borrego@Sun.COM if (subkey == NULL) {
65411963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
6558474SJose.Borrego@Sun.COM bzero(param, sizeof (struct winreg_EnumKey));
6568670SJose.Borrego@Sun.COM param->status = ERROR_NO_MORE_ITEMS;
6578474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
6588474SJose.Borrego@Sun.COM }
6598474SJose.Borrego@Sun.COM
6608670SJose.Borrego@Sun.COM if (NDR_MSTRING(mxa, subkey, (ndr_mstring_t *)¶m->name_out) == -1) {
66111963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
6628474SJose.Borrego@Sun.COM bzero(param, sizeof (struct winreg_EnumKey));
6638474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY;
6648474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
6658474SJose.Borrego@Sun.COM }
66611963SAfshin.Ardakani@Sun.COM
66711963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
66811963SAfshin.Ardakani@Sun.COM
6698670SJose.Borrego@Sun.COM /*
6708670SJose.Borrego@Sun.COM * This request requires that the length includes the null.
6718670SJose.Borrego@Sun.COM */
6728670SJose.Borrego@Sun.COM param->name_out.length = param->name_out.allosize;
6738474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS;
6748474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
6758474SJose.Borrego@Sun.COM }
6768474SJose.Borrego@Sun.COM
6778474SJose.Borrego@Sun.COM /*
6788474SJose.Borrego@Sun.COM * winreg_s_EnumValue
6798474SJose.Borrego@Sun.COM */
6808474SJose.Borrego@Sun.COM static int
winreg_s_EnumValue(void * arg,ndr_xa_t * mxa)6818474SJose.Borrego@Sun.COM winreg_s_EnumValue(void *arg, ndr_xa_t *mxa)
6828474SJose.Borrego@Sun.COM {
6838474SJose.Borrego@Sun.COM struct winreg_EnumValue *param = arg;
6848474SJose.Borrego@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
6858474SJose.Borrego@Sun.COM
6868474SJose.Borrego@Sun.COM if (ndr_hdlookup(mxa, id) == NULL) {
6878474SJose.Borrego@Sun.COM bzero(param, sizeof (struct winreg_EnumValue));
6888474SJose.Borrego@Sun.COM param->status = ERROR_NO_MORE_ITEMS;
6898474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
6908474SJose.Borrego@Sun.COM }
6918474SJose.Borrego@Sun.COM
6928474SJose.Borrego@Sun.COM bzero(param, sizeof (struct winreg_EnumValue));
6938474SJose.Borrego@Sun.COM param->status = ERROR_NO_MORE_ITEMS;
6948474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
6958474SJose.Borrego@Sun.COM }
6968474SJose.Borrego@Sun.COM
6978474SJose.Borrego@Sun.COM /*
6988474SJose.Borrego@Sun.COM * winreg_s_FlushKey
6998474SJose.Borrego@Sun.COM *
7008474SJose.Borrego@Sun.COM * Flush the attributes associated with the specified open key to disk.
7018474SJose.Borrego@Sun.COM */
7028474SJose.Borrego@Sun.COM static int
winreg_s_FlushKey(void * arg,ndr_xa_t * mxa)7038474SJose.Borrego@Sun.COM winreg_s_FlushKey(void *arg, ndr_xa_t *mxa)
7048474SJose.Borrego@Sun.COM {
7058474SJose.Borrego@Sun.COM struct winreg_FlushKey *param = arg;
7068474SJose.Borrego@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
7078474SJose.Borrego@Sun.COM
7088474SJose.Borrego@Sun.COM if (ndr_hdlookup(mxa, id) == NULL)
7098474SJose.Borrego@Sun.COM param->status = ERROR_INVALID_HANDLE;
7108474SJose.Borrego@Sun.COM else
7118474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS;
7128474SJose.Borrego@Sun.COM
7138474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
7148474SJose.Borrego@Sun.COM }
7158474SJose.Borrego@Sun.COM
7168474SJose.Borrego@Sun.COM /*
7178474SJose.Borrego@Sun.COM * winreg_s_GetKeySec
7188474SJose.Borrego@Sun.COM */
7198474SJose.Borrego@Sun.COM static int
winreg_s_GetKeySec(void * arg,ndr_xa_t * mxa)7208474SJose.Borrego@Sun.COM winreg_s_GetKeySec(void *arg, ndr_xa_t *mxa)
7218474SJose.Borrego@Sun.COM {
72211633SJoyce.McIntosh@Sun.COM static struct winreg_secdesc error_sd;
72311633SJoyce.McIntosh@Sun.COM struct winreg_GetKeySec *param = arg;
72411633SJoyce.McIntosh@Sun.COM struct winreg_value *sd_buf;
72511633SJoyce.McIntosh@Sun.COM smb_sd_t sd;
72611633SJoyce.McIntosh@Sun.COM uint32_t sd_len;
72711633SJoyce.McIntosh@Sun.COM uint32_t status;
7288474SJose.Borrego@Sun.COM
72911447Samw@Sun.COM bzero(&sd, sizeof (smb_sd_t));
73011447Samw@Sun.COM
73111447Samw@Sun.COM if ((status = winreg_sd_format(&sd)) != ERROR_SUCCESS)
73211447Samw@Sun.COM goto winreg_getkeysec_error;
73311447Samw@Sun.COM
73411447Samw@Sun.COM sd_len = smb_sd_len(&sd, SMB_ALL_SECINFO);
73511633SJoyce.McIntosh@Sun.COM sd_buf = NDR_MALLOC(mxa, sd_len + sizeof (struct winreg_value));
73611447Samw@Sun.COM
73711447Samw@Sun.COM param->sd = NDR_MALLOC(mxa, sizeof (struct winreg_secdesc));
73811633SJoyce.McIntosh@Sun.COM if ((param->sd == NULL) || (sd_buf == NULL)) {
73911447Samw@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY;
74011447Samw@Sun.COM goto winreg_getkeysec_error;
74111447Samw@Sun.COM }
74211447Samw@Sun.COM
74311447Samw@Sun.COM param->sd->sd_len = sd_len;
74411447Samw@Sun.COM param->sd->sd_size = sd_len;
74511447Samw@Sun.COM param->sd->sd_buf = sd_buf;
74611447Samw@Sun.COM
74711447Samw@Sun.COM sd_buf->vc_first_is = 0;
74811447Samw@Sun.COM sd_buf->vc_length_is = sd_len;
74911447Samw@Sun.COM param->status = srvsvc_sd_set_relative(&sd, sd_buf->value);
75011447Samw@Sun.COM
75111447Samw@Sun.COM smb_sd_term(&sd);
75211447Samw@Sun.COM return (NDR_DRC_OK);
75311447Samw@Sun.COM
75411447Samw@Sun.COM winreg_getkeysec_error:
75511447Samw@Sun.COM smb_sd_term(&sd);
7568474SJose.Borrego@Sun.COM bzero(param, sizeof (struct winreg_GetKeySec));
75711633SJoyce.McIntosh@Sun.COM param->sd = &error_sd;
75811447Samw@Sun.COM param->status = status;
7598474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
7608474SJose.Borrego@Sun.COM }
7618474SJose.Borrego@Sun.COM
76211447Samw@Sun.COM static uint32_t
winreg_sd_format(smb_sd_t * sd)76311447Samw@Sun.COM winreg_sd_format(smb_sd_t *sd)
76411447Samw@Sun.COM {
76511447Samw@Sun.COM smb_fssd_t fs_sd;
76611447Samw@Sun.COM acl_t *acl;
76711447Samw@Sun.COM uint32_t status = ERROR_SUCCESS;
76811447Samw@Sun.COM
76911447Samw@Sun.COM if (acl_fromtext("owner@:rwxpdDaARWcCos::allow", &acl) != 0)
77011447Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY);
77111447Samw@Sun.COM
77211447Samw@Sun.COM smb_fssd_init(&fs_sd, SMB_ALL_SECINFO, SMB_FSSD_FLAGS_DIR);
77311447Samw@Sun.COM fs_sd.sd_uid = 0;
77411447Samw@Sun.COM fs_sd.sd_gid = 0;
77511447Samw@Sun.COM fs_sd.sd_zdacl = acl;
77611447Samw@Sun.COM fs_sd.sd_zsacl = NULL;
77711447Samw@Sun.COM
77811447Samw@Sun.COM if (smb_sd_fromfs(&fs_sd, sd) != NT_STATUS_SUCCESS)
77911447Samw@Sun.COM status = ERROR_ACCESS_DENIED;
78011447Samw@Sun.COM smb_fssd_term(&fs_sd);
78111447Samw@Sun.COM return (status);
78211447Samw@Sun.COM }
78311447Samw@Sun.COM
7848474SJose.Borrego@Sun.COM /*
7858474SJose.Borrego@Sun.COM * winreg_s_NotifyChange
7868474SJose.Borrego@Sun.COM */
7878474SJose.Borrego@Sun.COM static int
winreg_s_NotifyChange(void * arg,ndr_xa_t * mxa)7888474SJose.Borrego@Sun.COM winreg_s_NotifyChange(void *arg, ndr_xa_t *mxa)
7898474SJose.Borrego@Sun.COM {
7908474SJose.Borrego@Sun.COM struct winreg_NotifyChange *param = arg;
7918474SJose.Borrego@Sun.COM
7928474SJose.Borrego@Sun.COM if (ndr_is_admin(mxa))
7938474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS;
7948474SJose.Borrego@Sun.COM else
7958474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED;
7968474SJose.Borrego@Sun.COM
7978474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
7988474SJose.Borrego@Sun.COM }
7998474SJose.Borrego@Sun.COM
8008474SJose.Borrego@Sun.COM /*
8018474SJose.Borrego@Sun.COM * winreg_s_OpenKey
8028474SJose.Borrego@Sun.COM *
8038474SJose.Borrego@Sun.COM * This is a request to open a windows registry key.
8048474SJose.Borrego@Sun.COM * If we recognize the key, we return a handle.
8058474SJose.Borrego@Sun.COM *
8068474SJose.Borrego@Sun.COM * Returns:
8078474SJose.Borrego@Sun.COM * ERROR_SUCCESS Valid handle returned.
8088474SJose.Borrego@Sun.COM * ERROR_FILE_NOT_FOUND No key or unable to allocate a handle.
8098474SJose.Borrego@Sun.COM */
8108474SJose.Borrego@Sun.COM static int
winreg_s_OpenKey(void * arg,ndr_xa_t * mxa)8118474SJose.Borrego@Sun.COM winreg_s_OpenKey(void *arg, ndr_xa_t *mxa)
8128474SJose.Borrego@Sun.COM {
8138474SJose.Borrego@Sun.COM struct winreg_OpenKey *param = arg;
8149914Samw@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
8159914Samw@Sun.COM ndr_handle_t *hd;
8168474SJose.Borrego@Sun.COM char *subkey = (char *)param->name.str;
8178474SJose.Borrego@Sun.COM winreg_subkey_t *key;
81811963SAfshin.Ardakani@Sun.COM
81911963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&winreg_mutex);
8208474SJose.Borrego@Sun.COM
8219914Samw@Sun.COM if (subkey == NULL || *subkey == '\0') {
8229914Samw@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL)
8239914Samw@Sun.COM subkey = hd->nh_data;
8249914Samw@Sun.COM }
8259914Samw@Sun.COM
8269914Samw@Sun.COM id = NULL;
8279914Samw@Sun.COM
8288670SJose.Borrego@Sun.COM if (subkey == NULL || list_is_empty(&winreg_keylist.kl_list)) {
82911963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
8308474SJose.Borrego@Sun.COM bzero(¶m->result_handle, sizeof (winreg_handle_t));
8318474SJose.Borrego@Sun.COM param->status = ERROR_FILE_NOT_FOUND;
8328474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
8338474SJose.Borrego@Sun.COM }
8348474SJose.Borrego@Sun.COM
8358474SJose.Borrego@Sun.COM key = list_head(&winreg_keylist.kl_list);
8368474SJose.Borrego@Sun.COM do {
8378474SJose.Borrego@Sun.COM if (strcasecmp(subkey, key->sk_name) == 0) {
83811963SAfshin.Ardakani@Sun.COM if (key->sk_predefined == B_TRUE)
83911963SAfshin.Ardakani@Sun.COM id = winreg_alloc_id(mxa, subkey);
84011963SAfshin.Ardakani@Sun.COM else
8418474SJose.Borrego@Sun.COM id = &key->sk_handle;
8428474SJose.Borrego@Sun.COM
8438474SJose.Borrego@Sun.COM if (id == NULL)
8448474SJose.Borrego@Sun.COM break;
8458474SJose.Borrego@Sun.COM
8468474SJose.Borrego@Sun.COM bcopy(id, ¶m->result_handle,
8478474SJose.Borrego@Sun.COM sizeof (winreg_handle_t));
84811963SAfshin.Ardakani@Sun.COM
84911963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
8508474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS;
8518474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
8528474SJose.Borrego@Sun.COM }
8538474SJose.Borrego@Sun.COM } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL);
8548474SJose.Borrego@Sun.COM
85511963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&winreg_mutex);
8568474SJose.Borrego@Sun.COM bzero(¶m->result_handle, sizeof (winreg_handle_t));
8578474SJose.Borrego@Sun.COM param->status = ERROR_FILE_NOT_FOUND;
8588474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
8598474SJose.Borrego@Sun.COM }
8608474SJose.Borrego@Sun.COM
8618474SJose.Borrego@Sun.COM /*
8628474SJose.Borrego@Sun.COM * winreg_s_QueryKey
8638474SJose.Borrego@Sun.COM */
8648474SJose.Borrego@Sun.COM /*ARGSUSED*/
8658474SJose.Borrego@Sun.COM static int
winreg_s_QueryKey(void * arg,ndr_xa_t * mxa)8668474SJose.Borrego@Sun.COM winreg_s_QueryKey(void *arg, ndr_xa_t *mxa)
8678474SJose.Borrego@Sun.COM {
8688474SJose.Borrego@Sun.COM struct winreg_QueryKey *param = arg;
8698474SJose.Borrego@Sun.COM int rc;
8708474SJose.Borrego@Sun.COM winreg_string_t *name;
8718474SJose.Borrego@Sun.COM
8728474SJose.Borrego@Sun.COM name = (winreg_string_t *)¶m->name;
8738474SJose.Borrego@Sun.COM bzero(param, sizeof (struct winreg_QueryKey));
87411963SAfshin.Ardakani@Sun.COM
8758474SJose.Borrego@Sun.COM if ((name = NDR_NEW(mxa, winreg_string_t)) != NULL)
8768474SJose.Borrego@Sun.COM rc = NDR_MSTRING(mxa, "", (ndr_mstring_t *)name);
8778474SJose.Borrego@Sun.COM
8788474SJose.Borrego@Sun.COM if ((name == NULL) || (rc != 0)) {
8798474SJose.Borrego@Sun.COM bzero(param, sizeof (struct winreg_QueryKey));
8808474SJose.Borrego@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY;
8818474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
8828474SJose.Borrego@Sun.COM }
8838474SJose.Borrego@Sun.COM
8848474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS;
8858474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
8868474SJose.Borrego@Sun.COM }
8878474SJose.Borrego@Sun.COM
8888474SJose.Borrego@Sun.COM /*
8898474SJose.Borrego@Sun.COM * winreg_s_QueryValue
8908474SJose.Borrego@Sun.COM *
8918474SJose.Borrego@Sun.COM * This is a request to get the value associated with a specified name.
8928474SJose.Borrego@Sun.COM *
8938474SJose.Borrego@Sun.COM * Returns:
8948474SJose.Borrego@Sun.COM * ERROR_SUCCESS Value returned.
8958474SJose.Borrego@Sun.COM * ERROR_FILE_NOT_FOUND PrimaryModule is not supported.
8968474SJose.Borrego@Sun.COM * ERROR_CANTREAD No such name or memory problem.
8978474SJose.Borrego@Sun.COM */
8988474SJose.Borrego@Sun.COM static int
winreg_s_QueryValue(void * arg,ndr_xa_t * mxa)8998474SJose.Borrego@Sun.COM winreg_s_QueryValue(void *arg, ndr_xa_t *mxa)
9008474SJose.Borrego@Sun.COM {
9018474SJose.Borrego@Sun.COM struct winreg_QueryValue *param = arg;
9028474SJose.Borrego@Sun.COM struct winreg_value *pv;
9038474SJose.Borrego@Sun.COM char *name;
9048474SJose.Borrego@Sun.COM char *value;
9058474SJose.Borrego@Sun.COM DWORD slen;
9068474SJose.Borrego@Sun.COM DWORD msize;
9078474SJose.Borrego@Sun.COM
9088474SJose.Borrego@Sun.COM name = (char *)param->value_name.str;
9098474SJose.Borrego@Sun.COM
9108474SJose.Borrego@Sun.COM if (strcasecmp(name, "PrimaryModule") == 0) {
9118474SJose.Borrego@Sun.COM param->status = ERROR_FILE_NOT_FOUND;
9128474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
9138474SJose.Borrego@Sun.COM }
9148474SJose.Borrego@Sun.COM
9158474SJose.Borrego@Sun.COM if ((value = winreg_lookup_value(name)) == NULL) {
9168474SJose.Borrego@Sun.COM param->status = ERROR_CANTREAD;
9178474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
9188474SJose.Borrego@Sun.COM }
9198474SJose.Borrego@Sun.COM
92010966SJordan.Brown@Sun.COM slen = smb_wcequiv_strlen(value) + sizeof (smb_wchar_t);
9218474SJose.Borrego@Sun.COM msize = sizeof (struct winreg_value) + slen;
9228474SJose.Borrego@Sun.COM
9238474SJose.Borrego@Sun.COM param->value = (struct winreg_value *)NDR_MALLOC(mxa, msize);
9248474SJose.Borrego@Sun.COM param->type = NDR_NEW(mxa, DWORD);
9258474SJose.Borrego@Sun.COM param->value_size = NDR_NEW(mxa, DWORD);
9268474SJose.Borrego@Sun.COM param->value_size_total = NDR_NEW(mxa, DWORD);
9278474SJose.Borrego@Sun.COM
9288474SJose.Borrego@Sun.COM if (param->value == NULL || param->type == NULL ||
9298474SJose.Borrego@Sun.COM param->value_size == NULL || param->value_size_total == NULL) {
9308474SJose.Borrego@Sun.COM param->status = ERROR_CANTREAD;
9318474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
9328474SJose.Borrego@Sun.COM }
9338474SJose.Borrego@Sun.COM
9348474SJose.Borrego@Sun.COM bzero(param->value, msize);
9358474SJose.Borrego@Sun.COM pv = param->value;
9368474SJose.Borrego@Sun.COM pv->vc_first_is = 0;
9378474SJose.Borrego@Sun.COM pv->vc_length_is = slen;
9388474SJose.Borrego@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/
93910966SJordan.Brown@Sun.COM (void) ndr_mbstowcs(NULL, (smb_wchar_t *)pv->value, value, slen);
9408474SJose.Borrego@Sun.COM
9418474SJose.Borrego@Sun.COM *param->type = 1;
9428474SJose.Borrego@Sun.COM *param->value_size = slen;
9438474SJose.Borrego@Sun.COM *param->value_size_total = slen;
9448474SJose.Borrego@Sun.COM
9458474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS;
9468474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
9478474SJose.Borrego@Sun.COM }
9488474SJose.Borrego@Sun.COM
9498474SJose.Borrego@Sun.COM /*
9508474SJose.Borrego@Sun.COM * Lookup a name in the registry and return the associated value.
9518474SJose.Borrego@Sun.COM * Our registry is a case-insensitive, name-value pair table.
9528474SJose.Borrego@Sun.COM *
9538474SJose.Borrego@Sun.COM * Windows ProductType: WinNT, ServerNT, LanmanNT.
9548474SJose.Borrego@Sun.COM * Windows NT4.0 workstation: WinNT
9558474SJose.Borrego@Sun.COM * Windows NT4.0 server: ServerNT
9568474SJose.Borrego@Sun.COM *
9578474SJose.Borrego@Sun.COM * If LanmanNT is used here, Windows 2000 sends LsarQueryInfoPolicy
9588474SJose.Borrego@Sun.COM * with info level 6, which we don't support. If we use ServerNT
9598474SJose.Borrego@Sun.COM * (as reported by NT4.0 Server) Windows 2000 send requests for
9608474SJose.Borrego@Sun.COM * levels 3 and 5, which are support.
9618474SJose.Borrego@Sun.COM *
9628474SJose.Borrego@Sun.COM * On success, returns a pointer to the value. Otherwise returns
9638474SJose.Borrego@Sun.COM * a null pointer.
9648474SJose.Borrego@Sun.COM */
9658474SJose.Borrego@Sun.COM static char *
winreg_lookup_value(const char * name)9668474SJose.Borrego@Sun.COM winreg_lookup_value(const char *name)
9678474SJose.Borrego@Sun.COM {
9688474SJose.Borrego@Sun.COM static struct registry {
9698474SJose.Borrego@Sun.COM char *name;
9708474SJose.Borrego@Sun.COM char *value;
9718474SJose.Borrego@Sun.COM } registry[] = {
97211963SAfshin.Ardakani@Sun.COM { "SystemRoot", "C:\\" },
97311963SAfshin.Ardakani@Sun.COM { "CurrentVersion", winreg_sysver },
97411963SAfshin.Ardakani@Sun.COM { "ProductType", "ServerNT" },
97511963SAfshin.Ardakani@Sun.COM { "Sources", winreg_sysname }, /* product name */
97611963SAfshin.Ardakani@Sun.COM { "EventMessageFile", "C:\\windows\\system32\\eventlog.dll" }
9778474SJose.Borrego@Sun.COM };
9788474SJose.Borrego@Sun.COM
9798474SJose.Borrego@Sun.COM int i;
9808474SJose.Borrego@Sun.COM
9818474SJose.Borrego@Sun.COM for (i = 0; i < sizeof (registry)/sizeof (registry[0]); ++i) {
98211963SAfshin.Ardakani@Sun.COM if (strcasecmp(registry[i].name, name) == 0)
98311963SAfshin.Ardakani@Sun.COM return (registry[i].value);
9848474SJose.Borrego@Sun.COM }
9858474SJose.Borrego@Sun.COM
9868474SJose.Borrego@Sun.COM return (NULL);
9878474SJose.Borrego@Sun.COM }
9888474SJose.Borrego@Sun.COM
9898474SJose.Borrego@Sun.COM /*
9908474SJose.Borrego@Sun.COM * winreg_s_SetKeySec
9918474SJose.Borrego@Sun.COM */
9928474SJose.Borrego@Sun.COM /*ARGSUSED*/
9938474SJose.Borrego@Sun.COM static int
winreg_s_SetKeySec(void * arg,ndr_xa_t * mxa)9948474SJose.Borrego@Sun.COM winreg_s_SetKeySec(void *arg, ndr_xa_t *mxa)
9958474SJose.Borrego@Sun.COM {
9968474SJose.Borrego@Sun.COM struct winreg_SetKeySec *param = arg;
9978474SJose.Borrego@Sun.COM
9988474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED;
9998474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
10008474SJose.Borrego@Sun.COM }
10018474SJose.Borrego@Sun.COM
10028474SJose.Borrego@Sun.COM /*
10038474SJose.Borrego@Sun.COM * winreg_s_CreateValue
10048474SJose.Borrego@Sun.COM */
10058474SJose.Borrego@Sun.COM /*ARGSUSED*/
10068474SJose.Borrego@Sun.COM static int
winreg_s_CreateValue(void * arg,ndr_xa_t * mxa)10078474SJose.Borrego@Sun.COM winreg_s_CreateValue(void *arg, ndr_xa_t *mxa)
10088474SJose.Borrego@Sun.COM {
10098474SJose.Borrego@Sun.COM struct winreg_CreateValue *param = arg;
10108474SJose.Borrego@Sun.COM
10118474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED;
10128474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
10138474SJose.Borrego@Sun.COM }
10148474SJose.Borrego@Sun.COM
10158474SJose.Borrego@Sun.COM /*
10168474SJose.Borrego@Sun.COM * winreg_s_Shutdown
10178474SJose.Borrego@Sun.COM *
10188474SJose.Borrego@Sun.COM * Attempt to shutdown or reboot the system: access denied.
10198474SJose.Borrego@Sun.COM */
10208474SJose.Borrego@Sun.COM /*ARGSUSED*/
10218474SJose.Borrego@Sun.COM static int
winreg_s_Shutdown(void * arg,ndr_xa_t * mxa)10228474SJose.Borrego@Sun.COM winreg_s_Shutdown(void *arg, ndr_xa_t *mxa)
10238474SJose.Borrego@Sun.COM {
10248474SJose.Borrego@Sun.COM struct winreg_Shutdown *param = arg;
10258474SJose.Borrego@Sun.COM
10268474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED;
10278474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
10288474SJose.Borrego@Sun.COM }
10298474SJose.Borrego@Sun.COM
10308474SJose.Borrego@Sun.COM /*
10318474SJose.Borrego@Sun.COM * winreg_s_AbortShutdown
10328474SJose.Borrego@Sun.COM *
10338474SJose.Borrego@Sun.COM * Abort a shutdown request.
10348474SJose.Borrego@Sun.COM */
10358474SJose.Borrego@Sun.COM static int
winreg_s_AbortShutdown(void * arg,ndr_xa_t * mxa)10368474SJose.Borrego@Sun.COM winreg_s_AbortShutdown(void *arg, ndr_xa_t *mxa)
10378474SJose.Borrego@Sun.COM {
10388474SJose.Borrego@Sun.COM struct winreg_AbortShutdown *param = arg;
10398474SJose.Borrego@Sun.COM
10408474SJose.Borrego@Sun.COM if (ndr_is_admin(mxa))
10418474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS;
10428474SJose.Borrego@Sun.COM else
10438474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED;
10448474SJose.Borrego@Sun.COM
10458474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
10468474SJose.Borrego@Sun.COM }
10478474SJose.Borrego@Sun.COM
10488474SJose.Borrego@Sun.COM /*
10498474SJose.Borrego@Sun.COM * winreg_s_GetVersion
10508474SJose.Borrego@Sun.COM *
10518474SJose.Borrego@Sun.COM * Return the windows registry version. The current version is 5.
10528474SJose.Borrego@Sun.COM * This call is usually made prior to enumerating or querying registry
10538474SJose.Borrego@Sun.COM * keys or values.
10548474SJose.Borrego@Sun.COM */
10558474SJose.Borrego@Sun.COM /*ARGSUSED*/
10568474SJose.Borrego@Sun.COM static int
winreg_s_GetVersion(void * arg,ndr_xa_t * mxa)10578474SJose.Borrego@Sun.COM winreg_s_GetVersion(void *arg, ndr_xa_t *mxa)
10588474SJose.Borrego@Sun.COM {
10598474SJose.Borrego@Sun.COM struct winreg_GetVersion *param = arg;
10608474SJose.Borrego@Sun.COM
10618474SJose.Borrego@Sun.COM param->version = 5;
10628474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS;
10638474SJose.Borrego@Sun.COM return (NDR_DRC_OK);
10648474SJose.Borrego@Sun.COM }
1065