[PATCH] Merge LDAP into pluggable Passdb.

Andrew Bartlett abartlet at pcug.org.au
Sat Jan 26 22:10:03 GMT 2002


This patch merges LDAP into the plugable passdb mechanism.

I'm not currently proposing this patch for inclusion, because Jerry
wants some sanity between Samba 2.2 and HEAD.

This patch also introduces the 'ldap uri' concept that Samba-TNG were
toying with recently - and removes the ldap server and ldap port
smb.conf parameters.  Instead, servers are listed in a URI format after
the colon in the 'passdb backend' parameter.

EG:

ldapsam:ldap://localhost

or 

ldapsam:ldaps://localhost.

The ldaps stuff doesn't seem to work for now - I'll need to chase this
up.  But basic functionality is intact, and it is now run-time
selectable.  Posted for *comment*, I don't expect it to be particularly
useful to anyone...

I suspect I'm going to get very familiar with LDAP very quickly...

Andrew Bartlett
-- 
Andrew Bartlett                                 abartlet at pcug.org.au
Manager, Authentication Subsystems, Samba Team  abartlet at samba.org
Student Network Administrator, Hawker College   abartlet at hawkerc.net
http://samba.org     http://build.samba.org     http://hawkerc.net
-------------- next part --------------
? cvs
? docs/docbook/confdefs.h
? source/config.abartlet
? source/bin/wrepld
? source/include/wrepld_proto.h
? source/nsswitch/.libs
Index: source/param/loadparm.c
===================================================================
RCS file: /data/cvs/samba/source/param/loadparm.c,v
retrieving revision 1.379
diff -u -r1.379 loadparm.c
--- source/param/loadparm.c	25 Jan 2002 22:53:49 -0000	1.379
+++ source/param/loadparm.c	27 Jan 2002 05:53:48 -0000
@@ -1318,11 +1318,9 @@
 	Globals.bHostnameLookups = False;
 
 #ifdef WITH_LDAP_SAM
-	string_set(&Globals.szLdapServer, "localhost");
 	string_set(&Globals.szLdapSuffix, "");
 	string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))");
 	string_set(&Globals.szLdapAdminDn, "");
-	Globals.ldap_port = 636;
 	Globals.ldap_ssl = LDAP_SSL_ON;
 #endif /* WITH_LDAP_SAM */
 
@@ -1530,11 +1528,9 @@
 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
 #ifdef WITH_LDAP_SAM
-FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
 FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
-FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
 #endif /* WITH_LDAP_SAM */
 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
Index: source/passdb/pdb_interface.c
===================================================================
RCS file: /data/cvs/samba/source/passdb/pdb_interface.c,v
retrieving revision 1.3
diff -u -r1.3 pdb_interface.c
--- source/passdb/pdb_interface.c	26 Jan 2002 06:18:59 -0000	1.3
+++ source/passdb/pdb_interface.c	27 Jan 2002 05:53:48 -0000
@@ -28,8 +28,8 @@
 	{ "smbpasswd_nua", pdb_init_smbpasswd_nua },
 	{ "tdbsam", pdb_init_tdbsam },
 	{ "tdbsam_nua", pdb_init_tdbsam_nua },
+	{ "ldapsam", pdb_init_ldapsam },
 #if 0
-	{ "ldap", pdb_init_ldap },
 	{ "nisplus", pdb_init_nisplus },	
 	{ "unix", pdb_init_unix },
 #endif
@@ -252,7 +252,7 @@
 	return pdb_context;
 }
 
-#if !defined(WITH_LDAP_SAM) && !defined(WITH_NISPLUS_SAM)
+#if !defined(WITH_NISPLUS_SAM)
 
 /******************************************************************
  Backward compatability functions for the original passdb interface
@@ -346,7 +346,7 @@
 	return pdb_context->pdb_delete_sam_account(pdb_context, sam_acct);
 }
 
-#endif /* !defined(WITH_LDAP_SAM) && !defined(WITH_NISPLUS_SAM) */
+#endif /* !defined(WITH_NISPLUS_SAM) */
 
 /***************************************************************
  Initialize the static context (at smbd startup etc). 
Index: source/passdb/pdb_ldap.c
===================================================================
RCS file: /data/cvs/samba/source/passdb/pdb_ldap.c,v
retrieving revision 1.20
diff -u -r1.20 pdb_ldap.c
--- source/passdb/pdb_ldap.c	23 Jan 2002 12:59:24 -0000	1.20
+++ source/passdb/pdb_ldap.c	27 Jan 2002 05:53:52 -0000
@@ -52,86 +52,149 @@
 #define SAM_ACCOUNT struct sam_passwd
 #endif
 
-struct ldap_enum_info {
+struct ldapsam_privates {
+
+	/* Former statics */
 	LDAP *ldap_struct;
 	LDAPMessage *result;
 	LDAPMessage *entry;
