diff options
-rw-r--r-- | source4/Makefile.in | 2 | ||||
-rw-r--r-- | source4/libgpo/ads_convenience.c | 284 | ||||
-rw-r--r-- | source4/libgpo/ads_convenience.h | 103 | ||||
-rw-r--r-- | source4/libgpo/config.mk | 4 | ||||
-rw-r--r-- | source4/libgpo/gpo.h | 56 | ||||
-rw-r--r-- | source4/libgpo/gpo_filesync.c | 241 | ||||
-rw-r--r-- | source4/libgpo/gpo_ldap.c | 150 | ||||
-rw-r--r-- | source4/libgpo/gpo_s4.h | 40 | ||||
-rw-r--r-- | source4/main.mk | 2 | ||||
-rw-r--r-- | source4/utils/net/config.mk | 4 | ||||
-rw-r--r-- | source4/utils/net/net.c | 1 | ||||
-rw-r--r-- | source4/utils/net/net_gpo.c | 85 |
12 files changed, 301 insertions, 671 deletions
diff --git a/source4/Makefile.in b/source4/Makefile.in index 40ea2868dd..b40d367602 100644 --- a/source4/Makefile.in +++ b/source4/Makefile.in @@ -46,7 +46,7 @@ ALL_PREDEP = basics .NOTPARALLEL: endif -base_srcdirs = $(srcdir) ../librpc/ ../lib/ ../libcli ../libgpo ../nsswitch ../libds +base_srcdirs = $(srcdir) ../librpc/ ../lib/ ../libcli ../nsswitch ../libds include $(srcdir)/build/make/rules.mk include $(srcdir)/build/make/python.mk diff --git a/source4/libgpo/ads_convenience.c b/source4/libgpo/ads_convenience.c deleted file mode 100644 index 09ceecc752..0000000000 --- a/source4/libgpo/ads_convenience.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - Samba CIFS implementation - ADS convenience functions for GPO - - Copyright (C) 2001 Andrew Tridgell (from samba3 ads.c) - Copyright (C) 2001 Remus Koos (from samba3 ads.c) - Copyright (C) 2001 Andrew Bartlett (from samba3 ads.c) - Copyright (C) 2008 Jelmer Vernooij, jelmer@samba.org - Copyright (C) 2008 Wilco Baan Hofman, wilco@baanhofman.nl - - 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 "libnet/libnet.h" -#include "librpc/gen_ndr/ndr_security.h" -#include "libgpo/ads_convenience.h" -#include "param/param.h" -#include "libcli/libcli.h" -#include "ldb_wrap.h" - -static ADS_STATUS ads_connect(ADS_STRUCT *ads); - -WERROR ads_startup (struct libnet_context *netctx, ADS_STRUCT **ads) -{ - *ads = talloc(netctx, ADS_STRUCT); - (*ads)->netctx = netctx; - - ads_connect(*ads); - - return WERR_OK; -} - -static ADS_STATUS ads_connect(ADS_STRUCT *ads) -{ - struct libnet_LookupDCs *io; - char *url; - - io = talloc_zero(ads, struct libnet_LookupDCs); - - /* We are looking for the PDC of the active domain. */ - io->in.name_type = NBT_NAME_PDC; - io->in.domain_name = lp_workgroup(ads->netctx->lp_ctx); - libnet_LookupDCs(ads->netctx, ads, io); - - url = talloc_asprintf(ads, "ldap://%s", io->out.dcs[0].name); - ads->ldbctx = ldb_wrap_connect(ads, ads->netctx->event_ctx, ads->netctx->lp_ctx, - url, NULL, ads->netctx->cred, 0); - if (ads->ldbctx == NULL) { - return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); - } - - return ADS_ERROR_NT(NT_STATUS_OK); -} - -ADS_STATUS ads_search_dn(ADS_STRUCT *ads, LDAPMessage **res, - const char *dn, const char **attrs) -{ - ADS_STATUS status; - - status.err.rc = ldb_search(ads->ldbctx, ads, res, - ldb_dn_new(ads, ads->ldbctx, dn), - LDB_SCOPE_BASE, - attrs, - "(objectclass=*)"); - - status.error_type = ENUM_ADS_ERROR_LDAP; - return status; -} - -const char * ads_get_dn(ADS_STRUCT *ads, LDAPMessage *res) -{ - return ldb_dn_get_linearized(res->msgs[0]->dn); -} - -bool ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *ctx, LDAPMessage *res, const char *field, struct security_descriptor **sd) -{ - const struct ldb_val *val; - enum ndr_err_code ndr_err; - - val = ldb_msg_find_ldb_val(res->msgs[0], field); - - *sd = talloc(ctx, struct security_descriptor); - if (*sd == NULL) { - return -1; - } - /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */ - ndr_err = ndr_pull_struct_blob(val, *sd, NULL, *sd, - (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(*sd); - return -1; - } - return 0; -} - -ADS_STATUS ads_search_retry_dn_sd_flags(ADS_STRUCT *ads, LDAPMessage **res, uint32_t sd_flags, - const char *dn, const char **attrs) -{ - return ads_do_search_all_sd_flags(ads, dn, LDB_SCOPE_BASE, "(objectclass=*)", attrs, sd_flags, res); -} - -ADS_STATUS ads_do_search_all_sd_flags (ADS_STRUCT *ads, const char *dn, int scope, - const char *filter, const char **attrs, - uint32_t sd_flags, LDAPMessage **res) -{ - int rv; - struct ldb_request *req; - struct ldb_control **controls; - struct ldb_parse_tree *tree; - struct ldb_dn *ldb_dn; - - controls = talloc_zero_array(ads, struct ldb_control *, 2); - controls[0] = talloc(ads, struct ldb_control); - controls[0]->oid = LDB_CONTROL_SD_FLAGS_OID; - controls[0]->data = &sd_flags; - controls[0]->critical = 1; - - tree = ldb_parse_tree(ads, filter); - - ldb_dn = ldb_dn_new(ads, ads->ldbctx, dn); - - rv = ldb_build_search_req_ex(&req, ads->ldbctx, (TALLOC_CTX *)res, ldb_dn, scope, tree, attrs, controls, - res, ldb_search_default_callback, NULL); - if (rv != LDB_SUCCESS) { - talloc_free(*res); - talloc_free(req); - talloc_free(tree); - return ADS_ERROR(rv); - } - rv = ldb_request(ads->ldbctx, req); - if (rv == LDB_SUCCESS) { - rv = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - talloc_free(req); - talloc_free(tree); - return ADS_ERROR(rv); - -} - -const char * ads_pull_string(ADS_STRUCT *ads, TALLOC_CTX *ctx, LDAPMessage *res, const char *field) -{ - return ldb_msg_find_attr_as_string(res->msgs[0], field, NULL); -} - -bool ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *res, const char *field, uint32_t *ret) -{ - if (ldb_msg_find_element(res->msgs[0], field) == NULL) { - return false; - } - *ret = ldb_msg_find_attr_as_uint(res->msgs[0], field, 0); - return true; -} - - -int ads_count_replies(ADS_STRUCT *ads, LDAPMessage *res) -{ - return res->count; -} - -ADS_STATUS ads_msgfree(ADS_STRUCT *ads, LDAPMessage *res) -{ - talloc_free(res); - return ADS_ERROR_NT(NT_STATUS_OK); -} - -/* - do a rough conversion between ads error codes and NT status codes - we'll need to fill this in more -*/ -NTSTATUS ads_ntstatus(ADS_STATUS status) -{ - switch (status.error_type) { - case ENUM_ADS_ERROR_NT: - return status.err.nt_status; - case ENUM_ADS_ERROR_SYSTEM: - return map_nt_error_from_unix(status.err.rc); - case ENUM_ADS_ERROR_LDAP: - if (status.err.rc == LDB_SUCCESS) { - return NT_STATUS_OK; - } - return NT_STATUS_UNSUCCESSFUL; - default: - break; - } - - if (ADS_ERR_OK(status)) { - return NT_STATUS_OK; - } - return NT_STATUS_UNSUCCESSFUL; -} - -/* - return a string for an error from an ads routine -*/ -const char *ads_errstr(ADS_STATUS status) -{ - switch (status.error_type) { - case ENUM_ADS_ERROR_SYSTEM: - return strerror(status.err.rc); - case ENUM_ADS_ERROR_LDAP: - return ldb_strerror(status.err.rc); - case ENUM_ADS_ERROR_NT: - return get_friendly_nt_error_msg(ads_ntstatus(status)); - default: - return "Unknown ADS error type!? (not compiled in?)"; - } -} - -ADS_STATUS ads_build_ldap_error(int ldb_error) -{ - ADS_STATUS ret; - ret.err.rc = ldb_error; - ret.error_type = ENUM_ADS_ERROR_LDAP; - return ret; -} - -ADS_STATUS ads_build_nt_error(NTSTATUS nt_status) -{ - ADS_STATUS ret; - ret.err.nt_status = nt_status; - ret.error_type = ENUM_ADS_ERROR_NT; - return ret; -} - - -bool nt_token_check_sid( const struct dom_sid *sid, const NT_USER_TOKEN *token) -{ - int i; - - if (!sid || !token) { - return false; - } - - if (dom_sid_equal(sid, token->user_sid)) { - return true; - } - if (dom_sid_equal(sid, token->group_sid)) { - return true; - } - for (i = 0; i < token->num_sids; i++) { - if (dom_sid_equal(sid, token->sids[i])) { - return true; - } - } - - return false; -} -const char *ads_get_ldap_server_name(ADS_STRUCT *ads) { - return ads->ldap_server_name; -} - - -/* - FIXME - Stub write functions, these do not do anything, though they should. -- Wilco -*/ - -ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) -{ - return NULL; -} - -ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val) -{ - return ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED); -} - -ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) -{ - return ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED); -} diff --git a/source4/libgpo/ads_convenience.h b/source4/libgpo/ads_convenience.h deleted file mode 100644 index ce2b9b6a06..0000000000 --- a/source4/libgpo/ads_convenience.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Samba CIFS implementation - ADS convenience functions for GPO - - Copyright (C) 2008 Jelmer Vernooij, jelmer@samba.org - Copyright (C) 2008 Wilco Baan Hofman, wilco@baanhofman.nl - - 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/>. -*/ - -#ifndef __ADS_CONVENIENCE_H__ -#define __ADS_CONVENIENCE_H__ - -#include "librpc/gen_ndr/security.h" - -#define ADS_ERR_OK(status) ((status.error_type == ENUM_ADS_ERROR_NT) ? NT_STATUS_IS_OK(status.err.nt_status):(status.err.rc == 0)) -#define ADS_ERROR(rc) ads_build_ldap_error(rc) -#define ADS_ERROR_NT(rc) ads_build_nt_error(rc) -#define ADS_SUCCESS ADS_ERROR(0) - -#define ADS_ERROR_HAVE_NO_MEMORY(x) do { \ - if (!(x)) {\ - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);\ - }\ -} while (0) - -#define LDAP_SCOPE_BASE LDB_SCOPE_BASE -#define LDAP_SCOPE_SUBTREE LDB_SCOPE_SUBTREE -#define LDAP_SCOPE_ONELEVEL LDB_SCOPE_ONELEVEL - - - - -typedef struct { - struct libnet_context *netctx; - struct ldb_context *ldbctx; - char *ldap_server_name; - - /* State information for the smb connection */ - struct cli_credentials *credentials; - struct smbcli_state *cli; -} ADS_STRUCT; - - -typedef struct security_token NT_USER_TOKEN; - -typedef struct ldb_result LDAPMessage; -typedef void ** ADS_MODLIST; - -/* there are 3 possible types of errors the ads subsystem can produce */ -enum ads_error_type { ENUM_ADS_ERROR_LDAP, ENUM_ADS_ERROR_SYSTEM, ENUM_ADS_ERROR_NT}; - -typedef struct { - enum ads_error_type error_type; - union err_state{ - int rc; - NTSTATUS nt_status; - } err; - int minor_status; -} ADS_STATUS; - - -/* Prototypes from ads_convenience.c */ -ADS_STATUS ads_build_nt_error(NTSTATUS); -ADS_STATUS ads_build_ldap_error(int); - -ADS_STATUS ads_startup (struct libnet_context *netctx, ADS_STRUCT **ads); -const char *ads_errstr(ADS_STATUS status); -const char * ads_get_dn(ADS_STRUCT *ads, LDAPMessage *res); -bool ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *ctx, LDAPMessage *res, const char *field, struct security_descriptor **sd); -const char * ads_pull_string(ADS_STRUCT *ads, TALLOC_CTX *ctx, LDAPMessage *res, const char *field); -bool ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *res, const char *field, uint32_t *ret); -int ads_count_replies(ADS_STRUCT *ads, LDAPMessage *res); -ADS_STATUS ads_do_search_all_sd_flags (ADS_STRUCT *ads, const char *dn, int scope, - const char *filter, const char **attrs, - uint32_t sd_flags, LDAPMessage **res); -ADS_STATUS ads_search_dn(ADS_STRUCT *ads, LDAPMessage **res, - const char *dn, const char **attrs); -ADS_STATUS ads_search_retry_dn_sd_flags(ADS_STRUCT *ads, LDAPMessage **res, uint32_t sd_flags, - const char *dn, const char **attrs); -ADS_STATUS ads_msgfree(ADS_STRUCT *ads, LDAPMessage *res); -NTSTATUS ads_ntstatus(ADS_STATUS status); -ADS_STATUS ads_build_ldap_error(int ldb_error); -ADS_STATUS ads_build_nt_error(NTSTATUS nt_status); -bool nt_token_check_sid( const struct dom_sid *sid, const NT_USER_TOKEN *token); -ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx); -ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val); -ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods); -const char *ads_get_ldap_server_name(ADS_STRUCT *ads); - - -#endif diff --git a/source4/libgpo/config.mk b/source4/libgpo/config.mk new file mode 100644 index 0000000000..77eb3073ac --- /dev/null +++ b/source4/libgpo/config.mk @@ -0,0 +1,4 @@ +[SUBSYSTEM::LIBGPO] +PRIVATE_DEPENDENCIES = LIBLDB LIBSAMBA-NET + +LIBGPO_OBJ_FILES = $(libgpodir)/gpo_ldap.o diff --git a/source4/libgpo/gpo.h b/source4/libgpo/gpo.h new file mode 100644 index 0000000000..808718ea49 --- /dev/null +++ b/source4/libgpo/gpo.h @@ -0,0 +1,56 @@ +/* + * Unix SMB/CIFS implementation. + * Group Policy Object Support + * Copyright (C) Guenther Deschner 2005-2008 (from samba 3 gpo.h) + * 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/>. + */ + +#ifndef __GPO_H__ +#define __GPO_H__ + + +/* GPO_OPTIONS */ +#define GPO_FLAG_DISABLE 0x00000001 +#define GPO_FLAG_FORCE 0x00000002 + +struct gp_context { + struct ldb_context *ldb_ctx; + struct loadparm_context *lp_ctx; + struct cli_credentials *credentials; + struct tevent_context *ev_ctx; +}; + +struct gp_object { + uint32_t version; + uint32_t flags; + const char *display_name; + const char *name; + const char *dn; + const char *file_sys_path; + struct security_descriptor *security_descriptor; +}; + +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); + +NTSTATUS gp_init(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct cli_credentials *creds, + struct tevent_context *ev_ctx, + struct gp_context **gp_ctx); +NTSTATUS gp_list_all_gpos(struct gp_context *gp_ctx, struct gp_object ***ret); +#endif diff --git a/source4/libgpo/gpo_filesync.c b/source4/libgpo/gpo_filesync.c deleted file mode 100644 index 3f6f5f7960..0000000000 --- a/source4/libgpo/gpo_filesync.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Group Policy Object Support - * - * Copyright (C) Guenther Deschner 2006 - * Copyright (C) Wilco Baan Hofman 2008 - * - * 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/libcli.h" -#include "system/filesys.h" - - -struct sync_context { - TALLOC_CTX *mem_ctx; - struct smbcli_state *cli; - char *remote_path; - char *local_path; - char *mask; - uint16_t attribute; -}; - -static void gpo_sync_func(struct clilist_file_info *info, - const char *mask, - void *state); - -NTSTATUS gpo_copy_file(TALLOC_CTX *mem_ctx, - struct smbcli_state *cli, - const char *nt_path, - const char *unix_path) -{ - NTSTATUS result; - int fnum; - int fd = 0; - char *data = NULL; - static int io_bufsize = 64512; - int read_size = io_bufsize; - off_t nread = 0; - - if ((fnum = smbcli_open(cli->tree, nt_path, O_RDONLY, DENY_NONE)) == -1) { - result = NT_STATUS_NO_SUCH_FILE; - goto out; - } - - if ((fd = open(unix_path, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) { - result = map_nt_error_from_unix(errno); - goto out; - } - - if ((data = talloc_size(mem_ctx, read_size)) == NULL) { - result = NT_STATUS_NO_MEMORY; - goto out; - } - - while (1) { - - int n = smbcli_read(cli->tree, fnum, data, nread, read_size); - - if (n <= 0) - break; - - if (write(fd, data, n) != n) { - break; - } - - nread += n; - } - - result = NT_STATUS_OK; - - out: - SAFE_FREE(data); - if (fnum) { - smbcli_close(cli->tree, fnum); - } - if (fd) { - close(fd); - } - - return result; -} - -/**************************************************************** - copy dir -****************************************************************/ - -static NTSTATUS gpo_copy_dir(const char *nt_dir, const char *unix_path) -{ - if ((mkdir(unix_path, 0644)) < 0 && errno != EEXIST) { - return NT_STATUS_ACCESS_DENIED; - } - - return NT_STATUS_OK; -} - -/**************************************************************** - sync files -****************************************************************/ - -static bool gpo_sync_files(struct sync_context *ctx) -{ - DEBUG(3,("calling cli_list with mask: %s\n", ctx->mask)); - - if (smbcli_list(ctx->cli->tree, - ctx->mask, - ctx->attribute, - gpo_sync_func, - ctx) == -1) { - DEBUG(1,("listing [%s] failed with error: %s\n", - ctx->mask, smbcli_errstr(ctx->cli->tree))); - return false; - } - - return true; -} - -/**************************************************************** - syncronisation call back -****************************************************************/ - -static void gpo_sync_func(struct clilist_file_info *info, - const char *mask, - void *state) -{ - NTSTATUS result; - struct sync_context *ctx; - char *nt_filename, *unix_filename; - char *nt_dir, *unix_dir; - char *old_nt_dir, *old_unix_dir; - - ctx = (struct sync_context *)state; - - if (strequal(info->name, ".") || strequal(info->name, "..")) { - return; - } - - DEBUG(5,("gpo_sync_func: got mask: [%s], name: [%s]\n", - mask, info->name)); - - if (info->attrib & FILE_ATTRIBUTE_DIRECTORY) { - - DEBUG(3,("got dir: [%s]\n", info->name)); - - nt_dir = talloc_asprintf(ctx->mem_ctx, "%s\\%s", - ctx->remote_path, - info->name); - - unix_dir = talloc_asprintf(ctx->mem_ctx, "%s/%s", - ctx->local_path, - info->name); - - result = gpo_copy_dir(nt_dir, unix_dir); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(1,("failed to copy dir: %s\n", - nt_errstr(result))); - } - - old_nt_dir = ctx->remote_path; - ctx->remote_path = talloc_strdup(ctx->mem_ctx, nt_dir); - - old_unix_dir = ctx->local_path; - ctx->local_path = talloc_strdup(ctx->mem_ctx, unix_dir); - - ctx->mask = talloc_asprintf(ctx->mem_ctx, - "%s\\*", - nt_dir); - if (!ctx->local_path || !ctx->mask || !ctx->remote_path) { - DEBUG(0,("gpo_sync_func: ENOMEM\n")); - return; - } - if (!gpo_sync_files(ctx)) { - DEBUG(0,("could not sync files\n")); - } - - ctx->remote_path = old_nt_dir; - ctx->local_path = old_unix_dir; - return; - } - - DEBUG(3,("got file: [%s]\n", info->name)); - - nt_filename = talloc_asprintf(ctx->mem_ctx, "%s\\%s", - ctx->remote_path, - info->name); - - unix_filename = talloc_asprintf(ctx->mem_ctx, "%s/%s", - ctx->local_path, - info->name); - - result = gpo_copy_file(ctx->mem_ctx, ctx->cli, - nt_filename, unix_filename); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(1,("failed to copy file: %s\n", - nt_errstr(result))); - } -} - - -/**************************************************************** - list a remote directory and download recursivly -****************************************************************/ - -NTSTATUS gpo_sync_directories(TALLOC_CTX *mem_ctx, - struct smbcli_state *cli, - const char *nt_path, - const char *local_path) -{ - struct sync_context ctx; - - ctx.mem_ctx = mem_ctx; - ctx.cli = cli; - ctx.remote_path = discard_const_p(char, nt_path); - ctx.local_path = discard_const_p(char, local_path); - ctx.attribute = (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY); - - ctx.mask = talloc_asprintf(mem_ctx, - "%s\\*", - nt_path); - if (!ctx.mask) { - return NT_STATUS_NO_MEMORY; - } - - if (!gpo_sync_files(&ctx)) { - return NT_STATUS_NO_SUCH_FILE; - } - - return NT_STATUS_OK; -} diff --git a/source4/libgpo/gpo_ldap.c b/source4/libgpo/gpo_ldap.c new file mode 100644 index 0000000000..dd8a26bfc1 --- /dev/null +++ b/source4/libgpo/gpo_ldap.c @@ -0,0 +1,150 @@ +/* + * Unix SMB/CIFS implementation. + * Group Policy Object Support + * Copyright (C) Jelmer Vernooij 2008 + * Copyright (C) Wilco Baan Hofman 2008-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 "param/param.h" +#include "lib/ldb/include/ldb.h" +#include "lib/ldb_wrap.h" +#include "auth/credentials/credentials.h" +#include "../librpc/gen_ndr/nbt.h" +#include "libcli/libcli.h" +#include "libnet/libnet.h" +#include "gpo.h" + +NTSTATUS gp_init(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct cli_credentials *credentials, + struct tevent_context *ev_ctx, + struct gp_context **gp_ctx) +{ + + struct libnet_LookupDCs *io; + char *url; + struct libnet_context *net_ctx; + struct ldb_context *ldb_ctx; + NTSTATUS rv; + + /* Initialise the libnet context */ + net_ctx = libnet_context_init(ev_ctx, lp_ctx); + net_ctx->cred = credentials; + + /* Prepare libnet lookup structure for looking a DC (PDC is correct). */ + io = talloc_zero(mem_ctx, struct libnet_LookupDCs); + io->in.name_type = NBT_NAME_PDC; + io->in.domain_name = lp_workgroup(lp_ctx); + + /* Find Active DC's */ + rv = libnet_LookupDCs(net_ctx, mem_ctx, io); + if (!NT_STATUS_IS_OK(rv)) { + DEBUG(0, ("Failed to lookup DCs in domain\n")); + return rv; + } + + /* Connect to ldap://DC_NAME with all relevant contexts*/ + url = talloc_asprintf(mem_ctx, "ldap://%s", io->out.dcs[0].name); + ldb_ctx = ldb_wrap_connect(mem_ctx, net_ctx->event_ctx, lp_ctx, + url, NULL, net_ctx->cred, 0); + if (ldb_ctx == NULL) { + return NT_STATUS_UNSUCCESSFUL; + } + + talloc_free(net_ctx); + + *gp_ctx = talloc_zero(mem_ctx, struct gp_context); + (*gp_ctx)->lp_ctx = lp_ctx; + (*gp_ctx)->credentials = credentials; + (*gp_ctx)->ev_ctx = ev_ctx; + (*gp_ctx)->ldb_ctx = ldb_ctx; + return NT_STATUS_OK; + +} + +NTSTATUS gp_list_all_gpos(struct gp_context *gp_ctx, struct gp_object ***ret) +{ + struct ldb_result *result; + int rv; + TALLOC_CTX *mem_ctx; + struct ldb_dn *dn; + struct gp_object **gpo; + unsigned int i, j; /* same as in struct ldb_result */ + + /* Create a forked memory context, as a base for everything here */ + mem_ctx = talloc_new(gp_ctx); + dn = ldb_get_default_basedn(gp_ctx->ldb_ctx); + rv = ldb_dn_add_child(dn, ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=Policies,CN=System")); + if (!rv) { + DEBUG(0, ("Can't append subtree to DN\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + DEBUG(10, ("Searching for policies in DN: %s\n", ldb_dn_get_linearized(dn))); + + rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_ONELEVEL, NULL, "(objectClass=groupPolicyContainer)"); + if (rv != LDB_SUCCESS) { + DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv),ldb_errstring(gp_ctx->ldb_ctx))); + return NT_STATUS_UNSUCCESSFUL; + } + + gpo = talloc_array(gp_ctx, struct gp_object *, result->count+1); + gpo[result->count] = NULL; + + for (i = 0; i < result->count; i++) { + gpo[i] = talloc(gp_ctx, struct gp_object); + + gpo[i]->dn = ldb_dn_get_linearized(result->msgs[i]->dn); + + DEBUG(9, ("Parsing GPO LDAP data for %s\n", gpo[i]->dn)); + for (j = 0; j < result->msgs[i]->num_elements; j++) { + struct ldb_message_element *element = &result->msgs[i]->elements[j]; + + if (strcmp(element->name, "displayName") == 0) { + SMB_ASSERT(element->num_values > 0); + gpo[i]->display_name = talloc_strdup(gp_ctx, (char *)element->values[0].data); + DEBUG(10, ("Found displayname: %s\n", gpo[i]->display_name)); + } + if (strcmp(element->name, "name") == 0) { + SMB_ASSERT(element->num_values > 0); + gpo[i]->name = talloc_strdup(gp_ctx, (char *)element->values[0].data); + DEBUG(10, ("Found name: %s\n", gpo[i]->name)); + } + if (strcmp(element->name, "flags") == 0) { + char *end; + SMB_ASSERT(element->num_values > 0); + gpo[i]->flags = (uint32_t) strtoll((char *)element->values[0].data, &end, 0); + SMB_ASSERT(*end == 0); + DEBUG(10, ("Found flags: %d\n", gpo[i]->flags)); + } + if (strcmp(element->name, "versionNumber") == 0) { + char *end; + SMB_ASSERT(element->num_values > 0); + gpo[i]->version = (uint32_t) strtoll((char *)element->values[0].data, &end, 0); + SMB_ASSERT(*end == 0); + DEBUG(10, ("Found version: %d\n", gpo[i]->version)); + } + if (strcmp(element->name, "gPCFileSysPath") == 0) { + SMB_ASSERT(element->num_values > 0); + gpo[i]->file_sys_path = talloc_strdup(gp_ctx, (char *)element->values[0].data); + DEBUG(10, ("Found file system path: %s\n", gpo[i]->file_sys_path)); + } + } + } + *ret = gpo; + talloc_free(mem_ctx); + return NT_STATUS_OK; +} diff --git a/source4/libgpo/gpo_s4.h b/source4/libgpo/gpo_s4.h deleted file mode 100644 index f616f6bd32..0000000000 --- a/source4/libgpo/gpo_s4.h +++ /dev/null @@ -1,40 +0,0 @@ - -/* - Samba CIFS implementation - ADS convenience functions for GPO - - Copyright (C) 2008 Jelmer Vernooij, jelmer@samba.org - Copyright (C) 2008 Wilco Baan Hofman, wilco@baanhofman.nl - - 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/>. -*/ - -#ifndef __LIBGPO_GPO_S4_H__ -#define __LIBGPO_GPO_S4_H__ - -#if _SAMBA_BUILD_ == 4 -#include "source4/libcli/libcli.h" -#endif - -NTSTATUS gpo_copy_file(TALLOC_CTX *mem_ctx, - struct smbcli_state *cli, - const char *nt_path, - const char *unix_path); - -NTSTATUS gpo_sync_directories(TALLOC_CTX *mem_ctx, - struct smbcli_state *cli, - const char *nt_path, - const char *local_path); - -#endif diff --git a/source4/main.mk b/source4/main.mk index 880d877e50..fc085c90bb 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -60,5 +60,5 @@ mkinclude ../libcli/nbt/config.mk mkinclude ../libcli/auth/config.mk mkinclude ../libcli/drsuapi/config.mk mkinclude ../libcli/samsync/config.mk -mkinclude ../libgpo/config.mk +mkinclude libgpo/config.mk mkinclude ../libcli/named_pipe_auth/config.mk diff --git a/source4/utils/net/config.mk b/source4/utils/net/config.mk index 56d2d8a08f..5549d5d7e4 100644 --- a/source4/utils/net/config.mk +++ b/source4/utils/net/config.mk @@ -33,6 +33,7 @@ PRIVATE_DEPENDENCIES = \ LIBPOPT \ POPT_SAMBA \ POPT_CREDENTIALS \ + LIBGPO \ net_drs # End BINARY net ################################# @@ -41,7 +42,8 @@ net_OBJ_FILES = $(addprefix $(utilssrcdir)/net/, \ net.o \ net_password.o \ net_join.o \ - net_vampire.o) + net_vampire.o \ + net_gpo.o) $(eval $(call proto_header_template,$(utilssrcdir)/net/net_proto.h,$(net_OBJ_FILES:.o=.c))) diff --git a/source4/utils/net/net.c b/source4/utils/net/net.c index a534957f5b..55dcca0931 100644 --- a/source4/utils/net/net.c +++ b/source4/utils/net/net.c @@ -201,6 +201,7 @@ static const struct net_functable net_functable[] = { {"samdump", "dump the sam of a domain\n", net_samdump, net_samdump_usage}, {"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage}, {"drs", "Implements functionality offered by repadmin.exe utility in Windows\n", net_drs, net_drs_usage}, + {"gpo", "Administer group policies\n", net_gpo, net_gpo_usage}, {NULL, NULL, NULL, NULL} }; diff --git a/source4/utils/net/net_gpo.c b/source4/utils/net/net_gpo.c new file mode 100644 index 0000000000..25dfaa315c --- /dev/null +++ b/source4/utils/net/net_gpo.c @@ -0,0 +1,85 @@ +/* + Samba Unix/Linux SMB client library + net ads commands for Group Policy + + Copyright (C) 2005-2008 Guenther Deschner + Copyright (C) 2009 Wilco Baan Hofman + + Based on Guenther's work in net_ads_gpo.h (samba 3) + + 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 "utils/net/net.h" +#include "libgpo/gpo.h" + +static int net_gpo_list_all(struct net_context *c, int argc, const char **argv) +{ + struct gp_context *gp_ctx; + struct gp_object **gpo; + unsigned int i; + NTSTATUS rv; + + rv = gp_init(c, c->lp_ctx, c->credentials, c->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_list_all_gpos(gp_ctx, &gpo); + if (!NT_STATUS_IS_OK(rv)) { + DEBUG(0, ("Failed to list all GPO's: %s\n", get_friendly_nt_error_msg(rv))); + return 1; + } + + for (i = 0; gpo[i] != NULL; i++) { + d_printf("GPO : %s\n", gpo[i]->name); + d_printf("display name : %s\n", gpo[i]->display_name); + d_printf("path : %s\n", gpo[i]->file_sys_path); + d_printf("dn : %s\n", gpo[i]->dn); + d_printf("version : %d\n", gpo[i]->version); + d_printf("flags : %d\n", gpo[i]->flags); + d_printf("\n"); + } + talloc_free(gp_ctx); + + return 0; +} + +static const struct net_functable net_gpo_functable[] = { +/* { "apply", "Apply GPO to container\n", net_gpo_apply, net_gpo_usage }, */ +// { "getgpo", "List specificied GPO\n", net_gpo_get_gpo, net_gpo_usage }, +// { "linkadd", "Link a GPO to a container\n", net_gpo_link_add, net_gpo_usage }, +/* { "linkdelete", "Delete GPO link from a container\n", net_gpo_link_delete, net_gpo_usage }, */ +// { "linkget", "List gPLink of container\n", net_gpo_link_get, net_gpo_usage }, +// { "list", "List all GPO's for machine/user\n", net_gpo_list, net_gpo_usage }, + { "listall", "List all GPO's on a DC\n", net_gpo_list_all, net_gpo_usage }, +// { "refresh", "List all GPO's for machine/user and download them\n", net_gpo_refresh, net_gpo_refresh_usage }, + { NULL, NULL } +}; + + +int net_gpo(struct net_context *ctx, int argc, const char **argv) +{ + return net_run_function(ctx, argc, argv, net_gpo_functable, net_gpo_usage); +} + + +int net_gpo_usage(struct net_context *ctx, int argc, const char **argv) +{ + d_printf("Syntax: net gpo <command> [options]\n"); + d_printf("For available commands please type net gpo help\n"); + return 0; +} |