2004-05-02 16:13:16 +04:00
/*
* Unix SMB / CIFS implementation .
* Generate AFS tickets
* Copyright ( C ) Volker Lendecke 2004
*
* 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
2004-05-02 16:13:16 +04:00
* ( 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
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2004-05-02 16:13:16 +04:00
*/
# include "includes.h"
# ifdef WITH_FAKE_KASERVER
2005-10-14 02:11:18 +04:00
# define NO_ASN1_TYPEDEFS 1
2011-07-15 17:27:07 +04:00
# include "system/filesys.h"
2009-05-04 00:13:36 +04:00
# include <afs/param.h>
2004-05-02 16:13:16 +04:00
# include <afs/stds.h>
# include <afs/afs.h>
# include <afs/auth.h>
# include <afs/venus.h>
# include <asm/unistd.h>
# include <openssl/des.h>
2004-06-10 21:13:30 +04:00
# include <sys/syscall.h>
2004-05-02 16:13:16 +04:00
2004-06-10 21:13:30 +04:00
int afs_syscall ( int subcall ,
2011-07-15 18:14:33 +04:00
const char * path ,
2004-06-10 21:13:30 +04:00
int cmd ,
char * cmarg ,
int follow )
{
2009-05-04 00:13:36 +04:00
/*
2004-06-10 21:13:30 +04:00
return ( syscall ( SYS_afs_syscall , subcall , path , cmd , cmarg , follow ) ) ;
2009-05-04 00:13:36 +04:00
*/
int errcode ;
2011-07-15 17:34:29 +04:00
int proc_afs_file ;
2009-05-04 00:13:36 +04:00
struct afsprocdata afs_syscall_data ;
afs_syscall_data . syscall = subcall ;
afs_syscall_data . param1 = ( long ) path ;
afs_syscall_data . param2 = cmd ;
afs_syscall_data . param3 = ( long ) cmarg ;
afs_syscall_data . param4 = follow ;
2011-07-15 17:34:29 +04:00
proc_afs_file = open ( PROC_SYSCALL_FNAME , O_RDWR ) ;
2009-05-04 00:13:36 +04:00
if ( proc_afs_file < 0 )
proc_afs_file = open ( PROC_SYSCALL_ARLA_FNAME , O_RDWR ) ;
if ( proc_afs_file < 0 )
return - 1 ;
errcode = ioctl ( proc_afs_file , VIOC_SYSCALL , & afs_syscall_data ) ;
close ( proc_afs_file ) ;
return errcode ;
2004-06-10 21:13:30 +04:00
}
2004-05-02 16:13:16 +04:00
struct ClearToken {
uint32 AuthHandle ;
char HandShakeKey [ 8 ] ;
uint32 ViceId ;
uint32 BeginTimestamp ;
uint32 EndTimestamp ;
} ;
2007-10-19 04:40:25 +04:00
static bool afs_decode_token ( const char * string , char * * cell ,
2004-05-02 16:13:16 +04:00
DATA_BLOB * ticket , struct ClearToken * ct )
{
DATA_BLOB blob ;
struct ClearToken result_ct ;
2008-01-23 13:04:10 +03:00
char * saveptr ;
2004-05-02 16:13:16 +04:00
2004-12-21 00:14:28 +03:00
char * s = SMB_STRDUP ( string ) ;
2004-05-02 16:13:16 +04:00
char * t ;
2008-01-23 13:04:10 +03:00
if ( ( t = strtok_r ( s , " \n " , & saveptr ) ) = = NULL ) {
DEBUG ( 10 , ( " strtok_r failed \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
2004-12-21 00:14:28 +03:00
* cell = SMB_STRDUP ( t ) ;
2004-05-02 16:13:16 +04:00
2008-01-23 13:04:10 +03:00
if ( ( t = strtok_r ( NULL , " \n " , & saveptr ) ) = = NULL ) {
DEBUG ( 10 , ( " strtok_r failed \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
if ( sscanf ( t , " %u " , & result_ct . AuthHandle ) ! = 1 ) {
DEBUG ( 10 , ( " sscanf AuthHandle failed \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
2008-01-23 13:04:10 +03:00
if ( ( t = strtok_r ( NULL , " \n " , & saveptr ) ) = = NULL ) {
DEBUG ( 10 , ( " strtok_r failed \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
blob = base64_decode_data_blob ( t ) ;
if ( ( blob . data = = NULL ) | |
( blob . length ! = sizeof ( result_ct . HandShakeKey ) ) ) {
2011-07-15 17:34:29 +04:00
DEBUG ( 10 , ( " invalid key: %x/%lu \n " , ( uint8_t ) * blob . data ,
( unsigned long ) blob . length ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
memcpy ( result_ct . HandShakeKey , blob . data , blob . length ) ;
data_blob_free ( & blob ) ;
2008-01-23 13:04:10 +03:00
if ( ( t = strtok_r ( NULL , " \n " , & saveptr ) ) = = NULL ) {
DEBUG ( 10 , ( " strtok_r failed \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
if ( sscanf ( t , " %u " , & result_ct . ViceId ) ! = 1 ) {
DEBUG ( 10 , ( " sscanf ViceId failed \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
2008-01-23 13:04:10 +03:00
if ( ( t = strtok_r ( NULL , " \n " , & saveptr ) ) = = NULL ) {
DEBUG ( 10 , ( " strtok_r failed \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
if ( sscanf ( t , " %u " , & result_ct . BeginTimestamp ) ! = 1 ) {
DEBUG ( 10 , ( " sscanf BeginTimestamp failed \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
2008-01-23 13:04:10 +03:00
if ( ( t = strtok_r ( NULL , " \n " , & saveptr ) ) = = NULL ) {
DEBUG ( 10 , ( " strtok_r failed \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
if ( sscanf ( t , " %u " , & result_ct . EndTimestamp ) ! = 1 ) {
DEBUG ( 10 , ( " sscanf EndTimestamp failed \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
2008-01-23 13:04:10 +03:00
if ( ( t = strtok_r ( NULL , " \n " , & saveptr ) ) = = NULL ) {
DEBUG ( 10 , ( " strtok_r failed \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
blob = base64_decode_data_blob ( t ) ;
if ( blob . data = = NULL ) {
DEBUG ( 10 , ( " Could not get ticket \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
* ticket = blob ;
* ct = result_ct ;
2011-07-15 17:35:18 +04:00
return true ;
2004-05-02 16:13:16 +04:00
}
/*
Put an AFS token into the Kernel so that it can authenticate against
the AFS server . This assumes correct local uid settings .
This is currently highly Linux and OpenAFS - specific . The correct API
call for this would be ktc_SetToken . But to do that we would have to
import a REALLY big bunch of libraries which I would currently like
to avoid .
*/
2007-10-19 04:40:25 +04:00
static bool afs_settoken ( const char * cell ,
2004-05-02 16:13:16 +04:00
const struct ClearToken * ctok ,
DATA_BLOB ticket )
{
int ret ;
struct {
char * in , * out ;
uint16 in_size , out_size ;
} iob ;
char buf [ 1024 ] ;
char * p = buf ;
int tmp ;
memcpy ( p , & ticket . length , sizeof ( uint32 ) ) ;
p + = sizeof ( uint32 ) ;
memcpy ( p , ticket . data , ticket . length ) ;
p + = ticket . length ;
tmp = sizeof ( struct ClearToken ) ;
memcpy ( p , & tmp , sizeof ( uint32 ) ) ;
p + = sizeof ( uint32 ) ;
memcpy ( p , ctok , tmp ) ;
p + = tmp ;
tmp = 0 ;
memcpy ( p , & tmp , sizeof ( uint32 ) ) ;
p + = sizeof ( uint32 ) ;
tmp = strlen ( cell ) ;
if ( tmp > = MAXKTCREALMLEN ) {
DEBUG ( 1 , ( " Realm too long \n " ) ) ;
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
strncpy ( p , cell , tmp ) ;
p + = tmp ;
* p = 0 ;
p + = 1 ;
iob . in = buf ;
iob . in_size = PTR_DIFF ( p , buf ) ;
iob . out = buf ;
iob . out_size = sizeof ( buf ) ;
#if 0
file_save ( " /tmp/ioctlbuf " , iob . in , iob . in_size ) ;
# endif
ret = afs_syscall ( AFSCALL_PIOCTL , 0 , VIOCSETTOK , ( char * ) & iob , 0 ) ;
DEBUG ( 10 , ( " afs VIOCSETTOK returned %d \n " , ret ) ) ;
return ( ret = = 0 ) ;
}
2007-10-19 04:40:25 +04:00
bool afs_settoken_str ( const char * token_string )
2004-05-02 16:13:16 +04:00
{
DATA_BLOB ticket ;
struct ClearToken ct ;
2007-10-19 04:40:25 +04:00
bool result ;
2004-05-02 16:13:16 +04:00
char * cell ;
if ( ! afs_decode_token ( token_string , & cell , & ticket , & ct ) )
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
2010-02-13 10:18:53 +03:00
if ( geteuid ( ) ! = sec_initial_uid ( ) )
2004-05-02 16:13:16 +04:00
ct . ViceId = getuid ( ) ;
result = afs_settoken ( cell , & ct , ticket ) ;
SAFE_FREE ( cell ) ;
data_blob_free ( & ticket ) ;
return result ;
}
# else
2007-10-19 04:40:25 +04:00
bool afs_settoken_str ( const char * token_string )
2004-05-02 16:13:16 +04:00
{
2011-07-15 17:35:18 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
# endif