[SCM] Samba Shared Repository - branch master updated - 63554b4078e3039bfeda46d8bc77d6ad7ab189ad

Jeremy Allison jra at samba.org
Tue Sep 16 17:35:18 GMT 2008


The branch, master has been updated
       via  63554b4078e3039bfeda46d8bc77d6ad7ab189ad (commit)
       via  544cd1b4b9c27a76944abbe512dba05487701816 (commit)
       via  d6de32db2f8d080cb746b3032c128f210154b75e (commit)
      from  f2723d193d8a7963b937414ee32e5c6f529b9032 (commit)

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


- Log -----------------------------------------------------------------
commit 63554b4078e3039bfeda46d8bc77d6ad7ab189ad
Author: Gerald (Jerry) Carter <jerry at samba.org>
Date:   Mon Sep 15 15:51:44 2008 -0500

    idmap_hash: Add the idmap/nss-info provider from Likewise Open.
    
    * Port the Likewise Open idmap/nss_info provider (renamed to
      idmap_hash).
    
    * uids & gids are generated based on a hashing algorithm that collapse
      the Domain SID to a 31 bit number.  The reverse mapping from the
      high order 11 bits to the originat8ing sdomain SID is stored in
      a has table initialized at start up.
    
    * Includes support for "idmap_hash:name_map = <filename>" for the
      name aliasing layer.  The name map file consist of entries in
      the form "alias = DOMAIN\name"

commit 544cd1b4b9c27a76944abbe512dba05487701816
Author: Gerald (Jerry) Carter <jerry at samba.org>
Date:   Mon Sep 15 15:50:15 2008 -0500

    winbindd: Update the calls to ws_name_XX() to reflect API changes.
    
    * Ensures that all points an which a name is received or returned
      to/from a client passes through the name aliases layer (users
      and groups).

commit d6de32db2f8d080cb746b3032c128f210154b75e
Author: Gerald (Jerry) Carter <jerry at samba.org>
Date:   Mon Sep 15 15:41:37 2008 -0500

    winbindd: Add support for name aliasing.
    
    * Add support user and group name aliasing by expanding
      the ws_name_replace() and ws_name_return() functions.
      The lookup path is
         aliases -> qualified name -> SID
         SID -> fully qualified name -> alias
      In other words, the name aliasing support is a thin layer
      built on top of SID/NAME translation.
    
    * Rename the ws_name_XX() functions to normalize_name_map()
      and normalize_name_unmap().  Chaneg interface to return
      NTSTATUS rather than char *.
    
    * Add associated cache validation functions.

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

Summary of changes:
 source3/Makefile.in                      |    8 +
 source3/configure.in                     |    1 +
 source3/include/nss_info.h               |   10 +
 source3/winbindd/idmap_hash/idmap_hash.c |  393 ++++++++++++++++++++++++++++++
 source3/winbindd/idmap_hash/idmap_hash.h |   60 +++++
 source3/winbindd/idmap_hash/mapfile.c    |  175 +++++++++++++
 source3/winbindd/nss_info.c              |   41 +++
 source3/winbindd/nss_info_template.c     |   32 +++-
 source3/winbindd/winbindd_cache.c        |  249 +++++++++++++++++++
 source3/winbindd/winbindd_group.c        |  182 ++++++++++++---
 source3/winbindd/winbindd_pam.c          |   60 ++++-
 source3/winbindd/winbindd_proto.h        |   18 ++-
 source3/winbindd/winbindd_rpc.c          |   44 +++-
 source3/winbindd/winbindd_user.c         |   74 ++++++-
 source3/winbindd/winbindd_util.c         |  107 +++++++--
 15 files changed, 1386 insertions(+), 68 deletions(-)
 create mode 100644 source3/winbindd/idmap_hash/idmap_hash.c
 create mode 100644 source3/winbindd/idmap_hash/idmap_hash.h
 create mode 100644 source3/winbindd/idmap_hash/mapfile.c


