summaryrefslogtreecommitdiff
path: root/source3/auth
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2002-08-17 17:00:51 +0000
committerJelmer Vernooij <jelmer@samba.org>2002-08-17 17:00:51 +0000
commitb2edf254eda92f775e7d3d9b6793b4d77f9000b6 (patch)
tree18eb2564a769678c774a19bb07c00fc4aa7b2758 /source3/auth
parent669a39fae36f8bc60753c9b352556ef8ffaeb568 (diff)
downloadsamba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.tar.gz
samba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.tar.bz2
samba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.zip
sync 3.0 branch with head
(This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290)
Diffstat (limited to 'source3/auth')
-rw-r--r--source3/auth/auth.c14
-rw-r--r--source3/auth/auth_domain.c139
-rw-r--r--source3/auth/auth_sam.c19
-rw-r--r--source3/auth/auth_util.c5
-rw-r--r--source3/auth/auth_winbind.c70
5 files changed, 178 insertions, 69 deletions
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 4f7a5c24a0..d43afc71e1 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -395,33 +395,33 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
{
case SEC_DOMAIN:
DEBUG(5,("Making default auth method list for security=domain\n"));
- auth_method_list = str_list_make("guest sam ntdomain");
+ auth_method_list = str_list_make("guest sam winbind ntdomain", NULL);
break;
case SEC_SERVER:
DEBUG(5,("Making default auth method list for security=server\n"));
- auth_method_list = str_list_make("guest sam smbserver");
+ auth_method_list = str_list_make("guest sam smbserver", NULL);
break;
case SEC_USER:
if (lp_encrypted_passwords()) {
DEBUG(5,("Making default auth method list for security=user, encrypt passwords = yes\n"));
- auth_method_list = str_list_make("guest sam");
+ auth_method_list = str_list_make("guest sam", NULL);
} else {
DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
- auth_method_list = str_list_make("guest unix");
+ auth_method_list = str_list_make("guest unix", NULL);
}
break;
case SEC_SHARE:
if (lp_encrypted_passwords()) {
DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n"));
- auth_method_list = str_list_make("guest sam");
+ auth_method_list = str_list_make("guest sam", NULL);
} else {
DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n"));
- auth_method_list = str_list_make("guest unix");
+ auth_method_list = str_list_make("guest unix", NULL);
}
break;
case SEC_ADS:
DEBUG(5,("Making default auth method list for security=ADS\n"));
- auth_method_list = str_list_make("guest sam ads ntdomain");
+ auth_method_list = str_list_make("guest sam ads winbind ntdomain", NULL);
break;
default:
DEBUG(5,("Unknown auth method!\n"));
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c
index 3352c5f9c8..d48cec5b29 100644
--- a/source3/auth/auth_domain.c
+++ b/source3/auth/auth_domain.c
@@ -29,6 +29,88 @@ BOOL global_machine_password_needs_changing = False;
extern pstring global_myname;
extern userdom_struct current_user_info;
+
+/*
+ resolve the name of a DC in ways appropriate for an ADS domain mode
+ an ADS domain may not have Netbios enabled at all, so this is
+ quite different from the RPC case
+ Note that we ignore the 'server' parameter here. That has the effect of using
+ the 'ADS server' smb.conf parameter, which is what we really want anyway
+ */
+static NTSTATUS ads_resolve_dc(fstring remote_machine,
+ struct in_addr *dest_ip)
+{
+ ADS_STRUCT *ads;
+ ads = ads_init_simple();
+ if (!ads) {
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+
+ DEBUG(4,("ads_resolve_dc: realm=%s\n", ads->config.realm));
+
+ ads->auth.no_bind = 1;
+
+#ifdef HAVE_ADS
+ /* a full ads_connect() is actually overkill, as we don't srictly need
+ to do the SASL auth in order to get the info we need, but libads
+ doesn't offer a better way right now */
+ ads_connect(ads);
+#endif
+
+ fstrcpy(remote_machine, ads->config.ldap_server_name);
+ strupper(remote_machine);
+ *dest_ip = ads->ldap_ip;
+ ads_destroy(&ads);
+
+ if (!*remote_machine || is_zero_ip(*dest_ip)) {
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+
+ DEBUG(4,("ads_resolve_dc: using server='%s' IP=%s\n",
+ remote_machine, inet_ntoa(*dest_ip)));
+
+ return NT_STATUS_OK;
+}
+
+/*
+ resolve the name of a DC in ways appropriate for RPC domain mode
+ this relies on the server supporting netbios and port 137 not being
+ firewalled
+ */
+static NTSTATUS rpc_resolve_dc(const char *server,
+ fstring remote_machine,
+ struct in_addr *dest_ip)
+{
+ if (is_ipaddress(server)) {
+ struct in_addr to_ip = *interpret_addr2(server);
+
+ /* we need to know the machines netbios name - this is a lousy
+ way to find it, but until we have a RPC call that does this
+ it will have to do */
+ if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) {
+ DEBUG(2, ("connect_to_domain_password_server: Can't "
+ "resolve name for IP %s\n", server));
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+
+ *dest_ip = to_ip;
+ return NT_STATUS_OK;
+ }
+
+ fstrcpy(remote_machine, server);
+ strupper(remote_machine);
+ if (!resolve_name(remote_machine, dest_ip, 0x20)) {
+ DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n",
+ remote_machine));
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+
+ DEBUG(4,("rpc_resolve_dc: using server='%s' IP=%s\n",
+ remote_machine, inet_ntoa(*dest_ip)));
+
+ return NT_STATUS_OK;
+}
+
/**
* Connect to a remote server for domain security authenticaion.
*
@@ -50,37 +132,22 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
fstring remote_machine;
NTSTATUS result;
- if (is_ipaddress(server)) {
- struct in_addr to_ip;
-
- /* we shouldn't have 255.255.255.255 forthe IP address of
- a password server anyways */
- if ((to_ip.s_addr=inet_addr(server)) == 0xFFFFFFFF) {
- DEBUG (0,("connect_to_domain_password_server: inet_addr(%s) returned 0xFFFFFFFF!\n", server));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) {
- DEBUG(0, ("connect_to_domain_password_server: Can't "
- "resolve name for IP %s\n", server));
- return NT_STATUS_UNSUCCESSFUL;
- }
+ if (lp_security() == SEC_ADS) {
+ result = ads_resolve_dc(remote_machine, &dest_ip);
} else {
- fstrcpy(remote_machine, server);
+ result = rpc_resolve_dc(server, remote_machine, &dest_ip);
}
- standard_sub_basic(current_user_info.smb_name, remote_machine, sizeof(remote_machine));
- strupper(remote_machine);
-
- if(!resolve_name( remote_machine, &dest_ip, 0x20)) {
- DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", remote_machine));
- return NT_STATUS_UNSUCCESSFUL;
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(2,("connect_to_domain_password_server: unable to resolve DC: %s\n",
+ nt_errstr(result)));
+ return result;
}
-
+
if (ismyip(dest_ip)) {
DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n",
remote_machine));
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_NO_LOGON_SERVERS;
}
/* TODO: Send a SAMLOGON request to determine whether this is a valid
@@ -98,11 +165,11 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
*/
if (!grab_server_mutex(server))
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_NO_LOGON_SERVERS;
/* Attempt connection */
- result = cli_full_connection(cli, global_myname, server,
- &dest_ip, 0, "IPC$", "IPC", "", "", "", 0);
+ result = cli_full_connection(cli, global_myname, remote_machine,
+ &dest_ip, 0, "IPC$", "IPC", "", "", "",0);
if (!NT_STATUS_IS_OK(result)) {
release_server_mutex();
@@ -129,7 +196,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
cli_ulogoff(*cli);
cli_shutdown(*cli);
release_server_mutex();
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_NO_LOGON_SERVERS;
}
snprintf((*cli)->mach_acct, sizeof((*cli)->mach_acct) - 1, "%s$", setup_creds_as);
@@ -139,7 +206,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
return NT_STATUS_NO_MEMORY;
}
- result = new_cli_nt_setup_creds(*cli, sec_chan, trust_passwd);
+ result = cli_nt_setup_creds(*cli, sec_chan, trust_passwd);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \
@@ -174,10 +241,10 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli,
*/
if (is_zero_ip(*ip))
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_NO_LOGON_SERVERS;
if (!lookup_dc_name(global_myname, domain, ip, dc_name))
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_NO_LOGON_SERVERS;
return connect_to_domain_password_server(cli, dc_name, setup_creds_as, sec_chan, trust_passwd);
}
@@ -196,7 +263,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
struct in_addr *ip_list = NULL;
int count = 0;
int i;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
time_t time_now = time(NULL);
BOOL use_pdc_only = False;
@@ -212,7 +279,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
use_pdc_only = True;
if (!get_dc_list(use_pdc_only, domain, &ip_list, &count))
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_NO_LOGON_SERVERS;
/*
* Firstly try and contact a PDC/BDC who has the same
@@ -288,7 +355,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
fstring remote_machine;
NET_USER_INFO_3 info3;
struct cli_state *cli = NULL;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
/*
* At this point, smb_apasswd points to the lanman response to
@@ -300,7 +367,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
while (!NT_STATUS_IS_OK(nt_status) &&
next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) {
- if(strequal(remote_machine, "*")) {
+ if(lp_security() != SEC_ADS && strequal(remote_machine, "*")) {
nt_status = find_connect_pdc(&cli, domain, setup_creds_as, sec_chan, trust_passwd, last_change_time);
} else {
nt_status = connect_to_domain_password_server(&cli, remote_machine, setup_creds_as, sec_chan, trust_passwd);
@@ -503,7 +570,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
#ifdef DEBUG_PASSWORD
DEBUG(100, ("Trust password for domain %s is %s\n", user_info->domain.str, trust_password));
#endif
- E_md4hash((uchar *)trust_password, trust_md4_password);
+ E_md4hash(trust_password, trust_md4_password);
SAFE_FREE(trust_password);
#if 0
diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
index 76579150ce..155370546a 100644
--- a/source3/auth/auth_sam.c
+++ b/source3/auth/auth_sam.c
@@ -107,7 +107,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
memcpy(client_response, ntv2_response.data, sizeof(client_response));
ntv2_owf_gen(part_passwd, user, domain, kr);
- SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, (char *)value_from_encryption);
+ SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, value_from_encryption);
if (user_sess_key != NULL)
{
SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key);
@@ -232,11 +232,26 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
{
return NT_STATUS_OK;
} else {
+ if (lp_ntlm_auth()) {
+ /* Apparently NT accepts NT responses in the LM feild
+ - I think this is related to Win9X pass-though authenticaion
+ */
+ DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM feild\n"));
+ if (smb_pwd_check_ntlmv1(user_info->lm_resp,
+ nt_pw, auth_context->challenge,
+ user_sess_key))
+ {
+ return NT_STATUS_OK;
+ } else {
+ DEBUG(3,("sam_password_ok: NT MD4 password in LM feild failed for user %s\n",pdb_get_username(sampass)));
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+ }
DEBUG(4,("sam_password_ok: LM password check failed for user %s\n",pdb_get_username(sampass)));
return NT_STATUS_WRONG_PASSWORD;
}
}
-
+
/* Should not be reached, but if they send nothing... */
DEBUG(3,("sam_password_ok: NEITHER LanMan nor NT password supplied for user %s\n",pdb_get_username(sampass)));
return NT_STATUS_WRONG_PASSWORD;
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 3ade220c0f..f914d91871 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -25,7 +25,6 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH
-extern fstring remote_machine;
extern pstring global_myname;
/****************************************************************************
@@ -394,7 +393,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
ret = make_user_info_map(user_info, smb_name,
client_domain,
- remote_machine,
+ get_remote_machine_name(),
local_lm_blob,
local_nt_blob,
plaintext_password,
@@ -429,7 +428,7 @@ BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
return make_user_info_map(user_info, smb_name,
client_domain,
- remote_machine,
+ get_remote_machine_name(),
lm_resp,
nt_resp,
no_plaintext_blob,
diff --git a/source3/auth/auth_winbind.c b/source3/auth/auth_winbind.c
index 671e198bf5..5bdccd39f3 100644
--- a/source3/auth/auth_winbind.c
+++ b/source3/auth/auth_winbind.c
@@ -32,6 +32,30 @@ NSS_STATUS winbindd_request(int req_type,
struct winbindd_request *request,
struct winbindd_response *response);
+NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response *response, NET_USER_INFO_3 *info3)
+{
+ uint8 *info3_ndr;
+ size_t len = response->length - sizeof(response);
+ prs_struct ps;
+ if (len > 0) {
+ info3_ndr = response->extra_data;
+ if (!prs_init(&ps, len, mem_ctx, UNMARSHALL)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ prs_append_data(&ps, info3_ndr, len);
+ ps.data_offset = 0;
+ if (!net_io_user_info3("", info3, &ps, 1, 3)) {
+ DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ prs_mem_free(&ps);
+
+ return NT_STATUS_OK;
+ } else {
+ DEBUG(2, ("get_info3_from_ndr: No info3 struct found!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+}
/* Authenticate a user with a challenge/response */
@@ -44,11 +68,11 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
- struct passwd *pw;
NTSTATUS nt_status;
+ NET_USER_INFO_3 info3;
if (!user_info) {
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_INVALID_PARAMETER;
}
if (!auth_context) {
@@ -62,11 +86,14 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- snprintf(request.data.auth_crap.user, sizeof(request.data.auth_crap.user),
- "%s\\%s", user_info->domain.str, user_info->smb_name.str);
+ request.data.auth_crap.flags = WINBIND_PAM_INFO3_NDR;
- fstrcpy(request.data.auth_crap.user, user_info->smb_name.str);
- fstrcpy(request.data.auth_crap.domain, user_info->domain.str);
+ push_utf8_fstring(request.data.auth_crap.user,
+ user_info->smb_name.str);
+ push_utf8_fstring(request.data.auth_crap.domain,
+ user_info->domain.str);
+ push_utf8_fstring(request.data.auth_crap.workstation,
+ user_info->wksta_name.str);
memcpy(request.data.auth_crap.chal, auth_context->challenge.data, sizeof(request.data.auth_crap.chal));
@@ -76,27 +103,28 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
sizeof(request.data.auth_crap.nt_resp));
memcpy(request.data.auth_crap.lm_resp, user_info->lm_resp.data,
- sizeof(request.data.auth_crap.lm_resp_len));
- memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data,
request.data.auth_crap.lm_resp_len);
+ memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data,
+ request.data.auth_crap.nt_resp_len);
result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
- if (result == NSS_STATUS_SUCCESS) {
-
- pw = Get_Pwnam(user_info->internal_username.str);
-
- if (pw) {
- if (make_server_info_pw(server_info, pw)) {
- nt_status = NT_STATUS_OK;
- } else {
- nt_status = NT_STATUS_NO_MEMORY;
+ nt_status = NT_STATUS(response.data.auth.nt_status);
+
+ if (result == NSS_STATUS_SUCCESS && response.extra_data) {
+ if (NT_STATUS_IS_OK(nt_status)) {
+ if (NT_STATUS_IS_OK(nt_status = get_info3_from_ndr(mem_ctx, &response, &info3))) {
+ nt_status =
+ make_server_info_info3(mem_ctx,
+ user_info->internal_username.str,
+ user_info->smb_name.str,
+ user_info->domain.str,
+ server_info,
+ &info3);
}
- } else {
- nt_status = NT_STATUS_NO_SUCH_USER;
}
- } else {
- nt_status = NT_STATUS_LOGON_FAILURE;
+ } else if (NT_STATUS_IS_OK(nt_status)) {
+ nt_status = NT_STATUS_UNSUCCESSFUL;
}
return nt_status;