[PATCH] multiple passdb backends

Jelmer Vernooij jelmer at nl.linux.org
Tue Mar 5 14:34:04 GMT 2002


Hi! 

This patch gives samba the ability to support multiple passdb
backends. Backends should be listed in the 'passdb backend' variable
in [global], like this:

passdb backend = plugin:/path/to/pdb_mysql.so:mysql_location ldap:ldap://user@somehost.somedomain/

Modules are separated by spaces, module and 'location' are separated
by a colon (:). This syntax is backwards compatible.

Currently, the max number of passdb modules should be about 32000,
which is probably enough ;-)

New accounts are *always* added to the first database that is listed.

Feedback, please ! :)

Jelmer

-- 
Jelmer Vernooij <jelmer at nl.linux.org> - http://nl.linux.org/~jelmer/
Development And Underdevelopment: http://library.thinkquest.org/C0110231/
 22:14:35 up 1 day,  6:09,  9 users,  load average: 1.12, 1.38, 1.31
-------------- next part --------------
Index: examples/pdb/README
===================================================================
RCS file: /cvsroot/samba/examples/pdb/README,v
retrieving revision 1.1
diff -u -3 -p -u -r1.1 README
--- examples/pdb/README	22 Feb 2002 02:57:49 -0000	1.1
+++ examples/pdb/README	5 Mar 2002 21:19:44 -0000
@@ -7,3 +7,5 @@ a pdb plugin. It just prints the name of
 DEBUG. Maybe it's nice to include some of the arguments to the function in the 
 future too..
 
+To debug passdb backends, try to run gdb on the 'pdbedit' executable. That's really much easier than restarting smbd constantly and attaching with your debugger.
+
Index: source/include/smb.h
===================================================================
RCS file: /cvsroot/samba/source/include/smb.h,v
retrieving revision 1.415
diff -u -3 -p -u -r1.415 smb.h
--- source/include/smb.h	2 Mar 2002 10:16:28 -0000	1.415
+++ source/include/smb.h	5 Mar 2002 21:19:47 -0000
@@ -596,6 +596,7 @@ typedef struct sam_passwd
 	TALLOC_CTX *mem_ctx;
 	
 	void (*free_fn)(struct sam_passwd **);
+    struct pdb_context *passdb;
 
 	struct user_data {
 		/* initiailization flags */
Index: source/passdb/pdb_interface.c
===================================================================
RCS file: /cvsroot/samba/source/passdb/pdb_interface.c,v
retrieving revision 1.6
diff -u -3 -p -u -r1.6 pdb_interface.c
--- source/passdb/pdb_interface.c	2 Mar 2002 10:16:27 -0000	1.6
+++ source/passdb/pdb_interface.c	5 Mar 2002 21:19:48 -0000
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    Password and authentication handling
    Copyright (C) Andrew Bartlett		    2002
+   Copyright (C) Jelmer Vernooij            2002
       
    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
@@ -37,6 +38,10 @@ const struct pdb_init_function_entry bui
 	{ NULL, NULL}
 };
 
