[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-test-2674-gf673bbd

Günther Deschner gd at samba.org
Fri Feb 29 14:50:42 GMT 2008


The branch, v3-2-test has been updated
       via  f673bbd300d972dd7ae2d092b3b1e642ed29cfd2 (commit)
      from  9a966e5593ae4474014aec5d8c68c489ac8ce0c9 (commit)

http://gitweb.samba.org/?samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit f673bbd300d972dd7ae2d092b3b1e642ed29cfd2
Author: Günther Deschner <gd at samba.org>
Date:   Fri Feb 29 15:46:14 2008 +0100

    Add infrastructure for reading/storing Group Policy state and control data in the registry.
    
    Guenther

-----------------------------------------------------------------------

Summary of changes:
 source/Makefile.in           |    3 +-
 source/include/gpo.h         |   60 +++-
 source/include/reg_objects.h |    7 +
 source/libgpo/gpo_reg.c      | 1058 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 1126 insertions(+), 2 deletions(-)
 create mode 100644 source/libgpo/gpo_reg.c


Changeset truncated at 500 lines:

diff --git a/source/Makefile.in b/source/Makefile.in
index c6815e9..baa9177 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -377,7 +377,8 @@ LIBWBCLIENT_OBJ0 = nsswitch/libwbclient/wbclient.o \
 LIBWBCLIENT_OBJ = $(LIBWBCLIENT_OBJ0) $(WBCOMMON_OBJ) @LIBTALLOC_STATIC@ $(LIBREPLACE_OBJ)
 
 LIBGPO_OBJ0 = libgpo/gpo_ldap.o libgpo/gpo_ini.o libgpo/gpo_util.o \
-	      libgpo/gpo_fetch.o libgpo/gpo_filesync.o libgpo/gpo_sec.o
+	      libgpo/gpo_fetch.o libgpo/gpo_filesync.o libgpo/gpo_sec.o \
+	      libgpo/gpo_reg.o
 LIBGPO_OBJ = $(LIBGPO_OBJ0)
 
 LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o \
diff --git a/source/include/gpo.h b/source/include/gpo.h
index 9b1a672..d8d9e8e 100644
--- a/source/include/gpo.h
+++ b/source/include/gpo.h
@@ -22,7 +22,8 @@ enum GPO_LINK_TYPE {
 	GP_LINK_MACHINE	= 1,
 	GP_LINK_SITE	= 2,
 	GP_LINK_DOMAIN	= 3,
-	GP_LINK_OU	= 4
+	GP_LINK_OU	= 4,
+	GP_LINK_LOCAL	= 5 /* for convenience */
 };
 
 /* GPO_OPTIONS */
@@ -33,6 +34,17 @@ enum GPO_LINK_TYPE {
 #define GPO_LIST_FLAG_MACHINE	0x00000001
 #define GPO_LIST_FLAG_SITEONLY	0x00000002
 
+/* following flags from http://support.microsoft.com/kb/312164/EN-US/ */
+#define GPO_INFO_FLAG_MACHINE			0x00000001
+#define GPO_INFO_FLAG_BACKGROUND	 	0x00000010
+#define GPO_INFO_FLAG_SLOWLINK			0x00000020
+#define GPO_INFO_FLAG_VERBOSE			0x00000040
+#define GPO_INFO_FLAG_NOCHANGES			0x00000080
+#define GPO_INFO_FLAG_LINKTRANSITION		0x00000100
+#define GPO_INFO_FLAG_LOGRSOP_TRANSITION	0x00000200
+#define GPO_INFO_FLAG_FORCED_REFRESH		0x00000400
+#define GPO_INFO_FLAG_SAFEMODE_BOOT		0x00000800
+
 #define GPO_VERSION_USER(x) (x >> 16)
 #define GPO_VERSION_MACHINE(x) (x & 0xffff)
 
@@ -88,10 +100,56 @@ struct GP_EXT {
 	char **extensions_guid;
 	char **snapins;
 	char **snapins_guid;
+	struct GP_EXT *next, *prev;
 };
 
 #define GPO_CACHE_DIR "gpo_cache"
 #define GPT_INI "GPT.INI"
+#define GPO_REFRESH_INTERVAL 60*90
+
+#define GPO_REG_STATE_MACHINE "State\\Machine"
+
+enum gp_reg_action {
+	GP_REG_ACTION_NONE = 0,
+	GP_REG_ACTION_ADD_VALUE = 1,
+	GP_REG_ACTION_ADD_KEY = 2,
+	GP_REG_ACTION_DEL_VALUES = 3,
+	GP_REG_ACTION_DEL_VALUE = 4,
+	GP_REG_ACTION_DEL_ALL_VALUES = 5,
+	GP_REG_ACTION_DEL_KEYS = 6,
+	GP_REG_ACTION_SEC_KEY_SET = 7,
+	GP_REG_ACTION_SEC_KEY_RESET = 8
+};
+
+struct gp_registry_entry {
+	enum gp_reg_action action;
+	const char *key;
+	const char *value;
+	struct registry_value *data;
+};
+
+struct gp_registry_value {
+	const char *value;
+	struct registry_value *data;
+};
+
+struct gp_registry_entry2 {
+	enum gp_reg_action action;
+	const char *key;
+	size_t num_values;
+	struct gp_registry_value **values;
+};
+
+struct gp_registry_entries {
+	size_t num_entries;
+	struct gp_registry_entry **entries;
+};
+
+struct gp_registry_context {
+	const struct nt_user_token *token;
+	const char *path;
+	struct registry_key *curr_key;
+};
 
 #define GP_EXT_GUID_SECURITY "827D319E-6EAC-11D2-A4EA-00C04F79F83A"
 #define GP_EXT_GUID_REGISTRY "35378EAC-683F-11D2-A89A-00C04FBBCFA2"
diff --git a/source/include/reg_objects.h b/source/include/reg_objects.h
index 3df701f..1d0d0d4 100644
--- a/source/include/reg_objects.h
+++ b/source/include/reg_objects.h
@@ -105,9 +105,16 @@ typedef struct {
 #define KEY_CURRENT_VERSION	"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
 #define KEY_PERFLIB		"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib"
 #define KEY_PERFLIB_009		"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009"
+#define KEY_GROUP_POLICY	"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Group Policy"
+#define KEY_WINLOGON		"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"
 #define KEY_SMBCONF		"HKLM\\SOFTWARE\\Samba\\smbconf"
+#define KEY_SAMBA_GROUP_POLICY	"HKLM\\SOFTWARE\\Samba\\Group Policy"
 #define KEY_TREE_ROOT		""
 
+#define KEY_GP_MACHINE_POLICY		"HKLM\\Software\\Policies"
+#define KEY_GP_MACHINE_WIN_POLICY	"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies"
+#define KEY_GP_USER_POLICY		"HKCU\\Software\\Policies"
+#define KEY_GP_USER_WIN_POLICY		"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies"
 /*
  * Registry key types
  *	Most keys are going to be GENERIC -- may need a better name?
diff --git a/source/libgpo/gpo_reg.c b/source/libgpo/gpo_reg.c
new file mode 100644
index 0000000..2a27a7e
--- /dev/null
+++ b/source/libgpo/gpo_reg.c
@@ -0,0 +1,1058 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  Group Policy Object Support
+ *  Copyright (C) Guenther Deschner 2007-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"
+
+
+extern REGISTRY_OPS regdb_ops;
+
+static int gp_reg_fetch_keys(const char *key, REGSUBKEY_CTR *subkey_ctr)
+{
+	return regdb_ops.fetch_subkeys(key, subkey_ctr);
+}
+
+static bool gp_reg_store_keys(const char *key, REGSUBKEY_CTR *subkeys)
+{
+	return regdb_ops.store_subkeys(key, subkeys);
+}
+
+static int gp_reg_fetch_values(const char *key, REGVAL_CTR *val)
+{
+	return regdb_ops.fetch_values(key, val);
+}
+
+static bool gp_reg_store_values(const char *key, REGVAL_CTR *val)
+{
+	return regdb_ops.store_values(key, val);
+}
+
+static WERROR gp_reg_get_secdesc(TALLOC_CTX *mem_ctx, const char *key,
+				 struct security_descriptor **psecdesc)
+{
+	return regdb_ops.get_secdesc(mem_ctx, key, psecdesc);
+}
+
+static WERROR gp_reg_set_secdesc(const char *key,
+				 struct security_descriptor *secdesc)
+{
+	return regdb_ops.set_secdesc(key, secdesc);
+}
+
+/****************************************************************
+****************************************************************/
+
+static REGISTRY_OPS gp_reg_ops = {
+	.fetch_subkeys		= gp_reg_fetch_keys,
+	.fetch_values		= gp_reg_fetch_values,
+	.store_subkeys		= gp_reg_store_keys,
+	.store_values		= gp_reg_store_values,
+/*	.reg_access_check	= gp_reg_reg_access_check, */
+	.get_secdesc		= gp_reg_get_secdesc,
+	.set_secdesc		= gp_reg_set_secdesc
+};
+
+/****************************************************************
+****************************************************************/
+
+struct nt_user_token *registry_create_system_token(TALLOC_CTX *mem_ctx)
+{
+	struct nt_user_token *token = NULL;
+
+	token = TALLOC_ZERO_P(mem_ctx, struct nt_user_token);
+	if (!token) {
+		DEBUG(1,("talloc failed\n"));
+		return NULL;
+	}
+
+	token->privileges = se_priv_all;
+
+	if (!NT_STATUS_IS_OK(add_sid_to_array(token, &global_sid_System,
+			 &token->user_sids, &token->num_sids))) {
+		DEBUG(1,("Error adding nt-authority system sid to token\n"));
+		return NULL;
+	}
+
+	return token;
+}
+
+/****************************************************************
+****************************************************************/
+
+WERROR gp_init_reg_ctx(TALLOC_CTX *mem_ctx,
+		       const char *initial_path,
+		       uint32_t desired_access,
+		       const struct nt_user_token *token,
+		       struct gp_registry_context **reg_ctx)
+{
+	struct gp_registry_context *tmp_ctx;
+	static REGISTRY_HOOK gp_reg_hook;
+	WERROR werr;
+
+	if (!reg_ctx) {
+		return WERR_INVALID_PARAM;
+	}
+
+	if (!regdb_init()) {
+		return WERR_CAN_NOT_COMPLETE;
+	}
+
+	gp_reg_hook.keyname = initial_path; /* KEY_SAMBA_GROUP_POLICY */
+	gp_reg_hook.ops = &gp_reg_ops;
+
+	/* not sure about the cache hook */
+	reghook_cache_init();
+
+	if (!reghook_cache_add(&gp_reg_hook)) {
+		return WERR_CAN_NOT_COMPLETE;
+	}
+
+	tmp_ctx = TALLOC_ZERO_P(mem_ctx, struct gp_registry_context);
+	W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
+
+	if (token) {
+		tmp_ctx->token = token;
+	} else {
+		tmp_ctx->token = registry_create_system_token(mem_ctx);
+	}
+	if (!tmp_ctx->token) {
+		TALLOC_FREE(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	if (initial_path) {
+		tmp_ctx->path = talloc_strdup(mem_ctx, initial_path);
+		if (!tmp_ctx->path) {
+			TALLOC_FREE(tmp_ctx);
+			return WERR_NOMEM;
+		}
+
+		werr = reg_open_path(mem_ctx, tmp_ctx->path, desired_access,
+				     tmp_ctx->token, &tmp_ctx->curr_key);
+		if (!W_ERROR_IS_OK(werr)) {
+			TALLOC_FREE(tmp_ctx);
+			return werr;
+		}
+	}
+
+	*reg_ctx = tmp_ctx;
+
+	return WERR_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+void gp_free_reg_ctx(struct gp_registry_context *reg_ctx)
+{
+	TALLOC_FREE(reg_ctx);
+}
+
+/****************************************************************
+****************************************************************/
+
+WERROR gp_store_reg_subkey(TALLOC_CTX *mem_ctx,
+			   const char *subkeyname,
+			   struct registry_key *curr_key,
+			   struct registry_key **new_key)
+{
+	enum winreg_CreateAction action = REG_ACTION_NONE;
+	WERROR werr;
+
+	werr = reg_createkey(mem_ctx, curr_key, subkeyname,
+			     REG_KEY_WRITE, new_key, &action);
+	if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
+		return WERR_OK;
+	}
+
+	return werr;
+}
+
+/****************************************************************
+****************************************************************/
+
+WERROR gp_read_reg_subkey(TALLOC_CTX *mem_ctx,
+			  struct gp_registry_context *reg_ctx,
+			  const char *subkeyname,
+			  struct registry_key **key)
+{
+	const char *tmp = NULL;
+
+	if (!reg_ctx || !subkeyname || !key) {
+		return WERR_INVALID_PARAM;
+	}
+
+	tmp = talloc_asprintf(mem_ctx, "%s\\%s", reg_ctx->path, subkeyname);
+	W_ERROR_HAVE_NO_MEMORY(tmp);
+
+	return reg_open_path(mem_ctx, tmp, REG_KEY_READ,
+			     reg_ctx->token, key);
+}
+
+/****************************************************************
+****************************************************************/
+
+WERROR gp_store_reg_val_sz(TALLOC_CTX *mem_ctx,
+			   struct registry_key *key,
+			   const char *val_name,
+			   const char *val)
+{
+	struct registry_value reg_val;
+	ZERO_STRUCT(reg_val);
+
+	/* FIXME: hack */
+	val = val ? val : " ";
+
+	reg_val.type = REG_SZ;
+	reg_val.v.sz.len = strlen(val);
+	reg_val.v.sz.str = talloc_strdup(mem_ctx, val);
+	W_ERROR_HAVE_NO_MEMORY(reg_val.v.sz.str);
+
+	return reg_setvalue(key, val_name, &reg_val);
+}
+
+/****************************************************************
+****************************************************************/
+
+static WERROR gp_store_reg_val_dword(TALLOC_CTX *mem_ctx,
+				     struct registry_key *key,
+				     const char *val_name,
+				     uint32_t val)
+{
+	struct registry_value reg_val;
+	ZERO_STRUCT(reg_val);
+
+	reg_val.type = REG_DWORD;
+	reg_val.v.dword = val;
+
+	return reg_setvalue(key, val_name, &reg_val);
+}
+
+/****************************************************************
+****************************************************************/
+
+WERROR gp_read_reg_val_sz(TALLOC_CTX *mem_ctx,
+			  struct registry_key *key,
+			  const char *val_name,
+			  const char **val)
+{
+	WERROR werr;
+	struct registry_value *reg_val = NULL;
+
+	werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
+	W_ERROR_NOT_OK_RETURN(werr);
+
+	if (reg_val->type != REG_SZ) {
+		return WERR_INVALID_DATATYPE;
+	}
+
+	*val = talloc_strdup(mem_ctx, reg_val->v.sz.str);
+	W_ERROR_HAVE_NO_MEMORY(*val);
+
+	return WERR_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static WERROR gp_read_reg_val_dword(TALLOC_CTX *mem_ctx,
+				    struct registry_key *key,
+				    const char *val_name,
+				    uint32_t *val)
+{
+	WERROR werr;
+	struct registry_value *reg_val = NULL;
+
+	werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
+	W_ERROR_NOT_OK_RETURN(werr);
+
+	if (reg_val->type != REG_DWORD) {
+		return WERR_INVALID_DATATYPE;
+	}
+
+	*val = reg_val->v.dword;
+
+	return WERR_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static WERROR gp_store_reg_gpovals(TALLOC_CTX *mem_ctx,
+				   struct registry_key *key,
+				   struct GROUP_POLICY_OBJECT *gpo)
+{
+	WERROR werr;
+
+	if (!key || !gpo) {
+		return WERR_INVALID_PARAM;
+	}
+
+	werr = gp_store_reg_val_dword(mem_ctx, key, "Version",
+				      gpo->version);
+	W_ERROR_NOT_OK_RETURN(werr);
+
+	werr = gp_store_reg_val_dword(mem_ctx, key, "WQLFilterPass",
+				      true); /* fake */
+	W_ERROR_NOT_OK_RETURN(werr);
+
+	werr = gp_store_reg_val_dword(mem_ctx, key, "AccessDenied",
+				      false); /* fake */
+	W_ERROR_NOT_OK_RETURN(werr);
+
+	werr = gp_store_reg_val_dword(mem_ctx, key, "GPO-Disabled",
+				      (gpo->options & GPO_FLAG_DISABLE));
+	W_ERROR_NOT_OK_RETURN(werr);
+
+	werr = gp_store_reg_val_dword(mem_ctx, key, "Options",
+				      gpo->options);
+	W_ERROR_NOT_OK_RETURN(werr);
+
+	werr = gp_store_reg_val_sz(mem_ctx, key, "GPOID",
+				   gpo->name);
+	W_ERROR_NOT_OK_RETURN(werr);
+
+	werr = gp_store_reg_val_sz(mem_ctx, key, "SOM",
+				   gpo->link);
+	W_ERROR_NOT_OK_RETURN(werr);
+
+	werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName",
+				   gpo->display_name);
+	W_ERROR_NOT_OK_RETURN(werr);
+
+	werr = gp_store_reg_val_sz(mem_ctx, key, "WQL-Id",
+				   NULL);
+	W_ERROR_NOT_OK_RETURN(werr);
+
+	return werr;
+}
+
+/****************************************************************
+****************************************************************/
+
+static const char *gp_reg_groupmembership_path(TALLOC_CTX *mem_ctx,
+					       const DOM_SID *sid,
+					       uint32_t flags)
+{
+	if (flags & GPO_LIST_FLAG_MACHINE) {
+		return "GroupMembership";
+	}
+
+	return talloc_asprintf(mem_ctx, "%s\\%s", sid_string_tos(sid),
+			       "GroupMembership");
+}
+
+/****************************************************************
+****************************************************************/
+
+static WERROR gp_reg_del_groupmembership(TALLOC_CTX *mem_ctx,
+					 struct registry_key *key,
+					 const struct nt_user_token *token,
+					 uint32_t flags)
+{
+	const char *path = NULL;
+
+	path = gp_reg_groupmembership_path(mem_ctx, &token->user_sids[0],


-- 
Samba Shared Repository


More information about the samba-cvs mailing list