2010-08-27 01:57:26 +04:00
/*
Unix SMB / CIFS implementation .
Authentication utility functions
Copyright ( C ) Simo Sorce 2010
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
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2011-03-25 04:28:05 +03:00
# include "auth.h"
2010-09-01 01:09:39 +04:00
# include "librpc/gen_ndr/krb5pac.h"
2011-02-25 00:30:16 +03:00
# include "nsswitch/libwbclient/wbclient.h"
2011-03-22 18:50:02 +03:00
# include "passdb.h"
2012-07-23 06:47:01 +04:00
# include "lib/param/loadparm.h"
2010-08-27 01:57:26 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_AUTH
# ifdef HAVE_KRB5
NTSTATUS get_user_from_kerberos_info ( TALLOC_CTX * mem_ctx ,
const char * cli_name ,
const char * princ_name ,
bool * is_mapped ,
bool * mapped_to_guest ,
char * * ntuser ,
char * * ntdomain ,
char * * username ,
struct passwd * * _pw )
{
NTSTATUS status ;
2021-10-08 18:59:59 +03:00
const char * domain = NULL ;
const char * realm = NULL ;
2010-08-27 01:57:26 +04:00
char * user = NULL ;
char * p ;
2010-11-09 23:07:25 +03:00
char * fuser = NULL ;
char * unixuser = NULL ;
2010-08-27 01:57:26 +04:00
struct passwd * pw = NULL ;
2021-11-26 12:57:17 +03:00
bool may_retry = false ;
2010-08-27 01:57:26 +04:00
DEBUG ( 3 , ( " Kerberos ticket principal name is [%s] \n " , princ_name ) ) ;
p = strchr_m ( princ_name , ' @ ' ) ;
if ( ! p ) {
DEBUG ( 3 , ( " [%s] Doesn't look like a valid principal \n " ,
princ_name ) ) ;
return NT_STATUS_LOGON_FAILURE ;
}
user = talloc_strndup ( mem_ctx , princ_name , p - princ_name ) ;
if ( ! user ) {
return NT_STATUS_NO_MEMORY ;
}
2021-10-08 18:59:59 +03:00
realm = p + 1 ;
2010-08-27 01:57:26 +04:00
if ( ! strequal ( realm , lp_realm ( ) ) ) {
DEBUG ( 3 , ( " Ticket for foreign realm %s@%s \n " , user , realm ) ) ;
if ( ! lp_allow_trusted_domains ( ) ) {
return NT_STATUS_LOGON_FAILURE ;
}
2021-10-08 18:59:59 +03:00
domain = realm ;
2010-08-27 01:57:26 +04:00
} else {
2021-10-08 18:59:59 +03:00
domain = lp_workgroup ( ) ;
2021-11-26 12:57:17 +03:00
may_retry = true ;
2010-08-27 01:57:26 +04:00
}
2010-11-09 23:07:25 +03:00
fuser = talloc_asprintf ( mem_ctx ,
" %s%c%s " ,
domain ,
* lp_winbind_separator ( ) ,
user ) ;
if ( ! fuser ) {
return NT_STATUS_NO_MEMORY ;
}
2010-08-27 01:57:26 +04:00
2010-11-09 23:07:25 +03:00
* is_mapped = map_username ( mem_ctx , fuser , & fuser ) ;
if ( ! fuser ) {
return NT_STATUS_NO_MEMORY ;
}
2012-02-11 20:52:07 +04:00
* mapped_to_guest = false ;
2010-08-27 01:57:26 +04:00
2010-11-09 23:07:25 +03:00
pw = smb_getpwnam ( mem_ctx , fuser , & unixuser , true ) ;
2021-11-26 12:57:17 +03:00
if ( may_retry & & pw = = NULL & & ! * is_mapped ) {
fuser = talloc_strdup ( mem_ctx , user ) ;
if ( ! fuser ) {
return NT_STATUS_NO_MEMORY ;
}
pw = smb_getpwnam ( mem_ctx , fuser , & unixuser , true ) ;
}
2010-08-27 01:57:26 +04:00
if ( pw ) {
2010-11-09 23:07:25 +03:00
if ( ! unixuser ) {
return NT_STATUS_NO_MEMORY ;
}
2010-08-27 01:57:26 +04:00
/* if a real user check pam account restrictions */
2017-02-17 22:53:39 +03:00
/* only really performed if "obey pam restriction" is true */
2010-08-27 01:57:26 +04:00
/* do this before an eventual mapping to guest occurs */
status = smb_pam_accountcheck ( pw - > pw_name , cli_name ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 1 , ( " PAM account restrictions prevent user "
" [%s] login \n " , unixuser ) ) ;
return status ;
}
}
if ( ! pw ) {
/* 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 ) {
* mapped_to_guest = true ;
2014-02-03 06:22:13 +04:00
fuser = talloc_strdup ( mem_ctx , lp_guest_account ( ) ) ;
2010-11-09 23:07:25 +03:00
if ( ! fuser ) {
return NT_STATUS_NO_MEMORY ;
}
2021-10-08 18:40:30 +03:00
pw = smb_getpwnam ( mem_ctx , fuser , & unixuser , false ) ;
2010-08-27 01:57:26 +04:00
}
/* extra sanity check that the guest account is valid */
if ( ! pw ) {
2015-11-03 12:09:13 +03:00
DBG_NOTICE ( " Username %s is invalid on this system \n " ,
fuser ) ;
2010-08-27 01:57:26 +04:00
return NT_STATUS_LOGON_FAILURE ;
}
}
2010-11-09 23:07:25 +03:00
if ( ! unixuser ) {
return NT_STATUS_NO_MEMORY ;
}
2010-08-27 01:57:26 +04:00
* username = talloc_strdup ( mem_ctx , unixuser ) ;
if ( ! * username ) {
return NT_STATUS_NO_MEMORY ;
}
* ntuser = user ;
2021-10-08 18:59:59 +03:00
* ntdomain = talloc_strdup ( mem_ctx , domain ) ;
if ( * ntdomain = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2010-08-27 01:57:26 +04:00
* _pw = pw ;
return NT_STATUS_OK ;
}
2010-08-27 02:48:46 +04:00
2011-02-11 03:50:37 +03:00
NTSTATUS make_session_info_krb5 ( TALLOC_CTX * mem_ctx ,
2010-08-27 02:48:46 +04:00
char * ntuser ,
char * ntdomain ,
char * username ,
struct passwd * pw ,
2011-02-11 03:50:37 +03:00
bool mapped_to_guest , bool username_was_mapped ,
2011-07-18 07:06:47 +04:00
struct auth_session_info * * session_info )
2010-08-27 02:48:46 +04:00
{
NTSTATUS status ;
2011-02-11 03:50:37 +03:00
struct auth_serversupplied_info * server_info ;
2010-08-27 02:48:46 +04:00
if ( mapped_to_guest ) {
2011-02-11 03:50:37 +03:00
status = make_server_info_guest ( mem_ctx , & server_info ) ;
2010-08-27 02:48:46 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 1 , ( " make_server_info_guest failed: %s! \n " ,
nt_errstr ( status ) ) ) ;
return status ;
}
} else {
/*
* We didn ' t get a PAC , we have to make up the user
* ourselves . Try to ask the pdb backend to provide
* SID consistency with ntlmssp session setup
*/
struct samu * sampass ;
sampass = samu_new ( talloc_tos ( ) ) ;
if ( sampass = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
if ( pdb_getsampwnam ( sampass , username ) ) {
DEBUG ( 10 , ( " found user %s in passdb, calling "
" make_server_info_sam \n " , username ) ) ;
2014-02-18 13:02:57 +04:00
status = make_server_info_sam ( mem_ctx ,
sampass ,
& server_info ) ;
2010-08-27 02:48:46 +04:00
} else {
/*
* User not in passdb , make it up artificially
*/
DEBUG ( 10 , ( " didn't find user %s in passdb, calling "
" make_server_info_pw \n " , username ) ) ;
2014-02-18 13:02:57 +04:00
status = make_server_info_pw ( mem_ctx ,
username ,
pw ,
& server_info ) ;
2010-08-27 02:48:46 +04:00
}
2011-09-12 17:50:31 +04:00
2010-08-27 02:48:46 +04:00
TALLOC_FREE ( sampass ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 1 , ( " make_server_info_[sam|pw] failed: %s! \n " ,
nt_errstr ( status ) ) ) ;
return status ;
}
/* make_server_info_pw does not set the domain. Without this
* we end up with the local netbios name in substitutions for
* % D . */
2011-02-11 03:50:37 +03:00
if ( server_info - > info3 ! = NULL ) {
2011-10-22 00:10:43 +04:00
server_info - > info3 - > base . logon_domain . string =
2011-02-11 03:50:37 +03:00
talloc_strdup ( server_info - > info3 , ntdomain ) ;
2010-08-27 02:48:46 +04:00
}
2011-02-10 13:04:01 +03:00
}
2011-02-11 03:50:37 +03:00
server_info - > nss_token | = username_was_mapped ;
2010-08-27 02:48:46 +04:00
2021-10-08 19:03:04 +03:00
status = create_local_token ( mem_ctx , server_info , NULL , ntuser , session_info ) ;
2011-02-11 03:50:37 +03:00
talloc_free ( server_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " failed to create local token: %s \n " ,
nt_errstr ( status ) ) ) ;
return status ;
2010-08-27 02:48:46 +04:00
}
return NT_STATUS_OK ;
}
2010-08-27 01:57:26 +04:00
# else /* HAVE_KRB5 */
NTSTATUS get_user_from_kerberos_info ( TALLOC_CTX * mem_ctx ,
const char * cli_name ,
const char * princ_name ,
bool * is_mapped ,
bool * mapped_to_guest ,
char * * ntuser ,
char * * ntdomain ,
char * * username ,
struct passwd * * _pw )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-08-27 02:48:46 +04:00
2011-02-11 03:50:37 +03:00
NTSTATUS make_session_info_krb5 ( TALLOC_CTX * mem_ctx ,
2010-08-27 02:48:46 +04:00
char * ntuser ,
char * ntdomain ,
char * username ,
struct passwd * pw ,
2011-02-11 03:50:37 +03:00
bool mapped_to_guest , bool username_was_mapped ,
2011-07-20 05:40:02 +04:00
struct auth_session_info * * session_info )
2010-08-27 02:48:46 +04:00
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-08-27 01:57:26 +04:00
# endif /* HAVE_KRB5 */