+struct pdb_context **passdb_contexts = NULL;
+size_t passdb_curpwent = 0;
+size_t passdb_count = 0;
+
 static BOOL context_setsampwent(struct pdb_context *context, BOOL update)
 {
 	if ((!context) || (!context->pdb_selected)) {
@@ -227,32 +232,6 @@ NTSTATUS make_pdb_context_name(struct pd
 	return NT_STATUS_OK;
 }
 
-
-/******************************************************************
- Return an already initilised pdb_context, to facilitate backward 
- compatiablity (see functions below).
-*******************************************************************/
-
-static struct pdb_context *pdb_get_static_context(BOOL reload) 
-{
-	static struct pdb_context *pdb_context = NULL;
-	
-	if ((pdb_context) && (reload)) {
-		pdb_context->free_fn(&pdb_context);
-		if (!NT_STATUS_IS_OK(make_pdb_context_name(&pdb_context, lp_passdb_backend()))) {
-			return NULL;
-		}
-	}
-	
-	if (!pdb_context) {
-		if (!NT_STATUS_IS_OK(make_pdb_context_name(&pdb_context, lp_passdb_backend()))) {
-			return NULL;
-		}
-	}
-	
-	return pdb_context;
-}
-
 #if !defined(WITH_NISPLUS_SAM)
 
 /******************************************************************
@@ -261,90 +240,91 @@ static struct pdb_context *pdb_get_stati
 
 BOOL pdb_setsampwent(BOOL update) 
 {
-	struct pdb_context *pdb_context = pdb_get_static_context(False);
+	passdb_curpwent = 0;
 
-	if (!pdb_context) {
+	if (passdb_curpwent >= passdb_count) {
 		return False;
 	}
 
-	return pdb_context->pdb_setsampwent(pdb_context, update);
+	DEBUG(5, ("passdb_curpwent set!\n"));
+	return passdb_contexts[passdb_curpwent]->pdb_setsampwent(passdb_contexts[passdb_curpwent], update);
 }
 
 void pdb_endsampwent(void) 
 {
-	struct pdb_context *pdb_context = pdb_get_static_context(False);
-
-	if (!pdb_context) {
+	if (passdb_curpwent >= passdb_count) {
 		return;
 	}
 
-	pdb_context->pdb_endsampwent(pdb_context);
+	DEBUG(5, ("passdb_curpwent set to 0 again!\n"));
+	passdb_contexts[passdb_curpwent]->pdb_endsampwent(passdb_contexts[passdb_curpwent]);
+	passdb_curpwent = 0;
 }
 
 BOOL pdb_getsampwent(SAM_ACCOUNT *user) 
 {
-	struct pdb_context *pdb_context = pdb_get_static_context(False);
-
-	if (!pdb_context) {
+	if (passdb_curpwent >= passdb_count) {
 		return False;
 	}
-
-	return pdb_context->pdb_getsampwent(pdb_context, user);
+	/* Just continue until we've found sthng */
+	while(passdb_contexts[passdb_curpwent]->pdb_getsampwent(passdb_contexts[passdb_curpwent], user) == False){
+		passdb_contexts[passdb_curpwent]->pdb_endsampwent(passdb_contexts[passdb_curpwent]);
+		passdb_curpwent++;
+		if(passdb_curpwent >= passdb_count)return False;
+		passdb_contexts[passdb_curpwent]->pdb_setsampwent(passdb_contexts[passdb_curpwent], False);
+	}
+	user->passdb = passdb_contexts[passdb_curpwent];
+	return True;
 }
 
 BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username) 
 {
-	struct pdb_context *pdb_context = pdb_get_static_context(False);
-
-	if (!pdb_context) {
-		return False;
+	size_t i;
+	for(i = 0; i < passdb_count; i++){
+		if(passdb_contexts[i]->pdb_getsampwnam(passdb_contexts[i], sam_acct, username) == True){
+			sam_acct->passdb = passdb_contexts[i];
+			return True;
+		}
 	}
-
-	return pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username);
+	return False;
 }
 
 BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct, uint32 rid) 
 {
-	struct pdb_context *pdb_context = pdb_get_static_context(False);
-
-	if (!pdb_context) {
-		return False;
+	size_t i;
+	for(i = 0; i < passdb_count; i++){
+		if(passdb_contexts[i]->pdb_getsampwrid(passdb_contexts[i], sam_acct, rid) == True){
+			sam_acct->passdb = passdb_contexts[i];
+			return True;
+		}
 	}
-
-	return pdb_context->pdb_getsampwrid(pdb_context, sam_acct, rid);
+	return False;
 }
 
 BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct) 
 {
-	struct pdb_context *pdb_context = pdb_get_static_context(False);
-
-	if (!pdb_context) {
+	if (!passdb_contexts[0]) {
 		return False;
 	}
 
-	return pdb_context->pdb_add_sam_account(pdb_context, sam_acct);
+	return passdb_contexts[0]->pdb_add_sam_account(passdb_contexts[0], sam_acct);
 }
 
 BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct) 
 {
-	struct pdb_context *pdb_context = pdb_get_static_context(False);
-
-	if (!pdb_context) {
+	if(!sam_acct->passdb){
 		return False;
 	}
-
-	return pdb_context->pdb_update_sam_account(pdb_context, sam_acct);
+	return sam_acct->passdb->pdb_update_sam_account(sam_acct->passdb, sam_acct);
 }
 
 BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct) 
 {
-	struct pdb_context *pdb_context = pdb_get_static_context(False);
-	
-	if (!pdb_context) {
+	if(!sam_acct->passdb){
 		return False;
 	}
 	
-	return pdb_context->pdb_delete_sam_account(pdb_context, sam_acct);
+	return sam_acct->passdb->pdb_delete_sam_account(sam_acct->passdb, sam_acct);
 }
 
 #endif /* !defined(WITH_NISPLUS_SAM) */
@@ -357,7 +337,26 @@ BOOL pdb_delete_sam_account(SAM_ACCOUNT 
 
 BOOL initialize_password_db(BOOL reload)
 {	
-	return (pdb_get_static_context(reload) != NULL);
+	char *conf = smb_xstrdup(lp_passdb_backend());
+	char *confcur = conf, *confnext;
+	while(confcur){
+		if(strchr(confcur, ' ')){
+			confnext = strchr(confcur,' ');
+			*confnext = '\0';
+			confnext++;
+		}else confnext = NULL;
+		/* Try to initialise pdb */
+		DEBUG(5,("Trying to load: %s\n", confcur));	
+		passdb_contexts = realloc(passdb_contexts, sizeof(struct pdb_context *) * (passdb_count+1));
+		if (!NT_STATUS_IS_OK(make_pdb_context_name(&passdb_contexts[passdb_count], confcur))){
+			DEBUG(5, ("Loading %s failed!\n", confcur));
+		}else passdb_count++;
+		if(!confnext)break;
+		confcur = confnext;
+	}
+	SAFE_FREE(conf);
+	DEBUG(5,("%d passdb modules loaded\n", passdb_count));
+	return (passdb_count == 0?False:True);
 }
 
 
@@ -373,11 +372,3 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *me
 
 	return NT_STATUS_OK;
 }
-
-
-
-
-
-
-
-


More information about the samba-technical mailing list