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
2018-05-21 04:58:12 +03:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_AUTH
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 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 ;
2018-09-25 14:11:09 +03:00
bool match ;
match = security_token_is_system ( token ) ;
if ( match ) {
/*
* SYSTEM user uid and gid is 0
*/
* sec = talloc_zero ( mem_ctx , struct security_unix_token ) ;
if ( * sec = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
return NT_STATUS_OK ;
}
2011-07-21 11:06:17 +04:00
/* we can't do unix security without a user and group */
2022-12-16 02:08:41 +03:00
if ( token - > num_sids < PRIMARY_SIDS_COUNT ) {
2011-07-21 11:06:17 +04:00
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
}
2016-09-18 15:03:33 +03:00
status = wbc_sids_to_xids ( ids , token - > num_sids ) ;
2011-07-21 11:06:17 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2011-10-17 16:20:45 +04:00
g = token - > num_sids ;
2022-12-16 02:08:41 +03:00
if ( ids [ PRIMARY_USER_SID_INDEX ] . xid . type ! = ID_TYPE_BOTH ) {
2011-10-17 16:20:45 +04:00
g - - ;
}
( * sec ) - > ngroups = g ;
( * sec ) - > groups = talloc_array ( * sec , gid_t , ( * sec ) - > ngroups ) ;
NT_STATUS_HAVE_NO_MEMORY ( ( * sec ) - > groups ) ;
g = 0 ;
2022-12-16 02:08:41 +03:00
if ( ids [ PRIMARY_USER_SID_INDEX ] . xid . type = = ID_TYPE_BOTH ) {
2011-10-17 16:20:45 +04:00
( * sec ) - > uid = ids [ 0 ] . xid . id ;
( * sec ) - > groups [ g ] = ids [ 0 ] . xid . id ;
g + + ;
2022-12-16 02:08:41 +03:00
} else if ( ids [ PRIMARY_USER_SID_INDEX ] . xid . type = = ID_TYPE_UID ) {
2011-07-21 11:06:17 +04:00
( * sec ) - > uid = ids [ 0 ] . xid . id ;
} else {
2018-12-16 19:11:55 +03:00
struct dom_sid_buf buf ;
2011-11-17 11:24:24 +04:00
DEBUG ( 0 , ( " Unable to convert first SID (%s) in user token to a UID. Conversion was returned as type %d, full token: \n " ,
2022-12-16 02:08:41 +03:00
dom_sid_str_buf ( ids [ PRIMARY_USER_SID_INDEX ] . sid , & buf ) ,
( int ) ids [ PRIMARY_USER_SID_INDEX ] . xid . type ) ) ;
2018-05-21 04:58:12 +03:00
security_token_debug ( DBGC_AUTH , 0 , token ) ;
2011-07-21 11:06:17 +04:00
return NT_STATUS_INVALID_SID ;
}
2022-12-16 02:08:41 +03:00
if ( ids [ PRIMARY_GROUP_SID_INDEX ] . xid . type = = ID_TYPE_BOTH | |
ids [ PRIMARY_GROUP_SID_INDEX ] . xid . type = = ID_TYPE_GID ) {
( * sec ) - > gid = ids [ PRIMARY_GROUP_SID_INDEX ] . xid . id ;
( * sec ) - > groups [ g ] = ids [ PRIMARY_GROUP_SID_INDEX ] . xid . id ;
2011-10-17 16:20:45 +04:00
g + + ;
2011-07-21 11:06:17 +04:00
} else {
2018-12-16 19:11:55 +03:00
struct dom_sid_buf buf ;
2011-11-17 11:24:24 +04:00
DEBUG ( 0 , ( " Unable to convert second SID (%s) in user token to a GID. Conversion was returned as type %d, full token: \n " ,
2022-12-16 02:08:41 +03:00
dom_sid_str_buf ( ids [ PRIMARY_GROUP_SID_INDEX ] . sid , & buf ) ,
( int ) ids [ PRIMARY_GROUP_SID_INDEX ] . xid . type ) ) ;
2018-05-21 04:58:12 +03:00
security_token_debug ( DBGC_AUTH , 0 , token ) ;
2011-07-21 11:06:17 +04:00
return NT_STATUS_INVALID_SID ;
}
2022-12-16 02:08:41 +03:00
for ( s = REMAINING_SIDS_INDEX ; s < token - > num_sids ; s + + ) {
2011-10-17 16:20:45 +04:00
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 {
2018-12-16 19:11:55 +03:00
struct dom_sid_buf buf ;
2011-11-17 11:24:24 +04:00
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 " ,
2018-12-16 19:11:55 +03:00
dom_sid_str_buf ( ids [ s ] . sid , & buf ) ,
( unsigned int ) s , ( int ) ids [ s ] . xid . type ) ) ;
2018-05-21 04:58:12 +03:00
security_token_debug ( DBGC_AUTH , 0 , token ) ;
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
/*
2020-06-04 16:39:02 +03:00
* Fill in the unix_info elements in a struct session_info
*/
NTSTATUS fill_unix_info ( struct loadparm_context * lp_ctx ,
const char * original_user_name ,
struct auth_session_info * session_info )
2011-07-21 12:21:19 +04:00
{
2020-06-04 16:39:02 +03:00
session_info - > unix_info = talloc_zero ( session_info ,
struct auth_user_info_unix ) ;
2011-07-21 12:21:19 +04:00
NT_STATUS_HAVE_NO_MEMORY ( session_info - > unix_info ) ;
2020-06-04 16:39:02 +03:00
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 ) ;
2011-07-21 12:21:19 +04:00
NT_STATUS_HAVE_NO_MEMORY ( session_info - > unix_info - > unix_name ) ;
2018-09-25 14:16:15 +03:00
if ( original_user_name = = NULL ) {
original_user_name = session_info - > unix_info - > unix_name ;
}
2020-01-17 21:31:06 +03:00
session_info - > unix_info - > sanitized_username =
talloc_alpha_strcpy ( session_info - > unix_info ,
original_user_name ,
" . _-$ " ) ;
NT_STATUS_HAVE_NO_MEMORY ( session_info - > unix_info - > sanitized_username ) ;
2011-07-21 12:21:19 +04:00
return NT_STATUS_OK ;
}
2020-06-04 16:39:02 +03: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 loadparm_context * lp_ctx ,
const char * original_user_name ,
struct auth_session_info * session_info )
{
NTSTATUS status = NT_STATUS_OK ;
status = security_token_to_unix_token ( session_info ,
session_info - > security_token ,
& session_info - > unix_token ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = fill_unix_info ( lp_ctx ,
original_user_name ,
session_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return NT_STATUS_OK ;
}
2020-06-04 16:41:34 +03:00
/*
* Set the given auth_user_info_unix and auth_unix_token elements in a
* struct session_info , similar auth_session_info_fill_unix ( ) .
* Receives the uid and gid for the unix token as parameters and does
* not query the unix token from winbind ( via security_token_to_unix_token ( ) ) .
* This is useful to fill a user session info manually if winbind is not
* available .
*/
NTSTATUS auth_session_info_set_unix ( struct loadparm_context * lp_ctx ,
const char * original_user_name ,
int uid ,
int gid ,
struct auth_session_info * session_info )
{
NTSTATUS status ;
session_info - > unix_token = talloc_zero ( session_info ,
struct security_unix_token ) ;
if ( session_info - > unix_token = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
session_info - > unix_token - > uid = uid ;
session_info - > unix_token - > gid = gid ;
status = fill_unix_info ( lp_ctx ,
original_user_name ,
session_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return NT_STATUS_OK ;
}