diff options
-rw-r--r-- | source3/Makefile.in | 3 | ||||
-rw-r--r-- | source3/include/gpo.h | 3 | ||||
-rw-r--r-- | source3/libgpo/gpo_fetch.c | 237 |
3 files changed, 242 insertions, 1 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 19bd0afbf3..1120228ba4 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -267,7 +267,8 @@ LIBADDNS_OBJ0 = libaddns/dnsrecord.o libaddns/dnsrequest.o libaddns/dnsresponse. libaddns/dnsupresp.o libaddns/dnsupdate.o libaddns/dnsgss.o LIBADDNS_OBJ = $(LIBADDNS_OBJ0) $(TALLOC_OBJ) -LIBGPO_OBJ0 = libgpo/gpo_ldap.o libgpo/gpo_parse.o libgpo/gpo_util.o +LIBGPO_OBJ0 = libgpo/gpo_ldap.o libgpo/gpo_parse.o libgpo/gpo_util.o \ + libgpo/gpo_fetch.o LIBGPO_OBJ = $(LIBGPO_OBJ0) LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o libads/sasl.o \ diff --git a/source3/include/gpo.h b/source3/include/gpo.h index 24aaaea75d..c3ae20dd20 100644 --- a/source3/include/gpo.h +++ b/source3/include/gpo.h @@ -90,3 +90,6 @@ struct GP_EXT { char **snapins; char **snapins_guid; }; + +#define GPO_CACHE_DIR "gpo_cache" +#define GPT_INI "GPT.INI" diff --git a/source3/libgpo/gpo_fetch.c b/source3/libgpo/gpo_fetch.c new file mode 100644 index 0000000000..23a719a95d --- /dev/null +++ b/source3/libgpo/gpo_fetch.c @@ -0,0 +1,237 @@ +/* + * Unix SMB/CIFS implementation. + * Group Policy Object Support + * Copyright (C) Guenther Deschner 2005-2006 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +/**************************************************************** + explode the GPO CIFS URI into their components +****************************************************************/ + +NTSTATUS ads_gpo_explode_filesyspath(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *file_sys_path, + char **server, + char **service, + char **nt_path, + char **unix_path) +{ + fstring tok; + pstring path; + + *server = NULL; + *service = NULL; + *nt_path = NULL; + *unix_path = NULL; + + if (!next_token(&file_sys_path, tok, "\\", sizeof(tok))) { + return NT_STATUS_INVALID_PARAMETER; + } + + if ((*server = talloc_strdup(mem_ctx, tok)) == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (!next_token(&file_sys_path, tok, "\\", sizeof(tok))) { + return NT_STATUS_INVALID_PARAMETER; + } + + if ((*service = talloc_strdup(mem_ctx, tok)) == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if ((*nt_path = talloc_asprintf(mem_ctx, "\\%s", file_sys_path)) == NULL) { + return NT_STATUS_NO_MEMORY; + } + + pstrcpy(path, lock_path(GPO_CACHE_DIR)); + pstrcat(path, "/"); + pstrcat(path, file_sys_path); + pstring_sub(path, "\\", "/"); + + if ((*unix_path = talloc_strdup(mem_ctx, path)) == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + +/**************************************************************** + prepare the local disc storage for "unix_path" +****************************************************************/ + +NTSTATUS ads_gpo_prepare_local_store(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *unix_path) +{ + const char *top_dir = lock_path(GPO_CACHE_DIR); + char *current_dir; + fstring tok; + + current_dir = talloc_strdup(mem_ctx, top_dir); + NT_STATUS_HAVE_NO_MEMORY(current_dir); + + if ((mkdir(top_dir, 0644)) < 0 && errno != EEXIST) { + return NT_STATUS_ACCESS_DENIED; + } + + while (next_token(&unix_path, tok, "/", sizeof(tok))) { + + if (strequal(tok, GPO_CACHE_DIR)) { + break; + } + } + + while (next_token(&unix_path, tok, "/", sizeof(tok))) { + + current_dir = talloc_asprintf_append(current_dir, "/%s", tok); + NT_STATUS_HAVE_NO_MEMORY(current_dir); + + if ((mkdir(current_dir, 0644)) < 0 && errno != EEXIST) { + return NT_STATUS_ACCESS_DENIED; + } + } + + return NT_STATUS_OK; +} + +/**************************************************************** + download a full GPO via CIFS +****************************************************************/ + +NTSTATUS ads_fetch_gpo_files(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + struct cli_state *cli, + struct GROUP_POLICY_OBJECT *gpo) +{ + NTSTATUS result; + int fnum = 0; + int fd = 0; + char *data = NULL; + static int io_bufsize = 64512; + int read_size = io_bufsize; + char *server, *service, *nt_path, *unix_path, *nt_ini_path, *unix_ini_path; + off_t start = 0; + off_t nread = 0; + + result = ads_gpo_explode_filesyspath(ads, mem_ctx, gpo->file_sys_path, + &server, &service, &nt_path, &unix_path); + if (!NT_STATUS_IS_OK(result)) { + goto out; + } + + result = ads_gpo_prepare_local_store(ads, mem_ctx, unix_path); + if (!NT_STATUS_IS_OK(result)) { + goto out; + } + + unix_ini_path = talloc_asprintf(mem_ctx, "%s/%s", unix_path, GPT_INI); + nt_ini_path = talloc_asprintf(mem_ctx, "%s\\%s", nt_path, GPT_INI); + if (!unix_path || !nt_ini_path) { + result = NT_STATUS_NO_MEMORY; + goto out; + } + + /* open local file */ + + fd = sys_open(unix_ini_path, O_WRONLY|O_CREAT|O_TRUNC, 0644); + if (fd == -1) { + result = map_nt_error_from_unix(errno); + goto out; + } + + /* open remote file */ + + fnum = cli_open(cli, nt_ini_path, O_RDONLY, DENY_NONE); + if (fnum == -1) { + result = NT_STATUS_NO_SUCH_FILE; + goto out; + } + + /* copy gpt.ini */ + + data = (char *)SMB_MALLOC(read_size); + if (data == NULL) { + result = NT_STATUS_NO_MEMORY; + goto out; + } + + while (1) { + + int n = cli_read(cli, fnum, data, nread + start, read_size); + + if (n <= 0) + break; + + if (write(fd, data, n) != n) { + break; + } + + nread += n; + } + + result = NT_STATUS_OK; + + out: + SAFE_FREE(data); + if (fd) { + close(fd); + } + if (fnum) { + cli_close(cli, fnum); + } + + return result; +} + +/**************************************************************** + get the locally stored gpt.ini version number +****************************************************************/ + +NTSTATUS ads_gpo_get_sysvol_gpt_version(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *unix_path, + uint32 *sysvol_version, + char **display_name) +{ + NTSTATUS status; + uint32 version; + char *local_path = NULL; + char *name = NULL; + + local_path = talloc_asprintf(mem_ctx, "%s/%s", unix_path, GPT_INI); + NT_STATUS_HAVE_NO_MEMORY(local_path); + + status = parse_gpt_ini(mem_ctx, local_path, &version, &name); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("ads_gpo_get_sysvol_gpt_version: failed to parse ini [%s]: %s\n", + unix_path, nt_errstr(status))); + return status; + } + + if (sysvol_version) { + *sysvol_version = version; + } + + if (name && *display_name) { + *display_name = talloc_strdup(mem_ctx, name); + } + + return NT_STATUS_OK; +} |