summaryrefslogtreecommitdiff
path: root/source4/auth/auth_sam.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/auth/auth_sam.c')
-rw-r--r--source4/auth/auth_sam.c129
1 files changed, 100 insertions, 29 deletions
diff --git a/source4/auth/auth_sam.c b/source4/auth/auth_sam.c
index 681907e74a..d7e4e97826 100644
--- a/source4/auth/auth_sam.c
+++ b/source4/auth/auth_sam.c
@@ -40,17 +40,20 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
{
if (acct_flags & ACB_PWNOTREQ) {
if (lp_null_passwords()) {
- DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", username));
+ DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n",
+ username));
return NT_STATUS_OK;
} else {
- DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", username));
+ DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n",
+ username));
return NT_STATUS_LOGON_FAILURE;
}
}
return ntlm_password_check(mem_ctx, &auth_context->challenge,
&user_info->lm_resp, &user_info->nt_resp,
- &user_info->lm_interactive_pwd, &user_info->nt_interactive_pwd,
+ &user_info->lm_interactive_pwd,
+ &user_info->nt_interactive_pwd,
username,
user_info->smb_name.str,
user_info->client_domain.str,
@@ -66,12 +69,12 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
const char *username,
uint16 acct_flags,
- struct ldb_message **msgs,
+ NTTIME *acct_expiry,
+ NTTIME *must_change_time,
+ NTTIME *last_set_time,
+ const char *workstation_list,
const auth_usersupplied_info *user_info)
{
- char *workstation_list;
- time_t kickoff_time;
-
DEBUG(4,("sam_account_ok: Checking SMB password for user %s\n", username));
/* Quit if the account was disabled. */
@@ -86,41 +89,37 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
return NT_STATUS_ACCOUNT_LOCKED_OUT;
}
-#if 0
/* Test account expire time */
- kickoff_time = pdb_get_kickoff_time(sampass);
- if (kickoff_time != 0 && time(NULL) > kickoff_time) {
+ if (!nt_time_is_zero(acct_expiry) && time(NULL) > nt_time_to_unix(acct_expiry)) {
DEBUG(1,("sam_account_ok: Account for user '%s' has expired.\n", username));
- DEBUG(3,("sam_account_ok: Account expired at '%ld' unix time.\n", (long)kickoff_time));
+ DEBUG(3,("sam_account_ok: Account expired at '%s'.\n",
+ nt_time_string(mem_ctx, acct_expiry)));
return NT_STATUS_ACCOUNT_EXPIRED;
}
if (!(acct_flags & ACB_PWNOEXP)) {
- time_t must_change_time = pdb_get_pass_must_change_time(sampass);
- time_t last_set_time = pdb_get_pass_last_set_time(sampass);
/* check for immediate expiry "must change at next logon" */
- if (must_change_time == 0 && last_set_time != 0) {
- DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n", username));
+ if (nt_time_is_zero(must_change_time) && !nt_time_is_zero(last_set_time)) {
+ DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n",
+ username));
return NT_STATUS_PASSWORD_MUST_CHANGE;
}
/* check for expired password */
- if (must_change_time < time(NULL) && must_change_time != 0) {
- DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n", username));
- DEBUG(1,("sam_account_ok: Password expired at '%s' (%ld) unix time.\n", timestring(mem_ctx, must_change_time), (long)must_change_time));
+ if (!nt_time_is_zero(must_change_time) && nt_time_to_unix(must_change_time) < time(NULL)) {
+ DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n",
+ username));
+ DEBUG(1,("sam_account_ok: Password expired at '%s' unix time.\n",
+ nt_time_string(mem_ctx, must_change_time)));
return NT_STATUS_PASSWORD_EXPIRED;
}
}
/* Test workstation. Workstation list is comma separated. */
- workstation_list = talloc_strdup(mem_ctx, pdb_get_workstations(sampass));
- if (!workstation_list)
- return NT_STATUS_NO_MEMORY;
-
- if (*workstation_list) {
+ if (workstation_list && *workstation_list) {
BOOL invalid_ws = True;
const char *s = workstation_list;
@@ -129,6 +128,7 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
while (next_token(&s, tok, ",", sizeof(tok))) {
DEBUG(10,("sam_account_ok: checking for workstation match %s and %s (len=%d)\n",
tok, user_info->wksta_name.str, user_info->wksta_name.len));
+
if(strequal(tok, user_info->wksta_name.str)) {
invalid_ws = False;
break;
@@ -138,7 +138,7 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
if (invalid_ws)
return NT_STATUS_INVALID_WORKSTATION;
}
-#endif
+
if (acct_flags & ACB_DOMTRUST) {
DEBUG(2,("sam_account_ok: Domain trust account %s denied by server\n", username));
return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT;
@@ -170,10 +170,20 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
auth_serversupplied_info **server_info)
{
struct ldb_message **msgs;
+ struct ldb_message **msgs_domain;
void *sam_ctx;
- uint16 acct_flags;
char *username = user_info->internal_username.str;
- BOOL ret;
+ uint16 acct_flags;
+ const char *workstation_list;
+ NTTIME acct_expiry;
+ NTTIME must_change_time;
+ NTTIME last_set_time;
+
+ uint_t ret;
+ uint_t ret_domain;
+
+ const char *domain_dn;
+
NTSTATUS nt_status;
DATA_BLOB user_sess_key = data_blob(NULL, 0);
DATA_BLOB lm_sess_key = data_blob(NULL, 0);
@@ -183,6 +193,19 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
struct samr_Hash *lmPwdHash, *ntPwdHash;
uint_t num_lm, num_nt;
+ struct dom_sid *domain_sid;
+
+ const char *attrs[] = {"unicodePwd", "lmPwdHash", "ntPwdHash",
+ "sAMAcctFlags",
+ "pwdLastSet",
+ "accountExpires",
+ "objectSid",
+ "userWorkstations",
+ NULL,
+ };
+
+ const char *domain_attrs[] = {NULL};
+
if (!user_info || !auth_context) {
return NT_STATUS_UNSUCCESSFUL;
}
@@ -191,28 +214,59 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
- /* pull all the user attributes */
- ret = samdb_search(sam_ctx, mem_ctx, NULL, &msgs, NULL,
+ /* pull the user attributes */
+ ret = samdb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
"(&(sAMAccountName=%s)(objectclass=user))",
username);
if (ret == 0) {
DEBUG(3,("check_sam_security: Couldn't find user [%s] in passdb file.\n",
username));
+ samdb_close(sam_ctx);
return NT_STATUS_NO_SUCH_USER;
}
if (ret > 1) {
DEBUG(1,("Found %d records matching user [%s]\n", ret, username));
+ samdb_close(sam_ctx);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
+ domain_sid = dom_sid_parse_talloc(mem_ctx, samdb_result_string(msgs[0], "objectSid", NULL));
+ if (!domain_sid) {
+ samdb_close(sam_ctx);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ sid_split_rid(domain_sid, NULL);
+
+ /* find the domain's DN */
+ ret_domain = samdb_search(sam_ctx, mem_ctx, NULL, &msgs_domain, domain_attrs,
+ "(&(objectSid=%s)(objectclass=domain))",
+ dom_sid_string(mem_ctx, domain_sid));
+
+ if (ret_domain == 0) {
+ DEBUG(3,("check_sam_security: Couldn't find domain [%s] in passdb file.\n",
+ dom_sid_string(mem_ctx, domain_sid)));
+ samdb_close(sam_ctx);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ if (ret_domain > 1) {
+ DEBUG(1,("Found %d records matching domain [%s]\n", ret, dom_sid_string(mem_ctx, domain_sid)));
+ samdb_close(sam_ctx);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ domain_dn = msgs_domain[0]->dn;
+
acct_flags = samdb_result_acct_flags(msgs[0], "sAMAcctFlags");
/* Quit if the account was locked out. */
if (acct_flags & ACB_AUTOLOCK) {
DEBUG(3,("check_sam_security: Account for user %s was locked out.\n",
username));
+ samdb_close(sam_ctx);
return NT_STATUS_ACCOUNT_LOCKED_OUT;
}
@@ -258,17 +312,32 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
user_info, &user_sess_key, &lm_sess_key);
if (!NT_STATUS_IS_OK(nt_status)) {
+ samdb_close(sam_ctx);
return nt_status;
}
- nt_status = sam_account_ok(mem_ctx, username, acct_flags, msgs, user_info);
+ acct_expiry = samdb_result_nttime(msgs[0], "accountExpires", 0);
+ must_change_time = samdb_result_force_pwd_change(sam_ctx, mem_ctx,
+ domain_dn, msgs[0], "pwdLastSet");
+ last_set_time = samdb_result_nttime(msgs[0], "pwdLastSet", 0);
+
+ workstation_list = samdb_result_string(msgs[0], "userWorkstations", NULL);
+
+ nt_status = sam_account_ok(mem_ctx, username, acct_flags,
+ &acct_expiry,
+ &must_change_time,
+ &last_set_time,
+ workstation_list,
+ user_info);
if (!NT_STATUS_IS_OK(nt_status)) {
+ samdb_close(sam_ctx);
return nt_status;
}
if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info, username))) {
DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status)));
+ samdb_close(sam_ctx);
return nt_status;
}
@@ -292,6 +361,7 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
if (!(groupSIDs = talloc_realloc_p((*server_info)->mem_ctx, groupSIDs,
struct dom_sid *, group_ret))) {
talloc_destroy((*server_info)->mem_ctx);
+ samdb_close(sam_ctx);
return NT_STATUS_NO_MEMORY;
}
@@ -313,6 +383,7 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
False, &(*server_info)->ptok))) {
DEBUG(1,("check_sam_security: create_nt_user_token failed with '%s'\n", nt_errstr(nt_status)));
free_server_info(server_info);
+ samdb_close(sam_ctx);
return nt_status;
}
}