rpc_server3: Remove pipes_struct->session_info
[samba.git] / source3 / rpc_server / winreg / srv_winreg_nt.c
index d9ee8d0602d1461f657e144fe0c87346ee100e91..3f282d4886e769c7b10ca07de82c19c518815bd9 100644 (file)
 
 #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 *)&regkey)) {
+       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;
        }
@@ -66,12 +76,15 @@ static WERROR open_registry_key(struct pipes_struct *p,
                                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,
@@ -82,7 +95,7 @@ static WERROR open_registry_key(struct pipes_struct *p,
                return result;
        }
 
-       if ( !create_policy_hnd( p, hnd, key ) ) {
+       if ( !create_policy_hnd( p, hnd, HTYPE_REGKEY, key ) ) {
                return WERR_FILE_NOT_FOUND;
        }
 
@@ -95,9 +108,10 @@ static WERROR open_registry_key(struct pipes_struct *p,
  *******************************************************************/
 
 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",
@@ -117,10 +131,14 @@ static bool close_registry_key(struct pipes_struct *p,
 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);
 
@@ -224,7 +242,9 @@ WERROR _winreg_OpenHKPN(struct pipes_struct *p,
 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;
@@ -240,7 +260,9 @@ WERROR _winreg_QueryValue(struct pipes_struct *p,
                          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;
@@ -357,7 +379,9 @@ WERROR _winreg_QueryInfoKey(struct pipes_struct *p,
                            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;
@@ -393,7 +417,9 @@ WERROR _winreg_QueryInfoKey(struct pipes_struct *p,
 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;
@@ -410,7 +436,9 @@ WERROR _winreg_EnumKey(struct pipes_struct *p,
                       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 )
@@ -439,7 +467,9 @@ WERROR _winreg_EnumValue(struct pipes_struct *p,
                         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;
 
@@ -520,8 +550,12 @@ WERROR _winreg_InitiateSystemShutdown(struct pipes_struct *p,
 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;
@@ -530,7 +564,7 @@ WERROR _winreg_InitiateSystemShutdownEx(struct pipes_struct *p,
        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;
        }
@@ -541,14 +575,12 @@ WERROR _winreg_InitiateSystemShutdownEx(struct pipes_struct *p,
        /* 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);
@@ -582,7 +614,8 @@ WERROR _winreg_InitiateSystemShutdownEx(struct pipes_struct *p,
                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. */
@@ -612,14 +645,21 @@ WERROR _winreg_InitiateSystemShutdownEx(struct pipes_struct *p,
 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 **********/
 
@@ -639,46 +679,6 @@ WERROR _winreg_AbortSystemShutdown(struct pipes_struct *p,
        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
  ********************************************************************/
@@ -686,37 +686,14 @@ static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
 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;
 }
 
 /*******************************************************************
@@ -726,31 +703,14 @@ WERROR _winreg_RestoreKey(struct pipes_struct *p,
 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;
 }
 
 /*******************************************************************
@@ -774,7 +734,9 @@ WERROR _winreg_SaveKeyEx(struct pipes_struct *p,
 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;
 
@@ -790,7 +752,7 @@ WERROR _winreg_CreateKey(struct pipes_struct *p,
                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;
        }
@@ -805,7 +767,9 @@ WERROR _winreg_CreateKey(struct pipes_struct *p,
 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 )
@@ -832,7 +796,9 @@ WERROR _winreg_SetValue(struct pipes_struct *p,
 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;
@@ -848,7 +814,9 @@ WERROR _winreg_DeleteKey(struct pipes_struct *p,
 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;
@@ -863,7 +831,9 @@ WERROR _winreg_DeleteValue(struct pipes_struct *p,
 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;
@@ -907,7 +877,9 @@ WERROR _winreg_GetKeySecurity(struct pipes_struct *p,
 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;
 
@@ -1050,12 +1022,14 @@ static WERROR construct_multiple_entry(TALLOC_CTX *mem_ctx,
 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) {
@@ -1145,3 +1119,6 @@ WERROR _winreg_DeleteKeyEx(struct pipes_struct *p,
        p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
        return WERR_NOT_SUPPORTED;
 }
+
+/* include the generated boilerplate */
+#include "librpc/gen_ndr/ndr_winreg_scompat.c"