From: Wilco Baan Hofman Date: Sun, 15 Mar 2009 03:40:12 +0000 (+0100) Subject: Make the gpo files build for samba 4. X-Git-Url: http://git.samba.org/samba.git/?p=kai%2Fsamba.git;a=commitdiff_plain;h=b939638dc79daa065c58755abf9f58d1df571401 Make the gpo files build for samba 4. Only gpt.ini remaining. Not suitable for merge yet, samba 3 is currently broken due to some changed public API. Signed-off-by: Günther Deschner --- diff --git a/libgpo/config.mk b/libgpo/config.mk index 9feb2f8a6d5..a9ad76c964a 100644 --- a/libgpo/config.mk +++ b/libgpo/config.mk @@ -3,4 +3,4 @@ PRIVATE_DEPENDENCIES = LIBLDB LIBSAMBA-NET LIBGPO_OBJ_FILES = ../libgpo/gpo_util.o ../libgpo/gpo_sec.o \ ../libgpo/gpext/gpext.o ../libgpo/gpo_fetch.o \ - $(libgpodir)/ads_convenience.o + $(libgpodir)/ads_convenience.o $(libgpodir)/gpo_filesync.o diff --git a/libgpo/gpo.h b/libgpo/gpo.h index 35adc9425b3..a8b5ad39344 100644 --- a/libgpo/gpo.h +++ b/libgpo/gpo.h @@ -176,8 +176,9 @@ NTSTATUS gpo_explode_filesyspath(TALLOC_CTX *mem_ctx, char **nt_path, char **unix_path); NTSTATUS gpo_fetch_files(TALLOC_CTX *mem_ctx, + ADS_STRUCT *ads, + struct loadparm_context *lp_ctx, const char *cache_path, - struct cli_state *cli, struct GROUP_POLICY_OBJECT *gpo); NTSTATUS gpo_get_sysvol_gpt_version(TALLOC_CTX *mem_ctx, const char *unix_path, @@ -255,18 +256,20 @@ ADS_STATUS gpo_process_gpo_list(ADS_STRUCT *ads, NTSTATUS check_refresh_gpo(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *cache_path, + struct loadparm_context *lp_ctx, uint32_t flags, - struct GROUP_POLICY_OBJECT *gpo, - struct cli_state **cli_out); + struct GROUP_POLICY_OBJECT *gpo); NTSTATUS check_refresh_gpo_list(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *cache_path, + struct loadparm_context *lp_ctx, uint32_t flags, struct GROUP_POLICY_OBJECT *gpo_list); NTSTATUS gpo_get_unix_path(TALLOC_CTX *mem_ctx, + const char *cache_path, struct GROUP_POLICY_OBJECT *gpo, char **unix_path); -char *gpo_flag_str(uint32_t flags); +char *gpo_flag_str(TALLOC_CTX *mem_ctx, uint32_t flags); NTSTATUS gp_find_file(TALLOC_CTX *mem_ctx, uint32_t flags, const char *filename, @@ -274,6 +277,7 @@ NTSTATUS gp_find_file(TALLOC_CTX *mem_ctx, const char **filename_out); ADS_STATUS gp_get_machine_token(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, const char *dn, NT_USER_TOKEN **token); diff --git a/libgpo/gpo_fetch.c b/libgpo/gpo_fetch.c index ee3f28d1f3a..b6d50ad852c 100644 --- a/libgpo/gpo_fetch.c +++ b/libgpo/gpo_fetch.c @@ -21,6 +21,17 @@ #include "system/filesys.h" #include "../libgpo/gpo.h" +#if _SAMBA_BUILD_ == 4 +#include "param/param.h" +#include "libcli/resolve/resolve.h" +#include "../lib/tevent/tevent.h" +#include "libcli/libcli.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/libcli_proto.h" +#include "libgpo/ads_convenience.h" +#include "libgpo/gpo.h" +#endif + /**************************************************************** explode the GPO CIFS URI into their components ****************************************************************/ @@ -118,24 +129,90 @@ static NTSTATUS gpo_prepare_local_store(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +static NTSTATUS gpo_connect_server(ADS_STRUCT *ads, struct loadparm_context *lp_ctx, + const char *server, const char *service, void *ret_cli) +{ + NTSTATUS result; +#if _SAMBA_BUILD_ == 3 + struct cli_state *cli; + + + result = cli_full_connection(&cli, + global_myname(), + server, + NULL, 0, + service, "A:", + ads->auth.user_name, NULL, + ads->auth.password, + CLI_FULL_CONNECTION_USE_KERBEROS | + CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS, + Undefined, NULL); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10,("check_refresh_gpo: " + "failed to connect: %s\n", + nt_errstr(result))); + return result; + } + } + *(struct cli_state **) ret_cli = cli; +#else + struct smbcli_state *cli = NULL; + struct smbcli_options options; + struct smbcli_session_options session_options; + + lp_smbcli_options(lp_ctx, &options); + lp_smbcli_session_options(lp_ctx, &session_options); + + result = smbcli_full_connection(NULL, &cli, + server, + NULL, service, + NULL /*devtype*/, NULL /* socket options */, + ads->credentials, + lp_resolve_context(lp_ctx), + tevent_context_init(ads), + &options, + &session_options, + lp_iconv_convenience(lp_ctx), + lp_gensec_settings(ads, lp_ctx)); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10,("failed to connect: %s\n", + nt_errstr(result))); + return result; + } + *(struct smbcli_state **) ret_cli = cli; +#endif + return NT_STATUS_OK; +} + /**************************************************************** download a full GPO via CIFS ****************************************************************/ NTSTATUS gpo_fetch_files(TALLOC_CTX *mem_ctx, + ADS_STRUCT *ads, + struct loadparm_context *lp_ctx, const char *cache_path, - struct cli_state *cli, struct GROUP_POLICY_OBJECT *gpo) { NTSTATUS result; char *server, *service, *nt_path, *unix_path; char *nt_ini_path, *unix_ini_path; +#if _SAMBA_BUILD_ == 3 + struct cli_state *cli; +#else + struct smbcli_state *cli; +#endif + result = gpo_explode_filesyspath(mem_ctx, cache_path, gpo->file_sys_path, &server, &service, &nt_path, &unix_path); NT_STATUS_NOT_OK_RETURN(result); + + result = gpo_connect_server(ads, lp_ctx, server, service, &cli); + + result = gpo_prepare_local_store(mem_ctx, cache_path, unix_path); NT_STATUS_NOT_OK_RETURN(result); diff --git a/libgpo/gpo_sec.c b/libgpo/gpo_sec.c index 1bcfa1cbf1a..5547f1e0cb9 100644 --- a/libgpo/gpo_sec.c +++ b/libgpo/gpo_sec.c @@ -23,6 +23,7 @@ #include "libgpo/ads_convenience.h" #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/ndr_misc.h" +#include "../libcli/security/secace.h" #include "../libgpo/gpo.h" #endif diff --git a/libgpo/gpo_util.c b/libgpo/gpo_util.c index 720db5a2e53..2dd7c496c82 100644 --- a/libgpo/gpo_util.c +++ b/libgpo/gpo_util.c @@ -16,17 +16,22 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ - +#define TALLOC_DEPRECATED 1 #include "includes.h" #include "librpc/gen_ndr/ndr_misc.h" #if _SAMBA_BUILD_ == 4 +#include "system/filesys.h" +#include "auth/auth.h" #include "../libgpo/gpo.h" +#include "../lib/talloc/talloc.h" #include "source4/libgpo/ads_convenience.h" #endif #undef strdup +#if 0 #define DEFAULT_DOMAIN_POLICY "Default Domain Policy" #define DEFAULT_DOMAIN_CONTROLLERS_POLICY "Default Domain Controllers Policy" +#endif /* should we store a parsed guid ? */ struct gp_table { @@ -571,7 +576,7 @@ ADS_STATUS gpo_process_gpo_list(ADS_STRUCT *ads, } #endif if (!W_ERROR_IS_OK(werr)) { - gp_free_reg_ctx(reg_ctx); + talloc_free(reg_ctx); return ADS_ERROR_NT(werror_to_ntstatus(werr)); } @@ -606,7 +611,7 @@ ADS_STATUS gpo_process_gpo_list(ADS_STRUCT *ads, } done: - gp_free_reg_ctx(reg_ctx); + talloc_free(reg_ctx); talloc_free(root_key); free_gp_extensions(); @@ -622,9 +627,9 @@ ADS_STATUS gpo_process_gpo_list(ADS_STRUCT *ads, NTSTATUS check_refresh_gpo(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *cache_path, + struct loadparm_context *lp_ctx, uint32_t flags, - struct GROUP_POLICY_OBJECT *gpo, - struct cli_state **cli_out) + struct GROUP_POLICY_OBJECT *gpo) { NTSTATUS result; char *server = NULL; @@ -633,7 +638,6 @@ NTSTATUS check_refresh_gpo(ADS_STRUCT *ads, char *unix_path = NULL; uint32_t sysvol_gpt_version = 0; char *display_name = NULL; - struct cli_state *cli = NULL; result = gpo_explode_filesyspath(mem_ctx, cache_path, gpo->file_sys_path, &server, &share, &nt_path, &unix_path); @@ -663,32 +667,7 @@ NTSTATUS check_refresh_gpo(ADS_STRUCT *ads, DEBUG(1,("check_refresh_gpo: need to refresh GPO\n")); -#if _SAMBA_BUILD == 3 - if (*cli_out == NULL) { - result = cli_full_connection(&cli, - global_myname(), - ads_get_ldap_server_name(ads), - /* server */ - NULL, 0, - share, "A:", - ads->auth.user_name, NULL, - ads->auth.password, - CLI_FULL_CONNECTION_USE_KERBEROS | - CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS, - Undefined, NULL); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(10,("check_refresh_gpo: " - "failed to connect: %s\n", - nt_errstr(result))); - goto out; - } - *cli_out = cli; - } -#else - /* TODO Implement */ -#endif - - result = gpo_fetch_files(mem_ctx, cache_path, *cli_out, gpo); + result = gpo_fetch_files(mem_ctx, ads, lp_ctx, cache_path, gpo); if (!NT_STATUS_IS_OK(result)) { goto out; } @@ -735,11 +714,11 @@ NTSTATUS check_refresh_gpo(ADS_STRUCT *ads, NTSTATUS check_refresh_gpo_list(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *cache_path, + struct loadparm_context *lp_ctx, uint32_t flags, struct GROUP_POLICY_OBJECT *gpo_list) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - struct cli_state *cli = NULL; struct GROUP_POLICY_OBJECT *gpo; if (!gpo_list) { @@ -748,7 +727,7 @@ NTSTATUS check_refresh_gpo_list(ADS_STRUCT *ads, for (gpo = gpo_list; gpo; gpo = gpo->next) { - result = check_refresh_gpo(ads, mem_ctx, cache_path, flags, gpo, &cli); + result = check_refresh_gpo(ads, mem_ctx, cache_path, lp_ctx, flags, gpo); if (!NT_STATUS_IS_OK(result)) { goto out; } @@ -757,9 +736,7 @@ NTSTATUS check_refresh_gpo_list(ADS_STRUCT *ads, result = NT_STATUS_OK; out: - if (cli) { - cli_shutdown(cli); - } + /* FIXME close cli connection */ return result; } @@ -768,45 +745,46 @@ NTSTATUS check_refresh_gpo_list(ADS_STRUCT *ads, ****************************************************************/ NTSTATUS gpo_get_unix_path(TALLOC_CTX *mem_ctx, + const char *cache_path, struct GROUP_POLICY_OBJECT *gpo, char **unix_path) { char *server, *share, *nt_path; - return gpo_explode_filesyspath(mem_ctx, gpo->file_sys_path, + return gpo_explode_filesyspath(mem_ctx, cache_path, gpo->file_sys_path, &server, &share, &nt_path, unix_path); } /**************************************************************** ****************************************************************/ -char *gpo_flag_str(uint32_t flags) +char *gpo_flag_str(TALLOC_CTX *ctx, uint32_t flags) { - fstring str = ""; + char *str = NULL; if (flags == 0) { return NULL; } if (flags & GPO_INFO_FLAG_SLOWLINK) - fstrcat(str, "GPO_INFO_FLAG_SLOWLINK "); + str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_SLOWLINK "); if (flags & GPO_INFO_FLAG_VERBOSE) - fstrcat(str, "GPO_INFO_FLAG_VERBOSE "); + str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_VERBOSE "); if (flags & GPO_INFO_FLAG_SAFEMODE_BOOT) - fstrcat(str, "GPO_INFO_FLAG_SAFEMODE_BOOT "); + str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_SAFEMODE_BOOT "); if (flags & GPO_INFO_FLAG_NOCHANGES) - fstrcat(str, "GPO_INFO_FLAG_NOCHANGES "); + str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_NOCHANGES "); if (flags & GPO_INFO_FLAG_MACHINE) - fstrcat(str, "GPO_INFO_FLAG_MACHINE "); + str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_MACHINE "); if (flags & GPO_INFO_FLAG_LOGRSOP_TRANSITION) - fstrcat(str, "GPO_INFO_FLAG_LOGRSOP_TRANSITION "); + str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_LOGRSOP_TRANSITION "); if (flags & GPO_INFO_FLAG_LINKTRANSITION) - fstrcat(str, "GPO_INFO_FLAG_LINKTRANSITION "); + str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_LINKTRANSITION "); if (flags & GPO_INFO_FLAG_FORCED_REFRESH) - fstrcat(str, "GPO_INFO_FLAG_FORCED_REFRESH "); + str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_FORCED_REFRESH "); if (flags & GPO_INFO_FLAG_BACKGROUND) - fstrcat(str, "GPO_INFO_FLAG_BACKGROUND "); + str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_BACKGROUND "); - return strdup(str); + return str; } /**************************************************************** @@ -857,12 +835,17 @@ NTSTATUS gp_find_file(TALLOC_CTX *mem_ctx, ADS_STATUS gp_get_machine_token(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, const char *dn, NT_USER_TOKEN **token) { NT_USER_TOKEN *ad_token = NULL; ADS_STATUS status; +#if _SAMBA_BUILD_ == 4 + struct auth_session_info *info; +#else NTSTATUS ntstatus; +#endif #ifndef HAVE_ADS return ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); @@ -871,12 +854,15 @@ ADS_STATUS gp_get_machine_token(ADS_STRUCT *ads, if (!ADS_ERR_OK(status)) { return status; } - +#if _SAMBA_BUILD_ == 4 + info = system_session(mem_ctx, lp_ctx); + *token = info->security_token; +#else ntstatus = merge_nt_token(mem_ctx, ad_token, get_system_token(), token); if (!NT_STATUS_IS_OK(ntstatus)) { return ADS_ERROR_NT(ntstatus); } - +#endif return ADS_SUCCESS; } diff --git a/source4/libgpo/ads_convenience.c b/source4/libgpo/ads_convenience.c index 77c4f5bdc2b..6e2dbca5381 100644 --- a/source4/libgpo/ads_convenience.c +++ b/source4/libgpo/ads_convenience.c @@ -258,6 +258,9 @@ bool nt_token_check_sid( const struct dom_sid *sid, const NT_USER_TOKEN *token) return false; } +const char *ads_get_ldap_server_name(ADS_STRUCT *ads) { + return ads->ldap_server_name; +} /* diff --git a/source4/libgpo/ads_convenience.h b/source4/libgpo/ads_convenience.h index bce2cc4eeaf..ce2b9b6a06b 100644 --- a/source4/libgpo/ads_convenience.h +++ b/source4/libgpo/ads_convenience.h @@ -45,6 +45,11 @@ 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; @@ -92,6 +97,7 @@ 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/gpo.h b/source4/libgpo/gpo.h new file mode 100644 index 00000000000..3e5cb06bdc6 --- /dev/null +++ b/source4/libgpo/gpo.h @@ -0,0 +1,36 @@ + +/* + 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 . +*/ + +#ifndef __LIBGPO_GPO_H__ +#define __LIBGPO_GPO_H__ + +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/libgpo/gpo_filesync.c b/source4/libgpo/gpo_filesync.c new file mode 100644 index 00000000000..3f6f5f79603 --- /dev/null +++ b/source4/libgpo/gpo_filesync.c @@ -0,0 +1,241 @@ +/* + * 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 . + */ + +#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; +}