+	
+	/* retrive-once info */
+	const char *uri;
+	
+	BOOL permit_non_unix_accounts;
+	
+	uint32 low_nua_rid; 
+	uint32 high_nua_rid; 
+	
 };
 
-static struct ldap_enum_info global_ldap_ent;
+/*******************************************************************
+ find the ldap password
+******************************************************************/
+static BOOL fetch_ldapsam_pw(char *dn, char* pw, int len)
+{
+	fstring key;
+	char *p;
+	void *data = NULL;
+	size_t size;
+	
+	pstrcpy(key, dn);
+	for (p=key; *p; p++)
+		if (*p == ',') *p = '/';
+	
+	data=secrets_fetch(key, &size);
+	if (!size) {
+		DEBUG(0,("fetch_ldap_pw: no ldap secret retrieved!\n"));
+		return False;
+	}
+	
+	if (size > len-1)
+	{
+		DEBUG(0,("fetch_ldap_pw: ldap secret is too long (%d > %d)!\n", size, len-1));
+		return False;
+	}
 
+	memcpy(pw, data, size);
+	pw[size] = '\0';
+	
+	return True;
+}
 
 
 /*******************************************************************
  open a connection to the ldap server.
 ******************************************************************/
-static BOOL ldap_open_connection (LDAP ** ldap_struct)
+static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct)
 {
-	int port;
-	int version, rc;
-	int tls = LDAP_OPT_X_TLS_HARD;
-
-	/* there should be an lp_ldap_ssl_port(), what happen if for some
-	   reason we need to bind an SSLed LDAP on port 389 ?? ---simo */
-	if (lp_ldap_ssl() == LDAP_SSL_ON && lp_ldap_port() == 389) {
-		port = 636;
-	}
-	else {
-		port = lp_ldap_port();
-	}
 
-	if ((*ldap_struct = ldap_init(lp_ldap_server(), port)) == NULL)	{
-		DEBUG(0, ("The LDAP server is not responding !\n"));
-		return False;
-	}
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+	DEBUG(0, ("ldapsam_open_connection: %s\n", ldap_state->uri));
+	
+	if (ldap_initialize(ldap_struct, ldap_state->uri) != LDAP_SUCCESS) {
+		DEBUG(0, ("ldap_initialize: %s\n", strerror(errno)));
+		return (False);
+	}
+#else 
+
+	/* Parse the string manually */
+
+	{
+		int rc;
+		int tls = LDAP_OPT_X_TLS_HARD;
+		int port = 0;
+		int version;
+		fstring protocol;
+		fstring host;
+		const char *p = ldap_state->uri; 
+		SMB_ASSERT(sizeof(protocol)>5 && sizeof(host)>254);
+		
+		/* skip leading "URL:" (if any) */
+		if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
+			p += 4;
+		}
 
-	/* Connect to older servers using SSL and V2 rather than Start TLS */
-	if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
-	{
-		if (version != LDAP_VERSION2)
-		{
-			version = LDAP_VERSION2;
-			ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
+		sscanf(p, "%5s://%254s:%d", protocol, host, &port);
+		
+		if (port == 0) {
+			if (strequal(protocol, "ldap")) {
+				port = LDAP_PORT;
+			} else if (strequal(protocol, "ldaps")) {
+				port = LDAPS_PORT;
+			} else {
+				DEBUG(0, ("unrecognised protocol!\n"));
+			}
 		}
-	}
 
-	switch (lp_ldap_ssl())
-	{
-		case LDAP_SSL_START_TLS:
-			if (ldap_get_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, 
-				&version) == LDAP_OPT_SUCCESS)
+		if ((*ldap_struct = ldap_init(host, port)) == NULL)	{
+			DEBUG(0, ("ldap_init failed !\n"));
+			return False;
+		}
+
+		/* Connect to older servers using SSL and V2 rather than Start TLS */
+		if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
+		{
+			if (version != LDAP_VERSION2)
 			{
-				if (version < LDAP_VERSION3)
+				version = LDAP_VERSION2;
+				ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
+			}
+		}
+
+		if strequal(protocol, "ldaps") { 
+			if (lp_ldap_ssl = LDAP_SSL_START_TLS) {
+				if (ldap_get_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, 
+						     &version) == LDAP_OPT_SUCCESS)
 				{
-					version = LDAP_VERSION3;
-					ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION,
-							&version);
+					if (version < LDAP_VERSION3)
+					{
+						version = LDAP_VERSION3;
+						ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION,
+								 &version);
+					}
+				}
+				if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
+				{
+					DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
+						 ldap_err2string(rc)));
+					return False;
+				}
+				DEBUG (2, ("StartTLS issued: using a TLS connection\n"));
+			} else {
+				
+				if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
+				{
+					DEBUG(0, ("Failed to setup a TLS session\n"));
 				}
 			}
