[SCM] SAMBA-CTDB repository - branch v3-4-ctdb updated - e780063d072342cc5c57a7adc6c8ea2cd8084775

Michael Adam obnox at samba.org
Tue Jun 23 12:19:41 GMT 2009


The branch, v3-4-ctdb has been updated
       via  e780063d072342cc5c57a7adc6c8ea2cd8084775 (commit)
       via  65f92495d27591ce7ed6e8f955484a0c71b0dd37 (commit)
       via  3df65b93aa7c0fecebd197b5e335f384c9942c8f (commit)
       via  7a1b9fae0108ebaa05e40b44d9dd32d89f346cdf (commit)
       via  d281d5fdf30cdf9a08c8b53c60405b1d10ff8314 (commit)
       via  25038a982bc47845ce05600f62399896e2e78cac (commit)
      from  42a7c48712b418acdc030d141a37d10a02c37223 (commit)

http://gitweb.samba.org/?p=obnox/samba-ctdb.git;a=shortlog;h=v3-4-ctdb


- Log -----------------------------------------------------------------
commit e780063d072342cc5c57a7adc6c8ea2cd8084775
Author: Michael Adam <obnox at samba.org>
Date:   Wed Jan 28 13:34:34 2009 +0100

    vfs_gpfs_prefetch: correctly return -1 on error condition in smbd_gpfs_fcntl()
    
    Michael

commit 65f92495d27591ce7ed6e8f955484a0c71b0dd37
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Apr 28 11:44:26 2008 +0200

    Add a gpfs_prefetch module
    
    This can not go upstream yet because it uses the non-GPL libgpfs. So it will
    not be compiled by default and will not be included in the SOFS RPMs. But upon
    Sven's request, we include it in the git tree and the source RPMs, so that it
    can be built for in-house tests.

commit 3df65b93aa7c0fecebd197b5e335f384c9942c8f
Author: Volker Lendecke <vl at samba.org>
Date:   Fri May 29 00:20:10 2009 +0200

    Support getting gpfs birthtime

commit 7a1b9fae0108ebaa05e40b44d9dd32d89f346cdf
Author: Mathias Dietz <mdietz at de.ibm.com>
Date:   Wed May 27 12:03:12 2009 +0200

    Store winattrs in GPFS
    
    1. Store win attributes in gpfs instead of posix bits.
        2. use of path based winattr calls of gpfs.
    
        Signed-off-by: Mathias Dietz <mdietz at de.ibm.com>

commit d281d5fdf30cdf9a08c8b53c60405b1d10ff8314
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Dec 15 00:16:56 2008 +0100

    Add the "net groupfilter" command
    
    This is the start of a bad hack for even worse systems: Many Unix systems still
    have the NGROUPS problem: A user can not be member of more than a very limited
    number of groups. Solaris for example limits this to 16 by default. Many
    Windows environments have a *LOT* more groups per user, some even go to
    hundreds. Whether that is efficient is debatable, but it's there.
    
    This patch implements the
    
    "net groupfilter"
    
    command with the "addsid", "delsid" and "list" subcommands. If any SIDs are
    present according to "net groupfilter list" (they are stored in secrets.tdb),
    then only the SIDs in that list are converted to GIDs for a user at login time.
    
    This gives the Administrator the possibility to define a set of groups that are
    used on the Unix box, making sure that no user is in more than NGROUPS of those
    at a time.
    
    This patch is incomplete in the sense that winbind is not aware of this, only
    smbd. So it is kind of an emergency hack for smbd-only machines.
    
    Volker
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 25038a982bc47845ce05600f62399896e2e78cac
Author: Andrew Tridgell <tridge at samba.org>
Date:   Mon Apr 21 18:41:32 2008 +0200

    apply patch from v3-0-ctdb to special case root in libnss_winbind
    
    This is needed to ensure the administrator can login to a node even
    when ctdbd and winbindd are stuck

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

