2007-12-21 20:57:34 +03:00
/*
Unix SMB / CIFS implementation .
Winbind client API
Copyright ( C ) Gerald ( Jerry ) Carter 2007
2008-10-02 15:07:14 +04:00
Copyright ( C ) Guenther Deschner 2008
2009-12-21 23:50:43 +03:00
Copyright ( C ) Volker Lendecke 2009
2007-12-21 20:57:34 +03:00
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
version 3 of the License , or ( at your option ) any later version .
This library 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
Library General Public License for more details .
You should have received a copy of the GNU Lesser General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
/* Required Headers */
2009-06-05 00:32:21 +04:00
# include "replace.h"
2007-12-21 20:57:34 +03:00
# include "libwbclient.h"
2010-01-23 21:38:28 +03:00
# include "../winbind_client.h"
2007-12-21 20:57:34 +03:00
2008-12-09 15:18:06 +03:00
/* Authenticate a username/password pair */
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCtxAuthenticateUser ( struct wbcContext * ctx ,
const char * username , const char * password )
2007-12-21 20:57:34 +03:00
{
2008-02-15 12:46:19 +03:00
wbcErr wbc_status = WBC_ERR_SUCCESS ;
struct wbcAuthUserParams params ;
2007-12-21 20:57:34 +03:00
2008-02-15 12:46:19 +03:00
ZERO_STRUCT ( params ) ;
2007-12-21 20:57:34 +03:00
2008-02-15 12:46:19 +03:00
params . account_name = username ;
params . level = WBC_AUTH_USER_LEVEL_PLAIN ;
params . password . plaintext = password ;
2007-12-21 20:57:34 +03:00
2015-02-22 01:30:11 +03:00
wbc_status = wbcCtxAuthenticateUserEx ( ctx , & params , NULL , NULL ) ;
2007-12-21 20:57:34 +03:00
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
2008-01-03 14:10:27 +03:00
return wbc_status ;
2007-12-21 20:57:34 +03:00
}
2008-01-24 16:05:59 +03:00
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcAuthenticateUser ( const char * username , const char * password )
{
return wbcCtxAuthenticateUser ( NULL , username , password ) ;
}
2010-04-03 16:46:11 +04:00
static bool sid_attr_compose ( struct wbcSidWithAttr * s ,
const struct wbcDomainSid * d ,
uint32_t rid , uint32_t attr )
{
if ( d - > num_auths > = WBC_MAXSUBAUTHS ) {
return false ;
}
s - > sid = * d ;
s - > sid . sub_auths [ s - > sid . num_auths + + ] = rid ;
s - > attributes = attr ;
return true ;
}
2010-04-04 01:08:20 +04:00
static void wbcAuthUserInfoDestructor ( void * ptr )
{
struct wbcAuthUserInfo * i = ( struct wbcAuthUserInfo * ) ptr ;
free ( i - > account_name ) ;
free ( i - > user_principal ) ;
free ( i - > full_name ) ;
free ( i - > domain_name ) ;
free ( i - > dns_domain_name ) ;
free ( i - > logon_server ) ;
free ( i - > logon_script ) ;
free ( i - > profile_path ) ;
free ( i - > home_directory ) ;
free ( i - > home_drive ) ;
free ( i - > sids ) ;
}
static wbcErr wbc_create_auth_info ( const struct winbindd_response * resp ,
2008-01-24 16:05:59 +03:00
struct wbcAuthUserInfo * * _i )
{
wbcErr wbc_status = WBC_ERR_SUCCESS ;
struct wbcAuthUserInfo * i ;
struct wbcDomainSid domain_sid ;
char * p ;
uint32_t sn = 0 ;
uint32_t j ;
2010-04-04 01:08:20 +04:00
i = ( struct wbcAuthUserInfo * ) wbcAllocateMemory (
2010-11-27 21:07:40 +03:00
1 , sizeof ( struct wbcAuthUserInfo ) ,
2010-04-04 01:08:20 +04:00
wbcAuthUserInfoDestructor ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( i , wbc_status ) ;
i - > user_flags = resp - > data . auth . info3 . user_flgs ;
2010-04-04 01:08:20 +04:00
i - > account_name = strdup ( resp - > data . auth . info3 . user_name ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( i - > account_name , wbc_status ) ;
2017-12-02 01:26:33 +03:00
if ( resp - > data . auth . validation_level = = 6 ) {
i - > user_principal = strdup ( resp - > data . auth . info6 . principal_name ) ;
BAIL_ON_PTR_ERROR ( i - > user_principal , wbc_status ) ;
} else {
i - > user_principal = NULL ;
}
2010-04-04 01:08:20 +04:00
i - > full_name = strdup ( resp - > data . auth . info3 . full_name ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( i - > full_name , wbc_status ) ;
2010-04-04 01:08:20 +04:00
i - > domain_name = strdup ( resp - > data . auth . info3 . logon_dom ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( i - > domain_name , wbc_status ) ;
2017-12-02 01:26:33 +03:00
if ( resp - > data . auth . validation_level = = 6 ) {
i - > dns_domain_name = strdup ( resp - > data . auth . info6 . dns_domainname ) ;
BAIL_ON_PTR_ERROR ( i - > dns_domain_name , wbc_status ) ;
} else {
i - > dns_domain_name = NULL ;
}
2008-01-24 16:05:59 +03:00
i - > acct_flags = resp - > data . auth . info3 . acct_flags ;
memcpy ( i - > user_session_key ,
resp - > data . auth . user_session_key ,
sizeof ( i - > user_session_key ) ) ;
memcpy ( i - > lm_session_key ,
resp - > data . auth . first_8_lm_hash ,
sizeof ( i - > lm_session_key ) ) ;
i - > logon_count = resp - > data . auth . info3 . logon_count ;
i - > bad_password_count = resp - > data . auth . info3 . bad_pw_count ;
i - > logon_time = resp - > data . auth . info3 . logon_time ;
i - > logoff_time = resp - > data . auth . info3 . logoff_time ;
i - > kickoff_time = resp - > data . auth . info3 . kickoff_time ;
i - > pass_last_set_time = resp - > data . auth . info3 . pass_last_set_time ;
i - > pass_can_change_time = resp - > data . auth . info3 . pass_can_change_time ;
i - > pass_must_change_time = resp - > data . auth . info3 . pass_must_change_time ;
2010-04-04 01:08:20 +04:00
i - > logon_server = strdup ( resp - > data . auth . info3 . logon_srv ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( i - > logon_server , wbc_status ) ;
2010-04-04 01:08:20 +04:00
i - > logon_script = strdup ( resp - > data . auth . info3 . logon_script ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( i - > logon_script , wbc_status ) ;
2010-04-04 01:08:20 +04:00
i - > profile_path = strdup ( resp - > data . auth . info3 . profile_path ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( i - > profile_path , wbc_status ) ;
2010-04-04 01:08:20 +04:00
i - > home_directory = strdup ( resp - > data . auth . info3 . home_dir ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( i - > home_directory , wbc_status ) ;
2010-04-04 01:08:20 +04:00
i - > home_drive = strdup ( resp - > data . auth . info3 . dir_drive ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( i - > home_drive , wbc_status ) ;
i - > num_sids = 2 ;
i - > num_sids + = resp - > data . auth . info3 . num_groups ;
i - > num_sids + = resp - > data . auth . info3 . num_other_sids ;
2010-04-04 01:08:20 +04:00
i - > sids = ( struct wbcSidWithAttr * ) calloc (
sizeof ( struct wbcSidWithAttr ) , i - > num_sids ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( i - > sids , wbc_status ) ;
wbc_status = wbcStringToSid ( resp - > data . auth . info3 . dom_sid ,
& domain_sid ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
sn = 0 ;
2010-04-03 16:46:11 +04:00
if ( ! sid_attr_compose ( & i - > sids [ sn ] , & domain_sid ,
resp - > data . auth . info3 . user_rid , 0 ) ) {
wbc_status = WBC_ERR_INVALID_SID ;
goto done ;
}
2008-01-24 16:05:59 +03:00
sn + + ;
2010-04-03 16:46:11 +04:00
if ( ! sid_attr_compose ( & i - > sids [ sn ] , & domain_sid ,
resp - > data . auth . info3 . group_rid , 0 ) ) {
wbc_status = WBC_ERR_INVALID_SID ;
goto done ;
}
2008-01-24 16:05:59 +03:00
sn + + ;
2008-02-23 12:43:58 +03:00
p = ( char * ) resp - > extra_data . data ;
2008-01-24 16:05:59 +03:00
if ( ! p ) {
2008-04-17 19:49:53 +04:00
wbc_status = WBC_ERR_INVALID_RESPONSE ;
2008-01-24 16:05:59 +03:00
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
for ( j = 0 ; j < resp - > data . auth . info3 . num_groups ; j + + ) {
uint32_t rid ;
uint32_t attrs ;
int ret ;
char * s = p ;
char * e = strchr ( p , ' \n ' ) ;
if ( ! e ) {
2008-04-17 19:49:53 +04:00
wbc_status = WBC_ERR_INVALID_RESPONSE ;
2008-01-24 16:05:59 +03:00
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
e [ 0 ] = ' \0 ' ;
p = & e [ 1 ] ;
ret = sscanf ( s , " 0x%08X:0x%08X " , & rid , & attrs ) ;
if ( ret ! = 2 ) {
2008-04-17 19:49:53 +04:00
wbc_status = WBC_ERR_INVALID_RESPONSE ;
2008-01-24 16:05:59 +03:00
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
2010-04-03 16:46:11 +04:00
if ( ! sid_attr_compose ( & i - > sids [ sn ] , & domain_sid ,
rid , attrs ) ) {
wbc_status = WBC_ERR_INVALID_SID ;
goto done ;
}
2008-01-24 16:05:59 +03:00
sn + + ;
}
for ( j = 0 ; j < resp - > data . auth . info3 . num_other_sids ; j + + ) {
uint32_t attrs ;
int ret ;
char * s = p ;
char * a ;
char * e = strchr ( p , ' \n ' ) ;
if ( ! e ) {
2008-04-17 19:49:53 +04:00
wbc_status = WBC_ERR_INVALID_RESPONSE ;
2008-01-24 16:05:59 +03:00
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
e [ 0 ] = ' \0 ' ;
p = & e [ 1 ] ;
e = strchr ( s , ' : ' ) ;
if ( ! e ) {
2008-04-17 19:49:53 +04:00
wbc_status = WBC_ERR_INVALID_RESPONSE ;
2008-01-24 16:05:59 +03:00
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
e [ 0 ] = ' \0 ' ;
a = & e [ 1 ] ;
ret = sscanf ( a , " 0x%08X " ,
& attrs ) ;
if ( ret ! = 1 ) {
2008-04-17 19:49:53 +04:00
wbc_status = WBC_ERR_INVALID_RESPONSE ;
2008-01-24 16:05:59 +03:00
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
wbc_status = wbcStringToSid ( s , & i - > sids [ sn ] . sid ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
i - > sids [ sn ] . attributes = attrs ;
sn + + ;
}
i - > num_sids = sn ;
* _i = i ;
i = NULL ;
done :
2010-04-04 01:08:20 +04:00
wbcFreeMemory ( i ) ;
2008-01-24 16:05:59 +03:00
return wbc_status ;
}
2010-04-03 16:52:08 +04:00
static void wbcAuthErrorInfoDestructor ( void * ptr )
{
struct wbcAuthErrorInfo * e = ( struct wbcAuthErrorInfo * ) ptr ;
free ( e - > nt_string ) ;
free ( e - > display_string ) ;
}
2010-02-06 18:53:07 +03:00
static wbcErr wbc_create_error_info ( const struct winbindd_response * resp ,
struct wbcAuthErrorInfo * * _e )
2008-01-24 16:05:59 +03:00
{
wbcErr wbc_status = WBC_ERR_SUCCESS ;
struct wbcAuthErrorInfo * e ;
2010-04-03 16:52:08 +04:00
e = ( struct wbcAuthErrorInfo * ) wbcAllocateMemory (
2010-11-27 21:07:40 +03:00
1 , sizeof ( struct wbcAuthErrorInfo ) ,
2010-04-03 16:52:08 +04:00
wbcAuthErrorInfoDestructor ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( e , wbc_status ) ;
e - > nt_status = resp - > data . auth . nt_status ;
e - > pam_error = resp - > data . auth . pam_error ;
2017-01-29 19:51:53 +03:00
e - > authoritative = resp - > data . auth . authoritative ;
2010-04-03 16:52:08 +04:00
e - > nt_string = strdup ( resp - > data . auth . nt_status_string ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( e - > nt_string , wbc_status ) ;
2010-04-03 16:52:08 +04:00
e - > display_string = strdup ( resp - > data . auth . error_string ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_PTR_ERROR ( e - > display_string , wbc_status ) ;
* _e = e ;
e = NULL ;
done :
2010-04-03 16:52:08 +04:00
wbcFreeMemory ( e ) ;
2008-01-24 16:05:59 +03:00
return wbc_status ;
}
2010-02-06 18:54:05 +03:00
static wbcErr wbc_create_password_policy_info ( const struct winbindd_response * resp ,
2008-08-15 04:00:46 +04:00
struct wbcUserPasswordPolicyInfo * * _i )
{
wbcErr wbc_status = WBC_ERR_SUCCESS ;
struct wbcUserPasswordPolicyInfo * i ;
2010-04-04 00:22:17 +04:00
i = ( struct wbcUserPasswordPolicyInfo * ) wbcAllocateMemory (
2010-11-27 21:07:40 +03:00
1 , sizeof ( struct wbcUserPasswordPolicyInfo ) , NULL ) ;
2008-08-15 04:00:46 +04:00
BAIL_ON_PTR_ERROR ( i , wbc_status ) ;
i - > min_passwordage = resp - > data . auth . policy . min_passwordage ;
i - > min_length_password = resp - > data . auth . policy . min_length_password ;
i - > password_history = resp - > data . auth . policy . password_history ;
i - > password_properties = resp - > data . auth . policy . password_properties ;
i - > expire = resp - > data . auth . policy . expire ;
* _i = i ;
i = NULL ;
done :
2010-04-04 00:22:17 +04:00
wbcFreeMemory ( i ) ;
2008-08-15 04:00:46 +04:00
return wbc_status ;
}
2010-04-04 13:57:39 +04:00
static void wbcLogonUserInfoDestructor ( void * ptr )
{
struct wbcLogonUserInfo * i = ( struct wbcLogonUserInfo * ) ptr ;
wbcFreeMemory ( i - > info ) ;
wbcFreeMemory ( i - > blobs ) ;
}
2010-02-06 18:56:29 +03:00
static wbcErr wbc_create_logon_info ( struct winbindd_response * resp ,
2008-10-10 17:18:02 +04:00
struct wbcLogonUserInfo * * _i )
{
wbcErr wbc_status = WBC_ERR_SUCCESS ;
struct wbcLogonUserInfo * i ;
2010-04-04 13:57:39 +04:00
i = ( struct wbcLogonUserInfo * ) wbcAllocateMemory (
2010-11-27 21:07:40 +03:00
1 , sizeof ( struct wbcLogonUserInfo ) ,
2010-04-04 13:57:39 +04:00
wbcLogonUserInfoDestructor ) ;
2008-10-10 17:18:02 +04:00
BAIL_ON_PTR_ERROR ( i , wbc_status ) ;
2010-04-04 01:08:20 +04:00
wbc_status = wbc_create_auth_info ( resp , & i - > info ) ;
2008-10-10 17:18:02 +04:00
BAIL_ON_WBC_ERROR ( wbc_status ) ;
2010-09-10 14:49:32 +04:00
if ( resp - > data . auth . krb5ccname [ 0 ] ! = ' \0 ' ) {
2008-10-10 17:18:02 +04:00
wbc_status = wbcAddNamedBlob ( & i - > num_blobs ,
& i - > blobs ,
" krb5ccname " ,
0 ,
( uint8_t * ) resp - > data . auth . krb5ccname ,
strlen ( resp - > data . auth . krb5ccname ) + 1 ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
2010-09-10 14:49:32 +04:00
if ( resp - > data . auth . unix_username [ 0 ] ! = ' \0 ' ) {
2008-10-10 17:18:02 +04:00
wbc_status = wbcAddNamedBlob ( & i - > num_blobs ,
& i - > blobs ,
" unix_username " ,
0 ,
( uint8_t * ) resp - > data . auth . unix_username ,
strlen ( resp - > data . auth . unix_username ) + 1 ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
* _i = i ;
i = NULL ;
done :
2010-04-04 13:57:39 +04:00
wbcFreeMemory ( i ) ;
2008-10-10 17:18:02 +04:00
return wbc_status ;
}
2009-05-28 02:55:57 +04:00
2008-12-09 15:18:06 +03:00
/* Authenticate with more detailed information */
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCtxAuthenticateUserEx ( struct wbcContext * ctx ,
const struct wbcAuthUserParams * params ,
struct wbcAuthUserInfo * * info ,
struct wbcAuthErrorInfo * * error )
2008-01-24 16:05:59 +03:00
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
2008-02-15 12:30:15 +03:00
int cmd = 0 ;
2008-01-24 16:05:59 +03:00
struct winbindd_request request ;
struct winbindd_response response ;
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
if ( error ) {
* error = NULL ;
}
if ( ! params ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
2012-07-19 01:38:47 +04:00
if ( params - > level ! = WBC_AUTH_USER_LEVEL_PAC & & ! params - > account_name ) {
2008-02-15 12:30:15 +03:00
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
2008-01-24 16:05:59 +03:00
/* Initialize request */
switch ( params - > level ) {
case WBC_AUTH_USER_LEVEL_PLAIN :
2008-02-15 12:34:46 +03:00
cmd = WINBINDD_PAM_AUTH ;
request . flags = WBFLAG_PAM_INFO3_TEXT |
WBFLAG_PAM_USER_SESSION_KEY |
WBFLAG_PAM_LMKEY ;
if ( ! params - > password . plaintext ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
if ( params - > domain_name & & params - > domain_name [ 0 ] ) {
/* We need to get the winbind separator :-( */
struct winbindd_response sep_response ;
ZERO_STRUCT ( sep_response ) ;
2015-02-22 01:30:11 +03:00
wbc_status = wbcRequestResponse ( ctx , WINBINDD_INFO ,
2008-02-15 12:34:46 +03:00
NULL , & sep_response ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
snprintf ( request . data . auth . user ,
sizeof ( request . data . auth . user ) - 1 ,
" %s%c%s " ,
params - > domain_name ,
sep_response . data . info . winbind_separator ,
params - > account_name ) ;
2023-07-19 03:55:15 +03:00
winbindd_free_response ( & sep_response ) ;
2008-02-15 12:34:46 +03:00
} else {
strncpy ( request . data . auth . user ,
params - > account_name ,
sizeof ( request . data . auth . user ) - 1 ) ;
}
2008-10-10 17:13:14 +04:00
2008-02-15 12:34:46 +03:00
strncpy ( request . data . auth . pass ,
params - > password . plaintext ,
2008-05-27 18:40:44 +04:00
sizeof ( request . data . auth . pass ) - 1 ) ;
2008-01-24 16:05:59 +03:00
break ;
case WBC_AUTH_USER_LEVEL_HASH :
wbc_status = WBC_ERR_NOT_IMPLEMENTED ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
break ;
case WBC_AUTH_USER_LEVEL_RESPONSE :
cmd = WINBINDD_PAM_AUTH_CRAP ;
request . flags = WBFLAG_PAM_INFO3_TEXT |
WBFLAG_PAM_USER_SESSION_KEY |
WBFLAG_PAM_LMKEY ;
2008-02-15 12:30:15 +03:00
if ( params - > password . response . lm_length & &
2008-03-26 03:27:36 +03:00
! params - > password . response . lm_data ) {
2008-02-15 12:30:15 +03:00
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
if ( params - > password . response . lm_length = = 0 & &
params - > password . response . lm_data ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
if ( params - > password . response . nt_length & &
! params - > password . response . nt_data ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
if ( params - > password . response . nt_length = = 0 & &
params - > password . response . nt_data ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
2008-01-24 16:05:59 +03:00
strncpy ( request . data . auth_crap . user ,
params - > account_name ,
sizeof ( request . data . auth_crap . user ) - 1 ) ;
2008-02-15 12:30:15 +03:00
if ( params - > domain_name ) {
strncpy ( request . data . auth_crap . domain ,
params - > domain_name ,
sizeof ( request . data . auth_crap . domain ) - 1 ) ;
}
2008-01-24 16:05:59 +03:00
if ( params - > workstation_name ) {
strncpy ( request . data . auth_crap . workstation ,
params - > workstation_name ,
sizeof ( request . data . auth_crap . workstation ) - 1 ) ;
}
request . data . auth_crap . logon_parameters =
params - > parameter_control ;
memcpy ( request . data . auth_crap . chal ,
params - > password . response . challenge ,
sizeof ( request . data . auth_crap . chal ) ) ;
request . data . auth_crap . lm_resp_len =
MIN ( params - > password . response . lm_length ,
sizeof ( request . data . auth_crap . lm_resp ) ) ;
2008-02-15 12:30:15 +03:00
if ( params - > password . response . lm_data ) {
memcpy ( request . data . auth_crap . lm_resp ,
params - > password . response . lm_data ,
request . data . auth_crap . lm_resp_len ) ;
}
2009-09-01 13:58:05 +04:00
request . data . auth_crap . nt_resp_len = params - > password . response . nt_length ;
if ( params - > password . response . nt_length > sizeof ( request . data . auth_crap . nt_resp ) ) {
request . flags | = WBFLAG_BIG_NTLMV2_BLOB ;
request . extra_len = params - > password . response . nt_length ;
2010-04-04 13:58:04 +04:00
request . extra_data . data = ( char * ) malloc (
request . extra_len ) ;
2009-09-01 13:58:05 +04:00
if ( request . extra_data . data = = NULL ) {
wbc_status = WBC_ERR_NO_MEMORY ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
memcpy ( request . extra_data . data ,
params - > password . response . nt_data ,
request . data . auth_crap . nt_resp_len ) ;
} else if ( params - > password . response . nt_data ) {
2008-02-15 12:30:15 +03:00
memcpy ( request . data . auth_crap . nt_resp ,
params - > password . response . nt_data ,
request . data . auth_crap . nt_resp_len ) ;
}
2008-01-24 16:05:59 +03:00
break ;
2012-07-19 01:38:47 +04:00
case WBC_AUTH_USER_LEVEL_PAC :
cmd = WINBINDD_PAM_AUTH_CRAP ;
request . flags = WBFLAG_PAM_AUTH_PAC | WBFLAG_PAM_INFO3_TEXT ;
request . extra_data . data = malloc ( params - > password . pac . length ) ;
if ( request . extra_data . data = = NULL ) {
wbc_status = WBC_ERR_NO_MEMORY ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
memcpy ( request . extra_data . data , params - > password . pac . data ,
params - > password . pac . length ) ;
request . extra_len = params - > password . pac . length ;
break ;
2008-02-15 05:16:09 +03:00
default :
2008-03-27 13:51:31 +03:00
break ;
2008-01-24 16:05:59 +03:00
}
2008-02-15 12:30:15 +03:00
if ( cmd = = 0 ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
2008-10-10 17:13:14 +04:00
if ( params - > flags ) {
request . flags | = params - > flags ;
}
2010-04-13 14:09:21 +04:00
if ( cmd = = WINBINDD_PAM_AUTH_CRAP ) {
2015-02-22 01:30:11 +03:00
wbc_status = wbcRequestResponsePriv ( ctx , cmd ,
& request , & response ) ;
2010-04-13 14:09:21 +04:00
} else {
2015-02-22 01:30:11 +03:00
wbc_status = wbcRequestResponse ( ctx , cmd ,
& request , & response ) ;
2010-04-13 14:09:21 +04:00
}
2008-01-24 16:05:59 +03:00
if ( response . data . auth . nt_status ! = 0 ) {
if ( error ) {
2010-02-06 18:53:07 +03:00
wbc_status = wbc_create_error_info ( & response ,
2008-01-24 16:05:59 +03:00
error ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
wbc_status = WBC_ERR_AUTH_ERROR ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
BAIL_ON_WBC_ERROR ( wbc_status ) ;
if ( info ) {
2010-04-04 01:08:20 +04:00
wbc_status = wbc_create_auth_info ( & response , info ) ;
2008-01-24 16:05:59 +03:00
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
done :
2010-01-23 21:38:28 +03:00
winbindd_free_response ( & response ) ;
2008-01-24 16:05:59 +03:00
2010-04-04 13:58:04 +04:00
free ( request . extra_data . data ) ;
2009-09-01 13:58:05 +04:00
2008-01-24 16:05:59 +03:00
return wbc_status ;
}
2008-04-17 01:35:12 +04:00
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcAuthenticateUserEx ( const struct wbcAuthUserParams * params ,
struct wbcAuthUserInfo * * info ,
struct wbcAuthErrorInfo * * error )
{
return wbcCtxAuthenticateUserEx ( NULL , params , info , error ) ;
}
2008-12-09 15:18:06 +03:00
/* Trigger a verification of the trust credentials of a specific domain */
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCtxCheckTrustCredentials ( struct wbcContext * ctx , const char * domain ,
struct wbcAuthErrorInfo * * error )
2008-04-17 01:35:12 +04:00
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
2009-10-06 19:45:24 +04:00
if ( domain ) {
strncpy ( request . domain_name , domain ,
sizeof ( request . domain_name ) - 1 ) ;
}
2008-04-17 01:35:12 +04:00
/* Send request */
2015-02-22 01:30:11 +03:00
wbc_status = wbcRequestResponsePriv ( ctx , WINBINDD_CHECK_MACHACC ,
2010-04-13 14:09:21 +04:00
& request , & response ) ;
2008-08-15 15:53:23 +04:00
if ( response . data . auth . nt_status ! = 0 ) {
if ( error ) {
2010-02-06 18:53:07 +03:00
wbc_status = wbc_create_error_info ( & response ,
2008-08-15 15:53:23 +04:00
error ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
wbc_status = WBC_ERR_AUTH_ERROR ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCheckTrustCredentials ( const char * domain ,
struct wbcAuthErrorInfo * * error )
{
return wbcCtxCheckTrustCredentials ( NULL , domain , error ) ;
}
2009-10-06 20:15:08 +04:00
/* Trigger a change of the trust credentials for a specific domain */
2021-10-12 15:30:09 +03:00
_PUBLIC_
2022-11-22 14:00:14 +03:00
wbcErr wbcCtxChangeTrustCredentialsAt ( struct wbcContext * ctx ,
const char * domain ,
const char * dcname ,
struct wbcAuthErrorInfo * * error )
2009-10-06 20:15:08 +04:00
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
if ( domain ) {
strncpy ( request . domain_name , domain ,
sizeof ( request . domain_name ) - 1 ) ;
}
2022-11-22 14:00:14 +03:00
if ( dcname ! = NULL ) {
strncpy ( request . data . init_conn . dcname , dcname ,
sizeof ( request . data . init_conn . dcname ) - 1 ) ;
}
2009-10-06 20:15:08 +04:00
/* Send request */
2015-02-22 01:30:11 +03:00
wbc_status = wbcRequestResponsePriv ( ctx , WINBINDD_CHANGE_MACHACC ,
& request , & response ) ;
2009-10-06 20:15:08 +04:00
if ( response . data . auth . nt_status ! = 0 ) {
if ( error ) {
2010-02-06 18:53:07 +03:00
wbc_status = wbc_create_error_info ( & response ,
2009-10-06 20:15:08 +04:00
error ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
wbc_status = WBC_ERR_AUTH_ERROR ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}
2022-11-22 14:00:14 +03:00
_PUBLIC_
wbcErr wbcChangeTrustCredentialsAt ( const char * domain ,
const char * dcname ,
struct wbcAuthErrorInfo * * error )
{
return wbcCtxChangeTrustCredentialsAt ( NULL , domain , dcname , error ) ;
}
_PUBLIC_
wbcErr wbcCtxChangeTrustCredentials ( struct wbcContext * ctx ,
const char * domain ,
struct wbcAuthErrorInfo * * error )
{
return wbcCtxChangeTrustCredentialsAt ( ctx , domain , NULL , error ) ;
}
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcChangeTrustCredentials ( const char * domain ,
struct wbcAuthErrorInfo * * error )
{
return wbcCtxChangeTrustCredentials ( NULL , domain , error ) ;
}
2009-12-21 23:50:43 +03:00
/*
* Trigger a no - op NETLOGON call . Lightweight version of
* wbcCheckTrustCredentials
*/
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCtxPingDc ( struct wbcContext * ctx , const char * domain ,
struct wbcAuthErrorInfo * * error )
{
return wbcCtxPingDc2 ( ctx , domain , error , NULL ) ;
}
2021-10-12 15:30:09 +03:00
_PUBLIC_
2009-12-21 23:50:43 +03:00
wbcErr wbcPingDc ( const char * domain , struct wbcAuthErrorInfo * * error )
2012-08-10 19:25:14 +04:00
{
return wbcPingDc2 ( domain , error , NULL ) ;
}
/*
* Trigger a no - op NETLOGON call . Lightweight version of
* wbcCheckTrustCredentials , optionally return attempted DC
*/
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCtxPingDc2 ( struct wbcContext * ctx , const char * domain ,
struct wbcAuthErrorInfo * * error , char * * dcname )
2009-12-21 23:50:43 +03:00
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
2014-12-10 17:02:18 +03:00
if ( domain ) {
strncpy ( request . domain_name , domain ,
sizeof ( request . domain_name ) - 1 ) ;
}
2009-12-21 23:50:43 +03:00
/* Send request */
2015-02-22 01:30:11 +03:00
wbc_status = wbcRequestResponse ( ctx , WINBINDD_PING_DC ,
2009-12-21 23:50:43 +03:00
& request ,
& response ) ;
2012-08-10 19:25:14 +04:00
if ( dcname & & response . extra_data . data ) {
size_t len ;
len = response . length - sizeof ( struct winbindd_response ) ;
* dcname = wbcAllocateMemory ( 1 , len , NULL ) ;
BAIL_ON_PTR_ERROR ( * dcname , wbc_status ) ;
strlcpy ( * dcname , response . extra_data . data , len ) ;
}
2009-12-21 23:50:43 +03:00
if ( response . data . auth . nt_status ! = 0 ) {
if ( error ) {
2010-02-06 18:53:07 +03:00
wbc_status = wbc_create_error_info ( & response ,
2009-12-21 23:50:43 +03:00
error ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
wbc_status = WBC_ERR_AUTH_ERROR ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
2022-09-02 23:31:32 +03:00
winbindd_free_response ( & response ) ;
2009-12-21 23:50:43 +03:00
return wbc_status ;
}
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcPingDc2 ( const char * domain , struct wbcAuthErrorInfo * * error ,
char * * dcname )
{
return wbcCtxPingDc2 ( NULL , domain , error , dcname ) ;
}
2008-12-09 15:18:06 +03:00
/* Trigger an extended logoff notification to Winbind for a specific user */
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCtxLogoffUserEx ( struct wbcContext * ctx ,
const struct wbcLogoffUserParams * params ,
struct wbcAuthErrorInfo * * error )
2008-08-15 15:53:23 +04:00
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
2017-07-13 16:52:15 +03:00
size_t i ;
2008-08-15 15:53:23 +04:00
/* validate input */
if ( ! params | | ! params - > username ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
if ( ( params - > num_blobs > 0 ) & & ( params - > blobs = = NULL ) ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
if ( ( params - > num_blobs = = 0 ) & & ( params - > blobs ! = NULL ) ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
strncpy ( request . data . logoff . user , params - > username ,
sizeof ( request . data . logoff . user ) - 1 ) ;
for ( i = 0 ; i < params - > num_blobs ; i + + ) {
if ( strcasecmp ( params - > blobs [ i ] . name , " ccfilename " ) = = 0 ) {
if ( params - > blobs [ i ] . blob . data ) {
strncpy ( request . data . logoff . krb5ccname ,
( const char * ) params - > blobs [ i ] . blob . data ,
sizeof ( request . data . logoff . krb5ccname ) - 1 ) ;
}
continue ;
}
if ( strcasecmp ( params - > blobs [ i ] . name , " user_uid " ) = = 0 ) {
if ( params - > blobs [ i ] . blob . data ) {
memcpy ( & request . data . logoff . uid ,
params - > blobs [ i ] . blob . data ,
MIN ( params - > blobs [ i ] . blob . length ,
sizeof ( request . data . logoff . uid ) ) ) ;
}
continue ;
}
if ( strcasecmp ( params - > blobs [ i ] . name , " flags " ) = = 0 ) {
if ( params - > blobs [ i ] . blob . data ) {
memcpy ( & request . flags ,
params - > blobs [ i ] . blob . data ,
MIN ( params - > blobs [ i ] . blob . length ,
sizeof ( request . flags ) ) ) ;
}
continue ;
}
}
/* Send request */
2015-02-22 01:30:11 +03:00
wbc_status = wbcRequestResponse ( ctx , WINBINDD_PAM_LOGOFF ,
2008-08-15 15:53:23 +04:00
& request ,
& response ) ;
/* Take the response above and return it to the caller */
2008-04-17 01:35:12 +04:00
if ( response . data . auth . nt_status ! = 0 ) {
if ( error ) {
2010-02-06 18:53:07 +03:00
wbc_status = wbc_create_error_info ( & response ,
2008-04-17 01:35:12 +04:00
error ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
wbc_status = WBC_ERR_AUTH_ERROR ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}
2008-05-13 21:52:20 +04:00
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcLogoffUserEx ( const struct wbcLogoffUserParams * params ,
struct wbcAuthErrorInfo * * error )
{
return wbcCtxLogoffUserEx ( NULL , params , error ) ;
}
2008-12-09 15:18:06 +03:00
/* Trigger a logoff notification to Winbind for a specific user */
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCtxLogoffUser ( struct wbcContext * ctx ,
const char * username , uid_t uid ,
const char * ccfilename )
2008-05-13 21:52:20 +04:00
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
/* validate input */
if ( ! username ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
strncpy ( request . data . logoff . user , username ,
sizeof ( request . data . logoff . user ) - 1 ) ;
request . data . logoff . uid = uid ;
if ( ccfilename ) {
strncpy ( request . data . logoff . krb5ccname , ccfilename ,
sizeof ( request . data . logoff . krb5ccname ) - 1 ) ;
}
/* Send request */
2015-02-22 01:30:11 +03:00
wbc_status = wbcRequestResponse ( ctx , WINBINDD_PAM_LOGOFF ,
2008-05-13 21:52:20 +04:00
& request ,
& response ) ;
/* Take the response above and return it to the caller */
done :
return wbc_status ;
}
2008-08-15 04:00:46 +04:00
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcLogoffUser ( const char * username ,
uid_t uid ,
const char * ccfilename )
{
return wbcCtxLogoffUser ( NULL , username , uid , ccfilename ) ;
}
2008-12-09 15:18:06 +03:00
/* Change a password for a user with more detailed information upon failure */
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCtxChangeUserPasswordEx ( struct wbcContext * ctx ,
const struct wbcChangePasswordParams * params ,
struct wbcAuthErrorInfo * * error ,
enum wbcPasswordChangeRejectReason * reject_reason ,
struct wbcUserPasswordPolicyInfo * * policy )
2008-08-15 04:00:46 +04:00
{
struct winbindd_request request ;
struct winbindd_response response ;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
int cmd = 0 ;
/* validate input */
if ( ! params - > account_name ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
2010-04-20 18:07:13 +04:00
goto done ;
2008-08-15 04:00:46 +04:00
}
if ( error ) {
* error = NULL ;
}
if ( policy ) {
* policy = NULL ;
}
if ( reject_reason ) {
* reject_reason = - 1 ;
}
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
switch ( params - > level ) {
case WBC_CHANGE_PASSWORD_LEVEL_PLAIN :
cmd = WINBINDD_PAM_CHAUTHTOK ;
if ( ! params - > account_name ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
2010-04-20 18:07:13 +04:00
goto done ;
2008-08-15 04:00:46 +04:00
}
strncpy ( request . data . chauthtok . user , params - > account_name ,
sizeof ( request . data . chauthtok . user ) - 1 ) ;
if ( params - > old_password . plaintext ) {
strncpy ( request . data . chauthtok . oldpass ,
params - > old_password . plaintext ,
sizeof ( request . data . chauthtok . oldpass ) - 1 ) ;
}
if ( params - > new_password . plaintext ) {
strncpy ( request . data . chauthtok . newpass ,
params - > new_password . plaintext ,
sizeof ( request . data . chauthtok . newpass ) - 1 ) ;
}
break ;
case WBC_CHANGE_PASSWORD_LEVEL_RESPONSE :
cmd = WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP ;
if ( ! params - > account_name | | ! params - > domain_name ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
2010-04-20 18:07:13 +04:00
goto done ;
2008-08-15 04:00:46 +04:00
}
if ( params - > old_password . response . old_lm_hash_enc_length & &
! params - > old_password . response . old_lm_hash_enc_data ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
2010-04-20 18:07:13 +04:00
goto done ;
2008-08-15 04:00:46 +04:00
}
if ( params - > old_password . response . old_lm_hash_enc_length = = 0 & &
params - > old_password . response . old_lm_hash_enc_data ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
2010-04-20 18:07:13 +04:00
goto done ;
2008-08-15 04:00:46 +04:00
}
if ( params - > old_password . response . old_nt_hash_enc_length & &
! params - > old_password . response . old_nt_hash_enc_data ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
2010-04-20 18:07:13 +04:00
goto done ;
2008-08-15 04:00:46 +04:00
}
if ( params - > old_password . response . old_nt_hash_enc_length = = 0 & &
params - > old_password . response . old_nt_hash_enc_data ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
2010-04-20 18:07:13 +04:00
goto done ;
2008-08-15 04:00:46 +04:00
}
if ( params - > new_password . response . lm_length & &
! params - > new_password . response . lm_data ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
2010-04-20 18:07:13 +04:00
goto done ;
2008-08-15 04:00:46 +04:00
}
if ( params - > new_password . response . lm_length = = 0 & &
params - > new_password . response . lm_data ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
2010-04-20 18:07:13 +04:00
goto done ;
2008-08-15 04:00:46 +04:00
}
if ( params - > new_password . response . nt_length & &
! params - > new_password . response . nt_data ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
2010-04-20 18:07:13 +04:00
goto done ;
2008-08-15 04:00:46 +04:00
}
if ( params - > new_password . response . nt_length = = 0 & &
params - > new_password . response . nt_data ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
2010-04-20 18:07:13 +04:00
goto done ;
2008-08-15 04:00:46 +04:00
}
strncpy ( request . data . chng_pswd_auth_crap . user ,
params - > account_name ,
sizeof ( request . data . chng_pswd_auth_crap . user ) - 1 ) ;
strncpy ( request . data . chng_pswd_auth_crap . domain ,
params - > domain_name ,
sizeof ( request . data . chng_pswd_auth_crap . domain ) - 1 ) ;
if ( params - > new_password . response . nt_data ) {
2010-04-23 21:41:29 +04:00
request . data . chng_pswd_auth_crap . new_nt_pswd_len =
params - > new_password . response . nt_length ;
2008-08-15 04:00:46 +04:00
memcpy ( request . data . chng_pswd_auth_crap . new_nt_pswd ,
params - > new_password . response . nt_data ,
request . data . chng_pswd_auth_crap . new_nt_pswd_len ) ;
}
if ( params - > new_password . response . lm_data ) {
2010-04-23 21:41:29 +04:00
request . data . chng_pswd_auth_crap . new_lm_pswd_len =
params - > new_password . response . lm_length ;
2008-08-15 04:00:46 +04:00
memcpy ( request . data . chng_pswd_auth_crap . new_lm_pswd ,
params - > new_password . response . lm_data ,
request . data . chng_pswd_auth_crap . new_lm_pswd_len ) ;
}
if ( params - > old_password . response . old_nt_hash_enc_data ) {
2010-04-23 21:41:29 +04:00
request . data . chng_pswd_auth_crap . old_nt_hash_enc_len =
params - > old_password . response . old_nt_hash_enc_length ;
2008-08-15 04:00:46 +04:00
memcpy ( request . data . chng_pswd_auth_crap . old_nt_hash_enc ,
params - > old_password . response . old_nt_hash_enc_data ,
request . data . chng_pswd_auth_crap . old_nt_hash_enc_len ) ;
}
if ( params - > old_password . response . old_lm_hash_enc_data ) {
2010-04-23 21:41:29 +04:00
request . data . chng_pswd_auth_crap . old_lm_hash_enc_len =
params - > old_password . response . old_lm_hash_enc_length ;
2008-08-15 04:00:46 +04:00
memcpy ( request . data . chng_pswd_auth_crap . old_lm_hash_enc ,
params - > old_password . response . old_lm_hash_enc_data ,
request . data . chng_pswd_auth_crap . old_lm_hash_enc_len ) ;
}
break ;
default :
wbc_status = WBC_ERR_INVALID_PARAM ;
2010-04-20 18:07:13 +04:00
goto done ;
2008-08-15 04:00:46 +04:00
break ;
}
/* Send request */
2015-02-22 01:30:11 +03:00
wbc_status = wbcRequestResponse ( ctx , cmd ,
2008-08-15 04:00:46 +04:00
& request ,
& response ) ;
if ( WBC_ERROR_IS_OK ( wbc_status ) ) {
goto done ;
}
/* Take the response above and return it to the caller */
if ( response . data . auth . nt_status ! = 0 ) {
if ( error ) {
2010-02-06 18:53:07 +03:00
wbc_status = wbc_create_error_info ( & response ,
2008-08-15 04:00:46 +04:00
error ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
}
if ( policy ) {
2010-02-06 18:54:05 +03:00
wbc_status = wbc_create_password_policy_info ( & response ,
2008-08-15 04:00:46 +04:00
policy ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
if ( reject_reason ) {
* reject_reason = response . data . auth . reject_reason ;
}
wbc_status = WBC_ERR_PWD_CHANGE_FAILED ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcChangeUserPasswordEx ( const struct wbcChangePasswordParams * params ,
struct wbcAuthErrorInfo * * error ,
enum wbcPasswordChangeRejectReason * reject_reason ,
struct wbcUserPasswordPolicyInfo * * policy )
{
return wbcCtxChangeUserPasswordEx ( NULL , params , error ,
reject_reason , policy ) ;
}
2008-12-09 15:18:06 +03:00
/* Change a password for a user */
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCtxChangeUserPassword ( struct wbcContext * ctx ,
const char * username ,
const char * old_password ,
const char * new_password )
2008-08-15 04:00:46 +04:00
{
wbcErr wbc_status = WBC_ERR_SUCCESS ;
struct wbcChangePasswordParams params ;
ZERO_STRUCT ( params ) ;
params . account_name = username ;
params . level = WBC_CHANGE_PASSWORD_LEVEL_PLAIN ;
params . old_password . plaintext = old_password ;
params . new_password . plaintext = new_password ;
2015-02-22 01:30:11 +03:00
wbc_status = wbcCtxChangeUserPasswordEx ( ctx , & params ,
NULL ,
NULL ,
NULL ) ;
2008-08-15 04:00:46 +04:00
BAIL_ON_WBC_ERROR ( wbc_status ) ;
done :
return wbc_status ;
}
2008-10-10 17:18:02 +04:00
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcChangeUserPassword ( const char * username ,
const char * old_password ,
const char * new_password )
{
return wbcCtxChangeUserPassword ( NULL , username ,
old_password , new_password ) ;
}
2008-12-09 15:18:06 +03:00
/* Logon a User */
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCtxLogonUser ( struct wbcContext * ctx ,
const struct wbcLogonUserParams * params ,
struct wbcLogonUserInfo * * info ,
struct wbcAuthErrorInfo * * error ,
struct wbcUserPasswordPolicyInfo * * policy )
2008-10-10 17:18:02 +04:00
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE ;
struct winbindd_request request ;
struct winbindd_response response ;
uint32_t i ;
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
if ( info ) {
* info = NULL ;
}
if ( error ) {
* error = NULL ;
}
if ( policy ) {
* policy = NULL ;
}
if ( ! params ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
if ( ! params - > username ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
if ( ( params - > num_blobs > 0 ) & & ( params - > blobs = = NULL ) ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
if ( ( params - > num_blobs = = 0 ) & & ( params - > blobs ! = NULL ) ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
/* Initialize request */
request . flags = WBFLAG_PAM_INFO3_TEXT |
WBFLAG_PAM_USER_SESSION_KEY |
WBFLAG_PAM_LMKEY ;
if ( ! params - > password ) {
wbc_status = WBC_ERR_INVALID_PARAM ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
strncpy ( request . data . auth . user ,
params - > username ,
sizeof ( request . data . auth . user ) - 1 ) ;
strncpy ( request . data . auth . pass ,
params - > password ,
sizeof ( request . data . auth . pass ) - 1 ) ;
for ( i = 0 ; i < params - > num_blobs ; i + + ) {
if ( strcasecmp ( params - > blobs [ i ] . name , " krb5_cc_type " ) = = 0 ) {
if ( params - > blobs [ i ] . blob . data ) {
strncpy ( request . data . auth . krb5_cc_type ,
( const char * ) params - > blobs [ i ] . blob . data ,
sizeof ( request . data . auth . krb5_cc_type ) - 1 ) ;
}
continue ;
}
if ( strcasecmp ( params - > blobs [ i ] . name , " user_uid " ) = = 0 ) {
if ( params - > blobs [ i ] . blob . data ) {
memcpy ( & request . data . auth . uid ,
params - > blobs [ i ] . blob . data ,
MIN ( sizeof ( request . data . auth . uid ) ,
params - > blobs [ i ] . blob . length ) ) ;
}
continue ;
}
if ( strcasecmp ( params - > blobs [ i ] . name , " flags " ) = = 0 ) {
if ( params - > blobs [ i ] . blob . data ) {
uint32_t flags ;
memcpy ( & flags ,
params - > blobs [ i ] . blob . data ,
MIN ( sizeof ( flags ) ,
params - > blobs [ i ] . blob . length ) ) ;
request . flags | = flags ;
}
continue ;
}
if ( strcasecmp ( params - > blobs [ i ] . name , " membership_of " ) = = 0 ) {
if ( params - > blobs [ i ] . blob . data & &
params - > blobs [ i ] . blob . data [ 0 ] > 0 ) {
strncpy ( request . data . auth . require_membership_of_sid ,
( const char * ) params - > blobs [ i ] . blob . data ,
sizeof ( request . data . auth . require_membership_of_sid ) - 1 ) ;
}
continue ;
}
}
2015-02-22 01:30:11 +03:00
wbc_status = wbcRequestResponse ( ctx , WINBINDD_PAM_AUTH ,
2008-10-10 17:18:02 +04:00
& request ,
& response ) ;
if ( response . data . auth . nt_status ! = 0 ) {
if ( error ) {
2010-02-06 18:53:07 +03:00
wbc_status = wbc_create_error_info ( & response ,
2008-10-10 17:18:02 +04:00
error ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
wbc_status = WBC_ERR_AUTH_ERROR ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
BAIL_ON_WBC_ERROR ( wbc_status ) ;
if ( info ) {
2010-02-06 18:56:29 +03:00
wbc_status = wbc_create_logon_info ( & response ,
2008-10-10 17:18:02 +04:00
info ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
if ( policy ) {
2010-02-06 18:54:05 +03:00
wbc_status = wbc_create_password_policy_info ( & response ,
2008-10-10 17:18:02 +04:00
policy ) ;
BAIL_ON_WBC_ERROR ( wbc_status ) ;
}
done :
2010-01-23 21:38:28 +03:00
winbindd_free_response ( & response ) ;
2008-10-10 17:18:02 +04:00
return wbc_status ;
}
2008-11-23 17:16:17 +03:00
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcLogonUser ( const struct wbcLogonUserParams * params ,
struct wbcLogonUserInfo * * info ,
struct wbcAuthErrorInfo * * error ,
struct wbcUserPasswordPolicyInfo * * policy )
{
return wbcCtxLogonUser ( NULL , params , info , error , policy ) ;
}
2010-04-04 16:01:23 +04:00
static void wbcCredentialCacheInfoDestructor ( void * ptr )
{
struct wbcCredentialCacheInfo * i =
( struct wbcCredentialCacheInfo * ) ptr ;
wbcFreeMemory ( i - > blobs ) ;
}
2008-12-09 15:18:06 +03:00
/* Authenticate a user with cached credentials */
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCtxCredentialCache ( struct wbcContext * ctx ,
struct wbcCredentialCacheParams * params ,
struct wbcCredentialCacheInfo * * info ,
struct wbcAuthErrorInfo * * error )
2008-11-23 17:16:17 +03:00
{
2010-01-24 18:44:15 +03:00
wbcErr status = WBC_ERR_UNKNOWN_FAILURE ;
struct wbcCredentialCacheInfo * result = NULL ;
struct winbindd_request request ;
struct winbindd_response response ;
struct wbcNamedBlob * initial_blob = NULL ;
struct wbcNamedBlob * challenge_blob = NULL ;
2017-07-13 16:52:15 +03:00
size_t i ;
2010-01-24 18:44:15 +03:00
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
2011-03-16 23:21:17 +03:00
* info = NULL ;
2010-01-24 18:44:15 +03:00
if ( error ! = NULL ) {
* error = NULL ;
}
if ( ( params = = NULL )
| | ( params - > account_name = = NULL )
| | ( params - > level ! = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP ) ) {
status = WBC_ERR_INVALID_PARAM ;
goto fail ;
}
2014-07-10 07:28:36 +04:00
for ( i = 0 ; i < params - > num_blobs ; i + + ) {
2015-11-20 16:06:18 +03:00
/*
* Older callers may used to provide the NEGOTIATE request
* as " initial_blob " , but it was completely ignored by winbindd .
*
* So we keep ignoring it .
*
* A new callers that is capable to support " new_spnego " ,
* will provide the NEGOTIATE request as " negotiate_blob "
* instead .
*/
if ( strcasecmp ( params - > blobs [ i ] . name , " negotiate_blob " ) = = 0 ) {
2014-07-10 07:28:36 +04:00
if ( initial_blob ! = NULL ) {
status = WBC_ERR_INVALID_PARAM ;
goto fail ;
}
initial_blob = & params - > blobs [ i ] ;
continue ;
}
if ( strcasecmp ( params - > blobs [ i ] . name , " challenge_blob " ) = = 0 ) {
if ( challenge_blob ! = NULL ) {
status = WBC_ERR_INVALID_PARAM ;
goto fail ;
}
challenge_blob = & params - > blobs [ i ] ;
continue ;
}
}
2010-01-24 18:44:15 +03:00
if ( params - > domain_name ! = NULL ) {
2015-02-22 01:30:11 +03:00
status = wbcRequestResponse ( ctx , WINBINDD_INFO ,
NULL , & response ) ;
2010-01-24 18:44:15 +03:00
if ( ! WBC_ERROR_IS_OK ( status ) ) {
goto fail ;
}
snprintf ( request . data . ccache_ntlm_auth . user ,
sizeof ( request . data . ccache_ntlm_auth . user ) - 1 ,
" %s%c%s " , params - > domain_name ,
response . data . info . winbind_separator ,
params - > account_name ) ;
} else {
strncpy ( request . data . ccache_ntlm_auth . user ,
params - > account_name ,
sizeof ( request . data . ccache_ntlm_auth . user ) - 1 ) ;
}
request . data . ccache_ntlm_auth . uid = getuid ( ) ;
request . data . ccache_ntlm_auth . initial_blob_len = 0 ;
request . data . ccache_ntlm_auth . challenge_blob_len = 0 ;
request . extra_len = 0 ;
if ( initial_blob ! = NULL ) {
request . data . ccache_ntlm_auth . initial_blob_len =
initial_blob - > blob . length ;
request . extra_len + = initial_blob - > blob . length ;
}
if ( challenge_blob ! = NULL ) {
request . data . ccache_ntlm_auth . challenge_blob_len =
challenge_blob - > blob . length ;
request . extra_len + = challenge_blob - > blob . length ;
}
if ( request . extra_len ! = 0 ) {
2010-04-04 16:01:23 +04:00
request . extra_data . data = ( char * ) malloc ( request . extra_len ) ;
2010-01-24 18:44:15 +03:00
if ( request . extra_data . data = = NULL ) {
status = WBC_ERR_NO_MEMORY ;
goto fail ;
}
}
if ( initial_blob ! = NULL ) {
memcpy ( request . extra_data . data ,
initial_blob - > blob . data , initial_blob - > blob . length ) ;
}
if ( challenge_blob ! = NULL ) {
memcpy ( request . extra_data . data
+ request . data . ccache_ntlm_auth . initial_blob_len ,
challenge_blob - > blob . data ,
challenge_blob - > blob . length ) ;
}
2015-02-22 01:30:11 +03:00
status = wbcRequestResponse ( ctx , WINBINDD_CCACHE_NTLMAUTH ,
& request , & response ) ;
2010-01-24 18:44:15 +03:00
if ( ! WBC_ERROR_IS_OK ( status ) ) {
goto fail ;
}
2010-04-04 16:01:23 +04:00
result = ( struct wbcCredentialCacheInfo * ) wbcAllocateMemory (
2010-11-27 21:07:40 +03:00
1 , sizeof ( struct wbcCredentialCacheInfo ) ,
2010-04-04 16:01:23 +04:00
wbcCredentialCacheInfoDestructor ) ;
2010-01-24 18:44:15 +03:00
if ( result = = NULL ) {
status = WBC_ERR_NO_MEMORY ;
goto fail ;
}
result - > num_blobs = 0 ;
2010-04-04 16:01:23 +04:00
result - > blobs = NULL ;
2010-01-24 18:44:15 +03:00
status = wbcAddNamedBlob ( & result - > num_blobs , & result - > blobs ,
" auth_blob " , 0 ,
( uint8_t * ) response . extra_data . data ,
response . data . ccache_ntlm_auth . auth_blob_len ) ;
if ( ! WBC_ERROR_IS_OK ( status ) ) {
goto fail ;
}
status = wbcAddNamedBlob (
& result - > num_blobs , & result - > blobs , " session_key " , 0 ,
response . data . ccache_ntlm_auth . session_key ,
sizeof ( response . data . ccache_ntlm_auth . session_key ) ) ;
if ( ! WBC_ERROR_IS_OK ( status ) ) {
goto fail ;
}
2015-11-20 16:06:18 +03:00
if ( response . data . ccache_ntlm_auth . new_spnego ) {
status = wbcAddNamedBlob (
& result - > num_blobs , & result - > blobs , " new_spnego " , 0 ,
& response . data . ccache_ntlm_auth . new_spnego ,
sizeof ( response . data . ccache_ntlm_auth . new_spnego ) ) ;
if ( ! WBC_ERROR_IS_OK ( status ) ) {
goto fail ;
}
}
2010-01-24 18:44:15 +03:00
* info = result ;
2010-04-04 14:12:12 +04:00
result = NULL ;
status = WBC_ERR_SUCCESS ;
2010-01-24 18:44:15 +03:00
fail :
2010-04-04 16:01:23 +04:00
free ( request . extra_data . data ) ;
2010-01-24 18:44:15 +03:00
winbindd_free_response ( & response ) ;
2010-04-04 16:01:23 +04:00
wbcFreeMemory ( result ) ;
2010-01-24 18:44:15 +03:00
return status ;
2008-11-23 17:16:17 +03:00
}
2010-01-09 22:20:36 +03:00
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCredentialCache ( struct wbcCredentialCacheParams * params ,
struct wbcCredentialCacheInfo * * info ,
struct wbcAuthErrorInfo * * error )
{
return wbcCtxCredentialCache ( NULL , params , info , error ) ;
}
2010-01-09 22:20:36 +03:00
/* Authenticate a user with cached credentials */
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCtxCredentialSave ( struct wbcContext * ctx ,
const char * user , const char * password )
2010-01-09 22:20:36 +03:00
{
struct winbindd_request request ;
struct winbindd_response response ;
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
strncpy ( request . data . ccache_save . user , user ,
sizeof ( request . data . ccache_save . user ) - 1 ) ;
strncpy ( request . data . ccache_save . pass , password ,
sizeof ( request . data . ccache_save . pass ) - 1 ) ;
request . data . ccache_save . uid = getuid ( ) ;
2015-02-22 01:30:11 +03:00
return wbcRequestResponse ( ctx , WINBINDD_CCACHE_SAVE , & request , & response ) ;
}
2021-10-12 15:30:09 +03:00
_PUBLIC_
2015-02-22 01:30:11 +03:00
wbcErr wbcCredentialSave ( const char * user , const char * password )
{
return wbcCtxCredentialSave ( NULL , user , password ) ;
2010-01-09 22:20:36 +03:00
}