-			if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
-			{
-				DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
-				       ldap_err2string(rc)));
-				return False;
-			}
-			DEBUG (2, ("StartTLS issued: using a TLS connection\n"));
-			break;
-			
-		case LDAP_SSL_ON:
-			if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
-			{
-				DEBUG(0, ("Failed to setup a TLS session\n"));
-			}
-			break;
-			
-		case LDAP_SSL_OFF:
-		default:
+		} else {
 			/* 
 			 * No special needs to setup options prior to the LDAP
 			 * bind (which should be called next via ldap_connect_system()
 			 */
-			break;
+		}
 	}
+#endif
 
 	DEBUG(2, ("ldap_open_connection: connection opened\n"));
 	return True;
@@ -140,14 +203,14 @@
 /*******************************************************************
  connect to the ldap server under system privilege.
 ******************************************************************/
-static BOOL ldap_connect_system(LDAP * ldap_struct)
+static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct)
 {
 	int rc;
 	static BOOL got_pw = False;
 	static pstring ldap_secret;
 
 	/* get the password if we don't have it already */
-	if (!got_pw && !(got_pw=fetch_ldap_pw(lp_ldap_admin_dn(), ldap_secret, sizeof(pstring)))) 
+	if (!got_pw && !(got_pw=fetch_ldapsam_pw(lp_ldap_admin_dn(), ldap_secret, sizeof(pstring)))) 
 	{
 		DEBUG(0, ("ldap_connect_system: Failed to retrieve password for %s from secrets.tdb\n",
 			lp_ldap_admin_dn()));
@@ -174,19 +237,19 @@
 /*******************************************************************
  run the search by name.
 ******************************************************************/
-static int ldap_search_one_user (LDAP * ldap_struct, const char *filter, LDAPMessage ** result)
+static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, LDAP * ldap_struct, const char *filter, LDAPMessage ** result)
 {
 	int scope = LDAP_SCOPE_SUBTREE;
 	int rc;
 
-	DEBUG(2, ("ldap_search_one_user: searching for:[%s]\n", filter));
+	DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter));
 
 	rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, NULL, 0, result);
 
 	if (rc != LDAP_SUCCESS)	{
-		DEBUG(0,("ldap_search_one_user: Problem during the LDAP search: %s\n", 
+		DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n", 
 			ldap_err2string (rc)));
-		DEBUG(3,("ldap_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(), 
+		DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(), 
 			filter));
 	}
 	
@@ -196,7 +259,7 @@
 /*******************************************************************
  run the search by name.
 ******************************************************************/
-static int ldap_search_one_user_by_name (LDAP * ldap_struct, const char *user,
+static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, LDAP * ldap_struct, const char *user,
 			     LDAPMessage ** result)
 {
 	pstring filter;
@@ -213,14 +276,15 @@
 	 */
 	all_string_sub(filter, "%u", user, sizeof(pstring));
 
-	return ldap_search_one_user(ldap_struct, filter, result);
+	return ldapsam_search_one_user(ldap_state, ldap_struct, filter, result);
 }
 
 /*******************************************************************
  run the search by uid.
 ******************************************************************/
-static int ldap_search_one_user_by_uid(LDAP * ldap_struct, int uid,
-			    LDAPMessage ** result)
+static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state, 
+					  LDAP * ldap_struct, int uid,
+					  LDAPMessage ** result)
 {
 	struct passwd *user;
 	pstring filter;
@@ -228,7 +292,7 @@
 	/* Get the username from the system and look that up in the LDAP */
 	
 	if ((user = sys_getpwuid(uid)) == NULL) {
-		DEBUG(3,("ldap_search_one_user_by_uid: Failed to locate uid [%d]\n", uid));
+		DEBUG(3,("ldapsam_search_one_user_by_uid: Failed to locate uid [%d]\n", uid));
 		return LDAP_NO_SUCH_OBJECT;
 	}
 	
@@ -236,14 +300,15 @@
 	
 	all_string_sub(filter, "%u", user->pw_name, sizeof(pstring));
 
-	return ldap_search_one_user(ldap_struct, filter, result);
+	return ldapsam_search_one_user(ldap_state, ldap_struct, filter, result);
 }
 
 /*******************************************************************
  run the search by rid.
 ******************************************************************/
-static int ldap_search_one_user_by_rid (LDAP * ldap_struct, uint32 rid,
-			    LDAPMessage ** result)
+static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state, 
+					   LDAP * ldap_struct, uint32 rid,
+					   LDAPMessage ** result)
 {
 	pstring filter;
 	int rc;
@@ -251,11 +316,12 @@
 	/* check if the user rid exsists, if not, try searching on the uid */
 	
 	snprintf(filter, sizeof(filter) - 1, "rid=%i", rid);
-	rc = ldap_search_one_user(ldap_struct, filter, result);
+	rc = ldapsam_search_one_user(ldap_state, ldap_struct, filter, result);
 	
 	if (rc != LDAP_SUCCESS)
-		rc = ldap_search_one_user_by_uid(ldap_struct, 
-			pdb_user_rid_to_uid(rid), result);
+		rc = ldapsam_search_one_user_by_uid(ldap_state, ldap_struct, 
+						    pdb_user_rid_to_uid(rid), 
+						    result);
 
 	return rc;
 }
