2001-04-24 20:00:12 +00:00
/* Unix NT password database implementation, version 0.7.5.
*
* 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 2 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 , write to the Free Software Foundation , Inc . , 675
* Mass Ave , Cambridge , MA 0213 9 , USA .
*/
/* indicate the following groups are defined */
# define PAM_SM_AUTH
# include "includes.h"
# include "debug.h"
# ifndef LINUX
/* This is only used in the Sun implementation. */
# include <security/pam_appl.h>
# endif /* LINUX */
# include <security/pam_modules.h>
# include "general.h"
# include "support.h"
# define AUTH_RETURN \
do { \
if ( ret_data ) { \
* ret_data = retval ; \
pam_set_data ( pamh , " smb_setcred_return " \
, ( void * ) ret_data , NULL ) ; \
} \
return retval ; \
} while ( 0 )
static int _smb_add_user ( pam_handle_t * pamh , unsigned int ctrl ,
2002-01-12 23:12:13 +00:00
const char * name , SAM_ACCOUNT * sampass , BOOL exist ) ;
2001-04-24 20:00:12 +00:00
2002-07-15 10:35:28 +00:00
2001-04-24 20:00:12 +00:00
/*
* pam_sm_authenticate ( ) authenticates users against the samba password file .
*
* First , obtain the password from the user . Then use a
* routine in ' support . c ' to authenticate the user .
*/
# define _SMB_AUTHTOK "-SMB-PASS"
int pam_sm_authenticate ( pam_handle_t * pamh , int flags ,
int argc , const char * * argv )
{
unsigned int ctrl ;
int retval , * ret_data = NULL ;
2002-01-12 23:12:13 +00:00
SAM_ACCOUNT * sampass = NULL ;
extern BOOL in_client ;
2001-04-24 20:00:12 +00:00
const char * name ;
2002-01-12 23:12:13 +00:00
BOOL found ;
2001-04-24 20:00:12 +00:00
/* Points to memory managed by the PAM library. Do not free. */
2002-07-15 10:35:28 +00:00
char * p = NULL ;
2001-04-24 20:00:12 +00:00
/* Samba initialization. */
setup_logging ( " pam_smbpass " , False ) ;
in_client = True ;
ctrl = set_ctrl ( flags , argc , argv ) ;
/* Get a few bytes so we can pass our return value to
2002-01-12 23:12:13 +00:00
pam_sm_setcred ( ) . */
2001-04-24 20:00:12 +00:00
ret_data = malloc ( sizeof ( int ) ) ;
/* get the username */
retval = pam_get_user ( pamh , & name , " Username: " ) ;
if ( retval ! = PAM_SUCCESS ) {
if ( on ( SMB_DEBUG , ctrl ) ) {
_log_err ( LOG_DEBUG , " auth: could not identify user " ) ;
}
AUTH_RETURN ;
}
if ( on ( SMB_DEBUG , ctrl ) ) {
_log_err ( LOG_DEBUG , " username [%s] obtained " , name ) ;
}
2001-12-11 23:44:33 +00:00
if ( ! initialize_password_db ( True ) ) {
2001-04-24 20:00:12 +00:00
_log_err ( LOG_ALERT , " Cannot access samba password database " ) ;
retval = PAM_AUTHINFO_UNAVAIL ;
AUTH_RETURN ;
}
2002-01-12 23:12:13 +00:00
pdb_init_sam ( & sampass ) ;
found = pdb_getsampwnam ( sampass , name ) ;
2001-04-24 20:00:12 +00:00
if ( on ( SMB_MIGRATE , ctrl ) ) {
2002-01-12 23:12:13 +00:00
retval = _smb_add_user ( pamh , ctrl , name , sampass , found ) ;
pdb_free_sam ( & sampass ) ;
2001-04-24 20:00:12 +00:00
AUTH_RETURN ;
}
2002-01-12 23:12:13 +00:00
if ( ! found ) {
2001-04-24 20:00:12 +00:00
_log_err ( LOG_ALERT , " Failed to find entry for user %s. " , name ) ;
retval = PAM_USER_UNKNOWN ;
2002-01-12 23:12:13 +00:00
pdb_free_sam ( & sampass ) ;
sampass = NULL ;
2001-04-24 20:00:12 +00:00
AUTH_RETURN ;
}
/* if this user does not have a password... */
2002-01-12 23:12:13 +00:00
if ( _smb_blankpasswd ( ctrl , sampass ) ) {
pdb_free_sam ( & sampass ) ;
2001-04-24 20:00:12 +00:00
retval = PAM_SUCCESS ;
AUTH_RETURN ;
}
/* get this user's authentication token */
2002-01-12 23:12:13 +00:00
retval = _smb_read_password ( pamh , ctrl , NULL , " Password: " , NULL , _SMB_AUTHTOK , & p ) ;
2001-04-24 20:00:12 +00:00
if ( retval ! = PAM_SUCCESS ) {
_log_err ( LOG_CRIT , " auth: no password provided for [%s] "
, name ) ;
2002-01-12 23:12:13 +00:00
pdb_free_sam ( & sampass ) ;
2001-04-24 20:00:12 +00:00
AUTH_RETURN ;
}
/* verify the password of this user */
2002-01-12 23:12:13 +00:00
retval = _smb_verify_password ( pamh , sampass , p , ctrl ) ;
pdb_free_sam ( & sampass ) ;
2001-04-24 20:00:12 +00:00
p = NULL ;
AUTH_RETURN ;
}
/*
* This function is for setting samba credentials . If anyone comes up
* with any credentials they think should be set , let me know .
*/
int pam_sm_setcred ( pam_handle_t * pamh , int flags ,
int argc , const char * * argv )
{
int retval , * pretval = NULL ;
retval = PAM_SUCCESS ;
pam_get_data ( pamh , " smb_setcred_return " , ( const void * * ) & pretval ) ;
if ( pretval ) {
retval = * pretval ;
2002-01-12 23:12:13 +00:00
SAFE_FREE ( pretval ) ;
2001-04-24 20:00:12 +00:00
}
pam_set_data ( pamh , " smb_setcred_return " , NULL , NULL ) ;
return retval ;
}
/* Helper function for adding a user to the db. */
static int _smb_add_user ( pam_handle_t * pamh , unsigned int ctrl ,
2002-01-12 23:12:13 +00:00
const char * name , SAM_ACCOUNT * sampass , BOOL exist )
2001-04-24 20:00:12 +00:00
{
pstring err_str ;
pstring msg_str ;
const char * pass = NULL ;
int retval ;
err_str [ 0 ] = ' \0 ' ;
msg_str [ 0 ] = ' \0 ' ;
/* Get the authtok; if we don't have one, silently fail. */
retval = pam_get_item ( pamh , PAM_AUTHTOK , ( const void * * ) & pass ) ;
if ( retval ! = PAM_SUCCESS ) {
_log_err ( LOG_ALERT
, " pam_get_item returned error to pam_sm_authenticate " ) ;
return PAM_AUTHTOK_RECOVER_ERR ;
} else if ( pass = = NULL ) {
return PAM_AUTHTOK_RECOVER_ERR ;
}
/* Add the user to the db if they aren't already there. */
2002-01-12 23:12:13 +00:00
if ( ! exist ) {
retval = local_password_change ( name , LOCAL_ADD_USER ,
2001-04-24 20:00:12 +00:00
pass , err_str ,
sizeof ( err_str ) ,
msg_str , sizeof ( msg_str ) ) ;
if ( ! retval & & * err_str )
{
err_str [ PSTRING_LEN - 1 ] = ' \0 ' ;
make_remark ( pamh , ctrl , PAM_ERROR_MSG , err_str ) ;
}
else if ( * msg_str )
{
msg_str [ PSTRING_LEN - 1 ] = ' \0 ' ;
make_remark ( pamh , ctrl , PAM_TEXT_INFO , msg_str ) ;
}
pass = NULL ;
return PAM_IGNORE ;
2002-01-12 23:12:13 +00:00
}
else {
2001-04-24 20:00:12 +00:00
/* Change the user's password IFF it's null. */
2002-01-12 23:12:13 +00:00
if ( ( pdb_get_lanman_passwd ( sampass ) = = NULL ) & & ( pdb_get_acct_ctrl ( sampass ) & ACB_PWNOTREQ ) )
2001-04-24 20:00:12 +00:00
{
2002-01-12 23:12:13 +00:00
retval = local_password_change ( name , 0 , pass , err_str , sizeof ( err_str ) ,
2001-04-24 20:00:12 +00:00
msg_str , sizeof ( msg_str ) ) ;
if ( ! retval & & * err_str )
{
err_str [ PSTRING_LEN - 1 ] = ' \0 ' ;
make_remark ( pamh , ctrl , PAM_ERROR_MSG , err_str ) ;
}
else if ( * msg_str )
{
msg_str [ PSTRING_LEN - 1 ] = ' \0 ' ;
make_remark ( pamh , ctrl , PAM_TEXT_INFO , msg_str ) ;
}
}
2002-01-12 23:12:13 +00:00
}
2001-04-24 20:00:12 +00:00
pass = NULL ;
return PAM_IGNORE ;
}
/* static module data */
# ifdef PAM_STATIC
struct pam_module _pam_smbpass_auth_modstruct = {
" pam_smbpass " ,
pam_sm_authenticate ,
pam_sm_setcred ,
NULL ,
NULL ,
NULL ,
NULL
} ;
# endif