summaryrefslogtreecommitdiff
path: root/source3/auth
diff options
context:
space:
mode:
Diffstat (limited to 'source3/auth')
-rw-r--r--source3/auth/auth.c59
-rw-r--r--source3/auth/auth_builtin.c9
-rw-r--r--source3/auth/auth_domain.c296
-rw-r--r--source3/auth/auth_rhosts.c19
-rw-r--r--source3/auth/auth_sam.c181
-rw-r--r--source3/auth/auth_server.c19
-rw-r--r--source3/auth/auth_unix.c2
-rw-r--r--source3/auth/auth_util.c402
-rw-r--r--source3/auth/auth_winbind.c20
-rw-r--r--source3/auth/pampass.c4
-rw-r--r--source3/auth/pass_check.c5
11 files changed, 498 insertions, 518 deletions
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 0c4fe76830..a2486acbd1 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -63,7 +63,7 @@ static struct auth_init_function_entry *auth_find_backend_entry(const char *name
struct auth_init_function_entry *entry = backends;
while(entry) {
- if (strequal(entry->name, name)) return entry;
+ if (strcmp(entry->name, name)==0) return entry;
entry = entry->next;
}
@@ -203,9 +203,9 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
const struct auth_usersupplied_info *user_info,
struct auth_serversupplied_info **server_info)
{
-
- NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
- const char *pdb_username;
+ /* if all the modules say 'not for me' this is reasonable */
+ NTSTATUS nt_status = NT_STATUS_NO_SUCH_USER;
+ const char *unix_username;
auth_methods *auth_method;
TALLOC_CTX *mem_ctx;
@@ -244,12 +244,24 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
return NT_STATUS_LOGON_FAILURE;
for (auth_method = auth_context->auth_method_list;auth_method; auth_method = auth_method->next) {
+ NTSTATUS result;
+
mem_ctx = talloc_init("%s authentication for user %s\\%s", auth_method->name,
user_info->domain.str, user_info->smb_name.str);
- nt_status = auth_method->auth(auth_context, auth_method->private_data, mem_ctx, user_info, server_info);
+ result = auth_method->auth(auth_context, auth_method->private_data, mem_ctx, user_info, server_info);
+
+ /* check if the module did anything */
+ if ( NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ) {
+ DEBUG(10,("check_ntlm_password: %s had nothing to say\n", auth_method->name));
+ talloc_destroy(mem_ctx);
+ continue;
+ }
+
+ nt_status = result;
+
if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(3, ("check_ntlm_password: %s authentication for user [%s] suceeded\n",
+ DEBUG(3, ("check_ntlm_password: %s authentication for user [%s] succeeded\n",
auth_method->name, user_info->smb_name.str));
} else {
DEBUG(5, ("check_ntlm_password: %s authentication for user [%s] FAILED with error %s\n",
@@ -258,40 +270,36 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
talloc_destroy(mem_ctx);
- if (NT_STATUS_IS_OK(nt_status))
- break;
+ if ( NT_STATUS_IS_OK(nt_status))
+ {
+ break;
+ }
}
- /* This is one of the few places the *relies* (rather than just sets defaults
- on the value of lp_security(). This needs to change. A new paramater
- perhaps? */
- if (lp_security() >= SEC_SERVER)
- smb_user_control(user_info, *server_info, nt_status);
-
if (NT_STATUS_IS_OK(nt_status)) {
- pdb_username = pdb_get_username((*server_info)->sam_account);
+ unix_username = (*server_info)->unix_name;
if (!(*server_info)->guest) {
/* We might not be root if we are an RPC call */
become_root();
- nt_status = smb_pam_accountcheck(pdb_username);
+ nt_status = smb_pam_accountcheck(unix_username);
unbecome_root();
if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] suceeded\n",
- pdb_username));
+ DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] succeeded\n",
+ unix_username));
} else {
DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] FAILED with error %s\n",
- pdb_username, nt_errstr(nt_status)));
+ unix_username, nt_errstr(nt_status)));
}
}
if (NT_STATUS_IS_OK(nt_status)) {
DEBUG((*server_info)->guest ? 5 : 2,
- ("check_ntlm_password: %sauthentication for user [%s] -> [%s] -> [%s] suceeded\n",
+ ("check_ntlm_password: %sauthentication for user [%s] -> [%s] -> [%s] succeeded\n",
(*server_info)->guest ? "guest " : "",
user_info->smb_name.str,
user_info->internal_username.str,
- pdb_username));
+ unix_username));
}
}
@@ -451,8 +459,13 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
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", NULL);
+ if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) {
+ DEBUG(5,("Making default auth method list for DC, security=user, encrypt passwords = yes\n"));
+ auth_method_list = str_list_make("guest sam winbind:trustdomain", NULL);
+ } else {
+ DEBUG(5,("Making default auth method list for standalone security=user, encrypt passwords = yes\n"));
+ 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", NULL);
diff --git a/source3/auth/auth_builtin.c b/source3/auth/auth_builtin.c
index 5a9b5534ab..f7cdfe3fd2 100644
--- a/source3/auth/auth_builtin.c
+++ b/source3/auth/auth_builtin.c
@@ -38,7 +38,8 @@ static NTSTATUS check_guest_security(const struct auth_context *auth_context,
const auth_usersupplied_info *user_info,
auth_serversupplied_info **server_info)
{
- NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+ /* mark this as 'not for me' */
+ NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
if (!(user_info->internal_username.str
&& *user_info->internal_username.str)) {
@@ -86,11 +87,11 @@ static NTSTATUS check_name_to_ntstatus_security(const struct auth_context *auth_
fstrcpy(user, user_info->smb_name.str);
if (strncasecmp("NT_STATUS", user, strlen("NT_STATUS")) == 0) {
- strupper(user);
+ strupper_m(user);
return nt_status_string_to_code(user);
}
- strlower(user);
+ strlower_m(user);
error_num = strtoul(user, NULL, 16);
DEBUG(5,("check_name_to_ntstatus_security: Error for user %s was %lx\n", user, error_num));
@@ -133,7 +134,7 @@ static NTSTATUS check_fixed_challenge_security(const struct auth_context *auth_c
const auth_usersupplied_info *user_info,
auth_serversupplied_info **server_info)
{
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/****************************************************************************
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c
index bc03fecf74..56bd6b9aca 100644
--- a/source3/auth/auth_domain.c
+++ b/source3/auth/auth_domain.c
@@ -29,86 +29,6 @@ extern BOOL global_machine_password_needs_changing;
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.flags |= ADS_AUTH_NO_BIND;
-
-#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, ("rpc_resolve_dc: 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,("rpc_resolve_dc: 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.
*
@@ -121,36 +41,14 @@ static NTSTATUS rpc_resolve_dc(const char *server,
**/
static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
- const char *server,
+ const char *dc_name, struct in_addr dc_ip,
const char *setup_creds_as,
uint16 sec_chan,
const unsigned char *trust_passwd,
BOOL *retry)
{
- struct in_addr dest_ip;
- fstring remote_machine;
NTSTATUS result;
- uint32 neg_flags = 0x000001ff;
-
- *retry = False;
-
- if (lp_security() == SEC_ADS)
- result = ads_resolve_dc(remote_machine, &dest_ip);
- else
- result = rpc_resolve_dc(server, remote_machine, &dest_ip);
-
- 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_NO_LOGON_SERVERS;
- }
-
/* TODO: Send a SAMLOGON request to determine whether this is a valid
logonserver. We can avoid a 30-second timeout if the DC is down
if the SAMLOGON request fails as it is only over UDP. */
@@ -165,14 +63,13 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
* ACCESS_DENIED errors if 2 auths are done from the same machine. JRA.
*/
- *retry = True;
-
- if (!grab_server_mutex(server))
+ if (!grab_server_mutex(dc_name))
return NT_STATUS_NO_LOGON_SERVERS;
/* Attempt connection */
- result = cli_full_connection(cli, global_myname(), remote_machine,
- &dest_ip, 0, "IPC$", "IPC", "", "", "",0, retry);
+ *retry = True;
+ result = cli_full_connection(cli, global_myname(), dc_name, &dc_ip, 0,
+ "IPC$", "IPC", "", "", "", 0, retry);
if (!NT_STATUS_IS_OK(result)) {
/* map to something more useful */
@@ -199,7 +96,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
if(cli_nt_session_open(*cli, PI_NETLOGON) == False) {
DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
-machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
+machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
cli_nt_session_close(*cli);
cli_ulogoff(*cli);
cli_shutdown(*cli);
@@ -214,11 +111,11 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
return NT_STATUS_NO_MEMORY;
}
- result = cli_nt_setup_creds(*cli, sec_chan, trust_passwd, &neg_flags, 2);
+ result = cli_nt_establish_netlogon(*cli, sec_chan, trust_passwd);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(0,("connect_to_domain_password_server: unable to setup the NETLOGON credentials to machine \
-%s. Error was : %s.\n", remote_machine, nt_errstr(result)));
+%s. Error was : %s.\n", dc_name, nt_errstr(result)));
cli_nt_session_close(*cli);
cli_ulogoff(*cli);
cli_shutdown(*cli);
@@ -232,61 +129,6 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
}
/***********************************************************************
- Utility function to attempt a connection to an IP address of a DC.
-************************************************************************/
-
-static NTSTATUS attempt_connect_to_dc(struct cli_state **cli,
- const char *domain,
- struct in_addr *ip,
- const char *setup_creds_as,
- uint16 sec_chan,
- const unsigned char *trust_passwd)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- BOOL retry = True;
- fstring dc_name;
- int i;
-
- /*
- * Ignore addresses we have already tried.
- */
-
- if (is_zero_ip(*ip))
- return NT_STATUS_NO_LOGON_SERVERS;
-
- if (!lookup_dc_name(global_myname(), domain, ip, dc_name))
- return NT_STATUS_NO_LOGON_SERVERS;
-
- for (i = 0; (!NT_STATUS_IS_OK(ret)) && retry && (i < 3); i++)
- ret = connect_to_domain_password_server(cli, dc_name, setup_creds_as,
- sec_chan, trust_passwd, &retry);
- return ret;
-}
-
-/***********************************************************************
- We have been asked to dynamically determine the IP addresses of
- the PDC and BDC's for DOMAIN, and query them in turn.
-************************************************************************/
-static NTSTATUS find_connect_dc(struct cli_state **cli,
- const char *domain,
- const char *setup_creds_as,
- uint16 sec_chan,
- unsigned char *trust_passwd,
- time_t last_change_time)
-{
- struct in_addr dc_ip;
- fstring srv_name;
-
- if (!rpc_find_dc(domain, srv_name, &dc_ip)) {
- DEBUG(0,("find_connect_dc: Failed to find an DCs for %s\n", lp_workgroup()));
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- return attempt_connect_to_dc( cli, domain, &dc_ip, setup_creds_as,
- sec_chan, trust_passwd );
-}
-
-/***********************************************************************
Do the same as security=server, but using NT Domain calls and a session
key from the machine password. If the server parameter is specified
use it, otherwise figure out a server from the 'password server' param.
@@ -297,15 +139,17 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
const char *domain,
uchar chal[8],
auth_serversupplied_info **server_info,
- const char *server, const char *setup_creds_as,
+ const char *dc_name, struct in_addr dc_ip,
+ const char *setup_creds_as,
uint16 sec_chan,
unsigned char trust_passwd[16],
time_t last_change_time)
{
- fstring remote_machine;
NET_USER_INFO_3 info3;
struct cli_state *cli = NULL;
NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
+ int i;
+ BOOL retry = True;
/*
* At this point, smb_apasswd points to the lanman response to
@@ -315,20 +159,14 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
* see if they were valid.
*/
- while (!NT_STATUS_IS_OK(nt_status) &&
- next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) {
- if(lp_security() != SEC_ADS && strequal(remote_machine, "*")) {
- nt_status = find_connect_dc(&cli, domain, setup_creds_as, sec_chan, trust_passwd, last_change_time);
- } else {
- int i;
- BOOL retry = True;
- for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry && (i < 3); i++)
- nt_status = connect_to_domain_password_server(&cli, remote_machine, setup_creds_as,
- sec_chan, trust_passwd, &retry);
- }
+ /* rety loop for robustness */
+
+ for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry && (i < 3); i++) {
+ nt_status = connect_to_domain_password_server(&cli, dc_name, dc_ip, setup_creds_as,
+ sec_chan, trust_passwd, &retry);
}
- if (!NT_STATUS_IS_OK(nt_status)) {
+ if ( !NT_STATUS_IS_OK(nt_status) ) {
DEBUG(0,("domain_client_validate: Domain password server not available.\n"));
return nt_status;
}
@@ -341,11 +179,15 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
*/
nt_status = cli_netlogon_sam_network_logon(cli, mem_ctx,
- user_info->smb_name.str, user_info->domain.str,
- user_info->wksta_name.str, chal,
- user_info->lm_resp, user_info->nt_resp,
- &info3);
+ NULL, user_info->smb_name.str, user_info->domain.str,
+ user_info->wksta_name.str, chal, user_info->lm_resp,
+ user_info->nt_resp, &info3);
+ /* let go as soon as possible so we avoid any potential deadlocks
+ with winbind lookup up users or groups */
+
+ release_server_mutex();
+
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("domain_client_validate: unable to validate password "
"for user %s in domain %s to Domain controller %s. "
@@ -360,7 +202,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
} else {
nt_status = make_server_info_info3(mem_ctx, user_info->internal_username.str,
user_info->smb_name.str, domain, server_info, &info3);
- uni_group_cache_store_netlogon(mem_ctx, &info3);
+ netsamlogon_cache_store( mem_ctx, &info3 );
}
#if 0
@@ -373,7 +215,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
if (NT_STATUS_IS_OK(status)) {
if(cli_nt_logoff(&cli, &ctr) == False) {
DEBUG(0,("domain_client_validate: unable to log off user %s in domain \
-%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));
+%s to Domain controller %s. Error was %s.\n", user, domain, dc_name, cli_errstr(&cli)));
nt_status = NT_STATUS_LOGON_FAILURE;
}
}
@@ -386,7 +228,6 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
cli_nt_session_close(cli);
cli_ulogoff(cli);
cli_shutdown(cli);
- release_server_mutex();
return nt_status;
}
@@ -401,11 +242,18 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
auth_serversupplied_info **server_info)
{
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
- char *password_server;
unsigned char trust_passwd[16];
time_t last_change_time;
const char *domain = lp_workgroup();
uint32 sec_channel_type = 0;
+ fstring dc_name;
+ struct in_addr dc_ip;
+
+ if ( lp_server_role() != ROLE_DOMAIN_MEMBER ) {
+ DEBUG(0,("check_ntdomain_security: Configuration error! Cannot use "
+ "ntdomain auth method when not a member of a domain.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
if (!user_info || !server_info || !auth_context) {
DEBUG(1,("check_ntdomain_security: Critical variables not present. Failing.\n"));
@@ -418,9 +266,9 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
* password file.
*/
- if(is_myname(user_info->domain.str)) {
+ if(strequal(get_global_sam_name(), user_info->domain.str)) {
DEBUG(3,("check_ntdomain_security: Requested domain was for this machine.\n"));
- return NT_STATUS_LOGON_FAILURE;
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*
@@ -443,22 +291,23 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
}
}
- /*
- * Treat each name in the 'password server =' line as a potential
- * PDC/BDC. Contact each in turn and try and authenticate.
- */
-
- password_server = lp_passwordserver();
+ /* we need our DC to send the net_sam_logon() request to */
+ if ( !get_dc_name(domain, dc_name, &dc_ip) ) {
+ DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n",
+ user_info->domain.str));
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+
nt_status = domain_client_validate(mem_ctx, user_info, domain,
- (uchar *)auth_context->challenge.data,
- server_info,
- password_server, global_myname(), sec_channel_type,trust_passwd, last_change_time);
+ (uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip,
+ global_myname(), sec_channel_type,trust_passwd, last_change_time);
+
return nt_status;
}
/* module initialisation */
-NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
+static NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
@@ -485,6 +334,8 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
char *trust_password;
time_t last_change_time;
DOM_SID sid;
+ fstring dc_name;
+ struct in_addr dc_ip;
if (!user_info || !server_info || !auth_context) {
DEBUG(1,("check_trustdomain_security: Critical variables not present. Failing.\n"));
@@ -492,25 +343,22 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
}
/*
- * Check that the requested domain is not our own machine name.
- * If it is, we should never check the PDC here, we use our own local
- * password file.
+ * Check that the requested domain is not our own machine name or domain name.
*/
- if(is_myname(user_info->domain.str)) {
- DEBUG(3,("check_trustdomain_security: Requested domain was for this machine.\n"));
- return NT_STATUS_LOGON_FAILURE;
+ if( strequal(get_global_sam_name(), user_info->domain.str)) {
+ DEBUG(3,("check_trustdomain_security: Requested domain [%s] was for this machine.\n",
+ user_info->domain.str));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
- /*
- * Check that the requested domain is not our own domain,
- * If it is, we should use our own local password file.
- */
-
- if(strequal(lp_workgroup(), (user_info->domain.str))) {
- DEBUG(3,("check_trustdomain_security: Requested domain was for this domain.\n"));
- return NT_STATUS_LOGON_FAILURE;
- }
+ /* No point is bothering if this is not a trusted domain.
+ This return makes "map to guest = bad user" work again.
+ The logic is that if we know nothing about the domain, that
+ user is known to us and does not exist */
+
+ if ( !is_trusted_domain( user_info->domain.str ) )
+ return NT_STATUS_NOT_IMPLEMENTED;
/*
* Get the trusted account password for the trusted domain
@@ -537,16 +385,24 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
}
#endif
- nt_status = domain_client_validate(mem_ctx, user_info, user_info->domain.str,
- (uchar *)auth_context->challenge.data,
- server_info, "*" /* Do a lookup */,
- lp_workgroup(), SEC_CHAN_DOMAIN, trust_md4_password, last_change_time);
+ /* use get_dc_name() for consistency even through we know that it will be
+ a netbios name */
+
+ if ( !get_dc_name(user_info->domain.str, dc_name, &dc_ip) ) {
+ DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n",
+ user_info->domain.str));
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+ nt_status = domain_client_validate(mem_ctx, user_info, user_info->domain.str,
+ (uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip,
+ lp_workgroup(), SEC_CHAN_DOMAIN, trust_md4_password, last_change_time);
+
return nt_status;
}
/* module initialisation */
-NTSTATUS auth_init_trustdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
+static NTSTATUS auth_init_trustdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
diff --git a/source3/auth/auth_rhosts.c b/source3/auth/auth_rhosts.c
index 3411083116..fab2d551f2 100644
--- a/source3/auth/auth_rhosts.c
+++ b/source3/auth/auth_rhosts.c
@@ -139,7 +139,7 @@ static BOOL check_hosts_equiv(SAM_ACCOUNT *account)
char *fname = NULL;
fname = lp_hosts_equiv();
- if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(account), &uid)))
+ if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(account), &uid)))
return False;
/* note: don't allow hosts.equiv on root */
@@ -162,11 +162,13 @@ static NTSTATUS check_hostsequiv_security(const struct auth_context *auth_contex
const auth_usersupplied_info *user_info,
auth_serversupplied_info **server_info)
{
- NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+ NTSTATUS nt_status;
SAM_ACCOUNT *account = NULL;
if (!NT_STATUS_IS_OK(nt_status =
auth_get_sam_account(user_info->internal_username.str,
&account))) {
+ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER))
+ nt_status = NT_STATUS_NOT_IMPLEMENTED;
return nt_status;
}
@@ -174,14 +176,14 @@ static NTSTATUS check_hostsequiv_security(const struct auth_context *auth_contex
nt_status = make_server_info_sam(server_info, account);
} else {
pdb_free_sam(&account);
- nt_status = NT_STATUS_LOGON_FAILURE;
+ nt_status = NT_STATUS_NOT_IMPLEMENTED;
}
return nt_status;
}
/* module initialisation */
-NTSTATUS auth_init_hostsequiv(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
+static NTSTATUS auth_init_hostsequiv(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
@@ -203,7 +205,7 @@ static NTSTATUS check_rhosts_security(const struct auth_context *auth_context,
const auth_usersupplied_info *user_info,
auth_serversupplied_info **server_info)
{
- NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+ NTSTATUS nt_status;
SAM_ACCOUNT *account = NULL;
pstring rhostsfile;
const char *home;
@@ -211,6 +213,8 @@ static NTSTATUS check_rhosts_security(const struct auth_context *auth_context,
if (!NT_STATUS_IS_OK(nt_status =
auth_get_sam_account(user_info->internal_username.str,
&account))) {
+ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER))
+ nt_status = NT_STATUS_NOT_IMPLEMENTED;
return nt_status;
}
@@ -223,19 +227,18 @@ static NTSTATUS check_rhosts_security(const struct auth_context *auth_context,
nt_status = make_server_info_sam(server_info, account);
} else {
pdb_free_sam(&account);
- nt_status = NT_STATUS_LOGON_FAILURE;
}
unbecome_root();
} else {
pdb_free_sam(&account);
- nt_status = NT_STATUS_LOGON_FAILURE;
+ nt_status = NT_STATUS_NOT_IMPLEMENTED;
}
return nt_status;
}
/* module initialisation */
-NTSTATUS auth_init_rhosts(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+static NTSTATUS auth_init_rhosts(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
index a7e49a270f..012696f46a 100644
--- a/source3/auth/auth_sam.c
+++ b/source3/auth/auth_sam.c
@@ -4,6 +4,7 @@
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Andrew Bartlett 2001
+ Copyright (C) Gerald Carter 2003
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
@@ -28,9 +29,9 @@
/****************************************************************************
core of smb password checking routine.
****************************************************************************/
-static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
+static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response,
const uchar *part_passwd,
- DATA_BLOB sec_blob,
+ const DATA_BLOB *sec_blob,
uint8 user_sess_key[16])
{
/* Finish the encryption of part_passwd. */
@@ -42,17 +43,17 @@ static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
return False;
}
- if (sec_blob.length != 8) {
- DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%d)\n", sec_blob.length));
+ if (sec_blob->length != 8) {
+ DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%d)\n", sec_blob->length));
return False;
}
- if (nt_response.length != 24) {
- DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", nt_response.length));
+ if (nt_response->length != 24) {
+ DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", nt_response->length));
return False;
}
- SMBOWFencrypt(part_passwd, sec_blob.data, p24);
+ SMBOWFencrypt(part_passwd, sec_blob->data, p24);
if (user_sess_key != NULL)
{
SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key);
@@ -61,16 +62,16 @@ static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
#if DEBUG_PASSWORD
- DEBUG(100,("Part password (P16) was |"));
+ DEBUG(100,("Part password (P16) was |\n"));
dump_data(100, part_passwd, 16);
- DEBUG(100,("Password from client was |"));
- dump_data(100, nt_response.data, nt_response.length);
- DEBUG(100,("Given challenge was |"));
- dump_data(100, sec_blob.data, sec_blob.length);
- DEBUG(100,("Value from encryption was |"));
+ DEBUGADD(100,("Password from client was |\n"));
+ dump_data(100, nt_response->data, nt_response->length);
+ DEBUGADD(100,("Given challenge was |\n"));
+ dump_data(100, sec_blob->data, sec_blob->length);
+ DEBUGADD(100,("Value from encryption was |\n"));
dump_data(100, p24, 24);
#endif
- return (memcmp(p24, nt_response.data, 24) == 0);
+ return (memcmp(p24, nt_response->data, 24) == 0);
}
@@ -79,9 +80,9 @@ core of smb password checking routine. (NTLMv2, LMv2)
Note: The same code works with both NTLMv2 and LMv2.
****************************************************************************/
-static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
+static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response,
const uchar *part_passwd,
- const DATA_BLOB sec_blob,
+ const DATA_BLOB *sec_blob,
const char *user, const char *domain,
uint8 user_sess_key[16])
{
@@ -98,42 +99,43 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
return False;
}
- if (ntv2_response.length < 16) {
+ if (ntv2_response->length < 24) {
/* We MUST have more than 16 bytes, or the stuff below will go
- crazy... */
+ crazy. No known implementation sends less than the 24 bytes
+ for LMv2, let alone NTLMv2. */
DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%d)\n",
- ntv2_response.length));
+ ntv2_response->length));
return False;
}
- client_key_data = data_blob(ntv2_response.data+16, ntv2_response.length-16);
+ client_key_data = data_blob(ntv2_response->data+16, ntv2_response->length-16);
/*
todo: should we be checking this for anything? We can't for LMv2,
but for NTLMv2 it is meant to contain the current time etc.
*/
- memcpy(client_response, ntv2_response.data, sizeof(client_response));
+ memcpy(client_response, ntv2_response->data, sizeof(client_response));
if (!ntv2_owf_gen(part_passwd, user, domain, kr)) {
return False;
}
- SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, 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);
}
#if DEBUG_PASSWORD
- DEBUG(100,("Part password (P16) was |"));
+ DEBUG(100,("Part password (P16) was |\n"));
dump_data(100, part_passwd, 16);
- DEBUG(100,("Password from client was |"));
- dump_data(100, ntv2_response.data, ntv2_response.length);
- DEBUG(100,("Variable data from client was |"));
+ DEBUGADD(100,("Password from client was |\n"));
+ dump_data(100, ntv2_response->data, ntv2_response->length);
+ DEBUGADD(100,("Variable data from client was |\n"));
dump_data(100, client_key_data.data, client_key_data.length);
- DEBUG(100,("Given challenge was |"));
- dump_data(100, sec_blob.data, sec_blob.length);
- DEBUG(100,("Value from encryption was |"));
+ DEBUGADD(100,("Given challenge was |\n"));
+ dump_data(100, sec_blob->data, sec_blob->length);
+ DEBUGADD(100,("Value from encryption was |\n"));
dump_data(100, value_from_encryption, 16);
#endif
data_blob_clear_free(&client_key_data);
@@ -185,8 +187,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
use it (ie. does it exist in the smbpasswd file).
*/
DEBUG(4,("sam_password_ok: Checking NTLMv2 password with domain [%s]\n", user_info->client_domain.str));
- if (smb_pwd_check_ntlmv2( user_info->nt_resp,
- nt_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv2( &user_info->nt_resp,
+ nt_pw, &auth_context->challenge,
user_info->smb_name.str,
user_info->client_domain.str,
user_sess_key))
@@ -195,11 +197,12 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
}
DEBUG(4,("sam_password_ok: Checking NTLMv2 password without a domain\n"));
- if (smb_pwd_check_ntlmv2( user_info->nt_resp,
- nt_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv2( &user_info->nt_resp,
+ nt_pw, &auth_context->challenge,
user_info->smb_name.str,
"",
user_sess_key))
+
{
return NT_STATUS_OK;
} else {
@@ -213,8 +216,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
use it (ie. does it exist in the smbpasswd file).
*/
DEBUG(4,("sam_password_ok: Checking NT MD4 password\n"));
- if (smb_pwd_check_ntlmv1(user_info->nt_resp,
- nt_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv1(&user_info->nt_resp,
+ nt_pw, &auth_context->challenge,
user_sess_key))
{
return NT_STATUS_OK;
@@ -224,7 +227,7 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
}
} else {
DEBUG(2,("sam_password_ok: NTLMv1 passwords NOT PERMITTED for user %s\n",pdb_get_username(sampass)));
- /* no return, because we might pick up LMv2 in the LM field */
+ /* no return, becouse we might pick up LMv2 in the LM field */
}
}
@@ -242,8 +245,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
lm_pw = pdb_get_lanman_passwd(sampass);
DEBUG(4,("sam_password_ok: Checking LM password\n"));
- if (smb_pwd_check_ntlmv1(user_info->lm_resp,
- lm_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv1(&user_info->lm_resp,
+ lm_pw, &auth_context->challenge,
user_sess_key))
{
return NT_STATUS_OK;
@@ -261,8 +264,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
- related to Win9X, legacy NAS pass-though authentication
*/
DEBUG(4,("sam_password_ok: Checking LMv2 password with domain %s\n", user_info->client_domain.str));
- if (smb_pwd_check_ntlmv2( user_info->lm_resp,
- nt_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv2( &user_info->lm_resp,
+ nt_pw, &auth_context->challenge,
user_info->smb_name.str,
user_info->client_domain.str,
user_sess_key))
@@ -271,8 +274,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
}
DEBUG(4,("sam_password_ok: Checking LMv2 password without a domain\n"));
- if (smb_pwd_check_ntlmv2( user_info->lm_resp,
- nt_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv2( &user_info->lm_resp,
+ nt_pw, &auth_context->challenge,
user_info->smb_name.str,
"",
user_sess_key))
@@ -286,8 +289,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM field\n"));
if (lp_ntlm_auth())
{
- if (smb_pwd_check_ntlmv1(user_info->lm_resp,
- nt_pw, auth_context->challenge,
+ if (smb_pwd_check_ntlmv1(&user_info->lm_resp,
+ nt_pw, &auth_context->challenge,
user_sess_key))
{
return NT_STATUS_OK;
@@ -330,7 +333,7 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
kickoff_time = pdb_get_kickoff_time(sampass);
if (kickoff_time != 0 && time(NULL) > kickoff_time) {
- DEBUG(1,("Account for user '%s' has expried.\n", pdb_get_username(sampass)));
+ DEBUG(1,("Account for user '%s' has expired.\n", pdb_get_username(sampass)));
DEBUG(3,("Account expired at '%ld' unix time.\n", (long)kickoff_time));
return NT_STATUS_ACCOUNT_EXPIRED;
}
@@ -438,14 +441,14 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
return NT_STATUS_NO_SUCH_USER;
}
- nt_status = sam_account_ok(mem_ctx, sampass, user_info);
+ nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, user_sess_key);
if (!NT_STATUS_IS_OK(nt_status)) {
pdb_free_sam(&sampass);
return nt_status;
}
- nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, user_sess_key);
+ nt_status = sam_account_ok(mem_ctx, sampass, user_info);
if (!NT_STATUS_IS_OK(nt_status)) {
pdb_free_sam(&sampass);
@@ -468,14 +471,14 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
}
/* module initialisation */
-NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+static NTSTATUS auth_init_sam_ignoredomain(struct auth_context *auth_context, const char *param, 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";
+ (*auth_method)->name = "sam_ignoredomain";
return NT_STATUS_OK;
}
@@ -490,83 +493,55 @@ static NTSTATUS check_samstrict_security(const struct auth_context *auth_context
const auth_usersupplied_info *user_info,
auth_serversupplied_info **server_info)
{
+ BOOL is_local_name, is_my_domain;
if (!user_info || !auth_context) {
return NT_STATUS_LOGON_FAILURE;
}
- /* If we are a domain member, we must not
- attempt to check the password locally,
- unless it is one of our aliases. */
+ is_local_name = is_myname(user_info->domain.str);
+ is_my_domain = strequal(user_info->domain.str, lp_workgroup());
+
+ /* check whether or not we service this domain/workgroup name */
- if (!is_myname(user_info->domain.str)) {
- DEBUG(7,("The requested user domain is not the local server name. [%s]\\[%s]\n",
- user_info->domain.str,user_info->internal_username.str));
- return NT_STATUS_NO_SUCH_USER;
+ switch ( lp_server_role() ) {
+ case ROLE_STANDALONE:
+ 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
+ ? "ROLE_DOMAIN_MEMBER" : "ROLE_STANDALONE") ));
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 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));
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ default: /* name is ok */
+ break;
}
return check_sam_security(auth_context, my_private_data, mem_ctx, user_info, server_info);
}
/* module initialisation */
-NTSTATUS auth_init_samstrict(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+static NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
}
(*auth_method)->auth = check_samstrict_security;
- (*auth_method)->name = "samstrict";
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
-Check SAM security (above) but with a few extra checks if we're a DC.
-****************************************************************************/
-
-static NTSTATUS check_samstrict_dc_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
-
- if (!user_info || !auth_context) {
- return NT_STATUS_LOGON_FAILURE;
- }
-
- /* If we are a domain member, we must not
- attempt to check the password locally,
- unless it is one of our aliases, empty
- or our domain if we are a logon server.*/
-
-
- if ((!is_myworkgroup(user_info->domain.str))&&
- (!is_myname(user_info->domain.str))) {
- DEBUG(7,("The requested user domain is not the local server name or our domain. [%s]\\[%s]\n",
- user_info->domain.str,user_info->internal_username.str));
- return NT_STATUS_NO_SUCH_USER;
- }
-
- return check_sam_security(auth_context, my_private_data, mem_ctx, user_info, server_info);
-}
-
-/* module initialisation */
-NTSTATUS auth_init_samstrict_dc(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- (*auth_method)->auth = check_samstrict_dc_security;
- (*auth_method)->name = "samstrict_dc";
+ (*auth_method)->name = "sam";
return NT_STATUS_OK;
}
NTSTATUS auth_sam_init(void)
{
- smb_register_auth(AUTH_INTERFACE_VERSION, "samstrict_dc", auth_init_samstrict_dc);
- smb_register_auth(AUTH_INTERFACE_VERSION, "samstrict", auth_init_samstrict);
smb_register_auth(AUTH_INTERFACE_VERSION, "sam", auth_init_sam);
+ smb_register_auth(AUTH_INTERFACE_VERSION, "sam_ignoredomain", auth_init_sam_ignoredomain);
return NT_STATUS_OK;
}
diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c
index 73af290af2..30e0e13a56 100644
--- a/source3/auth/auth_server.c
+++ b/source3/auth/auth_server.c
@@ -50,7 +50,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) {
standard_sub_basic(current_user_info.smb_name, desthost, sizeof(desthost));
- strupper(desthost);
+ strupper_m(desthost);
if(!resolve_name( desthost, &dest_ip, 0x20)) {
DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost));
@@ -222,7 +222,7 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context
static fstring baduser;
static BOOL tested_password_server = False;
static BOOL bad_password_server = False;
- NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+ NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
BOOL locally_made_cli = False;
/*
@@ -233,7 +233,7 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context
if(is_myname(user_info->domain.str)) {
DEBUG(3,("check_smbserver_security: Requested domain was for this machine.\n"));
- return NT_STATUS_LOGON_FAILURE;
+ return nt_status;
}
cli = my_private_data;
@@ -372,12 +372,19 @@ use this machine as the password server.\n"));
cli_ulogoff(cli);
- if NT_STATUS_IS_OK(nt_status) {
+ if (NT_STATUS_IS_OK(nt_status)) {
struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
if (pass) {
nt_status = make_server_info_pw(server_info, pass);
} else {
- nt_status = NT_STATUS_NO_SUCH_USER;
+ auth_add_user_script(user_info->domain.str, user_info->internal_username.str);
+ pass = Get_Pwnam(user_info->internal_username.str);
+
+ if (pass) {
+ nt_status = make_server_info_pw(server_info, pass);
+ } else {
+ nt_status = NT_STATUS_NO_SUCH_USER;
+ }
}
}
@@ -388,7 +395,7 @@ use this machine as the password server.\n"));
return(nt_status);
}
-NTSTATUS auth_init_smbserver(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
+static NTSTATUS auth_init_smbserver(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
diff --git a/source3/auth/auth_unix.c b/source3/auth/auth_unix.c
index 392178f77c..b9de6f7acb 100644
--- a/source3/auth/auth_unix.c
+++ b/source3/auth/auth_unix.c
@@ -119,7 +119,7 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context,
}
/* module initialisation */
-NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
+static NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index e8f2af41f3..8e1b420b47 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -1,4 +1,4 @@
-/*
+/*
Unix SMB/CIFS implementation.
Authentication utility functions
Copyright (C) Andrew Tridgell 1992-1998
@@ -36,7 +36,7 @@ extern DOM_SID global_sid_Authenticated_Users;
Create a UNIX user on demand.
****************************************************************************/
-static int smb_create_user(const char *unix_user, const char *homedir)
+static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
{
pstring add_script;
int ret;
@@ -44,7 +44,9 @@ static int smb_create_user(const char *unix_user, const char *homedir)
pstrcpy(add_script, lp_adduser_script());
if (! *add_script)
return -1;
- all_string_sub(add_script, "%u", unix_user, sizeof(pstring));
+ all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
+ if (domain)
+ all_string_sub(add_script, "%D", domain, sizeof(pstring));
if (homedir)
all_string_sub(add_script, "%H", homedir, sizeof(pstring));
ret = smbrun(add_script,NULL);
@@ -54,25 +56,30 @@ static int smb_create_user(const char *unix_user, const char *homedir)
/****************************************************************************
Add and Delete UNIX users on demand, based on NTSTATUS codes.
+ We don't care about RID's here so ignore.
****************************************************************************/
-void smb_user_control(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, NTSTATUS nt_status)
+void auth_add_user_script(const char *domain, const char *username)
{
- struct passwd *pwd=NULL;
-
- if (NT_STATUS_IS_OK(nt_status)) {
-
- if (!(server_info->sam_fill_level & SAM_FILL_UNIX)) {
-
- /*
- * User validated ok against Domain controller.
- * If the admin wants us to try and create a UNIX
- * user on the fly, do so.
- */
-
- if(lp_adduser_script() && !(pwd = Get_Pwnam(user_info->internal_username.str))) {
- smb_create_user(user_info->internal_username.str, NULL);
- }
+ uint32 rid;
+ /*
+ * User validated ok against Domain controller.
+ * If the admin wants us to try and create a UNIX
+ * user on the fly, do so.
+ */
+
+ if ( lp_adduser_script() )
+ smb_create_user(domain, username, NULL);
+ else {
+ DEBUG(10,("auth_add_user_script: no 'add user script'. Asking winbindd\n"));
+
+ /* should never get here is we a re a domain member running winbindd
+ However, a host set for 'security = server' might run winbindd for
+ account allocation */
+
+ if ( !winbind_create_user(username, NULL) ) {
+ DEBUG(5,("auth_add_user_script: winbindd_create_user() failed\n"));
+ rid = 0;
}
}
}
@@ -208,41 +215,26 @@ NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
client_domain, smb_name, wksta_name));
- if (lp_allow_trusted_domains() && *client_domain) {
-
- /* the client could have given us a workstation name
- or other crap for the workgroup - we really need a
- way of telling if this domain name is one of our
- trusted domain names
-
- Also don't allow "" as a domain, fixes a Win9X bug
+ /* don't allow "" as a domain, fixes a Win9X bug
where it doens't supply a domain for logon script
- 'net use' commands.
-
- Finally, we do this by looking up a cache of trusted domains!
- */
+ 'net use' commands.*/
+ if ( *client_domain )
domain = client_domain;
+ else
+ domain = lp_workgroup();
- if (is_trusted_domain(domain)) {
- return make_user_info(user_info, smb_name, internal_username,
- client_domain, domain, wksta_name,
- lm_pwd, nt_pwd, plaintext, ntlmssp_flags,
- encrypted);
- }
+ /* do what win2k does. Always map unknown domains to our own
+ and let the "passdb backend" handle unknown users. */
- } else {
- domain = lp_workgroup();
- }
+ if ( !is_trusted_domain(domain) )
+ domain = get_default_sam_name();
- return make_user_info(user_info,
- smb_name, internal_username,
- client_domain, domain,
- wksta_name,
- lm_pwd, nt_pwd,
- plaintext,
- ntlmssp_flags, encrypted);
+ /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
+ return make_user_info(user_info, smb_name, internal_username,
+ client_domain, domain, wksta_name, lm_pwd, nt_pwd,
+ plaintext, ntlmssp_flags, encrypted);
}
/****************************************************************************
@@ -611,10 +603,10 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
NT_USER_TOKEN *token;
int i;
- if (NT_STATUS_IS_ERR(uid_to_sid(&user_sid, uid))) {
+ if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, uid))) {
return NULL;
}
- if (NT_STATUS_IS_ERR(gid_to_sid(&group_sid, gid))) {
+ if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, gid))) {
return NULL;
}
@@ -625,7 +617,7 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
}
for (i = 0; i < ngroups; i++) {
- if (NT_STATUS_IS_ERR(gid_to_sid(&(group_sids)[i], (groups)[i]))) {
+ if (!NT_STATUS_IS_OK(gid_to_sid(&(group_sids)[i], (groups)[i]))) {
DEBUG(1, ("create_nt_token: failed to convert gid %ld to a sid!\n", (long int)groups[i]));
SAFE_FREE(group_sids);
return NULL;
@@ -654,29 +646,22 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
* of groups.
******************************************************************************/
-static NTSTATUS get_user_groups_from_local_sam(SAM_ACCOUNT *sampass,
+static NTSTATUS get_user_groups_from_local_sam(const char *username, uid_t uid, gid_t gid,
int *n_groups, DOM_SID **groups, gid_t **unix_groups)
{
- uid_t uid;
- gid_t gid;
int n_unix_groups;
int i;
*n_groups = 0;
*groups = NULL;
- if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(sampass), &uid)) || NT_STATUS_IS_ERR(sid_to_gid(pdb_get_group_sid(sampass), &gid))) {
- DEBUG(0, ("get_user_groups_from_local_sam: error fetching uid or gid for user!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
n_unix_groups = groups_max();
if ((*unix_groups = malloc( sizeof(gid_t) * n_unix_groups ) ) == NULL) {
DEBUG(0, ("get_user_groups_from_local_sam: Out of memory allocating unix group list\n"));
return NT_STATUS_NO_MEMORY;
}
- if (sys_getgrouplist(pdb_get_username(sampass), gid, *unix_groups, &n_unix_groups) == -1) {
+ if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
gid_t *groups_tmp;
groups_tmp = Realloc(*unix_groups, sizeof(gid_t) * n_unix_groups);
if (!groups_tmp) {
@@ -685,7 +670,7 @@ static NTSTATUS get_user_groups_from_local_sam(SAM_ACCOUNT *sampass,
}
*unix_groups = groups_tmp;
- if (sys_getgrouplist(pdb_get_username(sampass), gid, *unix_groups, &n_unix_groups) == -1) {
+ if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
DEBUG(0, ("get_user_groups_from_local_sam: failed to get the unix group list\n"));
SAFE_FREE(*unix_groups);
return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */
@@ -706,7 +691,7 @@ static NTSTATUS get_user_groups_from_local_sam(SAM_ACCOUNT *sampass,
*n_groups = n_unix_groups;
for (i = 0; i < *n_groups; i++) {
- if (NT_STATUS_IS_ERR(gid_to_sid(&(*groups)[i], (*unix_groups)[i]))) {
+ if (!NT_STATUS_IS_OK(gid_to_sid(&(*groups)[i], (*unix_groups)[i]))) {
DEBUG(1, ("get_user_groups_from_local_sam: failed to convert gid %ld to a sid!\n", (long int)(*unix_groups)[i+1]));
SAFE_FREE(*groups);
SAFE_FREE(*unix_groups);
@@ -721,10 +706,8 @@ static NTSTATUS get_user_groups_from_local_sam(SAM_ACCOUNT *sampass,
Make a user_info struct
***************************************************************************/
-static NTSTATUS make_server_info(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass)
+static NTSTATUS make_server_info(auth_serversupplied_info **server_info)
{
- NTSTATUS ret;
-
*server_info = malloc(sizeof(**server_info));
if (!*server_info) {
DEBUG(0,("make_server_info: malloc failed!\n"));
@@ -732,24 +715,25 @@ static NTSTATUS make_server_info(auth_serversupplied_info **server_info, SAM_ACC
}
ZERO_STRUCTP(*server_info);
- (*server_info)->sam_fill_level = SAM_FILL_ALL;
- (*server_info)->sam_account = sampass;
- if (NT_STATUS_IS_ERR(ret = sid_to_uid(pdb_get_user_sid(sampass), &((*server_info)->uid))))
- return ret;
- if (NT_STATUS_IS_ERR(ret = sid_to_gid(pdb_get_group_sid(sampass), &((*server_info)->gid))))
- return ret;
+ /* Initialise the uid and gid values to something non-zero
+ which may save us from giving away root access if there
+ is a bug in allocating these fields. */
+
+ (*server_info)->uid = -1;
+ (*server_info)->gid = -1;
return NT_STATUS_OK;
}
/***************************************************************************
- Make (and fill) a user_info struct from a SAM_ACCOUNT
+Fill a server_info struct from a SAM_ACCOUNT with their groups
***************************************************************************/
-NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
- SAM_ACCOUNT *sampass)
+static NTSTATUS add_user_groups(auth_serversupplied_info **server_info,
+ SAM_ACCOUNT *sampass,
+ uid_t uid, gid_t gid)
{
- NTSTATUS nt_status = NT_STATUS_OK;
+ NTSTATUS nt_status;
const DOM_SID *user_sid = pdb_get_user_sid(sampass);
const DOM_SID *group_sid = pdb_get_group_sid(sampass);
int n_groupSIDs = 0;
@@ -759,14 +743,11 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
BOOL is_guest;
uint32 rid;
- if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info, sampass))) {
- return nt_status;
- }
-
- if (!NT_STATUS_IS_OK(nt_status
- = get_user_groups_from_local_sam(sampass,
- &n_groupSIDs, &groupSIDs, &unix_groups)))
- {
+ nt_status = get_user_groups_from_local_sam(pdb_get_username(sampass),
+ uid, gid,
+ &n_groupSIDs, &groupSIDs,
+ &unix_groups);
+ if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(4,("get_user_groups_from_local_sam failed\n"));
free_server_info(server_info);
return nt_status;
@@ -789,11 +770,49 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
(*server_info)->n_groups = n_groupSIDs;
(*server_info)->groups = unix_groups;
-
(*server_info)->ptok = token;
+
+ return nt_status;
+}
+
+/***************************************************************************
+ Make (and fill) a user_info struct from a SAM_ACCOUNT
+***************************************************************************/
+
+NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
+ SAM_ACCOUNT *sampass)
+{
+ NTSTATUS nt_status;
+ struct passwd *pwd;
+
+ if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info)))
+ return nt_status;
+
+ (*server_info)->sam_account = sampass;
+
+ if ( !(pwd = getpwnam_alloc(pdb_get_username(sampass))) ) {
+ DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
+ pdb_get_username(sampass)));
+ free_server_info(server_info);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+ (*server_info)->unix_name = smb_xstrdup(pwd->pw_name);
+ (*server_info)->gid = pwd->pw_gid;
+ (*server_info)->uid = pwd->pw_uid;
- DEBUG(5,("make_server_info_sam: made server info for user %s\n",
- pdb_get_username((*server_info)->sam_account)));
+ passwd_free(&pwd);
+
+ if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, sampass,
+ (*server_info)->uid,
+ (*server_info)->gid))) {
+ free_server_info(server_info);
+ return nt_status;
+ }
+
+ (*server_info)->sam_fill_level = SAM_FILL_ALL;
+ DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
+ pdb_get_username(sampass),
+ (*server_info)->unix_name));
return nt_status;
}
@@ -810,7 +829,22 @@ NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, const struc
if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {
return nt_status;
}
- return make_server_info_sam(server_info, sampass);
+ if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
+ return nt_status;
+ }
+
+ (*server_info)->sam_account = sampass;
+
+ if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, sampass, pwd->pw_uid, pwd->pw_gid))) {
+ return nt_status;
+ }
+
+ (*server_info)->unix_name = smb_xstrdup(pwd->pw_name);
+
+ (*server_info)->sam_fill_level = SAM_FILL_ALL;
+ (*server_info)->uid = pwd->pw_uid;
+ (*server_info)->gid = pwd->pw_gid;
+ return nt_status;
}
/***************************************************************************
@@ -847,6 +881,43 @@ NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
}
/***************************************************************************
+ Purely internal function for make_server_info_info3
+ Fill the sam account from getpwnam
+***************************************************************************/
+static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
+ const char *domain,
+ const char *username,
+ char **found_username,
+ uid_t *uid, gid_t *gid,
+ SAM_ACCOUNT **sam_account)
+{
+ fstring dom_user;
+ struct passwd *passwd;
+
+ fstr_sprintf(dom_user, "%s%s%s",
+ domain, lp_winbind_separator(), username);
+
+ passwd = Get_Pwnam(dom_user);
+
+ /* if the lookup for DOMAIN\username failed, try again
+ with just 'username'. This is need for accessing the server
+ as a trust user that actually maps to a local account */
+
+ if ( !passwd )
+ passwd = Get_Pwnam(username);
+
+ if (passwd == NULL)
+ return NT_STATUS_NO_SUCH_USER;
+
+ *uid = passwd->pw_uid;
+ *gid = passwd->pw_gid;
+
+ *found_username = talloc_strdup(mem_ctx, passwd->pw_name);
+
+ return pdb_init_sam_pw(sam_account, passwd);
+}
+
+/***************************************************************************
Make a server_info struct from the info3 returned by a domain logon
***************************************************************************/
@@ -858,7 +929,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
NET_USER_INFO_3 *info3)
{
NTSTATUS nt_status = NT_STATUS_OK;
-
+ char *found_username;
const char *nt_domain;
const char *nt_username;
@@ -866,10 +937,8 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
DOM_SID user_sid;
DOM_SID group_sid;
- struct passwd *passwd;
-
- unid_t u_id, g_id;
- int u_type, g_type;
+ uid_t uid;
+ gid_t gid;
int n_lgroupSIDs;
DOM_SID *lgroupSIDs = NULL;
@@ -905,40 +974,20 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
/* If the server didn't give us one, just use the one we sent them */
domain = domain;
}
-
- u_type = ID_USERID;
- g_type = ID_GROUPID;
- if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&u_id, &u_type, &user_sid))
- && NT_STATUS_IS_OK(idmap_get_id_from_sid(&g_id, &g_type, &group_sid))
- && ((passwd = getpwuid_alloc(u_id.uid)))) {
- nt_status = pdb_init_sam_pw(&sam_account, passwd);
- passwd_free(&passwd);
- } else {
- char *dom_user;
- dom_user = talloc_asprintf(mem_ctx, "%s%s%s",
- nt_domain,
- lp_winbind_separator(),
- internal_username);
-
- if (!dom_user) {
- DEBUG(0, ("talloc_asprintf failed!\n"));
- return NT_STATUS_NO_MEMORY;
- } else {
-
- if (!(passwd = Get_Pwnam(dom_user))
- /* Only lookup local for the local
- domain, we don't want this for
- trusted domains */
- && strequal(nt_domain, lp_workgroup())) {
- passwd = Get_Pwnam(internal_username);
- }
-
- if (!passwd) {
- return NT_STATUS_NO_SUCH_USER;
- } else {
- nt_status = pdb_init_sam_pw(&sam_account, passwd);
- }
- }
+
+ /* try to fill the SAM account.. If getpwnam() fails, then try the
+ add user script (2.2.x behavior) */
+
+ nt_status = fill_sam_account(mem_ctx, nt_domain, internal_username,
+ &found_username, &uid, &gid, &sam_account);
+
+ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
+ DEBUG(3,("User %s does not exist, trying to add it\n",
+ internal_username));
+ auth_add_user_script(nt_domain, internal_username);
+ nt_status = fill_sam_account(mem_ctx, nt_domain,
+ internal_username, &found_username,
+ &uid, &gid, &sam_account);
}
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -946,17 +995,12 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
return nt_status;
}
- if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
+ if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
pdb_free_sam(&sam_account);
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_NO_MEMORY;
}
- if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
- pdb_free_sam(&sam_account);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
+ if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
pdb_free_sam(&sam_account);
return NT_STATUS_NO_MEMORY;
}
@@ -966,7 +1010,18 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
- if (!pdb_set_fullname(sam_account, unistr2_static(&(info3->uni_full_name)), PDB_CHANGED)) {
+ if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
+ pdb_free_sam(&sam_account);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
+ pdb_free_sam(&sam_account);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!pdb_set_fullname(sam_account, unistr2_static(&(info3->uni_full_name)),
+ PDB_CHANGED)) {
pdb_free_sam(&sam_account);
return NT_STATUS_NO_MEMORY;
}
@@ -991,20 +1046,31 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
- if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info, sam_account))) {
+ if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
DEBUG(4, ("make_server_info failed!\n"));
pdb_free_sam(&sam_account);
return nt_status;
}
+ /* save this here to _net_sam_logon() doesn't fail (it assumes a
+ valid SAM_ACCOUNT) */
+
+ (*server_info)->sam_account = sam_account;
+
+ (*server_info)->unix_name = smb_xstrdup(found_username);
+
+ /* Fill in the unix info we found on the way */
+
+ (*server_info)->sam_fill_level = SAM_FILL_ALL;
+ (*server_info)->uid = uid;
+ (*server_info)->gid = gid;
+
/* Store the user group information in the server_info
returned to the caller. */
- if (!NT_STATUS_IS_OK(nt_status
- = get_user_groups_from_local_sam(sam_account,
- &n_lgroupSIDs,
- &lgroupSIDs,
- &unix_groups)))
+ nt_status = get_user_groups_from_local_sam((*server_info)->unix_name,
+ uid, gid, &n_lgroupSIDs, &lgroupSIDs, &unix_groups);
+ if ( !NT_STATUS_IS_OK(nt_status) )
{
DEBUG(4,("get_user_groups_from_local_sam failed\n"));
return nt_status;
@@ -1018,8 +1084,9 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
(n_lgroupSIDs + info3->num_groups2 +
info3->num_other_sids));
if (!all_group_SIDs) {
- DEBUG(0, ("create_nt_token_info3: malloc() failed for DOM_SID list!\n"));
+ DEBUG(0, ("malloc() failed for DOM_SID list!\n"));
SAFE_FREE(lgroupSIDs);
+ free_server_info(server_info);
return NT_STATUS_NO_MEMORY;
}
@@ -1032,9 +1099,10 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
sid_copy(&all_group_SIDs[i+n_lgroupSIDs], &(info3->dom_sid.sid));
if (!sid_append_rid(&all_group_SIDs[i+n_lgroupSIDs], info3->gids[i].g_rid)) {
nt_status = NT_STATUS_INVALID_PARAMETER;
- DEBUG(3,("create_nt_token_info3: could not append additional group rid 0x%x\n",
+ DEBUG(3,("could not append additional group rid 0x%x\n",
info3->gids[i].g_rid));
SAFE_FREE(lgroupSIDs);
+ free_server_info(server_info);
return nt_status;
}
}
@@ -1060,6 +1128,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
all_group_SIDs, False, &token))) {
DEBUG(4,("create_nt_user_token failed\n"));
SAFE_FREE(all_group_SIDs);
+ free_server_info(server_info);
return nt_status;
}
@@ -1111,6 +1180,7 @@ void free_server_info(auth_serversupplied_info **server_info)
/* call pam_end here, unless we know we are keeping it */
delete_nt_token( &(*server_info)->ptok );
SAFE_FREE((*server_info)->groups);
+ SAFE_FREE((*server_info)->unix_name);
ZERO_STRUCT(**server_info);
}
SAFE_FREE(*server_info);
@@ -1208,4 +1278,52 @@ NTSTATUS nt_status_squash(NTSTATUS nt_status)
}
+/**
+ * Verify whether or not given domain is trusted.
+ *
+ * @param domain_name name of the domain to be verified
+ * @return true if domain is one of the trusted once or
+ * false if otherwise
+ **/
+
+BOOL is_trusted_domain(const char* dom_name)
+{
+ DOM_SID trustdom_sid;
+ char *pass = NULL;
+ time_t lct;
+ BOOL ret;
+
+ /* no trusted domains for a standalone server */
+
+ if ( lp_server_role() == ROLE_STANDALONE )
+ return False;
+
+ /* if we are a DC, then check for a direct trust relationships */
+
+ if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
+ become_root();
+ ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
+ unbecome_root();
+ SAFE_FREE(pass);
+ if (ret)
+ return True;
+ }
+ else {
+ /* if winbindd is not up and we are a domain member) then we need to update the
+ trustdom_cache ourselves */
+
+ if ( !winbind_ping() )
+ update_trustdom_cache();
+ }
+
+ /* now the trustdom cache should be available a DC could still
+ * have a transitive trust so fall back to the cache of trusted
+ * domains (like a domain member would use */
+
+ if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
+ return True;
+ }
+
+ return False;
+}
diff --git a/source3/auth/auth_winbind.c b/source3/auth/auth_winbind.c
index b8276b0866..aa8f345a5b 100644
--- a/source3/auth/auth_winbind.c
+++ b/source3/auth/auth_winbind.c
@@ -29,7 +29,7 @@
static 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);
+ size_t len = response->length - sizeof(struct winbindd_response);
prs_struct ps;
if (len > 0) {
info3_ndr = response->extra_data;
@@ -72,15 +72,20 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
if (!auth_context) {
DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n",
user_info->internal_username.str));
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_INVALID_PARAMETER;
}
+ if (strequal(user_info->domain.str, get_global_sam_name())) {
+ DEBUG(3,("check_winbind_security: Not using winbind, requested domain was for this SAM.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
+
/* Send off request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- request.data.auth_crap.flags = WINBIND_PAM_INFO3_NDR;
+ request.flags = WBFLAG_PAM_INFO3_NDR;
push_utf8_fstring(request.data.auth_crap.user,
user_info->smb_name.str);
@@ -100,8 +105,11 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
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);
-
+
+ /* we are contacting the privileged pipe */
+ become_root();
result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
+ unbecome_root();
if ( result == NSS_STATUS_UNAVAIL ) {
struct auth_methods *auth_method = my_private_data;
@@ -129,14 +137,14 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
}
}
} else if (NT_STATUS_IS_OK(nt_status)) {
- nt_status = NT_STATUS_UNSUCCESSFUL;
+ nt_status = NT_STATUS_NO_LOGON_SERVERS;
}
return nt_status;
}
/* module initialisation */
-NTSTATUS auth_init_winbind(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+static NTSTATUS auth_init_winbind(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
diff --git a/source3/auth/pampass.c b/source3/auth/pampass.c
index 045ceb7c72..d666e439b0 100644
--- a/source3/auth/pampass.c
+++ b/source3/auth/pampass.c
@@ -229,7 +229,7 @@ static struct chat_struct *make_pw_chat(char *p)
special_char_sub(prompt);
fstrcpy(t->prompt, prompt);
- strlower(t->prompt);
+ strlower_m(t->prompt);
trim_string(t->prompt, " ", " ");
if (!next_token(&p, reply, NULL, sizeof(fstring)))
@@ -240,7 +240,7 @@ static struct chat_struct *make_pw_chat(char *p)
special_char_sub(reply);
fstrcpy(t->reply, reply);
- strlower(t->reply);
+ strlower_m(t->reply);
trim_string(t->reply, " ", " ");
}
diff --git a/source3/auth/pass_check.c b/source3/auth/pass_check.c
index 88b82e3474..1ac8c1815a 100644
--- a/source3/auth/pass_check.c
+++ b/source3/auth/pass_check.c
@@ -757,7 +757,7 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas
/* try all lowercase if it's currently all uppercase */
if (strhasupper(pass2)) {
- strlower(pass2);
+ strlower_m(pass2);
if NT_STATUS_IS_OK(nt_status = password_check(pass2)) {
if (fn)
fn(user, pass2);
@@ -771,8 +771,7 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas
}
/* last chance - all combinations of up to level chars upper! */
- strlower(pass2);
-
+ strlower_m(pass2);
if (NT_STATUS_IS_OK(nt_status = string_combinations(pass2, password_check, level))) {
if (fn)