diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/lib/policy/gp_ldap.c | 126 | ||||
-rw-r--r-- | source4/lib/policy/policy.h | 10 | ||||
-rw-r--r-- | source4/utils/net/net_gpo.c | 54 |
3 files changed, 141 insertions, 49 deletions
diff --git a/source4/lib/policy/gp_ldap.c b/source4/lib/policy/gp_ldap.c index ee3da9d239..8f44adcc6d 100644 --- a/source4/lib/policy/gp_ldap.c +++ b/source4/lib/policy/gp_ldap.c @@ -51,59 +51,33 @@ static const struct gpo_stringmap gpo_inheritance [] = { { NULL, 0 } }; + static NTSTATUS parse_gpo(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct gp_object **ret) { - unsigned int i; struct gp_object *gpo = talloc(mem_ctx, struct gp_object); enum ndr_err_code ndr_err; + const DATA_BLOB *data; gpo->dn = talloc_steal(mem_ctx, ldb_dn_get_linearized(msg->dn)); DEBUG(9, ("Parsing GPO LDAP data for %s\n", gpo->dn)); - for (i = 0; i < msg->num_elements; i++) { - struct ldb_message_element *element = &msg->elements[i]; - if (strcmp(element->name, "displayName") == 0) { - SMB_ASSERT(element->num_values > 0); - gpo->display_name = talloc_strdup(gpo, (char *)element->values[0].data); - DEBUG(10, ("Found displayname: %s\n", gpo->display_name)); - } - if (strcmp(element->name, "name") == 0) { - SMB_ASSERT(element->num_values > 0); - gpo->name = talloc_strdup(gpo, (char *)element->values[0].data); - DEBUG(10, ("Found name: %s\n", gpo->name)); - } - if (strcmp(element->name, "flags") == 0) { - char *end; - SMB_ASSERT(element->num_values > 0); - gpo->flags = (uint32_t) strtoll((char *)element->values[0].data, &end, 0); - SMB_ASSERT(*end == 0); - DEBUG(10, ("Found flags: %d\n", gpo->flags)); - } - if (strcmp(element->name, "versionNumber") == 0) { - char *end; - SMB_ASSERT(element->num_values > 0); - gpo->version = (uint32_t) strtoll((char *)element->values[0].data, &end, 0); - SMB_ASSERT(*end == 0); - DEBUG(10, ("Found version: %d\n", gpo->version)); - } - if (strcmp(element->name, "gPCFileSysPath") == 0) { - SMB_ASSERT(element->num_values > 0); - gpo->file_sys_path = talloc_strdup(gpo, (char *)element->values[0].data); - DEBUG(10, ("Found file system path: %s\n", gpo->file_sys_path)); - } - if (strcmp(element->name, "nTSecurityDescriptor") == 0) { - gpo->security_descriptor = talloc(mem_ctx, struct security_descriptor); - ndr_err = ndr_pull_struct_blob(&element->values[0], - mem_ctx, - NULL, - gpo->security_descriptor, - (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - DEBUG(10, ("Found security descriptor.\n")); - } + gpo->display_name = talloc_steal(mem_ctx, ldb_msg_find_attr_as_string(msg, "displayName", "")); + gpo->name = talloc_steal(mem_ctx, ldb_msg_find_attr_as_string(msg, "name", "")); + gpo->flags = ldb_msg_find_attr_as_uint(msg, "name", 0); + gpo->version = ldb_msg_find_attr_as_uint(msg, "version", 0); + gpo->file_sys_path = talloc_steal(mem_ctx, ldb_msg_find_attr_as_string(msg, "gPCFileSysPath", "")); + + /* Pull the security descriptor through the NDR library */ + data = ldb_msg_find_ldb_val(msg, "nTSecurityDescriptor"); + gpo->security_descriptor = talloc(mem_ctx, struct security_descriptor); + ndr_err = ndr_pull_struct_blob(data, + mem_ctx, + NULL, + gpo->security_descriptor, + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); } *ret = gpo; @@ -357,7 +331,7 @@ static NTSTATUS parse_gplink (TALLOC_CTX *mem_ctx, const char *gplink_str, struc } -NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *req_dn, struct gp_link ***ret) +NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *dn_str, struct gp_link ***ret) { TALLOC_CTX *mem_ctx; struct ldb_dn *dn; @@ -371,7 +345,7 @@ NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *req_dn, struct gp /* Create a forked memory context, as a base for everything here */ mem_ctx = talloc_new(gp_ctx); - dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, req_dn); + dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str); rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, NULL, "(objectclass=*)"); if (rv != LDB_SUCCESS) { @@ -566,3 +540,63 @@ NTSTATUS gp_list_gpos(struct gp_context *gp_ctx, struct security_token *token, c *ret = gpos; return NT_STATUS_OK; } + +NTSTATUS gp_add_gplink(struct gp_context *gp_ctx, const char *dn_str, struct gp_link *gplink) +{ + TALLOC_CTX *mem_ctx; + struct ldb_result *result; + struct ldb_dn *dn; + struct ldb_message *msg; + const char *attrs[] = { "gPLink", NULL }; + const char *gplink_str; + int rv; + + /* Create a forked memory context, as a base for everything here */ + mem_ctx = talloc_new(gp_ctx); + + dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str); + + rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)"); + if (rv != LDB_SUCCESS) { + DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx))); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + if (result->count != 1) { + talloc_free(mem_ctx); + return NT_STATUS_NOT_FOUND; + } + + gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", ""); + + if (strstr(gplink_str, gplink->dn) != NULL) { + talloc_free(mem_ctx); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + + /* Prepend the new GPO link to the string. This list is backwards in priority. */ + gplink_str = talloc_asprintf(mem_ctx, "[LDAP://%s;%d]%s", gplink->dn, gplink->options, gplink_str); + + msg = ldb_msg_new(mem_ctx); + msg->dn = dn; + + rv = ldb_msg_add_string(msg, "gPLink", gplink_str); + if (rv != 0) { + DEBUG(0, ("LDB message add string failed: %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/policy.h b/source4/lib/policy/policy.h index 2e58094608..0f78b0f8b8 100644 --- a/source4/lib/policy/policy.h +++ b/source4/lib/policy/policy.h @@ -57,9 +57,11 @@ struct gp_link { const char *dn; }; +#if 0 /* Not used yet */ NTSTATUS gp_fetch_gpo(TALLOC_CTX *mem_ctx, struct ldb_context *ldb); NTSTATUS gp_apply_gpo(TALLOC_CTX *mem_ctx, struct ldb_context *ldb); NTSTATUS gp_check_refresh_gpo(TALLOC_CTX *mem_ctx, struct ldb_context *ldb); +#endif NTSTATUS gp_init(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, @@ -67,12 +69,18 @@ NTSTATUS gp_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct gp_context **gp_ctx); NTSTATUS gp_list_all_gpos(struct gp_context *gp_ctx, struct gp_object ***ret); -NTSTATUS gp_get_gpo_info(struct gp_context *gp_ctx, const char *name, struct gp_object **ret); NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *req_dn, struct gp_link ***ret); NTSTATUS gp_list_gpos(struct gp_context *gp_ctx, struct security_token *token, const char ***ret); +NTSTATUS gp_get_gpo_info(struct gp_context *gp_ctx, const char *dn_str, struct gp_object **ret); +NTSTATUS gp_set_gpo_info(struct gp_context *gp_ctx, const char *dn_str, struct gp_object *gpo); +NTSTATUS gp_del_gpo(struct gp_context *gp_ctx, const char *dn_str); + NTSTATUS gp_get_gplink_options(TALLOC_CTX *mem_ctx, uint32_t flags, const char ***ret); NTSTATUS gp_get_gpo_flags(TALLOC_CTX *mem_ctx, uint32_t flags, const char ***ret); +NTSTATUS gp_add_gplink(struct gp_context *gp_ctx, const char *dn_str, struct gp_link *gplink); +NTSTATUS gp_del_gplink(struct gp_context *gp_ctx, const char *dn_str, const char *gp_dn); + #endif diff --git a/source4/utils/net/net_gpo.c b/source4/utils/net/net_gpo.c index 6301fc2129..e828899cac 100644 --- a/source4/utils/net/net_gpo.c +++ b/source4/utils/net/net_gpo.c @@ -272,14 +272,64 @@ static int net_gpo_list(struct net_context *ctx, int argc, const char **argv) return 0; } +static int net_gpo_link_add_usage(struct net_context *ctx, int argc, const char **argv) +{ + d_printf("Syntax: net gpo linkadd <container> <gpo> ['disable'] ['enforce'] [options]\n"); + d_printf("For a list of available options, please type net gpo linkadd --help\n"); + return 0; +} + +static int net_gpo_link_add(struct net_context *ctx, int argc, const char **argv) +{ + struct gp_link *gplink = talloc_zero(ctx, struct gp_link); + struct gp_context *gp_ctx; + unsigned int i; + NTSTATUS status; + + if (argc < 2) { + return net_gpo_link_add_usage(ctx, argc, argv); + } + + if (argc >= 3) { + for (i = 2; i < argc; i++) { + if (strcmp(argv[i], "disable") == 0) { + gplink->options |= GPLINK_OPT_DISABLE; + } + if (strcmp(argv[i], "enforce") == 0) { + gplink->options |= GPLINK_OPT_ENFORCE; + } + } + } + gplink->dn = argv[1]; + + status = gp_init(ctx, ctx->lp_ctx, ctx->credentials, ctx->event_ctx, &gp_ctx); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to connect to DC's LDAP: %s\n", get_friendly_nt_error_msg(status))); + return 1; + } + + status = gp_add_gplink(gp_ctx, argv[0], gplink); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to add GPO link to container: %s\n", get_friendly_nt_error_msg(status))); + return 1; + } + d_printf("Added link to container.\n"); + + /* Display current links */ + net_gpo_link_get(ctx, 1, argv); + + 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 }, { "getgpo", "List specificied GPO\n", net_gpo_get_gpo, net_gpo_get_gpo_usage }, { "linkget", "List gPLink of container\n", net_gpo_link_get, net_gpo_link_get_usage }, -/* { "apply", "Apply GPO to container\n", net_gpo_apply, net_gpo_usage }, */ -// { "linkadd", "Link a GPO to a container\n", net_gpo_link_add, net_gpo_usage }, + { "linkadd", "Link a GPO to a container\n", net_gpo_link_add, net_gpo_link_add_usage }, /* { "linkdelete", "Delete GPO link from a container\n", net_gpo_link_delete, net_gpo_usage }, */ { "list", "List all GPO's for a machine/user\n", net_gpo_list, net_gpo_list_usage }, +/* { "apply", "Apply GPO to container\n", net_gpo_apply, net_gpo_usage }, */ // { "refresh", "List all GPO's for machine/user and download them\n", net_gpo_refresh, net_gpo_refresh_usage }, { NULL, NULL } }; |