2001-12-30 08:59:43 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-12-30 08:59:43 +03:00
ads ( active directory ) utility library
Copyright ( C ) Andrew Tridgell 2001
Copyright ( C ) Remus Koos 2001
Copyright ( C ) Andrew Bartlett 2001
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
2001-12-30 08:59:43 +03:00
( 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
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2001-12-30 08:59:43 +03:00
*/
# include "includes.h"
2009-11-27 17:52:57 +03:00
# include "smb_krb5.h"
2012-04-24 20:37:13 +04:00
# include "system/gssapi.h"
2011-02-24 13:56:08 +03:00
# include "smb_ldap.h"
2011-05-06 14:54:59 +04:00
# include "libads/ads_status.h"
2001-12-30 08:59:43 +03:00
/*
build a ADS_STATUS structure
*/
ADS_STATUS ads_build_error ( enum ads_error_type etype ,
int rc , int minor_status )
{
ADS_STATUS ret ;
2002-09-25 19:19:00 +04:00
2004-01-09 17:54:33 +03:00
if ( etype = = ENUM_ADS_ERROR_NT ) {
DEBUG ( 0 , ( " don't use ads_build_error with ENUM_ADS_ERROR_NT! \n " ) ) ;
2002-09-25 19:19:00 +04:00
ret . err . rc = - 1 ;
2004-01-09 17:54:33 +03:00
ret . error_type = ENUM_ADS_ERROR_SYSTEM ;
2002-09-25 19:19:00 +04:00
ret . minor_status = 0 ;
return ret ;
}
ret . err . rc = rc ;
ret . error_type = etype ;
2001-12-30 08:59:43 +03:00
ret . minor_status = minor_status ;
return ret ;
}
2002-09-25 19:19:00 +04:00
ADS_STATUS ads_build_nt_error ( enum ads_error_type etype ,
NTSTATUS nt_status )
{
ADS_STATUS ret ;
2004-01-09 17:54:33 +03:00
if ( etype ! = ENUM_ADS_ERROR_NT ) {
DEBUG ( 0 , ( " don't use ads_build_nt_error without ENUM_ADS_ERROR_NT! \n " ) ) ;
2002-09-25 19:19:00 +04:00
ret . err . rc = - 1 ;
2004-01-09 17:54:33 +03:00
ret . error_type = ENUM_ADS_ERROR_SYSTEM ;
2002-09-25 19:19:00 +04:00
ret . minor_status = 0 ;
return ret ;
}
ret . err . nt_status = nt_status ;
ret . error_type = etype ;
ret . minor_status = 0 ;
return ret ;
}
2001-12-30 08:59:43 +03:00
/*
do a rough conversion between ads error codes and NT status codes
we ' ll need to fill this in more
*/
2002-09-25 19:19:00 +04:00
NTSTATUS ads_ntstatus ( ADS_STATUS status )
2001-12-30 08:59:43 +03:00
{
2006-08-18 19:10:46 +04:00
switch ( status . error_type ) {
case ENUM_ADS_ERROR_NT :
2002-09-25 19:19:00 +04:00
return status . err . nt_status ;
2006-08-18 19:10:46 +04:00
case ENUM_ADS_ERROR_SYSTEM :
2006-08-17 17:46:02 +04:00
return map_nt_error_from_unix ( status . err . rc ) ;
2002-10-01 22:26:00 +04:00
# ifdef HAVE_LDAP
2006-08-18 19:10:46 +04:00
case ENUM_ADS_ERROR_LDAP :
2006-09-12 18:45:24 +04:00
if ( status . err . rc = = LDAP_SUCCESS ) {
return NT_STATUS_OK ;
}
2012-05-18 11:38:48 +04:00
if ( status . err . rc = = LDAP_TIMELIMIT_EXCEEDED ) {
return NT_STATUS_IO_TIMEOUT ;
}
2006-08-27 21:24:31 +04:00
return NT_STATUS_LDAP ( status . err . rc ) ;
2004-01-08 11:19:18 +03:00
# endif
# ifdef HAVE_KRB5
2006-08-18 19:10:46 +04:00
case ENUM_ADS_ERROR_KRB5 :
2006-08-22 04:36:31 +04:00
return krb5_to_nt_status ( status . err . rc ) ;
2002-10-01 22:26:00 +04:00
# endif
2006-08-18 19:10:46 +04:00
default :
break ;
}
if ( ADS_ERR_OK ( status ) ) {
return NT_STATUS_OK ;
}
2001-12-30 08:59:43 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
/*
return a string for an error from a ads routine
*/
const char * ads_errstr ( ADS_STATUS status )
{
switch ( status . error_type ) {
2004-01-09 17:54:33 +03:00
case ENUM_ADS_ERROR_SYSTEM :
2002-09-25 19:19:00 +04:00
return strerror ( status . err . rc ) ;
2001-12-30 08:59:43 +03:00
# ifdef HAVE_LDAP
2004-01-09 17:54:33 +03:00
case ENUM_ADS_ERROR_LDAP :
2002-09-25 19:19:00 +04:00
return ldap_err2string ( status . err . rc ) ;
2001-12-30 08:59:43 +03:00
# endif
# ifdef HAVE_KRB5
2004-01-09 17:54:33 +03:00
case ENUM_ADS_ERROR_KRB5 :
2002-09-25 19:19:00 +04:00
return error_message ( status . err . rc ) ;
2004-01-09 17:54:33 +03:00
case ENUM_ADS_ERROR_GSS :
2001-12-30 09:20:23 +03:00
{
2007-11-24 19:27:19 +03:00
char * ret ;
2015-04-18 18:40:14 +03:00
uint32_t msg_ctx ;
uint32_t minor ;
2004-12-19 06:23:10 +03:00
gss_buffer_desc msg1 , msg2 ;
2004-12-01 01:57:41 +03:00
msg_ctx = 0 ;
2002-01-14 09:34:53 +03:00
2001-12-30 08:59:43 +03:00
msg1 . value = NULL ;
msg2 . value = NULL ;
2002-09-25 19:19:00 +04:00
gss_display_status ( & minor , status . err . rc , GSS_C_GSS_CODE ,
2001-12-30 08:59:43 +03:00
GSS_C_NULL_OID , & msg_ctx , & msg1 ) ;
gss_display_status ( & minor , status . minor_status , GSS_C_MECH_CODE ,
GSS_C_NULL_OID , & msg_ctx , & msg2 ) ;
2007-11-24 19:27:19 +03:00
ret = talloc_asprintf ( talloc_tos ( ) , " %s : %s " ,
( char * ) msg1 . value , ( char * ) msg2 . value ) ;
SMB_ASSERT ( ret ! = NULL ) ;
2001-12-30 08:59:43 +03:00
gss_release_buffer ( & minor , & msg1 ) ;
gss_release_buffer ( & minor , & msg2 ) ;
return ret ;
2001-12-30 09:20:23 +03:00
}
2001-12-30 08:59:43 +03:00
# endif
2004-01-09 17:54:33 +03:00
case ENUM_ADS_ERROR_NT :
2004-01-08 11:19:18 +03:00
return get_friendly_nt_error_msg ( ads_ntstatus ( status ) ) ;
2001-12-30 08:59:43 +03:00
default :
return " Unknown ADS error type!? (not compiled in?) " ;
}
2007-03-27 04:00:50 +04:00
}
2001-12-30 08:59:43 +03:00
2012-02-13 04:23:15 +04:00
# ifdef HAVE_KRB5
2015-04-18 18:40:14 +03:00
NTSTATUS gss_err_to_ntstatus ( uint32_t maj , uint32_t min )
2007-12-27 04:12:36 +03:00
{
ADS_STATUS adss = ADS_ERROR_GSS ( maj , min ) ;
DEBUG ( 10 , ( " gss_err_to_ntstatus: Error %s \n " ,
ads_errstr ( adss ) ) ) ;
return ads_ntstatus ( adss ) ;
}
# endif