#include "includes.h"
#include "ntdomain.h"
-#include "../librpc/gen_ndr/srv_winreg.h"
+#include "librpc/rpc/dcesrv_core.h"
+#include "librpc/gen_ndr/ndr_winreg.h"
+#include "librpc/gen_ndr/ndr_winreg_scompat.h"
#include "registry.h"
#include "registry/reg_api.h"
-#include "registry/reg_api_regf.h"
#include "registry/reg_perfcount.h"
#include "rpc_misc.h"
#include "auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
+enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY };
+
/******************************************************************
Find a registry key handle and return a struct registry_key *
*****************************************************************/
static struct registry_key *find_regkey_by_hnd(struct pipes_struct *p,
- struct policy_handle *hnd)
+ struct policy_handle *hnd,
+ enum handle_types type)
{
struct registry_key *regkey = NULL;
-
- if(!find_policy_by_hnd(p,hnd,(void **)(void *)®key)) {
+ NTSTATUS status;
+
+ regkey = find_policy_by_hnd(p,
+ hnd,
+ type,
+ struct registry_key,
+ &status);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
return NULL;
}
const char *subkeyname,
uint32_t access_desired)
{
+ struct dcesrv_call_state *dce_call = p->dce_call;
+ struct auth_session_info *session_info =
+ dcesrv_call_session_info(dce_call);
WERROR result = WERR_OK;
struct registry_key *key;
if (parent == NULL) {
result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
- p->session_info->security_token, &key);
+ session_info->security_token, &key);
}
else {
result = reg_openkey(p->mem_ctx, parent, subkeyname,
return result;
}
- if ( !create_policy_hnd( p, hnd, key ) ) {
+ if ( !create_policy_hnd( p, hnd, HTYPE_REGKEY, key ) ) {
return WERR_FILE_NOT_FOUND;
}
*******************************************************************/
static bool close_registry_key(struct pipes_struct *p,
- struct policy_handle *hnd)
+ struct policy_handle *hnd,
+ enum handle_types type)
{
- struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
+ struct registry_key *regkey = find_regkey_by_hnd(p, hnd, type);
if ( !regkey ) {
DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
WERROR _winreg_CloseKey(struct pipes_struct *p,
struct winreg_CloseKey *r)
{
+ bool ok;
+
/* close the policy handle */
- if (!close_registry_key(p, r->in.handle))
+ ok = close_registry_key(p, r->in.handle, HTYPE_REGKEY);
+ if (!ok) {
return WERR_INVALID_HANDLE;
+ }
ZERO_STRUCTP(r->out.handle);
WERROR _winreg_OpenKey(struct pipes_struct *p,
struct winreg_OpenKey *r)
{
- struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
+ struct registry_key *parent = find_regkey_by_hnd(p,
+ r->in.parent_handle,
+ HTYPE_REGKEY);
if ( !parent )
return WERR_INVALID_HANDLE;
struct winreg_QueryValue *r)
{
WERROR status = WERR_FILE_NOT_FOUND;
- struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
+ struct registry_key *regkey = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
prs_struct prs_hkpd;
uint8_t *outbuf = NULL;
struct winreg_QueryInfoKey *r)
{
WERROR status = WERR_OK;
- struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
+ struct registry_key *regkey = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
if ( !regkey )
return WERR_INVALID_HANDLE;
WERROR _winreg_GetVersion(struct pipes_struct *p,
struct winreg_GetVersion *r)
{
- struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
+ struct registry_key *regkey = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
if ( !regkey )
return WERR_INVALID_HANDLE;
struct winreg_EnumKey *r)
{
WERROR err = WERR_OK;
- struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
+ struct registry_key *key = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
char *name;
if ( !key )
struct winreg_EnumValue *r)
{
WERROR err = WERR_OK;
- struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
+ struct registry_key *key = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
char *valname = NULL;
struct registry_value *val = NULL;
WERROR _winreg_InitiateSystemShutdownEx(struct pipes_struct *p,
struct winreg_InitiateSystemShutdownEx *r)
{
+ struct dcesrv_call_state *dce_call = p->dce_call;
+ struct auth_session_info *session_info =
+ dcesrv_call_session_info(dce_call);
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
char *shutdown_script = NULL;
- char *msg = NULL;
char *chkmsg = NULL;
fstring str_timeout;
fstring str_reason;
int ret = -1;
bool can_shutdown = false;
- shutdown_script = lp_shutdown_script(p->mem_ctx);
+ shutdown_script = lp_shutdown_script(p->mem_ctx, lp_sub);
if (!shutdown_script) {
return WERR_NOT_ENOUGH_MEMORY;
}
/* pull the message string and perform necessary sanity checks on it */
if ( r->in.message && r->in.message->string ) {
- if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
+ chkmsg = talloc_alpha_strcpy(p->mem_ctx,
+ r->in.message->string,
+ NULL);
+ if (chkmsg == NULL) {
return WERR_NOT_ENOUGH_MEMORY;
}
- chkmsg = talloc_array(p->mem_ctx, char, strlen(msg)+1);
- if (!chkmsg) {
- return WERR_NOT_ENOUGH_MEMORY;
- }
- alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
}
fstr_sprintf(str_timeout, "%d", r->in.timeout);
return WERR_NOT_ENOUGH_MEMORY;
}
- can_shutdown = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
+ can_shutdown = security_token_has_privilege(
+ session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
/* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
Take the error return from the script and provide it as the Windows return code. */
WERROR _winreg_AbortSystemShutdown(struct pipes_struct *p,
struct winreg_AbortSystemShutdown *r)
{
- const char *abort_shutdown_script = lp_abort_shutdown_script(talloc_tos());
+ struct dcesrv_call_state *dce_call = p->dce_call;
+ struct auth_session_info *session_info =
+ dcesrv_call_session_info(dce_call);
+ const char *abort_shutdown_script = NULL;
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
int ret = -1;
bool can_shutdown = false;
+ abort_shutdown_script = lp_abort_shutdown_script(talloc_tos(), lp_sub);
if (!*abort_shutdown_script)
return WERR_ACCESS_DENIED;
- can_shutdown = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
+ can_shutdown = security_token_has_privilege(
+ session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
}
-/*******************************************************************
- ********************************************************************/
-
-static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
-{
- char *p = NULL;
- int num_services = lp_numservices();
- int snum = -1;
- const char *share_path = NULL;
- char *fname = *pp_fname;
-
- /* convert to a unix path, stripping the C:\ along the way */
-
- if (!(p = valid_share_pathname(ctx, fname))) {
- return -1;
- }
-
- /* has to exist within a valid file share */
-
- for (snum=0; snum<num_services; snum++) {
- if (!lp_snum_ok(snum) || lp_printable(snum)) {
- continue;
- }
-
- share_path = lp_path(talloc_tos(), snum);
-
- /* make sure we have a path (e.g. [homes] ) */
- if (strlen(share_path) == 0) {
- continue;
- }
-
- if (strncmp(share_path, p, strlen(share_path)) == 0) {
- break;
- }
- }
-
- *pp_fname = p;
- return (snum < num_services) ? snum : -1;
-}
-
/*******************************************************************
_winreg_RestoreKey
********************************************************************/
WERROR _winreg_RestoreKey(struct pipes_struct *p,
struct winreg_RestoreKey *r)
{
- struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
- char *fname = NULL;
- int snum = -1;
+ struct registry_key *regkey = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
- if ( !regkey )
+ if ( !regkey ) {
return WERR_INVALID_HANDLE;
-
- if ( !r->in.filename || !r->in.filename->name )
- return WERR_INVALID_PARAMETER;
-
- fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
- if (!fname) {
- return WERR_NOT_ENOUGH_MEMORY;
}
-
- DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
- "\"%s\"\n", regkey->key->name, fname));
-
- if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
- return WERR_BAD_PATHNAME;
-
- /* user must posses SeRestorePrivilege for this this proceed */
-
- if ( !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_RESTORE)) {
- return WERR_ACCESS_DENIED;
- }
-
- DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
- regkey->key->name, fname, lp_servicename(talloc_tos(), snum) ));
-
- return reg_restorekey(regkey, fname);
+ return WERR_BAD_PATHNAME;
}
/*******************************************************************
WERROR _winreg_SaveKey(struct pipes_struct *p,
struct winreg_SaveKey *r)
{
- struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
- char *fname = NULL;
- int snum = -1;
+ struct registry_key *regkey = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
- if ( !regkey )
+ if ( !regkey ) {
return WERR_INVALID_HANDLE;
-
- if ( !r->in.filename || !r->in.filename->name )
- return WERR_INVALID_PARAMETER;
-
- fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
- if (!fname) {
- return WERR_NOT_ENOUGH_MEMORY;
}
-
- DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
- regkey->key->name, fname));
-
- if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
- return WERR_BAD_PATHNAME;
-
- DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
- regkey->key->name, fname, lp_servicename(talloc_tos(), snum) ));
-
- return reg_savekey(regkey, fname);
+ return WERR_BAD_PATHNAME;
}
/*******************************************************************
WERROR _winreg_CreateKey(struct pipes_struct *p,
struct winreg_CreateKey *r)
{
- struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
+ struct registry_key *parent = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
struct registry_key *new_key = NULL;
WERROR result = WERR_OK;
return result;
}
- if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
+ if (!create_policy_hnd(p, r->out.new_handle, HTYPE_REGKEY, new_key)) {
TALLOC_FREE(new_key);
return WERR_FILE_NOT_FOUND;
}
WERROR _winreg_SetValue(struct pipes_struct *p,
struct winreg_SetValue *r)
{
- struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
+ struct registry_key *key = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
struct registry_value *val = NULL;
if ( !key )
WERROR _winreg_DeleteKey(struct pipes_struct *p,
struct winreg_DeleteKey *r)
{
- struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
+ struct registry_key *parent = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
if ( !parent )
return WERR_INVALID_HANDLE;
WERROR _winreg_DeleteValue(struct pipes_struct *p,
struct winreg_DeleteValue *r)
{
- struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
+ struct registry_key *key = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
if ( !key )
return WERR_INVALID_HANDLE;
WERROR _winreg_GetKeySecurity(struct pipes_struct *p,
struct winreg_GetKeySecurity *r)
{
- struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
+ struct registry_key *key = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
WERROR err = WERR_OK;
struct security_descriptor *secdesc = NULL;
uint8_t *data = NULL;
WERROR _winreg_SetKeySecurity(struct pipes_struct *p,
struct winreg_SetKeySecurity *r)
{
- struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
+ struct registry_key *key = find_regkey_by_hnd(p,
+ r->in.handle,
+ HTYPE_REGKEY);
struct security_descriptor *secdesc = NULL;
WERROR err = WERR_OK;
WERROR _winreg_QueryMultipleValues2(struct pipes_struct *p,
struct winreg_QueryMultipleValues2 *r)
{
- struct registry_key *regkey = find_regkey_by_hnd(p, r->in.key_handle);
+ struct registry_key *regkey = find_regkey_by_hnd(p,
+ r->in.key_handle,
+ HTYPE_REGKEY);
struct registry_value *vals = NULL;
const char **names = NULL;
uint32_t offset = 0, num_vals = 0;
DATA_BLOB result = data_blob_null;
- int i = 0;
+ uint32_t i = 0;
WERROR err = WERR_OK;
if (!regkey) {
p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
+
+/* include the generated boilerplate */
+#include "librpc/gen_ndr/ndr_winreg_scompat.c"