[patch] logon hours support
Richard Renard
rrenard at idealx.com
Thu Aug 5 09:17:14 GMT 2004
hi list,
Here is a patch that gives samba3 support for logon hours.
tdb and ldap backend are working.
there is also a "-Z" flag added to pdbedit for resetting hours.
the logic is inspired from this mail
http://ma.ph-freiburg.de/tng/tng-technical/2003-04/msg00015.html
It needs some testing mostly about the daylight saving time stuff
missing is the "times" option to "net" allowing to set hours from
command line.
Thanks,
Richard.
--
Richard Renard
rrenard at idealx.com
-------------- next part --------------
diff -ruN samba-3.0.5.orig/examples/LDAP/samba.schema samba-3.0.5/examples/LDAP/samba.schema
--- samba-3.0.5.orig/examples/LDAP/samba.schema 2004-07-20 18:28:24.000000000 +0200
+++ samba-3.0.5/examples/LDAP/samba.schema 2004-08-04 17:21:21.000000000 +0200
@@ -212,6 +212,11 @@
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+attributetype ( 1.3.6.1.4.1.7165.2.1.50 NAME 'sambaLogonHours'
+ DESC 'Logon Hours'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{42} SINGLE-VALUE )
+
##
## string settings
@@ -329,7 +334,7 @@
displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $
sambaProfilePath $ description $ sambaUserWorkstations $
sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $
- sambaBadPasswordCount $ sambaBadPasswordTime))
+ sambaBadPasswordCount $ sambaBadPasswordTime $ sambaLogonHours))
##
## Group mapping info
diff -ruN samba-3.0.5.orig/source/auth/auth_sam.c samba-3.0.5/source/auth/auth_sam.c
--- samba-3.0.5.orig/source/auth/auth_sam.c 2004-07-20 18:28:01.000000000 +0200
+++ samba-3.0.5/source/auth/auth_sam.c 2004-08-05 11:01:28.000000000 +0200
@@ -65,6 +65,51 @@
lm_pw, nt_pw, user_sess_key, lm_sess_key);
}
+static BOOL logon_hours_ok(SAM_ACCOUNT *sampass)
+{
+ /* There is a problem when setting hours from a client which is
+ * configured for a TZ that does not support DST,
+ * one must add an hour to its clock to match DST.
+ * This is NT4's behavior. */
+
+ /* Logon hours are stored in UTC, first bit is Sunday from 12AM to 1AM */
+ const uint8 *hours;
+ time_t systime;
+ struct tm *utctime;
+ extern int daylight;
+
+ uint8 mask, field, test, bitpos, byte = 0x0;
+ int wday, hour = 0;
+
+ DEBUG(4,("logon_hours_ok: Checking logon hours password for user %s\n",pdb_get_username(sampass)));
+
+ tzset();
+
+ systime = time(NULL);
+ utctime = gmtime(&systime);
+
+ wday = utctime->tm_wday;
+ hour = utctime->tm_hour;
+
+ hours = pdb_get_hours(sampass);
+
+ /* FIXME: need to get the saving time offset, assumed to +1 for now */
+ if (daylight) hour += 1;
+
+ /* find the corresponding byte and bit */
+ bitpos = ((wday * 24 + hour)) % 168;
+ byte = bitpos / 8;
+ mask = 1 << (bitpos % 8);
+ field = hours[byte];
+
+ if (! (field & mask)) {
+ DEBUG(1,("logon_hours_ok: Account for user %s not allowed to logon at this time.\n", pdb_get_username(sampass)));
+ return False;
+ }
+
+ return True;
+}
+
/****************************************************************************
Do a specific test for a SAM_ACCOUNT being vaild for this connection
@@ -93,6 +138,11 @@
return NT_STATUS_ACCOUNT_LOCKED_OUT;
}
+ /* Quit if the account is not allowed to logon at this time. */
+ if (! logon_hours_ok(sampass)) {
+ return NT_STATUS_INVALID_LOGON_HOURS;
+ }
+
/* Test account expire time */
kickoff_time = pdb_get_kickoff_time(sampass);
diff -ruN samba-3.0.5.orig/source/include/smbldap.h samba-3.0.5/source/include/smbldap.h
--- samba-3.0.5.orig/source/include/smbldap.h 2004-07-20 18:28:12.000000000 +0200
+++ samba-3.0.5/source/include/smbldap.h 2004-08-04 17:21:21.000000000 +0200
@@ -93,6 +93,7 @@
#define LDAP_ATTR_LOGON_COUNT 36
#define LDAP_ATTR_MUNGED_DIAL 37
#define LDAP_ATTR_BAD_PASSWORD_TIME 38
+#define LDAP_ATTR_LOGON_HOURS 39
#define LDAP_ATTR_SID_LIST 40
diff -ruN samba-3.0.5.orig/source/lib/smbldap.c samba-3.0.5/source/lib/smbldap.c
--- samba-3.0.5.orig/source/lib/smbldap.c 2004-07-20 18:28:04.000000000 +0200
+++ samba-3.0.5/source/lib/smbldap.c 2004-08-04 17:21:21.000000000 +0200
@@ -100,6 +100,7 @@
{ LDAP_ATTR_MUNGED_DIAL, "sambaMungedDial" },
{ LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" },
{ LDAP_ATTR_BAD_PASSWORD_TIME, "sambaBadPasswordTime" },
+ { LDAP_ATTR_LOGON_HOURS, "sambaLogonHours" },
{ LDAP_ATTR_LIST_END, NULL }
};
diff -ruN samba-3.0.5.orig/source/passdb/passdb.c samba-3.0.5/source/passdb/passdb.c
--- samba-3.0.5.orig/source/passdb/passdb.c 2004-07-20 18:28:09.000000000 +0200
+++ samba-3.0.5/source/passdb/passdb.c 2004-08-04 17:21:21.000000000 +0200
@@ -605,6 +605,57 @@
return rid_offset;
}
+/*************************************************************
+ Routine to set 42 hex hours characters from a 21 byte array.
+**************************************************************/
+
+void pdb_sethexhours(char *p, const unsigned char *hours)
+{
+ if (hours != NULL) {
+ int i;
+ for (i = 0; i < 21; i++)
+ slprintf(&p[i*2], 3, "%02X", hours[i]);
+ }
+ else
+ {
+ safe_strcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
+ }
+}
+
+/*************************************************************
+ Routine to get the 42 hex characters and turn them
+ into a 21 byte array.
+**************************************************************/
+
+BOOL pdb_gethexhours(const char *p, unsigned char *hours)
+{
+ int i;
+ unsigned char lonybble, hinybble;
+ const char *hexchars = "0123456789ABCDEF";
+ char *p1, *p2;
+
+ if (!p)
+ return (False);
+
+ for (i = 0; i < 42; i += 2) {
+ hinybble = toupper(p[i]);
+ lonybble = toupper(p[i + 1]);
+
+ p1 = strchr(hexchars, hinybble);
+ p2 = strchr(hexchars, lonybble);
+
+ if (!p1 || !p2)
+ return (False);
+
+ hinybble = PTR_DIFF(p1, hexchars);
+ lonybble = PTR_DIFF(p2, hexchars);
+
+ hours[i / 2] = (hinybble << 4) | lonybble;
+ }
+ return (True);
+}
+
+
/*******************************************************************
Converts NT user RID to a UNIX uid.
********************************************************************/
diff -ruN samba-3.0.5.orig/source/passdb/pdb_ldap.c samba-3.0.5/source/passdb/pdb_ldap.c
--- samba-3.0.5.orig/source/passdb/pdb_ldap.c 2004-07-20 18:28:09.000000000 +0200
+++ samba-3.0.5/source/passdb/pdb_ldap.c 2004-08-04 17:21:21.000000000 +0200
@@ -708,6 +708,17 @@
pdb_set_hours_len(sampass, hours_len, PDB_SET);
pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
+
+ if(!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
+ get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_HOURS), temp)) {
+ /* leave as default */
+ } else {
+ pdb_gethexhours(temp, hours);
+ memset((char *)temp, '\0', strlen(temp) +1);
+ pdb_set_hours(sampass, hours, PDB_SET);
+ ZERO_STRUCT(hours);
+ }
+
/* pdb_set_munged_dial(sampass, munged_dial, PDB_SET); */
@@ -738,8 +749,6 @@
/* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
- pdb_set_hours(sampass, hours, PDB_SET);
-
/* check the timestamp of the cache vs ldap entry */
if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state,
entry)))
@@ -993,7 +1002,15 @@
}
}
- /* FIXME: Hours stuff goes in LDAP */
+ if (need_update(sampass, PDB_HOURS)) {
+ const char *hours = pdb_get_hours(sampass);
+ if (hours) {
+ pdb_sethexhours(temp, hours);
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
+ get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_HOURS),
+ temp);
+ }
+ }
if (need_update(sampass, PDB_ACCTCTRL))
smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
diff -ruN samba-3.0.5.orig/source/utils/pdbedit.c samba-3.0.5/source/utils/pdbedit.c
--- samba-3.0.5.orig/source/utils/pdbedit.c 2004-07-20 18:28:15.000000000 +0200
+++ samba-3.0.5/source/utils/pdbedit.c 2004-08-04 17:23:22.000000000 +0200
@@ -49,6 +49,7 @@
#define BIT_EXPORT 0x02000000
#define BIT_FIX_INIT 0x04000000
#define BIT_BADPWRESET 0x08000000
+#define BIT_LOGONHOURS 0x10000000
#define MASK_ALWAYS_GOOD 0x0000001F
#define MASK_USER_GOOD 0x00401F00
@@ -120,6 +121,9 @@
if (!sam_pwent) return -1;
if (verbosity) {
+ pstring temp;
+ const uint8 *hours;
+
printf ("Unix username: %s\n", pdb_get_username(sam_pwent));
printf ("NT username: %s\n", pdb_get_nt_username(sam_pwent));
printf ("Account Flags: %s\n", pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent), NEW_PW_FORMAT_SPACE_PADDED_LEN));
@@ -160,6 +164,10 @@
printf ("Bad password count : %d\n",
pdb_get_bad_password_count(sam_pwent));
+ hours = pdb_get_hours(sam_pwent);
+ pdb_sethexhours(temp, (const char *)hours);
+ printf ("Logon hours : %s\n", temp);
+
} else if (smbpwdstyle) {
char lm_passwd[33];
char nt_passwd[33];
@@ -298,7 +306,7 @@
const char *drive, const char *script,
const char *profile, const char *account_control,
const char *user_sid, const char *group_sid,
- const BOOL badpw)
+ const BOOL badpw, const BOOL hours)
{
SAM_ACCOUNT *sam_pwent=NULL;
BOOL ret;
@@ -374,6 +382,16 @@
pdb_set_bad_password_count(sam_pwent, 0, PDB_CHANGED);
pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED);
}
+
+ if (hours) {
+ uint8 hours[MAX_HOURS_LEN];
+ uint32 hours_len;
+
+ hours_len = pdb_get_hours_len(sam_pwent);
+ memset(hours, 0xff, hours_len);
+
+ pdb_set_hours(sam_pwent, hours, PDB_CHANGED);
+ }
if (NT_STATUS_IS_OK(in->pdb_update_sam_account (in, sam_pwent)))
print_user_info (in, username, True, False);
@@ -626,6 +644,7 @@
static long int account_policy_value = 0;
BOOL account_policy_value_set = False;
static BOOL badpw_reset = False;
+ static BOOL hours_reset = False;
struct pdb_context *bin;
struct pdb_context *bout;
@@ -657,6 +676,7 @@
{"account-control", 'c', POPT_ARG_STRING, &account_control, 0, "Values of account control", NULL},
{"force-initialized-passwords", 0, POPT_ARG_NONE, &force_initialised_password, 0, "Force initialization of corrupt password strings in a passdb backend", NULL},
{"bad-password-count-reset", 'z', POPT_ARG_NONE, &badpw_reset, 0, "reset bad password count", NULL},
+ {"logon-hours-reset", 'Z', POPT_ARG_NONE, &hours_reset, 0, "reset logon hours", NULL},
POPT_COMMON_SAMBA
POPT_TABLEEND
};
@@ -710,7 +730,8 @@
(account_policy_value_set ? BIT_ACCPOLVAL : 0) +
(backend_in ? BIT_IMPORT : 0) +
(backend_out ? BIT_EXPORT : 0) +
- (badpw_reset ? BIT_BADPWRESET : 0);
+ (badpw_reset ? BIT_BADPWRESET : 0) +
+ (hours_reset ? BIT_LOGONHOURS : 0);
if (setparms & BIT_BACKEND) {
if (!NT_STATUS_IS_OK(make_pdb_context_string(&bdef, backend))) {
@@ -813,6 +834,12 @@
checkparms |= BIT_MODIFY;
checkparms &= ~BIT_BADPWRESET;
}
+
+ /* if logon hours is reset, must modify */
+ if (checkparms & BIT_LOGONHOURS) {
+ checkparms |= BIT_MODIFY;
+ checkparms &= ~BIT_LOGONHOURS;
+ }
/* account operation */
if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) {
@@ -850,7 +877,7 @@
logon_script,
profile_path, account_control,
user_sid, group_sid,
- badpw_reset);
+ badpw_reset, hours_reset);
}
}
More information about the samba-technical
mailing list