Changeset truncated at 500 lines:

diff --git a/source3/Makefile.in b/source3/Makefile.in
index 11399ba..ae446fc 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -979,6 +979,10 @@ IDMAP_OBJ     = winbindd/idmap.o winbindd/idmap_util.o @IDMAP_STATIC@
 
 NSS_INFO_OBJ = winbindd/nss_info.o @NSS_INFO_STATIC@
 
+IDMAP_HASH_OBJ = \
+		winbindd/idmap_hash/idmap_hash.o \
+		winbindd/idmap_hash/mapfile.o
+
 WINBINDD_OBJ1 = \
 		winbindd/winbindd.o       \
 		winbindd/winbindd_user.o  \
@@ -2208,6 +2212,10 @@ bin/ad. at SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_ad.o
 	@echo "Building plugin $@"
 	@$(SHLD_MODULE) winbindd/idmap_ad.o
 
+bin/hash. at SHLIBEXT@: $(BINARY_PREREQS) $(IDMAP_HASH_OBJ)
+	@echo "Building plugin $@"
+	@$(SHLD_MODULE) $(IDMAP_HASH_OBJ)
+
 bin/tdb2. at SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_tdb2.o
 	@echo "Building plugin $@"
 	@$(SHLD_MODULE) winbindd/idmap_tdb2.o
diff --git a/source3/configure.in b/source3/configure.in
index d9766e4..8025cc3 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -6057,6 +6057,7 @@ SMB_MODULE(idmap_passdb, winbindd/idmap_passdb.o, "bin/passdb.$SHLIBEXT", IDMAP)
 SMB_MODULE(idmap_nss, winbindd/idmap_nss.o, "bin/nss.$SHLIBEXT", IDMAP)
 SMB_MODULE(idmap_rid, winbindd/idmap_rid.o, "bin/rid.$SHLIBEXT", IDMAP)
 SMB_MODULE(idmap_ad, winbindd/idmap_ad.o, "bin/ad.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_hash, \$(IDMAP_HASH_OBJ), "bin/hash.$SHLIBEXT", IDMAP)
 SMB_SUBSYSTEM(IDMAP, winbindd/idmap.o)
 
 SMB_MODULE(nss_info_template, winbindd/nss_info_template.o, "bin/template.$SHLIBEXT", NSS_INFO)
diff --git a/source3/include/nss_info.h b/source3/include/nss_info.h
index 1ff9ebc..e756136 100644
--- a/source3/include/nss_info.h
+++ b/source3/include/nss_info.h
@@ -66,6 +66,10 @@ struct nss_info_methods {
 				  TALLOC_CTX *ctx, 
 				  ADS_STRUCT *ads, LDAPMessage *msg,
 				  char **homedir, char **shell, char **gecos, gid_t *p_gid);
+	NTSTATUS (*map_to_alias)( TALLOC_CTX *mem_ctx, const char *domain,
+				  const char *name, char **alias );
+	NTSTATUS (*map_from_alias)( TALLOC_CTX *mem_ctx, const char *domain,
+				    const char *alias, char **name );
 	NTSTATUS (*close_fn)( void );
 };
 
@@ -84,6 +88,12 @@ NTSTATUS nss_get_info( const char *domain, const DOM_SID *user_sid,
                        char **homedir, char **shell, char **gecos,
                        gid_t *p_gid);
 
+NTSTATUS nss_map_to_alias( TALLOC_CTX *mem_ctx, const char *domain,
+			   const char *name, char **alias );
+
+NTSTATUS nss_map_from_alias( TALLOC_CTX *mem_ctx, const char *domain,
+			     const char *alias, char **name );
+
 NTSTATUS nss_close( const char *parameters );
 
 #endif /* _IDMAP_NSS_H_ */
diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c
new file mode 100644
index 0000000..a050f99
--- /dev/null
+++ b/source3/winbindd/idmap_hash/idmap_hash.c
@@ -0,0 +1,393 @@
+/*
+ *  idmap_hash.c
+ *
+ * Copyright (C) Gerald Carter  <jerry at samba.org>      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"
+#include "winbindd/winbindd.h"
+#include "idmap_hash.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_IDMAP
+
+struct sid_hash_table {
+	DOM_SID *sid;
+};
+
+struct sid_hash_table *hashed_domains = NULL;
+
+/*********************************************************************
+ Hash a domain SID (S-1-5-12-aaa-bbb-ccc) to a 12bit number
+ ********************************************************************/
+
+static uint32_t hash_domain_sid(const DOM_SID *sid)
+{
+	uint32_t hash;
+
+	if (sid->num_auths != 4)
+		return 0;
+
+	/* XOR the last three subauths */
+
+	hash = ((sid->sub_auths[1] ^ sid->sub_auths[2]) ^ sid->sub_auths[3]);
+
+	/* Take all 32-bits into account when generating the 12-bit
+	   hash value */
+	hash = (((hash & 0xFFF00000) >> 20)
+		+ ((hash & 0x000FFF00) >> 8)
+		+ (hash & 0x000000FF)) & 0x0000FFF;
+
+	/* return a 12-bit hash value */
+
+	return hash;
+}
+
+/*********************************************************************
+ Hash a Relative ID to a 20 bit number
+ ********************************************************************/
+
+static uint32_t hash_rid(uint32_t rid)
+{
+	/* 20 bits for the rid which allows us to support
+	   the first 100K users/groups in a domain */
+
+	return (rid & 0x0007FFFF);
+}
+
+/*********************************************************************
+ ********************************************************************/
+
+static uint32_t combine_hashes(uint32_t h_domain,
+			       uint32_t h_rid)
+{
+	uint32_t return_id = 0;
+
+	/* shift the hash_domain 19 bits to the left and OR with the
+	   hash_rid */
+
+	return_id = ((h_domain<<19) | h_rid);
+
+	return return_id;
+}
+
+/*********************************************************************
+ ********************************************************************/
+
+static void separate_hashes(uint32_t id,
+			    uint32_t *h_domain,
+			    uint32_t *h_rid)
+{
+	*h_rid = id & 0x0007FFFF;
+	*h_domain = (id & 0x7FF80000) >> 19;
+
+	return;
+}
+
+
+/*********************************************************************
+ ********************************************************************/
+
+static NTSTATUS be_init(struct idmap_domain *dom,
+			const char *params)
+{
+	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+	struct winbindd_tdc_domain *dom_list = NULL;
+	size_t num_domains = 0;
+	int i;
+
+	/* If the domain SID hash talbe has been initialized, assume
+	   that we completed this function previously */
+
+	if ( hashed_domains ) {
+		nt_status = NT_STATUS_OK;
+		goto done;
+	}
+
+	if (!wcache_tdc_fetch_list(&dom_list, &num_domains)) {
+		nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE;
+		BAIL_ON_NTSTATUS_ERROR(nt_status);
+	}
+
+	/* Create the hash table of domain SIDs */
+
+	hashed_domains = TALLOC_ZERO_ARRAY(NULL, struct sid_hash_table, 4096);
+	BAIL_ON_PTR_NT_ERROR(hashed_domains, nt_status);
+
+	/* create the hash table of domain SIDs */
+
+	for (i=0; i<num_domains; i++) {
+		uint32_t hash;
+
+		if (is_null_sid(&dom_list[i].sid))
+			continue;
+		if ((hash = hash_domain_sid(&dom_list[i].sid)) == 0)
+			continue;
+
+		DEBUG(5,("hash:be_init() Adding %s (%s) -> %d\n",
+			 dom_list[i].domain_name,
+			 sid_string_dbg(&dom_list[i].sid),
+			 hash));
+
+		hashed_domains[hash].sid = talloc(hashed_domains, DOM_SID);
+		sid_copy(hashed_domains[hash].sid, &dom_list[i].sid);
+	}
+
+done:
+	return nt_status;
+}
+
+/*********************************************************************
+ ********************************************************************/
+
+static NTSTATUS unixids_to_sids(struct idmap_domain *dom,
+				struct id_map **ids)
+{
+	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+	int i;
+
+	nt_status = be_init(dom, NULL);
+	BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+	if (!ids) {
+		nt_status = NT_STATUS_INVALID_PARAMETER;
+		BAIL_ON_NTSTATUS_ERROR(nt_status);
+	}
+
+	for (i=0; ids[i]; i++) {
+		uint32_t h_domain, h_rid;
+
+		ids[i]->status = ID_UNMAPPED;
+
+		separate_hashes(ids[i]->xid.id, &h_domain, &h_rid);
+
+		/* Make sure the caller allocated memor for us */
+
+		if (!ids[i]->sid) {
+			nt_status = NT_STATUS_INVALID_PARAMETER;
+			BAIL_ON_NTSTATUS_ERROR(nt_status);
+		}
+
+		/* If the domain hash doesn't find a SID in the table,
+		   skip it */
+
+		if (!hashed_domains[h_domain].sid)
+			continue;
+
+		sid_copy(ids[i]->sid, hashed_domains[h_domain].sid);
+		sid_append_rid(ids[i]->sid, h_rid);
+		ids[i]->status = ID_MAPPED;
+	}
+
+done:
+	return nt_status;
+}
+
+/*********************************************************************
+ ********************************************************************/
+
+static NTSTATUS sids_to_unixids(struct idmap_domain *dom,
+				struct id_map **ids)
+{
+	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+	int i;
+
+	nt_status = be_init(dom, NULL);
+	BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+	if (!ids) {
+		nt_status = NT_STATUS_INVALID_PARAMETER;
+		BAIL_ON_NTSTATUS_ERROR(nt_status);
+	}
+
+	for (i=0; ids[i]; i++) {
+		DOM_SID sid;
+		uint32_t rid;
+		uint32_t h_domain, h_rid;
+
+		ids[i]->status = ID_UNMAPPED;
+
+		sid_copy(&sid, ids[i]->sid);
+		sid_split_rid(&sid, &rid);
+
+		h_domain = hash_domain_sid(&sid);
+		h_rid = hash_rid(rid);
+
+		/* Check that both hashes are non-zero*/
+
+		if (h_domain && h_rid) {
+			ids[i]->xid.id = combine_hashes(h_domain, h_rid);
+			ids[i]->status = ID_MAPPED;
+		}
+	}
+
+done:
+	return nt_status;
+}
+
+/*********************************************************************
+ ********************************************************************/
+
+static NTSTATUS be_close(struct idmap_domain *dom)
+{
+	if (hashed_domains)
+		talloc_free(hashed_domains);
+
+	return NT_STATUS_OK;
+}
+
+/*********************************************************************
+ ********************************************************************/
+
+static NTSTATUS nss_hash_init(struct nss_domain_entry *e )
+{
+	return be_init(NULL, NULL);
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS nss_hash_get_info(struct nss_domain_entry *e,
+				    const DOM_SID *sid,
+				    TALLOC_CTX *ctx,
+				    ADS_STRUCT *ads,
+				    LDAPMessage *msg,
+				    char **homedir,
+				    char **shell,
+				    char **gecos,
+				    gid_t *p_gid )
+{
+	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+
+	nt_status = nss_hash_init(e);
+	BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+	if (!homedir || !shell || !gecos) {
+		nt_status = NT_STATUS_INVALID_PARAMETER;
+		BAIL_ON_NTSTATUS_ERROR(nt_status);
+	}
+
+	*homedir = talloc_strdup(ctx, lp_template_homedir());
+	BAIL_ON_PTR_NT_ERROR(*homedir, nt_status);
+
+	*shell   = talloc_strdup(ctx, lp_template_shell());
+	BAIL_ON_PTR_NT_ERROR(*shell, nt_status);
+
+	*gecos   = NULL;
+
+	/* Initialize the gid so that the upper layer fills
+	   in the proper Windows primary group */
+
+	if (*p_gid) {
+		*p_gid = (gid_t)-1;
+	}
+
+done:
+	return nt_status;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS nss_hash_map_to_alias(TALLOC_CTX *mem_ctx,
+					const char *domain,
+					const char *name,
+					char **alias)
+{
+	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+	const char *value;
+
+	value = talloc_asprintf(mem_ctx, "%s\\%s", domain, name);
+	BAIL_ON_PTR_NT_ERROR(value, nt_status);
+
+	nt_status = mapfile_lookup_key(mem_ctx, value, alias);
+	BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+done:
+	return nt_status;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS nss_hash_map_from_alias(TALLOC_CTX *mem_ctx,
+					  const char *domain,
+					  const char *alias,
+					  char **name)
+{
+	return mapfile_lookup_value(mem_ctx, alias, name);
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS nss_hash_close(void)
+{
+	return NT_STATUS_OK;
+}
+
+/*********************************************************************
+ Dispatch Tables for IDMap and NssInfo Methods
+********************************************************************/
+
+static struct idmap_methods hash_idmap_methods = {
+	.init            = be_init,
+	.unixids_to_sids = unixids_to_sids,
+	.sids_to_unixids = sids_to_unixids,
+	.close_fn        = be_close
+};
+
+static struct nss_info_methods hash_nss_methods = {
+	.init           = nss_hash_init,
+	.get_nss_info   = nss_hash_get_info,
+	.map_to_alias   = nss_hash_map_to_alias,
+	.map_from_alias = nss_hash_map_from_alias,
+	.close_fn       = nss_hash_close
+};
+
+/**********************************************************************
+ Register with the idmap and idmap_nss subsystems. We have to protect
+ against the idmap and nss_info interfaces being in a half-registered
+ state.
+ **********************************************************************/
+
+NTSTATUS idmap_hash_init(void)
+{
+	static NTSTATUS idmap_status = NT_STATUS_UNSUCCESSFUL;
+	static NTSTATUS nss_status = NT_STATUS_UNSUCCESSFUL;
+
+	if ( !NT_STATUS_IS_OK(idmap_status) ) {
+		idmap_status =  smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
+						   "hash", &hash_idmap_methods);
+
+		if ( !NT_STATUS_IS_OK(idmap_status) ) {
+			DEBUG(0,("Failed to register hash idmap plugin.\n"));
+			return idmap_status;
+		}
+	}
+
+	if ( !NT_STATUS_IS_OK(nss_status) ) {
+		nss_status = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
+						    "hash", &hash_nss_methods);
+		if ( !NT_STATUS_IS_OK(nss_status) ) {
+			DEBUG(0,("Failed to register hash idmap nss plugin.\n"));
+			return nss_status;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
diff --git a/source3/winbindd/idmap_hash/idmap_hash.h b/source3/winbindd/idmap_hash/idmap_hash.h
new file mode 100644
index 0000000..621520e
--- /dev/null
+++ b/source3/winbindd/idmap_hash/idmap_hash.h
@@ -0,0 +1,60 @@
+/*
+ *  lwopen.h
+ *
+ *  Copyright (C) Gerald Carter  <jerry at samba.org>
+ *
+ *  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 _LWOPEN_H
+#define _LWOPEN_H
+
+#define BAIL_ON_NTSTATUS_ERROR(x)	   \
+	do {				   \
+		if (!NT_STATUS_IS_OK(x)) { \
+			DEBUG(10,("Failed! (%s)\n", nt_errstr(x)));	\
+			goto done;	   \
+		}			   \


-- 
Samba Shared Repository


More information about the samba-cvs mailing list