2005-09-15 03:58:14 +04:00
/*
Unix SMB / CIFS implementation .
Call out to a shell script for an authentication check .
Copyright ( C ) Jeremy Allison 2005.
2010-04-11 13:50:55 +04:00
2005-09-15 03:58:14 +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
2005-09-15 03:58:14 +04:00
( at your option ) any later version .
2010-04-11 13:50:55 +04:00
2005-09-15 03:58:14 +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 .
2010-04-11 13:50:55 +04:00
2005-09-15 03:58:14 +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/>.
2005-09-15 03:58:14 +04:00
*/
# include "includes.h"
2011-03-25 04:28:05 +03:00
# include "auth.h"
2005-09-15 03:58:14 +04:00
# undef malloc
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_AUTH
/* Create a string containing the supplied :
* domain \ n
* user \ n
* ascii hex challenge \ n
* ascii hex LM response \ n
* ascii hex NT response \ n \ 0
* and execute a shell script to check this .
* Allows external programs to create users on demand .
* Script returns zero on success , non - zero on fail .
*/
static NTSTATUS script_check_user_credentials ( const struct auth_context * auth_context ,
void * my_private_data ,
TALLOC_CTX * mem_ctx ,
2010-01-10 16:16:04 +03:00
const struct auth_usersupplied_info * user_info ,
2010-01-10 16:24:22 +03:00
struct auth_serversupplied_info * * server_info )
2005-09-15 03:58:14 +04:00
{
const char * script = lp_parm_const_string ( GLOBAL_SECTION_SNUM , " auth_script " , " script " , NULL ) ;
char * secret_str ;
size_t secret_str_len ;
char hex_str [ 49 ] ;
int ret , i ;
if ( ! script ) {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( ! user_info ) {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( ! auth_context ) {
DEBUG ( 3 , ( " script_check_user_credentials: no auth_info ! \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
2010-06-01 15:11:14 +04:00
secret_str_len = strlen ( user_info - > mapped . domain_name ) + 1 +
2010-06-01 14:27:03 +04:00
strlen ( user_info - > client . account_name ) + 1 +
2005-09-15 03:58:14 +04:00
16 + 1 + /* 8 bytes of challenge going to 16 */
48 + 1 + /* 24 bytes of challenge going to 48 */
48 + 1 ;
2006-08-17 15:54:23 +04:00
secret_str = ( char * ) malloc ( secret_str_len ) ;
2005-09-15 03:58:14 +04:00
if ( ! secret_str ) {
return NT_STATUS_NO_MEMORY ;
}
2012-03-30 04:13:07 +04:00
if ( strlcpy ( secret_str , user_info - > mapped . domain_name , secret_str_len ) > = secret_str_len ) {
/* Truncate. */
goto cat_out ;
}
if ( strlcat ( secret_str , " \n " , secret_str_len ) > = secret_str_len ) {
/* Truncate. */
goto cat_out ;
}
if ( strlcat ( secret_str , user_info - > client . account_name , secret_str_len ) > = secret_str_len ) {
/* Truncate. */
goto cat_out ;
}
if ( strlcat ( secret_str , " \n " , secret_str_len ) > = secret_str_len ) {
/* Truncate. */
goto cat_out ;
}
2005-09-15 03:58:14 +04:00
for ( i = 0 ; i < 8 ; i + + ) {
slprintf ( & hex_str [ i * 2 ] , 3 , " %02X " , auth_context - > challenge . data [ i ] ) ;
}
2012-03-30 04:13:07 +04:00
if ( strlcat ( secret_str , hex_str , secret_str_len ) > = secret_str_len ) {
/* Truncate. */
goto cat_out ;
}
if ( strlcat ( secret_str , " \n " , secret_str_len ) > = secret_str_len ) {
/* Truncate. */
goto cat_out ;
}
2005-09-15 03:58:14 +04:00
2010-06-01 15:52:01 +04:00
if ( user_info - > password . response . lanman . data ) {
2005-09-15 03:58:14 +04:00
for ( i = 0 ; i < 24 ; i + + ) {
2010-06-01 15:52:01 +04:00
slprintf ( & hex_str [ i * 2 ] , 3 , " %02X " , user_info - > password . response . lanman . data [ i ] ) ;
2005-09-15 03:58:14 +04:00
}
2012-03-30 04:13:07 +04:00
if ( strlcat ( secret_str , hex_str , secret_str_len ) > = secret_str_len ) {
/* Truncate. */
goto cat_out ;
}
}
if ( strlcat ( secret_str , " \n " , secret_str_len ) > = secret_str_len ) {
/* Truncate. */
goto cat_out ;
2005-09-15 03:58:14 +04:00
}
2010-06-01 15:52:01 +04:00
if ( user_info - > password . response . nt . data ) {
2005-09-15 03:58:14 +04:00
for ( i = 0 ; i < 24 ; i + + ) {
2010-06-01 15:52:01 +04:00
slprintf ( & hex_str [ i * 2 ] , 3 , " %02X " , user_info - > password . response . nt . data [ i ] ) ;
2005-09-15 03:58:14 +04:00
}
2012-03-30 04:13:07 +04:00
if ( strlcat ( secret_str , hex_str , secret_str_len ) > = secret_str_len ) {
/* Truncate. */
goto cat_out ;
}
}
if ( strlcat ( secret_str , " \n " , secret_str_len ) > = secret_str_len ) {
/* Truncate. */
goto cat_out ;
2005-09-15 03:58:14 +04:00
}
DEBUG ( 10 , ( " script_check_user_credentials: running %s with parameters: \n %s \n " ,
script , secret_str ) ) ;
ret = smbrunsecret ( script , secret_str ) ;
SAFE_FREE ( secret_str ) ;
if ( ret ) {
DEBUG ( 1 , ( " script_check_user_credentials: failed to authenticate %s \\ %s \n " ,
2010-06-01 15:11:14 +04:00
user_info - > mapped . domain_name , user_info - > client . account_name ) ) ;
2005-09-15 03:58:14 +04:00
/* auth failed. */
return NT_STATUS_NO_SUCH_USER ;
}
/* Cause the auth system to keep going.... */
return NT_STATUS_NOT_IMPLEMENTED ;
2012-03-30 04:13:07 +04:00
cat_out :
SAFE_FREE ( secret_str ) ;
return NT_STATUS_NO_MEMORY ;
2005-09-15 03:58:14 +04:00
}
/* module initialisation */
static NTSTATUS auth_init_script ( struct auth_context * auth_context , const char * param , auth_methods * * auth_method )
{
2010-04-11 14:37:48 +04:00
struct auth_methods * result ;
2011-06-07 05:44:43 +04:00
result = talloc_zero ( auth_context , struct auth_methods ) ;
2010-04-11 14:37:48 +04:00
if ( result = = NULL ) {
2005-09-15 03:58:14 +04:00
return NT_STATUS_NO_MEMORY ;
}
2010-04-11 14:37:48 +04:00
result - > name = " script " ;
result - > auth = script_check_user_credentials ;
2005-09-15 03:58:14 +04:00
if ( param & & * param ) {
/* we load the 'fallback' module - if script isn't here, call this
module */
2006-09-19 05:25:52 +04:00
auth_methods * priv ;
if ( ! load_auth_module ( auth_context , param , & priv ) ) {
2005-09-15 03:58:14 +04:00
return NT_STATUS_UNSUCCESSFUL ;
}
2010-04-11 14:37:48 +04:00
result - > private_data = ( void * ) priv ;
2005-09-15 03:58:14 +04:00
}
2010-04-11 14:37:48 +04:00
* auth_method = result ;
2005-09-15 03:58:14 +04:00
return NT_STATUS_OK ;
}
2006-12-20 04:07:21 +03:00
NTSTATUS auth_script_init ( void ) ;
2005-09-15 03:58:14 +04:00
NTSTATUS auth_script_init ( void )
{
return smb_register_auth ( AUTH_INTERFACE_VERSION , " script " , auth_init_script ) ;
}