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 .
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 , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "auth/auth.h"
# include "libcli/security/security.h"
# include "libcli/auth/libcli_auth.h"
# include "dsdb/samdb/samdb.h"
2008-04-02 06:53:27 +04:00
# include "auth/session_proto.h"
2007-11-26 04:25:20 +03:00
2008-04-02 06:53:27 +04: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 ;
}
2010-04-13 06:00:06 +04:00
_PUBLIC_ NTSTATUS auth_generate_session_info ( TALLOC_CTX * mem_ctx ,
2010-08-14 13:55:30 +04:00
struct auth_context * auth_context , /* Optional if the domain SID is in the NT AUTHORITY domain */
2010-04-13 06:00:06 +04:00
struct auth_serversupplied_info * server_info ,
2010-04-19 09:51:57 +04:00
uint32_t session_info_flags ,
2010-04-13 06:00:06 +04:00
struct auth_session_info * * _session_info )
2007-11-26 04:25:20 +03:00
{
struct auth_session_info * session_info ;
NTSTATUS nt_status ;
2010-04-13 16:11:26 +04:00
unsigned int i , num_groupSIDs = 0 ;
const char * account_sid_string ;
const char * account_sid_dn ;
DATA_BLOB account_sid_blob ;
const char * primary_group_string ;
const char * primary_group_dn ;
DATA_BLOB primary_group_blob ;
2007-11-26 04:25:20 +03:00
2010-04-13 16:11:26 +04:00
const char * filter ;
struct dom_sid * * groupSIDs = NULL ;
2010-09-28 06:45:56 +04:00
const struct dom_sid * anonymous_sid , * system_sid ;
2010-04-13 16:11:26 +04:00
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
NT_STATUS_HAVE_NO_MEMORY ( tmp_ctx ) ;
session_info = talloc ( tmp_ctx , struct auth_session_info ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( session_info , tmp_ctx ) ;
2007-11-26 04:25:20 +03:00
session_info - > server_info = talloc_reference ( session_info , server_info ) ;
/* unless set otherwise, the session key is the user session
* key from the auth subsystem */
session_info - > session_key = server_info - > user_session_key ;
2010-08-14 13:55:30 +04:00
anonymous_sid = dom_sid_parse_talloc ( tmp_ctx , SID_NT_ANONYMOUS ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( anonymous_sid , tmp_ctx ) ;
system_sid = dom_sid_parse_talloc ( tmp_ctx , SID_NT_SYSTEM ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( system_sid , tmp_ctx ) ;
if ( dom_sid_equal ( anonymous_sid , server_info - > account_sid ) ) {
/* Don't expand nested groups of system, anonymous etc*/
} else if ( dom_sid_equal ( system_sid , server_info - > account_sid ) ) {
/* Don't expand nested groups of system, anonymous etc*/
} else if ( auth_context ) {
groupSIDs = talloc_array ( tmp_ctx , struct dom_sid * , server_info - > n_domain_groups ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( groupSIDs , tmp_ctx ) ;
if ( ! groupSIDs ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
num_groupSIDs = server_info - > n_domain_groups ;
for ( i = 0 ; i < server_info - > n_domain_groups ; i + + ) {
groupSIDs [ i ] = server_info - > domain_groups [ i ] ;
}
filter = talloc_asprintf ( tmp_ctx , " (&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u)) " ,
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 */
2010-04-13 16:11:26 +04:00
2010-08-14 13:55:30 +04:00
/* Expands the account SID - this function takes in
* memberOf - like values , so we fake one up with the
* < SID = S - . . . > format of DN and then let it expand
* them , as long as they meet the filter - so only
* builtin groups
*
* We already have the primary group in the token , so set
* ' only childs ' flag to true
*/
account_sid_string = dom_sid_string ( tmp_ctx , server_info - > account_sid ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( account_sid_string , server_info ) ;
account_sid_dn = talloc_asprintf ( tmp_ctx , " <SID=%s> " , account_sid_string ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( account_sid_dn , server_info ) ;
account_sid_blob = data_blob_string_const ( account_sid_dn ) ;
nt_status = authsam_expand_nested_groups ( auth_context - > sam_ctx , & account_sid_blob , true , filter ,
tmp_ctx , & groupSIDs , & num_groupSIDs ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
talloc_free ( tmp_ctx ) ;
return nt_status ;
}
2010-04-13 16:11:26 +04:00
2010-08-14 13:55:30 +04:00
/* Expands the primary group - this function takes in
* memberOf - like values , so we fake one up with the
* < SID = S - . . . > format of DN and then let it expand
2010-04-13 16:11:26 +04:00
* them , as long as they meet the filter - so only
2010-08-14 13:55:30 +04:00
* builtin groups
*
* We already have the primary group in the token , so set
* ' only childs ' flag to true
*/
primary_group_string = dom_sid_string ( tmp_ctx , server_info - > primary_group_sid ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( primary_group_string , server_info ) ;
primary_group_dn = talloc_asprintf ( tmp_ctx , " <SID=%s> " , primary_group_string ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( primary_group_dn , server_info ) ;
primary_group_blob = data_blob_string_const ( primary_group_dn ) ;
nt_status = authsam_expand_nested_groups ( auth_context - > sam_ctx , & primary_group_blob , true , filter ,
tmp_ctx , & groupSIDs , & num_groupSIDs ) ;
2010-04-13 16:11:26 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
talloc_free ( tmp_ctx ) ;
return nt_status ;
}
2010-08-14 13:55:30 +04:00
for ( i = 0 ; i < server_info - > n_domain_groups ; i + + ) {
char * group_string ;
const char * group_dn ;
DATA_BLOB group_blob ;
group_string = dom_sid_string ( tmp_ctx ,
server_info - > domain_groups [ i ] ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( group_string , server_info ) ;
group_dn = talloc_asprintf ( tmp_ctx , " <SID=%s> " , group_string ) ;
talloc_free ( group_string ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( group_dn , server_info ) ;
group_blob = data_blob_string_const ( group_dn ) ;
/* This function takes in memberOf values and expands
* them , as long as they meet the filter - so only
* builtin groups */
nt_status = authsam_expand_nested_groups ( auth_context - > sam_ctx , & group_blob , true , filter ,
tmp_ctx , & groupSIDs , & num_groupSIDs ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
talloc_free ( tmp_ctx ) ;
return nt_status ;
}
}
2010-04-13 16:11:26 +04:00
}
2007-11-26 04:25:20 +03:00
nt_status = security_token_create ( session_info ,
2010-08-14 13:55:30 +04:00
auth_context ? auth_context - > lp_ctx : NULL ,
2007-11-26 04:25:20 +03:00
server_info - > account_sid ,
server_info - > primary_group_sid ,
2010-04-13 16:11:26 +04:00
num_groupSIDs ,
groupSIDs ,
2010-04-19 09:51:57 +04:00
session_info_flags ,
2007-11-26 04:25:20 +03:00
& session_info - > security_token ) ;
2010-04-13 16:11:26 +04:00
NT_STATUS_NOT_OK_RETURN_AND_FREE ( nt_status , tmp_ctx ) ;
2007-11-26 04:25:20 +03:00
session_info - > credentials = NULL ;
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 ;
}
/**
* prints a struct auth_session_info security token to debug output .
*/
void auth_session_info_debug ( int dbg_lev ,
const struct auth_session_info * session_info )
{
if ( ! session_info ) {
DEBUG ( dbg_lev , ( " Session Info: (NULL) \n " ) ) ;
return ;
}
2010-09-17 09:23:19 +04:00
security_token_debug ( 0 , dbg_lev , session_info - > security_token ) ;
2007-11-26 04:25:20 +03:00
}