*/
#include "includes.h"
+#include "registry.h"
+#include "reg_dispatcher.h"
+#include "../libcli/security/security.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_REGISTRY
/********************************************************************
********************************************************************/
-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;
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->hook && key->hook->ops && key->hook->ops->store_subkeys )
- return key->hook->ops->store_subkeys( key->name, subkeys );
+ if (key->ops && key->ops->store_subkeys)
+ return key->ops->store_subkeys(key->name, subkeys);
return false;
}
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->hook && key->hook->ops && key->hook->ops->store_values )
- return key->hook->ops->store_values( key->name, val );
+ if (key->ops && key->ops->store_values)
+ return key->ops->store_values(key->name, 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, bool lazy)
+{
+ if (key->ops && key->ops->delete_subkey) {
+ return key->ops->delete_subkey(key->name, subkey, lazy);
+ }
+
+ 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;
- if ( key->hook && key->hook->ops && key->hook->ops->fetch_subkeys )
- result = key->hook->ops->fetch_subkeys( key->name, subkey_ctr );
+ if (key->ops && key->ops->fetch_subkeys)
+ result = key->ops->fetch_subkeys(key->name, subkey_ctr);
return result;
}
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;
DEBUG(10, ("fetch_reg_values called for key '%s' (ops %p)\n", key->name,
- (key->hook && key->hook->ops) ? (void *)key->hook->ops : NULL));
+ (key->ops) ? (void *)key->ops : NULL));
- if ( key->hook && key->hook->ops && key->hook->ops->fetch_values )
- result = key->hook->ops->fetch_values( key->name, val );
+ if (key->ops && key->ops->fetch_values)
+ result = key->ops->fetch_values(key->name, val);
return result;
}
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;
-
- /* use the default security check if the backend has not defined its
- * own */
- if (key->hook && key->hook->ops && key->hook->ops->reg_access_check) {
- return key->hook->ops->reg_access_check( key->name, requested,
- granted, token );
+ /* 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;
}
- /*
- * The secdesc routines can't yet cope with a NULL talloc ctx sanely.
- */
+ /* use the default security check if the backend has not defined its
+ * own */
- if (!(mem_ctx = talloc_init("regkey_access_check"))) {
- return false;
+ if (key->ops && key->ops->reg_access_check) {
+ return key->ops->reg_access_check(key->name, requested,
+ granted, token);
}
- 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, ®_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;
WERROR werr;
- if (key->hook && key->hook->ops && key->hook->ops->get_secdesc) {
- werr = key->hook->ops->get_secdesc(mem_ctx, key->name,
- psecdesc);
+ if (key->ops && key->ops->get_secdesc) {
+ werr = key->ops->get_secdesc(mem_ctx, key->name, psecdesc);
if (W_ERROR_IS_OK(werr)) {
return WERR_OK;
}
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->hook && key->hook->ops && key->hook->ops->set_secdesc) {
- return key->hook->ops->set_secdesc(key->name, psecdesc);
+ if (key->ops && key->ops->set_secdesc) {
+ return key->ops->set_secdesc(key->name, psecdesc);
}
return WERR_ACCESS_DENIED;
* 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->hook && key->hook->ops && key->hook->ops->subkeys_need_update)
+ if (key->ops && key->ops->subkeys_need_update)
{
- return key->hook->ops->subkeys_need_update(subkeys);
+ return key->ops->subkeys_need_update(subkeys);
}
return false;
* 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->hook && key->hook->ops && key->hook->ops->values_need_update)
+ if (key->ops && key->ops->values_need_update)
{
- return key->hook->ops->values_need_update(values);
+ return key->ops->values_need_update(values);
}
return false;