@@ -264,7 +330,7 @@
 search an attribute and return the first value found.
 ******************************************************************/
 static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
-		     char *attribute, char *value)
+				  char *attribute, char *value)
 {
 	char **values;
 
@@ -274,11 +340,11 @@
 		
 		return False;
 	}
-
+	
 	pstrcpy(value, values[0]);
 	ldap_value_free(values);
 	DEBUG (2, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
-		
+	
 	return True;
 }
 
@@ -362,8 +428,9 @@
 Initialize SAM_ACCOUNT from an LDAP query
 (Based on init_sam_from_buffer in pdb_tdb.c)
 *********************************************************************/
-static BOOL init_sam_from_ldap (SAM_ACCOUNT * sampass,
-		   LDAP * ldap_struct, LDAPMessage * entry)
+static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, 
+				SAM_ACCOUNT * sampass,
+				LDAP * ldap_struct, LDAPMessage * entry)
 {
 	time_t  logon_time,
 			logoff_time,
@@ -574,7 +641,9 @@
 Initialize SAM_ACCOUNT from an LDAP query
 (Based on init_buffer_from_sam in pdb_tdb.c)
 *********************************************************************/
-static BOOL init_ldap_from_sam (LDAPMod *** mods, int ldap_state, const SAM_ACCOUNT * sampass)
+static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, 
+				LDAPMod *** mods, int ldap_op, 
+				const SAM_ACCOUNT * sampass)
 {
 	pstring temp;
 
@@ -591,26 +660,26 @@
 	 */
 
 
-	make_a_mod(mods, ldap_state, "uid", pdb_get_username(sampass));
+	make_a_mod(mods, ldap_op, "uid", pdb_get_username(sampass));
 	DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
 
 	slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
-	make_a_mod(mods, ldap_state, "pwdLastSet", temp);
+	make_a_mod(mods, ldap_op, "pwdLastSet", temp);
 
 	slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
-	make_a_mod(mods, ldap_state, "logonTime", temp);
+	make_a_mod(mods, ldap_op, "logonTime", temp);
 
 	slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
-	make_a_mod(mods, ldap_state, "logoffTime", temp);
+	make_a_mod(mods, ldap_op, "logoffTime", temp);
 
 	slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
-	make_a_mod(mods, ldap_state, "kickoffTime", temp);
+	make_a_mod(mods, ldap_op, "kickoffTime", temp);
 
 	slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
-	make_a_mod(mods, ldap_state, "pwdCanChange", temp);
+	make_a_mod(mods, ldap_op, "pwdCanChange", temp);
 
 	slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
-	make_a_mod(mods, ldap_state, "pwdMustChange", temp);
+	make_a_mod(mods, ldap_op, "pwdMustChange", temp);
 
 	/* displayName, cn, and gecos should all be the same
 	   *  most easily accomplished by giving them the same OID
@@ -618,48 +687,48 @@
 	   *  add-user script
 	 */
 
-	make_a_mod(mods, ldap_state, "displayName", pdb_get_fullname(sampass));
-	make_a_mod(mods, ldap_state, "cn", pdb_get_fullname(sampass));
-	make_a_mod(mods, ldap_state, "description", pdb_get_acct_desc(sampass));
-	make_a_mod(mods, ldap_state, "userWorkstations", pdb_get_workstations(sampass));
+	make_a_mod(mods, ldap_op, "displayName", pdb_get_fullname(sampass));
+	make_a_mod(mods, ldap_op, "cn", pdb_get_fullname(sampass));
+	make_a_mod(mods, ldap_op, "description", pdb_get_acct_desc(sampass));
+	make_a_mod(mods, ldap_op, "userWorkstations", pdb_get_workstations(sampass));
 
 	/*
 	 * Only updates fields which have been set (not defaults from smb.conf)
 	 */
 
 	if (IS_SAM_SET(sampass, FLAG_SAM_SMBHOME))
-	make_a_mod(mods, ldap_state, "smbHome", pdb_get_homedir(sampass));
+	make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass));
 		
 	if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE))
-	make_a_mod(mods, ldap_state, "homeDrive", pdb_get_dirdrive(sampass));
+	make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dirdrive(sampass));
 		
 	if (IS_SAM_SET(sampass, FLAG_SAM_LOGONSCRIPT))
-	make_a_mod(mods, ldap_state, "scriptPath", pdb_get_logon_script(sampass));
+	make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass));
 
 	if (IS_SAM_SET(sampass, FLAG_SAM_PROFILE))
