selftest: Move Samba4 selftest wscript to the top level
[ira/wip.git] / source3 / registry / reg_dispatcher.c
index c68ecdedebcd01014a32cd57505af0de5a5f91b8..a96047817d9a033f5704a285d5daf93edfd0c43a 100644 (file)
@@ -24,6 +24,9 @@
  */
 
 #include "includes.h"
+#include "registry.h"
+#include "reg_dispatcher.h"
+#include "../libcli/security/security.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_REGISTRY
@@ -34,43 +37,39 @@ static const struct generic_mapping reg_generic_map =
 /********************************************************************
 ********************************************************************/
 
-static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd)
+static WERROR construct_registry_sd(TALLOC_CTX *ctx, struct security_descriptor **psd)
 {
-       SEC_ACE ace[3];
-       SEC_ACCESS mask;
+       struct security_ace ace[3];
        size_t i = 0;
-       SEC_DESC *sd;
-       SEC_ACL *acl;
+       struct security_descriptor *sd;
+       struct security_acl *theacl;
        size_t sd_size;
 
        /* basic access for Everyone */
 
-       init_sec_access(&mask, REG_KEY_READ);
        init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                    mask, 0);
+                    REG_KEY_READ, 0);
 
        /* Full Access 'BUILTIN\Administrators' */
 
-       init_sec_access(&mask, REG_KEY_ALL);
        init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
-                    SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+                    SEC_ACE_TYPE_ACCESS_ALLOWED, REG_KEY_ALL, 0);
 
        /* Full Access 'NT Authority\System' */
 
-       init_sec_access(&mask, REG_KEY_ALL );
        init_sec_ace(&ace[i++], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                    mask, 0);
+                    REG_KEY_ALL, 0);
 
        /* create the security descriptor */
 
-       acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace);
-       if (acl == NULL) {
+       theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace);
+       if (theacl == NULL) {
                return WERR_NOMEM;
        }
 
-       sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
+       sd = make_sec_desc(ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
                           &global_sid_Builtin_Administrators,
-                          &global_sid_System, NULL, acl,
+                          &global_sid_System, NULL, theacl,
                           &sd_size);
        if (sd == NULL) {
                return WERR_NOMEM;
@@ -84,7 +83,8 @@ static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd)
  High level wrapper function for storing registry subkeys
  ***********************************************************************/
 
-bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
+bool store_reg_keys(struct registry_key_handle *key,
+                   struct regsubkey_ctr *subkeys)
 {
        if (key->ops && key->ops->store_subkeys)
                return key->ops->store_subkeys(key->name, subkeys);
@@ -96,7 +96,7 @@ bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
  High level wrapper function for storing registry values
  ***********************************************************************/
 
-bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
+bool store_reg_values(struct registry_key_handle *key, struct regval_ctr *val)
 {
        if (key->ops && key->ops->store_values)
                return key->ops->store_values(key->name, val);
@@ -104,12 +104,31 @@ bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
        return false;
 }
 
+WERROR create_reg_subkey(struct registry_key_handle *key, const char *subkey)
+{
+       if (key->ops && key->ops->create_subkey) {
+               return key->ops->create_subkey(key->name, subkey);
+       }
+
+       return WERR_NOT_SUPPORTED;
+}
+
+WERROR delete_reg_subkey(struct registry_key_handle *key, const char *subkey)
+{
+       if (key->ops && key->ops->delete_subkey) {
+               return key->ops->delete_subkey(key->name, subkey);
+       }
+
+       return WERR_NOT_SUPPORTED;
+}
+
 /***********************************************************************
  High level wrapper function for enumerating registry subkeys
  Initialize the TALLOC_CTX if necessary
  ***********************************************************************/
 
-int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
+int fetch_reg_keys(struct registry_key_handle *key,
+                  struct regsubkey_ctr *subkey_ctr)
 {
        int result = -1;
 
@@ -123,7 +142,7 @@ int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
  High level wrapper function for enumerating registry values
  ***********************************************************************/
 
-int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
+int fetch_reg_values(struct registry_key_handle *key, struct regval_ctr *val)
 {
        int result = -1;
 
@@ -141,13 +160,19 @@ int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
  underlying registry backend
  ***********************************************************************/
 
-bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
-                         const struct nt_user_token *token )
+bool regkey_access_check(struct registry_key_handle *key, uint32 requested,
+                        uint32 *granted,
+                        const struct security_token *token )
 {
-       SEC_DESC *sec_desc;
+       struct security_descriptor *sec_desc;
        NTSTATUS status;
        WERROR err;
-       TALLOC_CTX *mem_ctx;
+
+       /* root free-pass, like we have on all other pipes like samr, lsa, etc. */
+       if (geteuid() == sec_initial_uid()) {
+               *granted = REG_KEY_ALL;
+               return true;
+       }
 
        /* use the default security check if the backend has not defined its
         * own */
@@ -157,33 +182,24 @@ bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
                                                  granted, token);
        }
 
-       /*
-        * The secdesc routines can't yet cope with a NULL talloc ctx sanely.
-        */
-
-       if (!(mem_ctx = talloc_init("regkey_access_check"))) {
-               return false;
-       }
-
-       err = regkey_get_secdesc(mem_ctx, key, &sec_desc);
+       err = regkey_get_secdesc(talloc_tos(), key, &sec_desc);
 
        if (!W_ERROR_IS_OK(err)) {
-               TALLOC_FREE(mem_ctx);
                return false;
        }
 
        se_map_generic( &requested, &reg_generic_map );
 
-       if (!se_access_check(sec_desc, token, requested, granted, &status)) {
-               TALLOC_FREE(mem_ctx);
+       status =se_access_check(sec_desc, token, requested, granted);
+       TALLOC_FREE(sec_desc);
+       if (!NT_STATUS_IS_OK(status)) {
                return false;
        }
 
-       TALLOC_FREE(mem_ctx);
        return NT_STATUS_IS_OK(status);
 }
 
-WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key,
+WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, struct registry_key_handle *key,
                          struct security_descriptor **psecdesc)
 {
        struct security_descriptor *secdesc;
@@ -205,7 +221,7 @@ WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key,
        return WERR_OK;
 }
 
-WERROR regkey_set_secdesc(REGISTRY_KEY *key,
+WERROR regkey_set_secdesc(struct registry_key_handle *key,
                          struct security_descriptor *psecdesc)
 {
        if (key->ops && key->ops->set_secdesc) {
@@ -219,7 +235,8 @@ WERROR regkey_set_secdesc(REGISTRY_KEY *key,
  * Check whether the in-memory version of the subkyes of a
  * registry key needs update from disk.
  */
-bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys)
+bool reg_subkeys_need_update(struct registry_key_handle *key,
+                            struct regsubkey_ctr *subkeys)
 {
        if (key->ops && key->ops->subkeys_need_update)
        {
@@ -233,7 +250,8 @@ bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys)
  * Check whether the in-memory version of the values of a
  * registry key needs update from disk.
  */
-bool reg_values_need_update(REGISTRY_KEY *key, REGVAL_CTR *values)
+bool reg_values_need_update(struct registry_key_handle *key,
+                           struct regval_ctr *values)
 {
        if (key->ops && key->ops->values_need_update)
        {