2023-10-19 09:45:17 +03:00
/*
2007-11-26 04:25:20 +03:00
Unix SMB / CIFS implementation .
Authentication utility functions
Copyright ( C ) Andrew Tridgell 1992 - 1998
2010-04-09 11:18:53 +04:00
Copyright ( C ) Andrew Bartlett 2001 - 2010
2007-11-26 04:25:20 +03:00
Copyright ( C ) Jeremy Allison 2000 - 2001
Copyright ( C ) Rafal Szczesniak 2002
Copyright ( C ) Stefan Metzmacher 2005
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 3 of the License , or
( at your option ) any later version .
2023-10-19 09:45:17 +03:00
2007-11-26 04:25:20 +03:00
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 .
2023-10-19 09:45:17 +03:00
2007-11-26 04:25:20 +03:00
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "auth/auth.h"
2010-12-22 09:17:07 +03:00
# include "auth/auth_sam.h"
2011-02-09 06:22:16 +03:00
# include "auth/credentials/credentials.h"
# include "auth/credentials/credentials_krb5.h"
2007-11-26 04:25:20 +03:00
# include "libcli/security/security.h"
2023-09-21 06:13:20 +03:00
# include "libcli/security/claims-conversions.h"
2007-11-26 04:25:20 +03:00
# include "libcli/auth/libcli_auth.h"
2023-09-21 06:13:20 +03:00
# include "librpc/gen_ndr/claims.h"
# include "librpc/gen_ndr/ndr_claims.h"
2007-11-26 04:25:20 +03:00
# include "dsdb/samdb/samdb.h"
2008-04-02 06:53:27 +04:00
# include "auth/session_proto.h"
2011-02-09 06:22:16 +03:00
# include "system/kerberos.h"
# include <gssapi/gssapi.h>
2011-07-21 11:06:17 +04:00
# include "libcli/wbclient/wbclient.h"
2007-11-26 04:25:20 +03:00
2018-05-21 04:58:12 +03:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_AUTH
2023-10-19 09:45:17 +03:00
_PUBLIC_ struct auth_session_info * anonymous_session ( TALLOC_CTX * mem_ctx ,
2010-07-16 08:32:42 +04:00
struct loadparm_context * lp_ctx )
2007-11-26 04:25:20 +03:00
{
NTSTATUS nt_status ;
struct auth_session_info * session_info = NULL ;
2010-04-09 11:18:53 +04:00
nt_status = auth_anonymous_session_info ( mem_ctx , lp_ctx , & session_info ) ;
2007-11-26 04:25:20 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return NULL ;
}
return session_info ;
}
2023-05-09 05:30:40 +03:00
_PUBLIC_ NTSTATUS auth_generate_security_token ( TALLOC_CTX * mem_ctx ,
struct loadparm_context * lp_ctx , /* Optional, if you don't want privileges */
struct ldb_context * sam_ctx , /* Optional, if you don't want local groups */
const struct auth_user_info_dc * user_info_dc ,
2023-09-27 05:16:21 +03:00
const struct auth_user_info_dc * device_info_dc ,
const struct auth_claims auth_claims ,
2023-05-09 05:30:40 +03:00
uint32_t session_info_flags ,
struct security_token * * _security_token )
2007-11-26 04:25:20 +03:00
{
2023-05-09 05:30:40 +03:00
struct security_token * security_token = NULL ;
2007-11-26 04:25:20 +03:00
NTSTATUS nt_status ;
2023-05-09 05:30:40 +03:00
uint32_t i ;
uint32_t num_sids = 0 ;
2023-09-27 05:16:21 +03:00
uint32_t num_device_sids = 0 ;
2023-05-09 05:30:40 +03:00
const char * filter = NULL ;
2022-09-27 05:13:12 +03:00
struct auth_SidAttr * sids = NULL ;
2023-10-19 10:02:13 +03:00
struct auth_SidAttr * device_sids = NULL ;
2010-04-13 16:11:26 +04:00
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
2023-05-09 05:30:40 +03:00
if ( tmp_ctx = = NULL ) {
2014-02-13 08:51:11 +04:00
return NT_STATUS_NO_MEMORY ;
}
2007-11-26 04:25:20 +03:00
2022-09-27 05:13:12 +03:00
sids = talloc_array ( tmp_ctx , struct auth_SidAttr , user_info_dc - > num_sids ) ;
2014-02-13 08:51:11 +04:00
if ( sids = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2010-12-21 06:08:34 +03:00
2011-02-08 08:53:13 +03:00
num_sids = user_info_dc - > num_sids ;
2010-12-21 06:08:34 +03:00
2011-02-08 08:53:13 +03:00
for ( i = 0 ; i < user_info_dc - > num_sids ; i + + ) {
sids [ i ] = user_info_dc - > sids [ i ] ;
2010-12-21 06:08:34 +03:00
}
2012-12-29 08:13:54 +04:00
/*
* Finally add the " standard " sids .
* The only difference between guest and " anonymous "
* is the addition of Authenticated_Users .
*/
if ( session_info_flags & AUTH_SESSION_INFO_DEFAULT_GROUPS ) {
2022-09-27 05:13:12 +03:00
sids = talloc_realloc ( tmp_ctx , sids , struct auth_SidAttr , num_sids + 2 ) ;
2019-05-07 04:28:49 +03:00
if ( sids = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2012-12-29 08:13:54 +04:00
2022-09-27 05:13:12 +03:00
sid_copy ( & sids [ num_sids ] . sid , & global_sid_World ) ;
2022-12-15 01:58:11 +03:00
sids [ num_sids ] . attrs = SE_GROUP_DEFAULT_FLAGS ;
2012-12-29 08:13:54 +04:00
num_sids + + ;
2022-09-27 05:13:12 +03:00
sid_copy ( & sids [ num_sids ] . sid , & global_sid_Network ) ;
2022-12-15 01:58:11 +03:00
sids [ num_sids ] . attrs = SE_GROUP_DEFAULT_FLAGS ;
2012-12-29 08:13:54 +04:00
num_sids + + ;
}
if ( session_info_flags & AUTH_SESSION_INFO_AUTHENTICATED ) {
2022-09-27 05:13:12 +03:00
sids = talloc_realloc ( tmp_ctx , sids , struct auth_SidAttr , num_sids + 1 ) ;
2019-05-07 04:28:49 +03:00
if ( sids = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2012-12-29 08:13:54 +04:00
2022-09-27 05:13:12 +03:00
sid_copy ( & sids [ num_sids ] . sid , & global_sid_Authenticated_Users ) ;
2022-12-15 01:58:11 +03:00
sids [ num_sids ] . attrs = SE_GROUP_DEFAULT_FLAGS ;
2012-12-29 08:13:54 +04:00
num_sids + + ;
}
2017-03-06 02:11:18 +03:00
if ( session_info_flags & AUTH_SESSION_INFO_NTLM ) {
2022-09-27 05:13:12 +03:00
sids = talloc_realloc ( tmp_ctx , sids , struct auth_SidAttr , num_sids + 1 ) ;
2019-05-07 04:28:49 +03:00
if ( sids = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2017-03-06 02:11:18 +03:00
2022-09-27 05:13:12 +03:00
if ( ! dom_sid_parse ( SID_NT_NTLM_AUTHENTICATION , & sids [ num_sids ] . sid ) ) {
2019-05-07 04:28:49 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2017-03-06 02:11:18 +03:00
return NT_STATUS_INTERNAL_ERROR ;
}
2022-12-15 01:58:11 +03:00
sids [ num_sids ] . attrs = SE_GROUP_DEFAULT_FLAGS ;
2017-03-06 02:11:18 +03:00
num_sids + + ;
}
2012-12-29 08:13:54 +04:00
2023-09-11 06:26:41 +03:00
if ( num_sids > PRIMARY_USER_SID_INDEX & & dom_sid_equal ( & global_sid_Anonymous , & sids [ PRIMARY_USER_SID_INDEX ] . sid ) ) {
2010-08-14 13:55:30 +04:00
/* Don't expand nested groups of system, anonymous etc*/
2023-09-11 06:26:41 +03:00
} else if ( num_sids > PRIMARY_USER_SID_INDEX & & dom_sid_equal ( & global_sid_System , & sids [ PRIMARY_USER_SID_INDEX ] . sid ) ) {
2010-08-14 13:55:30 +04:00
/* Don't expand nested groups of system, anonymous etc*/
2023-05-09 05:30:40 +03:00
} else if ( sam_ctx ! = NULL ) {
2022-12-16 04:24:18 +03:00
filter = talloc_asprintf ( tmp_ctx , " (&(objectClass=group)(groupType: " LDB_OID_COMPARATOR_AND " :=%u)) " ,
2010-08-14 13:55:30 +04:00
GROUP_TYPE_BUILTIN_LOCAL_GROUP ) ;
2010-06-30 11:37:08 +04:00
2010-08-14 13:55:30 +04:00
/* Search for each group in the token */
2012-12-29 08:13:54 +04:00
for ( i = 0 ; i < num_sids ; i + + ) {
2018-12-16 19:11:55 +03:00
struct dom_sid_buf buf ;
2011-01-20 15:39:37 +03:00
const char * sid_dn ;
DATA_BLOB sid_blob ;
2012-12-29 08:13:54 +04:00
2018-12-16 19:11:55 +03:00
sid_dn = talloc_asprintf (
tmp_ctx ,
" <SID=%s> " ,
2022-09-27 05:13:12 +03:00
dom_sid_str_buf ( & sids [ i ] . sid , & buf ) ) ;
2014-02-13 08:51:11 +04:00
if ( sid_dn = = NULL ) {
2019-05-07 04:28:49 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2014-02-13 08:51:11 +04:00
return NT_STATUS_NO_MEMORY ;
}
2011-01-20 15:39:37 +03:00
sid_blob = data_blob_string_const ( sid_dn ) ;
2019-05-07 04:28:49 +03:00
2010-08-14 13:55:30 +04:00
/* This function takes in memberOf values and expands
* them , as long as they meet the filter - so only
2011-01-20 15:39:37 +03:00
* builtin groups
*
* We already have the SID in the token , so set
* ' only childs ' flag to true */
nt_status = dsdb_expand_nested_groups ( sam_ctx , & sid_blob , true , filter ,
tmp_ctx , & sids , & num_sids ) ;
2010-08-14 13:55:30 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
talloc_free ( tmp_ctx ) ;
return nt_status ;
}
}
2010-04-13 16:11:26 +04:00
}
2023-09-27 05:16:21 +03:00
if ( device_info_dc ! = NULL ) {
2023-10-19 10:02:13 +03:00
/*
* Make a copy of the device SIDs in case we need to add extra SIDs on
* the end . One can never have too much copying .
*/
2023-09-27 05:16:21 +03:00
num_device_sids = device_info_dc - > num_sids ;
2023-10-19 10:02:13 +03:00
device_sids = talloc_array ( tmp_ctx ,
struct auth_SidAttr ,
num_device_sids ) ;
if ( device_sids = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2023-09-27 05:16:21 +03:00
2023-10-19 10:02:32 +03:00
for ( i = 0 ; i < num_device_sids ; i + + ) {
device_sids [ i ] = device_info_dc - > sids [ i ] ;
}
if ( session_info_flags & AUTH_SESSION_INFO_DEVICE_DEFAULT_GROUPS ) {
device_sids = talloc_realloc ( tmp_ctx ,
device_sids ,
struct auth_SidAttr ,
num_device_sids + 2 ) ;
if ( device_sids = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
device_sids [ num_device_sids + + ] = ( struct auth_SidAttr ) {
. sid = global_sid_World ,
. attrs = SE_GROUP_DEFAULT_FLAGS ,
} ;
device_sids [ num_device_sids + + ] = ( struct auth_SidAttr ) {
. sid = global_sid_Network ,
. attrs = SE_GROUP_DEFAULT_FLAGS ,
} ;
}
2023-10-20 05:00:12 +03:00
if ( session_info_flags & AUTH_SESSION_INFO_DEVICE_AUTHENTICATED ) {
device_sids = talloc_realloc ( tmp_ctx ,
device_sids ,
struct auth_SidAttr ,
num_device_sids + 1 ) ;
if ( device_sids = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
device_sids [ num_device_sids + + ] = ( struct auth_SidAttr ) {
. sid = global_sid_Authenticated_Users ,
. attrs = SE_GROUP_DEFAULT_FLAGS ,
} ;
}
2023-10-19 10:02:13 +03:00
}
2023-09-27 05:16:21 +03:00
2023-05-09 05:30:40 +03:00
nt_status = security_token_create ( mem_ctx ,
2010-12-21 02:19:53 +03:00
lp_ctx ,
2011-01-20 15:39:37 +03:00
num_sids ,
sids ,
2023-09-27 05:16:21 +03:00
num_device_sids ,
device_sids ,
auth_claims ,
2010-04-19 09:51:57 +04:00
session_info_flags ,
2023-05-09 05:30:40 +03:00
& security_token ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
TALLOC_FREE ( tmp_ctx ) ;
return nt_status ;
}
talloc_steal ( mem_ctx , security_token ) ;
* _security_token = security_token ;
talloc_free ( tmp_ctx ) ;
return NT_STATUS_OK ;
}
_PUBLIC_ NTSTATUS auth_generate_session_info ( TALLOC_CTX * mem_ctx ,
2023-05-09 05:06:23 +03:00
struct loadparm_context * lp_ctx , /* Optional, if you don't want privileges */
2023-05-09 05:30:40 +03:00
struct ldb_context * sam_ctx , /* Optional, if you don't want local groups */
const struct auth_user_info_dc * user_info_dc ,
uint32_t session_info_flags ,
struct auth_session_info * * _session_info )
{
struct auth_session_info * session_info ;
NTSTATUS nt_status ;
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
NT_STATUS_HAVE_NO_MEMORY ( tmp_ctx ) ;
session_info = talloc_zero ( tmp_ctx , struct auth_session_info ) ;
if ( session_info = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
session_info - > info = talloc_reference ( session_info , user_info_dc - > info ) ;
2023-08-03 01:49:51 +03:00
if ( session_info - > info = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2023-05-09 05:30:40 +03:00
session_info - > torture = talloc_zero ( session_info , struct auth_user_info_torture ) ;
if ( session_info - > torture = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
session_info - > torture - > num_dc_sids = user_info_dc - > num_sids ;
session_info - > torture - > dc_sids = talloc_reference ( session_info , user_info_dc - > sids ) ;
if ( session_info - > torture - > dc_sids = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
/* unless set otherwise, the session key is the user session
* key from the auth subsystem */
session_info - > session_key = data_blob_talloc ( session_info , user_info_dc - > user_session_key . data , user_info_dc - > user_session_key . length ) ;
2023-08-07 03:41:45 +03:00
if ( ! session_info - > session_key . data & & user_info_dc - > user_session_key . length ) {
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
2023-05-09 05:30:40 +03:00
}
nt_status = auth_generate_security_token ( session_info ,
lp_ctx ,
sam_ctx ,
user_info_dc ,
2023-09-27 05:16:21 +03:00
NULL /*device_info_dc */ ,
( struct auth_claims ) { } ,
2023-05-09 05:30:40 +03:00
session_info_flags ,
& session_info - > security_token ) ;
2014-02-14 09:04:22 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
TALLOC_FREE ( tmp_ctx ) ;
return nt_status ;
}
2007-11-26 04:25:20 +03:00
2018-04-09 21:44:00 +03:00
session_info - > unique_session_token = GUID_random ( ) ;
2007-11-26 04:25:20 +03:00
session_info - > credentials = NULL ;
2022-06-10 10:18:07 +03:00
session_info - > ticket_type = user_info_dc - > ticket_type ;
2010-04-13 16:11:26 +04:00
talloc_steal ( mem_ctx , session_info ) ;
2007-11-26 04:25:20 +03:00
* _session_info = session_info ;
2010-08-14 13:55:30 +04:00
talloc_free ( tmp_ctx ) ;
2007-11-26 04:25:20 +03:00
return NT_STATUS_OK ;
}
2012-05-02 20:24:34 +04:00
2011-04-05 10:15:27 +04:00
/* Fill out the auth_session_info with a cli_credentials based on the
* auth_session_info we were forwarded over named pipe forwarding .
2011-02-09 06:22:16 +03:00
*
2023-07-20 12:34:28 +03:00
* NOTE : The structure members of session_info_transport are stolen
2011-02-09 06:22:16 +03:00
* with talloc_move ( ) into auth_session_info for long term use
*/
struct auth_session_info * auth_session_info_from_transport ( TALLOC_CTX * mem_ctx ,
struct auth_session_info_transport * session_info_transport ,
struct loadparm_context * lp_ctx ,
const char * * reason )
{
struct auth_session_info * session_info ;
2011-04-05 10:15:27 +04:00
session_info = talloc_steal ( mem_ctx , session_info_transport - > session_info ) ;
2014-11-11 05:23:02 +03:00
/*
* This is to allow us to check the type of this pointer using
* talloc_get_type ( )
*/
talloc_set_name ( session_info , " struct auth_session_info " ) ;
2012-05-02 20:24:34 +04:00
# ifdef HAVE_GSS_IMPORT_CRED
2011-02-09 06:22:16 +03:00
if ( session_info_transport - > exported_gssapi_credentials . length ) {
struct cli_credentials * creds ;
OM_uint32 minor_status ;
gss_buffer_desc cred_token ;
gss_cred_id_t cred_handle ;
const char * error_string ;
int ret ;
2021-06-22 10:39:53 +03:00
bool ok ;
2011-02-09 06:22:16 +03:00
DEBUG ( 10 , ( " Delegated credentials supplied by client \n " ) ) ;
cred_token . value = session_info_transport - > exported_gssapi_credentials . data ;
cred_token . length = session_info_transport - > exported_gssapi_credentials . length ;
ret = gss_import_cred ( & minor_status ,
& cred_token ,
& cred_handle ) ;
if ( ret ! = GSS_S_COMPLETE ) {
* reason = " Internal error in gss_import_cred() " ;
return NULL ;
}
creds = cli_credentials_init ( session_info ) ;
if ( ! creds ) {
* reason = " Out of memory in cli_credentials_init() " ;
return NULL ;
}
session_info - > credentials = creds ;
2021-06-22 10:39:53 +03:00
ok = cli_credentials_set_conf ( creds , lp_ctx ) ;
if ( ! ok ) {
* reason = " Failed to load smb.conf " ;
return NULL ;
}
2011-02-09 06:22:16 +03:00
/* Just so we don't segfault trying to get at a username */
cli_credentials_set_anonymous ( creds ) ;
ret = cli_credentials_set_client_gss_creds ( creds ,
lp_ctx ,
cred_handle ,
CRED_SPECIFIED ,
& error_string ) ;
if ( ret ) {
* reason = talloc_asprintf ( mem_ctx ,
2023-09-11 06:52:16 +03:00
" Failed to set pipe forwarded "
2011-02-09 06:22:16 +03:00
" creds: %s \n " , error_string ) ;
return NULL ;
}
/* This credential handle isn't useful for password
* authentication , so ensure nobody tries to do that */
cli_credentials_set_kerberos_state ( creds ,
2020-08-19 16:46:11 +03:00
CRED_USE_KERBEROS_REQUIRED ,
CRED_SPECIFIED ) ;
2011-02-09 06:22:16 +03:00
}
2012-05-02 20:24:34 +04:00
# endif
2011-02-09 06:22:16 +03:00
return session_info ;
}
/* Create a auth_session_info_transport from an auth_session_info.
*
2011-04-05 10:15:27 +04:00
* NOTE : Members of the auth_session_info_transport structure are
* talloc_referenced ( ) into this structure , and should not be changed .
2011-02-09 06:22:16 +03:00
*/
NTSTATUS auth_session_info_transport_from_session ( TALLOC_CTX * mem_ctx ,
struct auth_session_info * session_info ,
struct tevent_context * event_ctx ,
struct loadparm_context * lp_ctx ,
struct auth_session_info_transport * * transport_out )
{
2011-04-05 10:15:27 +04:00
struct auth_session_info_transport * session_info_transport
= talloc_zero ( mem_ctx , struct auth_session_info_transport ) ;
if ( ! session_info_transport ) {
2011-02-09 06:22:16 +03:00
return NT_STATUS_NO_MEMORY ;
2011-04-05 10:15:27 +04:00
} ;
session_info_transport - > session_info = talloc_reference ( session_info_transport , session_info ) ;
if ( ! session_info_transport - > session_info ) {
return NT_STATUS_NO_MEMORY ;
} ;
2012-05-02 20:24:34 +04:00
# ifdef HAVE_GSS_EXPORT_CRED
2011-02-09 06:22:16 +03:00
if ( session_info - > credentials ) {
struct gssapi_creds_container * gcc ;
OM_uint32 gret ;
OM_uint32 minor_status ;
gss_buffer_desc cred_token ;
const char * error_string ;
int ret ;
ret = cli_credentials_get_client_gss_creds ( session_info - > credentials ,
event_ctx ,
lp_ctx ,
& gcc , & error_string ) ;
if ( ret ! = 0 ) {
* transport_out = session_info_transport ;
return NT_STATUS_OK ;
}
gret = gss_export_cred ( & minor_status ,
gcc - > creds ,
& cred_token ) ;
if ( gret ! = GSS_S_COMPLETE ) {
return NT_STATUS_INTERNAL_ERROR ;
}
if ( cred_token . length ) {
session_info_transport - > exported_gssapi_credentials
= data_blob_talloc ( session_info_transport ,
cred_token . value ,
cred_token . length ) ;
gss_release_buffer ( & minor_status , & cred_token ) ;
NT_STATUS_HAVE_NO_MEMORY ( session_info_transport - > exported_gssapi_credentials . data ) ;
}
}
2012-05-02 20:24:34 +04:00
# endif
2011-02-09 06:22:16 +03:00
* transport_out = session_info_transport ;
return NT_STATUS_OK ;
}
2023-07-20 12:34:28 +03:00
/* Produce a session_info for an arbitrary DN or principal in the local
2010-12-22 09:17:07 +03:00
* DB , assuming the local DB holds all the groups
*
* Supply either a principal or a DN
*/
NTSTATUS authsam_get_session_info_principal ( TALLOC_CTX * mem_ctx ,
struct loadparm_context * lp_ctx ,
struct ldb_context * sam_ctx ,
const char * principal ,
struct ldb_dn * user_dn ,
uint32_t session_info_flags ,
struct auth_session_info * * session_info )
{
NTSTATUS nt_status ;
2011-02-08 08:53:13 +03:00
struct auth_user_info_dc * user_info_dc ;
2010-12-22 09:17:07 +03:00
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
if ( ! tmp_ctx ) {
return NT_STATUS_NO_MEMORY ;
}
2011-02-08 08:53:13 +03:00
nt_status = authsam_get_user_info_dc_principal ( tmp_ctx , lp_ctx , sam_ctx ,
2010-12-22 09:17:07 +03:00
principal , user_dn ,
2011-02-08 08:53:13 +03:00
& user_info_dc ) ;
2010-12-22 09:17:07 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
talloc_free ( tmp_ctx ) ;
return nt_status ;
}
nt_status = auth_generate_session_info ( tmp_ctx , lp_ctx , sam_ctx ,
2023-09-27 05:11:20 +03:00
user_info_dc ,
session_info_flags ,
2010-12-22 09:17:07 +03:00
session_info ) ;
if ( NT_STATUS_IS_OK ( nt_status ) ) {
talloc_steal ( mem_ctx , * session_info ) ;
}
talloc_free ( tmp_ctx ) ;
2011-01-13 08:55:05 +03:00
return nt_status ;
2010-12-22 09:17:07 +03:00
}
2007-11-26 04:25:20 +03:00
/**
* prints a struct auth_session_info security token to debug output .
*/
2023-10-19 09:45:17 +03:00
void auth_session_info_debug ( int dbg_lev ,
2007-11-26 04:25:20 +03:00
const struct auth_session_info * session_info )
{
if ( ! session_info ) {
DEBUG ( dbg_lev , ( " Session Info: (NULL) \n " ) ) ;
2023-10-19 09:45:17 +03:00
return ;
2007-11-26 04:25:20 +03:00
}
2018-05-21 04:58:12 +03:00
security_token_debug ( DBGC_AUTH , dbg_lev ,
session_info - > security_token ) ;
2007-11-26 04:25:20 +03:00
}
2023-09-21 05:48:02 +03:00
NTSTATUS encode_claims_set ( TALLOC_CTX * mem_ctx ,
struct CLAIMS_SET * claims_set ,
DATA_BLOB * claims_blob )
{
TALLOC_CTX * tmp_ctx = NULL ;
enum ndr_err_code ndr_err ;
struct CLAIMS_SET_NDR * claims_set_info = NULL ;
struct CLAIMS_SET_METADATA * metadata = NULL ;
struct CLAIMS_SET_METADATA_NDR * metadata_ndr = NULL ;
if ( claims_blob = = NULL ) {
return NT_STATUS_INVALID_PARAMETER_3 ;
}
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2023-10-05 03:43:54 +03:00
metadata_ndr = talloc ( tmp_ctx , struct CLAIMS_SET_METADATA_NDR ) ;
2023-09-21 05:48:02 +03:00
if ( metadata_ndr = = NULL ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2023-10-05 03:43:54 +03:00
metadata = talloc ( metadata_ndr , struct CLAIMS_SET_METADATA ) ;
2023-09-21 05:48:02 +03:00
if ( metadata = = NULL ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2023-10-05 03:43:54 +03:00
claims_set_info = talloc ( metadata , struct CLAIMS_SET_NDR ) ;
2023-09-21 05:48:02 +03:00
if ( claims_set_info = = NULL ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2023-10-05 03:43:54 +03:00
* metadata_ndr = ( struct CLAIMS_SET_METADATA_NDR ) {
. claims . metadata = metadata ,
} ;
2023-09-21 05:48:02 +03:00
2023-10-05 03:43:54 +03:00
* metadata = ( struct CLAIMS_SET_METADATA ) {
. claims_set = claims_set_info ,
. compression_format = CLAIMS_COMPRESSION_FORMAT_XPRESS_HUFF ,
} ;
2023-09-21 05:48:02 +03:00
2023-10-05 03:43:54 +03:00
* claims_set_info = ( struct CLAIMS_SET_NDR ) {
. claims . claims = claims_set ,
} ;
2023-09-21 05:48:02 +03:00
ndr_err = ndr_push_struct_blob ( claims_blob , mem_ctx , metadata_ndr ,
( ndr_push_flags_fn_t ) ndr_push_CLAIMS_SET_METADATA_NDR ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
NTSTATUS nt_status = ndr_map_error2ntstatus ( ndr_err ) ;
DBG_ERR ( " CLAIMS_SET_METADATA_NDR push failed: %s \n " ,
nt_errstr ( nt_status ) ) ;
talloc_free ( tmp_ctx ) ;
return nt_status ;
}
talloc_free ( tmp_ctx ) ;
return NT_STATUS_OK ;
}
2023-09-21 06:13:20 +03:00
/*
* Construct a ‘ claims_data ’ structure from a claims blob , such as is found in a
* PAC .
*/
NTSTATUS claims_data_from_encoded_claims_set ( TALLOC_CTX * claims_data_ctx ,
const DATA_BLOB * encoded_claims_set ,
struct claims_data * * out )
{
struct claims_data * claims_data = NULL ;
DATA_BLOB data = { } ;
if ( out = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
* out = NULL ;
claims_data = talloc ( claims_data_ctx , struct claims_data ) ;
if ( claims_data = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
if ( encoded_claims_set ! = NULL ) {
/*
* We make a copy of the data , for it might not be
* talloc ‐ allocated — we might have obtained it directly with
* krb5_pac_get_buffer ( ) .
*/
data = data_blob_dup_talloc ( claims_data , * encoded_claims_set ) ;
if ( data . length ! = encoded_claims_set - > length ) {
talloc_free ( claims_data ) ;
return NT_STATUS_NO_MEMORY ;
}
}
* claims_data = ( struct claims_data ) {
. encoded_claims_set = data ,
. flags = CLAIMS_DATA_ENCODED_CLAIMS_PRESENT ,
} ;
* out = claims_data ;
return NT_STATUS_OK ;
}
/*
* Construct a ‘ claims_data ’ structure from a talloc ‐ allocated claims set , such
* as we might build from searching the database . If this function returns
* successfully , it assumes ownership of the claims set .
*/
NTSTATUS claims_data_from_claims_set ( TALLOC_CTX * claims_data_ctx ,
struct CLAIMS_SET * claims_set ,
struct claims_data * * out )
{
struct claims_data * claims_data = NULL ;
if ( out = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
* out = NULL ;
claims_data = talloc ( claims_data_ctx , struct claims_data ) ;
if ( claims_data = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
* claims_data = ( struct claims_data ) {
. claims_set = talloc_steal ( claims_data , claims_set ) ,
. flags = CLAIMS_DATA_CLAIMS_PRESENT ,
} ;
* out = claims_data ;
return NT_STATUS_OK ;
}
/*
* From a ‘ claims_data ’ structure , return an encoded claims blob that can be put
* into a PAC .
*/
2023-10-05 05:11:42 +03:00
NTSTATUS claims_data_encoded_claims_set ( TALLOC_CTX * mem_ctx ,
struct claims_data * claims_data ,
2023-09-21 06:13:20 +03:00
DATA_BLOB * encoded_claims_set_out )
{
2023-10-05 05:11:42 +03:00
uint8_t * data = NULL ;
size_t len ;
2023-09-21 06:13:20 +03:00
if ( encoded_claims_set_out = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
* encoded_claims_set_out = data_blob_null ;
if ( claims_data = = NULL ) {
return NT_STATUS_OK ;
}
if ( ! ( claims_data - > flags & CLAIMS_DATA_ENCODED_CLAIMS_PRESENT ) ) {
NTSTATUS status ;
/* See whether we have a claims set that we can encode. */
if ( ! ( claims_data - > flags & CLAIMS_DATA_CLAIMS_PRESENT ) ) {
return NT_STATUS_OK ;
}
status = encode_claims_set ( claims_data ,
claims_data - > claims_set ,
& claims_data - > encoded_claims_set ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
claims_data - > flags | = CLAIMS_DATA_ENCODED_CLAIMS_PRESENT ;
}
2023-10-05 05:11:42 +03:00
if ( claims_data - > encoded_claims_set . data ! = NULL ) {
data = talloc_reference ( mem_ctx , claims_data - > encoded_claims_set . data ) ;
if ( data = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
}
len = claims_data - > encoded_claims_set . length ;
* encoded_claims_set_out = data_blob_const ( data , len ) ;
2023-09-21 06:13:20 +03:00
return NT_STATUS_OK ;
}
/*
* From a ‘ claims_data ’ structure , return an array of security claims that can
* be put in a security token for access checks .
*/
NTSTATUS claims_data_security_claims ( TALLOC_CTX * mem_ctx ,
struct claims_data * claims_data ,
struct CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 * * security_claims_out ,
uint32_t * n_security_claims_out )
{
struct CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 * security_claims = NULL ;
uint32_t n_security_claims ;
NTSTATUS status ;
if ( security_claims_out = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( n_security_claims_out = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
* security_claims_out = NULL ;
* n_security_claims_out = 0 ;
if ( claims_data = = NULL ) {
return NT_STATUS_OK ;
}
if ( ! ( claims_data - > flags & CLAIMS_DATA_SECURITY_CLAIMS_PRESENT ) ) {
struct CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 * decoded_claims = NULL ;
uint32_t n_decoded_claims = 0 ;
/* See whether we have a claims set that we can convert. */
if ( ! ( claims_data - > flags & CLAIMS_DATA_CLAIMS_PRESENT ) ) {
/*
* See whether we have an encoded claims set that we can
* decode .
*/
if ( ! ( claims_data - > flags & CLAIMS_DATA_ENCODED_CLAIMS_PRESENT ) ) {
/* We don’ t have anything. */
return NT_STATUS_OK ;
}
/* Decode an existing claims set. */
if ( claims_data - > encoded_claims_set . length ) {
TALLOC_CTX * tmp_ctx = NULL ;
struct CLAIMS_SET_METADATA_NDR claims ;
const struct CLAIMS_SET_METADATA * metadata = NULL ;
enum ndr_err_code ndr_err ;
tmp_ctx = talloc_new ( claims_data ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
ndr_err = ndr_pull_struct_blob ( & claims_data - > encoded_claims_set ,
tmp_ctx ,
& claims ,
( ndr_pull_flags_fn_t ) ndr_pull_CLAIMS_SET_METADATA_NDR ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
status = ndr_map_error2ntstatus ( ndr_err ) ;
DBG_ERR ( " Failed to parse encoded claims set: %s \n " ,
nt_errstr ( status ) ) ;
talloc_free ( tmp_ctx ) ;
return status ;
}
metadata = claims . claims . metadata ;
if ( metadata ! = NULL ) {
struct CLAIMS_SET_NDR * claims_set_ndr = metadata - > claims_set ;
if ( claims_set_ndr ! = NULL ) {
struct CLAIMS_SET * * claims_set = & claims_set_ndr - > claims . claims ;
claims_data - > claims_set = talloc_move ( claims_data , claims_set ) ;
}
}
talloc_free ( tmp_ctx ) ;
}
claims_data - > flags | = CLAIMS_DATA_CLAIMS_PRESENT ;
}
/*
* Convert the decoded claims set to the security attribute
* claims format .
*/
status = token_claims_to_claims_v1 ( claims_data ,
claims_data - > claims_set ,
& decoded_claims ,
& n_decoded_claims ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
claims_data - > security_claims = decoded_claims ;
claims_data - > n_security_claims = n_decoded_claims ;
claims_data - > flags | = CLAIMS_DATA_SECURITY_CLAIMS_PRESENT ;
}
if ( claims_data - > security_claims ! = NULL ) {
security_claims = talloc_reference ( mem_ctx , claims_data - > security_claims ) ;
if ( security_claims = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
}
n_security_claims = claims_data - > n_security_claims ;
* security_claims_out = security_claims ;
* n_security_claims_out = n_security_claims ;
return NT_STATUS_OK ;
}