[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Wed Feb 2 08:31:01 MST 2011


The branch, master has been updated
       via  8ddfe78 s3-dssync-passdb: implement accounts, aliases and groups
       via  6e0498d s3-dssync-passdb: fill in passdb_process_objects
       via  41ba1d3 s3-dssync-passdb: fill in passdb_finish.
       via  1f884cf s3-dssync-passdb: fill in passdb_startup.
       via  91e6dad s3-dssync-passdb: add basic routines and net function.
       via  1c1aeba s3:net: make some net_rpc_samsync.c functions static
       via  0313969 s3:net: "net rpc vampire" is an alias for "net rpc vampire passdb"
       via  bf7a27c s3:libnet: add 'process_links' to dssync_ops
       via  cecf54b s3:groupdb: allow machine accounts as members.
       via  255f2e0 s3:winbindd: catch lookup_names/sids schannel errors over ncacn_ip_tcp (bug #7944)
      from  50be0b2 s3: Remove superfluous ;

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 8ddfe78a5fdbae99856fd935a3103fad9df812f2
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jan 5 16:56:14 2011 +0100

    s3-dssync-passdb: implement accounts, aliases and groups
    
    metze
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Wed Feb  2 16:30:26 CET 2011 on sn-devel-104

commit 6e0498d0e289ed596a86a1b084475bdeec9b7105
Author: Günther Deschner <gd at samba.org>
Date:   Sat Nov 22 00:35:20 2008 +0100

    s3-dssync-passdb: fill in passdb_process_objects
    
    Guenther
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 41ba1d3a1cdb1ecf3f3e607cea73c35dc19a3deb
Author: Günther Deschner <gd at samba.org>
Date:   Fri Nov 21 23:59:55 2008 +0100

    s3-dssync-passdb: fill in passdb_finish.
    
    Guenther
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 1f884cfbcb126c8f8bfeeabd349e082ae8fae3b6
Author: Günther Deschner <gd at samba.org>
Date:   Fri Nov 21 23:58:42 2008 +0100

    s3-dssync-passdb: fill in passdb_startup.
    
    Guenther
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 91e6dad7494421c764c2fd701931f7053f15bda1
Author: Günther Deschner <gd at samba.org>
Date:   Fri Nov 21 23:48:45 2008 +0100

    s3-dssync-passdb: add basic routines and net function.
    
    Guenther

commit 1c1aebae827d68feb5a94247787e97c9f4ba43a3
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jan 4 13:02:35 2011 +0100

    s3:net: make some net_rpc_samsync.c functions static
    
    metze

commit 0313969aed6b6a5c7d75a3ec92b1797362a99046
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jan 4 08:50:20 2011 +0100

    s3:net: "net rpc vampire" is an alias for "net rpc vampire passdb"
    
    The should use exactly the same code path for both.
    
    metze

commit bf7a27c3975c3822e0de8ff15730e6d6d1f46457
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jan 13 17:18:24 2011 +0100

    s3:libnet: add 'process_links' to dssync_ops
    
    This allows the backend to handle linked attributes.
    
    metze

commit cecf54b32bf15b0e05af899ab12f06f110dd45ec
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 21 11:55:10 2011 +0100

    s3:groupdb: allow machine accounts as members.
    
    metze

commit 255f2e06991aa543cd2c6f4d0123664b2a76c99d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 1 18:46:57 2011 +0100

    s3:winbindd: catch lookup_names/sids schannel errors over ncacn_ip_tcp (bug #7944)
    
    If winbindd connects to a domain controller it doesn't establish the lsa
    connection over ncacn_ip_tcp direct. This happens only on demand.
    
    If someone does a 'net rpc testjoin' and then a
    wbinfo -n DOMAIN\\administrator, we'll get DCERPC faults with
    ACCESS_DENIED/SEC_PKG_ERROR, because winbindd's in memory copy
    of the schannel session key is invalidated.
    
    This problem can also happen on other calls, but the
    lookup_names/sids calls on thet lsa ncacn_ip_tcp connection
    are the most important ones.
    
    The long term fix is to store the schannel client state in a
    tdb, but for now it's enough to catch the error and invalidate
    the all connections to the dc and reestablish the schannel
    session key.
    
    The fix for bug 7568 (commit be396411a4e1f3a174f8a44b6c062d834135e70a)
    made this worse, as it assumes winbindd's in memory session key is
    always the current one.
    
    metze

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

Summary of changes:
 source3/Makefile.in                   |    1 +
 source3/groupdb/mapping.c             |    8 +-
 source3/libnet/libnet_dssync.c        |   22 +
 source3/libnet/libnet_dssync.h        |    6 +
 source3/libnet/libnet_dssync_passdb.c | 1880 +++++++++++++++++++++++++++++++++
 source3/utils/net_proto.h             |   24 -
 source3/utils/net_rpc.c               |    5 +-
 source3/utils/net_rpc_samsync.c       |  146 +++-
 source3/winbindd/winbindd_msrpc.c     |   28 +
 9 files changed, 2062 insertions(+), 58 deletions(-)
 create mode 100644 source3/libnet/libnet_dssync_passdb.c


Changeset truncated at 500 lines:

diff --git a/source3/Makefile.in b/source3/Makefile.in
index 7e07435..b891dcd 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -1123,6 +1123,7 @@ LIBNET_OBJ = libnet/libnet_join.o \
 	     librpc/gen_ndr/ndr_libnet_join.o
 
 LIBNET_DSSYNC_OBJ = libnet/libnet_dssync.o \
+		    libnet/libnet_dssync_passdb.o \
 		    libnet/libnet_dssync_keytab.o \
 		    ../libcli/drsuapi/repl_decrypt.o
 
diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c
index 0c6da8c..837f84a 100644
--- a/source3/groupdb/mapping.c
+++ b/source3/groupdb/mapping.c
@@ -324,8 +324,8 @@ int smb_add_user_group(const char *unix_group, const char *unix_user)
 		if (!add_script) {
 			return -1;
 		}
-		add_script = talloc_string_sub(ctx,
-				add_script, "%u", unix_user);
+		add_script = talloc_string_sub2(ctx,
+				add_script, "%u", unix_user, true, false, true);
 		if (!add_script) {
 			return -1;
 		}
@@ -364,8 +364,8 @@ int smb_delete_user_group(const char *unix_group, const char *unix_user)
 		if (!del_script) {
 			return -1;
 		}
-		del_script = talloc_string_sub(ctx,
-				del_script, "%u", unix_user);
+		del_script = talloc_string_sub2(ctx,
+				del_script, "%u", unix_user, true, false, true);
 		if (!del_script) {
 			return -1;
 		}
diff --git a/source3/libnet/libnet_dssync.c b/source3/libnet/libnet_dssync.c
index 3aed8b6..64a4df0 100644
--- a/source3/libnet/libnet_dssync.c
+++ b/source3/libnet/libnet_dssync.c
@@ -451,6 +451,8 @@ static NTSTATUS libnet_dssync_getncchanges(TALLOC_CTX *mem_ctx,
 	for (y=0, last_query = false; !last_query; y++) {
 		struct drsuapi_DsReplicaObjectListItemEx *first_object = NULL;
 		struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr = NULL;
+		uint32_t linked_attributes_count = 0;
+		struct drsuapi_DsReplicaLinkedAttribute *linked_attributes = NULL;
 
 		if (level == 8) {
 			DEBUG(1,("start[%d] tmp_higest_usn: %llu , highest_usn: %llu\n",y,
@@ -537,6 +539,9 @@ static NTSTATUS libnet_dssync_getncchanges(TALLOC_CTX *mem_ctx,
 			first_object = ctr6->first_object;
 			mapping_ctr = &ctr6->mapping_ctr;
 
+			linked_attributes = ctr6->linked_attributes;
+			linked_attributes_count = ctr6->linked_attributes_count;
+
 			if (ctr6->more_data) {
 				req->req8.highwatermark = ctr6->new_highwatermark;
 			} else {
@@ -576,6 +581,23 @@ static NTSTATUS libnet_dssync_getncchanges(TALLOC_CTX *mem_ctx,
 				goto out;
 			}
 		}
+
+		if (linked_attributes_count == 0) {
+			continue;
+		}
+
+		if (ctx->ops->process_links) {
+			status = ctx->ops->process_links(ctx, mem_ctx,
+							 linked_attributes_count,
+							 linked_attributes,
+							 mapping_ctr);
+			if (!NT_STATUS_IS_OK(status)) {
+				ctx->error_message = talloc_asprintf(ctx,
+					"Failed to call processing function: %s",
+					nt_errstr(status));
+				goto out;
+			}
+		}
 	}
 
 	*pnew_utdv = new_utdv;
diff --git a/source3/libnet/libnet_dssync.h b/source3/libnet/libnet_dssync.h
index 91f48f5..d426d8b 100644
--- a/source3/libnet/libnet_dssync.h
+++ b/source3/libnet/libnet_dssync.h
@@ -30,6 +30,11 @@ struct dssync_ops {
 				    TALLOC_CTX *mem_ctx,
 				    struct drsuapi_DsReplicaObjectListItemEx *objects,
 				    struct drsuapi_DsReplicaOIDMapping_Ctr *mappings);
+	NTSTATUS (*process_links)(struct dssync_context *ctx,
+				  TALLOC_CTX *mem_ctx,
+				  uint32_t count,
+				  struct drsuapi_DsReplicaLinkedAttribute *links,
+				  struct drsuapi_DsReplicaOIDMapping_Ctr *mappings);
 	NTSTATUS (*finish)(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
 			   struct replUpToDateVectorBlob *new_utdv);
 };
@@ -58,6 +63,7 @@ struct dssync_context {
 };
 
 extern const struct dssync_ops libnet_dssync_keytab_ops;
+extern const struct dssync_ops libnet_dssync_passdb_ops;
 
 /* The following definitions come from libnet/libnet_dssync.c  */
 
diff --git a/source3/libnet/libnet_dssync_passdb.c b/source3/libnet/libnet_dssync_passdb.c
new file mode 100644
index 0000000..585428a
--- /dev/null
+++ b/source3/libnet/libnet_dssync_passdb.c
@@ -0,0 +1,1880 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Guenther Deschner <gd at samba.org> 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 "libnet/libnet_dssync.h"
+#include "libnet/libnet_samsync.h"
+#include "../libcli/security/security.h"
+#include "../libds/common/flags.h"
+#include "../librpc/gen_ndr/ndr_drsuapi.h"
+#include "dbwrap.h"
+
+/****************************************************************
+****************************************************************/
+
+struct dssync_passdb {
+	struct pdb_methods *methods;
+	struct db_context *all;
+	struct db_context *aliases;
+	struct db_context *groups;
+};
+
+struct dssync_passdb_obj {
+	struct dssync_passdb_obj *self;
+	uint32_t type;
+	struct drsuapi_DsReplicaObjectListItemEx *cur;
+	TDB_DATA key;
+	TDB_DATA data;
+	struct db_context *members;
+};
+
+struct dssync_passdb_mem {
+	struct dssync_passdb_mem *self;
+	bool active;
+	struct drsuapi_DsReplicaObjectIdentifier3 *cur;
+	struct dssync_passdb_obj *obj;
+	TDB_DATA key;
+	TDB_DATA data;
+};
+
+static NTSTATUS dssync_insert_obj(struct dssync_passdb *pctx,
+				  struct db_context *db,
+				  struct dssync_passdb_obj *obj)
+{
+	NTSTATUS status;
+	struct db_record *rec;
+
+	rec = db->fetch_locked(db, talloc_tos(), obj->key);
+	if (rec == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	if (rec->value.dsize != 0) {
+		abort();
+	}
+
+	status = rec->store(rec, obj->data, TDB_INSERT);
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(rec);
+		return status;
+	}
+	TALLOC_FREE(rec);
+	return NT_STATUS_OK;
+}
+
+static struct dssync_passdb_obj *dssync_parse_obj(const TDB_DATA data)
+{
+	struct dssync_passdb_obj *obj;
+
+	if (data.dsize != sizeof(obj)) {
+		return NULL;
+	}
+
+	/*
+	 * we need to copy the pointer to avoid alignment problems
+	 * on some systems.
+	 */
+	memcpy(&obj, data.dptr, sizeof(obj));
+
+	return talloc_get_type_abort(obj, struct dssync_passdb_obj);
+}
+
+static struct dssync_passdb_obj *dssync_search_obj_by_guid(struct dssync_passdb *pctx,
+							   struct db_context *db,
+							   const struct GUID *guid)
+{
+	struct dssync_passdb_obj *obj;
+	int ret;
+	TDB_DATA key;
+	TDB_DATA data;
+
+	key = make_tdb_data((const uint8_t *)(void *)guid,
+			     sizeof(*guid));
+
+	ret = db->fetch(db, talloc_tos(), key, &data);
+	if (ret != 0) {
+		return NULL;
+	}
+
+	obj = dssync_parse_obj(data);
+	return obj;
+}
+
+static NTSTATUS dssync_create_obj(struct dssync_passdb *pctx,
+				  struct db_context *db,
+				  uint32_t type,
+				  struct drsuapi_DsReplicaObjectListItemEx *cur,
+				  struct dssync_passdb_obj **_obj)
+{
+	NTSTATUS status;
+	struct dssync_passdb_obj *obj;
+
+	obj = talloc_zero(pctx, struct dssync_passdb_obj);
+	if (obj == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	obj->self = obj;
+	obj->cur = cur;
+	obj->type = type;
+	obj->key = make_tdb_data((const uint8_t *)(void *)&cur->object.identifier->guid,
+				   sizeof(cur->object.identifier->guid));
+	obj->data = make_tdb_data((const uint8_t *)(void *)&obj->self,
+				  sizeof(obj->self));
+
+	obj->members = db_open_rbt(obj);
+	if (obj->members == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	status = dssync_insert_obj(pctx, db, obj);
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(obj);
+		return status;
+	}
+	*_obj = obj;
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS dssync_insert_mem(struct dssync_passdb *pctx,
+				  struct dssync_passdb_obj *obj,
+				  struct dssync_passdb_mem *mem)
+{
+	NTSTATUS status;
+	struct db_record *rec;
+
+	rec = obj->members->fetch_locked(obj->members, talloc_tos(), mem->key);
+	if (rec == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	if (rec->value.dsize != 0) {
+		abort();
+	}
+
+	status = rec->store(rec, mem->data, TDB_INSERT);
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(rec);
+		return status;
+	}
+	TALLOC_FREE(rec);
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS dssync_create_mem(struct dssync_passdb *pctx,
+				  struct dssync_passdb_obj *obj,
+				  bool active,
+				  struct drsuapi_DsReplicaObjectIdentifier3 *cur,
+				  struct dssync_passdb_mem **_mem)
+{
+	NTSTATUS status;
+	struct dssync_passdb_mem *mem;
+
+	mem = talloc_zero(pctx, struct dssync_passdb_mem);
+	if (mem == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	mem->self = mem;
+	mem->cur = cur;
+	mem->active = active;
+	mem->obj = NULL;
+	mem->key = make_tdb_data((const uint8_t *)(void *)&cur->guid,
+				   sizeof(cur->guid));
+	mem->data = make_tdb_data((const uint8_t *)(void *)&mem->self,
+				  sizeof(mem->self));
+
+	status = dssync_insert_mem(pctx, obj, mem);
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(obj);
+		return status;
+	}
+	*_mem = mem;
+	return NT_STATUS_OK;
+}
+
+static struct dssync_passdb_mem *dssync_parse_mem(const TDB_DATA data)
+{
+	struct dssync_passdb_mem *mem;
+
+	if (data.dsize != sizeof(mem)) {
+		return NULL;
+	}
+
+	/*
+	 * we need to copy the pointer to avoid alignment problems
+	 * on some systems.
+	 */
+	memcpy(&mem, data.dptr, sizeof(mem));
+
+	return talloc_get_type_abort(mem, struct dssync_passdb_mem);
+}
+
+static NTSTATUS passdb_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
+			       struct replUpToDateVectorBlob **pold_utdv)
+{
+	NTSTATUS status;
+	struct dssync_passdb *pctx;
+
+	pctx = talloc_zero(mem_ctx, struct dssync_passdb);
+	if (pctx == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (ctx->output_filename) {
+		status = make_pdb_method_name(&pctx->methods, ctx->output_filename);
+	} else {
+		status = make_pdb_method_name(&pctx->methods, lp_passdb_backend());
+	}
+
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	pctx->all = db_open_rbt(pctx);
+	if (pctx->all == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	pctx->aliases = db_open_rbt(pctx);
+	if (pctx->aliases == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	pctx->groups = db_open_rbt(pctx);
+	if (pctx->groups == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	ctx->private_data = pctx;
+
+	return status;
+}
+
+/****************************************************************
+****************************************************************/
+
+struct dssync_passdb_traverse_amembers {
+	struct dssync_context *ctx;
+	struct dssync_passdb_obj *obj;
+	const char *name;
+	uint32_t idx;
+};
+
+struct dssync_passdb_traverse_aliases {
+	struct dssync_context *ctx;
+	const char *name;
+	uint32_t idx;
+};
+
+static int dssync_passdb_traverse_amembers(struct db_record *rec,
+					   void *private_data)
+{
+	struct dssync_passdb_traverse_amembers *state =
+		(struct dssync_passdb_traverse_amembers *)private_data;
+	struct dssync_passdb *pctx =
+		talloc_get_type_abort(state->ctx->private_data,
+		struct dssync_passdb);
+	struct dssync_passdb_mem *mem;
+	NTSTATUS status;
+	struct dom_sid alias_sid;
+	struct dom_sid member_sid;
+	const char *member_dn;
+	size_t num_members;
+	size_t i;
+	struct dom_sid *members;
+	bool is_member = false;
+	const char *action;
+
+	state->idx++;
+
+	alias_sid = state->obj->cur->object.identifier->sid;
+
+	mem = dssync_parse_mem(rec->value);
+	if (mem == NULL) {
+		return -1;
+	}
+
+	member_sid = mem->cur->sid;
+	member_dn = mem->cur->dn;
+
+	mem->obj = dssync_search_obj_by_guid(pctx, pctx->all, &mem->cur->guid);
+	if (mem->obj == NULL) {
+		DEBUG(0,("alias[%s] member[%s] can't resolve member - ignoring\n",
+			 sid_string_dbg(&alias_sid),
+			 is_null_sid(&member_sid)?
+			 sid_string_dbg(&member_sid):
+			 member_dn));
+		return 0;
+	}
+
+	switch (mem->obj->type) {
+	case ATYPE_DISTRIBUTION_LOCAL_GROUP:
+	case ATYPE_DISTRIBUTION_GLOBAL_GROUP:
+		DEBUG(0, ("alias[%s] ignore distribution group [%s]\n",
+			  sid_string_dbg(&alias_sid),
+			  member_dn));
+		return 0;
+	default:
+		break;
+	}
+
+	DEBUG(0,("alias[%s] member[%s]\n",
+		 sid_string_dbg(&alias_sid),
+		 sid_string_dbg(&member_sid)));
+
+	status = pdb_enum_aliasmem(&alias_sid, talloc_tos(),
+				   &members, &num_members);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("Could not find current alias members %s - %s\n",
+			  sid_string_dbg(&alias_sid),
+			  nt_errstr(status)));
+		return -1;
+	}
+
+	for (i=0; i < num_members; i++) {
+		bool match;
+
+		match = dom_sid_equal(&members[i], &member_sid);
+		if (match) {
+			is_member = true;
+			break;
+		}
+	}
+
+	status = NT_STATUS_OK;
+	action = "none";
+	if (!is_member && mem->active) {
+		action = "add";
+		pdb_add_aliasmem(&alias_sid, &member_sid);
+	} else if (is_member && !mem->active) {
+		action = "delete";
+		pdb_del_aliasmem(&alias_sid, &member_sid);
+	}
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("Could not %s %s as alias members of %s - %s\n",
+			  action,
+			  sid_string_dbg(&member_sid),
+			  sid_string_dbg(&alias_sid),
+			  nt_errstr(status)));
+		return -1;
+	}
+
+	return 0;
+}
+
+static int dssync_passdb_traverse_aliases(struct db_record *rec,
+					  void *private_data)
+{
+	struct dssync_passdb_traverse_aliases *state =
+		(struct dssync_passdb_traverse_aliases *)private_data;
+	struct dssync_passdb *pctx =
+		talloc_get_type_abort(state->ctx->private_data,
+		struct dssync_passdb);
+	struct dssync_passdb_traverse_amembers mstate;
+	struct dssync_passdb_obj *obj;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list