diff options
-rw-r--r-- | source3/auth/auth.c | 20 | ||||
-rw-r--r-- | source3/include/smb.h | 13 | ||||
-rw-r--r-- | source3/param/loadparm.c | 1 | ||||
-rw-r--r-- | source3/smbd/sesssetup.c | 55 |
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) { |