2000-05-09 15:43:00 +04:00
/*
Unix SMB / Netbios implementation .
Version 3.0
2001-11-23 03:14:04 +03:00
Winbind daemon - pam auth funcions
2000-05-09 15:43:00 +04:00
Copyright ( C ) Andrew Tridgell 2000
2001-08-23 06:55:42 +04:00
Copyright ( C ) Tim Potter 2001
Copyright ( C ) Andrew Bartlett 2001
2000-05-09 15:43:00 +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
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 "winbindd.h"
/* Return a password structure from a username. Specify whether cached data
can be returned . */
enum winbindd_result winbindd_pam_auth ( struct winbindd_cli_state * state )
{
2001-09-04 11:13:01 +04:00
NTSTATUS result ;
2001-11-05 03:21:17 +03:00
fstring name_domain , name_user ;
2001-05-17 10:08:49 +04:00
int passlen ;
2001-08-12 15:19:57 +04:00
unsigned char trust_passwd [ 16 ] ;
time_t last_change_time ;
2001-10-31 13:46:25 +03:00
auth_usersupplied_info * user_info ;
2001-11-05 03:21:17 +03:00
uint32 smb_uid_low ;
NET_USER_INFO_3 info3 ;
NET_ID_INFO_CTR ctr ;
struct cli_state * cli ;
This is my 'Authentication Rewrite' version 1.01, mostly as submitted to
samba-technical a few weeks ago.
The idea here is to standardize the checking of user names and passwords,
thereby ensuring that all authtentications pass the same standards. The
interface currently implemented in as
nt_status = check_password(user_info, server_info)
where user_info contains (mostly) the authentication data, and server_info
contains things like the user-id they got, and their resolved user name.
The current ugliness with the way the structures are created will be killed
the next revision, when they will be created and malloced by creator functions.
This patch also includes the first implementation of NTLMv2 in HEAD, but which
needs some more testing. We also add a hack to allow plaintext passwords to be
compared with smbpasswd, not the system password database.
Finally, this patch probably reintroduces the PAM accounts bug we had in
2.2.0, I'll fix that once this hits the tree. (I've just finished testing
it on a wide variety of platforms, so I want to get this patch in).
(This used to be commit b30b6202f31d339b48d51c0d38174cafd1cfcd42)
2001-08-03 17:09:23 +04:00
2001-05-07 08:32:40 +04:00
DEBUG ( 3 , ( " [%5d]: pam auth %s \n " , state - > pid ,
state - > request . data . auth . user ) ) ;
2000-05-09 15:43:00 +04:00
/* Parse domain and username */
2001-05-17 10:08:49 +04:00
2001-05-07 08:32:40 +04:00
parse_domain_user ( state - > request . data . auth . user , name_domain ,
name_user ) ;
2000-05-09 15:43:00 +04:00
/* don't allow the null domain */
2001-05-17 10:08:49 +04:00
if ( strcmp ( name_domain , " " ) = = 0 )
return WINBINDD_ERROR ;
2000-05-09 15:43:00 +04:00
2001-05-17 10:08:49 +04:00
passlen = strlen ( state - > request . data . auth . pass ) ;
This is my 'Authentication Rewrite' version 1.01, mostly as submitted to
samba-technical a few weeks ago.
The idea here is to standardize the checking of user names and passwords,
thereby ensuring that all authtentications pass the same standards. The
interface currently implemented in as
nt_status = check_password(user_info, server_info)
where user_info contains (mostly) the authentication data, and server_info
contains things like the user-id they got, and their resolved user name.
The current ugliness with the way the structures are created will be killed
the next revision, when they will be created and malloced by creator functions.
This patch also includes the first implementation of NTLMv2 in HEAD, but which
needs some more testing. We also add a hack to allow plaintext passwords to be
compared with smbpasswd, not the system password database.
Finally, this patch probably reintroduces the PAM accounts bug we had in
2.2.0, I'll fix that once this hits the tree. (I've just finished testing
it on a wide variety of platforms, so I want to get this patch in).
(This used to be commit b30b6202f31d339b48d51c0d38174cafd1cfcd42)
2001-08-03 17:09:23 +04:00
2001-11-05 03:21:17 +03:00
if ( state - > request . data . auth . pass [ 0 ] )
make_user_info_winbind ( & user_info ,
name_user , name_domain ,
state - > request . data . auth . pass ) ;
else
This is my 'Authentication Rewrite' version 1.01, mostly as submitted to
samba-technical a few weeks ago.
The idea here is to standardize the checking of user names and passwords,
thereby ensuring that all authtentications pass the same standards. The
interface currently implemented in as
nt_status = check_password(user_info, server_info)
where user_info contains (mostly) the authentication data, and server_info
contains things like the user-id they got, and their resolved user name.
The current ugliness with the way the structures are created will be killed
the next revision, when they will be created and malloced by creator functions.
This patch also includes the first implementation of NTLMv2 in HEAD, but which
needs some more testing. We also add a hack to allow plaintext passwords to be
compared with smbpasswd, not the system password database.
Finally, this patch probably reintroduces the PAM accounts bug we had in
2.2.0, I'll fix that once this hits the tree. (I've just finished testing
it on a wide variety of platforms, so I want to get this patch in).
(This used to be commit b30b6202f31d339b48d51c0d38174cafd1cfcd42)
2001-08-03 17:09:23 +04:00
return WINBINDD_ERROR ;
2001-08-12 15:19:57 +04:00
/*
* Get the machine account password for our primary domain
*/
2001-11-05 03:21:17 +03:00
if ( ! secrets_fetch_trust_account_password (
lp_workgroup ( ) , trust_passwd , & last_change_time ) ) {
DEBUG ( 0 , ( " winbindd_pam_auth: could not fetch trust account "
" password for domain %s \n " , lp_workgroup ( ) ) ) ;
2001-08-12 15:19:57 +04:00
return WINBINDD_ERROR ;
}
2001-11-05 03:21:17 +03:00
/* We really don't care what LUID we give the user. */
generate_random_buffer ( ( unsigned char * ) & smb_uid_low , 4 , False ) ;
ZERO_STRUCT ( info3 ) ;
2001-11-23 03:14:04 +03:00
result = cm_get_netlogon_cli ( lp_workgroup ( ) , trust_passwd , & cli ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2001-11-05 03:21:17 +03:00
DEBUG ( 3 , ( " could not open handle to NETLOGON pipe \n " ) ) ;
2001-11-23 03:14:04 +03:00
goto done ;
2001-10-05 04:20:06 +04:00
}
2001-11-05 03:21:17 +03:00
result = cli_nt_login_network ( cli , user_info , smb_uid_low ,
& ctr , & info3 ) ;
2001-06-07 08:35:01 +04:00
2001-11-05 03:21:17 +03:00
free_user_info ( & user_info ) ;
2001-08-22 06:48:16 +04:00
2001-11-05 03:21:17 +03:00
cli_shutdown ( cli ) ;
2001-11-23 03:14:04 +03:00
done :
2001-09-04 11:13:01 +04:00
return NT_STATUS_IS_OK ( result ) ? WINBINDD_OK : WINBINDD_ERROR ;
2001-08-22 06:48:16 +04:00
}
/* Challenge Response Authentication Protocol */
enum winbindd_result winbindd_pam_auth_crap ( struct winbindd_cli_state * state )
{
2001-09-04 11:13:01 +04:00
NTSTATUS result ;
2001-11-05 03:21:17 +03:00
fstring name_domain , name_user ;
2001-08-22 06:48:16 +04:00
unsigned char trust_passwd [ 16 ] ;
time_t last_change_time ;
2001-11-05 03:21:17 +03:00
2001-10-31 13:46:25 +03:00
auth_usersupplied_info * user_info ;
2001-11-05 03:21:17 +03:00
uint32 smb_uid_low ;
NET_USER_INFO_3 info3 ;
NET_ID_INFO_CTR ctr ;
struct cli_state * cli ;
2001-08-22 06:48:16 +04:00
DEBUG ( 3 , ( " [%5d]: pam auth crap %s \n " , state - > pid ,
state - > request . data . auth_crap . user ) ) ;
/* Parse domain and username */
parse_domain_user ( state - > request . data . auth_crap . user , name_domain ,
name_user ) ;
2001-11-05 03:21:17 +03:00
make_user_info_winbind_crap (
& user_info , name_user ,
name_domain , state - > request . data . auth_crap . chal ,
( uchar * ) state - > request . data . auth_crap . lm_resp ,
state - > request . data . auth_crap . lm_resp_len ,
( uchar * ) state - > request . data . auth_crap . nt_resp ,
state - > request . data . auth_crap . nt_resp_len ) ;
2001-08-22 06:48:16 +04:00
/*
* Get the machine account password for our primary domain
*/
2001-11-05 03:21:17 +03:00
if ( ! secrets_fetch_trust_account_password (
lp_workgroup ( ) , trust_passwd , & last_change_time ) ) {
DEBUG ( 0 , ( " winbindd_pam_auth: could not fetch trust account "
" password for domain %s \n " , lp_workgroup ( ) ) ) ;
2001-08-22 06:48:16 +04:00
return WINBINDD_ERROR ;
}
2001-11-05 03:21:17 +03:00
/* We really don't care what LUID we give the user. */
generate_random_buffer ( ( unsigned char * ) & smb_uid_low , 4 , False ) ;
ZERO_STRUCT ( info3 ) ;
2001-11-23 03:14:04 +03:00
result = cm_get_netlogon_cli ( lp_workgroup ( ) , trust_passwd , & cli ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2001-11-05 03:21:17 +03:00
DEBUG ( 3 , ( " could not open handle to NETLOGON pipe \n " ) ) ;
2001-11-23 03:14:04 +03:00
goto done ;
2001-10-05 04:20:06 +04:00
}
2001-11-05 03:21:17 +03:00
result = cli_nt_login_network ( cli , user_info , smb_uid_low ,
& ctr , & info3 ) ;
2001-08-22 06:48:16 +04:00
2001-11-05 03:21:17 +03:00
free_user_info ( & user_info ) ;
2000-05-09 15:43:00 +04:00
2001-11-05 03:21:17 +03:00
cli_shutdown ( cli ) ;
2001-10-31 09:20:58 +03:00
2001-11-23 03:14:04 +03:00
done :
2001-09-04 11:13:01 +04:00
return NT_STATUS_IS_OK ( result ) ? WINBINDD_OK : WINBINDD_ERROR ;
2000-05-09 15:43:00 +04:00
}
2001-05-07 08:32:40 +04:00
/* Change a user password */
enum winbindd_result winbindd_pam_chauthtok ( struct winbindd_cli_state * state )
{
char * oldpass , * newpass ;
fstring domain , user ;
uchar nt_oldhash [ 16 ] ;
uchar lm_oldhash [ 16 ] ;
DEBUG ( 3 , ( " [%5d]: pam chauthtok %s \n " , state - > pid ,
state - > request . data . chauthtok . user ) ) ;
/* Setup crap */
if ( state = = NULL ) return WINBINDD_ERROR ;
parse_domain_user ( state - > request . data . chauthtok . user , domain , user ) ;
oldpass = state - > request . data . chauthtok . oldpass ;
newpass = state - > request . data . chauthtok . newpass ;
nt_lm_owf_gen ( oldpass , nt_oldhash , lm_oldhash ) ;
/* Change password */
#if 0
/* XXX */
if ( ! msrpc_sam_ntchange_pwd ( server_state . controller , domain , user ,
lm_oldhash , nt_oldhash , newpass ) ) {
DEBUG ( 0 , ( " password change failed for user %s/%s \n " , domain , user ) ) ;
return WINBINDD_ERROR ;
}
# endif
return WINBINDD_OK ;
}