/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* Windows Registry RPC (WINREG) server-side interface.
*
* The registry is a database with a hierarchical structure similar to
* a file system, with keys in place of directories and values in place
* of files. The top level keys are known as root keys and each key can
* contain subkeys and values. As with directories and sub-directories,
* the terms key and subkey are used interchangeably. Values, analogous
* to files, contain data.
*
* A specific subkey can be identifies by its fully qualified name (FQN),
* which is analogous to a file system path. In the registry, the key
* separator is the '\' character, which is reserved and cannot appear
* in key or value names. Registry names are case-insensitive.
*
* For example: HKEY_LOCAL_MACHINE\System\CurrentControlSet
*
* The HKEY_LOCAL_MACHINE root key contains a subkey called System, and
* System contains a subkey called CurrentControlSet.
*
* The WINREG RPC interface returns Win32 error codes.
*/
#include <strings.h>
#include <smbsrv/libmlsvc.h>
/*
* List of supported registry keys (case-insensitive).
*/
static char *winreg_keys[] = {
"HKLM",
"HKU",
"HKLM\\SOFTWARE",
"HKLM\\SYSTEM",
"System",
"CurrentControlSet",
"SunOS",
"Solaris",
"System\\CurrentControlSet\\Services\\Eventlog",
"System\\CurrentControlSet\\Control\\ProductOptions",
"SOFTWARE",
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
};
static char *winreg_log[] = {
"Application",
"Security",
"System",
"smbd",
"smbrdr"
};
typedef struct winreg_subkey {
typedef struct winreg_keylist {
int kl_count;
static void winreg_add_predefined(const char *);
static boolean_t winreg_key_has_subkey(const char *);
static char *winreg_lookup_value(const char *);
static int winreg_s_OpenHKCR(void *, ndr_xa_t *);
static int winreg_s_OpenHKCU(void *, ndr_xa_t *);
static int winreg_s_OpenHKLM(void *, ndr_xa_t *);
static int winreg_s_OpenHKPD(void *, ndr_xa_t *);
static int winreg_s_OpenHKU(void *, ndr_xa_t *);
static int winreg_s_OpenHKCC(void *, ndr_xa_t *);
static int winreg_s_OpenHKDD(void *, ndr_xa_t *);
static int winreg_s_OpenHKPT(void *, ndr_xa_t *);
static int winreg_s_OpenHKPN(void *, ndr_xa_t *);
static int winreg_s_OpenHK(void *, ndr_xa_t *, const char *);
static int winreg_s_Close(void *, ndr_xa_t *);
static int winreg_s_CreateKey(void *, ndr_xa_t *);
static int winreg_s_DeleteKey(void *, ndr_xa_t *);
static int winreg_s_DeleteValue(void *, ndr_xa_t *);
static int winreg_s_EnumKey(void *, ndr_xa_t *);
static int winreg_s_EnumValue(void *, ndr_xa_t *);
static int winreg_s_FlushKey(void *, ndr_xa_t *);
static int winreg_s_GetKeySec(void *, ndr_xa_t *);
static int winreg_s_NotifyChange(void *, ndr_xa_t *);
static int winreg_s_OpenKey(void *, ndr_xa_t *);
static int winreg_s_QueryKey(void *, ndr_xa_t *);
static int winreg_s_QueryValue(void *, ndr_xa_t *);
static int winreg_s_SetKeySec(void *, ndr_xa_t *);
static int winreg_s_CreateValue(void *, ndr_xa_t *);
static int winreg_s_Shutdown(void *, ndr_xa_t *);
static int winreg_s_AbortShutdown(void *, ndr_xa_t *);
static int winreg_s_GetVersion(void *, ndr_xa_t *);
{0}
};
"Winreg", /* name */
"Windows Registry", /* desc */
"\\winreg", /* endpoint */
PIPE_WINREG, /* sec_addr_port */
"338cd001-2244-31f1-aaaa-900038001003", 1, /* abstract */
0, /* no bind_instance_size */
0, /* no bind_req() */
0, /* no unbind_and_close() */
0, /* use generic_call_stub() */
winreg_stub_table /* stub_table */
};
/*
* winreg_initialize
*
* Initialize and register the WINREG RPC interface with the RPC runtime
* library. It must be called in order to use either the client side
* or the server side functions.
*/
void
winreg_initialize(void)
{
char *sysname;
int i;
(void) mutex_lock(&winreg_mutex);
winreg_keylist.kl_count = 0;
for (i = 0; i < sizeof (winreg_keys)/sizeof (winreg_keys[0]); ++i)
for (i = 0; i < sizeof (winreg_log)/sizeof (winreg_log[0]); ++i) {
winreg_eventlog, winreg_log[i]);
}
(void) mutex_unlock(&winreg_mutex);
sysname = "Solaris";
else
(void) ndr_svc_register(&winreg_service);
}
static void
{
}
}
static int
{
}
static int
{
}
static int
{
}
static int
{
}
static int
{
}
static int
{
}
static int
{
}
static int
{
}
static int
{
}
/*
* winreg_s_OpenHK
*
* Common code to open root HKEYs.
*/
static int
{
(void) mutex_lock(&winreg_mutex);
} else {
}
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
/*
* winreg_s_Close
*
* This is a request to close the WINREG interface specified by the
* handle. We don't track handles (yet), so just zero out the handle
* and return NDR_DRC_OK. Setting the handle to zero appears to be
* standard behaviour.
*/
static int
{
(void) mutex_lock(&winreg_mutex);
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
static ndr_hdid_t *
{
char *data;
return (NULL);
return (NULL);
}
return (id);
}
static void
{
}
}
/*
* winreg_s_CreateKey
*/
static int
{
char *subkey;
return (NDR_DRC_OK);
}
(void) mutex_lock(&winreg_mutex);
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
goto new_key;
/*
* Check for an existing key.
*/
do {
sizeof (winreg_handle_t));
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
/*
* Create a new key.
*/
goto no_memory;
goto no_memory;
}
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
/*
* winreg_s_DeleteKey
*/
static int
{
char *subkey;
return (NDR_DRC_OK);
}
(void) mutex_lock(&winreg_mutex);
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
do {
/* Predefined keys cannot be deleted */
break;
}
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
/*
* Call with the winreg_mutex held.
*/
static boolean_t
{
int keylen;
return (B_FALSE);
do {
/*
* Potential match. If sk_name is longer than
* subkey, then sk_name is a subkey of our key.
*/
return (B_TRUE);
}
return (B_FALSE);
}
/*
* Call with the winreg_mutex held.
*/
static char *
{
char *entry;
char *p;
int subkeylen;
int count = 0;
return (NULL);
return (NULL);
if ((*p != '\\') || (*p == '\0')) {
/*
* Not the same subkey or an exact match.
* We're looking for children of subkey.
*/
continue;
}
++p;
++count;
continue;
}
return (NULL);
*p = '\0';
return (entry);
}
}
return (NULL);
}
/*
* winreg_s_DeleteValue
*/
/*ARGSUSED*/
static int
{
return (NDR_DRC_OK);
}
/*
* winreg_s_EnumKey
*/
static int
{
char *subkey;
(void) mutex_lock(&winreg_mutex);
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
(void) mutex_unlock(&winreg_mutex);
/*
* This request requires that the length includes the null.
*/
return (NDR_DRC_OK);
}
/*
* winreg_s_EnumValue
*/
static int
{
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* winreg_s_FlushKey
*
* Flush the attributes associated with the specified open key to disk.
*/
static int
{
else
return (NDR_DRC_OK);
}
/*
* winreg_s_GetKeySec
*/
static int
{
goto winreg_getkeysec_error;
goto winreg_getkeysec_error;
}
sd_buf->vc_first_is = 0;
smb_sd_term(&sd);
return (NDR_DRC_OK);
smb_sd_term(&sd);
return (NDR_DRC_OK);
}
static uint32_t
{
return (ERROR_NOT_ENOUGH_MEMORY);
return (status);
}
/*
* winreg_s_NotifyChange
*/
static int
{
if (ndr_is_admin(mxa))
else
return (NDR_DRC_OK);
}
/*
* winreg_s_OpenKey
*
* This is a request to open a windows registry key.
* If we recognize the key, we return a handle.
*
* Returns:
* ERROR_SUCCESS Valid handle returned.
* ERROR_FILE_NOT_FOUND No key or unable to allocate a handle.
*/
static int
{
(void) mutex_lock(&winreg_mutex);
}
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
do {
else
break;
sizeof (winreg_handle_t));
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
(void) mutex_unlock(&winreg_mutex);
return (NDR_DRC_OK);
}
/*
* winreg_s_QueryKey
*/
/*ARGSUSED*/
static int
{
int rc;
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
/*
* winreg_s_QueryValue
*
* This is a request to get the value associated with a specified name.
*
* Returns:
* ERROR_SUCCESS Value returned.
* ERROR_FILE_NOT_FOUND PrimaryModule is not supported.
* ERROR_CANTREAD No such name or memory problem.
*/
static int
{
char *name;
char *value;
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
return (NDR_DRC_OK);
}
pv->vc_first_is = 0;
/*LINTED E_BAD_PTR_CAST_ALIGN*/
return (NDR_DRC_OK);
}
/*
* Lookup a name in the registry and return the associated value.
* Our registry is a case-insensitive, name-value pair table.
*
* Windows ProductType: WinNT, ServerNT, LanmanNT.
* Windows NT4.0 workstation: WinNT
* Windows NT4.0 server: ServerNT
*
* If LanmanNT is used here, Windows 2000 sends LsarQueryInfoPolicy
* with info level 6, which we don't support. If we use ServerNT
* (as reported by NT4.0 Server) Windows 2000 send requests for
* levels 3 and 5, which are support.
*
* On success, returns a pointer to the value. Otherwise returns
* a null pointer.
*/
static char *
{
static struct registry {
char *name;
char *value;
} registry[] = {
{ "SystemRoot", "C:\\" },
{ "CurrentVersion", winreg_sysver },
{ "ProductType", "ServerNT" },
{ "EventMessageFile", "C:\\windows\\system32\\eventlog.dll" }
};
int i;
}
return (NULL);
}
/*
* winreg_s_SetKeySec
*/
/*ARGSUSED*/
static int
{
return (NDR_DRC_OK);
}
/*
* winreg_s_CreateValue
*/
/*ARGSUSED*/
static int
{
return (NDR_DRC_OK);
}
/*
* winreg_s_Shutdown
*
* Attempt to shutdown or reboot the system: access denied.
*/
/*ARGSUSED*/
static int
{
return (NDR_DRC_OK);
}
/*
* winreg_s_AbortShutdown
*
* Abort a shutdown request.
*/
static int
{
if (ndr_is_admin(mxa))
else
return (NDR_DRC_OK);
}
/*
* winreg_s_GetVersion
*
* Return the windows registry version. The current version is 5.
* This call is usually made prior to enumerating or querying registry
* keys or values.
*/
/*ARGSUSED*/
static int
{
return (NDR_DRC_OK);
}