summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/auth/auth.c20
-rw-r--r--source3/include/smb.h13
-rw-r--r--source3/param/loadparm.c1
-rw-r--r--source3/smbd/sesssetup.c55
4 files changed, 55 insertions, 34 deletions
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index b777e97cc9..61f638fcd0 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -279,6 +279,8 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
}
}
+ /* successful authentication */
+
if (NT_STATUS_IS_OK(nt_status)) {
unix_username = (*server_info)->unix_name;
if (!(*server_info)->guest) {
@@ -304,14 +306,22 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
user_info->internal_username.str,
unix_username));
}
+
+ return nt_status;
}
-
- if (!NT_STATUS_IS_OK(nt_status)) {
+
+ /* failed authentication; check for guest lapping */
+
+ if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
+ make_server_info_guest(server_info);
+ nt_status = NT_STATUS_OK;
+ } else {
DEBUG(2, ("check_ntlm_password: Authentication for user [%s] -> [%s] FAILED with error %s\n",
- user_info->smb_name.str, user_info->internal_username.str,
- nt_errstr(nt_status)));
- ZERO_STRUCTP(server_info);
+ user_info->smb_name.str, user_info->internal_username.str,
+ nt_errstr(nt_status)));
+ ZERO_STRUCTP(server_info);
}
+
return nt_status;
}
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 35ae5723b0..4bf967bf35 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -1649,12 +1649,6 @@ struct unix_error_map {
};
/*
-#include "ntdomain.h"
-
-#include "client.h"
-*/
-
-/*
* Size of new password account encoding string. This is enough space to
* hold 11 ACB characters, plus the surrounding [] and a terminating null.
* Do not change unless you are adding new ACB bits!
@@ -1683,9 +1677,10 @@ struct unix_error_map {
level security.
*/
-#define NEVER_MAP_TO_GUEST 0
-#define MAP_TO_GUEST_ON_BAD_USER 1
-#define MAP_TO_GUEST_ON_BAD_PASSWORD 2
+#define NEVER_MAP_TO_GUEST 0
+#define MAP_TO_GUEST_ON_BAD_USER 1
+#define MAP_TO_GUEST_ON_BAD_PASSWORD 2
+#define MAP_TO_GUEST_ON_BAD_UID 3
#define SAFE_NETBIOS_CHARS ". -_"
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 2c6a93483d..7089bbfd6a 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -763,6 +763,7 @@ static const struct enum_list enum_map_to_guest[] = {
{NEVER_MAP_TO_GUEST, "Never"},
{MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
{MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
+ {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
{-1, NULL}
};
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 6f963fc603..5808de9788 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -144,7 +144,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
char *client, *p, *domain;
fstring netbios_domain_name;
struct passwd *pw;
- char *user;
+ fstring user;
int sess_vuid;
NTSTATUS ret;
DATA_BLOB auth_data;
@@ -154,6 +154,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
uint8 tok_id[2];
DATA_BLOB nullblob = data_blob(NULL, 0);
fstring real_username;
+ BOOL map_domainuser_to_guest = False;
ZERO_STRUCT(ticket);
ZERO_STRUCT(auth_data);
@@ -238,37 +239,52 @@ static int reply_spnego_kerberos(connection_struct *conn,
}
}
- asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client);
+ fstr_sprintf(user, "%s%c%s", domain, *lp_winbind_separator(), client);
/* lookup the passwd struct, create a new user if necessary */
map_username( user );
pw = smb_getpwnam( user, real_username, True );
-
if (!pw) {
- DEBUG(1,("Username %s is invalid on this system\n",user));
- SAFE_FREE(user);
- SAFE_FREE(client);
- data_blob_free(&ap_rep);
- data_blob_free(&session_key);
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+
+ /* this was originally the behavior of Samba 2.2, if a user
+ did not have a local uid but has been authenticated, then
+ map them to a guest account */
+
+ if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID){
+ map_domainuser_to_guest = True;
+ fstrcpy(user,lp_guestaccount());
+ pw = smb_getpwnam( user, real_username, True );
+ }
+
+ /* extra sanity check that the guest account is valid */
+
+ if ( !pw ) {
+ DEBUG(1,("Username %s is invalid on this system\n", user));
+ SAFE_FREE(client);
+ data_blob_free(&ap_rep);
+ data_blob_free(&session_key);
+ return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+ }
}
/* setup the string used by %U */
sub_set_smb_name( real_username );
reload_services(True);
-
- if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw)))
- {
- DEBUG(1,("make_server_info_from_pw failed!\n"));
- SAFE_FREE(user);
- SAFE_FREE(client);
- data_blob_free(&ap_rep);
- data_blob_free(&session_key);
- passwd_free(&pw);
- return ERROR_NT(ret);
+ if ( map_domainuser_to_guest ) {
+ make_server_info_guest(&server_info);
+ } else {
+ ret = make_server_info_pw(&server_info, real_username, pw);
+ if ( !NT_STATUS_IS_OK(ret) ) {
+ DEBUG(1,("make_server_info_from_pw failed!\n"));
+ SAFE_FREE(client);
+ data_blob_free(&ap_rep);
+ data_blob_free(&session_key);
+ passwd_free(&pw);
+ return ERROR_NT(ret);
+ }
}
passwd_free(&pw);
@@ -284,7 +300,6 @@ static int reply_spnego_kerberos(connection_struct *conn,
A better interface would copy it.... */
sess_vuid = register_vuid(server_info, session_key, nullblob, client);
- SAFE_FREE(user);
SAFE_FREE(client);
if (sess_vuid == -1) {