DEBUG(3, ("check_ntlm_password: mapped user is: [%s]\\[%s]@[%s]\n",
user_info->domain.str, user_info->internal_username.str, user_info->wksta_name.str));
+ if (auth_context->challenge.length == 0) {
+ /* get a challenge, if we have not asked for one yet */
+ get_ntlm_challenge(auth_context);
+ }
+
if (auth_context->challenge.length != 8) {
DEBUG(0, ("check_ntlm_password: Invalid challenge stored for this auth context - cannot continue\n"));
return NT_STATUS_LOGON_FAILURE;
Clear out a auth_context, and destroy the attached TALLOC_CTX
***************************************************************************/
-static void free_auth_context(struct auth_context **auth_context)
+void free_auth_context(struct auth_context **auth_context)
{
struct auth_methods *auth_method;
-
+
if (*auth_context) {
/* Free private data of context's authentication methods */
for (auth_method = (*auth_context)->auth_method_list; auth_method; auth_method = auth_method->next) {
(*auth_context)->mem_ctx = mem_ctx;
(*auth_context)->check_ntlm_password = check_ntlm_password;
(*auth_context)->get_ntlm_challenge = get_ntlm_challenge;
- (*auth_context)->free = free_auth_context;
return NT_STATUS_OK;
}
DATA_BLOB user_session_key;
DATA_BLOB lm_session_key;
- char *account_name;
- char *full_name;
- char *logon_script;
- char *profile_path;
- char *home_dir;
- char *home_drive;
+ const char *account_name;
+ const char *domain;
+
+ const char *full_name;
+ const char *logon_script;
+ const char *profile_path;
+ const char *home_directory;
+ const char *home_drive;
+
+ NTTIME last_logon;
+ NTTIME last_logoff;
+ NTTIME acct_expiry;
+ NTTIME last_password_change;
+ NTTIME allow_password_change;
+ NTTIME force_password_change;
- NTTIME logon_time;
- NTTIME logoff_time;
- NTTIME kickoff_time;
- NTTIME password_last_set;
- NTTIME password_can_change;
- NTTIME password_must_change;
-
uint16 logon_count;
uint16 bad_password_count;
const struct auth_usersupplied_info *user_info,
struct auth_serversupplied_info **server_info);
NTSTATUS (*nt_status_squash)(NTSTATUS nt_status);
- void (*free)(struct auth_context **auth_context);
};
struct auth_methods
ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state);
}
if ((*auth_ntlmssp_state)->auth_context) {
- ((*auth_ntlmssp_state)->auth_context->free)(&(*auth_ntlmssp_state)->auth_context);
+ free_auth_context(&(*auth_ntlmssp_state)->auth_context);
}
if ((*auth_ntlmssp_state)->server_info) {
free_server_info(&(*auth_ntlmssp_state)->server_info);
"accountExpires",
"objectSid",
"userWorkstations",
+
+ /* required for server_info, not access control: */
+ "sAMAaccountName",
+ "displayName",
+ "scriptPath",
+ "profilePath",
+ "homeDirectory",
+ "homeDrive",
+ "lastLogon",
+ "lastLogoff",
+ "accountExpires",
+ "badPwdCount",
+ "logonCount",
NULL,
};
(*server_info)->n_domain_groups = group_ret;
(*server_info)->domain_groups = groupSIDs;
-
}
+ (*server_info)->account_name
+ = talloc_strdup((*server_info)->mem_ctx,
+ samdb_result_string(msgs[0], "sAMAccountName", ""));
+
+ (*server_info)->domain
+ = talloc_strdup((*server_info)->mem_ctx,
+ samdb_result_string(msgs_domain[0], "name", ""));
+
+ (*server_info)->full_name
+ = talloc_strdup((*server_info)->mem_ctx,
+ samdb_result_string(msgs[0], "displayName", ""));
+
+ (*server_info)->logon_script
+ = talloc_strdup((*server_info)->mem_ctx,
+ samdb_result_string(msgs[0], "scriptPath", ""));
+ (*server_info)->profile_path
+ = talloc_strdup((*server_info)->mem_ctx,
+ samdb_result_string(msgs[0], "profilePath", ""));
+ (*server_info)->home_directory
+ = talloc_strdup((*server_info)->mem_ctx,
+ samdb_result_string(msgs[0], "homeDirectory", ""));
+
+ (*server_info)->home_drive
+ = talloc_strdup((*server_info)->mem_ctx,
+ 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,
+ domain_dn, msgs[0], "pwdLastSet");
+ (*server_info)->allow_password_change
+ = samdb_result_force_password_change(sam_ctx, mem_ctx,
+ domain_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;
(*server_info)->user_session_key = user_sess_key;
(*server_info)->lm_session_key = lm_sess_key;
+ 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)->mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ samdb_close(sam_ctx);
+
return nt_status;
}
Decrypt and encrypt the passwords.
****************************************************************************/
-BOOL make_user_info_netlogon_network(struct auth_usersupplied_info **user_info,
+NTSTATUS make_user_info_netlogon_network(struct auth_usersupplied_info **user_info,
const char *smb_name,
const char *client_domain,
const char *wksta_name,
const uint8_t *lm_network_password, int lm_password_len,
const uint8_t *nt_network_password, int nt_password_len)
{
- BOOL ret;
NTSTATUS nt_status;
DATA_BLOB lm_blob = data_blob(lm_network_password, lm_password_len);
DATA_BLOB nt_blob = data_blob(nt_network_password, nt_password_len);
NULL, NULL, NULL,
True);
- ret = NT_STATUS_IS_OK(nt_status) ? True : False;
-
data_blob_free(&lm_blob);
data_blob_free(&nt_blob);
- return ret;
+ return nt_status;
}
/****************************************************************************
Decrypt and encrypt the passwords.
****************************************************************************/
-BOOL make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
- const char *smb_name,
- const char *client_domain,
- const char *wksta_name,
- const uint8_t chal[8],
- const uint8_t lm_interactive_password[16],
- const uint8_t nt_interactive_password[16],
- const uint8_t *dc_sess_key)
+NTSTATUS make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
+ const char *smb_name,
+ const char *client_domain,
+ const char *wksta_name,
+ const uint8_t chal[8],
+ const struct samr_Password *lm_interactive_password,
+ const struct samr_Password *nt_interactive_password)
{
- char lm_password[16];
- char nt_password[16];
+ NTSTATUS nt_status;
+ DATA_BLOB local_lm_blob;
+ DATA_BLOB local_nt_blob;
+
+ DATA_BLOB lm_interactive_blob;
+ DATA_BLOB nt_interactive_blob;
uint8_t local_lm_response[24];
uint8_t local_nt_response[24];
- uint8_t key[16];
-
- ZERO_STRUCT(key);
- memcpy(key, dc_sess_key, 8);
-
- if (lm_interactive_password) memcpy(lm_password, lm_interactive_password, sizeof(lm_password));
- if (nt_interactive_password) memcpy(nt_password, nt_interactive_password, sizeof(nt_password));
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("key:"));
- dump_data(100, (char *)key, sizeof(key));
- DEBUG(100,("lm owf password:"));
- dump_data(100, lm_password, sizeof(lm_password));
+ SMBOWFencrypt(lm_interactive_password->hash, chal, local_lm_response);
+ SMBOWFencrypt(nt_interactive_password->hash, chal, local_nt_response);
- DEBUG(100,("nt owf password:"));
- dump_data(100, nt_password, sizeof(nt_password));
-#endif
+ local_lm_blob = data_blob(local_lm_response,
+ sizeof(local_lm_response));
+ lm_interactive_blob = data_blob(lm_interactive_password,
+ sizeof(lm_interactive_password));
- if (lm_interactive_password)
- arcfour_crypt((uint8_t *)lm_password, key, sizeof(lm_password));
-
- if (nt_interactive_password)
- arcfour_crypt((uint8_t *)nt_password, key, sizeof(nt_password));
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("decrypt of lm owf password:"));
- dump_data(100, lm_password, sizeof(lm_password));
-
- DEBUG(100,("decrypt of nt owf password:"));
- dump_data(100, nt_password, sizeof(nt_password));
-#endif
+ local_nt_blob = data_blob(local_nt_response,
+ sizeof(local_nt_response));
+ nt_interactive_blob = data_blob(nt_interactive_password,
+ sizeof(nt_interactive_password));
- if (lm_interactive_password)
- SMBOWFencrypt((const uint8_t *)lm_password, chal, local_lm_response);
-
- if (nt_interactive_password)
- SMBOWFencrypt((const uint8_t *)nt_password, chal, local_nt_response);
+ nt_status = make_user_info_map(user_info,
+ smb_name, client_domain,
+ wksta_name,
+ &local_lm_blob,
+ &local_nt_blob,
+ &lm_interactive_blob,
+ &nt_interactive_blob,
+ NULL,
+ True);
- /* Password info paranoia */
- ZERO_STRUCT(key);
-
- {
- BOOL ret;
- NTSTATUS nt_status;
- DATA_BLOB local_lm_blob;
- DATA_BLOB local_nt_blob;
-
- DATA_BLOB lm_interactive_blob;
- DATA_BLOB nt_interactive_blob;
-
- if (lm_interactive_password) {
- local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
- lm_interactive_blob = data_blob(lm_password, sizeof(lm_password));
- ZERO_STRUCT(lm_password);
- }
-
- if (nt_interactive_password) {
- local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
- nt_interactive_blob = data_blob(nt_password, sizeof(nt_password));
- ZERO_STRUCT(nt_password);
- }
-
- nt_status = make_user_info_map(user_info,
- smb_name, client_domain,
- wksta_name,
- lm_interactive_password ? &local_lm_blob : NULL,
- nt_interactive_password ? &local_nt_blob : NULL,
- lm_interactive_password ? &lm_interactive_blob : NULL,
- nt_interactive_password ? &nt_interactive_blob : NULL,
- NULL,
- True);
-
- ret = NT_STATUS_IS_OK(nt_status) ? True : False;
- data_blob_free(&local_lm_blob);
- data_blob_free(&local_nt_blob);
- data_blob_free(&lm_interactive_blob);
- data_blob_free(&nt_interactive_blob);
- return ret;
- }
+ data_blob_free(&local_lm_blob);
+ data_blob_free(&local_nt_blob);
+ data_blob_free(&lm_interactive_blob);
+ data_blob_free(&nt_interactive_blob);
+ return nt_status;
}
(*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
(*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
+ (*server_info)->account_name = "";
+ (*server_info)->domain = "";
+ (*server_info)->full_name = "Anonymous";
+ (*server_info)->logon_script = "";
+ (*server_info)->profile_path = "";
+ (*server_info)->home_directory = "";
+ (*server_info)->home_drive = "";
+
+ (*server_info)->last_logon = 0;
+ (*server_info)->last_logoff = 0;
+ (*server_info)->acct_expiry = 0;
+ (*server_info)->last_password_change = 0;
+ (*server_info)->allow_password_change = 0;
+ (*server_info)->force_password_change = 0;
+
+ (*server_info)->logon_count = 0;
+ (*server_info)->bad_password_count = 0;
+
+ (*server_info)->acct_flags = ACB_NORMAL;
+
return nt_status;
}
} netr_ChallengeResponse;
typedef [flag(NDR_PAHEX)] struct {
- netr_IdentityInfo logon_info;
+ netr_IdentityInfo identity_info;
uint8 challenge[8];
netr_ChallengeResponse nt;
netr_ChallengeResponse lm;
} netr_NetworkInfo;
typedef union {
- [case(1)] netr_PasswordInfo *interactive;
+ [case(1)] netr_PasswordInfo *password;
[case(2)] netr_NetworkInfo *network;
- [case(3)] netr_PasswordInfo *service;
+ [case(3)] netr_PasswordInfo *password;
[case(6)] netr_NetworkInfo *network;
} netr_LogonLevel;
} netr_LMSessionKey;
typedef struct {
- NTTIME logon_time;
- NTTIME logoff_time;
- NTTIME kickoff_time;
- NTTIME password_last_set;
- NTTIME password_can_change;
- NTTIME password_must_change;
+ NTTIME last_logon;
+ NTTIME last_logoff;
+ NTTIME acct_expiry;
+ NTTIME last_password_change;
+ NTTIME allow_password_change;
+ NTTIME force_password_change;
netr_String account_name;
netr_String full_name;
netr_String logon_script;
uint32 primary_gid;
uint32 group_count;
[size_is(group_count)] netr_GroupMembership *groupids;
- uint32 user_flags;
+ uint32 acct_flags;
netr_UserSessionKey key;
netr_String logon_server;
netr_String domain;
} netr_SidAttr;
typedef struct {
- NTTIME logon_time;
- NTTIME logoff_time;
- NTTIME kickoff_time;
- NTTIME password_last_set;
- NTTIME password_can_change;
- NTTIME password_must_change;
+ NTTIME last_logon;
+ NTTIME last_logoff;
+ NTTIME acct_expiry;
+ NTTIME last_password_change;
+ NTTIME allow_password_change;
+ NTTIME force_password_change;
netr_String account_name;
netr_String full_name;
netr_String logon_script;
uint32 primary_gid;
uint32 group_count;
[size_is(group_count)] netr_GroupMembership *groupids;
- uint32 user_flags;
+ uint32 acct_flags;
netr_UserSessionKey key;
netr_String logon_server;
netr_String domain;
{
struct server_pipe_state *pipe_state = conn->private;
- if (pipe_state)
+ if (pipe_state) {
talloc_destroy(pipe_state->mem_ctx);
-
+ }
+
conn->private = NULL;
}
*/
+
+#if 0
+
+static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct netr_LogonSamLogon *r)
+{
+ struct server_pipe_state *pipe_state = dce_call->conn->private;
+
+ struct auth_context *auth_context;
+ struct auth_usersupplied_info *user_info;
+ struct auth_serversupplied_info *server_info;
+ NTSTATUS nt_status;
+ const uint8_t *chal;
+
+
+ switch (r->in.logon_level) {
+ case 1:
+ case 3:
+ creds_arcfour_crypt(pipe_state->creds,
+ r->in.logon.password->lmpassword.hash,
+ sizeof(r->in.logon.password->lmpassword.hash));
+ creds_arcfour_crypt(pipe_state->creds,
+ r->in.logon.password->ntpassword.hash,
+ sizeof(r->in.logon.password->ntpassword.hash));
+
+ nt_status = make_auth_context_subsystem(&auth_context);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
+
+ chal = auth_context->get_ntlm_challenge(auth_context);
+ nt_status = make_user_info_netlogon_interactive(&user_info,
+ r->in.logon.password->identity_info.account_name.string,
+ r->in.logon.password->identity_info.domain_name.string,
+ r->in.logon.password->identity_info.workstation.string,
+ chal,
+ &r->in.logon.password->lmpassword,
+ &r->in.logon.password->ntpassword);
+ break;
+
+ case 2:
+ case 6:
+ nt_status = make_auth_context_fixed(&auth_context, r->in.logon.network->challenge);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
+
+ nt_status = make_user_info_netlogon_network(&user_info,
+ r->in.logon.network->identity_info.account_name.string,
+ r->in.logon.network->identity_info.domain_name.string,
+ r->in.logon.network->identity_info.workstation.string,
+ r->in.logon.network->nt.data, r->in.logon.network->nt.length,
+ r->in.logon.network->lm.data, r->in.logon.network->lm.length);
+ break;
+ default:
+ free_auth_context(&auth_context);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
+
+ nt_status = auth_context->check_ntlm_password(auth_context,
+ user_info,
+ &server_info);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ free_auth_context(&auth_context);
+ return nt_status;
+ }
+ free_auth_context(&auth_context);
+
+ switch (r->in.validation_level) {
+ case 2:
+ {
+ struct netr_SamInfo *sam;
+ sam = talloc_p(mem_ctx, struct netr_SamInfo);
+ r->out.validation.sam = sam;
+
+ sam->last_logon = server_info->last_logon;
+ sam->last_logoff = server_info->last_logoff;
+ sam->acct_expiry = server_info->acct_expiry;
+ sam->last_password_change = server_info->last_password_change;
+ sam->allow_password_change = server_info->allow_password_change;
+ sam->force_password_change = server_info->force_password_change;
+
+ sam->account_name.string = talloc_strdup(mem_ctx, server_info->account_name);
+ sam->full_name.string = talloc_strdup(mem_ctx, server_info->full_name);
+ sam->logon_script.string = talloc_strdup(mem_ctx, server_info->account_name);
+ sam->profile_path.string = talloc_strdup(mem_ctx, server_info->profile_path);
+ sam->home_directory.string = talloc_strdup(mem_ctx, server_info->home_directory);
+ sam->home_drive.string = talloc_strdup(mem_ctx, server_info->home_drive);
+
+ sam->logon_count = server_info->logon_count;
+ sam->bad_password_count = sam->bad_password_count;
+ sam->rid = server_info->user_sid->sub_auths[server_info->user_sid->num_auths-1];
+ sam->primary_gid = server_info->primary_group_sid->sub_auths[server_info->primary_group_sid->num_auths-1];
+ sam->group_count = 0;
+ sam->groupids = NULL;
+
+ sam->acct_flags = server_info->acct_flags;
+
+ sam->domain.string = talloc_strdup(mem_ctx, server_info->domain);
+
+ /* need to finish */
+
+ break;
+ }
+ case 3:
+ {
+ struct netr_SamInfo2 *sam;
+ sam = talloc_p(mem_ctx, struct netr_SamInfo2);
+ r->out.validation.sam2 = sam;
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ r->out.authoritative = 1;
+
+ return NT_STATUS_OK;
+}
+#else
static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct netr_LogonSamLogon *r)
{
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
-
+#endif
/*
netr_LogonSamLogoff
samlogon_state->r.in.logon_level = levels[i];
samlogon_state->r.in.logon.network = &ninfo;
- ninfo.logon_info.domain_name.string = lp_workgroup();
- ninfo.logon_info.parameter_control = 0;
- ninfo.logon_info.logon_id_low = 0;
- ninfo.logon_info.logon_id_high = 0;
- ninfo.logon_info.account_name.string = samlogon_state->account_name;
- ninfo.logon_info.workstation.string = TEST_MACHINE_NAME;
+ ninfo.identity_info.domain_name.string = lp_workgroup();
+ ninfo.identity_info.parameter_control = 0;
+ ninfo.identity_info.logon_id_low = 0;
+ ninfo.identity_info.logon_id_high = 0;
+ ninfo.identity_info.account_name.string = samlogon_state->account_name;
+ ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
memcpy(ninfo.challenge, chall->data, 8);