diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/lib/policy/config.mk | 2 | ||||
-rw-r--r-- | source4/lib/policy/gp_filesys.c | 161 | ||||
-rw-r--r-- | source4/lib/policy/gp_ldap.c | 140 | ||||
-rw-r--r-- | source4/lib/policy/gp_manage.c | 172 | ||||
-rw-r--r-- | source4/lib/policy/policy.h | 14 | ||||
-rw-r--r-- | source4/lib/policy/wscript_build | 2 | ||||
-rw-r--r-- | source4/utils/net/net_gpo.c | 34 |
7 files changed, 506 insertions, 19 deletions
diff --git a/source4/lib/policy/config.mk b/source4/lib/policy/config.mk index 74403f8565..0a3e731c54 100644 --- a/source4/lib/policy/config.mk +++ b/source4/lib/policy/config.mk @@ -1,6 +1,6 @@ [SUBSYSTEM::policy] PRIVATE_DEPENDENCIES = LIBLDB LIBSAMBA-NET -policy_OBJ_FILES = $(policydir)/gp_ldap.o $(policydir)/gp_filesys.c +policy_OBJ_FILES = $(policydir)/gp_ldap.o $(policydir)/gp_filesys.c $(policydir)/gp_manage.c PC_FILES += $(policydir)/policy.pc diff --git a/source4/lib/policy/gp_filesys.c b/source4/lib/policy/gp_filesys.c index 771ba5e072..388c1d25b8 100644 --- a/source4/lib/policy/gp_filesys.c +++ b/source4/lib/policy/gp_filesys.c @@ -24,6 +24,8 @@ #include "libcli/resolve/resolve.h" #include <sys/stat.h> #include <fcntl.h> +#include <unistd.h> +#include <dirent.h> #define GP_MAX_DEPTH 25 @@ -184,7 +186,7 @@ static NTSTATUS gp_cli_connect(struct gp_context *gp_ctx) return NT_STATUS_OK; } -NTSTATUS gp_fetch_gpo (struct gp_context *gp_ctx, struct gp_object *gpo, const char **ret_local_path) +NTSTATUS gp_fetch_gpt (struct gp_context *gp_ctx, struct gp_object *gpo, const char **ret_local_path) { TALLOC_CTX *mem_ctx; struct gp_list_state *state; @@ -246,3 +248,160 @@ NTSTATUS gp_fetch_gpo (struct gp_context *gp_ctx, struct gp_object *gpo, const c talloc_free(mem_ctx); return NT_STATUS_OK; } + +static NTSTATUS push_recursive (struct gp_context *gp_ctx, const char *local_path, const char *remote_path, int depth) +{ + DIR *dir; + struct dirent *dirent; + char *entry_local_path; + char *entry_remote_path; + int local_fd, remote_fd; + int buf[1024]; + int nread, total_read; + + dir = opendir(local_path); + while ((dirent = readdir(dir)) != NULL) { + if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) { + continue; + } + + entry_local_path = talloc_asprintf(gp_ctx, "%s/%s", local_path, dirent->d_name); + entry_remote_path = talloc_asprintf(gp_ctx, "%s\\%s", remote_path, dirent->d_name); + if (dirent->d_type == DT_DIR) { + DEBUG(6, ("Pushing directory %s to %s on sysvol\n", entry_local_path, entry_remote_path)); + smbcli_mkdir(gp_ctx->cli->tree, entry_remote_path); + if (depth < GP_MAX_DEPTH) + push_recursive(gp_ctx, entry_local_path, entry_remote_path, depth+1); + } else { + DEBUG(6, ("Pushing file %s to %s on sysvol\n", entry_local_path, entry_remote_path)); + remote_fd = smbcli_open(gp_ctx->cli->tree, entry_remote_path, O_WRONLY | O_CREAT, 0); + if (remote_fd < 0) { + talloc_free(entry_local_path); + talloc_free(entry_remote_path); + DEBUG(0, ("Failed to create remote file: %s\n", entry_remote_path)); + return NT_STATUS_UNSUCCESSFUL; + } + local_fd = open(entry_local_path, O_RDONLY); + if (local_fd < 0) { + talloc_free(entry_local_path); + talloc_free(entry_remote_path); + DEBUG(0, ("Failed to open local file: %s\n", entry_local_path)); + return NT_STATUS_UNSUCCESSFUL; + } + total_read = 0; + while ((nread = read(local_fd, &buf, sizeof(buf)))) { + smbcli_write(gp_ctx->cli->tree, remote_fd, 0, &buf, total_read, nread); + total_read += nread; + } + + close(local_fd); + smbcli_close(gp_ctx->cli->tree, remote_fd); + } + talloc_free(entry_local_path); + talloc_free(entry_remote_path); + } + closedir(dir); + + return NT_STATUS_OK; +} + + + +NTSTATUS gp_push_gpt(struct gp_context *gp_ctx, const char *local_path, const char *file_sys_path) +{ + NTSTATUS status; + unsigned int i, bkslash_cnt; + char *share_path; + + if (gp_ctx->cli == NULL) { + status = gp_cli_connect(gp_ctx); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to create cli connection to DC\n")); + return status; + } + } + + /* Get the path from the share down (\\..\..\(this\stuff) */ + for (i = 0, bkslash_cnt = 0; file_sys_path[i] != '\0'; i++) { + if (file_sys_path[i] == '\\') + bkslash_cnt++; + + if (bkslash_cnt == 4) { + share_path = talloc_strdup(gp_ctx, &file_sys_path[i]); + break; + } + } + + DEBUG(5, ("Copying %s to %s on sysvol\n", local_path, share_path)); + + smbcli_mkdir(gp_ctx->cli->tree, share_path); + + status = push_recursive(gp_ctx, local_path, share_path, 0); + + talloc_free(share_path); + return status; +} + +NTSTATUS gp_create_gpt(struct gp_context *gp_ctx, const char *name, const char *file_sys_path) +{ + TALLOC_CTX *mem_ctx; + const char *tmp_dir, *policy_dir, *tmp_str; + int rv; + int fd; + NTSTATUS status; + + /* Create a forked memory context, as a base for everything here */ + mem_ctx = talloc_new(gp_ctx); + + tmp_dir = gp_tmpdir(mem_ctx); + policy_dir = talloc_asprintf(mem_ctx, "%s/%s", tmp_dir, name); + rv = mkdir(policy_dir, 0755); + if (rv < 0) { + DEBUG(0, ("Could not create the policy dir: %s\n", policy_dir)); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + tmp_str = talloc_asprintf(mem_ctx, "%s/User", policy_dir); + rv = mkdir(tmp_str, 0755); + if (rv < 0) { + DEBUG(0, ("Could not create the User dir: %s\n", tmp_str)); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + tmp_str = talloc_asprintf(mem_ctx, "%s/Machine", policy_dir); + rv = mkdir(tmp_str, 0755); + if (rv < 0) { + DEBUG(0, ("Could not create the Machine dir: %s\n", tmp_str)); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + tmp_str = talloc_asprintf(mem_ctx, "%s/GPT.INI", policy_dir); + fd = open(tmp_str, O_CREAT | O_WRONLY, 0644); + if (fd < 0) { + DEBUG(0, ("Could not create the GPT.INI: %s\n", tmp_str)); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + rv = write(fd, "[General]\r\nVersion=0\r\n", 23); + if (rv != 23) { + DEBUG(0, ("Short write in GPT.INI\n")); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + close(fd); + + + status = gp_push_gpt(gp_ctx, policy_dir, file_sys_path); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + talloc_free(mem_ctx); + return NT_STATUS_OK; +} diff --git a/source4/lib/policy/gp_ldap.c b/source4/lib/policy/gp_ldap.c index a7d5eb6158..b8b24d4c86 100644 --- a/source4/lib/policy/gp_ldap.c +++ b/source4/lib/policy/gp_ldap.c @@ -367,8 +367,7 @@ NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *dn_str, struct gp } } } - DEBUG(0, ("Object or gPLink attribute not found.\n")); - return NT_STATUS_NOT_FOUND; + gplink_str = talloc_strdup(mem_ctx, ""); found: @@ -661,14 +660,22 @@ NTSTATUS gp_del_gplink(struct gp_context *gp_ctx, const char *dn_str, const char 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; + if (strcmp(gplink_str, "") == 0) { + rv = ldb_msg_add_empty(msg, "gPLink", LDB_FLAG_MOD_DELETE, NULL); + if (rv != 0) { + DEBUG(0, ("LDB message add empty element failed: %s\n", ldb_strerror(rv))); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + } else { + 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; } - 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))); @@ -740,3 +747,118 @@ NTSTATUS gp_set_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum talloc_free(msg); return NT_STATUS_OK; } + +NTSTATUS gp_create_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo) +{ + struct ldb_message *msg; + TALLOC_CTX *mem_ctx; + int rv; + char *dn_str; + struct ldb_dn *child_dn, *gpo_dn; + + mem_ctx = talloc_new(gp_ctx); + + /* CN={GUID} */ + msg = ldb_msg_new(mem_ctx); + + msg->dn = ldb_get_default_basedn(gp_ctx->ldb_ctx); + dn_str = talloc_asprintf(mem_ctx, "CN=%s,CN=Policies,CN=System", gpo->name); + child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str); + rv = ldb_dn_add_child(msg->dn, child_dn); + if (!rv) goto ldb_msg_add_error; + + rv = ldb_msg_add_string(msg, "objectClass", "top"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "objectClass", "container"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "objectClass", "groupPolicyContainer"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "displayName", gpo->display_name); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "name", gpo->name); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "CN", gpo->name); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "gPCFileSysPath", gpo->file_sys_path); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "flags", + talloc_asprintf(mem_ctx, "%d", gpo->flags)); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "versionNumber", + talloc_asprintf(mem_ctx, "%d", gpo->version)); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "gpCFunctionalityVersion", "2"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + + /* FIXME Add security descriptor as well */ + + rv = ldb_add(gp_ctx->ldb_ctx, msg); + if (rv != LDB_SUCCESS) { + DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx))); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + gpo_dn = msg->dn; + + /* CN=User */ + msg = ldb_msg_new(mem_ctx); + msg->dn = ldb_dn_copy(mem_ctx, gpo_dn); + child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=User"); + rv = ldb_dn_add_child(msg->dn, child_dn); + if (!rv) goto ldb_msg_add_error; + + rv = ldb_msg_add_string(msg, "objectClass", "top"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "objectClass", "container"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "CN", "User"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "name", "User"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + + rv = ldb_add(gp_ctx->ldb_ctx, msg); + if (rv != LDB_SUCCESS) { + DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx))); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + /* CN=Machine */ + msg = ldb_msg_new(mem_ctx); + msg->dn = ldb_dn_copy(mem_ctx, gpo_dn); + child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=Machine"); + rv = ldb_dn_add_child(msg->dn, child_dn); + if (!rv) goto ldb_msg_add_error; + + rv = ldb_msg_add_string(msg, "objectClass", "top"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "objectClass", "container"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "CN", "Machine"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + rv = ldb_msg_add_string(msg, "name", "Machine"); + if (rv != LDB_SUCCESS) goto ldb_msg_add_error; + + rv = ldb_add(gp_ctx->ldb_ctx, msg); + if (rv != LDB_SUCCESS) { + DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx))); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + + talloc_free(mem_ctx); + return NT_STATUS_OK; + + ldb_msg_add_error: + DEBUG(0, ("LDB Error adding element to ldb message\n")); + talloc_free(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; +} diff --git a/source4/lib/policy/gp_manage.c b/source4/lib/policy/gp_manage.c new file mode 100644 index 0000000000..d273678207 --- /dev/null +++ b/source4/lib/policy/gp_manage.c @@ -0,0 +1,172 @@ +/* + * Unix SMB/CIFS implementation. + * Group Policy Object Support + * Copyright (C) Wilco Baan Hofman 2010 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#include "includes.h" +#include "../libcli/security/dom_sid.h" +#include "../libcli/security/security_descriptor.h" +#include "../librpc/ndr/libndr.h" +#include "param/param.h" +#include "lib/policy/policy.h" + +static uint32_t gp_ads_to_dir_access_mask(uint32_t access_mask) +{ + uint32_t fs_mask; + + /* Copy the standard access mask */ + fs_mask = access_mask & 0x001F0000; + + /* When READ_PROP and LIST_CONTENTS are set, read access is granted on the GPT */ + if (access_mask & SEC_ADS_READ_PROP && access_mask & SEC_ADS_LIST) { + fs_mask |= SEC_STD_SYNCHRONIZE | SEC_DIR_LIST | SEC_DIR_READ_ATTRIBUTE | + SEC_DIR_READ_EA | SEC_DIR_TRAVERSE; + } + + /* When WRITE_PROP is set, full write access is granted on the GPT */ + if (access_mask & SEC_ADS_WRITE_PROP) { + fs_mask |= SEC_STD_SYNCHRONIZE | SEC_DIR_WRITE_ATTRIBUTE | + SEC_DIR_WRITE_EA | SEC_DIR_ADD_FILE | + SEC_DIR_ADD_SUBDIR; + } + + /* Map CREATE_CHILD to add file and add subdir */ + if (access_mask & SEC_ADS_CREATE_CHILD) + fs_mask |= SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR; + + /* Map ADS delete child to dir delete child */ + if (access_mask & SEC_ADS_DELETE_CHILD) + fs_mask |= SEC_DIR_DELETE_CHILD; + + return fs_mask; +} + +NTSTATUS gp_create_gpt_security_descriptor (TALLOC_CTX *mem_ctx, struct security_descriptor *ds_sd, struct security_descriptor **ret) +{ + struct security_descriptor *fs_sd; + uint32_t i; + + /* Allocate the file system security descriptor */ + fs_sd = talloc(mem_ctx, struct security_descriptor); + + /* Copy the basic information from the directory server security descriptor */ + fs_sd->owner_sid = talloc_memdup(fs_sd, fs_sd->owner_sid, sizeof(struct dom_sid)); + fs_sd->group_sid = talloc_memdup(fs_sd, fs_sd->group_sid, sizeof(struct dom_sid)); + fs_sd->type = ds_sd->type; + fs_sd->revision = ds_sd->revision; + + /* Copy the sacl */ + fs_sd->sacl = security_acl_dup(fs_sd, ds_sd->sacl); + + /* Copy the dacl */ + fs_sd->dacl = talloc_zero(fs_sd, struct security_acl); + + for (i = 0; i < ds_sd->dacl->num_aces; i++) { + char *trustee = dom_sid_string(fs_sd, &ds_sd->dacl->aces[i].trustee); + struct security_ace *ace; + + /* Don't add the allow for SID_BUILTIN_PREW2K */ + if (!(ds_sd->dacl->aces[i].type & SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) && + strcmp(trustee, SID_BUILTIN_PREW2K) == 0) { + talloc_free(trustee); + continue; + } + + /* Copy the ace from the directory server security descriptor */ + ace = talloc_memdup(fs_sd, &ds_sd->dacl->aces[i], sizeof(struct security_ace)); + + /* Set specific inheritance flags for within the GPO */ + ace->flags |= SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT; + if (strcmp(trustee, SID_CREATOR_OWNER) == 0) { + ace->flags |= SEC_ACE_FLAG_INHERIT_ONLY; + } + + /* Get a directory access mask from the assigned access mask on the LDAP object */ + ace->access_mask = gp_ads_to_dir_access_mask(ace->access_mask); + + /* Add the ace to the security descriptor DACL */ + security_descriptor_dacl_add(fs_sd, ace); + + /* Clean up the allocated data in this iteration */ + talloc_free(trustee); + } + + *ret = fs_sd; + return NT_STATUS_OK; +} + + +NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, struct gp_object **ret) +{ + struct GUID guid_struct; + char *guid_str; + char *name; + //struct security_descriptor *sd; + TALLOC_CTX *mem_ctx; + struct gp_object *gpo; + unsigned int i; + NTSTATUS status; + + /* Create a forked memory context, as a base for everything here */ + mem_ctx = talloc_new(gp_ctx); + + /* Create the gpo struct to return later */ + gpo = talloc(gp_ctx, struct gp_object); + + /* Generate GUID */ + guid_struct = GUID_random(); + guid_str = GUID_string(mem_ctx, &guid_struct); + name = talloc_asprintf(gpo, "{%s}", guid_str); + for (i = 0; name[i] != '\0'; i++) { + name[i] = toupper(name[i]); + } + + gpo->name = name; + gpo->flags = 0; + gpo->version = 0; + gpo->display_name = talloc_strdup(gpo, display_name); + gpo->file_sys_path = talloc_asprintf(gpo, "\\\\%s\\sysvol\\%s\\Policies\\%s", lp_realm(gp_ctx->lp_ctx), lp_realm(gp_ctx->lp_ctx), name); + + /* FIXME: Add gpo->security_descriptor */ + + /* Create the GPT */ + status = gp_create_gpt(gp_ctx, name, gpo->file_sys_path); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to create GPT\n")); + return status; + } + + /* Create matching file and DS security descriptors */ +/* 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")); + return status; + } +*/ + + /* Create the LDAP GPO, including CN=User and CN=Machine */ + status = gp_create_ldap_gpo(gp_ctx, gpo); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to create LDAP group policy object\n")); + return status; + } + + + talloc_free(mem_ctx); + + *ret = gpo; + return NT_STATUS_OK; +} diff --git a/source4/lib/policy/policy.h b/source4/lib/policy/policy.h index c02253f377..9f45b965e4 100644 --- a/source4/lib/policy/policy.h +++ b/source4/lib/policy/policy.h @@ -61,11 +61,6 @@ 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, @@ -73,6 +68,7 @@ NTSTATUS gp_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct gp_context **gp_ctx); + /* LDAP functions */ NTSTATUS gp_list_all_gpos(struct gp_context *gp_ctx, struct gp_object ***ret); NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *req_dn, struct gp_link ***ret); @@ -91,7 +87,13 @@ NTSTATUS gp_del_gplink(struct gp_context *gp_ctx, const char *dn_str, const char NTSTATUS gp_get_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance *inheritance); 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); + /* File system functions */ -NTSTATUS gp_fetch_gpo (struct gp_context *gp_ctx, struct gp_object *gpo, const char **path); +NTSTATUS gp_fetch_gpt (struct gp_context *gp_ctx, struct gp_object *gpo, const char **path); +NTSTATUS gp_create_gpt(struct gp_context *gp_ctx, const char *name, const char *file_sys_path); + +/* Managing functions */ +NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, struct gp_object **ret); #endif diff --git a/source4/lib/policy/wscript_build b/source4/lib/policy/wscript_build index d47be384cb..4c832efd32 100644 --- a/source4/lib/policy/wscript_build +++ b/source4/lib/policy/wscript_build @@ -1,7 +1,7 @@ #!/usr/bin/env python bld.SAMBA_LIBRARY('policy', - source='gp_ldap.c gp_filesys.c', + source='gp_ldap.c gp_filesys.c gp_manage.c', pc_files='policy.pc', public_deps='LIBLDB LIBSAMBA-NET', public_headers='policy.h', diff --git a/source4/utils/net/net_gpo.c b/source4/utils/net/net_gpo.c index a990098ed9..4a280a239c 100644 --- a/source4/utils/net/net_gpo.c +++ b/source4/utils/net/net_gpo.c @@ -470,7 +470,7 @@ static int net_gpo_fetch(struct net_context *ctx, int argc, const char **argv) return 1; } - rv = gp_fetch_gpo(gp_ctx, gpo, &path); + rv = gp_fetch_gpt(gp_ctx, gpo, &path); if (!NT_STATUS_IS_OK(rv)) { DEBUG(0, ("Failed to fetch GPO: %s\n", get_friendly_nt_error_msg(rv))); return 1; @@ -479,7 +479,38 @@ static int net_gpo_fetch(struct net_context *ctx, int argc, const char **argv) return 0; } +static int net_gpo_create_usage(struct net_context *ctx, int argc, const char **argv) +{ + d_printf("Syntax: net gpo create <displayname> [options]\n"); + d_printf("For a list of available options, please type net gpo create --help\n"); + return 0; +} + +static int net_gpo_create(struct net_context *ctx, int argc, const char **argv) +{ + struct gp_context *gp_ctx; + struct gp_object *gpo; + NTSTATUS rv; + + if (argc != 1) { + return net_gpo_create_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; + } + + rv = gp_create_gpo(gp_ctx, argv[0], &gpo); + if (!NT_STATUS_IS_OK(rv)) { + DEBUG(0, ("Failed to create GPO: %s\n", get_friendly_nt_error_msg(rv))); + return 1; + } + + 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 }, @@ -490,6 +521,7 @@ static const struct net_functable net_gpo_functable[] = { { "getinheritance", "Get inheritance flag from a container\n", net_gpo_inheritance_get, net_gpo_inheritance_get_usage }, { "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 }, { NULL, NULL } }; |