Summary of changes:
 nsswitch/winbind_nss_linux.c       |    8 +
 source/modules/vfs_gpfs_prefetch.c |  308 ++++++++++++++++++++++++++++++++++++
 source3/Makefile.in                |    5 +
 source3/auth/auth_util.c           |   30 ++++
 source3/configure.in               |    3 +-
 source3/include/proto.h            |    3 +
 source3/include/secrets.h          |    2 +
 source3/lib/util_sid.c             |   29 ++++
 source3/modules/gpfs.c             |   54 +++++++
 source3/modules/vfs_gpfs.c         |  167 +++++++++++++++++++
 source3/modules/vfs_gpfs.h         |    3 +
 source3/passdb/secrets.c           |   33 ++++
 source3/utils/net.c                |  144 +++++++++++++++++
 13 files changed, 788 insertions(+), 1 deletions(-)
 create mode 100644 source/modules/vfs_gpfs_prefetch.c


Changeset truncated at 500 lines:

diff --git a/nsswitch/winbind_nss_linux.c b/nsswitch/winbind_nss_linux.c
index 4a79432..4121476 100644
--- a/nsswitch/winbind_nss_linux.c
+++ b/nsswitch/winbind_nss_linux.c
@@ -1034,6 +1034,14 @@ _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
 		user, group);
 #endif
 
+	if (strcmp(user, "root") == 0) {
+		/* as a special case, don't return groups for
+		   'root'. This ensures that no matter what state
+		   winbind is in, we can still ssh into the host as
+		   root. */
+		return NSS_STATUS_NOTFOUND;
+	}
+
 #if HAVE_PTHREAD
 	pthread_mutex_lock(&winbind_nss_mutex);
 #endif
