diff options
author | Stefan Metzmacher <metze@samba.org> | 2005-01-09 12:55:25 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:08:34 -0500 |
commit | 46a32687da249174a666d9166fccbe705c8beba0 (patch) | |
tree | 07a43ce2b630ea0a943c01ba4d631c9da18630c8 /source4/auth/auth_sam.c | |
parent | b61b22d73a0b0fb3322884e3712c89a52a47f56b (diff) | |
download | samba-46a32687da249174a666d9166fccbe705c8beba0.tar.gz samba-46a32687da249174a666d9166fccbe705c8beba0.tar.bz2 samba-46a32687da249174a666d9166fccbe705c8beba0.zip |
r4620: - add interface functions to the auth subsystem so that callers doesn't need to
use function pointers anymore
- make the module init much easier
- a lot of cleanups
don't try to read the diff in auth/ better read the new files
it passes test_echo.sh and test_rpc.sh
abartlet: please fix spelling fixes
metze
(This used to be commit 3c0d16b8236451f2cfd38fc3db8ae2906106d847)
Diffstat (limited to 'source4/auth/auth_sam.c')
-rw-r--r-- | source4/auth/auth_sam.c | 575 |
1 files changed, 263 insertions, 312 deletions
diff --git a/source4/auth/auth_sam.c b/source4/auth/auth_sam.c index a261fb223f..195cdeb06d 100644 --- a/source4/auth/auth_sam.c +++ b/source4/auth/auth_sam.c @@ -3,6 +3,7 @@ Password and authentication handling Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2004 Copyright (C) Gerald Carter 2003 + Copyright (C) Stefan Metzmacher 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,57 +26,52 @@ #include "auth/auth.h" #include "lib/ldb/include/ldb.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - /**************************************************************************** Do a specific test for an smb password being correct, given a smb_password and the lanman and NT responses. ****************************************************************************/ - -static NTSTATUS sam_password_ok(const struct auth_context *auth_context, - TALLOC_CTX *mem_ctx, - const char *username, - uint16_t acct_flags, - const struct samr_Password *lm_pwd, - const struct samr_Password *nt_pwd, - const struct auth_usersupplied_info *user_info, - DATA_BLOB *user_sess_key, - DATA_BLOB *lm_sess_key) +static NTSTATUS authsam_password_ok(const struct auth_context *auth_context, + TALLOC_CTX *mem_ctx, + uint16_t acct_flags, + const struct samr_Password *lm_pwd, + const struct samr_Password *nt_pwd, + const struct auth_usersupplied_info *user_info, + DATA_BLOB *user_sess_key, + DATA_BLOB *lm_sess_key) { NTSTATUS status; 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)); + user_info->account_name)); return NT_STATUS_OK; } else { DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", - username)); + user_info->account_name)); return NT_STATUS_LOGON_FAILURE; } } - status = ntlm_password_check(mem_ctx, &auth_context->challenge, - &user_info->lm_resp, &user_info->nt_resp, - &user_info->lm_interactive_password, - &user_info->nt_interactive_password, - username, - user_info->smb_name.str, - user_info->client_domain.str, - lm_pwd->hash, nt_pwd->hash, user_sess_key, lm_sess_key); - - if (NT_STATUS_IS_OK(status)) { - if (user_sess_key && user_sess_key->data) { - talloc_steal(auth_context, user_sess_key->data); - } - if (lm_sess_key && lm_sess_key->data) { - talloc_steal(auth_context, lm_sess_key->data); - } + status = ntlm_password_check(mem_ctx, &auth_context->challenge.data, + &user_info->lm_resp, &user_info->nt_resp, + &user_info->lm_interactive_password, + &user_info->nt_interactive_password, + user_info->account_name, + user_info->client.account_name, + user_info->client.domain_name, + lm_pwd->hash, nt_pwd->hash, + user_sess_key, lm_sess_key); + NT_STATUS_NOT_OK_RETURN(status); + + if (user_sess_key && user_sess_key->data) { + talloc_steal(auth_context, user_sess_key->data); + } + if (lm_sess_key && lm_sess_key->data) { + talloc_steal(auth_context, lm_sess_key->data); } - return status; + return NT_STATUS_OK; } @@ -83,59 +79,55 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, Do a specific test for a SAM_ACCOUNT being vaild for this connection (ie not disabled, expired and the like). ****************************************************************************/ - -static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx, - const char *username, - uint16_t acct_flags, - NTTIME *acct_expiry, - NTTIME *must_change_time, - NTTIME *last_set_time, - const char *workstation_list, - const struct auth_usersupplied_info *user_info) +static NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, + uint16_t acct_flags, + NTTIME acct_expiry, + NTTIME must_change_time, + NTTIME last_set_time, + const char *workstation_list, + const struct auth_usersupplied_info *user_info) { - DEBUG(4,("sam_account_ok: Checking SMB password for user %s\n", username)); + DEBUG(4,("authsam_account_ok: Checking SMB password for user %s\n", user_info->account_name)); /* Quit if the account was disabled. */ if (acct_flags & ACB_DISABLED) { - DEBUG(1,("sam_account_ok: Account for user '%s' was disabled.\n", username)); + DEBUG(1,("authsam_account_ok: Account for user '%s' was disabled.\n", user_info->account_name)); return NT_STATUS_ACCOUNT_DISABLED; } /* Quit if the account was locked out. */ if (acct_flags & ACB_AUTOLOCK) { - DEBUG(1,("sam_account_ok: Account for user %s was locked out.\n", username)); + DEBUG(1,("authsam_account_ok: Account for user %s was locked out.\n", user_info->account_name)); return NT_STATUS_ACCOUNT_LOCKED_OUT; } /* Test account expire time */ - if ((*acct_expiry) != -1 && 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 '%s'.\n", - nt_time_string(mem_ctx, *acct_expiry))); + if ((acct_expiry) != -1 && time(NULL) > nt_time_to_unix(acct_expiry)) { + DEBUG(1,("authsam_account_ok: Account for user '%s' has expired.\n", user_info->account_name)); + DEBUG(3,("authsam_account_ok: Account expired at '%s'.\n", + nt_time_string(mem_ctx, acct_expiry))); return NT_STATUS_ACCOUNT_EXPIRED; } if (!(acct_flags & ACB_PWNOEXP)) { - /* check for immediate expiry "must change at next logon" */ - if (*must_change_time == 0 && *last_set_time != 0) { + if (must_change_time == 0 && last_set_time != 0) { DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n", - username)); + user_info->account_name)); return NT_STATUS_PASSWORD_MUST_CHANGE; } /* check for expired password */ - if ((*must_change_time) != 0 && nt_time_to_unix(*must_change_time) < time(NULL)) { + if ((must_change_time) != 0 && nt_time_to_unix(must_change_time) < time(NULL)) { DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n", - username)); + user_info->account_name)); DEBUG(1,("sam_account_ok: Password expired at '%s' unix time.\n", - nt_time_string(mem_ctx, *must_change_time))); + nt_time_string(mem_ctx, must_change_time))); return NT_STATUS_PASSWORD_EXPIRED; } } /* Test workstation. Workstation list is comma separated. */ - if (workstation_list && *workstation_list) { BOOL invalid_ws = True; const char *s = workstation_list; @@ -143,35 +135,36 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx, fstring tok; 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)) { + DEBUG(10,("sam_account_ok: checking for workstation match '%s' and '%s'\n", + tok, user_info->workstation_name)); + + if (strequal(tok, user_info->workstation_name)) { invalid_ws = False; break; } } - - if (invalid_ws) + + if (invalid_ws) { return NT_STATUS_INVALID_WORKSTATION; + } } if (acct_flags & ACB_DOMTRUST) { - DEBUG(2,("sam_account_ok: Domain trust account %s denied by server\n", username)); + DEBUG(2,("sam_account_ok: Domain trust account %s denied by server\n", user_info->account_name)); return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT; } - + if (acct_flags & ACB_SVRTRUST) { - DEBUG(2,("sam_account_ok: Server trust account %s denied by server\n", username)); + DEBUG(2,("sam_account_ok: Server trust account %s denied by server\n", user_info->account_name)); return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT; } - + if (acct_flags & ACB_WSTRUST) { - DEBUG(4,("sam_account_ok: Wksta trust account %s denied by server\n", username)); + DEBUG(4,("sam_account_ok: Wksta trust account %s denied by server\n", user_info->account_name)); return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT; } - + return NT_STATUS_OK; } @@ -179,21 +172,21 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx, Look for the specified user in the sam, return ldb result structures ****************************************************************************/ -static NTSTATUS sam_search_user(const char *username, const char *domain, - TALLOC_CTX *mem_ctx, void *sam_ctx, - struct ldb_message ***ret_msgs, - struct ldb_message ***ret_msgs_domain) +static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, void *sam_ctx, + const char *account_name, + const char *domain_name, + struct ldb_message ***ret_msgs, + struct ldb_message ***ret_msgs_domain) { struct ldb_message **msgs; struct ldb_message **msgs_domain; - uint_t ret; - uint_t ret_domain; + int ret; + int ret_domain; const char *domain_dn = NULL; - const char *domain_sid; - const char *attrs[] = {"unicodePwd", "lmPwdHash", "ntPwdHash", + const char *attrs[] = {"unicodePwd", "lmPwdHash", "ntPwdHash", "userAccountControl", "pwdLastSet", "accountExpires", @@ -218,44 +211,52 @@ static NTSTATUS sam_search_user(const char *username, const char *domain, const char *domain_attrs[] = {"name", "objectSid"}; - if (domain) { + if (domain_name) { /* find the domain's DN */ ret_domain = samdb_search(sam_ctx, mem_ctx, NULL, &msgs_domain, domain_attrs, "(&(|(realm=%s)(name=%s))(objectclass=domain))", - domain, domain); - + domain_name, domain_name); + if (ret_domain == -1) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + if (ret_domain == 0) { - DEBUG(3,("check_sam_security: Couldn't find domain [%s] in passdb file.\n", - domain)); + DEBUG(3,("sam_search_user: Couldn't find domain [%s] in samdb.\n", + domain_name)); return NT_STATUS_NO_SUCH_USER; } - + if (ret_domain > 1) { DEBUG(0,("Found %d records matching domain [%s]\n", - ret_domain, domain)); + ret_domain, domain_name)); return NT_STATUS_INTERNAL_DB_CORRUPTION; } domain_dn = msgs_domain[0]->dn; - } + /* pull the user attributes */ ret = samdb_search(sam_ctx, mem_ctx, domain_dn, &msgs, attrs, "(&(sAMAccountName=%s)(objectclass=user))", - username); + account_name); + if (ret == -1) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } if (ret == 0) { - DEBUG(3,("check_sam_security: Couldn't find user [%s] in passdb file.\n", - username)); + DEBUG(3,("sam_search_user: Couldn't find user [%s] in samdb.\n", + account_name)); return NT_STATUS_NO_SUCH_USER; } if (ret > 1) { - DEBUG(0,("Found %d records matching user [%s]\n", ret, username)); + DEBUG(0,("Found %d records matching user [%s]\n", ret, account_name)); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - - if (!domain) { + + if (!domain_name) { + const char *domain_sid; + domain_sid = samdb_result_sid_prefix(mem_ctx, msgs[0], "objectSid"); if (!domain_sid) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -265,9 +266,12 @@ static NTSTATUS sam_search_user(const char *username, const char *domain, ret_domain = samdb_search(sam_ctx, mem_ctx, NULL, &msgs_domain, domain_attrs, "(&(objectSid=%s)(objectclass=domain))", domain_sid); + if (ret_domain == -1) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } if (ret_domain == 0) { - DEBUG(3,("check_sam_security: Couldn't find domain [%s] in passdb file.\n", + DEBUG(3,("check_sam_security: Couldn't find domain [%s] in passdb file.\n", domain_sid)); return NT_STATUS_NO_SUCH_USER; } @@ -277,56 +281,46 @@ static NTSTATUS sam_search_user(const char *username, const char *domain, ret_domain, domain_sid)); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - - domain_dn = msgs_domain[0]->dn; } + *ret_msgs = msgs; *ret_msgs_domain = msgs_domain; return NT_STATUS_OK; } -NTSTATUS sam_check_password(const struct auth_context *auth_context, - const char *username, - TALLOC_CTX *mem_ctx, void *sam_ctx, - struct ldb_message **msgs, - const char *domain_dn, - const struct auth_usersupplied_info *user_info, - DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) +static NTSTATUS authsam_authenticate(const struct auth_context *auth_context, + TALLOC_CTX *mem_ctx, void *sam_ctx, + struct ldb_message **msgs, + struct ldb_message **msgs_domain, + const struct auth_usersupplied_info *user_info, + DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) { - uint16_t acct_flags; const char *workstation_list; NTTIME acct_expiry; NTTIME must_change_time; NTTIME last_set_time; struct samr_Password *lm_pwd, *nt_pwd; - NTSTATUS nt_status; - + const char *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)); + user_info->account_name)); return NT_STATUS_ACCOUNT_LOCKED_OUT; } - if (!NT_STATUS_IS_OK(nt_status = samdb_result_passwords(mem_ctx, msgs[0], - &lm_pwd, &nt_pwd))) { - return nt_status; - } + nt_status = samdb_result_passwords(mem_ctx, msgs[0], &lm_pwd, &nt_pwd); + NT_STATUS_NOT_OK_RETURN(nt_status); - nt_status = sam_password_ok(auth_context, mem_ctx, - username, acct_flags, - lm_pwd, nt_pwd, - user_info, user_sess_key, lm_sess_key); - - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } + nt_status = authsam_password_ok(auth_context, mem_ctx, + acct_flags, lm_pwd, nt_pwd, + user_info, user_sess_key, lm_sess_key); + NT_STATUS_NOT_OK_RETURN(nt_status); acct_expiry = samdb_result_nttime(msgs[0], "accountExpires", 0); must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx, @@ -336,40 +330,34 @@ NTSTATUS sam_check_password(const struct auth_context *auth_context, 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); + nt_status = authsam_account_ok(mem_ctx, acct_flags, + acct_expiry, + must_change_time, + last_set_time, + workstation_list, + user_info); return nt_status; } -NTSTATUS sam_make_server_info(TALLOC_CTX *mem_ctx, void *sam_ctx, - struct ldb_message **msgs, struct ldb_message **msgs_domain, - struct auth_serversupplied_info **server_info) +static NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, void *sam_ctx, + struct ldb_message **msgs, + struct ldb_message **msgs_domain, + DATA_BLOB user_sess_key, DATA_BLOB lm_sess_key, + struct auth_serversupplied_info **_server_info) { - + struct auth_serversupplied_info *server_info; struct ldb_message **group_msgs; int group_ret; const char *group_attrs[3] = { "sAMAccountType", "objectSid", NULL }; /* find list of sids */ struct dom_sid **groupSIDs = NULL; - struct dom_sid *user_sid; + struct dom_sid *account_sid; struct dom_sid *primary_group_sid; - const char *sidstr; + const char *str; int i; uint_t rid; - - NTSTATUS nt_status; - if (!NT_STATUS_IS_OK(nt_status = make_server_info(mem_ctx, server_info, - samdb_result_string(msgs[0], "sAMAccountName", "")))) { - DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status))); - return nt_status; - } - group_ret = samdb_search(sam_ctx, mem_ctx, NULL, &group_msgs, group_attrs, "(&(member=%s)(sAMAccountType=*))", @@ -377,22 +365,29 @@ NTSTATUS sam_make_server_info(TALLOC_CTX *mem_ctx, void *sam_ctx, if (group_ret == -1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } + + server_info = talloc(mem_ctx, struct auth_serversupplied_info); + NT_STATUS_HAVE_NO_MEMORY(server_info); - if (group_ret > 0 && - !(groupSIDs = talloc_array(*server_info, struct dom_sid *, group_ret))) { - talloc_free(*server_info); - return NT_STATUS_NO_MEMORY; + if (group_ret > 0) { + groupSIDs = talloc_array(server_info, struct dom_sid *, group_ret); + NT_STATUS_HAVE_NO_MEMORY(groupSIDs); } - + /* Need to unroll some nested groups, but not aliases */ for (i = 0; i < group_ret; i++) { - sidstr = ldb_msg_find_string(group_msgs[i], "objectSid", NULL); - groupSIDs[i] = dom_sid_parse_talloc(*server_info, sidstr); + str = ldb_msg_find_string(group_msgs[i], "objectSid", NULL); + groupSIDs[i] = dom_sid_parse_talloc(groupSIDs, str); + NT_STATUS_HAVE_NO_MEMORY(groupSIDs[i]); } - - sidstr = ldb_msg_find_string(msgs[0], "objectSid", NULL); - user_sid = dom_sid_parse_talloc(*server_info, sidstr); - primary_group_sid = dom_sid_parse_talloc(*server_info, sidstr); + + str = ldb_msg_find_string(msgs[0], "objectSid", NULL); + account_sid = dom_sid_parse_talloc(server_info, str); + NT_STATUS_HAVE_NO_MEMORY(account_sid); + + primary_group_sid = dom_sid_dup(server_info, account_sid); + NT_STATUS_HAVE_NO_MEMORY(primary_group_sid); + rid = samdb_result_uint(msgs[0], "primaryGroupID", ~0); if (rid == ~0) { if (group_ret > 0) { @@ -403,71 +398,68 @@ NTSTATUS sam_make_server_info(TALLOC_CTX *mem_ctx, void *sam_ctx, } else { primary_group_sid->sub_auths[primary_group_sid->num_auths-1] = rid; } + + server_info->account_sid = account_sid; + server_info->primary_group_sid = primary_group_sid; - (*server_info)->user_sid = user_sid; - (*server_info)->primary_group_sid = primary_group_sid; - - (*server_info)->n_domain_groups = group_ret; - (*server_info)->domain_groups = groupSIDs; - - (*server_info)->account_name - = talloc_strdup(*server_info, - samdb_result_string(msgs[0], "sAMAccountName", "")); - - (*server_info)->domain - = talloc_strdup(*server_info, - samdb_result_string(msgs_domain[0], "name", "")); - - (*server_info)->full_name - = talloc_strdup(*server_info, - samdb_result_string(msgs[0], "displayName", "")); - - (*server_info)->logon_script - = talloc_strdup(*server_info, - samdb_result_string(msgs[0], "scriptPath", "")); - (*server_info)->profile_path - = talloc_strdup(*server_info, - samdb_result_string(msgs[0], "profilePath", "")); - (*server_info)->home_directory - = talloc_strdup(*server_info, - samdb_result_string(msgs[0], "homeDirectory", "")); - - (*server_info)->home_drive - = talloc_strdup(*server_info, - samdb_result_string(msgs[0], "homeDrive", "")); - - (*server_info)->last_logon = samdb_result_nttime(msgs[0], "lastLogon", 0); - (*server_info)->last_logoff = samdb_result_nttime(msgs[0], "lastLogoff", 0); - (*server_info)->acct_expiry = samdb_result_nttime(msgs[0], "accountExpires", 0); - (*server_info)->last_password_change = samdb_result_nttime(msgs[0], "pwdLastSet", 0); - (*server_info)->allow_password_change - = samdb_result_allow_password_change(sam_ctx, mem_ctx, - msgs_domain[0]->dn, msgs[0], "pwdLastSet"); - (*server_info)->force_password_change - = samdb_result_force_password_change(sam_ctx, mem_ctx, - msgs_domain[0]->dn, msgs[0], "pwdLastSet"); - - (*server_info)->logon_count = samdb_result_uint(msgs[0], "logonCount", 0); - (*server_info)->bad_password_count = samdb_result_uint(msgs[0], "badPwdCount", 0); - - (*server_info)->acct_flags = samdb_result_acct_flags(msgs[0], "userAccountControl"); - - (*server_info)->guest = False; - - if (!(*server_info)->account_name - || !(*server_info)->full_name - || !(*server_info)->logon_script - || !(*server_info)->profile_path - || !(*server_info)->home_directory - || !(*server_info)->home_drive) { - talloc_destroy(*server_info); - return NT_STATUS_NO_MEMORY; - } + server_info->n_domain_groups = group_ret; + server_info->domain_groups = groupSIDs; - return nt_status; + str = samdb_result_string(msgs[0], "sAMAccountName", ""); + server_info->account_name = talloc_strdup(server_info, str); + NT_STATUS_HAVE_NO_MEMORY(server_info->account_name); + + str = samdb_result_string(msgs_domain[0], "name", ""); + server_info->domain_name = talloc_strdup(server_info, str); + NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name); + + str = samdb_result_string(msgs[0], "displayName", ""); + server_info->full_name = talloc_strdup(server_info, str); + NT_STATUS_HAVE_NO_MEMORY(server_info->full_name); + + str = samdb_result_string(msgs[0], "scriptPath", ""); + server_info->logon_script = talloc_strdup(server_info, str); + NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script); + + str = samdb_result_string(msgs[0], "profilePath", ""); + server_info->profile_path = talloc_strdup(server_info, str); + NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path); + + str = samdb_result_string(msgs[0], "homeDirectory", ""); + server_info->home_directory = talloc_strdup(server_info, str); + NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory); + + str = samdb_result_string(msgs[0], "homeDrive", ""); + server_info->home_drive = talloc_strdup(server_info, str); + NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive); + + server_info->last_logon = samdb_result_nttime(msgs[0], "lastLogon", 0); + server_info->last_logoff = samdb_result_nttime(msgs[0], "lastLogoff", 0); + server_info->acct_expiry = samdb_result_nttime(msgs[0], "accountExpires", 0); + server_info->last_password_change = samdb_result_nttime(msgs[0], "pwdLastSet", 0); + + server_info->allow_password_change = samdb_result_allow_password_change(sam_ctx, mem_ctx, + msgs_domain[0]->dn, msgs[0], "pwdLastSet"); + server_info->force_password_change = samdb_result_force_password_change(sam_ctx, mem_ctx, + msgs_domain[0]->dn, msgs[0], "pwdLastSet"); + + server_info->logon_count = samdb_result_uint(msgs[0], "logonCount", 0); + server_info->bad_password_count = samdb_result_uint(msgs[0], "badPwdCount", 0); + + server_info->acct_flags = samdb_result_acct_flags(msgs[0], "userAccountControl"); + + server_info->user_session_key = user_sess_key; + server_info->lm_session_key = lm_sess_key; + + server_info->authenticated = True; + + *_server_info = server_info; + + return NT_STATUS_OK; } -NTSTATUS sam_get_server_info(const char *username, const char *domain, TALLOC_CTX *mem_ctx, +NTSTATUS sam_get_server_info(TALLOC_CTX *mem_ctx, const char *account_name, const char *domain_name, + DATA_BLOB user_sess_key, DATA_BLOB lm_sess_key, struct auth_serversupplied_info **server_info) { NTSTATUS nt_status; @@ -481,35 +473,33 @@ NTSTATUS sam_get_server_info(const char *username, const char *domain, TALLOC_CT return NT_STATUS_INVALID_SYSTEM_SERVICE; } - nt_status = sam_search_user(username, domain, mem_ctx, sam_ctx, &msgs, &domain_msgs); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } + nt_status = authsam_search_account(mem_ctx, sam_ctx, account_name, domain_name, &msgs, &domain_msgs); + NT_STATUS_NOT_OK_RETURN(nt_status); - nt_status = sam_make_server_info(mem_ctx, sam_ctx, msgs, domain_msgs, server_info); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } + nt_status = authsam_make_server_info(mem_ctx, sam_ctx, msgs, domain_msgs, + user_sess_key, lm_sess_key, + server_info); + NT_STATUS_NOT_OK_RETURN(nt_status); return NT_STATUS_OK; } -static NTSTATUS check_sam_security_internals(const struct auth_context *auth_context, - const char *domain, - TALLOC_CTX *mem_ctx, - const struct auth_usersupplied_info *user_info, - struct auth_serversupplied_info **server_info) +static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx, + TALLOC_CTX *mem_ctx, + const char *domain, + const struct auth_usersupplied_info *user_info, + struct auth_serversupplied_info **server_info) { - /* mark this as 'not for me' */ - NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED; - const char *username = user_info->internal_username.str; + NTSTATUS nt_status; + const char *account_name = user_info->account_name; struct ldb_message **msgs; struct ldb_message **domain_msgs; void *sam_ctx; DATA_BLOB user_sess_key, lm_sess_key; - if (!username || !*username) { - return nt_status; + if (!account_name || !*account_name) { + /* 'not for me' */ + return NT_STATUS_NOT_IMPLEMENTED; } sam_ctx = samdb_connect(mem_ctx); @@ -517,82 +507,52 @@ static NTSTATUS check_sam_security_internals(const struct auth_context *auth_con return NT_STATUS_INVALID_SYSTEM_SERVICE; } - nt_status = sam_search_user(username, domain, mem_ctx, sam_ctx, &msgs, &domain_msgs); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } + nt_status = authsam_search_account(mem_ctx, sam_ctx, account_name, domain, &msgs, &domain_msgs); + NT_STATUS_NOT_OK_RETURN(nt_status); - nt_status = sam_check_password(auth_context, username, mem_ctx, sam_ctx, msgs, domain_msgs[0]->dn, user_info, - &user_sess_key, &lm_sess_key); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - nt_status = sam_make_server_info(mem_ctx, sam_ctx, msgs, domain_msgs, server_info); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } + nt_status = authsam_authenticate(ctx->auth_ctx, mem_ctx, sam_ctx, msgs, domain_msgs, user_info, + &user_sess_key, &lm_sess_key); + NT_STATUS_NOT_OK_RETURN(nt_status); - talloc_reference(auth_context, *server_info); + nt_status = authsam_make_server_info(mem_ctx, sam_ctx, msgs, domain_msgs, + user_sess_key, lm_sess_key, + server_info); + NT_STATUS_NOT_OK_RETURN(nt_status); - (*server_info)->user_session_key = user_sess_key; - (*server_info)->lm_session_key = lm_sess_key; return NT_STATUS_OK; } -static NTSTATUS check_sam_security(const struct auth_context *auth_context, - void *my_private_data, - TALLOC_CTX *mem_ctx, - const struct auth_usersupplied_info *user_info, - struct auth_serversupplied_info **server_info) +static NTSTATUS authsam_ignoredomain_check_password(struct auth_method_context *ctx, + TALLOC_CTX *mem_ctx, + const struct auth_usersupplied_info *user_info, + struct auth_serversupplied_info **server_info) { - return check_sam_security_internals(auth_context, NULL, - mem_ctx, user_info, server_info); + return authsam_check_password_internals(ctx, mem_ctx, NULL, user_info, server_info); } -/* module initialisation */ -static NTSTATUS auth_init_sam_ignoredomain(struct auth_context *auth_context, - const char *param, - struct auth_methods **auth_method) -{ - if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; - } - - (*auth_method)->auth = check_sam_security; - (*auth_method)->name = "sam_ignoredomain"; - return NT_STATUS_OK; -} - - /**************************************************************************** Check SAM security (above) but with a few extra checks. ****************************************************************************/ - -static NTSTATUS check_samstrict_security(const struct auth_context *auth_context, - void *my_private_data, - TALLOC_CTX *mem_ctx, - const struct auth_usersupplied_info *user_info, - struct auth_serversupplied_info **server_info) +static NTSTATUS authsam_check_password(struct auth_method_context *ctx, + TALLOC_CTX *mem_ctx, + const struct auth_usersupplied_info *user_info, + struct auth_serversupplied_info **server_info) { const char *domain; BOOL is_local_name, is_my_domain; - if (!user_info || !auth_context) { - return NT_STATUS_LOGON_FAILURE; - } - - is_local_name = is_myname(user_info->domain.str); - is_my_domain = strequal(user_info->domain.str, lp_workgroup()); + is_local_name = is_myname(user_info->domain_name); + is_my_domain = strequal(user_info->domain_name, lp_workgroup()); /* check whether or not we service this domain/workgroup name */ - - switch ( lp_server_role() ) { + switch (lp_server_role()) { case ROLE_STANDALONE: + domain = lp_netbios_name(); + break; case ROLE_DOMAIN_MEMBER: - if ( !is_local_name ) { - DEBUG(6,("check_samstrict_security: %s is not one of my local names (%s)\n", - user_info->domain.str, (lp_server_role() == ROLE_DOMAIN_MEMBER + if (!is_local_name) { + DEBUG(6,("authsam_check_password: %s is not one of my local names (%s)\n", + user_info->domain_name, (lp_server_role() == ROLE_DOMAIN_MEMBER ? "ROLE_DOMAIN_MEMBER" : "ROLE_STANDALONE") )); return NT_STATUS_NOT_IMPLEMENTED; } @@ -600,55 +560,46 @@ static NTSTATUS check_samstrict_security(const struct auth_context *auth_context break; case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: - if ( !is_local_name && !is_my_domain ) { - DEBUG(6,("check_samstrict_security: %s is not one of my local names or domain name (DC)\n", - user_info->domain.str)); + if (!is_local_name && !is_my_domain) { + DEBUG(6,("authsam_check_password: %s is not one of my local names or domain name (DC)\n", + user_info->domain_name)); return NT_STATUS_NOT_IMPLEMENTED; } domain = lp_workgroup(); break; - default: /* name is ok */ - domain = user_info->domain.str; - break; + default: + DEBUG(6,("authsam_check_password: lp_server_role() has an undefined value\n")); + return NT_STATUS_NOT_IMPLEMENTED; } - - return check_sam_security_internals(auth_context, domain, mem_ctx, user_info, server_info); + + return authsam_check_password_internals(ctx, mem_ctx, domain, user_info, server_info); } -/* module initialisation */ -static NTSTATUS auth_init_sam(struct auth_context *auth_context, - const char *param, - struct auth_methods **auth_method) -{ - if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; - } +static const struct auth_operations sam_ignoredomain_ops = { + .name = "sam_ignoredomain", + .get_challenge = auth_get_challenge_not_implemented, + .check_password = authsam_ignoredomain_check_password +}; - (*auth_method)->auth = check_samstrict_security; - (*auth_method)->name = "sam"; - return NT_STATUS_OK; -} +static const struct auth_operations sam_ops = { + .name = "sam", + .get_challenge = auth_get_challenge_not_implemented, + .check_password = authsam_check_password +}; NTSTATUS auth_sam_init(void) { NTSTATUS ret; - struct auth_operations ops; - ops.name = "sam"; - ops.init = auth_init_sam; - ret = auth_register(&ops); + ret = auth_register(&sam_ops); if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' auth backend!\n", - ops.name)); + DEBUG(0,("Failed to register 'sam' auth backend!\n")); return ret; } - ops.name = "sam_ignoredomain"; - ops.init = auth_init_sam_ignoredomain; - ret = auth_register(&ops); + ret = auth_register(&sam_ignoredomain_ops); if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' auth backend!\n", - ops.name)); + DEBUG(0,("Failed to register 'sam_ignoredomain' auth backend!\n")); return ret; } |