-	make_a_mod(mods, ldap_state, "profilePath", pdb_get_profile_path(sampass));
+	make_a_mod(mods, ldap_op, "profilePath", pdb_get_profile_path(sampass));
 
 
 	if ( !pdb_get_user_rid(sampass))
 		slprintf(temp, sizeof(temp) - 1, "%i", pdb_uid_to_user_rid(pdb_get_uid(sampass)));
 	else
 		slprintf(temp, sizeof(temp) - 1, "%i", pdb_get_user_rid(sampass));
-	make_a_mod(mods, ldap_state, "rid", temp);
+	make_a_mod(mods, ldap_op, "rid", temp);
 
 	if ( !pdb_get_group_rid(sampass))
 		slprintf(temp, sizeof(temp) - 1, "%i", pdb_gid_to_group_rid(pdb_get_gid(sampass)));
 	else
 		slprintf(temp, sizeof(temp) - 1, "%i", pdb_get_group_rid(sampass));
-	make_a_mod(mods, ldap_state, "primaryGroupID", temp);
+	make_a_mod(mods, ldap_op, "primaryGroupID", temp);
 
 	/* FIXME: Hours stuff goes in LDAP  */
 	pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass));
-	make_a_mod (mods, ldap_state, "lmPassword", temp);
+	make_a_mod (mods, ldap_op, "lmPassword", temp);
 	
 	pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass));
-	make_a_mod (mods, ldap_state, "ntPassword", temp);
+	make_a_mod (mods, ldap_op, "ntPassword", temp);
 	
-	make_a_mod (mods, ldap_state, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
+	make_a_mod (mods, ldap_op, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
 		NEW_PW_FORMAT_SPACE_PADDED_LEN));
 
 	return True;
@@ -668,45 +737,46 @@
 /**********************************************************************
 Connect to LDAP server for password enumeration
 *********************************************************************/
-BOOL pdb_setsampwent(BOOL update)
+BOOL ldapsam_setsampwent(struct pdb_context *context, BOOL update)
 {
+	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
 	int rc;
 	pstring filter;
 
-	if (!ldap_open_connection(&global_ldap_ent.ldap_struct))
+	if (!ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct))
 	{
 		return False;
 	}
-	if (!ldap_connect_system(global_ldap_ent.ldap_struct))
+	if (!ldapsam_connect_system(ldap_state, ldap_state->ldap_struct))
 	{
-		ldap_unbind(global_ldap_ent.ldap_struct);
+		ldap_unbind(ldap_state->ldap_struct);
 		return False;
 	}
 
 	pstrcpy(filter, lp_ldap_filter());
 	all_string_sub(filter, "%u", "*", sizeof(pstring));
 
-	rc = ldap_search_s(global_ldap_ent.ldap_struct, lp_ldap_suffix(),
+	rc = ldap_search_s(ldap_state->ldap_struct, lp_ldap_suffix(),
 			   LDAP_SCOPE_SUBTREE, filter, NULL, 0,
-			   &global_ldap_ent.result);
+			   &ldap_state->result);
 
 	if (rc != LDAP_SUCCESS)
 	{
 		DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
 		DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
-		ldap_msgfree(global_ldap_ent.result);
-		ldap_unbind(global_ldap_ent.ldap_struct);
-		global_ldap_ent.ldap_struct = NULL;
-		global_ldap_ent.result = NULL;
+		ldap_msgfree(ldap_state->result);
+		ldap_unbind(ldap_state->ldap_struct);
+		ldap_state->ldap_struct = NULL;
+		ldap_state->result = NULL;
 		return False;
 	}
 
-	DEBUG(2, ("pdb_setsampwent: %d entries in the base!\n",
-		ldap_count_entries(global_ldap_ent.ldap_struct,
-		global_ldap_ent.result)));
+	DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
+		ldap_count_entries(ldap_state->ldap_struct,
+		ldap_state->result)));
 
-	global_ldap_ent.entry = ldap_first_entry(global_ldap_ent.ldap_struct,
-				 global_ldap_ent.result);
+	ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
+				 ldap_state->result);
 
 	return True;
 }
@@ -714,53 +784,55 @@
 /**********************************************************************
 End enumeration of the LDAP password list 
 *********************************************************************/
-void pdb_endsampwent(void)
+void ldapsam_endsampwent(struct pdb_context *context)
 {
-	if (global_ldap_ent.ldap_struct && global_ldap_ent.result)
+	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+	if (ldap_state->ldap_struct && ldap_state->result)
 	{
-		ldap_msgfree(global_ldap_ent.result);
-		ldap_unbind(global_ldap_ent.ldap_struct);
-		global_ldap_ent.ldap_struct = NULL;
-		global_ldap_ent.result = NULL;
+		ldap_msgfree(ldap_state->result);
+		ldap_unbind(ldap_state->ldap_struct);
+		ldap_state->ldap_struct = NULL;
+		ldap_state->result = NULL;
 	}
 }
 
 /**********************************************************************
 Get the next entry in the LDAP password database 
 *********************************************************************/
