189dc44ceSjose borrego /*
289dc44ceSjose borrego * CDDL HEADER START
389dc44ceSjose borrego *
489dc44ceSjose borrego * The contents of this file are subject to the terms of the
589dc44ceSjose borrego * Common Development and Distribution License (the "License").
689dc44ceSjose borrego * You may not use this file except in compliance with the License.
789dc44ceSjose borrego *
889dc44ceSjose borrego * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
989dc44ceSjose borrego * or http://www.opensolaris.org/os/licensing.
1089dc44ceSjose borrego * See the License for the specific language governing permissions
1189dc44ceSjose borrego * and limitations under the License.
1289dc44ceSjose borrego *
1389dc44ceSjose borrego * When distributing Covered Code, include this CDDL HEADER in each
1489dc44ceSjose borrego * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1589dc44ceSjose borrego * If applicable, add the following below this CDDL HEADER, with the
1689dc44ceSjose borrego * fields enclosed by brackets "[]" replaced with your own identifying
1789dc44ceSjose borrego * information: Portions Copyright [yyyy] [name of copyright owner]
1889dc44ceSjose borrego *
1989dc44ceSjose borrego * CDDL HEADER END
2089dc44ceSjose borrego */
21148c5f43SAlan Wright
2289dc44ceSjose borrego /*
23148c5f43SAlan Wright * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24*5831d79bSGordon Ross * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
2589dc44ceSjose borrego */
2689dc44ceSjose borrego
2789dc44ceSjose borrego /*
2889dc44ceSjose borrego * Windows Registry RPC (WINREG) server-side interface.
2989dc44ceSjose borrego *
307f667e74Sjose borrego * The registry is a database with a hierarchical structure similar to
317f667e74Sjose borrego * a file system, with keys in place of directories and values in place
327f667e74Sjose borrego * of files. The top level keys are known as root keys and each key can
337f667e74Sjose borrego * contain subkeys and values. As with directories and sub-directories,
347f667e74Sjose borrego * the terms key and subkey are used interchangeably. Values, analogous
357f667e74Sjose borrego * to files, contain data.
3689dc44ceSjose borrego *
377f667e74Sjose borrego * A specific subkey can be identifies by its fully qualified name (FQN),
387f667e74Sjose borrego * which is analogous to a file system path. In the registry, the key
397f667e74Sjose borrego * separator is the '\' character, which is reserved and cannot appear
407f667e74Sjose borrego * in key or value names. Registry names are case-insensitive.
417f667e74Sjose borrego *
427f667e74Sjose borrego * For example: HKEY_LOCAL_MACHINE\System\CurrentControlSet
437f667e74Sjose borrego *
44b1352070SAlan Wright * The HKEY_LOCAL_MACHINE root key contains a subkey called System, and
457f667e74Sjose borrego * System contains a subkey called CurrentControlSet.
467f667e74Sjose borrego *
477f667e74Sjose borrego * The WINREG RPC interface returns Win32 error codes.
4889dc44ceSjose borrego */
4989dc44ceSjose borrego
5089dc44ceSjose borrego #include <sys/utsname.h>
5189dc44ceSjose borrego #include <strings.h>
5289dc44ceSjose borrego
5389dc44ceSjose borrego #include <smbsrv/libsmb.h>
5489dc44ceSjose borrego #include <smbsrv/nmpipes.h>
5589dc44ceSjose borrego #include <smbsrv/libmlsvc.h>
5689dc44ceSjose borrego #include <smbsrv/ndl/winreg.ndl>
5789dc44ceSjose borrego
5889dc44ceSjose borrego /*
5989dc44ceSjose borrego * List of supported registry keys (case-insensitive).
6089dc44ceSjose borrego */
6189dc44ceSjose borrego static char *winreg_keys[] = {
62b1352070SAlan Wright "HKLM",
63b1352070SAlan Wright "HKU",
64b1352070SAlan Wright "HKLM\\SOFTWARE",
65b1352070SAlan Wright "HKLM\\SYSTEM",
66b1352070SAlan Wright "System",
67b1352070SAlan Wright "CurrentControlSet",
689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States "SunOS",
699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States "Solaris",
7089dc44ceSjose borrego "System\\CurrentControlSet\\Services\\Eventlog",
7189dc44ceSjose borrego "System\\CurrentControlSet\\Control\\ProductOptions",
72b1352070SAlan Wright "SOFTWARE",
7389dc44ceSjose borrego "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
7489dc44ceSjose borrego };
7589dc44ceSjose borrego
76148c5f43SAlan Wright static char *winreg_eventlog = "System\\CurrentControlSet\\Services\\Eventlog";
77148c5f43SAlan Wright
78148c5f43SAlan Wright static char *winreg_log[] = {
79148c5f43SAlan Wright "Application",
80148c5f43SAlan Wright "Security",
81148c5f43SAlan Wright "System",
82148c5f43SAlan Wright "smbd",
83148c5f43SAlan Wright "smbrdr"
84148c5f43SAlan Wright };
85148c5f43SAlan Wright
8689dc44ceSjose borrego typedef struct winreg_subkey {
8789dc44ceSjose borrego list_node_t sk_lnd;
8889dc44ceSjose borrego ndr_hdid_t sk_handle;
8989dc44ceSjose borrego char sk_name[MAXPATHLEN];
9089dc44ceSjose borrego boolean_t sk_predefined;
9189dc44ceSjose borrego } winreg_subkey_t;
9289dc44ceSjose borrego
9389dc44ceSjose borrego typedef struct winreg_keylist {
9489dc44ceSjose borrego list_t kl_list;
9589dc44ceSjose borrego int kl_count;
9689dc44ceSjose borrego } winreg_keylist_t;
9789dc44ceSjose borrego
9889dc44ceSjose borrego static winreg_keylist_t winreg_keylist;
999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static mutex_t winreg_mutex;
10089dc44ceSjose borrego
101148c5f43SAlan Wright static void winreg_add_predefined(const char *);
1029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static ndr_hdid_t *winreg_alloc_id(ndr_xa_t *, const char *);
1039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void winreg_dealloc_id(ndr_xa_t *, ndr_hdid_t *);
10489dc44ceSjose borrego static boolean_t winreg_key_has_subkey(const char *);
1057f667e74Sjose borrego static char *winreg_enum_subkey(ndr_xa_t *, const char *, uint32_t);
10689dc44ceSjose borrego static char *winreg_lookup_value(const char *);
107f96bd5c8SAlan Wright static uint32_t winreg_sd_format(smb_sd_t *);
108f96bd5c8SAlan Wright uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *);
10989dc44ceSjose borrego
1107f667e74Sjose borrego static int winreg_s_OpenHKCR(void *, ndr_xa_t *);
1117f667e74Sjose borrego static int winreg_s_OpenHKCU(void *, ndr_xa_t *);
11289dc44ceSjose borrego static int winreg_s_OpenHKLM(void *, ndr_xa_t *);
1137f667e74Sjose borrego static int winreg_s_OpenHKPD(void *, ndr_xa_t *);
1147f667e74Sjose borrego static int winreg_s_OpenHKU(void *, ndr_xa_t *);
1157f667e74Sjose borrego static int winreg_s_OpenHKCC(void *, ndr_xa_t *);
1167f667e74Sjose borrego static int winreg_s_OpenHKDD(void *, ndr_xa_t *);
1177f667e74Sjose borrego static int winreg_s_OpenHKPT(void *, ndr_xa_t *);
1187f667e74Sjose borrego static int winreg_s_OpenHKPN(void *, ndr_xa_t *);
1197f667e74Sjose borrego static int winreg_s_OpenHK(void *, ndr_xa_t *, const char *);
12089dc44ceSjose borrego static int winreg_s_Close(void *, ndr_xa_t *);
12189dc44ceSjose borrego static int winreg_s_CreateKey(void *, ndr_xa_t *);
12289dc44ceSjose borrego static int winreg_s_DeleteKey(void *, ndr_xa_t *);
12389dc44ceSjose borrego static int winreg_s_DeleteValue(void *, ndr_xa_t *);
12489dc44ceSjose borrego static int winreg_s_EnumKey(void *, ndr_xa_t *);
12589dc44ceSjose borrego static int winreg_s_EnumValue(void *, ndr_xa_t *);
12689dc44ceSjose borrego static int winreg_s_FlushKey(void *, ndr_xa_t *);
12789dc44ceSjose borrego static int winreg_s_GetKeySec(void *, ndr_xa_t *);
12889dc44ceSjose borrego static int winreg_s_NotifyChange(void *, ndr_xa_t *);
12989dc44ceSjose borrego static int winreg_s_OpenKey(void *, ndr_xa_t *);
13089dc44ceSjose borrego static int winreg_s_QueryKey(void *, ndr_xa_t *);
13189dc44ceSjose borrego static int winreg_s_QueryValue(void *, ndr_xa_t *);
13289dc44ceSjose borrego static int winreg_s_SetKeySec(void *, ndr_xa_t *);
13389dc44ceSjose borrego static int winreg_s_CreateValue(void *, ndr_xa_t *);
13489dc44ceSjose borrego static int winreg_s_Shutdown(void *, ndr_xa_t *);
13589dc44ceSjose borrego static int winreg_s_AbortShutdown(void *, ndr_xa_t *);
13689dc44ceSjose borrego static int winreg_s_GetVersion(void *, ndr_xa_t *);
13789dc44ceSjose borrego
13889dc44ceSjose borrego static ndr_stub_table_t winreg_stub_table[] = {
1397f667e74Sjose borrego { winreg_s_OpenHKCR, WINREG_OPNUM_OpenHKCR },
1407f667e74Sjose borrego { winreg_s_OpenHKCU, WINREG_OPNUM_OpenHKCU },
14189dc44ceSjose borrego { winreg_s_OpenHKLM, WINREG_OPNUM_OpenHKLM },
1427f667e74Sjose borrego { winreg_s_OpenHKPD, WINREG_OPNUM_OpenHKPD },
1437f667e74Sjose borrego { winreg_s_OpenHKU, WINREG_OPNUM_OpenHKUsers },
14489dc44ceSjose borrego { winreg_s_Close, WINREG_OPNUM_Close },
14589dc44ceSjose borrego { winreg_s_CreateKey, WINREG_OPNUM_CreateKey },
14689dc44ceSjose borrego { winreg_s_DeleteKey, WINREG_OPNUM_DeleteKey },
14789dc44ceSjose borrego { winreg_s_DeleteValue, WINREG_OPNUM_DeleteValue },
14889dc44ceSjose borrego { winreg_s_EnumKey, WINREG_OPNUM_EnumKey },
14989dc44ceSjose borrego { winreg_s_EnumValue, WINREG_OPNUM_EnumValue },
15089dc44ceSjose borrego { winreg_s_FlushKey, WINREG_OPNUM_FlushKey },
15189dc44ceSjose borrego { winreg_s_GetKeySec, WINREG_OPNUM_GetKeySec },
15289dc44ceSjose borrego { winreg_s_NotifyChange, WINREG_OPNUM_NotifyChange },
15389dc44ceSjose borrego { winreg_s_OpenKey, WINREG_OPNUM_OpenKey },
15489dc44ceSjose borrego { winreg_s_QueryKey, WINREG_OPNUM_QueryKey },
15589dc44ceSjose borrego { winreg_s_QueryValue, WINREG_OPNUM_QueryValue },
15689dc44ceSjose borrego { winreg_s_SetKeySec, WINREG_OPNUM_SetKeySec },
15789dc44ceSjose borrego { winreg_s_CreateValue, WINREG_OPNUM_CreateValue },
15889dc44ceSjose borrego { winreg_s_Shutdown, WINREG_OPNUM_Shutdown },
15989dc44ceSjose borrego { winreg_s_AbortShutdown, WINREG_OPNUM_AbortShutdown },
16089dc44ceSjose borrego { winreg_s_GetVersion, WINREG_OPNUM_GetVersion },
1617f667e74Sjose borrego { winreg_s_OpenHKCC, WINREG_OPNUM_OpenHKCC },
1627f667e74Sjose borrego { winreg_s_OpenHKDD, WINREG_OPNUM_OpenHKDD },
1637f667e74Sjose borrego { winreg_s_OpenHKPT, WINREG_OPNUM_OpenHKPT },
1647f667e74Sjose borrego { winreg_s_OpenHKPN, WINREG_OPNUM_OpenHKPN },
16589dc44ceSjose borrego {0}
16689dc44ceSjose borrego };
16789dc44ceSjose borrego
16889dc44ceSjose borrego static ndr_service_t winreg_service = {
16989dc44ceSjose borrego "Winreg", /* name */
17089dc44ceSjose borrego "Windows Registry", /* desc */
17189dc44ceSjose borrego "\\winreg", /* endpoint */
17289dc44ceSjose borrego PIPE_WINREG, /* sec_addr_port */
17389dc44ceSjose borrego "338cd001-2244-31f1-aaaa-900038001003", 1, /* abstract */
17489dc44ceSjose borrego NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */
17589dc44ceSjose borrego 0, /* no bind_instance_size */
17689dc44ceSjose borrego 0, /* no bind_req() */
17789dc44ceSjose borrego 0, /* no unbind_and_close() */
17889dc44ceSjose borrego 0, /* use generic_call_stub() */
17989dc44ceSjose borrego &TYPEINFO(winreg_interface), /* interface ti */
18089dc44ceSjose borrego winreg_stub_table /* stub_table */
18189dc44ceSjose borrego };
18289dc44ceSjose borrego
18389dc44ceSjose borrego static char winreg_sysname[SYS_NMLN];
1849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static char winreg_sysver[SMB_VERSTR_LEN];
18589dc44ceSjose borrego
18689dc44ceSjose borrego /*
18789dc44ceSjose borrego * winreg_initialize
18889dc44ceSjose borrego *
18989dc44ceSjose borrego * Initialize and register the WINREG RPC interface with the RPC runtime
19089dc44ceSjose borrego * library. It must be called in order to use either the client side
19189dc44ceSjose borrego * or the server side functions.
19289dc44ceSjose borrego */
19389dc44ceSjose borrego void
winreg_initialize(void)19489dc44ceSjose borrego winreg_initialize(void)
19589dc44ceSjose borrego {
1969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_version_t version;
19789dc44ceSjose borrego struct utsname name;
198148c5f43SAlan Wright char subkey[MAXPATHLEN];
19989dc44ceSjose borrego char *sysname;
20089dc44ceSjose borrego int i;
20189dc44ceSjose borrego
2029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex);
2039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
20489dc44ceSjose borrego list_create(&winreg_keylist.kl_list, sizeof (winreg_subkey_t),
20589dc44ceSjose borrego offsetof(winreg_subkey_t, sk_lnd));
20689dc44ceSjose borrego winreg_keylist.kl_count = 0;
20789dc44ceSjose borrego
208148c5f43SAlan Wright for (i = 0; i < sizeof (winreg_keys)/sizeof (winreg_keys[0]); ++i)
209148c5f43SAlan Wright winreg_add_predefined(winreg_keys[i]);
2109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
211148c5f43SAlan Wright for (i = 0; i < sizeof (winreg_log)/sizeof (winreg_log[0]); ++i) {
212148c5f43SAlan Wright (void) snprintf(subkey, MAXPATHLEN, "%s", winreg_log[i]);
213148c5f43SAlan Wright winreg_add_predefined(subkey);
214148c5f43SAlan Wright
215148c5f43SAlan Wright (void) snprintf(subkey, MAXPATHLEN, "%s\\%s",
216148c5f43SAlan Wright winreg_eventlog, winreg_log[i]);
217148c5f43SAlan Wright winreg_add_predefined(subkey);
218148c5f43SAlan Wright
219148c5f43SAlan Wright (void) snprintf(subkey, MAXPATHLEN, "%s\\%s\\%s",
220148c5f43SAlan Wright winreg_eventlog, winreg_log[i], winreg_log[i]);
221148c5f43SAlan Wright winreg_add_predefined(subkey);
22289dc44ceSjose borrego }
22389dc44ceSjose borrego
2249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
2259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
22689dc44ceSjose borrego if (uname(&name) < 0)
22789dc44ceSjose borrego sysname = "Solaris";
22889dc44ceSjose borrego else
22989dc44ceSjose borrego sysname = name.sysname;
23089dc44ceSjose borrego
23189dc44ceSjose borrego (void) strlcpy(winreg_sysname, sysname, SYS_NMLN);
2329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
2339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_config_get_version(&version);
2349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) snprintf(winreg_sysver, SMB_VERSTR_LEN, "%d.%d",
2359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States version.sv_major, version.sv_minor);
2369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
23789dc44ceSjose borrego (void) ndr_svc_register(&winreg_service);
23889dc44ceSjose borrego }
23989dc44ceSjose borrego
240148c5f43SAlan Wright static void
winreg_add_predefined(const char * subkey)241148c5f43SAlan Wright winreg_add_predefined(const char *subkey)
242148c5f43SAlan Wright {
243148c5f43SAlan Wright winreg_subkey_t *key;
244148c5f43SAlan Wright
245148c5f43SAlan Wright if ((key = malloc(sizeof (winreg_subkey_t))) != NULL) {
246148c5f43SAlan Wright bzero(key, sizeof (winreg_subkey_t));
247148c5f43SAlan Wright (void) strlcpy(key->sk_name, subkey, MAXPATHLEN);
248148c5f43SAlan Wright key->sk_predefined = B_TRUE;
249148c5f43SAlan Wright
250148c5f43SAlan Wright list_insert_tail(&winreg_keylist.kl_list, key);
251148c5f43SAlan Wright ++winreg_keylist.kl_count;
252148c5f43SAlan Wright }
253148c5f43SAlan Wright }
254148c5f43SAlan Wright
25589dc44ceSjose borrego static int
winreg_s_OpenHKCR(void * arg,ndr_xa_t * mxa)2567f667e74Sjose borrego winreg_s_OpenHKCR(void *arg, ndr_xa_t *mxa)
25789dc44ceSjose borrego {
2587f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKCR"));
25989dc44ceSjose borrego }
26089dc44ceSjose borrego
2617f667e74Sjose borrego static int
winreg_s_OpenHKCU(void * arg,ndr_xa_t * mxa)2627f667e74Sjose borrego winreg_s_OpenHKCU(void *arg, ndr_xa_t *mxa)
2637f667e74Sjose borrego {
2647f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKCU"));
26589dc44ceSjose borrego }
26689dc44ceSjose borrego
26789dc44ceSjose borrego static int
winreg_s_OpenHKLM(void * arg,ndr_xa_t * mxa)26889dc44ceSjose borrego winreg_s_OpenHKLM(void *arg, ndr_xa_t *mxa)
26989dc44ceSjose borrego {
2707f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKLM"));
27189dc44ceSjose borrego }
27289dc44ceSjose borrego
2737f667e74Sjose borrego static int
winreg_s_OpenHKPD(void * arg,ndr_xa_t * mxa)2747f667e74Sjose borrego winreg_s_OpenHKPD(void *arg, ndr_xa_t *mxa)
2757f667e74Sjose borrego {
2767f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKPD"));
2777f667e74Sjose borrego }
2787f667e74Sjose borrego
2797f667e74Sjose borrego static int
winreg_s_OpenHKU(void * arg,ndr_xa_t * mxa)2807f667e74Sjose borrego winreg_s_OpenHKU(void *arg, ndr_xa_t *mxa)
2817f667e74Sjose borrego {
2827f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKU"));
2837f667e74Sjose borrego }
2847f667e74Sjose borrego
2857f667e74Sjose borrego static int
winreg_s_OpenHKCC(void * arg,ndr_xa_t * mxa)2867f667e74Sjose borrego winreg_s_OpenHKCC(void *arg, ndr_xa_t *mxa)
2877f667e74Sjose borrego {
2887f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKCC"));
2897f667e74Sjose borrego }
2907f667e74Sjose borrego
2917f667e74Sjose borrego static int
winreg_s_OpenHKDD(void * arg,ndr_xa_t * mxa)2927f667e74Sjose borrego winreg_s_OpenHKDD(void *arg, ndr_xa_t *mxa)
2937f667e74Sjose borrego {
2947f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKDD"));
2957f667e74Sjose borrego }
2967f667e74Sjose borrego
2977f667e74Sjose borrego static int
winreg_s_OpenHKPT(void * arg,ndr_xa_t * mxa)2987f667e74Sjose borrego winreg_s_OpenHKPT(void *arg, ndr_xa_t *mxa)
2997f667e74Sjose borrego {
3007f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKPT"));
3017f667e74Sjose borrego }
3027f667e74Sjose borrego
3037f667e74Sjose borrego static int
winreg_s_OpenHKPN(void * arg,ndr_xa_t * mxa)3047f667e74Sjose borrego winreg_s_OpenHKPN(void *arg, ndr_xa_t *mxa)
3057f667e74Sjose borrego {
3067f667e74Sjose borrego return (winreg_s_OpenHK(arg, mxa, "HKPN"));
30789dc44ceSjose borrego }
30889dc44ceSjose borrego
30989dc44ceSjose borrego /*
3107f667e74Sjose borrego * winreg_s_OpenHK
31189dc44ceSjose borrego *
3127f667e74Sjose borrego * Common code to open root HKEYs.
31389dc44ceSjose borrego */
31489dc44ceSjose borrego static int
winreg_s_OpenHK(void * arg,ndr_xa_t * mxa,const char * hkey)3157f667e74Sjose borrego winreg_s_OpenHK(void *arg, ndr_xa_t *mxa, const char *hkey)
31689dc44ceSjose borrego {
3177f667e74Sjose borrego struct winreg_OpenHKCR *param = arg;
31889dc44ceSjose borrego ndr_hdid_t *id;
31989dc44ceSjose borrego
3209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex);
3217f667e74Sjose borrego
3229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((id = winreg_alloc_id(mxa, hkey)) == NULL) {
32389dc44ceSjose borrego bzero(¶m->handle, sizeof (winreg_handle_t));
32489dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED;
32589dc44ceSjose borrego } else {
32689dc44ceSjose borrego bcopy(id, ¶m->handle, sizeof (winreg_handle_t));
32789dc44ceSjose borrego param->status = ERROR_SUCCESS;
32889dc44ceSjose borrego }
32989dc44ceSjose borrego
3309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
33189dc44ceSjose borrego return (NDR_DRC_OK);
33289dc44ceSjose borrego }
33389dc44ceSjose borrego
33489dc44ceSjose borrego /*
33589dc44ceSjose borrego * winreg_s_Close
33689dc44ceSjose borrego *
33789dc44ceSjose borrego * This is a request to close the WINREG interface specified by the
33889dc44ceSjose borrego * handle. We don't track handles (yet), so just zero out the handle
33989dc44ceSjose borrego * and return NDR_DRC_OK. Setting the handle to zero appears to be
34089dc44ceSjose borrego * standard behaviour.
34189dc44ceSjose borrego */
34289dc44ceSjose borrego static int
winreg_s_Close(void * arg,ndr_xa_t * mxa)34389dc44ceSjose borrego winreg_s_Close(void *arg, ndr_xa_t *mxa)
34489dc44ceSjose borrego {
34589dc44ceSjose borrego struct winreg_Close *param = arg;
34689dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
3479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
3489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex);
3499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States winreg_dealloc_id(mxa, id);
3509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
3519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
3529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States bzero(¶m->result_handle, sizeof (winreg_handle_t));
3539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States param->status = ERROR_SUCCESS;
3549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NDR_DRC_OK);
3559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
3579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static ndr_hdid_t *
winreg_alloc_id(ndr_xa_t * mxa,const char * key)3589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States winreg_alloc_id(ndr_xa_t *mxa, const char *key)
3599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_handle_t *hd;
3619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_hdid_t *id;
3629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char *data;
3639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
3649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((data = strdup(key)) == NULL)
3659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NULL);
3669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
3679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((id = ndr_hdalloc(mxa, data)) == NULL) {
3689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States free(data);
3699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NULL);
3709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
3729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((hd = ndr_hdlookup(mxa, id)) != NULL)
3739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States hd->nh_data_free = free;
3749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
3759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (id);
3769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
3789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
winreg_dealloc_id(ndr_xa_t * mxa,ndr_hdid_t * id)3799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States winreg_dealloc_id(ndr_xa_t *mxa, ndr_hdid_t *id)
3809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3817f667e74Sjose borrego ndr_handle_t *hd;
3827f667e74Sjose borrego
3837f667e74Sjose borrego if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
3847f667e74Sjose borrego free(hd->nh_data);
3857f667e74Sjose borrego hd->nh_data = NULL;
3867f667e74Sjose borrego }
38789dc44ceSjose borrego
38889dc44ceSjose borrego ndr_hdfree(mxa, id);
38989dc44ceSjose borrego }
39089dc44ceSjose borrego
39189dc44ceSjose borrego /*
39289dc44ceSjose borrego * winreg_s_CreateKey
39389dc44ceSjose borrego */
39489dc44ceSjose borrego static int
winreg_s_CreateKey(void * arg,ndr_xa_t * mxa)39589dc44ceSjose borrego winreg_s_CreateKey(void *arg, ndr_xa_t *mxa)
39689dc44ceSjose borrego {
39789dc44ceSjose borrego struct winreg_CreateKey *param = arg;
39889dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
39989dc44ceSjose borrego ndr_handle_t *hd;
40089dc44ceSjose borrego winreg_subkey_t *key;
40189dc44ceSjose borrego char *subkey;
40289dc44ceSjose borrego DWORD *action;
40389dc44ceSjose borrego
40489dc44ceSjose borrego subkey = (char *)param->subkey.str;
40589dc44ceSjose borrego
40689dc44ceSjose borrego if (!ndr_is_admin(mxa) || (subkey == NULL)) {
40789dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey));
40889dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED;
40989dc44ceSjose borrego return (NDR_DRC_OK);
41089dc44ceSjose borrego }
41189dc44ceSjose borrego
4129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex);
4139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
41489dc44ceSjose borrego hd = ndr_hdlookup(mxa, id);
41589dc44ceSjose borrego if (hd == NULL) {
4169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
41789dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey));
41889dc44ceSjose borrego param->status = ERROR_INVALID_HANDLE;
41989dc44ceSjose borrego return (NDR_DRC_OK);
42089dc44ceSjose borrego }
42189dc44ceSjose borrego
42289dc44ceSjose borrego if ((action = NDR_NEW(mxa, DWORD)) == NULL) {
4239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
42489dc44ceSjose borrego bzero(param, sizeof (struct winreg_CreateKey));
42589dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY;
42689dc44ceSjose borrego return (NDR_DRC_OK);
42789dc44ceSjose borrego }
42889dc44ceSjose borrego
42989dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list))
43089dc44ceSjose borrego goto new_key;
43189dc44ceSjose borrego
43289dc44ceSjose borrego /*
43389dc44ceSjose borrego * Check for an existing key.
43489dc44ceSjose borrego */
43589dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list);
43689dc44ceSjose borrego do {
43789dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) {
43889dc44ceSjose borrego bcopy(&key->sk_handle, ¶m->result_handle,
43989dc44ceSjose borrego sizeof (winreg_handle_t));
4409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
4419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
44289dc44ceSjose borrego *action = WINREG_ACTION_EXISTING_KEY;
44389dc44ceSjose borrego param->action = action;
44489dc44ceSjose borrego param->status = ERROR_SUCCESS;
44589dc44ceSjose borrego return (NDR_DRC_OK);
44689dc44ceSjose borrego }
44789dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL);
44889dc44ceSjose borrego
44989dc44ceSjose borrego new_key:
45089dc44ceSjose borrego /*
45189dc44ceSjose borrego * Create a new key.
45289dc44ceSjose borrego */
4539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((id = winreg_alloc_id(mxa, subkey)) == NULL)
4549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States goto no_memory;
4557f667e74Sjose borrego
4569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((key = malloc(sizeof (winreg_subkey_t))) == NULL) {
4579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States winreg_dealloc_id(mxa, id);
4589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States goto no_memory;
45989dc44ceSjose borrego }
46089dc44ceSjose borrego
46189dc44ceSjose borrego bcopy(id, &key->sk_handle, sizeof (ndr_hdid_t));
46289dc44ceSjose borrego (void) strlcpy(key->sk_name, subkey, MAXPATHLEN);
46389dc44ceSjose borrego key->sk_predefined = B_FALSE;
46489dc44ceSjose borrego list_insert_tail(&winreg_keylist.kl_list, key);
46589dc44ceSjose borrego ++winreg_keylist.kl_count;
46689dc44ceSjose borrego
46789dc44ceSjose borrego bcopy(id, ¶m->result_handle, sizeof (winreg_handle_t));
4689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
4699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
47089dc44ceSjose borrego *action = WINREG_ACTION_NEW_KEY;
47189dc44ceSjose borrego param->action = action;
47289dc44ceSjose borrego param->status = ERROR_SUCCESS;
47389dc44ceSjose borrego return (NDR_DRC_OK);
4749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
4759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States no_memory:
4769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
4779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States bzero(param, sizeof (struct winreg_CreateKey));
4789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States param->status = ERROR_NOT_ENOUGH_MEMORY;
4799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NDR_DRC_OK);
48089dc44ceSjose borrego }
48189dc44ceSjose borrego
48289dc44ceSjose borrego /*
48389dc44ceSjose borrego * winreg_s_DeleteKey
48489dc44ceSjose borrego */
48589dc44ceSjose borrego static int
winreg_s_DeleteKey(void * arg,ndr_xa_t * mxa)48689dc44ceSjose borrego winreg_s_DeleteKey(void *arg, ndr_xa_t *mxa)
48789dc44ceSjose borrego {
48889dc44ceSjose borrego struct winreg_DeleteKey *param = arg;
48989dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
49089dc44ceSjose borrego winreg_subkey_t *key;
49189dc44ceSjose borrego char *subkey;
49289dc44ceSjose borrego
49389dc44ceSjose borrego subkey = (char *)param->subkey.str;
49489dc44ceSjose borrego
49589dc44ceSjose borrego if (!ndr_is_admin(mxa) || (subkey == NULL)) {
49689dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED;
49789dc44ceSjose borrego return (NDR_DRC_OK);
49889dc44ceSjose borrego }
49989dc44ceSjose borrego
5009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex);
5019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
50289dc44ceSjose borrego if ((ndr_hdlookup(mxa, id) == NULL) ||
50389dc44ceSjose borrego list_is_empty(&winreg_keylist.kl_list) ||
50489dc44ceSjose borrego winreg_key_has_subkey(subkey)) {
5059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
50689dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED;
50789dc44ceSjose borrego return (NDR_DRC_OK);
50889dc44ceSjose borrego }
50989dc44ceSjose borrego
51089dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list);
51189dc44ceSjose borrego do {
51289dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) {
51389dc44ceSjose borrego if (key->sk_predefined == B_TRUE) {
51489dc44ceSjose borrego /* Predefined keys cannot be deleted */
51589dc44ceSjose borrego break;
51689dc44ceSjose borrego }
51789dc44ceSjose borrego
51889dc44ceSjose borrego list_remove(&winreg_keylist.kl_list, key);
51989dc44ceSjose borrego --winreg_keylist.kl_count;
5209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States winreg_dealloc_id(mxa, &key->sk_handle);
52189dc44ceSjose borrego free(key);
5229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
5239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
52489dc44ceSjose borrego param->status = ERROR_SUCCESS;
52589dc44ceSjose borrego return (NDR_DRC_OK);
52689dc44ceSjose borrego }
52789dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL);
52889dc44ceSjose borrego
5299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
53089dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED;
53189dc44ceSjose borrego return (NDR_DRC_OK);
53289dc44ceSjose borrego }
53389dc44ceSjose borrego
5349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
5359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Call with the winreg_mutex held.
5369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */
53789dc44ceSjose borrego static boolean_t
winreg_key_has_subkey(const char * subkey)53889dc44ceSjose borrego winreg_key_has_subkey(const char *subkey)
53989dc44ceSjose borrego {
54089dc44ceSjose borrego winreg_subkey_t *key;
54189dc44ceSjose borrego int keylen;
54289dc44ceSjose borrego
54389dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list))
54489dc44ceSjose borrego return (B_FALSE);
54589dc44ceSjose borrego
54689dc44ceSjose borrego keylen = strlen(subkey);
54789dc44ceSjose borrego
54889dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list);
54989dc44ceSjose borrego do {
55089dc44ceSjose borrego if (strncasecmp(subkey, key->sk_name, keylen) == 0) {
55189dc44ceSjose borrego /*
55289dc44ceSjose borrego * Potential match. If sk_name is longer than
55389dc44ceSjose borrego * subkey, then sk_name is a subkey of our key.
55489dc44ceSjose borrego */
55589dc44ceSjose borrego if (keylen < strlen(key->sk_name))
55689dc44ceSjose borrego return (B_TRUE);
55789dc44ceSjose borrego }
55889dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL);
55989dc44ceSjose borrego
56089dc44ceSjose borrego return (B_FALSE);
56189dc44ceSjose borrego }
56289dc44ceSjose borrego
5639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
5649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Call with the winreg_mutex held.
5659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */
56689dc44ceSjose borrego static char *
winreg_enum_subkey(ndr_xa_t * mxa,const char * subkey,uint32_t index)5677f667e74Sjose borrego winreg_enum_subkey(ndr_xa_t *mxa, const char *subkey, uint32_t index)
56889dc44ceSjose borrego {
56989dc44ceSjose borrego winreg_subkey_t *key;
5707f667e74Sjose borrego char *entry;
5717f667e74Sjose borrego char *p;
5727f667e74Sjose borrego int subkeylen;
5737f667e74Sjose borrego int count = 0;
57489dc44ceSjose borrego
57589dc44ceSjose borrego if (subkey == NULL)
57689dc44ceSjose borrego return (NULL);
57789dc44ceSjose borrego
57889dc44ceSjose borrego if (list_is_empty(&winreg_keylist.kl_list))
57989dc44ceSjose borrego return (NULL);
58089dc44ceSjose borrego
5817f667e74Sjose borrego subkeylen = strlen(subkey);
5827f667e74Sjose borrego
5837f667e74Sjose borrego for (key = list_head(&winreg_keylist.kl_list);
5847f667e74Sjose borrego key != NULL; key = list_next(&winreg_keylist.kl_list, key)) {
5857f667e74Sjose borrego if (strncasecmp(subkey, key->sk_name, subkeylen) == 0) {
5867f667e74Sjose borrego p = key->sk_name + subkeylen;
5877f667e74Sjose borrego
5887f667e74Sjose borrego if ((*p != '\\') || (*p == '\0')) {
5897f667e74Sjose borrego /*
5907f667e74Sjose borrego * Not the same subkey or an exact match.
5917f667e74Sjose borrego * We're looking for children of subkey.
5927f667e74Sjose borrego */
5937f667e74Sjose borrego continue;
59489dc44ceSjose borrego }
5957f667e74Sjose borrego
5967f667e74Sjose borrego ++p;
5977f667e74Sjose borrego
5987f667e74Sjose borrego if (count < index) {
5997f667e74Sjose borrego ++count;
6007f667e74Sjose borrego continue;
6017f667e74Sjose borrego }
6027f667e74Sjose borrego
6037f667e74Sjose borrego if ((entry = NDR_STRDUP(mxa, p)) == NULL)
6047f667e74Sjose borrego return (NULL);
6057f667e74Sjose borrego
6067f667e74Sjose borrego if ((p = strchr(entry, '\\')) != NULL)
6077f667e74Sjose borrego *p = '\0';
6087f667e74Sjose borrego
6097f667e74Sjose borrego return (entry);
6107f667e74Sjose borrego }
6117f667e74Sjose borrego }
61289dc44ceSjose borrego
61389dc44ceSjose borrego return (NULL);
61489dc44ceSjose borrego }
61589dc44ceSjose borrego
61689dc44ceSjose borrego /*
61789dc44ceSjose borrego * winreg_s_DeleteValue
61889dc44ceSjose borrego */
61989dc44ceSjose borrego /*ARGSUSED*/
62089dc44ceSjose borrego static int
winreg_s_DeleteValue(void * arg,ndr_xa_t * mxa)62189dc44ceSjose borrego winreg_s_DeleteValue(void *arg, ndr_xa_t *mxa)
62289dc44ceSjose borrego {
62389dc44ceSjose borrego struct winreg_DeleteValue *param = arg;
62489dc44ceSjose borrego
62589dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED;
62689dc44ceSjose borrego return (NDR_DRC_OK);
62789dc44ceSjose borrego }
62889dc44ceSjose borrego
62989dc44ceSjose borrego /*
63089dc44ceSjose borrego * winreg_s_EnumKey
63189dc44ceSjose borrego */
63289dc44ceSjose borrego static int
winreg_s_EnumKey(void * arg,ndr_xa_t * mxa)63389dc44ceSjose borrego winreg_s_EnumKey(void *arg, ndr_xa_t *mxa)
63489dc44ceSjose borrego {
63589dc44ceSjose borrego struct winreg_EnumKey *param = arg;
63689dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
6377f667e74Sjose borrego ndr_handle_t *hd;
6387f667e74Sjose borrego char *subkey;
6397f667e74Sjose borrego char *name = NULL;
64089dc44ceSjose borrego
6419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex);
6429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
6437f667e74Sjose borrego if ((hd = ndr_hdlookup(mxa, id)) != NULL)
6447f667e74Sjose borrego name = hd->nh_data;
6457f667e74Sjose borrego
6467f667e74Sjose borrego if (hd == NULL || name == NULL) {
6479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
64889dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey));
64989dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS;
65089dc44ceSjose borrego return (NDR_DRC_OK);
65189dc44ceSjose borrego }
65289dc44ceSjose borrego
6537f667e74Sjose borrego subkey = winreg_enum_subkey(mxa, name, param->index);
6547f667e74Sjose borrego if (subkey == NULL) {
6559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
65689dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey));
65789dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS;
65889dc44ceSjose borrego return (NDR_DRC_OK);
65989dc44ceSjose borrego }
66089dc44ceSjose borrego
6617f667e74Sjose borrego if (NDR_MSTRING(mxa, subkey, (ndr_mstring_t *)¶m->name_out) == -1) {
6629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
66389dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumKey));
66489dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY;
66589dc44ceSjose borrego return (NDR_DRC_OK);
66689dc44ceSjose borrego }
6679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
6689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
6699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
6707f667e74Sjose borrego /*
6717f667e74Sjose borrego * This request requires that the length includes the null.
6727f667e74Sjose borrego */
6737f667e74Sjose borrego param->name_out.length = param->name_out.allosize;
67489dc44ceSjose borrego param->status = ERROR_SUCCESS;
67589dc44ceSjose borrego return (NDR_DRC_OK);
67689dc44ceSjose borrego }
67789dc44ceSjose borrego
67889dc44ceSjose borrego /*
67989dc44ceSjose borrego * winreg_s_EnumValue
68089dc44ceSjose borrego */
68189dc44ceSjose borrego static int
winreg_s_EnumValue(void * arg,ndr_xa_t * mxa)68289dc44ceSjose borrego winreg_s_EnumValue(void *arg, ndr_xa_t *mxa)
68389dc44ceSjose borrego {
68489dc44ceSjose borrego struct winreg_EnumValue *param = arg;
68589dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
68689dc44ceSjose borrego
68789dc44ceSjose borrego if (ndr_hdlookup(mxa, id) == NULL) {
68889dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumValue));
68989dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS;
69089dc44ceSjose borrego return (NDR_DRC_OK);
69189dc44ceSjose borrego }
69289dc44ceSjose borrego
69389dc44ceSjose borrego bzero(param, sizeof (struct winreg_EnumValue));
69489dc44ceSjose borrego param->status = ERROR_NO_MORE_ITEMS;
69589dc44ceSjose borrego return (NDR_DRC_OK);
69689dc44ceSjose borrego }
69789dc44ceSjose borrego
69889dc44ceSjose borrego /*
69989dc44ceSjose borrego * winreg_s_FlushKey
70089dc44ceSjose borrego *
70189dc44ceSjose borrego * Flush the attributes associated with the specified open key to disk.
70289dc44ceSjose borrego */
70389dc44ceSjose borrego static int
winreg_s_FlushKey(void * arg,ndr_xa_t * mxa)70489dc44ceSjose borrego winreg_s_FlushKey(void *arg, ndr_xa_t *mxa)
70589dc44ceSjose borrego {
70689dc44ceSjose borrego struct winreg_FlushKey *param = arg;
70789dc44ceSjose borrego ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
70889dc44ceSjose borrego
70989dc44ceSjose borrego if (ndr_hdlookup(mxa, id) == NULL)
71089dc44ceSjose borrego param->status = ERROR_INVALID_HANDLE;
71189dc44ceSjose borrego else
71289dc44ceSjose borrego param->status = ERROR_SUCCESS;
71389dc44ceSjose borrego
71489dc44ceSjose borrego return (NDR_DRC_OK);
71589dc44ceSjose borrego }
71689dc44ceSjose borrego
71789dc44ceSjose borrego /*
71889dc44ceSjose borrego * winreg_s_GetKeySec
71989dc44ceSjose borrego */
72089dc44ceSjose borrego static int
winreg_s_GetKeySec(void * arg,ndr_xa_t * mxa)72189dc44ceSjose borrego winreg_s_GetKeySec(void *arg, ndr_xa_t *mxa)
72289dc44ceSjose borrego {
72396a62adaSjoyce mcintosh static struct winreg_secdesc error_sd;
72489dc44ceSjose borrego struct winreg_GetKeySec *param = arg;
725f96bd5c8SAlan Wright struct winreg_value *sd_buf;
726f96bd5c8SAlan Wright smb_sd_t sd;
727f96bd5c8SAlan Wright uint32_t sd_len;
728f96bd5c8SAlan Wright uint32_t status;
72989dc44ceSjose borrego
730f96bd5c8SAlan Wright bzero(&sd, sizeof (smb_sd_t));
731f96bd5c8SAlan Wright
732f96bd5c8SAlan Wright if ((status = winreg_sd_format(&sd)) != ERROR_SUCCESS)
733f96bd5c8SAlan Wright goto winreg_getkeysec_error;
734f96bd5c8SAlan Wright
735f96bd5c8SAlan Wright sd_len = smb_sd_len(&sd, SMB_ALL_SECINFO);
73696a62adaSjoyce mcintosh sd_buf = NDR_MALLOC(mxa, sd_len + sizeof (struct winreg_value));
737f96bd5c8SAlan Wright
738f96bd5c8SAlan Wright param->sd = NDR_MALLOC(mxa, sizeof (struct winreg_secdesc));
73996a62adaSjoyce mcintosh if ((param->sd == NULL) || (sd_buf == NULL)) {
740f96bd5c8SAlan Wright status = ERROR_NOT_ENOUGH_MEMORY;
741f96bd5c8SAlan Wright goto winreg_getkeysec_error;
742f96bd5c8SAlan Wright }
743f96bd5c8SAlan Wright
744f96bd5c8SAlan Wright param->sd->sd_len = sd_len;
745f96bd5c8SAlan Wright param->sd->sd_size = sd_len;
746f96bd5c8SAlan Wright param->sd->sd_buf = sd_buf;
747f96bd5c8SAlan Wright
748f96bd5c8SAlan Wright sd_buf->vc_first_is = 0;
749f96bd5c8SAlan Wright sd_buf->vc_length_is = sd_len;
750f96bd5c8SAlan Wright param->status = srvsvc_sd_set_relative(&sd, sd_buf->value);
751f96bd5c8SAlan Wright
752f96bd5c8SAlan Wright smb_sd_term(&sd);
75389dc44ceSjose borrego return (NDR_DRC_OK);
754f96bd5c8SAlan Wright
755f96bd5c8SAlan Wright winreg_getkeysec_error:
756f96bd5c8SAlan Wright smb_sd_term(&sd);
757f96bd5c8SAlan Wright bzero(param, sizeof (struct winreg_GetKeySec));
75896a62adaSjoyce mcintosh param->sd = &error_sd;
759f96bd5c8SAlan Wright param->status = status;
760f96bd5c8SAlan Wright return (NDR_DRC_OK);
761f96bd5c8SAlan Wright }
762f96bd5c8SAlan Wright
763f96bd5c8SAlan Wright static uint32_t
winreg_sd_format(smb_sd_t * sd)764f96bd5c8SAlan Wright winreg_sd_format(smb_sd_t *sd)
765f96bd5c8SAlan Wright {
766f96bd5c8SAlan Wright smb_fssd_t fs_sd;
767f96bd5c8SAlan Wright acl_t *acl;
768f96bd5c8SAlan Wright uint32_t status = ERROR_SUCCESS;
769f96bd5c8SAlan Wright
770f96bd5c8SAlan Wright if (acl_fromtext("owner@:rwxpdDaARWcCos::allow", &acl) != 0)
771f96bd5c8SAlan Wright return (ERROR_NOT_ENOUGH_MEMORY);
772f96bd5c8SAlan Wright
773f96bd5c8SAlan Wright smb_fssd_init(&fs_sd, SMB_ALL_SECINFO, SMB_FSSD_FLAGS_DIR);
774f96bd5c8SAlan Wright fs_sd.sd_uid = 0;
775f96bd5c8SAlan Wright fs_sd.sd_gid = 0;
776f96bd5c8SAlan Wright fs_sd.sd_zdacl = acl;
777f96bd5c8SAlan Wright fs_sd.sd_zsacl = NULL;
778f96bd5c8SAlan Wright
779f96bd5c8SAlan Wright if (smb_sd_fromfs(&fs_sd, sd) != NT_STATUS_SUCCESS)
780f96bd5c8SAlan Wright status = ERROR_ACCESS_DENIED;
781f96bd5c8SAlan Wright smb_fssd_term(&fs_sd);
782f96bd5c8SAlan Wright return (status);
78389dc44ceSjose borrego }
78489dc44ceSjose borrego
78589dc44ceSjose borrego /*
78689dc44ceSjose borrego * winreg_s_NotifyChange
78789dc44ceSjose borrego */
78889dc44ceSjose borrego static int
winreg_s_NotifyChange(void * arg,ndr_xa_t * mxa)78989dc44ceSjose borrego winreg_s_NotifyChange(void *arg, ndr_xa_t *mxa)
79089dc44ceSjose borrego {
79189dc44ceSjose borrego struct winreg_NotifyChange *param = arg;
79289dc44ceSjose borrego
79389dc44ceSjose borrego if (ndr_is_admin(mxa))
79489dc44ceSjose borrego param->status = ERROR_SUCCESS;
79589dc44ceSjose borrego else
79689dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED;
79789dc44ceSjose borrego
79889dc44ceSjose borrego return (NDR_DRC_OK);
79989dc44ceSjose borrego }
80089dc44ceSjose borrego
80189dc44ceSjose borrego /*
80289dc44ceSjose borrego * winreg_s_OpenKey
80389dc44ceSjose borrego *
80489dc44ceSjose borrego * This is a request to open a windows registry key.
80589dc44ceSjose borrego * If we recognize the key, we return a handle.
80689dc44ceSjose borrego *
80789dc44ceSjose borrego * Returns:
80889dc44ceSjose borrego * ERROR_SUCCESS Valid handle returned.
80989dc44ceSjose borrego * ERROR_FILE_NOT_FOUND No key or unable to allocate a handle.
81089dc44ceSjose borrego */
81189dc44ceSjose borrego static int
winreg_s_OpenKey(void * arg,ndr_xa_t * mxa)81289dc44ceSjose borrego winreg_s_OpenKey(void *arg, ndr_xa_t *mxa)
81389dc44ceSjose borrego {
81489dc44ceSjose borrego struct winreg_OpenKey *param = arg;
815b1352070SAlan Wright ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
816b1352070SAlan Wright ndr_handle_t *hd;
81789dc44ceSjose borrego char *subkey = (char *)param->name.str;
81889dc44ceSjose borrego winreg_subkey_t *key;
8199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
8209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&winreg_mutex);
82189dc44ceSjose borrego
822b1352070SAlan Wright if (subkey == NULL || *subkey == '\0') {
823b1352070SAlan Wright if ((hd = ndr_hdlookup(mxa, id)) != NULL)
824b1352070SAlan Wright subkey = hd->nh_data;
825b1352070SAlan Wright }
826b1352070SAlan Wright
827b1352070SAlan Wright id = NULL;
828b1352070SAlan Wright
8297f667e74Sjose borrego if (subkey == NULL || list_is_empty(&winreg_keylist.kl_list)) {
8309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
83189dc44ceSjose borrego bzero(¶m->result_handle, sizeof (winreg_handle_t));
83289dc44ceSjose borrego param->status = ERROR_FILE_NOT_FOUND;
83389dc44ceSjose borrego return (NDR_DRC_OK);
83489dc44ceSjose borrego }
83589dc44ceSjose borrego
83689dc44ceSjose borrego key = list_head(&winreg_keylist.kl_list);
83789dc44ceSjose borrego do {
83889dc44ceSjose borrego if (strcasecmp(subkey, key->sk_name) == 0) {
8399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (key->sk_predefined == B_TRUE)
8409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States id = winreg_alloc_id(mxa, subkey);
8419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States else
84289dc44ceSjose borrego id = &key->sk_handle;
84389dc44ceSjose borrego
84489dc44ceSjose borrego if (id == NULL)
84589dc44ceSjose borrego break;
84689dc44ceSjose borrego
84789dc44ceSjose borrego bcopy(id, ¶m->result_handle,
84889dc44ceSjose borrego sizeof (winreg_handle_t));
8499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
8509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
85189dc44ceSjose borrego param->status = ERROR_SUCCESS;
85289dc44ceSjose borrego return (NDR_DRC_OK);
85389dc44ceSjose borrego }
85489dc44ceSjose borrego } while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL);
85589dc44ceSjose borrego
8569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&winreg_mutex);
85789dc44ceSjose borrego bzero(¶m->result_handle, sizeof (winreg_handle_t));
85889dc44ceSjose borrego param->status = ERROR_FILE_NOT_FOUND;
85989dc44ceSjose borrego return (NDR_DRC_OK);
86089dc44ceSjose borrego }
86189dc44ceSjose borrego
86289dc44ceSjose borrego /*
86389dc44ceSjose borrego * winreg_s_QueryKey
86489dc44ceSjose borrego */
86589dc44ceSjose borrego /*ARGSUSED*/
86689dc44ceSjose borrego static int
winreg_s_QueryKey(void * arg,ndr_xa_t * mxa)86789dc44ceSjose borrego winreg_s_QueryKey(void *arg, ndr_xa_t *mxa)
86889dc44ceSjose borrego {
86989dc44ceSjose borrego struct winreg_QueryKey *param = arg;
87089dc44ceSjose borrego int rc;
87189dc44ceSjose borrego winreg_string_t *name;
87289dc44ceSjose borrego
87389dc44ceSjose borrego name = (winreg_string_t *)¶m->name;
87489dc44ceSjose borrego bzero(param, sizeof (struct winreg_QueryKey));
8759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
87689dc44ceSjose borrego if ((name = NDR_NEW(mxa, winreg_string_t)) != NULL)
87789dc44ceSjose borrego rc = NDR_MSTRING(mxa, "", (ndr_mstring_t *)name);
87889dc44ceSjose borrego
87989dc44ceSjose borrego if ((name == NULL) || (rc != 0)) {
88089dc44ceSjose borrego bzero(param, sizeof (struct winreg_QueryKey));
88189dc44ceSjose borrego param->status = ERROR_NOT_ENOUGH_MEMORY;
88289dc44ceSjose borrego return (NDR_DRC_OK);
88389dc44ceSjose borrego }
88489dc44ceSjose borrego
88589dc44ceSjose borrego param->status = ERROR_SUCCESS;
88689dc44ceSjose borrego return (NDR_DRC_OK);
88789dc44ceSjose borrego }
88889dc44ceSjose borrego
88989dc44ceSjose borrego /*
89089dc44ceSjose borrego * winreg_s_QueryValue
89189dc44ceSjose borrego *
89289dc44ceSjose borrego * This is a request to get the value associated with a specified name.
89389dc44ceSjose borrego *
89489dc44ceSjose borrego * Returns:
89589dc44ceSjose borrego * ERROR_SUCCESS Value returned.
89689dc44ceSjose borrego * ERROR_FILE_NOT_FOUND PrimaryModule is not supported.
89789dc44ceSjose borrego * ERROR_CANTREAD No such name or memory problem.
89889dc44ceSjose borrego */
89989dc44ceSjose borrego static int
winreg_s_QueryValue(void * arg,ndr_xa_t * mxa)90089dc44ceSjose borrego winreg_s_QueryValue(void *arg, ndr_xa_t *mxa)
90189dc44ceSjose borrego {
90289dc44ceSjose borrego struct winreg_QueryValue *param = arg;
90389dc44ceSjose borrego struct winreg_value *pv;
90489dc44ceSjose borrego char *name;
90589dc44ceSjose borrego char *value;
90689dc44ceSjose borrego DWORD slen;
90789dc44ceSjose borrego DWORD msize;
90889dc44ceSjose borrego
90989dc44ceSjose borrego name = (char *)param->value_name.str;
91089dc44ceSjose borrego
911*5831d79bSGordon Ross if (name == NULL ||
912*5831d79bSGordon Ross strcasecmp(name, "PrimaryModule") == 0) {
91389dc44ceSjose borrego param->status = ERROR_FILE_NOT_FOUND;
91489dc44ceSjose borrego return (NDR_DRC_OK);
91589dc44ceSjose borrego }
91689dc44ceSjose borrego
91789dc44ceSjose borrego if ((value = winreg_lookup_value(name)) == NULL) {
91889dc44ceSjose borrego param->status = ERROR_CANTREAD;
91989dc44ceSjose borrego return (NDR_DRC_OK);
92089dc44ceSjose borrego }
92189dc44ceSjose borrego
922bbf6f00cSJordan Brown slen = smb_wcequiv_strlen(value) + sizeof (smb_wchar_t);
92389dc44ceSjose borrego msize = sizeof (struct winreg_value) + slen;
92489dc44ceSjose borrego
92589dc44ceSjose borrego param->value = (struct winreg_value *)NDR_MALLOC(mxa, msize);
92689dc44ceSjose borrego param->type = NDR_NEW(mxa, DWORD);
92789dc44ceSjose borrego param->value_size = NDR_NEW(mxa, DWORD);
92889dc44ceSjose borrego param->value_size_total = NDR_NEW(mxa, DWORD);
92989dc44ceSjose borrego
93089dc44ceSjose borrego if (param->value == NULL || param->type == NULL ||
93189dc44ceSjose borrego param->value_size == NULL || param->value_size_total == NULL) {
93289dc44ceSjose borrego param->status = ERROR_CANTREAD;
93389dc44ceSjose borrego return (NDR_DRC_OK);
93489dc44ceSjose borrego }
93589dc44ceSjose borrego
93689dc44ceSjose borrego bzero(param->value, msize);
93789dc44ceSjose borrego pv = param->value;
93889dc44ceSjose borrego pv->vc_first_is = 0;
93989dc44ceSjose borrego pv->vc_length_is = slen;
94089dc44ceSjose borrego /*LINTED E_BAD_PTR_CAST_ALIGN*/
941bbf6f00cSJordan Brown (void) ndr_mbstowcs(NULL, (smb_wchar_t *)pv->value, value, slen);
94289dc44ceSjose borrego
94389dc44ceSjose borrego *param->type = 1;
94489dc44ceSjose borrego *param->value_size = slen;
94589dc44ceSjose borrego *param->value_size_total = slen;
94689dc44ceSjose borrego
94789dc44ceSjose borrego param->status = ERROR_SUCCESS;
94889dc44ceSjose borrego return (NDR_DRC_OK);
94989dc44ceSjose borrego }
95089dc44ceSjose borrego
95189dc44ceSjose borrego /*
95289dc44ceSjose borrego * Lookup a name in the registry and return the associated value.
95389dc44ceSjose borrego * Our registry is a case-insensitive, name-value pair table.
95489dc44ceSjose borrego *
95589dc44ceSjose borrego * Windows ProductType: WinNT, ServerNT, LanmanNT.
95689dc44ceSjose borrego * Windows NT4.0 workstation: WinNT
95789dc44ceSjose borrego * Windows NT4.0 server: ServerNT
95889dc44ceSjose borrego *
95989dc44ceSjose borrego * If LanmanNT is used here, Windows 2000 sends LsarQueryInfoPolicy
96089dc44ceSjose borrego * with info level 6, which we don't support. If we use ServerNT
96189dc44ceSjose borrego * (as reported by NT4.0 Server) Windows 2000 send requests for
96289dc44ceSjose borrego * levels 3 and 5, which are support.
96389dc44ceSjose borrego *
96489dc44ceSjose borrego * On success, returns a pointer to the value. Otherwise returns
96589dc44ceSjose borrego * a null pointer.
96689dc44ceSjose borrego */
96789dc44ceSjose borrego static char *
winreg_lookup_value(const char * name)96889dc44ceSjose borrego winreg_lookup_value(const char *name)
96989dc44ceSjose borrego {
97089dc44ceSjose borrego static struct registry {
97189dc44ceSjose borrego char *name;
97289dc44ceSjose borrego char *value;
97389dc44ceSjose borrego } registry[] = {
9749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { "SystemRoot", "C:\\" },
9759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { "CurrentVersion", winreg_sysver },
97689dc44ceSjose borrego { "ProductType", "ServerNT" },
9779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { "Sources", winreg_sysname }, /* product name */
9789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { "EventMessageFile", "C:\\windows\\system32\\eventlog.dll" }
97989dc44ceSjose borrego };
98089dc44ceSjose borrego
98189dc44ceSjose borrego int i;
98289dc44ceSjose borrego
98389dc44ceSjose borrego for (i = 0; i < sizeof (registry)/sizeof (registry[0]); ++i) {
9849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (strcasecmp(registry[i].name, name) == 0)
98589dc44ceSjose borrego return (registry[i].value);
98689dc44ceSjose borrego }
98789dc44ceSjose borrego
98889dc44ceSjose borrego return (NULL);
98989dc44ceSjose borrego }
99089dc44ceSjose borrego
99189dc44ceSjose borrego /*
99289dc44ceSjose borrego * winreg_s_SetKeySec
99389dc44ceSjose borrego */
99489dc44ceSjose borrego /*ARGSUSED*/
99589dc44ceSjose borrego static int
winreg_s_SetKeySec(void * arg,ndr_xa_t * mxa)99689dc44ceSjose borrego winreg_s_SetKeySec(void *arg, ndr_xa_t *mxa)
99789dc44ceSjose borrego {
99889dc44ceSjose borrego struct winreg_SetKeySec *param = arg;
99989dc44ceSjose borrego
100089dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED;
100189dc44ceSjose borrego return (NDR_DRC_OK);
100289dc44ceSjose borrego }
100389dc44ceSjose borrego
100489dc44ceSjose borrego /*
100589dc44ceSjose borrego * winreg_s_CreateValue
100689dc44ceSjose borrego */
100789dc44ceSjose borrego /*ARGSUSED*/
100889dc44ceSjose borrego static int
winreg_s_CreateValue(void * arg,ndr_xa_t * mxa)100989dc44ceSjose borrego winreg_s_CreateValue(void *arg, ndr_xa_t *mxa)
101089dc44ceSjose borrego {
101189dc44ceSjose borrego struct winreg_CreateValue *param = arg;
101289dc44ceSjose borrego
101389dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED;
101489dc44ceSjose borrego return (NDR_DRC_OK);
101589dc44ceSjose borrego }
101689dc44ceSjose borrego
101789dc44ceSjose borrego /*
101889dc44ceSjose borrego * winreg_s_Shutdown
101989dc44ceSjose borrego *
102089dc44ceSjose borrego * Attempt to shutdown or reboot the system: access denied.
102189dc44ceSjose borrego */
102289dc44ceSjose borrego /*ARGSUSED*/
102389dc44ceSjose borrego static int
winreg_s_Shutdown(void * arg,ndr_xa_t * mxa)102489dc44ceSjose borrego winreg_s_Shutdown(void *arg, ndr_xa_t *mxa)
102589dc44ceSjose borrego {
102689dc44ceSjose borrego struct winreg_Shutdown *param = arg;
102789dc44ceSjose borrego
102889dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED;
102989dc44ceSjose borrego return (NDR_DRC_OK);
103089dc44ceSjose borrego }
103189dc44ceSjose borrego
103289dc44ceSjose borrego /*
103389dc44ceSjose borrego * winreg_s_AbortShutdown
103489dc44ceSjose borrego *
103589dc44ceSjose borrego * Abort a shutdown request.
103689dc44ceSjose borrego */
103789dc44ceSjose borrego static int
winreg_s_AbortShutdown(void * arg,ndr_xa_t * mxa)103889dc44ceSjose borrego winreg_s_AbortShutdown(void *arg, ndr_xa_t *mxa)
103989dc44ceSjose borrego {
104089dc44ceSjose borrego struct winreg_AbortShutdown *param = arg;
104189dc44ceSjose borrego
104289dc44ceSjose borrego if (ndr_is_admin(mxa))
104389dc44ceSjose borrego param->status = ERROR_SUCCESS;
104489dc44ceSjose borrego else
104589dc44ceSjose borrego param->status = ERROR_ACCESS_DENIED;
104689dc44ceSjose borrego
104789dc44ceSjose borrego return (NDR_DRC_OK);
104889dc44ceSjose borrego }
104989dc44ceSjose borrego
105089dc44ceSjose borrego /*
105189dc44ceSjose borrego * winreg_s_GetVersion
105289dc44ceSjose borrego *
105389dc44ceSjose borrego * Return the windows registry version. The current version is 5.
105489dc44ceSjose borrego * This call is usually made prior to enumerating or querying registry
105589dc44ceSjose borrego * keys or values.
105689dc44ceSjose borrego */
105789dc44ceSjose borrego /*ARGSUSED*/
105889dc44ceSjose borrego static int
winreg_s_GetVersion(void * arg,ndr_xa_t * mxa)105989dc44ceSjose borrego winreg_s_GetVersion(void *arg, ndr_xa_t *mxa)
106089dc44ceSjose borrego {
106189dc44ceSjose borrego struct winreg_GetVersion *param = arg;
106289dc44ceSjose borrego
106389dc44ceSjose borrego param->version = 5;
106489dc44ceSjose borrego param->status = ERROR_SUCCESS;
106589dc44ceSjose borrego return (NDR_DRC_OK);
106689dc44ceSjose borrego }
1067