summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/auth/auth.h2
-rw-r--r--source4/auth/sam.c68
-rw-r--r--source4/kdc/hdb-ldb.c29
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);