-BOOL pdb_getsampwent(SAM_ACCOUNT * user)
+BOOL ldapsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT * user)
 {
-	if (!global_ldap_ent.entry)
+	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+	BOOL ret = False;
+	if (!ldap_state->entry)
 		return False;
 
-	global_ldap_ent.entry =	ldap_next_entry(global_ldap_ent.ldap_struct,
-				global_ldap_ent.entry);
+	ret =  init_sam_from_ldap(ldap_state, user, ldap_state->ldap_struct,
+					  ldap_state->entry);
 
-	if (global_ldap_ent.entry != NULL)
-	{
-		return init_sam_from_ldap(user, global_ldap_ent.ldap_struct,
-					  global_ldap_ent.entry);
-	}
-	return False;
+	ldap_state->entry =	ldap_next_entry(ldap_state->ldap_struct,
+				ldap_state->entry);
+
+	return ret;
 }
 
 /**********************************************************************
 Get SAM_ACCOUNT entry from LDAP by username 
 *********************************************************************/
-BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname)
+BOOL ldapsam_getsampwnam(struct pdb_context *context, SAM_ACCOUNT * user, const char *sname)
 {
+	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
 	LDAP *ldap_struct;
 	LDAPMessage *result;
 	LDAPMessage *entry;
 
-	if (!ldap_open_connection(&ldap_struct))
+	if (!ldapsam_open_connection(ldap_state, &ldap_struct))
 		return False;
-	if (!ldap_connect_system(ldap_struct))
+	if (!ldapsam_connect_system(ldap_state, ldap_struct))
 	{
 		ldap_unbind(ldap_struct);
 		return False;
 	}
-	if (ldap_search_one_user_by_name(ldap_struct, sname, &result) != LDAP_SUCCESS)
+	if (ldapsam_search_one_user_by_name(ldap_state, ldap_struct, sname, &result) != LDAP_SUCCESS)
 	{
 		ldap_unbind(ldap_struct);
 		return False;
@@ -776,7 +848,7 @@
 	entry = ldap_first_entry(ldap_struct, result);
 	if (entry)
 	{
-		init_sam_from_ldap(user, ldap_struct, entry);
+		init_sam_from_ldap(ldap_state, user, ldap_struct, entry);
 		ldap_msgfree(result);
 		ldap_unbind(ldap_struct);
 		return True;
@@ -792,21 +864,22 @@
 /**********************************************************************
 Get SAM_ACCOUNT entry from LDAP by rid 
 *********************************************************************/
-BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
+BOOL ldapsam_getsampwrid(struct pdb_context *context, SAM_ACCOUNT * user, uint32 rid)
 {
+	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
 	LDAP *ldap_struct;
 	LDAPMessage *result;
 	LDAPMessage *entry;
 
-	if (!ldap_open_connection(&ldap_struct))
+	if (!ldapsam_open_connection(ldap_state, &ldap_struct))
 		return False;
 
-	if (!ldap_connect_system(ldap_struct))
+	if (!ldapsam_connect_system(ldap_state, ldap_struct))
 	{
 		ldap_unbind(ldap_struct);
 		return False;
 	}
-	if (ldap_search_one_user_by_rid(ldap_struct, rid, &result) !=
+	if (ldapsam_search_one_user_by_rid(ldap_state, ldap_struct, rid, &result) !=
 	    LDAP_SUCCESS)
 	{
 		ldap_unbind(ldap_struct);
@@ -825,7 +898,7 @@
 	entry = ldap_first_entry(ldap_struct, result);
 	if (entry)
 	{
-		init_sam_from_ldap(user, ldap_struct, entry);
+		init_sam_from_ldap(ldap_state, user, ldap_struct, entry);
 		ldap_msgfree(result);
 		ldap_unbind(ldap_struct);
 		return True;
@@ -841,8 +914,9 @@
 /**********************************************************************
 Delete entry from LDAP for username 
 *********************************************************************/
-BOOL pdb_delete_sam_account(SAM_ACCOUNT * sam_acct)
+BOOL ldapsam_delete_sam_account(struct pdb_context *context, const SAM_ACCOUNT * sam_acct)
 {
+	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
 	const char *sname;
 	int rc;
 	char *dn;
@@ -857,18 +931,18 @@
 
 	sname = pdb_get_username(sam_acct);
 
-	if (!ldap_open_connection (&ldap_struct))
+	if (!ldapsam_open_connection(ldap_state, &ldap_struct))
 		return False;
 
 	DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
 	
-	if (!ldap_connect_system (ldap_struct)) {
+	if (!ldapsam_connect_system(ldap_state, ldap_struct)) {
 		ldap_unbind (ldap_struct);
 		DEBUG(0, ("Failed to delete user %s from LDAP.\n", sname));
 		return False;
 	}
 
-	rc = ldap_search_one_user_by_name (ldap_struct, sname, &result);
+	rc = ldapsam_search_one_user_by_name(ldap_state, ldap_struct, sname, &result);
 	if (ldap_count_entries (ldap_struct, result) == 0) {
 		DEBUG (0, ("User doesn't exit!\n"));
 		ldap_msgfree (result);
@@ -900,8 +974,9 @@
 /**********************************************************************
 Update SAM_ACCOUNT 
 *********************************************************************/
-BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd)
+BOOL ldapsam_update_sam_account(struct pdb_context *context, const SAM_ACCOUNT * newpwd)
 {
+	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
 	int rc;
 	char *dn;
 	LDAP *ldap_struct;
@@ -909,17 +984,17 @@
 	LDAPMessage *entry;
 	LDAPMod **mods;
 
-	if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */
+	if (!ldapsam_open_connection(ldap_state, &ldap_struct)) /* open a connection to the server */
 		return False;
 
-	if (!ldap_connect_system(ldap_struct))	/* connect as system account */
+	if (!ldapsam_connect_system(ldap_state, ldap_struct))	/* connect as system account */
 	{
 		ldap_unbind(ldap_struct);
 		return False;
 	}
 
-	rc = ldap_search_one_user_by_name(ldap_struct,
-					  pdb_get_username(newpwd), &result);
+	rc = ldapsam_search_one_user_by_name(ldap_state, ldap_struct,
+					     pdb_get_username(newpwd), &result);
 
 	if (ldap_count_entries(ldap_struct, result) == 0)
 	{
@@ -929,7 +1004,7 @@
 		return False;
 	}
 
-	init_ldap_from_sam(&mods, LDAP_MOD_REPLACE, newpwd);
+	init_ldap_from_sam(ldap_state, &mods, LDAP_MOD_REPLACE, newpwd);
 
 	entry = ldap_first_entry(ldap_struct, result);
 	dn = ldap_get_dn(ldap_struct, entry);
@@ -961,8 +1036,9 @@
 /**********************************************************************
 Add SAM_ACCOUNT to LDAP 
 *********************************************************************/
-BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
+BOOL ldapsam_add_sam_account(struct pdb_context *context, const SAM_ACCOUNT * newpwd)
 {
+	struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
 	int rc;
 	pstring filter;
 	LDAP *ldap_struct;
@@ -972,18 +1048,18 @@
 	int 		ldap_op;
 	uint32		num_result;
 
-	if (!ldap_open_connection(&ldap_struct))	/* open a connection to the server */
+	if (!ldapsam_open_connection(ldap_state, &ldap_struct))	/* open a connection to the server */
 	{
 		return False;
 	}
 
-	if (!ldap_connect_system(ldap_struct))	/* connect as system account */
+	if (!ldapsam_connect_system(ldap_state, ldap_struct))	/* connect as system account */
 	{
 		ldap_unbind(ldap_struct);
 		return False;
 	}
 
-	rc = ldap_search_one_user_by_name (ldap_struct, pdb_get_username(newpwd), &result);
+	rc = ldapsam_search_one_user_by_name (ldap_state, ldap_struct, pdb_get_username(newpwd), &result);
 
 	if (ldap_count_entries(ldap_struct, result) != 0)
 	{
@@ -995,7 +1071,7 @@
 	ldap_msgfree(result);
 
 	slprintf (filter, sizeof (filter) - 1, "uid=%s", pdb_get_username(newpwd));
-	rc = ldap_search_one_user(ldap_struct, filter, &result);
+	rc = ldapsam_search_one_user(ldap_state, ldap_struct, filter, &result);
 	num_result = ldap_count_entries(ldap_struct, result);
 	
 	if (num_result > 1) {
@@ -1024,7 +1100,7 @@
 
 	ldap_msgfree(result);
 
-	init_ldap_from_sam(&mods, ldap_op, newpwd);
+	init_ldap_from_sam(ldap_state, &mods, ldap_op, newpwd);
 	make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
 
 	if (ldap_op == LDAP_MOD_REPLACE) {
@@ -1053,10 +1129,105 @@
 	return True;
 }
 
+static void free_private_data(void **vp) 
+{
+	struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
+
+	if ((*ldap_state)->ldap_struct) {
+		ldap_unbind((*ldap_state)->ldap_struct);
+	}
+
+	*ldap_state = NULL;
+
+	/* No need to free any further, as it is talloc()ed */
+}
+
+NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+	NTSTATUS nt_status;
+	struct ldapsam_privates *ldap_state;
+
+	if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
+		return nt_status;
+	}
+
+	(*pdb_method)->name = "ldapsam";
+
+	(*pdb_method)->setsampwent = ldapsam_setsampwent;
+	(*pdb_method)->endsampwent = ldapsam_endsampwent;
+	(*pdb_method)->getsampwent = ldapsam_getsampwent;
+	(*pdb_method)->getsampwnam = ldapsam_getsampwnam;
+	(*pdb_method)->getsampwrid = ldapsam_getsampwrid;
+	(*pdb_method)->add_sam_account = ldapsam_add_sam_account;
+	(*pdb_method)->update_sam_account = ldapsam_update_sam_account;
+	(*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
+
+	/* TODO: Setup private data and free */
+
+	ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates));
+
+	if (!ldap_state) {
+		DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (location) {
+		ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
+	} else {
+		ldap_state->uri = "ldap://localhost";
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	(*pdb_method)->private_data = ldap_state;
+
+	(*pdb_method)->free_private_data = free_private_data;
+
+	return NT_STATUS_OK;
+}
+
+NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+	NTSTATUS nt_status;
+	struct ldapsam_privates *ldap_state;
+	uint32 low_nua_uid, high_nua_uid;
+
+	if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) {
+		return nt_status;
+	}
+
+	(*pdb_method)->name = "ldapsam_nua";
+
+	ldap_state = (*pdb_method)->private_data;
+	
+	ldap_state->permit_non_unix_accounts = True;
+
+	if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
+		DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n"));
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	ldap_state->low_nua_rid=pdb_uid_to_user_rid(low_nua_uid);
+
+	ldap_state->high_nua_rid=pdb_uid_to_user_rid(high_nua_uid);
+
+	return NT_STATUS_OK;
+}
+
+
 #else
-void dummy_function(void);
-void
-dummy_function (void)
+
+NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
 {
-}				/* stop some compilers complaining */
+	DEBUG(0, ("ldapsam not compiled in!\n"));
+	return NT_STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+	DEBUG(0, ("ldapsam_nua not compiled in!\n"));
+	return NT_STATUS_UNSUCCESSFUL;
+}
+
+
 #endif
+
Index: source/passdb/secrets.c
===================================================================
RCS file: /data/cvs/samba/source/passdb/secrets.c,v
retrieving revision 1.26
diff -u -r1.26 secrets.c
--- source/passdb/secrets.c	9 Jan 2002 02:35:08 -0000	1.26
+++ source/passdb/secrets.c	27 Jan 2002 05:53:52 -0000
@@ -258,31 +258,3 @@
 	return secrets_store(key, pw, strlen(pw));
 }
 
-BOOL fetch_ldap_pw(char *dn, char* pw, int len)
-{
-	fstring key;
-	char *p;
-	void *data = NULL;
-	size_t size;
-	
-	pstrcpy(key, dn);
-	for (p=key; *p; p++)
-		if (*p == ',') *p = '/';
-	
-	data=secrets_fetch(key, &size);
-	if (!size) {
-		DEBUG(0,("fetch_ldap_pw: no ldap secret retrieved!\n"));
-		return False;
-	}
-	
-	if (size > len-1)
-	{
-		DEBUG(0,("fetch_ldap_pw: ldap secret is too long (%d > %d)!\n", size, len-1));
-		return False;
-	}
-
-	memcpy(pw, data, size);
-	pw[size] = '\0';
-	
-	return True;
-}
Index: source/rpc_server/srv_samr_nt.c
===================================================================
RCS file: /data/cvs/samba/source/rpc_server/srv_samr_nt.c,v
retrieving revision 1.80
diff -u -r1.80 srv_samr_nt.c
--- source/rpc_server/srv_samr_nt.c	26 Jan 2002 10:03:25 -0000	1.80
+++ source/rpc_server/srv_samr_nt.c	27 Jan 2002 05:53:59 -0000
@@ -270,22 +270,22 @@
 	if (pw_buf == NULL)
 		return NT_STATUS_NO_MEMORY;
 
-	pdb_init_sam(&pwd);
-
 	if (!pdb_setsampwent(False)) {
 		DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
 		pdb_free_sam(&pwd);
 		return NT_STATUS_ACCESS_DENIED;
 	}
 	
-	while (((not_finished = pdb_getsampwent(pwd)) != False) 
+	pdb_init_sam(&pwd);
+
+	while (((NT_STATUS_IS_OK(pdb_init_sam(&pwd)) && (not_finished = pdb_getsampwent(pwd))) != False) 
 	       && (*num_entries) < max_num_entries) 
 	{
 	        int user_name_len;
 		
 	        if (start_idx > 0) {
 
-			pdb_reset_sam(pwd);
+			pdb_free_sam(&pwd);
 
 			/* skip the requested number of entries.
 			   not very efficient, but hey...  */
@@ -317,12 +317,11 @@
 
 		(*total_entries)++;
 		
-		pdb_reset_sam(pwd);
+		pdb_free_sam(&pwd);
 
 	}
 	
 	pdb_endsampwent();
-	pdb_free_sam(&pwd);
 
 	if (not_finished)
 		return STATUS_MORE_ENTRIES;
@@ -1266,7 +1265,7 @@
 
     if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
                          q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
-        r_u->status = NT_STATUS_WRONG_PASSWORD;
+	    r_u->status = NT_STATUS_WRONG_PASSWORD;
 
     init_samr_r_chgpasswd_user(r_u, r_u->status);
 


More information about the samba-technical mailing list