Author: abartlet Date: 2007-07-27 06:31:12 +0000 (Fri, 27 Jul 2007) New Revision: 24061
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=24061 Log: Anther part of bug #4823, which is that until now Samba4 didn't parse the logon hours, even if set. This code happily stolen from the great work in Samba3 :-) Andrew Bartlett Modified: branches/SAMBA_4_0/source/auth/auth.h branches/SAMBA_4_0/source/auth/sam.c branches/SAMBA_4_0/source/kdc/hdb-ldb.c Changeset: Modified: branches/SAMBA_4_0/source/auth/auth.h =================================================================== --- branches/SAMBA_4_0/source/auth/auth.h 2007-07-27 03:08:15 UTC (rev 24060) +++ branches/SAMBA_4_0/source/auth/auth.h 2007-07-27 06:31:12 UTC (rev 24061) @@ -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; Modified: branches/SAMBA_4_0/source/auth/sam.c =================================================================== --- branches/SAMBA_4_0/source/auth/sam.c 2007-07-27 03:08:15 UTC (rev 24060) +++ branches/SAMBA_4_0/source/auth/sam.c 2007-07-27 06:31:12 UTC (rev 24061) @@ -45,6 +45,7 @@ "pwdLastSet", "accountExpires", + "logonHours", "objectSid", @@ -67,9 +68,70 @@ }; 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 (ie not disabled, expired and the like). @@ -164,6 +226,10 @@ } } + 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; Modified: branches/SAMBA_4_0/source/kdc/hdb-ldb.c =================================================================== --- branches/SAMBA_4_0/source/kdc/hdb-ldb.c 2007-07-27 03:08:15 UTC (rev 24060) +++ branches/SAMBA_4_0/source/kdc/hdb-ldb.c 2007-07-27 06:31:12 UTC (rev 24061) @@ -54,29 +54,6 @@ { 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 @@ 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 @@ } 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 @@ 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);