summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libgpo/config.mk2
-rw-r--r--libgpo/gpo.h12
-rw-r--r--libgpo/gpo_fetch.c79
-rw-r--r--libgpo/gpo_sec.c1
-rw-r--r--libgpo/gpo_util.c90
-rw-r--r--source4/libgpo/ads_convenience.c3
-rw-r--r--source4/libgpo/ads_convenience.h6
-rw-r--r--source4/libgpo/gpo.h36
-rw-r--r--source4/libgpo/gpo_filesync.c241
9 files changed, 412 insertions, 58 deletions
diff --git a/libgpo/config.mk b/libgpo/config.mk
index 9feb2f8a6d..a9ad76c964 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 35adc9425b..a8b5ad3934 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 ee3f28d1f3..b6d50ad852 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 1bcfa1cbf1..5547f1e0cb 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 720db5a2e5..2dd7c496c8 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 <http://www.gnu.org/licenses/>.
*/
-
+#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 77c4f5bdc2..6e2dbca538 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 bce2cc4eea..ce2b9b6a06 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 0000000000..3e5cb06bdc
--- /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 <http://www.gnu.org/licenses/>.
+*/
+
+#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 0000000000..3f6f5f7960
--- /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 <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;
+}