1998-11-12 07:06:48 +00:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
change a password in a local smbpasswd file
Copyright ( C ) Andrew Tridgell 1998
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 .
*/
# include "includes.h"
/*************************************************************
add a new user to the local smbpasswd file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 13:27:58 +00:00
static BOOL add_new_user ( char * user_name , uid_t uid , BOOL trust_account ,
BOOL disable_user , BOOL set_no_password ,
uchar * new_p16 , uchar * new_nt_p16 )
1998-11-12 07:06:48 +00:00
{
struct smb_passwd new_smb_pwent ;
/* Create a new smb passwd entry and set it to the given password. */
1999-12-13 13:27:58 +00:00
new_smb_pwent . smb_userid = uid ;
new_smb_pwent . smb_name = user_name ;
1998-11-12 07:06:48 +00:00
new_smb_pwent . smb_passwd = NULL ;
new_smb_pwent . smb_nt_passwd = NULL ;
1999-12-13 13:27:58 +00:00
new_smb_pwent . acct_ctrl = ( trust_account ? ACB_WSTRUST : ACB_NORMAL ) ;
1998-11-12 07:06:48 +00:00
1999-12-13 13:27:58 +00:00
if ( disable_user ) {
new_smb_pwent . acct_ctrl | = ACB_DISABLED ;
} else if ( set_no_password ) {
new_smb_pwent . acct_ctrl | = ACB_PWNOTREQ ;
} else {
1998-11-12 07:06:48 +00:00
new_smb_pwent . smb_passwd = new_p16 ;
new_smb_pwent . smb_nt_passwd = new_nt_p16 ;
}
return add_smbpwd_entry ( & new_smb_pwent ) ;
}
/*************************************************************
1999-12-13 13:27:58 +00:00
change a password entry in the local smbpasswd file
1998-11-12 07:06:48 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 13:27:58 +00:00
BOOL local_password_change ( char * user_name , BOOL trust_account , BOOL add_user ,
BOOL enable_user , BOOL disable_user , BOOL set_no_password ,
char * new_passwd ,
char * err_str , size_t err_str_len ,
char * msg_str , size_t msg_str_len )
1998-11-12 07:06:48 +00:00
{
1999-12-13 13:27:58 +00:00
struct passwd * pwd ;
void * vp ;
1998-11-12 07:06:48 +00:00
struct smb_passwd * smb_pwent ;
1999-12-13 13:27:58 +00:00
uchar new_p16 [ 16 ] ;
uchar new_nt_p16 [ 16 ] ;
1998-11-12 07:06:48 +00:00
1998-11-12 23:49:32 +00:00
* err_str = ' \0 ' ;
* msg_str = ' \0 ' ;
1999-12-13 13:27:58 +00:00
pwd = sys_getpwnam ( user_name ) ;
1998-11-12 07:06:48 +00:00
/*
1999-12-13 13:27:58 +00:00
* Check for a local account .
1998-11-12 07:06:48 +00:00
*/
1999-12-13 13:27:58 +00:00
if ( ! pwd ) {
slprintf ( err_str , err_str_len - 1 , " User %s does not \
exist in system password file ( usually / etc / passwd ) . Cannot add \
account without a valid local system user . \ n " , user_name);
1998-11-12 07:06:48 +00:00
return False ;
}
/* Calculate the MD4 hash (NT compatible) of the new password. */
nt_lm_owf_gen ( new_passwd , new_nt_p16 , new_p16 ) ;
1999-12-13 13:27:58 +00:00
/*
* Open the smbpaswd file .
*/
vp = startsmbpwent ( True ) ;
if ( ! vp & & errno = = ENOENT ) {
FILE * fp ;
slprintf ( msg_str , msg_str_len - 1 ,
" smbpasswd file did not exist - attempting to create it. \n " ) ;
fp = sys_fopen ( lp_smb_passwd_file ( ) , " w " ) ;
if ( fp ) {
fprintf ( fp , " # Samba SMB password file \n " ) ;
fclose ( fp ) ;
vp = startsmbpwent ( True ) ;
}
}
if ( ! vp ) {
slprintf ( err_str , err_str_len - 1 , " Cannot open file %s. Error was %s \n " ,
lp_smb_passwd_file ( ) , strerror ( errno ) ) ;
return False ;
}
1998-11-12 07:06:48 +00:00
/* Get the smb passwd entry for this user */
smb_pwent = getsmbpwnam ( user_name ) ;
1999-12-13 13:27:58 +00:00
if ( smb_pwent = = NULL ) {
if ( add_user = = False ) {
1998-11-12 23:49:32 +00:00
slprintf ( err_str , err_str_len - 1 ,
1999-12-13 13:27:58 +00:00
" Failed to find entry for user %s. \n " , pwd - > pw_name ) ;
endsmbpwent ( vp ) ;
1998-11-12 07:06:48 +00:00
return False ;
}
1999-12-13 13:27:58 +00:00
if ( add_new_user ( user_name , pwd - > pw_uid , trust_account , disable_user ,
set_no_password , new_p16 , new_nt_p16 ) ) {
1998-11-12 23:49:32 +00:00
slprintf ( msg_str , msg_str_len - 1 , " Added user %s. \n " , user_name ) ;
1999-12-13 13:27:58 +00:00
endsmbpwent ( vp ) ;
1998-11-12 07:06:48 +00:00
return True ;
1999-12-13 13:27:58 +00:00
} else {
1998-11-12 23:49:32 +00:00
slprintf ( err_str , err_str_len - 1 , " Failed to add entry for user %s. \n " , user_name ) ;
1999-12-13 13:27:58 +00:00
endsmbpwent ( vp ) ;
1998-11-12 07:06:48 +00:00
return False ;
}
1999-12-13 13:27:58 +00:00
} else {
1998-11-12 07:06:48 +00:00
/* the entry already existed */
add_user = False ;
}
/*
* We are root - just write the new password
* and the valid last change time .
*/
1999-12-13 13:27:58 +00:00
if ( disable_user ) {
smb_pwent - > acct_ctrl | = ACB_DISABLED ;
} else if ( enable_user ) {
if ( smb_pwent - > smb_passwd = = NULL ) {
smb_pwent - > smb_passwd = new_p16 ;
smb_pwent - > smb_nt_passwd = new_nt_p16 ;
}
smb_pwent - > acct_ctrl & = ~ ACB_DISABLED ;
} else if ( set_no_password ) {
smb_pwent - > acct_ctrl | = ACB_PWNOTREQ ;
/* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
smb_pwent - > smb_passwd = NULL ;
smb_pwent - > smb_nt_passwd = NULL ;
} else {
/*
* If we ' re dealing with setting a completely empty user account
* ie . One with a password of ' XXXX ' , but not set disabled ( like
* an account created from scratch ) then if the old password was
* ' XX ' s then getsmbpwent will have set the ACB_DISABLED flag .
* We remove that as we ' re giving this user their first password
* and the decision hasn ' t really been made to disable them ( ie .
* don ' t create them disabled ) . JRA .
*/
if ( ( smb_pwent - > smb_passwd = = NULL ) & & ( smb_pwent - > acct_ctrl & ACB_DISABLED ) )
smb_pwent - > acct_ctrl & = ~ ACB_DISABLED ;
smb_pwent - > acct_ctrl & = ~ ACB_PWNOTREQ ;
smb_pwent - > smb_passwd = new_p16 ;
smb_pwent - > smb_nt_passwd = new_nt_p16 ;
1998-11-12 07:06:48 +00:00
}
1999-12-13 13:27:58 +00:00
if ( mod_smbpwd_entry ( smb_pwent , True ) = = False ) {
1998-11-12 23:49:32 +00:00
slprintf ( err_str , err_str_len - 1 , " Failed to modify entry for user %s. \n " ,
1999-12-13 13:27:58 +00:00
pwd - > pw_name ) ;
endsmbpwent ( vp ) ;
1998-11-12 07:06:48 +00:00
return False ;
}
1999-12-13 13:27:58 +00:00
endsmbpwent ( vp ) ;
1998-11-12 07:06:48 +00:00
return True ;
}