diff --git a/source/modules/vfs_gpfs_prefetch.c b/source/modules/vfs_gpfs_prefetch.c
new file mode 100644
index 0000000..308ac10
--- /dev/null
+++ b/source/modules/vfs_gpfs_prefetch.c
@@ -0,0 +1,308 @@
+/*
+   Unix SMB/CIFS implementation.
+   Make use of gpfs prefetch functionality
+
+   Copyright (C) Volker Lendecke 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"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+#include <gpfs.h>
+#include <gpfs_fcntl.h>
+
+static int (*gpfs_fcntl_fn)(int fd, void *arg);
+
+static int smbd_gpfs_fcntl(int fd, void *arg)
+{
+	static void *libgpfs_handle = NULL;
+
+	DEBUG(10, ("smbd_gpfs_fcntl called for %d\n", fd));
+
+	if (gpfs_fcntl_fn == NULL) {
+		libgpfs_handle = sys_dlopen("libgpfs.so", RTLD_LAZY);
+
+		if (libgpfs_handle == NULL) {
+			DEBUG(10, ("sys_dlopen for libgpfs failed: %s\n",
+				   strerror(errno)));
+			return -1;
+		}
+
+		gpfs_fcntl_fn = sys_dlsym(libgpfs_handle, "gpfs_fcntl");
+		if (gpfs_fcntl_fn == NULL) {
+			DEBUG(3, ("libgpfs.so does not contain the symbol "
+				  "'gpfs_fcntl'\n"));
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	return gpfs_fcntl_fn(fd, arg);
+}
+
+struct gpfs_prefetch_config {
+	name_compare_entry *namelist;
+	size_t size;
+};
+
+struct gpfs_prefetch_hints {
+	blksize_t st_blksize;
+	/*
+	 * The current center around which config->size bytes are
+	 * prefetched
+	 */
+	SMB_OFF_T center;
+};
+
+static void gpfs_prefetch_recenter(vfs_handle_struct *handle,
+				   files_struct *fsp,
+				   SMB_OFF_T offset, size_t size,
+				   struct gpfs_prefetch_hints *hints)
+{
+	int ret;
+	SMB_OFF_T new_center;
+
+	struct {
+		gpfsFcntlHeader_t hdr;
+		gpfsMultipleAccessRange_t acc;
+	} arg;
+
+
+	if (hints->st_blksize == 0) {
+		SMB_STRUCT_STAT sbuf;
+
+		if (SMB_VFS_NEXT_FSTAT(handle, fsp, &sbuf) == -1) {
+			return;
+		}
+		DEBUG(10, ("gpfs_prefetch_recenter: st_blksize = %d\n",
+			   (int)sbuf.st_blksize));
+		hints->st_blksize = sbuf.st_blksize;
+	}
+
+	new_center = (offset > size) ? offset : 0;
+
+	DEBUG(10, ("gpfs_prefetch_recenter: size=%d, offset=%d, "
+		   "old_center=%d, new_center=%d\n", (int)size, (int)offset,
+		   (int)hints->center, (int)new_center));
+
+	ZERO_STRUCT(arg);
+
+	arg.hdr.totalLength = sizeof(arg);
+	arg.hdr.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
+	arg.hdr.fcntlReserved = 0;
+	arg.acc.structLen = sizeof(arg.acc);
+	arg.acc.structType = GPFS_MULTIPLE_ACCESS_RANGE;
+	arg.acc.accRangeCnt = 1;
+	arg.acc.relRangeCnt = 1;
+
+	arg.acc.accRangeArray[0].blockNumber = new_center/hints->st_blksize;
+	arg.acc.accRangeArray[0].start = 0;
+	arg.acc.accRangeArray[0].length = size;
+	arg.acc.accRangeArray[0].isWrite = 0;
+
+	arg.acc.relRangeArray[0].blockNumber = hints->center/hints->st_blksize;
+	arg.acc.relRangeArray[0].start = 0;
+	arg.acc.relRangeArray[0].length = size;
+	arg.acc.relRangeArray[0].isWrite = 0;
+
+	ret = smbd_gpfs_fcntl(fsp->fh->fd, &arg);
+	if (ret == -1) {
+		DEBUG(5, ("gpfs_fcntl returned %s\n", strerror(errno)));
+	}
+
+	hints->center = new_center;
+}
+
+static ssize_t gpfs_prefetch_pread(vfs_handle_struct *handle,
+				   files_struct *fsp, void *data,
+				   size_t n, SMB_OFF_T offset)
+{
+	struct gpfs_prefetch_config *config =
+		(struct gpfs_prefetch_config *)handle->data;
+	struct gpfs_prefetch_hints *hints = (struct gpfs_prefetch_hints *)
+		VFS_FETCH_FSP_EXTENSION(handle, fsp);
+	SMB_OFF_T out_of_center;
+
+	/*
+	 * How far away from the center of the prefetch region is the
+	 * request?
+	 */
+
+	out_of_center = (offset > hints->center)
+		? (offset - hints->center) : (hints->center - offset);
+
+	DEBUG(10, ("gpfs_prefetch_pread: n=%d, offset=%d, center=%d, "
+		   "out_of_center=%d, size=%d\n", (int)n, (int)offset,
+		   (int)hints->center, (int)out_of_center,
+		   (int)config->size));
+	/*
+	 * Are we completely out of the prefetch range or less than
+	 * 10% at its borders?
+	 */
+
+	if ((out_of_center > config->size)
+	    || ((config->size - out_of_center) * 10 < config->size)) {
+		/*
+		 * Re-center the prefetch area
+		 */
+		gpfs_prefetch_recenter(handle, fsp, offset, config->size,
+				       hints);
+	}
+
+	return SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
+}
+
+static int gpfs_prefetch_open(vfs_handle_struct *handle,  const char *fname,
+			      files_struct *fsp, int flags, mode_t mode)
+{
+	int fd, ret;
+	struct gpfs_prefetch_hints *hints;
+	struct gpfs_prefetch_config *config =
+		(struct gpfs_prefetch_config *)handle->data;
+
+	struct {
+		gpfsFcntlHeader_t hdr;
+		gpfsAccessRange_t acc;
+	} arg;
+
+	DEBUG(10, ("gpfs_prefetch_open called for %s, config=%p, "
+		   "config->namelist = %p, config->size=%d\n", fname,
+		   config, config->namelist, (int)config->size));
+
+	if (!is_in_path(fname, config->namelist,
+			handle->conn->case_sensitive)) {
+		DEBUG(10, ("gpfs_prefetch_open not in list: %s\n", fname));
+		return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+	}
+
+	hints = (struct gpfs_prefetch_hints *)VFS_ADD_FSP_EXTENSION(
+		handle, fsp, struct gpfs_prefetch_hints);
+	if (hints == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+
+	fd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+	if (fd == -1) {
+		VFS_REMOVE_FSP_EXTENSION(handle, fsp);
+		return -1;
+	}
+
+	arg.hdr.totalLength = sizeof(arg);
+	arg.hdr.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
+	arg.hdr.fcntlReserved = 0;
+	arg.acc.structLen = sizeof(arg.acc);
+	arg.acc.structType = GPFS_ACCESS_RANGE;
+	arg.acc.start = 0;
+	arg.acc.length = 1;
+	arg.acc.isWrite = 0;
+
+	ret = smbd_gpfs_fcntl(fd, &arg);
+	if (ret == -1) {
+		DEBUG(5, ("gpfs_fcntl returned %s\n", strerror(errno)));
+	}
+
+	hints->st_blksize = 0;
+	hints->center = 0;
+
+	return fd;
+}
+
+static void gpfs_prefetch_config_free(void **data)
+{
+	struct gpfs_prefetch_config **config =
+		(struct gpfs_prefetch_config **)data;
+
+	free_namearray((*config)->namelist);
+	TALLOC_FREE(*config);
+}
+
+static int gpfs_prefetch_connect(struct vfs_handle_struct *handle,
+				 const char *service,
+				 const char *user)
+{
+	struct gpfs_prefetch_config *config;
+	const char *mask;
+
+	config = talloc(handle, struct gpfs_prefetch_config);
+	if (config == NULL) {
+		DEBUG(0, ("talloc failed\n"));
+		errno = ENOMEM;
+		return -1;
+	}
+
+	mask = lp_parm_const_string(SNUM(handle->conn), "gpfs_prefetch",
+				    "mask", "");
+
+	set_namearray(&config->namelist, mask);
+	config->size = lp_parm_int(SNUM(handle->conn), "gpfs_prefetch",
+				   "size", 1024);
+
+	/*
+	 * The size calculations in the core routines assume that
+	 * config->size is the size from the center to the border of
+	 * the prefetched area. So we need to multiply by 1024/2 here
+	 * to get the whole prefetch area in kilobytes.
+	 */
+	config->size *= 1024/2;
+
+	SMB_VFS_HANDLE_SET_DATA(handle, config, gpfs_prefetch_config_free,
+				struct gpfs_prefetch_config, goto fail);
+
+	return SMB_VFS_NEXT_CONNECT(handle, service, user);
+
+fail:
+	free_namearray(config->namelist);
+	TALLOC_FREE(config);
+	return -1;
+}
+
+/* VFS operations structure */
+
+static vfs_op_tuple gpfs_prefetch_op_tuples[] = {
+
+	{SMB_VFS_OP(gpfs_prefetch_open),	SMB_VFS_OP_OPEN,
+	 SMB_VFS_LAYER_TRANSPARENT },
+	{SMB_VFS_OP(gpfs_prefetch_pread),	SMB_VFS_OP_PREAD,
+	 SMB_VFS_LAYER_TRANSPARENT },
+	{SMB_VFS_OP(gpfs_prefetch_connect),	SMB_VFS_OP_CONNECT,
+	 SMB_VFS_LAYER_TRANSPARENT },
+
+        { SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP }
+};
+
+/*
+ * When done properly upstream (GPL issue resolved), change this
+ * routine name to vfs_gpfs_prefetch_init!!
+ */
+
+NTSTATUS init_samba_module(void);
+NTSTATUS init_samba_module(void)
+{
+	NTSTATUS status;
+
+	DEBUG(10, ("vfs_gpfs_prefetch_init called\n"));
+
+	status = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "gpfs_prefetch",
+				  gpfs_prefetch_op_tuples);
+	DEBUG(10, ("smb_register_vfs returned %s\n",
+		   nt_errstr(status)));
+
+	return status;
+}
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 4001eda..897eb67 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -673,6 +673,7 @@ VFS_CACHEPRIME_OBJ = modules/vfs_cacheprime.o
 VFS_PREALLOC_OBJ = modules/vfs_prealloc.o
 VFS_COMMIT_OBJ = modules/vfs_commit.o
 VFS_GPFS_OBJ = modules/vfs_gpfs.o modules/gpfs.o modules/nfs4_acls.o
