2011-07-21 11:06:17 +04:00
/*
Unix SMB / CIFS implementation .
Deal with unix elements in the security token
Copyright ( C ) Andrew Tridgell 2004
Copyright ( C ) Andrew Bartlett 2011
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/wbclient/wbclient.h"
2011-07-21 12:21:19 +04:00
# include "param/param.h"
2011-07-21 11:06:17 +04:00
/*
form a security_unix_token from the current security_token
*/
NTSTATUS security_token_to_unix_token ( TALLOC_CTX * mem_ctx ,
struct wbc_context * wbc_ctx ,
struct security_token * token ,
struct security_unix_token * * sec )
{
2011-10-17 16:20:45 +04:00
uint32_t s , g ;
2011-07-21 11:06:17 +04:00
NTSTATUS status ;
struct id_map * ids ;
struct composite_context * ctx ;
/* we can't do unix security without a user and group */
if ( token - > num_sids < 2 ) {
return NT_STATUS_ACCESS_DENIED ;
}
2011-10-17 16:20:45 +04:00
* sec = talloc_zero ( mem_ctx , struct security_unix_token ) ;
if ( * sec = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2011-07-21 11:06:17 +04:00
2011-10-17 16:20:45 +04:00
ids = talloc_zero_array ( mem_ctx , struct id_map , token - > num_sids ) ;
NT_STATUS_HAVE_NO_MEMORY ( ids ) ;
2011-07-21 11:06:17 +04:00
2011-10-17 16:20:45 +04:00
for ( s = 0 ; s < token - > num_sids ; s + + ) {
ids [ s ] . sid = & token - > sids [ s ] ;
ids [ s ] . status = ID_UNKNOWN ;
2011-07-21 11:06:17 +04:00
}
ctx = wbc_sids_to_xids_send ( wbc_ctx , ids , token - > num_sids , ids ) ;
NT_STATUS_HAVE_NO_MEMORY ( ctx ) ;
status = wbc_sids_to_xids_recv ( ctx , & ids ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
2011-10-17 16:20:45 +04:00
g = token - > num_sids ;
if ( ids [ 0 ] . xid . type ! = ID_TYPE_BOTH ) {
g - - ;
}
( * sec ) - > ngroups = g ;
( * sec ) - > groups = talloc_array ( * sec , gid_t , ( * sec ) - > ngroups ) ;
NT_STATUS_HAVE_NO_MEMORY ( ( * sec ) - > groups ) ;
g = 0 ;
if ( ids [ 0 ] . xid . type = = ID_TYPE_BOTH ) {
( * sec ) - > uid = ids [ 0 ] . xid . id ;
( * sec ) - > groups [ g ] = ids [ 0 ] . xid . id ;
g + + ;
} else if ( ids [ 0 ] . xid . type = = ID_TYPE_UID ) {
2011-07-21 11:06:17 +04:00
( * sec ) - > uid = ids [ 0 ] . xid . id ;
} else {
2011-11-17 11:24:24 +04:00
char * sid_str = dom_sid_string ( mem_ctx , ids [ 0 ] . sid ) ;
DEBUG ( 0 , ( " Unable to convert first SID (%s) in user token to a UID. Conversion was returned as type %d, full token: \n " ,
sid_str , ( int ) ids [ 0 ] . xid . type ) ) ;
security_token_debug ( 0 , 0 , token ) ;
talloc_free ( sid_str ) ;
2011-07-21 11:06:17 +04:00
return NT_STATUS_INVALID_SID ;
}
if ( ids [ 1 ] . xid . type = = ID_TYPE_BOTH | |
ids [ 1 ] . xid . type = = ID_TYPE_GID ) {
( * sec ) - > gid = ids [ 1 ] . xid . id ;
2011-10-17 16:20:45 +04:00
( * sec ) - > groups [ g ] = ids [ 1 ] . xid . id ;
g + + ;
2011-07-21 11:06:17 +04:00
} else {
2011-11-17 11:24:24 +04:00
char * sid_str = dom_sid_string ( mem_ctx , ids [ 1 ] . sid ) ;
DEBUG ( 0 , ( " Unable to convert second SID (%s) in user token to a GID. Conversion was returned as type %d, full token: \n " ,
sid_str , ( int ) ids [ 1 ] . xid . type ) ) ;
security_token_debug ( 0 , 0 , token ) ;
talloc_free ( sid_str ) ;
2011-07-21 11:06:17 +04:00
return NT_STATUS_INVALID_SID ;
}
2011-10-17 16:20:45 +04:00
for ( s = 2 ; s < token - > num_sids ; s + + ) {
if ( ids [ s ] . xid . type = = ID_TYPE_BOTH | |
ids [ s ] . xid . type = = ID_TYPE_GID ) {
( * sec ) - > groups [ g ] = ids [ s ] . xid . id ;
g + + ;
2011-07-21 11:06:17 +04:00
} else {
2011-11-17 11:24:24 +04:00
char * sid_str = dom_sid_string ( mem_ctx , ids [ s ] . sid ) ;
DEBUG ( 0 , ( " Unable to convert SID (%s) at index %u in user token to a GID. Conversion was returned as type %d, full token: \n " ,
sid_str , ( unsigned int ) s , ( int ) ids [ s ] . xid . type ) ) ;
security_token_debug ( 0 , 0 , token ) ;
talloc_free ( sid_str ) ;
2011-07-21 11:06:17 +04:00
return NT_STATUS_INVALID_SID ;
}
}
2011-11-17 11:24:24 +04:00
DEBUG ( 5 , ( " Successfully converted security token to a unix token: " ) ) ;
security_token_debug ( 0 , 5 , token ) ;
2011-07-21 11:06:17 +04:00
TALLOC_FREE ( ids ) ;
return NT_STATUS_OK ;
}
2011-07-21 12:21:19 +04:00
/*
Fill in the auth_user_info_unix and auth_unix_token elements in a struct session_info
*/
NTSTATUS auth_session_info_fill_unix ( struct wbc_context * wbc_ctx ,
struct loadparm_context * lp_ctx ,
struct auth_session_info * session_info )
{
char * su ;
size_t len ;
NTSTATUS status = security_token_to_unix_token ( session_info , wbc_ctx ,
session_info - > security_token ,
& session_info - > unix_token ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
session_info - > unix_info = talloc_zero ( session_info , struct auth_user_info_unix ) ;
NT_STATUS_HAVE_NO_MEMORY ( session_info - > unix_info ) ;
session_info - > unix_info - > system = security_token_is_system ( session_info - > security_token ) ;
session_info - > unix_info - > unix_name = talloc_asprintf ( session_info - > unix_info ,
" %s%s%s " , session_info - > info - > domain_name ,
lpcfg_winbind_separator ( lp_ctx ) ,
session_info - > info - > account_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( session_info - > unix_info - > unix_name ) ;
len = strlen ( session_info - > info - > account_name ) + 1 ;
session_info - > unix_info - > sanitized_username = su = talloc_array ( session_info - > unix_info , char , len ) ;
NT_STATUS_HAVE_NO_MEMORY ( su ) ;
alpha_strcpy ( su , session_info - > info - > account_name ,
" . _-$ " , len ) ;
return NT_STATUS_OK ;
}