diff options
| author | Michael Adam <obnox@samba.org> | 2007-09-11 16:50:32 +0000 | 
|---|---|---|
| committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:30:39 -0500 | 
| commit | e16f8188eaee0d4b8e059bea755100a98ac1867d (patch) | |
| tree | c5021e9b3ea03ca89e4e93435c081c09caf0a12d /source3 | |
| parent | 3853c7e1447e473bf34f207971b5f1c03a17ffb5 (diff) | |
| download | samba-e16f8188eaee0d4b8e059bea755100a98ac1867d.tar.gz samba-e16f8188eaee0d4b8e059bea755100a98ac1867d.tar.bz2 samba-e16f8188eaee0d4b8e059bea755100a98ac1867d.zip  | |
r25092: Add support for storing trusted domain passwords in LDAP for
passdb backend = ldapsam.
Along with reproducing the functionality of the secrets.tdb
code, I have prepared the handling of the previous trust password
(in case we are contacting a dc which does not yet know of a recent
password change). This information has still to be propagated
to the outside, but this requires a change of the api and also
a change of the secrets.tdb code.
Michael
(This used to be commit 6c3c20e6c4a2b04de8111f2c79b431f0775c2a0f)
Diffstat (limited to 'source3')
| -rw-r--r-- | source3/include/smbldap.h | 1 | ||||
| -rw-r--r-- | source3/passdb/pdb_ldap.c | 282 | 
2 files changed, 278 insertions, 5 deletions
diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index bc438a98de..c05f53ae31 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -40,6 +40,7 @@ struct smbldap_state;  #define LDAP_OBJ_IDMAP_ENTRY		"sambaIdmapEntry"  #define LDAP_OBJ_SID_ENTRY		"sambaSidEntry"  #define LDAP_OBJ_TRUST_PASSWORD         "sambaTrustPassword" +#define LDAP_OBJ_TRUSTDOM_PASSWORD      "sambaTrustedDomainPassword"  #define LDAP_OBJ_ACCOUNT		"account"  #define LDAP_OBJ_POSIXACCOUNT		"posixAccount" diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index b081ae2bb9..e68c8242ca 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -5475,15 +5475,128 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,   trusted domains functions   *********************************************************************/ +static char *trusteddom_dn(struct ldapsam_privates *ldap_state, +			   const char *domain) +{ +	return talloc_asprintf(talloc_tos(), "sambaDomainName=%s,%s", domain, +			       ldap_state->domain_dn); +} + +static BOOL get_trusteddom_pw_int(struct ldapsam_privates *ldap_state, +				  const char *domain, LDAPMessage **entry) +{ +	int rc; +	char *filter; +	int scope = LDAP_SCOPE_SUBTREE; +	const char **attrs = NULL; /* NULL: get all attrs */ +	int attrsonly = 0; /* 0: return values too */ +	LDAPMessage *result = NULL; +	char *trusted_dn; +	uint32 num_result; + +	filter = talloc_asprintf(talloc_tos(), +				 "(&(objectClass=%s)(sambaDomainName=%s))", +				 LDAP_OBJ_TRUSTDOM_PASSWORD, domain); + +	trusted_dn = trusteddom_dn(ldap_state, domain); +	if (trusted_dn == NULL) { +		return False; +	} +	rc = smbldap_search(ldap_state->smbldap_state, trusted_dn, scope, +			    filter, attrs, attrsonly, &result); + +	if (rc == LDAP_NO_SUCH_OBJECT) { +		*entry = NULL; +		return True; +	} + +	if (rc != LDAP_SUCCESS) { +		return False; +	} + +	num_result = ldap_count_entries(priv2ld(ldap_state), result); + +	if (num_result > 1) { +		DEBUG(1, ("ldapsam_get_trusteddom_pw: more than one " +			  "sambaTrustedDomainPassword object for domain '%s'" +			  "?!\n", domain)); +		return False; +	} + +	if (num_result == 0) { +		DEBUG(1, ("ldapsam_get_trusteddom_pw: no " +			  "sambaTrustedDomainPassword object for domain %s.\n", +			  domain)); +		*entry = NULL; +	} else { +		*entry = ldap_first_entry(priv2ld(ldap_state), result); +	} + +	return True; +} +  static BOOL ldapsam_get_trusteddom_pw(struct pdb_methods *methods,  				      const char *domain,  				      char** pwd,  				      DOM_SID *sid,  	        	 	      time_t *pass_last_set_time)  { -	return secrets_fetch_trusted_domain_password(domain, pwd, -				sid, pass_last_set_time); +	struct ldapsam_privates *ldap_state = +		(struct ldapsam_privates *)methods->private_data; +	LDAPMessage *entry = NULL; + +	DEBUG(10, ("ldapsam_get_trusteddom_pw called for domain %s\n", domain)); + +	if (!get_trusteddom_pw_int(ldap_state, domain, &entry) || +	    (entry == NULL)) +	{ +		return False; +	} + +	/* password */ +	if (pwd != NULL) { +		char *pwd_str; +		pwd_str = smbldap_talloc_single_attribute(priv2ld(ldap_state), +				entry, "sambaClearTextPassword", talloc_tos()); +		if (pwd_str == NULL) { +			return False; +		} +		/* trusteddom_pw routines do not use talloc yet... */ +		*pwd = SMB_STRDUP(pwd_str); +		if (*pwd == NULL) { +			return False; +		} +	} + +	/* last change time */ +	if (pass_last_set_time != NULL) { +		char *time_str; +		time_str = smbldap_talloc_single_attribute(priv2ld(ldap_state), +				entry, "sambaPwdLastSet", talloc_tos()); +		if (time_str == NULL) { +			return False; +		} +		*pass_last_set_time = (time_t)atol(time_str); +	} + +	/* domain sid */ +	if (sid != NULL) { +		char *sid_str; +		DOM_SID *dom_sid; +		sid_str = smbldap_talloc_single_attribute(priv2ld(ldap_state), +							  entry, "sambaSID", +							  talloc_tos()); +		if (sid_str == NULL) { +			return False; +		} +		dom_sid = string_sid_talloc(talloc_tos(), sid_str); +		if (dom_sid == NULL) { +			return False; +		} +		sid_copy(sid, dom_sid); +	} +	return True;  }  static BOOL ldapsam_set_trusteddom_pw(struct pdb_methods *methods, @@ -5491,13 +5604,95 @@ static BOOL ldapsam_set_trusteddom_pw(struct pdb_methods *methods,  				      const char* pwd,  	        	  	      const DOM_SID *sid)  { -	return secrets_store_trusted_domain_password(domain, pwd, sid); +	struct ldapsam_privates *ldap_state = +		(struct ldapsam_privates *)methods->private_data; +	LDAPMessage *entry = NULL; +	LDAPMod **mods = NULL; +	char *prev_pwd = NULL; +	char *trusted_dn = NULL; +	int rc; + +	DEBUG(10, ("ldapsam_set_trusteddom_pw called for domain %s\n", domain)); + +	/* +	 * get the current entry (if there is one) in order to put the +	 * current password into the previous password attribute +	 */ +	if (!get_trusteddom_pw_int(ldap_state, domain, &entry)) { +		return False; +	} + +	mods = NULL; +	smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass", +			 "sambaTrustedDomainPassword"); +	smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaDomainName", +			 domain); +	smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaSID", +			 sid_string_tos(sid)); +	smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaPwdLastSet", +			 talloc_asprintf(talloc_tos(), "%li", time(NULL))); +	smbldap_make_mod(priv2ld(ldap_state), entry, &mods, +			 "sambaClearTextPassword", pwd); +	if (entry != NULL) { +		prev_pwd = smbldap_talloc_single_attribute(priv2ld(ldap_state), +				entry, "sambaClearTextPassword", talloc_tos()); +		if (prev_pwd != NULL) { +			smbldap_make_mod(priv2ld(ldap_state), entry, &mods, +					 "sambaPreviousClearTextPassword", +					 prev_pwd); +		} +	} + +	trusted_dn = trusteddom_dn(ldap_state, domain); +	if (trusted_dn == NULL) { +		return False; +	} +	if (entry == NULL) { +		rc = smbldap_add(ldap_state->smbldap_state, trusted_dn, mods); +	} else { +		rc = smbldap_modify(ldap_state->smbldap_state, trusted_dn, mods); +	} + +	if (rc != LDAP_SUCCESS) { +		DEBUG(1, ("error writing trusted domain password!\n")); +		return False; +	} + +	return True;  }  static BOOL ldapsam_del_trusteddom_pw(struct pdb_methods *methods,  				      const char *domain)  { -	return trusted_domain_password_delete(domain); +	int rc; +	struct ldapsam_privates *ldap_state = +		(struct ldapsam_privates *)methods->private_data; +	LDAPMessage *entry = NULL; +	const char *trusted_dn; + +	if (!get_trusteddom_pw_int(ldap_state, domain, &entry)) { +		return False; +	} + +	if (entry == NULL) { +		DEBUG(5, ("ldapsam_del_trusteddom_pw: no such trusted domain: " +			  "%s\n", domain)); +		return True; +	} + +	trusted_dn = smbldap_talloc_dn(talloc_tos(), priv2ld(ldap_state), +				       entry); +	if (trusted_dn == NULL) { +		DEBUG(0,("ldapsam_del_trusteddom_pw: Out of memory!\n")); +		return False; +	} + +	rc = smbldap_delete(ldap_state->smbldap_state, trusted_dn); +	if (rc != LDAP_SUCCESS) { +		return False; +	} + +	return True;  }  static NTSTATUS ldapsam_enum_trusteddoms(struct pdb_methods *methods, @@ -5505,7 +5700,84 @@ static NTSTATUS ldapsam_enum_trusteddoms(struct pdb_methods *methods,  					 uint32 *num_domains,  					 struct trustdom_info ***domains)  { -	return secrets_trusted_domains(mem_ctx, num_domains, domains); +	int rc; +	struct ldapsam_privates *ldap_state = +		(struct ldapsam_privates *)methods->private_data; +	char *filter; +	int scope = LDAP_SCOPE_SUBTREE; +	const char *attrs[] = { "sambaDomainName", "sambaSID", NULL }; +	int attrsonly = 0; /* 0: return values too */ +	LDAPMessage *result = NULL; +	LDAPMessage *entry = NULL; + +	filter = talloc_asprintf(talloc_tos(), "(objectClass=%s)", +				 LDAP_OBJ_TRUSTDOM_PASSWORD); + +	rc = smbldap_search(ldap_state->smbldap_state, +			    ldap_state->domain_dn, +			    scope, +			    filter, +			    attrs, +			    attrsonly, +			    &result); + +	if (rc != LDAP_SUCCESS) { +		return NT_STATUS_UNSUCCESSFUL; +	} + +	*num_domains = 0; +	if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) { +		DEBUG(1, ("talloc failed\n")); +		return NT_STATUS_NO_MEMORY; +	} + +	for (entry = ldap_first_entry(priv2ld(ldap_state), result); +	     entry != NULL; +	     entry = ldap_next_entry(priv2ld(ldap_state), entry)) +	{ +		char *dom_name, *dom_sid_str; +		struct trustdom_info *dom_info; + +		dom_info = TALLOC_P(*domains, struct trustdom_info); +		if (dom_info == NULL) { +			DEBUG(1, ("talloc failed\n")); +			return NT_STATUS_NO_MEMORY; +		} + +		dom_name = smbldap_talloc_single_attribute(priv2ld(ldap_state), +							   entry, +							   "sambaDomainName", +							   talloc_tos()); +		if (dom_name == NULL) { +			DEBUG(1, ("talloc failed\n")); +			return NT_STATUS_NO_MEMORY; +		} +		dom_info->name = dom_name; + +		dom_sid_str = smbldap_talloc_single_attribute( +					priv2ld(ldap_state), entry, "sambaSID", +					talloc_tos()); +		if (dom_sid_str == NULL) { +			DEBUG(1, ("talloc failed\n")); +			return NT_STATUS_NO_MEMORY; +		} +		if (!string_to_sid(&dom_info->sid, dom_sid_str)) { +			DEBUG(1, ("Error calling string_to_sid on SID %s\n", +				  dom_sid_str)); +			return NT_STATUS_UNSUCCESSFUL; +		} + +		ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info, +			     domains, num_domains); + +		if (*domains == NULL) { +			DEBUG(1, ("talloc failed\n")); +			return NT_STATUS_NO_MEMORY; +		} +	} + +	DEBUG(5, ("ldapsam_enum_trusteddoms: got %d domains\n", *num_domains)); +	return NT_STATUS_OK;  }  | 