+VFS_GPFS_PREFETCH_OBJ = modules/vfs_gpfs_prefetch.o modules/gpfs.o
 VFS_NOTIFY_FAM_OBJ = modules/vfs_notify_fam.o
 VFS_READAHEAD_OBJ = modules/vfs_readahead.o
 VFS_TSMSM_OBJ = modules/vfs_tsmsm.o
@@ -2613,6 +2614,10 @@ bin/gpfs. at SHLIBEXT@: $(BINARY_PREREQS) $(VFS_GPFS_OBJ)
 	@echo "Building plugin $@"
 	@$(SHLD_MODULE) $(VFS_GPFS_OBJ)
 
+bin/gpfs_prefetch. at SHLIBEXT@: $(BINARY_PREREQS) $(VFS_GPFS_PREFETCH_OBJ)
+	@echo "Building plugin $@"
+	@$(SHLD_MODULE) $(VFS_GPFS_PREFETCH_OBJ)
+
 bin/notify_fam. at SHLIBEXT@: $(BINARY_PREREQS) $(VFS_NOTIFY_FAM_OBJ)
 	@echo "Building plugin $@"
 	@$(SHLD_MODULE) $(VFS_NOTIFY_FAM_OBJ) @SMB_FAM_LIBS@
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 4a8fc95..8cc559e 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -703,6 +703,8 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info)
 	NTSTATUS status;
 	size_t i;
 	struct dom_sid tmp_sid;
