Add net gpo setacl support. Create gp_set_acl function. Show ACL in net gpo show.
authorWilco Baan Hofman <wilco@baanhofman.nl>
Thu, 20 May 2010 14:56:40 +0000 (16:56 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Sun, 20 Jun 2010 15:19:12 +0000 (17:19 +0200)
Cleanup memory allocation of gp_create_gpo

Signed-off-by: Jelmer Vernooij <jelmer@samba.org>
source4/lib/policy/gp_ldap.c
source4/lib/policy/gp_manage.c
source4/lib/policy/policy.h
source4/utils/net/net_gpo.c

index 5ef161d12c2780e0514b0575e3fcce4804082cc6..730c4d8e0b7a48c34deee173b56432e9597f70b3 100644 (file)
@@ -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;
+}
index 580f87116de36d687152d71fa2ce53c06078c72d..968eaf202540d4156c2f54ae56dafed7ad5ac2c4 100644 (file)
@@ -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;
+}
index 264cc70da116e4bd619bacc68fe34d019191261d..86ab33ee7d65b3365e11a4774d431fc5e0268af9 100644 (file)
@@ -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
index 4a280a239c46ff1707beea9a5587c421154060b6..f570d83a2602af53f9d0362a7f53b158a4688eed 100644 (file)
@@ -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");