diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/auth/auth.c | 10 | ||||
-rw-r--r-- | source4/auth/auth.h | 29 | ||||
-rw-r--r-- | source4/auth/auth_ntlmssp.c | 2 | ||||
-rw-r--r-- | source4/auth/auth_sam.c | 68 | ||||
-rw-r--r-- | source4/auth/auth_util.c | 149 | ||||
-rw-r--r-- | source4/librpc/idl/netlogon.idl | 34 | ||||
-rw-r--r-- | source4/rpc_server/netlogon/dcerpc_netlogon.c | 133 | ||||
-rw-r--r-- | source4/torture/rpc/netlogon.c | 12 |
8 files changed, 302 insertions, 135 deletions
diff --git a/source4/auth/auth.c b/source4/auth/auth.c index f22ca348e6..60807deac4 100644 --- a/source4/auth/auth.c +++ b/source4/auth/auth.c @@ -170,6 +170,11 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, 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; @@ -251,10 +256,10 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, 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) { @@ -290,7 +295,6 @@ static NTSTATUS make_auth_context(struct auth_context **auth_context) (*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; } diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 8ef8ffcc18..dea068f078 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -71,20 +71,22 @@ struct auth_serversupplied_info 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; @@ -121,7 +123,6 @@ struct auth_context { 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 diff --git a/source4/auth/auth_ntlmssp.c b/source4/auth/auth_ntlmssp.c index 50ec07fe41..622a89c939 100644 --- a/source4/auth/auth_ntlmssp.c +++ b/source4/auth/auth_ntlmssp.c @@ -174,7 +174,7 @@ void auth_ntlmssp_end(struct auth_ntlmssp_state **auth_ntlmssp_state) 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); diff --git a/source4/auth/auth_sam.c b/source4/auth/auth_sam.c index 2481b97ce6..e7f428c922 100644 --- a/source4/auth/auth_sam.c +++ b/source4/auth/auth_sam.c @@ -196,6 +196,19 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, "accountExpires", "objectSid", "userWorkstations", + + /* required for server_info, not access control: */ + "sAMAaccountName", + "displayName", + "scriptPath", + "profilePath", + "homeDirectory", + "homeDrive", + "lastLogon", + "lastLogoff", + "accountExpires", + "badPwdCount", + "logonCount", NULL, }; @@ -346,14 +359,67 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, (*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; } diff --git a/source4/auth/auth_util.c b/source4/auth/auth_util.c index 8fc1d2ac59..c505d4a88e 100644 --- a/source4/auth/auth_util.c +++ b/source4/auth/auth_util.c @@ -157,14 +157,13 @@ NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info, 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); @@ -177,11 +176,9 @@ BOOL make_user_info_netlogon_network(struct auth_usersupplied_info **user_info, 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; } /**************************************************************************** @@ -189,99 +186,51 @@ BOOL make_user_info_netlogon_network(struct auth_usersupplied_info **user_info, 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; } @@ -532,6 +481,26 @@ NTSTATUS make_server_info_guest(struct auth_serversupplied_info **server_info) (*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; } diff --git a/source4/librpc/idl/netlogon.idl b/source4/librpc/idl/netlogon.idl index 35a10d8602..a3e1e804dc 100644 --- a/source4/librpc/idl/netlogon.idl +++ b/source4/librpc/idl/netlogon.idl @@ -114,16 +114,16 @@ interface netlogon } 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; @@ -146,12 +146,12 @@ interface netlogon } 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; @@ -164,7 +164,7 @@ interface netlogon 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; @@ -180,12 +180,12 @@ interface netlogon } 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; @@ -198,7 +198,7 @@ interface netlogon 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; diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 5c5e812805..bfc5e3b759 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -47,9 +47,10 @@ static void netlogon_unbind(struct dcesrv_connection *conn, const struct dcesrv_ { struct server_pipe_state *pipe_state = conn->private; - if (pipe_state) + if (pipe_state) { talloc_destroy(pipe_state->mem_ctx); - + } + conn->private = NULL; } @@ -424,12 +425,138 @@ static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX */ + +#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 diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index 68571a2f6c..a0b49d91eb 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -306,12 +306,12 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, 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); |