+	struct dom_sid *filter_sids;
+	size_t num_filter_sids;
 
 	/*
 	 * If winbind is not around, we can not make much use of the SIDs the
@@ -739,11 +741,37 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info)
 	server_info->utok.ngroups = 0;
 	server_info->utok.groups = NULL;
 
+	if (!secrets_groupfilter_fetch(talloc_tos(), &filter_sids,
+				       &num_filter_sids)) {
+		num_filter_sids = 0;
+	}
+
 	/* Start at index 1, where the groups start. */
 
 	for (i=1; i<server_info->ptok->num_sids; i++) {
 		gid_t gid;
 		DOM_SID *sid = &server_info->ptok->user_sids[i];
+		size_t sidindex;
+
+		/*
+		 * For secondary groups, potentially apply a group
+		 * filter for hosts with a silly groups-per-user limit
+		 * such as for example Solaris
+		 */
+
+		if ((i > 1) && (num_filter_sids != 0)) {
+			/*
+			 * We have a SID filter in secrets.tdb, only
+			 * convert the SIDs in that filter to GIDs.
+			 */
+			if (bsearch(sid, filter_sids, num_filter_sids,
+				    sizeof(struct dom_sid),
+				    sid_compare_sort) == NULL) {
+				DEBUG(10, ("Filtering out SID %s\n",
+					   sid_string_dbg(sid)));
+				continue;
+			}
+		}
 
 		if (!sid_to_gid(sid, &gid)) {
 			DEBUG(10, ("Could not convert SID %s to gid, "
@@ -755,6 +783,8 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info)
 					&server_info->utok.ngroups);
 	}
 
+	TALLOC_FREE(filter_sids);
+
 	/*
 	 * Add the "Unix Group" SID for each gid to catch mapped groups
 	 * and their Unix equivalent.  This is to solve the backwards
diff --git a/source3/configure.in b/source3/configure.in
index 408340d..0465646 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -1084,7 +1084,7 @@ AC_TRY_LINK([#include <gpfs_gpl.h>],
 echo $samba_cv_HAVE_GPFS
 if test x"$samba_cv_HAVE_GPFS" = x"yes"; then
     AC_DEFINE(HAVE_GPFS,1,[Whether GPFS GPL libs are available])
-    default_shared_modules="$default_shared_modules vfs_gpfs"
+    default_shared_modules="$default_shared_modules vfs_gpfs vfs_gpfs_prefetch"
 fi
 LIBS="$save_LIBS"
 
@@ -6264,6 +6264,7 @@ SMB_MODULE(vfs_cacheprime, \$(VFS_CACHEPRIME_OBJ), "bin/cacheprime.$SHLIBEXT", V
 SMB_MODULE(vfs_prealloc, \$(VFS_PREALLOC_OBJ), "bin/prealloc.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_commit, \$(VFS_COMMIT_OBJ), "bin/commit.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_gpfs, \$(VFS_GPFS_OBJ), "bin/gpfs.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_gpfs_prefetch, \$(VFS_GPFS_PREFETCH_OBJ), "bin/gpfs_prefetch.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_readahead, \$(VFS_READAHEAD_OBJ), "bin/readahead.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_tsmsm, \$(VFS_TSMSM_OBJ), "bin/tsmsm.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_fileid, \$(VFS_FILEID_OBJ), "bin/fileid.$SHLIBEXT", VFS)
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 18555bc..e807c42 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1310,6 +1310,7 @@ bool sid_linearize(char *outbuf, size_t len, const DOM_SID *sid);
 bool sid_parse(const char *inbuf, size_t len, DOM_SID *sid);
 int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2);
 int sid_compare_domain(const DOM_SID *sid1, const DOM_SID *sid2);
+int sid_compare_sort(const void *p1, const void *p2);
 bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2);
 bool non_mappable_sid(DOM_SID *sid);
 char *sid_binstring(const DOM_SID *sid);
@@ -4710,6 +4711,8 @@ bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
 				struct dcinfo **ppdc);
 bool secrets_store_generic(const char *owner, const char *key, const char *secret);
 char *secrets_fetch_generic(const char *owner, const char *key);
+bool secrets_groupfilter_fetch(TALLOC_CTX *mem_ctx, struct dom_sid **psids,
+			       size_t *pnum_sids);
 bool secrets_store_local_schannel_key(uint8_t schannel_key[16]);
 bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16]);
 
diff --git a/source3/include/secrets.h b/source3/include/secrets.h
index 3c8e2cc..42590b2 100644
--- a/source3/include/secrets.h
+++ b/source3/include/secrets.h
@@ -53,6 +53,8 @@
 #define SECRETS_AUTH_DOMAIN      "SECRETS/AUTH_DOMAIN"
 #define SECRETS_AUTH_PASSWORD  "SECRETS/AUTH_PASSWORD"
 
+#define SECRETS_GROUPFILTER_KEY "SECRETS/GROUPFILTER"
+
 /* structure for storing machine account password
    (ie. when samba server is member of a domain */
 struct machine_acct_pass {
diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c
index 97284af..163c6c2 100644
--- a/source3/lib/util_sid.c
+++ b/source3/lib/util_sid.c
@@ -467,6 +467,35 @@ int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
 	return sid_compare_auth(sid1, sid2);
 }
 
+int sid_compare_sort(const void *p1, const void *p2)
+{
+	const struct dom_sid *sid1 = (const struct dom_sid *)p1;
+	const struct dom_sid *sid2 = (const struct dom_sid *)p2;
+	int i, res;
+
+	if (sid1->sid_rev_num != sid2->sid_rev_num) {
+		return sid1->sid_rev_num - sid2->sid_rev_num;
+	}
+
+	for (i = 0; i < 6; i++) {
+		if (sid1->id_auth[i] != sid2->id_auth[i]) {
+			return sid1->id_auth[i] - sid2->id_auth[i];
+		}
+	}
+
+	if (sid1->num_auths != sid2->num_auths) {
+		return sid1->num_auths - sid2->num_auths;
+	}
+
+	for (i = 0; i<sid1->num_auths; i++) {


-- 
SAMBA-CTDB repository


More information about the samba-cvs mailing list