#include "winbindd.h"
#include "../libcli/auth/libcli_auth.h"
#include "../librpc/gen_ndr/cli_samr.h"
+#include "smb_krb5.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
DOM_SID user_sid;
fstring sidstr;
- sid_copy(&user_sid, info3->base.domain_sid);
- sid_append_rid(&user_sid, info3->base.rid);
+ sid_compose(&user_sid, info3->base.domain_sid,
+ info3->base.rid);
sid_to_fstring(sidstr, &user_sid);
afsname = talloc_string_sub(mem_ctx, afsname,
"%s", sidstr);
return NT_STATUS_OK;
}
-NTSTATUS check_info3_in_group(struct netr_SamInfo3 *info3,
- const char *group_sid)
+static NTSTATUS check_info3_in_group(struct netr_SamInfo3 *info3,
+ const char *group_sid)
/**
* Check whether a user belongs to a group or list of groups.
*
return domain;
}
- if (is_myname(domain_name)) {
- DEBUG(3, ("Authentication for domain %s (local domain "
- "to this server) not supported at this "
- "stage\n", domain_name));
- return NULL;
+ if (strequal(domain_name, get_global_sam_name())) {
+ return find_domain_from_name_noinit(domain_name);
}
/* we can auth against trusted domains */
/****************************************************************
****************************************************************/
-NTSTATUS append_auth_data(struct winbindd_cli_state *state,
- struct netr_SamInfo3 *info3,
- const char *name_domain,
- const char *name_user)
+static NTSTATUS append_auth_data(struct winbindd_cli_state *state,
+ struct netr_SamInfo3 *info3,
+ const char *name_domain,
+ const char *name_user)
{
NTSTATUS result;
uint32_t flags = state->request->flags;
return NT_STATUS_OK;
}
-void winbindd_pam_auth(struct winbindd_cli_state *state)
-{
- struct winbindd_domain *domain;
- fstring name_domain, name_user, mapped_user;
- char *mapped = NULL;
- NTSTATUS result;
- NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
-
- /* Ensure null termination */
- state->request->data.auth.user
- [sizeof(state->request->data.auth.user)-1]='\0';
-
- /* Ensure null termination */
- state->request->data.auth.pass
- [sizeof(state->request->data.auth.pass)-1]='\0';
-
- DEBUG(3, ("[%5lu]: pam auth %s\n", (unsigned long)state->pid,
- state->request->data.auth.user));
-
- if (!check_request_flags(state->request->flags)) {
- result = NT_STATUS_INVALID_PARAMETER_MIX;
- goto done;
- }
-
- /* Parse domain and username */
-
- name_map_status = normalize_name_unmap(state->mem_ctx,
- state->request->data.auth.user,
- &mapped);
-
- /* If the name normalization didnt' actually do anything,
- just use the original name */
-
- if (NT_STATUS_IS_OK(name_map_status)
- ||NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) {
- fstrcpy(mapped_user, mapped);
- } else {
- fstrcpy(mapped_user, state->request->data.auth.user);
- }
-
- if (!canonicalize_username(mapped_user, name_domain, name_user)) {
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
-
- domain = find_auth_domain(state->request->flags, name_domain);
-
- if (domain == NULL) {
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
-
- sendto_domain(state, domain);
- return;
- done:
- set_auth_errors(state->response, result);
- DEBUG(5, ("Plain text authentication for %s returned %s "
- "(PAM: %d)\n",
- state->request->data.auth.user,
- state->response->data.auth.nt_status_string,
- state->response->data.auth.pam_error));
- request_error(state);
-}
-
static NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
struct winbindd_cli_state *state,
struct netr_SamInfo3 **info3)
return result;
}
+static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
+ const char *domain, const char *user,
+ const DATA_BLOB *challenge,
+ const DATA_BLOB *lm_resp,
+ const DATA_BLOB *nt_resp,
+ struct netr_SamInfo3 **pinfo3)
+{
+ struct auth_usersupplied_info *user_info = NULL;
+ struct auth_serversupplied_info *server_info = NULL;
+ struct netr_SamInfo3 *info3;
+ NTSTATUS status;
+
+ status = make_user_info(&user_info, user, user, domain, domain,
+ global_myname(), lm_resp, nt_resp, NULL, NULL,
+ NULL, True);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("make_user_info failed: %s\n", nt_errstr(status)));
+ return status;
+ }
+
+ status = check_sam_security(challenge, talloc_tos(), user_info,
+ &server_info);
+ free_user_info(&user_info);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("check_ntlm_password failed: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+
+ info3 = TALLOC_ZERO_P(mem_ctx, struct netr_SamInfo3);
+ if (info3 == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("serverinfo_to_SamInfo3 failed: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+
+ DEBUG(10, ("Authenticated user %s\\%s successfully\n", domain, user));
+ *pinfo3 = info3;
+ return NT_STATUS_OK;
+}
+
typedef NTSTATUS (*netlogon_fn_t)(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
uint32 logon_parameters,
int attempts = 0;
unsigned char local_lm_response[24];
unsigned char local_nt_response[24];
- struct winbindd_domain *contact_domain;
fstring name_domain, name_user;
bool retry;
NTSTATUS result;
/* do password magic */
+ generate_random_buffer(chal, sizeof(chal));
- generate_random_buffer(chal, 8);
if (lp_client_ntlmv2_auth()) {
DATA_BLOB server_chal;
DATA_BLOB names_blob;
sizeof(local_nt_response));
}
- /* what domain should we contact? */
-
- if ( IS_DC ) {
- if (!(contact_domain = find_domain_from_name(name_domain))) {
- DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
- state->request->data.auth.user, name_domain, name_user, name_domain));
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
-
- } else {
- if (is_myname(name_domain)) {
- DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain));
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
+ if (strequal(name_domain, get_global_sam_name())) {
+ DATA_BLOB chal_blob = data_blob_const(chal, sizeof(chal));
- contact_domain = find_our_domain();
+ result = winbindd_dual_auth_passdb(
+ state->mem_ctx, name_domain, name_user,
+ &chal_blob, &lm_resp, &nt_resp, info3);
+ goto done;
}
/* check authentication loop */
ZERO_STRUCTP(my_info3);
retry = false;
- result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
+ result = cm_connect_netlogon(domain, &netlogon_pipe);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
* -- abartlet 21 April 2008
*/
- logon_fn = contact_domain->can_do_samlogon_ex
+ logon_fn = domain->can_do_samlogon_ex
? rpccli_netlogon_sam_network_logon_ex
: rpccli_netlogon_sam_network_logon;
result = logon_fn(netlogon_pipe,
state->mem_ctx,
0,
- contact_domain->dcname, /* server name */
+ domain->dcname, /* server name */
name_user, /* user name */
name_domain, /* target domain */
global_myname(), /* workstation */
attempts += 1;
if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR)
- && contact_domain->can_do_samlogon_ex) {
+ && domain->can_do_samlogon_ex) {
DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
"retrying with NetSamLogon\n"));
- contact_domain->can_do_samlogon_ex = false;
+ domain->can_do_samlogon_ex = false;
retry = true;
continue;
}
might not yet have noticed that the DC has killed
our connection. */
- if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) {
+ if (!rpccli_is_connected(netlogon_pipe)) {
retry = true;
continue;
}
"password was changed and we didn't know it. "
"Killing connections to domain %s\n",
name_domain));
- invalidate_cm_connection(&contact_domain->conn);
+ invalidate_cm_connection(&domain->conn);
retry = true;
}
NTSTATUS status_tmp;
uint32 acct_flags;
- status_tmp = cm_connect_sam(contact_domain, state->mem_ctx,
+ status_tmp = cm_connect_sam(domain, state->mem_ctx,
&samr_pipe, &samr_domain_handle);
if (!NT_STATUS_IS_OK(status_tmp)) {
NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_EXPIRED) ||
NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) ||
NT_STATUS_EQUAL(result, NT_STATUS_WRONG_PASSWORD)) {
- goto process_result;
+ goto done;
}
if (state->request->flags & WBFLAG_PAM_FALLBACK_AFTER_KRB5) {
const char *name_user = NULL;
const char *name_domain = NULL;
const char *workstation;
- struct winbindd_domain *contact_domain;
int attempts = 0;
bool retry;
state->request->data.auth_crap.nt_resp_len);
}
- /* what domain should we contact? */
+ if (strequal(name_domain, get_global_sam_name())) {
+ DATA_BLOB chal_blob = data_blob_const(
+ state->request->data.auth_crap.chal,
+ sizeof(state->request->data.auth_crap.chal));
- if ( IS_DC ) {
- if (!(contact_domain = find_domain_from_name(name_domain))) {
- DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
- state->request->data.auth_crap.user, name_domain, name_user, name_domain));
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
- } else {
- if (is_myname(name_domain)) {
- DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain));
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
- contact_domain = find_our_domain();
+ result = winbindd_dual_auth_passdb(
+ state->mem_ctx, name_domain, name_user,
+ &chal_blob, &lm_resp, &nt_resp, &info3);
+ goto process_result;
}
do {
retry = false;
netlogon_pipe = NULL;
- result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
+ result = cm_connect_netlogon(domain, &netlogon_pipe);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n",
goto done;
}
- logon_fn = contact_domain->can_do_samlogon_ex
+ logon_fn = domain->can_do_samlogon_ex
? rpccli_netlogon_sam_network_logon_ex
: rpccli_netlogon_sam_network_logon;
result = logon_fn(netlogon_pipe,
state->mem_ctx,
state->request->data.auth_crap.logon_parameters,
- contact_domain->dcname,
+ domain->dcname,
name_user,
name_domain,
/* Bug #3248 - found by Stefan Burkei. */
&info3);
if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR)
- && contact_domain->can_do_samlogon_ex) {
+ && domain->can_do_samlogon_ex) {
DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
"retrying with NetSamLogon\n"));
- contact_domain->can_do_samlogon_ex = false;
+ domain->can_do_samlogon_ex = false;
retry = true;
continue;
}
might not yet have noticed that the DC has killed
our connection. */
- if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) {
+ if (!rpccli_is_connected(netlogon_pipe)) {
retry = true;
continue;
}
"password was changed and we didn't know it. "
"Killing connections to domain %s\n",
name_domain));
- invalidate_cm_connection(&contact_domain->conn);
+ invalidate_cm_connection(&domain->conn);
retry = true;
}
} while ( (attempts < 2) && retry );
+process_result:
+
if (NT_STATUS_IS_OK(result)) {
wcache_invalidate_samlogon(find_domain_from_name(name_domain), info3);
struct winbindd_domain *contact_domain;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ /* Ensure null termination */
+ state->request->data.chauthtok.user[
+ sizeof(state->request->data.chauthtok.user)-1]='\0';
+
DEBUG(3, ("[%5lu]: pam chauthtok %s\n", (unsigned long)state->pid,
state->request->data.chauthtok.user));
set_auth_errors(state->response, NT_STATUS_NO_SUCH_USER);
DEBUG(5, ("winbindd_pam_chauthtok: canonicalize_username %s failed with %s"
"(PAM: %d)\n",
- state->request->data.auth.user,
+ state->request->data.chauthtok.user,
state->response->data.auth.nt_status_string,
state->response->data.auth.pam_error));
request_error(state);
uid_t caller_uid = (uid_t)-1;
uid_t request_uid = state->request->data.logoff.uid;
- DEBUG(3, ("[%5lu]: pam logoff %s\n", (unsigned long)state->pid,
- state->request->data.logoff.user));
-
/* Ensure null termination */
state->request->data.logoff.user
[sizeof(state->request->data.logoff.user)-1]='\0';
state->request->data.logoff.krb5ccname
[sizeof(state->request->data.logoff.krb5ccname)-1]='\0';
- if (request_uid == (gid_t)-1) {
+ DEBUG(3, ("[%5lu]: pam logoff %s\n", (unsigned long)state->pid,
+ state->request->data.logoff.user));
+
+ if (request_uid == (uid_t)-1) {
goto failed;
}