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  */
21*148c5f43SAlan Wright 
2289dc44ceSjose borrego /*
23*148c5f43SAlan Wright  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2489dc44ceSjose borrego  */
2589dc44ceSjose borrego 
2689dc44ceSjose borrego /*
2789dc44ceSjose borrego  * Windows Registry RPC (WINREG) server-side interface.
2889dc44ceSjose borrego  *
297f667e74Sjose borrego  * The registry is a database with a hierarchical structure similar to
307f667e74Sjose borrego  * a file system, with keys in place of directories and values in place
317f667e74Sjose borrego  * of files.  The top level keys are known as root keys and each key can
327f667e74Sjose borrego  * contain subkeys and values.  As with directories and sub-directories,
337f667e74Sjose borrego  * the terms key and subkey are used interchangeably.  Values, analogous
347f667e74Sjose borrego  * to files, contain data.
3589dc44ceSjose borrego  *
367f667e74Sjose borrego  * A specific subkey can be identifies by its fully qualified name (FQN),
377f667e74Sjose borrego  * which is analogous to a file system path.  In the registry, the key
387f667e74Sjose borrego  * separator is the '\' character, which is reserved and cannot appear
397f667e74Sjose borrego  * in key or value names.  Registry names are case-insensitive.
407f667e74Sjose borrego  *
417f667e74Sjose borrego  * For example:  HKEY_LOCAL_MACHINE\System\CurrentControlSet
427f667e74Sjose borrego  *
43b1352070SAlan Wright  * The HKEY_LOCAL_MACHINE root key contains a subkey called System, and
447f667e74Sjose borrego  * System contains a subkey called CurrentControlSet.
457f667e74Sjose borrego  *
467f667e74Sjose borrego  * The WINREG RPC interface returns Win32 error codes.
4789dc44ceSjose borrego  */
4889dc44ceSjose borrego 
4989dc44ceSjose borrego #include <sys/utsname.h>
5089dc44ceSjose borrego #include <strings.h>
5189dc44ceSjose borrego 
5289dc44ceSjose borrego #include <smbsrv/libsmb.h>
5389dc44ceSjose borrego #include <smbsrv/nmpipes.h>
5489dc44ceSjose borrego #include <smbsrv/libmlsvc.h>
5589dc44ceSjose borrego #include <smbsrv/ndl/winreg.ndl>
5689dc44ceSjose borrego 
5789dc44ceSjose borrego /*
5889dc44ceSjose borrego  * List of supported registry keys (case-insensitive).
5989dc44ceSjose borrego  */
6089dc44ceSjose borrego static char *winreg_keys[] = {
61b1352070SAlan Wright 	"HKLM",
62b1352070SAlan Wright 	"HKU",
63b1352070SAlan Wright 	"HKLM\\SOFTWARE",
64b1352070SAlan Wright 	"HKLM\\SYSTEM",
65b1352070SAlan Wright 	"System",
66b1352070SAlan Wright 	"CurrentControlSet",
679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	"SunOS",
689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	"Solaris",
6989dc44ceSjose borrego 	"System\\CurrentControlSet\\Services\\Eventlog",
7089dc44ceSjose borrego 	"System\\CurrentControlSet\\Control\\ProductOptions",
71b1352070SAlan Wright 	"SOFTWARE",
7289dc44ceSjose borrego 	"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
7389dc44ceSjose borrego };
7489dc44ceSjose borrego 
75*148c5f43SAlan Wright static char *winreg_eventlog = "System\\CurrentControlSet\\Services\\Eventlog";
76*148c5f43SAlan Wright 
77*148c5f43SAlan Wright static char *winreg_log[] = {
78*148c5f43SAlan Wright 	"Application",
79*148c5f43SAlan Wright 	"Security",
80*148c5f43SAlan Wright 	"System",
81*148c5f43SAlan Wright 	"smbd",
82*148c5f43SAlan Wright 	"smbrdr"
83*148c5f43SAlan Wright };
84*148c5f43SAlan Wright 
8589dc44ceSjose borrego typedef struct winreg_subkey {
8689dc44ceSjose borrego 	list_node_t sk_lnd;
8789dc44ceSjose borrego 	ndr_hdid_t sk_handle;
8889dc44ceSjose borrego 	char sk_name[MAXPATHLEN];
8989dc44ceSjose borrego 	boolean_t sk_predefined;
9089dc44ceSjose borrego } winreg_subkey_t;
9189dc44ceSjose borrego 
9289dc44ceSjose borrego typedef struct winreg_keylist {
9389dc44ceSjose borrego 	list_t kl_list;
9489dc44ceSjose borrego 	int kl_count;
9589dc44ceSjose borrego } winreg_keylist_t;
9689dc44ceSjose borrego 
9789dc44ceSjose borrego static winreg_keylist_t winreg_keylist;
989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static mutex_t winreg_mutex;
9989dc44ceSjose borrego 
100*148c5f43SAlan Wright static void winreg_add_predefined(const char *);
1019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static ndr_hdid_t *winreg_alloc_id(ndr_xa_t *, const char *);
1029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void winreg_dealloc_id(ndr_xa_t *, ndr_hdid_t *);
10389dc44ceSjose borrego static boolean_t winreg_key_has_subkey(const char *);
1047f667e74Sjose borrego static char *winreg_enum_subkey(ndr_xa_t *, const char *, uint32_t);
10589dc44ceSjose borrego static char *winreg_lookup_value(const char *);
106f96bd5c8SAlan Wright static uint32_t winreg_sd_format(smb_sd_t *);
107f96bd5c8SAlan Wright uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *);
10889dc44ceSjose borrego 
1097f667e74Sjose borrego static int winreg_s_OpenHKCR(void *, ndr_xa_t *);
1107f667e74Sjose borrego static int winreg_s_OpenHKCU(void *, ndr_xa_t *);
11189dc44ceSjose borrego static int winreg_s_OpenHKLM(void *, ndr_xa_t *);
1127f667e74Sjose borrego static int winreg_s_OpenHKPD(void *, ndr_xa_t *);
1137f667e74Sjose borrego static int winreg_s_OpenHKU(void *, ndr_xa_t *);
1147f667e74Sjose borrego static int winreg_s_OpenHKCC(void *, ndr_xa_t *);
1157f667e74Sjose borrego static int winreg_s_OpenHKDD(void *, ndr_xa_t *);
1167f667e74Sjose borrego static int winreg_s_OpenHKPT(void *, ndr_xa_t *);
1177f667e74Sjose borrego static int winreg_s_OpenHKPN(void *, ndr_xa_t *);
1187f667e74Sjose borrego static int winreg_s_OpenHK(void *, ndr_xa_t *, const char *);
11989dc44ceSjose borrego static int winreg_s_Close(void *, ndr_xa_t *);
12089dc44ceSjose borrego static int winreg_s_CreateKey(void *, ndr_xa_t *);
12189dc44ceSjose borrego static int winreg_s_DeleteKey(void *, ndr_xa_t *);
12289dc44ceSjose borrego static int winreg_s_DeleteValue(void *, ndr_xa_t *);
12389dc44ceSjose borrego static int winreg_s_EnumKey(void *, ndr_xa_t *);
12489dc44ceSjose borrego static int winreg_s_EnumValue(void *, ndr_xa_t *);
12589dc44ceSjose borrego static int winreg_s_FlushKey(void *, ndr_xa_t *);
12689dc44ceSjose borrego static int winreg_s_GetKeySec(void *, ndr_xa_t *);
12789dc44ceSjose borrego static int winreg_s_NotifyChange(void *, ndr_xa_t *);
12889dc44ceSjose borrego static int winreg_s_OpenKey(void *, ndr_xa_t *);
12989dc44ceSjose borrego static int winreg_s_QueryKey(void *, ndr_xa_t *);
13089dc44ceSjose borrego static int winreg_s_QueryValue(void *, ndr_xa_t *);
13189dc44ceSjose borrego static int winreg_s_SetKeySec(void *, ndr_xa_t *);
13289dc44ceSjose borrego static int winreg_s_CreateValue(void *, ndr_xa_t *);
13389dc44ceSjose borrego static int winreg_s_Shutdown(void *, ndr_xa_t *);
13489dc44ceSjose borrego static int winreg_s_AbortShutdown(void *, ndr_xa_t *);
13589dc44ceSjose borrego static int winreg_s_GetVersion(void *, ndr_xa_t *);
13689dc44ceSjose borrego 
13789dc44ceSjose borrego static ndr_stub_table_t winreg_stub_table[] = {
1387f667e74Sjose borrego 	{ winreg_s_OpenHKCR,	WINREG_OPNUM_OpenHKCR },
1397f667e74Sjose borrego 	{ winreg_s_OpenHKCU,	WINREG_OPNUM_OpenHKCU },
14089dc44ceSjose borrego 	{ winreg_s_OpenHKLM,	WINREG_OPNUM_OpenHKLM },
1417f667e74Sjose borrego 	{ winreg_s_OpenHKPD,	WINREG_OPNUM_OpenHKPD },
1427f667e74Sjose borrego 	{ winreg_s_OpenHKU,	WINREG_OPNUM_OpenHKUsers },
14389dc44ceSjose borrego 	{ winreg_s_Close,	WINREG_OPNUM_Close },
14489dc44ceSjose borrego 	{ winreg_s_CreateKey,	WINREG_OPNUM_CreateKey },
14589dc44ceSjose borrego 	{ winreg_s_DeleteKey,	WINREG_OPNUM_DeleteKey },
14689dc44ceSjose borrego 	{ winreg_s_DeleteValue,	WINREG_OPNUM_DeleteValue },
14789dc44ceSjose borrego 	{ winreg_s_EnumKey,	WINREG_OPNUM_EnumKey },
14889dc44ceSjose borrego 	{ winreg_s_EnumValue,	WINREG_OPNUM_EnumValue },
14989dc44ceSjose borrego 	{ winreg_s_FlushKey,	WINREG_OPNUM_FlushKey },
15089dc44ceSjose borrego 	{ winreg_s_GetKeySec,	WINREG_OPNUM_GetKeySec },
15189dc44ceSjose borrego 	{ winreg_s_NotifyChange,	WINREG_OPNUM_NotifyChange },
15289dc44ceSjose borrego 	{ winreg_s_OpenKey,	WINREG_OPNUM_OpenKey },
15389dc44ceSjose borrego 	{ winreg_s_QueryKey,	WINREG_OPNUM_QueryKey },
15489dc44ceSjose borrego 	{ winreg_s_QueryValue,	WINREG_OPNUM_QueryValue },
15589dc44ceSjose borrego 	{ winreg_s_SetKeySec,	WINREG_OPNUM_SetKeySec },
15689dc44ceSjose borrego 	{ winreg_s_CreateValue,	WINREG_OPNUM_CreateValue },
15789dc44ceSjose borrego 	{ winreg_s_Shutdown,	WINREG_OPNUM_Shutdown },
15889dc44ceSjose borrego 	{ winreg_s_AbortShutdown,	WINREG_OPNUM_AbortShutdown },
15989dc44ceSjose borrego 	{ winreg_s_GetVersion,	WINREG_OPNUM_GetVersion },
1607f667e74Sjose borrego 	{ winreg_s_OpenHKCC,	WINREG_OPNUM_OpenHKCC },
1617f667e74Sjose borrego 	{ winreg_s_OpenHKDD,	WINREG_OPNUM_OpenHKDD },
1627f667e74Sjose borrego 	{ winreg_s_OpenHKPT,	WINREG_OPNUM_OpenHKPT },
1637f667e74Sjose borrego 	{ winreg_s_OpenHKPN,	WINREG_OPNUM_OpenHKPN },
16489dc44ceSjose borrego 	{0}
16589dc44ceSjose borrego };
16689dc44ceSjose borrego 
16789dc44ceSjose borrego static ndr_service_t winreg_service = {
16889dc44ceSjose borrego 	"Winreg",			/* name */
16989dc44ceSjose borrego 	"Windows Registry",		/* desc */
17089dc44ceSjose borrego 	"\\winreg",			/* endpoint */
17189dc44ceSjose borrego 	PIPE_WINREG,			/* sec_addr_port */
17289dc44ceSjose borrego 	"338cd001-2244-31f1-aaaa-900038001003", 1,	/* abstract */
17389dc44ceSjose borrego 	NDR_TRANSFER_SYNTAX_UUID,		2,	/* transfer */
17489dc44ceSjose borrego 	0,				/* no bind_instance_size */
17589dc44ceSjose borrego 	0,				/* no bind_req() */
17689dc44ceSjose borrego 	0,				/* no unbind_and_close() */
17789dc44ceSjose borrego 	0,				/* use generic_call_stub() */
17889dc44ceSjose borrego 	&TYPEINFO(winreg_interface),	/* interface ti */
17989dc44ceSjose borrego 	winreg_stub_table		/* stub_table */
18089dc44ceSjose borrego };
18189dc44ceSjose borrego 
18289dc44ceSjose borrego static char winreg_sysname[SYS_NMLN];
1839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static char winreg_sysver[SMB_VERSTR_LEN];
18489dc44ceSjose borrego 
18589dc44ceSjose borrego /*
18689dc44ceSjose borrego  * winreg_initialize
18789dc44ceSjose borrego  *
18889dc44ceSjose borrego  * Initialize and register the WINREG RPC interface with the RPC runtime
18989dc44ceSjose borrego  * library. It must be called in order to use either the client side
19089dc44ceSjose borrego  * or the server side functions.
19189dc44ceSjose borrego  */
19289dc44ceSjose borrego void
19389dc44ceSjose borrego winreg_initialize(void)
19489dc44ceSjose borrego {
1959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_version_t version;
19689dc44ceSjose borrego 	struct utsname name;
197*148c5f43SAlan Wright 	char subkey[MAXPATHLEN];
19889dc44ceSjose borrego 	char *sysname;
19989dc44ceSjose borrego 	int i;
20089dc44ceSjose borrego 
2019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&winreg_mutex);
2029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20389dc44ceSjose borrego 	list_create(&winreg_keylist.kl_list, sizeof (winreg_subkey_t),
20489dc44ceSjose borrego 	    offsetof(winreg_subkey_t, sk_lnd));
20589dc44ceSjose borrego 	winreg_keylist.kl_count = 0;
20689dc44ceSjose borrego 
207*148c5f43SAlan Wright 	for (i = 0; i < sizeof (winreg_keys)/sizeof (winreg_keys[0]); ++i)
208*148c5f43SAlan Wright 		winreg_add_predefined(winreg_keys[i]);
2099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
210*148c5f43SAlan Wright 	for (i = 0; i < sizeof (winreg_log)/sizeof (winreg_log[0]); ++i) {
211*148c5f43SAlan Wright 		(void) snprintf(subkey, MAXPATHLEN, "%s", winreg_log[i]);
212*148c5f43SAlan Wright 		winreg_add_predefined(subkey);
213*148c5f43SAlan Wright 
214*148c5f43SAlan Wright 		(void) snprintf(subkey, MAXPATHLEN, "%s\\%s",
215*148c5f43SAlan Wright 		    winreg_eventlog, winreg_log[i]);
216*148c5f43SAlan Wright 		winreg_add_predefined(subkey);
217*148c5f43SAlan Wright 
218*148c5f43SAlan Wright 		(void) snprintf(subkey, MAXPATHLEN, "%s\\%s\\%s",
219*148c5f43SAlan Wright 		    winreg_eventlog, winreg_log[i], winreg_log[i]);
220*148c5f43SAlan Wright 		winreg_add_predefined(subkey);
22189dc44ceSjose borrego 	}
22289dc44ceSjose borrego 
2239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&winreg_mutex);
2249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
22589dc44ceSjose borrego 	if (uname(&name) < 0)
22689dc44ceSjose borrego 		sysname = "Solaris";
22789dc44ceSjose borrego 	else
22889dc44ceSjose borrego 		sysname = name.sysname;
22989dc44ceSjose borrego 
23089dc44ceSjose borrego 	(void) strlcpy(winreg_sysname, sysname, SYS_NMLN);
2319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_config_get_version(&version);
2339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) snprintf(winreg_sysver, SMB_VERSTR_LEN, "%d.%d",
2349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    version.sv_major, version.sv_minor);
2359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
23689dc44ceSjose borrego 	(void) ndr_svc_register(&winreg_service);
23789dc44ceSjose borrego }
23889dc44ceSjose borrego 
239*148c5f43SAlan Wright static void
240*148c5f43SAlan Wright winreg_add_predefined(const char *subkey)
241*148c5f43SAlan Wright {
242*148c5f43SAlan Wright 	winreg_subkey_t *key;
243*148c5f43SAlan Wright 
244*148c5f43SAlan Wright 	if ((key = malloc(sizeof (winreg_subkey_t))) != NULL) {
245*148c5f43SAlan Wright 		bzero(key, sizeof (winreg_subkey_t));
246*148c5f43SAlan Wright 		(void) strlcpy(key->sk_name, subkey, MAXPATHLEN);
247*148c5f43SAlan Wright 		key->sk_predefined = B_TRUE;
248*148c5f43SAlan Wright 
249*148c5f43SAlan Wright 		list_insert_tail(&winreg_keylist.kl_list, key);
250*148c5f43SAlan Wright 		++winreg_keylist.kl_count;
251*148c5f43SAlan Wright 	}
252*148c5f43SAlan Wright }
253*148c5f43SAlan Wright 
25489dc44ceSjose borrego static int
2557f667e74Sjose borrego winreg_s_OpenHKCR(void *arg, ndr_xa_t *mxa)
25689dc44ceSjose borrego {
2577f667e74Sjose borrego 	return (winreg_s_OpenHK(arg, mxa, "HKCR"));
25889dc44ceSjose borrego }
25989dc44ceSjose borrego 
2607f667e74Sjose borrego static int
2617f667e74Sjose borrego winreg_s_OpenHKCU(void *arg, ndr_xa_t *mxa)
2627f667e74Sjose borrego {
2637f667e74Sjose borrego 	return (winreg_s_OpenHK(arg, mxa, "HKCU"));
26489dc44ceSjose borrego }
26589dc44ceSjose borrego 
26689dc44ceSjose borrego static int
26789dc44ceSjose borrego winreg_s_OpenHKLM(void *arg, ndr_xa_t *mxa)
26889dc44ceSjose borrego {
2697f667e74Sjose borrego 	return (winreg_s_OpenHK(arg, mxa, "HKLM"));
27089dc44ceSjose borrego }
27189dc44ceSjose borrego 
2727f667e74Sjose borrego static int
2737f667e74Sjose borrego winreg_s_OpenHKPD(void *arg, ndr_xa_t *mxa)
2747f667e74Sjose borrego {
2757f667e74Sjose borrego 	return (winreg_s_OpenHK(arg, mxa, "HKPD"));
2767f667e74Sjose borrego }
2777f667e74Sjose borrego 
2787f667e74Sjose borrego static int
2797f667e74Sjose borrego winreg_s_OpenHKU(void *arg, ndr_xa_t *mxa)
2807f667e74Sjose borrego {
2817f667e74Sjose borrego 	return (winreg_s_OpenHK(arg, mxa, "HKU"));
2827f667e74Sjose borrego }
2837f667e74Sjose borrego 
2847f667e74Sjose borrego static int
2857f667e74Sjose borrego winreg_s_OpenHKCC(void *arg, ndr_xa_t *mxa)
2867f667e74Sjose borrego {
2877f667e74Sjose borrego 	return (winreg_s_OpenHK(arg, mxa, "HKCC"));
2887f667e74Sjose borrego }
2897f667e74Sjose borrego 
2907f667e74Sjose borrego static int
2917f667e74Sjose borrego winreg_s_OpenHKDD(void *arg, ndr_xa_t *mxa)
2927f667e74Sjose borrego {
2937f667e74Sjose borrego 	return (winreg_s_OpenHK(arg, mxa, "HKDD"));
2947f667e74Sjose borrego }
2957f667e74Sjose borrego 
2967f667e74Sjose borrego static int
2977f667e74Sjose borrego winreg_s_OpenHKPT(void *arg, ndr_xa_t *mxa)
2987f667e74Sjose borrego {
2997f667e74Sjose borrego 	return (winreg_s_OpenHK(arg, mxa, "HKPT"));
3007f667e74Sjose borrego }
3017f667e74Sjose borrego 
3027f667e74Sjose borrego static int
3037f667e74Sjose borrego winreg_s_OpenHKPN(void *arg, ndr_xa_t *mxa)
3047f667e74Sjose borrego {
3057f667e74Sjose borrego 	return (winreg_s_OpenHK(arg, mxa, "HKPN"));
30689dc44ceSjose borrego }
30789dc44ceSjose borrego 
30889dc44ceSjose borrego /*
3097f667e74Sjose borrego  * winreg_s_OpenHK
31089dc44ceSjose borrego  *
3117f667e74Sjose borrego  * Common code to open root HKEYs.
31289dc44ceSjose borrego  */
31389dc44ceSjose borrego static int
3147f667e74Sjose borrego winreg_s_OpenHK(void *arg, ndr_xa_t *mxa, const char *hkey)
31589dc44ceSjose borrego {
3167f667e74Sjose borrego 	struct winreg_OpenHKCR *param = arg;
31789dc44ceSjose borrego 	ndr_hdid_t *id;
31889dc44ceSjose borrego 
3199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&winreg_mutex);
3207f667e74Sjose borrego 
3219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((id = winreg_alloc_id(mxa, hkey)) == NULL) {
32289dc44ceSjose borrego 		bzero(&param->handle, sizeof (winreg_handle_t));
32389dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
32489dc44ceSjose borrego 	} else {
32589dc44ceSjose borrego 		bcopy(id, &param->handle, sizeof (winreg_handle_t));
32689dc44ceSjose borrego 		param->status = ERROR_SUCCESS;
32789dc44ceSjose borrego 	}
32889dc44ceSjose borrego 
3299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&winreg_mutex);
33089dc44ceSjose borrego 	return (NDR_DRC_OK);
33189dc44ceSjose borrego }
33289dc44ceSjose borrego 
33389dc44ceSjose borrego /*
33489dc44ceSjose borrego  * winreg_s_Close
33589dc44ceSjose borrego  *
33689dc44ceSjose borrego  * This is a request to close the WINREG interface specified by the
33789dc44ceSjose borrego  * handle. We don't track handles (yet), so just zero out the handle
33889dc44ceSjose borrego  * and return NDR_DRC_OK. Setting the handle to zero appears to be
33989dc44ceSjose borrego  * standard behaviour.
34089dc44ceSjose borrego  */
34189dc44ceSjose borrego static int
34289dc44ceSjose borrego winreg_s_Close(void *arg, ndr_xa_t *mxa)
34389dc44ceSjose borrego {
34489dc44ceSjose borrego 	struct winreg_Close *param = arg;
34589dc44ceSjose borrego 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
3469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&winreg_mutex);
3489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	winreg_dealloc_id(mxa, id);
3499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&winreg_mutex);
3509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(&param->result_handle, sizeof (winreg_handle_t));
3529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	param->status = ERROR_SUCCESS;
3539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (NDR_DRC_OK);
3549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static ndr_hdid_t *
3579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States winreg_alloc_id(ndr_xa_t *mxa, const char *key)
3589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ndr_handle_t	*hd;
3609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ndr_hdid_t	*id;
3619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char		*data;
3629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((data = strdup(key)) == NULL)
3649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (NULL);
3659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((id = ndr_hdalloc(mxa, data)) == NULL) {
3679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(data);
3689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (NULL);
3699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((hd = ndr_hdlookup(mxa, id)) != NULL)
3729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		hd->nh_data_free = free;
3739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (id);
3759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
3789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States winreg_dealloc_id(ndr_xa_t *mxa, ndr_hdid_t *id)
3799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3807f667e74Sjose borrego 	ndr_handle_t *hd;
3817f667e74Sjose borrego 
3827f667e74Sjose borrego 	if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
3837f667e74Sjose borrego 		free(hd->nh_data);
3847f667e74Sjose borrego 		hd->nh_data = NULL;
3857f667e74Sjose borrego 	}
38689dc44ceSjose borrego 
38789dc44ceSjose borrego 	ndr_hdfree(mxa, id);
38889dc44ceSjose borrego }
38989dc44ceSjose borrego 
39089dc44ceSjose borrego /*
39189dc44ceSjose borrego  * winreg_s_CreateKey
39289dc44ceSjose borrego  */
39389dc44ceSjose borrego static int
39489dc44ceSjose borrego winreg_s_CreateKey(void *arg, ndr_xa_t *mxa)
39589dc44ceSjose borrego {
39689dc44ceSjose borrego 	struct winreg_CreateKey *param = arg;
39789dc44ceSjose borrego 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
39889dc44ceSjose borrego 	ndr_handle_t *hd;
39989dc44ceSjose borrego 	winreg_subkey_t *key;
40089dc44ceSjose borrego 	char *subkey;
40189dc44ceSjose borrego 	DWORD *action;
40289dc44ceSjose borrego 
40389dc44ceSjose borrego 	subkey = (char *)param->subkey.str;
40489dc44ceSjose borrego 
40589dc44ceSjose borrego 	if (!ndr_is_admin(mxa) || (subkey == NULL)) {
40689dc44ceSjose borrego 		bzero(param, sizeof (struct winreg_CreateKey));
40789dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
40889dc44ceSjose borrego 		return (NDR_DRC_OK);
40989dc44ceSjose borrego 	}
41089dc44ceSjose borrego 
4119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&winreg_mutex);
4129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
41389dc44ceSjose borrego 	hd = ndr_hdlookup(mxa, id);
41489dc44ceSjose borrego 	if (hd == NULL) {
4159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&winreg_mutex);
41689dc44ceSjose borrego 		bzero(param, sizeof (struct winreg_CreateKey));
41789dc44ceSjose borrego 		param->status = ERROR_INVALID_HANDLE;
41889dc44ceSjose borrego 		return (NDR_DRC_OK);
41989dc44ceSjose borrego 	}
42089dc44ceSjose borrego 
42189dc44ceSjose borrego 	if ((action = NDR_NEW(mxa, DWORD)) == NULL) {
4229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&winreg_mutex);
42389dc44ceSjose borrego 		bzero(param, sizeof (struct winreg_CreateKey));
42489dc44ceSjose borrego 		param->status = ERROR_NOT_ENOUGH_MEMORY;
42589dc44ceSjose borrego 		return (NDR_DRC_OK);
42689dc44ceSjose borrego 	}
42789dc44ceSjose borrego 
42889dc44ceSjose borrego 	if (list_is_empty(&winreg_keylist.kl_list))
42989dc44ceSjose borrego 		goto new_key;
43089dc44ceSjose borrego 
43189dc44ceSjose borrego 	/*
43289dc44ceSjose borrego 	 * Check for an existing key.
43389dc44ceSjose borrego 	 */
43489dc44ceSjose borrego 	key = list_head(&winreg_keylist.kl_list);
43589dc44ceSjose borrego 	do {
43689dc44ceSjose borrego 		if (strcasecmp(subkey, key->sk_name) == 0) {
43789dc44ceSjose borrego 			bcopy(&key->sk_handle, &param->result_handle,
43889dc44ceSjose borrego 			    sizeof (winreg_handle_t));
4399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			(void) mutex_unlock(&winreg_mutex);
44189dc44ceSjose borrego 			*action = WINREG_ACTION_EXISTING_KEY;
44289dc44ceSjose borrego 			param->action = action;
44389dc44ceSjose borrego 			param->status = ERROR_SUCCESS;
44489dc44ceSjose borrego 			return (NDR_DRC_OK);
44589dc44ceSjose borrego 		}
44689dc44ceSjose borrego 	} while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL);
44789dc44ceSjose borrego 
44889dc44ceSjose borrego new_key:
44989dc44ceSjose borrego 	/*
45089dc44ceSjose borrego 	 * Create a new key.
45189dc44ceSjose borrego 	 */
4529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((id = winreg_alloc_id(mxa, subkey)) == NULL)
4539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		goto no_memory;
4547f667e74Sjose borrego 
4559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((key = malloc(sizeof (winreg_subkey_t))) == NULL) {
4569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		winreg_dealloc_id(mxa, id);
4579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		goto no_memory;
45889dc44ceSjose borrego 	}
45989dc44ceSjose borrego 
46089dc44ceSjose borrego 	bcopy(id, &key->sk_handle, sizeof (ndr_hdid_t));
46189dc44ceSjose borrego 	(void) strlcpy(key->sk_name, subkey, MAXPATHLEN);
46289dc44ceSjose borrego 	key->sk_predefined = B_FALSE;
46389dc44ceSjose borrego 	list_insert_tail(&winreg_keylist.kl_list, key);
46489dc44ceSjose borrego 	++winreg_keylist.kl_count;
46589dc44ceSjose borrego 
46689dc44ceSjose borrego 	bcopy(id, &param->result_handle, sizeof (winreg_handle_t));
4679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&winreg_mutex);
46989dc44ceSjose borrego 	*action = WINREG_ACTION_NEW_KEY;
47089dc44ceSjose borrego 	param->action = action;
47189dc44ceSjose borrego 	param->status = ERROR_SUCCESS;
47289dc44ceSjose borrego 	return (NDR_DRC_OK);
4739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States no_memory:
4759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&winreg_mutex);
4769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(param, sizeof (struct winreg_CreateKey));
4779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	param->status = ERROR_NOT_ENOUGH_MEMORY;
4789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (NDR_DRC_OK);
47989dc44ceSjose borrego }
48089dc44ceSjose borrego 
48189dc44ceSjose borrego /*
48289dc44ceSjose borrego  * winreg_s_DeleteKey
48389dc44ceSjose borrego  */
48489dc44ceSjose borrego static int
48589dc44ceSjose borrego winreg_s_DeleteKey(void *arg, ndr_xa_t *mxa)
48689dc44ceSjose borrego {
48789dc44ceSjose borrego 	struct winreg_DeleteKey *param = arg;
48889dc44ceSjose borrego 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
48989dc44ceSjose borrego 	winreg_subkey_t *key;
49089dc44ceSjose borrego 	char *subkey;
49189dc44ceSjose borrego 
49289dc44ceSjose borrego 	subkey = (char *)param->subkey.str;
49389dc44ceSjose borrego 
49489dc44ceSjose borrego 	if (!ndr_is_admin(mxa) || (subkey == NULL)) {
49589dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
49689dc44ceSjose borrego 		return (NDR_DRC_OK);
49789dc44ceSjose borrego 	}
49889dc44ceSjose borrego 
4999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&winreg_mutex);
5009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
50189dc44ceSjose borrego 	if ((ndr_hdlookup(mxa, id) == NULL) ||
50289dc44ceSjose borrego 	    list_is_empty(&winreg_keylist.kl_list) ||
50389dc44ceSjose borrego 	    winreg_key_has_subkey(subkey)) {
5049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&winreg_mutex);
50589dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
50689dc44ceSjose borrego 		return (NDR_DRC_OK);
50789dc44ceSjose borrego 	}
50889dc44ceSjose borrego 
50989dc44ceSjose borrego 	key = list_head(&winreg_keylist.kl_list);
51089dc44ceSjose borrego 	do {
51189dc44ceSjose borrego 		if (strcasecmp(subkey, key->sk_name) == 0) {
51289dc44ceSjose borrego 			if (key->sk_predefined == B_TRUE) {
51389dc44ceSjose borrego 				/* Predefined keys cannot be deleted */
51489dc44ceSjose borrego 				break;
51589dc44ceSjose borrego 			}
51689dc44ceSjose borrego 
51789dc44ceSjose borrego 			list_remove(&winreg_keylist.kl_list, key);
51889dc44ceSjose borrego 			--winreg_keylist.kl_count;
5199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			winreg_dealloc_id(mxa, &key->sk_handle);
52089dc44ceSjose borrego 			free(key);
5219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
5229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			(void) mutex_unlock(&winreg_mutex);
52389dc44ceSjose borrego 			param->status = ERROR_SUCCESS;
52489dc44ceSjose borrego 			return (NDR_DRC_OK);
52589dc44ceSjose borrego 		}
52689dc44ceSjose borrego 	} while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL);
52789dc44ceSjose borrego 
5289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&winreg_mutex);
52989dc44ceSjose borrego 	param->status = ERROR_ACCESS_DENIED;
53089dc44ceSjose borrego 	return (NDR_DRC_OK);
53189dc44ceSjose borrego }
53289dc44ceSjose borrego 
5339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
5349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Call with the winreg_mutex held.
5359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
53689dc44ceSjose borrego static boolean_t
53789dc44ceSjose borrego winreg_key_has_subkey(const char *subkey)
53889dc44ceSjose borrego {
53989dc44ceSjose borrego 	winreg_subkey_t *key;
54089dc44ceSjose borrego 	int keylen;
54189dc44ceSjose borrego 
54289dc44ceSjose borrego 	if (list_is_empty(&winreg_keylist.kl_list))
54389dc44ceSjose borrego 		return (B_FALSE);
54489dc44ceSjose borrego 
54589dc44ceSjose borrego 	keylen = strlen(subkey);
54689dc44ceSjose borrego 
54789dc44ceSjose borrego 	key = list_head(&winreg_keylist.kl_list);
54889dc44ceSjose borrego 	do {
54989dc44ceSjose borrego 		if (strncasecmp(subkey, key->sk_name, keylen) == 0) {
55089dc44ceSjose borrego 			/*
55189dc44ceSjose borrego 			 * Potential match.  If sk_name is longer than
55289dc44ceSjose borrego 			 * subkey, then sk_name is a subkey of our key.
55389dc44ceSjose borrego 			 */
55489dc44ceSjose borrego 			if (keylen < strlen(key->sk_name))
55589dc44ceSjose borrego 				return (B_TRUE);
55689dc44ceSjose borrego 		}
55789dc44ceSjose borrego 	} while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL);
55889dc44ceSjose borrego 
55989dc44ceSjose borrego 	return (B_FALSE);
56089dc44ceSjose borrego }
56189dc44ceSjose borrego 
5629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
5639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Call with the winreg_mutex held.
5649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
56589dc44ceSjose borrego static char *
5667f667e74Sjose borrego winreg_enum_subkey(ndr_xa_t *mxa, const char *subkey, uint32_t index)
56789dc44ceSjose borrego {
56889dc44ceSjose borrego 	winreg_subkey_t *key;
5697f667e74Sjose borrego 	char *entry;
5707f667e74Sjose borrego 	char *p;
5717f667e74Sjose borrego 	int subkeylen;
5727f667e74Sjose borrego 	int count = 0;
57389dc44ceSjose borrego 
57489dc44ceSjose borrego 	if (subkey == NULL)
57589dc44ceSjose borrego 		return (NULL);
57689dc44ceSjose borrego 
57789dc44ceSjose borrego 	if (list_is_empty(&winreg_keylist.kl_list))
57889dc44ceSjose borrego 		return (NULL);
57989dc44ceSjose borrego 
5807f667e74Sjose borrego 	subkeylen = strlen(subkey);
5817f667e74Sjose borrego 
5827f667e74Sjose borrego 	for (key = list_head(&winreg_keylist.kl_list);
5837f667e74Sjose borrego 	    key != NULL; key = list_next(&winreg_keylist.kl_list, key)) {
5847f667e74Sjose borrego 		if (strncasecmp(subkey, key->sk_name, subkeylen) == 0) {
5857f667e74Sjose borrego 			p = key->sk_name + subkeylen;
5867f667e74Sjose borrego 
5877f667e74Sjose borrego 			if ((*p != '\\') || (*p == '\0')) {
5887f667e74Sjose borrego 				/*
5897f667e74Sjose borrego 				 * Not the same subkey or an exact match.
5907f667e74Sjose borrego 				 * We're looking for children of subkey.
5917f667e74Sjose borrego 				 */
5927f667e74Sjose borrego 				continue;
59389dc44ceSjose borrego 			}
5947f667e74Sjose borrego 
5957f667e74Sjose borrego 			++p;
5967f667e74Sjose borrego 
5977f667e74Sjose borrego 			if (count < index) {
5987f667e74Sjose borrego 				++count;
5997f667e74Sjose borrego 				continue;
6007f667e74Sjose borrego 			}
6017f667e74Sjose borrego 
6027f667e74Sjose borrego 			if ((entry = NDR_STRDUP(mxa, p)) == NULL)
6037f667e74Sjose borrego 				return (NULL);
6047f667e74Sjose borrego 
6057f667e74Sjose borrego 			if ((p = strchr(entry, '\\')) != NULL)
6067f667e74Sjose borrego 				*p = '\0';
6077f667e74Sjose borrego 
6087f667e74Sjose borrego 			return (entry);
6097f667e74Sjose borrego 		}
6107f667e74Sjose borrego 	}
61189dc44ceSjose borrego 
61289dc44ceSjose borrego 	return (NULL);
61389dc44ceSjose borrego }
61489dc44ceSjose borrego 
61589dc44ceSjose borrego /*
61689dc44ceSjose borrego  * winreg_s_DeleteValue
61789dc44ceSjose borrego  */
61889dc44ceSjose borrego /*ARGSUSED*/
61989dc44ceSjose borrego static int
62089dc44ceSjose borrego winreg_s_DeleteValue(void *arg, ndr_xa_t *mxa)
62189dc44ceSjose borrego {
62289dc44ceSjose borrego 	struct winreg_DeleteValue *param = arg;
62389dc44ceSjose borrego 
62489dc44ceSjose borrego 	param->status = ERROR_ACCESS_DENIED;
62589dc44ceSjose borrego 	return (NDR_DRC_OK);
62689dc44ceSjose borrego }
62789dc44ceSjose borrego 
62889dc44ceSjose borrego /*
62989dc44ceSjose borrego  * winreg_s_EnumKey
63089dc44ceSjose borrego  */
63189dc44ceSjose borrego static int
63289dc44ceSjose borrego winreg_s_EnumKey(void *arg, ndr_xa_t *mxa)
63389dc44ceSjose borrego {
63489dc44ceSjose borrego 	struct winreg_EnumKey *param = arg;
63589dc44ceSjose borrego 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
6367f667e74Sjose borrego 	ndr_handle_t *hd;
6377f667e74Sjose borrego 	char *subkey;
6387f667e74Sjose borrego 	char *name = NULL;
63989dc44ceSjose borrego 
6409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&winreg_mutex);
6419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6427f667e74Sjose borrego 	if ((hd = ndr_hdlookup(mxa, id)) != NULL)
6437f667e74Sjose borrego 		name = hd->nh_data;
6447f667e74Sjose borrego 
6457f667e74Sjose borrego 	if (hd == NULL || name == NULL) {
6469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&winreg_mutex);
64789dc44ceSjose borrego 		bzero(param, sizeof (struct winreg_EnumKey));
64889dc44ceSjose borrego 		param->status = ERROR_NO_MORE_ITEMS;
64989dc44ceSjose borrego 		return (NDR_DRC_OK);
65089dc44ceSjose borrego 	}
65189dc44ceSjose borrego 
6527f667e74Sjose borrego 	subkey = winreg_enum_subkey(mxa, name, param->index);
6537f667e74Sjose borrego 	if (subkey == NULL) {
6549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&winreg_mutex);
65589dc44ceSjose borrego 		bzero(param, sizeof (struct winreg_EnumKey));
65689dc44ceSjose borrego 		param->status = ERROR_NO_MORE_ITEMS;
65789dc44ceSjose borrego 		return (NDR_DRC_OK);
65889dc44ceSjose borrego 	}
65989dc44ceSjose borrego 
6607f667e74Sjose borrego 	if (NDR_MSTRING(mxa, subkey, (ndr_mstring_t *)&param->name_out) == -1) {
6619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&winreg_mutex);
66289dc44ceSjose borrego 		bzero(param, sizeof (struct winreg_EnumKey));
66389dc44ceSjose borrego 		param->status = ERROR_NOT_ENOUGH_MEMORY;
66489dc44ceSjose borrego 		return (NDR_DRC_OK);
66589dc44ceSjose borrego 	}
6669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&winreg_mutex);
6689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6697f667e74Sjose borrego 	/*
6707f667e74Sjose borrego 	 * This request requires that the length includes the null.
6717f667e74Sjose borrego 	 */
6727f667e74Sjose borrego 	param->name_out.length = param->name_out.allosize;
67389dc44ceSjose borrego 	param->status = ERROR_SUCCESS;
67489dc44ceSjose borrego 	return (NDR_DRC_OK);
67589dc44ceSjose borrego }
67689dc44ceSjose borrego 
67789dc44ceSjose borrego /*
67889dc44ceSjose borrego  * winreg_s_EnumValue
67989dc44ceSjose borrego  */
68089dc44ceSjose borrego static int
68189dc44ceSjose borrego winreg_s_EnumValue(void *arg, ndr_xa_t *mxa)
68289dc44ceSjose borrego {
68389dc44ceSjose borrego 	struct winreg_EnumValue *param = arg;
68489dc44ceSjose borrego 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
68589dc44ceSjose borrego 
68689dc44ceSjose borrego 	if (ndr_hdlookup(mxa, id) == NULL) {
68789dc44ceSjose borrego 		bzero(param, sizeof (struct winreg_EnumValue));
68889dc44ceSjose borrego 		param->status = ERROR_NO_MORE_ITEMS;
68989dc44ceSjose borrego 		return (NDR_DRC_OK);
69089dc44ceSjose borrego 	}
69189dc44ceSjose borrego 
69289dc44ceSjose borrego 	bzero(param, sizeof (struct winreg_EnumValue));
69389dc44ceSjose borrego 	param->status = ERROR_NO_MORE_ITEMS;
69489dc44ceSjose borrego 	return (NDR_DRC_OK);
69589dc44ceSjose borrego }
69689dc44ceSjose borrego 
69789dc44ceSjose borrego /*
69889dc44ceSjose borrego  * winreg_s_FlushKey
69989dc44ceSjose borrego  *
70089dc44ceSjose borrego  * Flush the attributes associated with the specified open key to disk.
70189dc44ceSjose borrego  */
70289dc44ceSjose borrego static int
70389dc44ceSjose borrego winreg_s_FlushKey(void *arg, ndr_xa_t *mxa)
70489dc44ceSjose borrego {
70589dc44ceSjose borrego 	struct winreg_FlushKey *param = arg;
70689dc44ceSjose borrego 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
70789dc44ceSjose borrego 
70889dc44ceSjose borrego 	if (ndr_hdlookup(mxa, id) == NULL)
70989dc44ceSjose borrego 		param->status = ERROR_INVALID_HANDLE;
71089dc44ceSjose borrego 	else
71189dc44ceSjose borrego 		param->status = ERROR_SUCCESS;
71289dc44ceSjose borrego 
71389dc44ceSjose borrego 	return (NDR_DRC_OK);
71489dc44ceSjose borrego }
71589dc44ceSjose borrego 
71689dc44ceSjose borrego /*
71789dc44ceSjose borrego  * winreg_s_GetKeySec
71889dc44ceSjose borrego  */
71989dc44ceSjose borrego static int
72089dc44ceSjose borrego winreg_s_GetKeySec(void *arg, ndr_xa_t *mxa)
72189dc44ceSjose borrego {
72296a62adaSjoyce mcintosh 	static struct winreg_secdesc	error_sd;
72389dc44ceSjose borrego 	struct winreg_GetKeySec		*param = arg;
724f96bd5c8SAlan Wright 	struct winreg_value		*sd_buf;
725f96bd5c8SAlan Wright 	smb_sd_t			sd;
726f96bd5c8SAlan Wright 	uint32_t			sd_len;
727f96bd5c8SAlan Wright 	uint32_t			status;
72889dc44ceSjose borrego 
729f96bd5c8SAlan Wright 	bzero(&sd, sizeof (smb_sd_t));
730f96bd5c8SAlan Wright 
731f96bd5c8SAlan Wright 	if ((status = winreg_sd_format(&sd)) != ERROR_SUCCESS)
732f96bd5c8SAlan Wright 		goto winreg_getkeysec_error;
733f96bd5c8SAlan Wright 
734f96bd5c8SAlan Wright 	sd_len = smb_sd_len(&sd, SMB_ALL_SECINFO);
73596a62adaSjoyce mcintosh 	sd_buf = NDR_MALLOC(mxa, sd_len + sizeof (struct winreg_value));
736f96bd5c8SAlan Wright 
737f96bd5c8SAlan Wright 	param->sd = NDR_MALLOC(mxa, sizeof (struct winreg_secdesc));
73896a62adaSjoyce mcintosh 	if ((param->sd == NULL) || (sd_buf == NULL)) {
739f96bd5c8SAlan Wright 		status = ERROR_NOT_ENOUGH_MEMORY;
740f96bd5c8SAlan Wright 		goto winreg_getkeysec_error;
741f96bd5c8SAlan Wright 	}
742f96bd5c8SAlan Wright 
743f96bd5c8SAlan Wright 	param->sd->sd_len = sd_len;
744f96bd5c8SAlan Wright 	param->sd->sd_size = sd_len;
745f96bd5c8SAlan Wright 	param->sd->sd_buf = sd_buf;
746f96bd5c8SAlan Wright 
747f96bd5c8SAlan Wright 	sd_buf->vc_first_is = 0;
748f96bd5c8SAlan Wright 	sd_buf->vc_length_is = sd_len;
749f96bd5c8SAlan Wright 	param->status = srvsvc_sd_set_relative(&sd, sd_buf->value);
750f96bd5c8SAlan Wright 
751f96bd5c8SAlan Wright 	smb_sd_term(&sd);
75289dc44ceSjose borrego 	return (NDR_DRC_OK);
753f96bd5c8SAlan Wright 
754f96bd5c8SAlan Wright winreg_getkeysec_error:
755f96bd5c8SAlan Wright 	smb_sd_term(&sd);
756f96bd5c8SAlan Wright 	bzero(param, sizeof (struct winreg_GetKeySec));
75796a62adaSjoyce mcintosh 	param->sd = &error_sd;
758f96bd5c8SAlan Wright 	param->status = status;
759f96bd5c8SAlan Wright 	return (NDR_DRC_OK);
760f96bd5c8SAlan Wright }
761f96bd5c8SAlan Wright 
762f96bd5c8SAlan Wright static uint32_t
763f96bd5c8SAlan Wright winreg_sd_format(smb_sd_t *sd)
764f96bd5c8SAlan Wright {
765f96bd5c8SAlan Wright 	smb_fssd_t	fs_sd;
766f96bd5c8SAlan Wright 	acl_t		*acl;
767f96bd5c8SAlan Wright 	uint32_t	status = ERROR_SUCCESS;
768f96bd5c8SAlan Wright 
769f96bd5c8SAlan Wright 	if (acl_fromtext("owner@:rwxpdDaARWcCos::allow", &acl) != 0)
770f96bd5c8SAlan Wright 		return (ERROR_NOT_ENOUGH_MEMORY);
771f96bd5c8SAlan Wright 
772f96bd5c8SAlan Wright 	smb_fssd_init(&fs_sd, SMB_ALL_SECINFO, SMB_FSSD_FLAGS_DIR);
773f96bd5c8SAlan Wright 	fs_sd.sd_uid = 0;
774f96bd5c8SAlan Wright 	fs_sd.sd_gid = 0;
775f96bd5c8SAlan Wright 	fs_sd.sd_zdacl = acl;
776f96bd5c8SAlan Wright 	fs_sd.sd_zsacl = NULL;
777f96bd5c8SAlan Wright 
778f96bd5c8SAlan Wright 	if (smb_sd_fromfs(&fs_sd, sd) != NT_STATUS_SUCCESS)
779f96bd5c8SAlan Wright 		status = ERROR_ACCESS_DENIED;
780f96bd5c8SAlan Wright 	smb_fssd_term(&fs_sd);
781f96bd5c8SAlan Wright 	return (status);
78289dc44ceSjose borrego }
78389dc44ceSjose borrego 
78489dc44ceSjose borrego /*
78589dc44ceSjose borrego  * winreg_s_NotifyChange
78689dc44ceSjose borrego  */
78789dc44ceSjose borrego static int
78889dc44ceSjose borrego winreg_s_NotifyChange(void *arg, ndr_xa_t *mxa)
78989dc44ceSjose borrego {
79089dc44ceSjose borrego 	struct winreg_NotifyChange *param = arg;
79189dc44ceSjose borrego 
79289dc44ceSjose borrego 	if (ndr_is_admin(mxa))
79389dc44ceSjose borrego 		param->status = ERROR_SUCCESS;
79489dc44ceSjose borrego 	else
79589dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
79689dc44ceSjose borrego 
79789dc44ceSjose borrego 	return (NDR_DRC_OK);
79889dc44ceSjose borrego }
79989dc44ceSjose borrego 
80089dc44ceSjose borrego /*
80189dc44ceSjose borrego  * winreg_s_OpenKey
80289dc44ceSjose borrego  *
80389dc44ceSjose borrego  * This is a request to open a windows registry key.
80489dc44ceSjose borrego  * If we recognize the key, we return a handle.
80589dc44ceSjose borrego  *
80689dc44ceSjose borrego  * Returns:
80789dc44ceSjose borrego  *	ERROR_SUCCESS		Valid handle returned.
80889dc44ceSjose borrego  *	ERROR_FILE_NOT_FOUND	No key or unable to allocate a handle.
80989dc44ceSjose borrego  */
81089dc44ceSjose borrego static int
81189dc44ceSjose borrego winreg_s_OpenKey(void *arg, ndr_xa_t *mxa)
81289dc44ceSjose borrego {
81389dc44ceSjose borrego 	struct winreg_OpenKey *param = arg;
814b1352070SAlan Wright 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
815b1352070SAlan Wright 	ndr_handle_t *hd;
81689dc44ceSjose borrego 	char *subkey = (char *)param->name.str;
81789dc44ceSjose borrego 	winreg_subkey_t *key;
8189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&winreg_mutex);
82089dc44ceSjose borrego 
821b1352070SAlan Wright 	if (subkey == NULL || *subkey == '\0') {
822b1352070SAlan Wright 		if ((hd = ndr_hdlookup(mxa, id)) != NULL)
823b1352070SAlan Wright 			subkey = hd->nh_data;
824b1352070SAlan Wright 	}
825b1352070SAlan Wright 
826b1352070SAlan Wright 	id = NULL;
827b1352070SAlan Wright 
8287f667e74Sjose borrego 	if (subkey == NULL || list_is_empty(&winreg_keylist.kl_list)) {
8299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&winreg_mutex);
83089dc44ceSjose borrego 		bzero(&param->result_handle, sizeof (winreg_handle_t));
83189dc44ceSjose borrego 		param->status = ERROR_FILE_NOT_FOUND;
83289dc44ceSjose borrego 		return (NDR_DRC_OK);
83389dc44ceSjose borrego 	}
83489dc44ceSjose borrego 
83589dc44ceSjose borrego 	key = list_head(&winreg_keylist.kl_list);
83689dc44ceSjose borrego 	do {
83789dc44ceSjose borrego 		if (strcasecmp(subkey, key->sk_name) == 0) {
8389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (key->sk_predefined == B_TRUE)
8399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				id = winreg_alloc_id(mxa, subkey);
8409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			else
84189dc44ceSjose borrego 				id = &key->sk_handle;
84289dc44ceSjose borrego 
84389dc44ceSjose borrego 			if (id == NULL)
84489dc44ceSjose borrego 				break;
84589dc44ceSjose borrego 
84689dc44ceSjose borrego 			bcopy(id, &param->result_handle,
84789dc44ceSjose borrego 			    sizeof (winreg_handle_t));
8489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			(void) mutex_unlock(&winreg_mutex);
85089dc44ceSjose borrego 			param->status = ERROR_SUCCESS;
85189dc44ceSjose borrego 			return (NDR_DRC_OK);
85289dc44ceSjose borrego 		}
85389dc44ceSjose borrego 	} while ((key = list_next(&winreg_keylist.kl_list, key)) != NULL);
85489dc44ceSjose borrego 
8559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&winreg_mutex);
85689dc44ceSjose borrego 	bzero(&param->result_handle, sizeof (winreg_handle_t));
85789dc44ceSjose borrego 	param->status = ERROR_FILE_NOT_FOUND;
85889dc44ceSjose borrego 	return (NDR_DRC_OK);
85989dc44ceSjose borrego }
86089dc44ceSjose borrego 
86189dc44ceSjose borrego /*
86289dc44ceSjose borrego  * winreg_s_QueryKey
86389dc44ceSjose borrego  */
86489dc44ceSjose borrego /*ARGSUSED*/
86589dc44ceSjose borrego static int
86689dc44ceSjose borrego winreg_s_QueryKey(void *arg, ndr_xa_t *mxa)
86789dc44ceSjose borrego {
86889dc44ceSjose borrego 	struct winreg_QueryKey *param = arg;
86989dc44ceSjose borrego 	int rc;
87089dc44ceSjose borrego 	winreg_string_t	*name;
87189dc44ceSjose borrego 
87289dc44ceSjose borrego 	name = (winreg_string_t	*)&param->name;
87389dc44ceSjose borrego 	bzero(param, sizeof (struct winreg_QueryKey));
8749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
87589dc44ceSjose borrego 	if ((name = NDR_NEW(mxa, winreg_string_t)) != NULL)
87689dc44ceSjose borrego 		rc = NDR_MSTRING(mxa, "", (ndr_mstring_t *)name);
87789dc44ceSjose borrego 
87889dc44ceSjose borrego 	if ((name == NULL) || (rc != 0)) {
87989dc44ceSjose borrego 		bzero(param, sizeof (struct winreg_QueryKey));
88089dc44ceSjose borrego 		param->status = ERROR_NOT_ENOUGH_MEMORY;
88189dc44ceSjose borrego 		return (NDR_DRC_OK);
88289dc44ceSjose borrego 	}
88389dc44ceSjose borrego 
88489dc44ceSjose borrego 	param->status = ERROR_SUCCESS;
88589dc44ceSjose borrego 	return (NDR_DRC_OK);
88689dc44ceSjose borrego }
88789dc44ceSjose borrego 
88889dc44ceSjose borrego /*
88989dc44ceSjose borrego  * winreg_s_QueryValue
89089dc44ceSjose borrego  *
89189dc44ceSjose borrego  * This is a request to get the value associated with a specified name.
89289dc44ceSjose borrego  *
89389dc44ceSjose borrego  * Returns:
89489dc44ceSjose borrego  *	ERROR_SUCCESS		Value returned.
89589dc44ceSjose borrego  *	ERROR_FILE_NOT_FOUND	PrimaryModule is not supported.
89689dc44ceSjose borrego  *	ERROR_CANTREAD          No such name or memory problem.
89789dc44ceSjose borrego  */
89889dc44ceSjose borrego static int
89989dc44ceSjose borrego winreg_s_QueryValue(void *arg, ndr_xa_t *mxa)
90089dc44ceSjose borrego {
90189dc44ceSjose borrego 	struct winreg_QueryValue *param = arg;
90289dc44ceSjose borrego 	struct winreg_value *pv;
90389dc44ceSjose borrego 	char *name;
90489dc44ceSjose borrego 	char *value;
90589dc44ceSjose borrego 	DWORD slen;
90689dc44ceSjose borrego 	DWORD msize;
90789dc44ceSjose borrego 
90889dc44ceSjose borrego 	name = (char *)param->value_name.str;
90989dc44ceSjose borrego 
91089dc44ceSjose borrego 	if (strcasecmp(name, "PrimaryModule") == 0) {
91189dc44ceSjose borrego 		param->status = ERROR_FILE_NOT_FOUND;
91289dc44ceSjose borrego 		return (NDR_DRC_OK);
91389dc44ceSjose borrego 	}
91489dc44ceSjose borrego 
91589dc44ceSjose borrego 	if ((value = winreg_lookup_value(name)) == NULL) {
91689dc44ceSjose borrego 		param->status = ERROR_CANTREAD;
91789dc44ceSjose borrego 		return (NDR_DRC_OK);
91889dc44ceSjose borrego 	}
91989dc44ceSjose borrego 
920bbf6f00cSJordan Brown 	slen = smb_wcequiv_strlen(value) + sizeof (smb_wchar_t);
92189dc44ceSjose borrego 	msize = sizeof (struct winreg_value) + slen;
92289dc44ceSjose borrego 
92389dc44ceSjose borrego 	param->value = (struct winreg_value *)NDR_MALLOC(mxa, msize);
92489dc44ceSjose borrego 	param->type = NDR_NEW(mxa, DWORD);
92589dc44ceSjose borrego 	param->value_size = NDR_NEW(mxa, DWORD);
92689dc44ceSjose borrego 	param->value_size_total = NDR_NEW(mxa, DWORD);
92789dc44ceSjose borrego 
92889dc44ceSjose borrego 	if (param->value == NULL || param->type == NULL ||
92989dc44ceSjose borrego 	    param->value_size == NULL || param->value_size_total == NULL) {
93089dc44ceSjose borrego 		param->status = ERROR_CANTREAD;
93189dc44ceSjose borrego 		return (NDR_DRC_OK);
93289dc44ceSjose borrego 	}
93389dc44ceSjose borrego 
93489dc44ceSjose borrego 	bzero(param->value, msize);
93589dc44ceSjose borrego 	pv = param->value;
93689dc44ceSjose borrego 	pv->vc_first_is = 0;
93789dc44ceSjose borrego 	pv->vc_length_is = slen;
93889dc44ceSjose borrego 	/*LINTED E_BAD_PTR_CAST_ALIGN*/
939bbf6f00cSJordan Brown 	(void) ndr_mbstowcs(NULL, (smb_wchar_t *)pv->value, value, slen);
94089dc44ceSjose borrego 
94189dc44ceSjose borrego 	*param->type = 1;
94289dc44ceSjose borrego 	*param->value_size = slen;
94389dc44ceSjose borrego 	*param->value_size_total = slen;
94489dc44ceSjose borrego 
94589dc44ceSjose borrego 	param->status = ERROR_SUCCESS;
94689dc44ceSjose borrego 	return (NDR_DRC_OK);
94789dc44ceSjose borrego }
94889dc44ceSjose borrego 
94989dc44ceSjose borrego /*
95089dc44ceSjose borrego  * Lookup a name in the registry and return the associated value.
95189dc44ceSjose borrego  * Our registry is a case-insensitive, name-value pair table.
95289dc44ceSjose borrego  *
95389dc44ceSjose borrego  * Windows ProductType: WinNT, ServerNT, LanmanNT.
95489dc44ceSjose borrego  *	Windows NT4.0 workstation: WinNT
95589dc44ceSjose borrego  *	Windows NT4.0 server:      ServerNT
95689dc44ceSjose borrego  *
95789dc44ceSjose borrego  * If LanmanNT is used here, Windows 2000 sends LsarQueryInfoPolicy
95889dc44ceSjose borrego  * with info level 6, which we don't support.  If we use ServerNT
95989dc44ceSjose borrego  * (as reported by NT4.0 Server) Windows 2000 send requests for
96089dc44ceSjose borrego  * levels 3 and 5, which are support.
96189dc44ceSjose borrego  *
96289dc44ceSjose borrego  * On success, returns a pointer to the value.  Otherwise returns
96389dc44ceSjose borrego  * a null pointer.
96489dc44ceSjose borrego  */
96589dc44ceSjose borrego static char *
96689dc44ceSjose borrego winreg_lookup_value(const char *name)
96789dc44ceSjose borrego {
96889dc44ceSjose borrego 	static struct registry {
96989dc44ceSjose borrego 		char *name;
97089dc44ceSjose borrego 		char *value;
97189dc44ceSjose borrego 	} registry[] = {
9729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		{ "SystemRoot",		"C:\\" },
9739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		{ "CurrentVersion",	winreg_sysver },
97489dc44ceSjose borrego 		{ "ProductType",	"ServerNT" },
9759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		{ "Sources",		winreg_sysname }, /* product name */
9769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		{ "EventMessageFile",	"C:\\windows\\system32\\eventlog.dll" }
97789dc44ceSjose borrego 	};
97889dc44ceSjose borrego 
97989dc44ceSjose borrego 	int i;
98089dc44ceSjose borrego 
98189dc44ceSjose borrego 	for (i = 0; i < sizeof (registry)/sizeof (registry[0]); ++i) {
9829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (strcasecmp(registry[i].name, name) == 0)
98389dc44ceSjose borrego 			return (registry[i].value);
98489dc44ceSjose borrego 	}
98589dc44ceSjose borrego 
98689dc44ceSjose borrego 	return (NULL);
98789dc44ceSjose borrego }
98889dc44ceSjose borrego 
98989dc44ceSjose borrego /*
99089dc44ceSjose borrego  * winreg_s_SetKeySec
99189dc44ceSjose borrego  */
99289dc44ceSjose borrego /*ARGSUSED*/
99389dc44ceSjose borrego static int
99489dc44ceSjose borrego winreg_s_SetKeySec(void *arg, ndr_xa_t *mxa)
99589dc44ceSjose borrego {
99689dc44ceSjose borrego 	struct winreg_SetKeySec *param = arg;
99789dc44ceSjose borrego 
99889dc44ceSjose borrego 	param->status = ERROR_ACCESS_DENIED;
99989dc44ceSjose borrego 	return (NDR_DRC_OK);
100089dc44ceSjose borrego }
100189dc44ceSjose borrego 
100289dc44ceSjose borrego /*
100389dc44ceSjose borrego  * winreg_s_CreateValue
100489dc44ceSjose borrego  */
100589dc44ceSjose borrego /*ARGSUSED*/
100689dc44ceSjose borrego static int
100789dc44ceSjose borrego winreg_s_CreateValue(void *arg, ndr_xa_t *mxa)
100889dc44ceSjose borrego {
100989dc44ceSjose borrego 	struct winreg_CreateValue *param = arg;
101089dc44ceSjose borrego 
101189dc44ceSjose borrego 	param->status = ERROR_ACCESS_DENIED;
101289dc44ceSjose borrego 	return (NDR_DRC_OK);
101389dc44ceSjose borrego }
101489dc44ceSjose borrego 
101589dc44ceSjose borrego /*
101689dc44ceSjose borrego  * winreg_s_Shutdown
101789dc44ceSjose borrego  *
101889dc44ceSjose borrego  * Attempt to shutdown or reboot the system: access denied.
101989dc44ceSjose borrego  */
102089dc44ceSjose borrego /*ARGSUSED*/
102189dc44ceSjose borrego static int
102289dc44ceSjose borrego winreg_s_Shutdown(void *arg, ndr_xa_t *mxa)
102389dc44ceSjose borrego {
102489dc44ceSjose borrego 	struct winreg_Shutdown *param = arg;
102589dc44ceSjose borrego 
102689dc44ceSjose borrego 	param->status = ERROR_ACCESS_DENIED;
102789dc44ceSjose borrego 	return (NDR_DRC_OK);
102889dc44ceSjose borrego }
102989dc44ceSjose borrego 
103089dc44ceSjose borrego /*
103189dc44ceSjose borrego  * winreg_s_AbortShutdown
103289dc44ceSjose borrego  *
103389dc44ceSjose borrego  * Abort a shutdown request.
103489dc44ceSjose borrego  */
103589dc44ceSjose borrego static int
103689dc44ceSjose borrego winreg_s_AbortShutdown(void *arg, ndr_xa_t *mxa)
103789dc44ceSjose borrego {
103889dc44ceSjose borrego 	struct winreg_AbortShutdown *param = arg;
103989dc44ceSjose borrego 
104089dc44ceSjose borrego 	if (ndr_is_admin(mxa))
104189dc44ceSjose borrego 		param->status = ERROR_SUCCESS;
104289dc44ceSjose borrego 	else
104389dc44ceSjose borrego 		param->status = ERROR_ACCESS_DENIED;
104489dc44ceSjose borrego 
104589dc44ceSjose borrego 	return (NDR_DRC_OK);
104689dc44ceSjose borrego }
104789dc44ceSjose borrego 
104889dc44ceSjose borrego /*
104989dc44ceSjose borrego  * winreg_s_GetVersion
105089dc44ceSjose borrego  *
105189dc44ceSjose borrego  * Return the windows registry version.  The current version is 5.
105289dc44ceSjose borrego  * This call is usually made prior to enumerating or querying registry
105389dc44ceSjose borrego  * keys or values.
105489dc44ceSjose borrego  */
105589dc44ceSjose borrego /*ARGSUSED*/
105689dc44ceSjose borrego static int
105789dc44ceSjose borrego winreg_s_GetVersion(void *arg, ndr_xa_t *mxa)
105889dc44ceSjose borrego {
105989dc44ceSjose borrego 	struct winreg_GetVersion *param = arg;
106089dc44ceSjose borrego 
106189dc44ceSjose borrego 	param->version = 5;
106289dc44ceSjose borrego 	param->status = ERROR_SUCCESS;
106389dc44ceSjose borrego 	return (NDR_DRC_OK);
106489dc44ceSjose borrego }
1065