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 | |
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)
-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; } |