diff options
-rw-r--r-- | source4/lib/policy/gp_ldap.c | 47 | ||||
-rw-r--r-- | source4/lib/policy/gp_manage.c | 52 | ||||
-rw-r--r-- | source4/lib/policy/policy.h | 3 | ||||
-rw-r--r-- | source4/utils/net/net_gpo.c | 54 |
4 files changed, 153 insertions, 3 deletions
diff --git a/source4/lib/policy/gp_ldap.c b/source4/lib/policy/gp_ldap.c index 5ef161d12c..730c4d8e0b 100644 --- a/source4/lib/policy/gp_ldap.c +++ b/source4/lib/policy/gp_ldap.c @@ -29,7 +29,7 @@ #include "../libcli/security/dom_sid.h" #include "libcli/security/security.h" #include "../lib/talloc/talloc.h" -#include "policy.h" +#include "lib/policy/policy.h" struct gpo_stringmap { const char *str; @@ -868,3 +868,48 @@ NTSTATUS gp_create_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo) talloc_free(mem_ctx); return NT_STATUS_UNSUCCESSFUL; } + +NTSTATUS gp_set_ads_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd) +{ + TALLOC_CTX *mem_ctx; + DATA_BLOB data; + enum ndr_err_code ndr_err; + struct ldb_message *msg; + int rv; + + /* Create a forked memory context to clean up easily */ + mem_ctx = talloc_new(gp_ctx); + + /* Push the security descriptor through the NDR library */ + ndr_err = ndr_push_struct_blob(&data, + mem_ctx, + lp_iconv_convenience(gp_ctx->lp_ctx), + sd, + (ndr_push_flags_fn_t)ndr_push_security_descriptor); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + + + /* Create a LDB message */ + msg = ldb_msg_new(mem_ctx); + msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str); + + rv = ldb_msg_add_value(msg, "nTSecurityDescriptor", &data, NULL); + if (rv != 0) { + DEBUG(0, ("LDB message add element failed for adding nTSecurityDescriptor: %s\n", ldb_strerror(rv))); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; + + rv = ldb_modify(gp_ctx->ldb_ctx, msg); + if (rv != 0) { + DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv))); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + talloc_free(mem_ctx); + return NT_STATUS_OK; +} diff --git a/source4/lib/policy/gp_manage.c b/source4/lib/policy/gp_manage.c index 580f87116d..968eaf2025 100644 --- a/source4/lib/policy/gp_manage.c +++ b/source4/lib/policy/gp_manage.c @@ -134,6 +134,7 @@ NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, str name[i] = toupper(name[i]); } + /* Prepare the GPO struct */ gpo->dn = NULL; gpo->name = name; gpo->flags = 0; @@ -145,6 +146,7 @@ NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, str status = gp_create_gpt(gp_ctx, name, gpo->file_sys_path); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to create GPT\n")); + talloc_free(mem_ctx); return status; } @@ -153,6 +155,7 @@ NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, str status = gp_create_ldap_gpo(gp_ctx, gpo); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to create LDAP group policy object\n")); + talloc_free(mem_ctx); return status; } @@ -160,6 +163,7 @@ NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, str status = gp_get_gpo_info(gp_ctx, gpo->dn, &gpo); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to fetch LDAP group policy object\n")); + talloc_free(mem_ctx); return status; } @@ -167,6 +171,7 @@ NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, str status = gp_create_gpt_security_descriptor(mem_ctx, gpo->security_descriptor, &sd); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to convert ADS security descriptor to filesystem security descriptor\n")); + talloc_free(mem_ctx); return status; } @@ -174,6 +179,7 @@ NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, str status = gp_set_gpt_security_descriptor(gp_ctx, gpo, sd); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to set security descriptor (ACL) on the file system\n")); + talloc_free(mem_ctx); return status; } @@ -182,3 +188,49 @@ NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, str *ret = gpo; return NT_STATUS_OK; } + +NTSTATUS gp_set_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd) +{ + TALLOC_CTX *mem_ctx; + struct security_descriptor *fs_sd; + struct gp_object *gpo; + NTSTATUS status; + + /* Create a forked memory context, as a base for everything here */ + mem_ctx = talloc_new(gp_ctx); + + /* Set the ACL on LDAP database */ + status = gp_set_ads_acl(gp_ctx, dn_str, sd); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to set ACL on ADS\n")); + talloc_free(mem_ctx); + return status; + } + + /* Get the group policy object information, for filesystem location and merged sd */ + status = gp_get_gpo_info(gp_ctx, dn_str, &gpo); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to set ACL on ADS\n")); + talloc_free(mem_ctx); + return status; + } + + /* Create matching file and DS security descriptors */ + status = gp_create_gpt_security_descriptor(mem_ctx, gpo->security_descriptor, &fs_sd); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to convert ADS security descriptor to filesystem security descriptor\n")); + talloc_free(mem_ctx); + return status; + } + + /* Set the security descriptor on the filesystem for this GPO */ + status = gp_set_gpt_security_descriptor(gp_ctx, gpo, fs_sd); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to set security descriptor (ACL) on the file system\n")); + talloc_free(mem_ctx); + return status; + } + + talloc_free(mem_ctx); + return NT_STATUS_OK; +} diff --git a/source4/lib/policy/policy.h b/source4/lib/policy/policy.h index 264cc70da1..86ab33ee7d 100644 --- a/source4/lib/policy/policy.h +++ b/source4/lib/policy/policy.h @@ -88,6 +88,7 @@ NTSTATUS gp_get_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum NTSTATUS gp_set_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance inheritance); NTSTATUS gp_create_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo); +NTSTATUS gp_set_ads_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd); /* File system functions */ NTSTATUS gp_fetch_gpt (struct gp_context *gp_ctx, struct gp_object *gpo, const char **path); @@ -96,5 +97,7 @@ NTSTATUS gp_set_gpt_security_descriptor(struct gp_context *gp_ctx, struct gp_obj /* Managing functions */ NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, struct gp_object **ret); +NTSTATUS gp_create_gpt_security_descriptor (TALLOC_CTX *mem_ctx, struct security_descriptor *ds_sd, struct security_descriptor **ret); +NTSTATUS gp_set_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd); #endif diff --git a/source4/utils/net/net_gpo.c b/source4/utils/net/net_gpo.c index 4a280a239c..f570d83a26 100644 --- a/source4/utils/net/net_gpo.c +++ b/source4/utils/net/net_gpo.c @@ -26,6 +26,8 @@ #include "lib/ldb/include/ldb.h" #include "auth/auth.h" #include "param/param.h" +#include "libcli/security/sddl.h" +#include "dsdb/samdb/samdb.h" #include "lib/policy/policy.h" static int net_gpo_list_all_usage(struct net_context *ctx, int argc, const char **argv) @@ -91,6 +93,7 @@ static int net_gpo_get_gpo(struct net_context *ctx, int argc, const char **argv) struct gp_context *gp_ctx; struct gp_object *gpo; const char **gpo_flags; + char *sddl; int i; NTSTATUS rv; @@ -126,6 +129,11 @@ static int net_gpo_get_gpo(struct net_context *ctx, int argc, const char **argv) d_printf(" %s\n", gpo_flags[i]); } } + sddl = sddl_encode(gp_ctx, gpo->security_descriptor, samdb_domain_sid(gp_ctx->ldb_ctx)); + if (sddl != NULL) { + d_printf("ACL : %s\n", sddl); + } + d_printf("\n"); talloc_free(gp_ctx); @@ -511,6 +519,49 @@ static int net_gpo_create(struct net_context *ctx, int argc, const char **argv) return 0; } + +static int net_gpo_set_acl_usage(struct net_context *ctx, int argc, const char **argv) +{ + d_printf("Syntax: net gpo setacl <dn> <sddl> [options]\n"); + d_printf("For a list of available options, please type net gpo setacl --help\n"); + return 0; +} + +static int net_gpo_set_acl(struct net_context *ctx, int argc, const char **argv) +{ + struct gp_context *gp_ctx; + struct security_descriptor *sd; + NTSTATUS rv; + + if (argc != 2) { + return net_gpo_set_acl_usage(ctx, argc, argv); + } + + rv = gp_init(ctx, ctx->lp_ctx, ctx->credentials, ctx->event_ctx, &gp_ctx); + if (!NT_STATUS_IS_OK(rv)) { + DEBUG(0, ("Failed to connect to DC's LDAP: %s\n", get_friendly_nt_error_msg(rv))); + return 1; + } + + /* Convert sddl to security descriptor */ + sd = sddl_decode(gp_ctx, argv[1], samdb_domain_sid(gp_ctx->ldb_ctx)); + if (sd == NULL) { + DEBUG(0, ("Invalid SDDL\n")); + return 1; + } + + rv = gp_set_acl(gp_ctx, argv[0], sd); + if (!NT_STATUS_IS_OK(rv)) { + DEBUG(0, ("Failed to set ACL on GPO: %s\n", get_friendly_nt_error_msg(rv))); + return 1; + } + + talloc_free(gp_ctx); + return 0; +} + + + static const struct net_functable net_gpo_functable[] = { { "listall", "List all GPO's on a DC\n", net_gpo_list_all, net_gpo_list_all_usage }, { "list", "List all active GPO's for a machine/user\n", net_gpo_list, net_gpo_list_usage }, @@ -522,11 +573,10 @@ static const struct net_functable net_gpo_functable[] = { { "setinheritance", "Set inheritance flag on a container\n", net_gpo_inheritance_set, net_gpo_inheritance_set_usage }, { "fetch", "Download a GPO\n", net_gpo_fetch, net_gpo_fetch_usage }, { "create", "Create a GPO\n", net_gpo_create, net_gpo_create_usage }, + { "setacl", "Set ACL on a GPO\n", net_gpo_set_acl, net_gpo_set_acl_usage }, { NULL, NULL } }; - - int net_gpo_usage(struct net_context *ctx, int argc, const char **argv) { d_printf("Syntax: net gpo <command> [options]\n"); |