diff options
-rw-r--r-- | source4/auth/auth.h | 2 | ||||
-rw-r--r-- | source4/auth/sam.c | 68 | ||||
-rw-r--r-- | source4/kdc/hdb-ldb.c | 29 |
3 files changed, 72 insertions, 27 deletions
diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 8dce7bbd5b..c694141373 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -21,6 +21,8 @@ #ifndef _SAMBA_AUTH_H #define _SAMBA_AUTH_H +extern const char *user_attrs[]; + union netr_Validation; struct netr_SamBaseInfo; struct netr_SamInfo3; diff --git a/source4/auth/sam.c b/source4/auth/sam.c index 681576c1c7..2fb0a239ff 100644 --- a/source4/auth/sam.c +++ b/source4/auth/sam.c @@ -45,6 +45,7 @@ const char *user_attrs[] = { "pwdLastSet", "accountExpires", + "logonHours", "objectSid", @@ -67,8 +68,69 @@ const char *user_attrs[] = { }; const char *domain_ref_attrs[] = {"nETBIOSName", "nCName", - "dnsRoot", "objectClass", NULL}; + "dnsRoot", "objectClass", NULL}; +/**************************************************************************** + Check if a user is allowed to logon at this time. Note this is the + servers local time, as logon hours are just specified as a weekly + bitmask. +****************************************************************************/ + +static BOOL logon_hours_ok(struct ldb_message *msg, const char *name_for_logs) +{ + /* In logon hours first bit is Sunday from 12AM to 1AM */ + const struct ldb_val *hours; + struct tm *utctime; + time_t lasttime; + const char *asct; + uint8_t bitmask, bitpos; + + hours = ldb_msg_find_ldb_val(msg, "logonHours"); + if (!hours) { + DEBUG(5,("logon_hours_ok: No hours restrictions for user %s\n", name_for_logs)); + return True; + } + + if (hours->length != 168/8) { + DEBUG(5,("logon_hours_ok: malformed logon hours restrictions for user %s\n", name_for_logs)); + return True; + } + + lasttime = time(NULL); + utctime = gmtime(&lasttime); + if (!utctime) { + DEBUG(1, ("logon_hours_ok: failed to get gmtime. Failing logon for user %s\n", + name_for_logs)); + return False; + } + + /* find the corresponding byte and bit */ + bitpos = (utctime->tm_wday * 24 + utctime->tm_hour) % 168; + bitmask = 1 << (bitpos % 8); + + if (! (hours->data[bitpos/8] & bitmask)) { + struct tm *t = localtime(&lasttime); + if (!t) { + asct = "INVALID TIME"; + } else { + asct = asctime(t); + if (!asct) { + asct = "INVALID TIME"; + } + } + + DEBUG(1, ("logon_hours_ok: Account for user %s not allowed to " + "logon at this time (%s).\n", + name_for_logs, asct )); + return False; + } + + asct = asctime(utctime); + DEBUG(5,("logon_hours_ok: user %s allowed to logon at this time (%s)\n", + name_for_logs, asct ? asct : "UNKNOWN TIME" )); + + return True; +} /**************************************************************************** Do a specific test for a SAM_ACCOUNT being vaild for this connection @@ -164,6 +226,10 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, } } + if (!logon_hours_ok(msg, name_for_logs)) { + return NT_STATUS_INVALID_LOGON_HOURS; + } + if (acct_flags & ACB_DOMTRUST) { DEBUG(2,("sam_account_ok: Domain trust account %s denied by server\n", name_for_logs)); return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT; diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c index 62fcf0cb00..ddee8d19d1 100644 --- a/source4/kdc/hdb-ldb.c +++ b/source4/kdc/hdb-ldb.c @@ -54,29 +54,6 @@ enum hdb_ldb_ent_type { HDB_LDB_ENT_TYPE_CLIENT, HDB_LDB_ENT_TYPE_SERVER, HDB_LDB_ENT_TYPE_KRBTGT, HDB_LDB_ENT_TYPE_ANY }; -static const char * const krb5_attrs[] = { - "objectClass", - "sAMAccountName", - - "userPrincipalName", - "servicePrincipalName", - - "userAccountControl", - - "pwdLastSet", - "accountExpires", - - "whenCreated", - "whenChanged", - - "msDS-KeyVersionNumber", - - "unicodePwd", - "supplementalCredentials", - - NULL -}; - static const char *realm_ref_attrs[] = { "nCName", "dnsRoot", @@ -615,7 +592,7 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con krb5_error_code ret; int lret; char *filter = NULL; - const char * const *princ_attrs = krb5_attrs; + const char * const *princ_attrs = user_attrs; char *short_princ; char *short_princ_talloc; @@ -886,7 +863,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db, } ldb_ret = gendb_search_dn((struct ldb_context *)db->hdb_db, - mem_ctx, user_dn, &msg, krb5_attrs); + mem_ctx, user_dn, &msg, user_attrs); if (ldb_ret != 1) { return HDB_ERR_NOENTRY; @@ -1083,7 +1060,7 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag lret = ldb_search(ldb_ctx, realm_dn, LDB_SCOPE_SUBTREE, "(objectClass=user)", - krb5_attrs, &res); + user_attrs, &res); if (lret != LDB_SUCCESS) { talloc_free(priv); |