diff options
author | Andrew Bartlett <abartlet@samba.org> | 2009-05-26 13:09:57 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2009-05-27 07:58:07 +1000 |
commit | 5264ad627d59e0f2cb03cb3bdd3baf8943d7fa5b (patch) | |
tree | 73a8391c8c47e3a0191d0fdb0bffc5a53afda199 /source4 | |
parent | 8c871706e0c6cf42e06f33b7bfeed7fb5a7d4ff0 (diff) | |
download | samba-5264ad627d59e0f2cb03cb3bdd3baf8943d7fa5b.tar.gz samba-5264ad627d59e0f2cb03cb3bdd3baf8943d7fa5b.tar.bz2 samba-5264ad627d59e0f2cb03cb3bdd3baf8943d7fa5b.zip |
Handle the krbtgt special case by looking for RID -514
It turns out (seen in MS-SAMR 3.1.1.7.1 for example) that the primary
way the krbtgt account is recognised as special is that RID. This
should fix issues such as 'password expired' on the kpasswd service.
Andrew Bartlett
Diffstat (limited to 'source4')
-rw-r--r-- | source4/kdc/hdb-samba4.c | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index 1fdb744a84..585285795f 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -38,6 +38,7 @@ #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" #include "librpc/gen_ndr/netlogon.h" +#include "libcli/security/security.h" #include "auth/auth.h" #include "auth/credentials/credentials.h" #include "auth/auth_sam.h" @@ -499,7 +500,9 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, struct hdb_ldb_private *p; NTTIME acct_expiry; + NTSTATUS status; + uint32_t rid; struct ldb_message_element *objectclasses; struct ldb_val computer_val; const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL); @@ -580,49 +583,70 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, /* First try and figure out the flags based on the userAccountControl */ entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type); - if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT) { - entry_ex->entry.flags.invalid = 0; - entry_ex->entry.flags.server = 1; - entry_ex->entry.flags.forwardable = 1; - entry_ex->entry.flags.ok_as_delegate = 1; - } - /* Windows 2008 seems to enforce this (very sensible) rule by * default - don't allow offline attacks on a user's password * by asking for a ticket to them as a service (encrypted with * their probably patheticly insecure password) */ - if (lp_parm_bool(lp_ctx, NULL, "kdc", "require spn for service", true)) { + if (entry_ex->entry.flags.server + && lp_parm_bool(lp_ctx, NULL, "kdc", "require spn for service", true)) { if (!is_computer && !ldb_msg_find_attr_as_string(msg, "servicePrincipalName", NULL)) { entry_ex->entry.flags.server = 0; } } - /* use 'whenCreated' */ - entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0); - /* use '???' */ - entry_ex->entry.created_by.principal = NULL; + { + /* These (created_by, modified_by) parts of the entry are not relevant for Samba4's use + * of the Heimdal KDC. They are stored in a the traditional + * DB for audit purposes, and still form part of the structure + * we must return */ + + /* use 'whenCreated' */ + entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0); + /* use '???' */ + entry_ex->entry.created_by.principal = NULL; + + entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event)); + if (entry_ex->entry.modified_by == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + ret = ENOMEM; + goto out; + } + + /* use 'whenChanged' */ + entry_ex->entry.modified_by->time = ldb_msg_find_krb5time_ldap_time(msg, "whenChanged", 0); + /* use '???' */ + entry_ex->entry.modified_by->principal = NULL; + } - entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event)); - if (entry_ex->entry.modified_by == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - ret = ENOMEM; + + /* The lack of password controls etc applies to krbtgt by + * virtue of being that particular RID */ + status = dom_sid_split_rid(NULL, samdb_result_dom_sid(mem_ctx, msg, "objectSid"), NULL, &rid); + + if (!NT_STATUS_IS_OK(status)) { + ret = EINVAL; goto out; } - /* use 'whenChanged' */ - entry_ex->entry.modified_by->time = ldb_msg_find_krb5time_ldap_time(msg, "whenChanged", 0); - /* use '???' */ - entry_ex->entry.modified_by->principal = NULL; + if (rid == DOMAIN_RID_KRBTGT) { + entry_ex->entry.valid_end = NULL; + entry_ex->entry.pw_end = NULL; - entry_ex->entry.valid_start = NULL; + entry_ex->entry.flags.invalid = 0; + entry_ex->entry.flags.server = 1; + entry_ex->entry.flags.change_pw = 1; + entry_ex->entry.flags.client = 0; + entry_ex->entry.flags.forwardable = 1; + entry_ex->entry.flags.ok_as_delegate = 1; + } else if (entry_ex->entry.flags.server && ent_type == HDB_SAMBA4_ENT_TYPE_SERVER) { + /* The account/password expiry only applies when the account is used as a + * client (ie password login), not when used as a server */ - /* The account/password expiry only applies when the account is used as a - * client (ie password login), not when used as a server */ - if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT || ent_type == HDB_SAMBA4_ENT_TYPE_SERVER) { /* Make very well sure we don't use this for a client, - * it could bypass the above password restrictions */ + * it could bypass the password restrictions */ entry_ex->entry.flags.client = 0; + entry_ex->entry.valid_end = NULL; entry_ex->entry.pw_end = NULL; @@ -653,7 +677,9 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, *entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry); } } - + + entry_ex->entry.valid_start = NULL; + entry_ex->entry.max_life = NULL; entry_ex->entry.max_renew = NULL; |