2008-02-17 03:57:57 +03:00
/*
2003-04-07 22:01:40 +04:00
Unix SMB / CIFS implementation .
kerberos authorization data ( PAC ) utility library
2008-02-17 03:57:57 +03:00
Copyright ( C ) Jim McDonough < jmcd @ us . ibm . com > 2003
2005-09-30 21:13:37 +04:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2004 - 2005
Copyright ( C ) Andrew Tridgell 2001
Copyright ( C ) Luke Howard 2002 - 2003
Copyright ( C ) Stefan Metzmacher 2004 - 2005
2008-02-27 21:38:48 +03:00
Copyright ( C ) Guenther Deschner 2005 , 2007 , 2008
2008-02-17 03:57:57 +03:00
2003-04-07 22:01:40 +04:00
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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2003-04-07 22:01:40 +04:00
( at your option ) any later version .
2008-02-17 03:57:57 +03:00
2003-04-07 22:01:40 +04:00
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 .
2008-02-17 03:57:57 +03:00
2003-04-07 22:01:40 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-04-07 22:01:40 +04:00
*/
# include "includes.h"
2008-10-20 21:21:10 +04:00
# include "librpc/gen_ndr/ndr_krb5pac.h"
2009-11-27 17:52:57 +03:00
# include "smb_krb5.h"
2010-07-02 02:32:52 +04:00
# include "libads/kerberos_proto.h"
2003-04-07 22:01:40 +04:00
# ifdef HAVE_KRB5
2008-02-17 03:57:20 +03:00
/****************************************************************
2010-05-06 06:45:14 +04:00
Given a username , password and other details , return the
PAC_LOGON_INFO ( the structure containing the important user
information such as groups ) .
2007-07-19 17:34:45 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-08-14 20:04:37 +04:00
NTSTATUS kerberos_return_pac ( TALLOC_CTX * mem_ctx ,
const char * name ,
const char * pass ,
time_t time_offset ,
2007-08-14 23:47:57 +04:00
time_t * expire_time ,
time_t * renew_till_time ,
const char * cache_name ,
2007-10-19 04:40:25 +04:00
bool request_pac ,
bool add_netbios_addr ,
2007-08-14 23:47:57 +04:00
time_t renewable_time ,
2008-10-13 19:27:21 +04:00
const char * impersonate_princ_s ,
2010-05-06 06:45:14 +04:00
struct PAC_LOGON_INFO * * logon_info )
2007-07-19 17:34:45 +04:00
{
krb5_error_code ret ;
NTSTATUS status = NT_STATUS_INVALID_PARAMETER ;
DATA_BLOB tkt , ap_rep , sesskey1 , sesskey2 ;
char * client_princ_out = NULL ;
const char * auth_princ = NULL ;
const char * local_service = NULL ;
const char * cc = " MEMORY:kerberos_return_pac " ;
ZERO_STRUCT ( tkt ) ;
ZERO_STRUCT ( ap_rep ) ;
ZERO_STRUCT ( sesskey1 ) ;
ZERO_STRUCT ( sesskey2 ) ;
if ( ! name | | ! pass ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2007-08-14 23:47:57 +04:00
if ( cache_name ) {
cc = cache_name ;
}
2007-07-19 17:34:45 +04:00
if ( ! strchr_m ( name , ' @ ' ) ) {
auth_princ = talloc_asprintf ( mem_ctx , " %s@%s " , name ,
lp_realm ( ) ) ;
} else {
auth_princ = name ;
}
NT_STATUS_HAVE_NO_MEMORY ( auth_princ ) ;
local_service = talloc_asprintf ( mem_ctx , " %s$@%s " ,
2011-06-09 09:31:03 +04:00
lp_netbios_name ( ) , lp_realm ( ) ) ;
2007-07-19 17:34:45 +04:00
NT_STATUS_HAVE_NO_MEMORY ( local_service ) ;
ret = kerberos_kinit_password_ext ( auth_princ ,
pass ,
time_offset ,
2007-08-14 23:47:57 +04:00
expire_time ,
renew_till_time ,
2007-07-19 17:34:45 +04:00
cc ,
2007-08-14 23:47:57 +04:00
request_pac ,
add_netbios_addr ,
renewable_time ,
2007-07-19 17:34:45 +04:00
& status ) ;
if ( ret ) {
2007-08-14 23:47:57 +04:00
DEBUG ( 1 , ( " kinit failed for '%s' with: %s (%d) \n " ,
auth_princ , error_message ( ret ) , ret ) ) ;
2007-07-19 17:34:45 +04:00
/* status already set */
goto out ;
}
2007-08-14 23:47:57 +04:00
DEBUG ( 10 , ( " got TGT for %s in %s \n " , auth_princ , cc ) ) ;
if ( expire_time ) {
DEBUGADD ( 10 , ( " \t valid until: %s (%d) \n " ,
2008-10-12 01:57:44 +04:00
http_timestring ( talloc_tos ( ) , * expire_time ) ,
2007-08-14 23:47:57 +04:00
( int ) * expire_time ) ) ;
}
if ( renew_till_time ) {
DEBUGADD ( 10 , ( " \t renewable till: %s (%d) \n " ,
2008-10-12 01:57:44 +04:00
http_timestring ( talloc_tos ( ) , * renew_till_time ) ,
2007-08-14 23:47:57 +04:00
( int ) * renew_till_time ) ) ;
}
/* we cannot continue with krb5 when UF_DONT_REQUIRE_PREAUTH is set,
* in that case fallback to NTLM - gd */
if ( expire_time & & renew_till_time & &
( * expire_time = = 0 ) & & ( * renew_till_time = = 0 ) ) {
return NT_STATUS_INVALID_LOGON_TYPE ;
}
2010-07-21 04:00:12 +04:00
ret = cli_krb5_get_ticket ( mem_ctx ,
local_service ,
2007-07-19 17:34:45 +04:00
time_offset ,
& tkt ,
& sesskey1 ,
0 ,
cc ,
2009-11-05 21:10:55 +03:00
NULL ,
impersonate_princ_s ) ;
2007-07-19 17:34:45 +04:00
if ( ret ) {
2007-08-14 23:47:57 +04:00
DEBUG ( 1 , ( " failed to get ticket for %s: %s \n " ,
local_service , error_message ( ret ) ) ) ;
2009-11-12 17:42:03 +03:00
if ( impersonate_princ_s ) {
DEBUGADD ( 1 , ( " tried S4U2SELF impersonation as: %s \n " ,
impersonate_princ_s ) ) ;
}
2007-07-19 17:34:45 +04:00
status = krb5_to_nt_status ( ret ) ;
goto out ;
}
status = ads_verify_ticket ( mem_ctx ,
lp_realm ( ) ,
time_offset ,
& tkt ,
& client_princ_out ,
2010-05-06 06:45:14 +04:00
logon_info ,
2007-07-19 17:34:45 +04:00
& ap_rep ,
& sesskey2 ,
False ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-08-14 23:47:57 +04:00
DEBUG ( 1 , ( " ads_verify_ticket failed: %s \n " ,
nt_errstr ( status ) ) ) ;
2007-07-19 17:34:45 +04:00
goto out ;
}
2010-05-06 06:45:14 +04:00
if ( ! * logon_info ) {
2007-08-14 23:47:57 +04:00
DEBUG ( 1 , ( " no PAC \n " ) ) ;
2007-07-19 17:34:45 +04:00
status = NT_STATUS_INVALID_PARAMETER ;
goto out ;
}
out :
2007-08-14 23:47:57 +04:00
if ( cc ! = cache_name ) {
ads_kdestroy ( cc ) ;
}
2007-07-19 17:34:45 +04:00
data_blob_free ( & tkt ) ;
data_blob_free ( & ap_rep ) ;
data_blob_free ( & sesskey1 ) ;
data_blob_free ( & sesskey2 ) ;
2009-03-18 08:23:27 +03:00
TALLOC_FREE ( client_princ_out ) ;
2007-07-19 17:34:45 +04:00
return status ;
}
2003-04-07 22:01:40 +04:00
# endif