2000-06-23 09:49:11 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2000-06-23 09:49:11 +04:00
uid / user handling
Copyright ( C ) Tim Potter 2000
2011-02-14 23:39:10 +03:00
2000-06-23 09:49:11 +04:00
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
2000-06-23 09:49:11 +04:00
( at your option ) any later version .
2011-02-14 23:39:10 +03:00
2000-06-23 09:49:11 +04: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 .
2011-02-14 23:39:10 +03:00
2000-06-23 09:49:11 +04:00
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/>.
2000-06-23 09:49:11 +04:00
*/
# include "includes.h"
2011-10-27 14:00:53 +04:00
# include "system/passwd.h"
2011-03-22 18:57:01 +03:00
# include "smbd/smbd.h"
2009-01-08 14:03:45 +03:00
# include "smbd/globals.h"
2010-09-17 09:31:28 +04:00
# include "libcli/security/security_token.h"
2011-03-24 15:46:20 +03:00
# include "auth.h"
2011-04-14 02:36:23 +04:00
# include "smbprofile.h"
2012-06-28 22:59:51 +04:00
# include "../lib/util/setid.h"
2000-06-23 09:49:11 +04:00
extern struct current_user current_user ;
2008-01-11 03:35:54 +03:00
/****************************************************************************
Are two UNIX tokens equal ?
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-02-11 10:49:15 +03:00
bool unix_token_equal ( const struct security_unix_token * t1 , const struct security_unix_token * t2 )
2008-01-11 03:35:54 +03:00
{
if ( t1 - > uid ! = t2 - > uid | | t1 - > gid ! = t2 - > gid | |
t1 - > ngroups ! = t2 - > ngroups ) {
return false ;
}
if ( memcmp ( t1 - > groups , t2 - > groups ,
t1 - > ngroups * sizeof ( gid_t ) ) ! = 0 ) {
return false ;
}
return true ;
}
2000-08-04 02:38:43 +04:00
/****************************************************************************
Become the specified uid .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-23 09:49:11 +04:00
2007-10-19 04:40:25 +04:00
static bool become_uid ( uid_t uid )
2000-06-23 09:49:11 +04:00
{
/* Check for dodgy uid values */
if ( uid = = ( uid_t ) - 1 | |
( ( sizeof ( uid_t ) = = 2 ) & & ( uid = = ( uid_t ) 65535 ) ) ) {
2009-01-08 14:03:45 +03:00
if ( ! become_uid_done ) {
2000-06-23 09:49:11 +04:00
DEBUG ( 1 , ( " WARNING: using uid %d is a security risk \n " ,
( int ) uid ) ) ;
2009-01-08 14:03:45 +03:00
become_uid_done = true ;
2000-06-23 09:49:11 +04:00
}
}
/* Set effective user id */
set_effective_uid ( uid ) ;
return True ;
}
2000-08-04 02:38:43 +04:00
/****************************************************************************
Become the specified gid .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-23 09:49:11 +04:00
2007-10-19 04:40:25 +04:00
static bool become_gid ( gid_t gid )
2000-06-23 09:49:11 +04:00
{
/* Check for dodgy gid values */
if ( gid = = ( gid_t ) - 1 | | ( ( sizeof ( gid_t ) = = 2 ) & &
( gid = = ( gid_t ) 65535 ) ) ) {
2009-01-08 14:03:45 +03:00
if ( ! become_gid_done ) {
2000-06-23 09:49:11 +04:00
DEBUG ( 1 , ( " WARNING: using gid %d is a security risk \n " ,
( int ) gid ) ) ;
2009-01-08 14:03:45 +03:00
become_gid_done = true ;
2000-06-23 09:49:11 +04:00
}
}
2011-02-14 23:39:10 +03:00
2000-06-23 09:49:11 +04:00
/* Set effective group id */
set_effective_gid ( gid ) ;
return True ;
}
2000-08-04 02:38:43 +04:00
/****************************************************************************
Become the specified uid and gid .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-23 09:49:11 +04:00
2007-10-19 04:40:25 +04:00
static bool become_id ( uid_t uid , gid_t gid )
2000-06-23 09:49:11 +04:00
{
return become_gid ( gid ) & & become_uid ( uid ) ;
}
2000-08-04 02:38:43 +04:00
/****************************************************************************
Drop back to root privileges in order to change to another user .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-23 09:49:11 +04:00
static void gain_root ( void )
{
2001-06-26 07:45:45 +04:00
if ( non_root_mode ( ) ) {
return ;
}
2000-06-23 09:49:11 +04:00
if ( geteuid ( ) ! = 0 ) {
set_effective_uid ( 0 ) ;
if ( geteuid ( ) ! = 0 ) {
DEBUG ( 0 ,
( " Warning: You appear to have a trapdoor "
" uid system \n " ) ) ;
}
}
if ( getegid ( ) ! = 0 ) {
set_effective_gid ( 0 ) ;
if ( getegid ( ) ! = 0 ) {
DEBUG ( 0 ,
( " Warning: You appear to have a trapdoor "
" gid system \n " ) ) ;
}
}
}
2000-08-04 02:38:43 +04:00
/****************************************************************************
Get the list of current groups .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-23 09:49:11 +04:00
2011-02-28 23:31:53 +03:00
static int get_current_groups ( gid_t gid , uint32_t * p_ngroups , gid_t * * p_groups )
2000-06-23 09:49:11 +04:00
{
2000-08-02 06:11:55 +04:00
int i ;
2002-07-15 14:35:28 +04:00
int ngroups ;
gid_t * groups = NULL ;
2000-08-02 06:11:55 +04:00
( * p_ngroups ) = 0 ;
( * p_groups ) = NULL ;
2002-07-15 14:35:28 +04:00
/* this looks a little strange, but is needed to cope with
systems that put the current egid in the group list
returned from getgroups ( ) ( tridge ) */
save_re_gid ( ) ;
set_effective_gid ( gid ) ;
2012-06-28 22:59:51 +04:00
samba_setgid ( gid ) ;
2000-08-02 06:11:55 +04:00
2017-04-18 00:30:54 +03:00
ngroups = sys_getgroups ( 0 , NULL ) ;
2002-07-15 14:35:28 +04:00
if ( ngroups < = 0 ) {
goto fail ;
}
2004-12-07 21:25:53 +03:00
if ( ( groups = SMB_MALLOC_ARRAY ( gid_t , ngroups + 1 ) ) = = NULL ) {
2000-08-02 06:11:55 +04:00
DEBUG ( 0 , ( " setup_groups malloc fail ! \n " ) ) ;
2002-07-15 14:35:28 +04:00
goto fail ;
2000-08-02 06:11:55 +04:00
}
2001-04-28 04:05:11 +04:00
if ( ( ngroups = sys_getgroups ( ngroups , groups ) ) = = - 1 ) {
2002-07-15 14:35:28 +04:00
goto fail ;
2001-04-28 04:05:11 +04:00
}
2000-08-02 06:11:55 +04:00
2002-07-15 14:35:28 +04:00
restore_re_gid ( ) ;
2000-08-02 06:11:55 +04:00
( * p_ngroups ) = ngroups ;
( * p_groups ) = groups ;
2000-06-23 09:49:11 +04:00
2011-03-08 19:47:36 +03:00
DEBUG ( 4 , ( " get_current_groups: user is in %u groups: " , ngroups ) ) ;
2000-08-02 06:11:55 +04:00
for ( i = 0 ; i < ngroups ; i + + ) {
2011-03-08 19:47:36 +03:00
DEBUG ( 4 , ( " %s%d " , ( i ? " , " : " " ) , ( int ) groups [ i ] ) ) ;
2000-06-23 09:49:11 +04:00
}
2011-03-08 19:47:36 +03:00
DEBUG ( 4 , ( " \n " ) ) ;
2000-06-23 09:49:11 +04:00
2002-07-15 14:35:28 +04:00
return ngroups ;
fail :
SAFE_FREE ( groups ) ;
restore_re_gid ( ) ;
return - 1 ;
2000-06-23 09:49:11 +04:00
}
2000-08-04 02:38:43 +04:00
/****************************************************************************
Create a new security context on the stack . It is the same as the old
one . User changes are done using the set_sec_ctx ( ) function .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-23 09:49:11 +04:00
2007-10-19 04:40:25 +04:00
bool push_sec_ctx ( void )
2000-06-23 09:49:11 +04:00
{
2000-06-23 23:57:42 +04:00
struct sec_ctx * ctx_p ;
2014-11-17 14:52:35 +03:00
START_PROFILE ( push_sec_ctx ) ;
2000-06-23 09:49:11 +04:00
/* Check we don't overflow our stack */
2000-08-09 22:40:48 +04:00
if ( sec_ctx_stack_ndx = = MAX_SEC_CTX_DEPTH ) {
2000-06-23 09:49:11 +04:00
DEBUG ( 0 , ( " Security context stack overflow! \n " ) ) ;
2007-06-16 01:58:49 +04:00
smb_panic ( " Security context stack overflow! " ) ;
2000-06-23 09:49:11 +04:00
}
/* Store previous user context */
sec_ctx_stack_ndx + + ;
2000-06-23 23:57:42 +04:00
ctx_p = & sec_ctx_stack [ sec_ctx_stack_ndx ] ;
2000-06-23 09:49:11 +04:00
2006-02-02 23:44:50 +03:00
ctx_p - > ut . uid = geteuid ( ) ;
ctx_p - > ut . gid = getegid ( ) ;
2000-06-23 09:49:11 +04:00
2011-03-08 19:47:36 +03:00
DEBUG ( 4 , ( " push_sec_ctx(%u, %u) : sec_ctx_stack_ndx = %d \n " ,
2006-02-02 23:44:50 +03:00
( unsigned int ) ctx_p - > ut . uid , ( unsigned int ) ctx_p - > ut . gid , sec_ctx_stack_ndx ) ) ;
2000-10-05 07:28:58 +04:00
2006-02-04 01:19:41 +03:00
ctx_p - > token = dup_nt_token ( NULL ,
sec_ctx_stack [ sec_ctx_stack_ndx - 1 ] . token ) ;
2000-08-04 02:38:43 +04:00
2006-02-02 23:44:50 +03:00
ctx_p - > ut . ngroups = sys_getgroups ( 0 , NULL ) ;
2000-06-23 23:57:42 +04:00
2006-02-02 23:44:50 +03:00
if ( ctx_p - > ut . ngroups ! = 0 ) {
if ( ! ( ctx_p - > ut . groups = SMB_MALLOC_ARRAY ( gid_t , ctx_p - > ut . ngroups ) ) ) {
2000-06-23 23:57:42 +04:00
DEBUG ( 0 , ( " Out of memory in push_sec_ctx() \n " ) ) ;
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( ctx_p - > token ) ;
2000-06-23 23:57:42 +04:00
return False ;
}
2000-06-23 09:49:11 +04:00
2006-02-02 23:44:50 +03:00
sys_getgroups ( ctx_p - > ut . ngroups , ctx_p - > ut . groups ) ;
2000-06-23 23:57:42 +04:00
} else {
2006-02-02 23:44:50 +03:00
ctx_p - > ut . groups = NULL ;
2000-06-23 23:57:42 +04:00
}
2000-06-23 09:49:11 +04:00
2014-11-17 14:52:35 +03:00
END_PROFILE ( push_sec_ctx ) ;
2000-06-23 09:49:11 +04:00
return True ;
}
2007-06-08 23:58:32 +04:00
/****************************************************************************
Change UNIX security context . Calls panic if not successful so no return value .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-06-09 04:10:26 +04:00
# ifndef HAVE_DARWIN_INITGROUPS
/* Normal credential switch path. */
2007-06-08 23:58:32 +04:00
static void set_unix_security_ctx ( uid_t uid , gid_t gid , int ngroups , gid_t * groups )
{
/* Start context switch */
gain_root ( ) ;
# ifdef HAVE_SETGROUPS
2007-09-14 19:08:07 +04:00
if ( sys_setgroups ( gid , ngroups , groups ) ! = 0 & & ! non_root_mode ( ) ) {
2007-09-14 08:17:17 +04:00
smb_panic ( " sys_setgroups failed " ) ;
}
2007-06-08 23:58:32 +04:00
# endif
become_id ( uid , gid ) ;
/* end context switch */
}
2007-06-09 04:10:26 +04:00
# else /* HAVE_DARWIN_INITGROUPS */
/* The Darwin groups implementation is a little unusual. The list of
* groups in the kernel credential is not exhaustive , but more like
* a cache . The full group list is held in userspace and checked
* dynamically .
*
* This is an optional mechanism , and setgroups ( 2 ) opts out
* of it . That is , if you call setgroups , then the list of groups you
* set are the only groups that are ever checked . This is not what we
* want . We want to opt in to the dynamic resolution mechanism , so we
* need to specify the uid of the user whose group list ( cache ) we are
* setting .
*
* The Darwin rules are :
* 1. Thou shalt setegid , initgroups and seteuid IN THAT ORDER
* 2. Thou shalt not pass more that NGROUPS_MAX to initgroups
* 3. Thou shalt leave the first entry in the groups list well alone
*/
# include <sys/syscall.h>
static void set_unix_security_ctx ( uid_t uid , gid_t gid , int ngroups , gid_t * groups )
{
int max = groups_max ( ) ;
/* Start context switch */
gain_root ( ) ;
become_gid ( gid ) ;
if ( syscall ( SYS_initgroups , ( ngroups > max ) ? max : ngroups ,
2007-09-14 19:08:07 +04:00
groups , uid ) = = - 1 & & ! non_root_mode ( ) ) {
2007-06-09 04:10:26 +04:00
DEBUG ( 0 , ( " WARNING: failed to set group list "
2012-09-08 11:19:33 +04:00
" (%d groups) for UID %d: %s \n " ,
2007-06-09 04:10:26 +04:00
ngroups , uid , strerror ( errno ) ) ) ;
2007-09-14 08:17:17 +04:00
smb_panic ( " sys_setgroups failed " ) ;
2007-06-09 04:10:26 +04:00
}
become_uid ( uid ) ;
/* end context switch */
}
# endif /* HAVE_DARWIN_INITGROUPS */
2000-08-04 02:38:43 +04:00
/****************************************************************************
Set the current security context to a given user .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-23 09:49:11 +04:00
2014-11-17 14:52:35 +03:00
static void set_sec_ctx_internal ( uid_t uid , gid_t gid ,
int ngroups , gid_t * groups ,
const struct security_token * token )
2000-06-23 09:49:11 +04:00
{
2000-06-23 23:57:42 +04:00
struct sec_ctx * ctx_p = & sec_ctx_stack [ sec_ctx_stack_ndx ] ;
2011-02-14 23:39:10 +03:00
2000-06-23 09:49:11 +04:00
/* Set the security context */
2011-03-08 19:47:36 +03:00
DEBUG ( 4 , ( " setting sec ctx (%u, %u) - sec_ctx_stack_ndx = %d \n " ,
2001-04-28 01:14:18 +04:00
( unsigned int ) uid , ( unsigned int ) gid , sec_ctx_stack_ndx ) ) ;
2000-06-23 09:49:11 +04:00
2010-09-17 09:31:28 +04:00
security_token_debug ( DBGC_CLASS , 5 , token ) ;
2002-09-25 19:19:00 +04:00
debug_unix_user_token ( DBGC_CLASS , 5 , uid , gid , ngroups , groups ) ;
2001-01-04 22:27:08 +03:00
2007-06-08 23:58:32 +04:00
/* Change uid, gid and supplementary group list. */
set_unix_security_ctx ( uid , gid , ngroups , groups ) ;
2000-06-23 09:49:11 +04:00
2006-02-02 23:44:50 +03:00
ctx_p - > ut . ngroups = ngroups ;
2000-06-23 21:31:38 +04:00
2006-02-02 23:44:50 +03:00
SAFE_FREE ( ctx_p - > ut . groups ) ;
2006-06-28 04:50:14 +04:00
if ( token & & ( token = = ctx_p - > token ) ) {
2000-08-09 22:40:48 +04:00
smb_panic ( " DUPLICATE_TOKEN " ) ;
2006-06-28 04:50:14 +04:00
}
2000-08-09 22:40:48 +04:00
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( ctx_p - > token ) ;
2011-02-14 23:39:10 +03:00
2006-06-28 04:50:14 +04:00
if ( ngroups ) {
2014-04-14 16:42:56 +04:00
ctx_p - > ut . groups = ( gid_t * ) smb_xmemdup ( groups ,
sizeof ( gid_t ) * ngroups ) ;
2006-06-28 04:50:14 +04:00
} else {
ctx_p - > ut . groups = NULL ;
}
if ( token ) {
ctx_p - > token = dup_nt_token ( NULL , token ) ;
if ( ! ctx_p - > token ) {
smb_panic ( " dup_nt_token failed " ) ;
}
} else {
ctx_p - > token = NULL ;
}
2000-06-23 09:49:11 +04:00
2006-02-02 23:44:50 +03:00
ctx_p - > ut . uid = uid ;
ctx_p - > ut . gid = gid ;
2000-06-23 09:49:11 +04:00
/* Update current_user stuff */
2006-02-02 23:44:50 +03:00
current_user . ut . uid = uid ;
current_user . ut . gid = gid ;
current_user . ut . ngroups = ngroups ;
current_user . ut . groups = groups ;
2001-07-25 22:07:36 +04:00
current_user . nt_user_token = ctx_p - > token ;
2000-06-23 09:49:11 +04:00
}
2014-11-17 14:52:35 +03:00
void set_sec_ctx ( uid_t uid , gid_t gid , int ngroups , gid_t * groups , const struct security_token * token )
{
START_PROFILE ( set_sec_ctx ) ;
set_sec_ctx_internal ( uid , gid , ngroups , groups , token ) ;
END_PROFILE ( set_sec_ctx ) ;
}
2000-08-04 02:38:43 +04:00
/****************************************************************************
Become root context .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-23 09:49:11 +04:00
void set_root_sec_ctx ( void )
{
/* May need to worry about supplementary groups at some stage */
2014-11-17 14:52:35 +03:00
START_PROFILE ( set_root_sec_ctx ) ;
set_sec_ctx_internal ( 0 , 0 , 0 , NULL , NULL ) ;
END_PROFILE ( set_root_sec_ctx ) ;
2000-06-23 09:49:11 +04:00
}
2000-08-04 02:38:43 +04:00
/****************************************************************************
Pop a security context from the stack .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-23 09:49:11 +04:00
2007-10-19 04:40:25 +04:00
bool pop_sec_ctx ( void )
2000-06-23 09:49:11 +04:00
{
2000-06-23 23:57:42 +04:00
struct sec_ctx * ctx_p ;
struct sec_ctx * prev_ctx_p ;
2014-11-17 14:52:35 +03:00
START_PROFILE ( pop_sec_ctx ) ;
2000-06-23 09:49:11 +04:00
/* Check for stack underflow */
if ( sec_ctx_stack_ndx = = 0 ) {
DEBUG ( 0 , ( " Security context stack underflow! \n " ) ) ;
2007-06-16 01:58:49 +04:00
smb_panic ( " Security context stack underflow! " ) ;
2000-06-23 09:49:11 +04:00
}
2000-06-23 23:57:42 +04:00
ctx_p = & sec_ctx_stack [ sec_ctx_stack_ndx ] ;
2000-06-23 09:49:11 +04:00
/* Clear previous user info */
2006-02-02 23:44:50 +03:00
ctx_p - > ut . uid = ( uid_t ) - 1 ;
ctx_p - > ut . gid = ( gid_t ) - 1 ;
2000-06-23 09:49:11 +04:00
2006-02-02 23:44:50 +03:00
SAFE_FREE ( ctx_p - > ut . groups ) ;
ctx_p - > ut . ngroups = 0 ;
2000-06-23 09:49:11 +04:00
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( ctx_p - > token ) ;
2000-08-04 02:38:43 +04:00
2000-06-23 09:49:11 +04:00
/* Pop back previous user */
sec_ctx_stack_ndx - - ;
2000-06-23 23:57:42 +04:00
prev_ctx_p = & sec_ctx_stack [ sec_ctx_stack_ndx ] ;
2007-06-08 23:58:32 +04:00
/* Change uid, gid and supplementary group list. */
set_unix_security_ctx ( prev_ctx_p - > ut . uid ,
prev_ctx_p - > ut . gid ,
prev_ctx_p - > ut . ngroups ,
prev_ctx_p - > ut . groups ) ;
2000-06-23 09:49:11 +04:00
/* Update current_user stuff */
2006-02-02 23:44:50 +03:00
current_user . ut . uid = prev_ctx_p - > ut . uid ;
current_user . ut . gid = prev_ctx_p - > ut . gid ;
current_user . ut . ngroups = prev_ctx_p - > ut . ngroups ;
current_user . ut . groups = prev_ctx_p - > ut . groups ;
2000-08-04 02:38:43 +04:00
current_user . nt_user_token = prev_ctx_p - > token ;
2000-06-23 09:49:11 +04:00
2014-11-17 14:52:35 +03:00
END_PROFILE ( pop_sec_ctx ) ;
2011-03-08 19:47:36 +03:00
DEBUG ( 4 , ( " pop_sec_ctx (%u, %u) - sec_ctx_stack_ndx = %d \n " ,
2001-04-28 01:14:18 +04:00
( unsigned int ) geteuid ( ) , ( unsigned int ) getegid ( ) , sec_ctx_stack_ndx ) ) ;
2000-06-23 09:49:11 +04:00
return True ;
}
/* Initialise the security context system */
void init_sec_ctx ( void )
{
int i ;
2000-06-23 23:57:42 +04:00
struct sec_ctx * ctx_p ;
2000-06-23 09:49:11 +04:00
/* Initialise security context stack */
memset ( sec_ctx_stack , 0 , sizeof ( struct sec_ctx ) * MAX_SEC_CTX_DEPTH ) ;
for ( i = 0 ; i < MAX_SEC_CTX_DEPTH ; i + + ) {
2006-02-02 23:44:50 +03:00
sec_ctx_stack [ i ] . ut . uid = ( uid_t ) - 1 ;
sec_ctx_stack [ i ] . ut . gid = ( gid_t ) - 1 ;
2000-06-23 09:49:11 +04:00
}
/* Initialise first level of stack. It is the current context */
2000-06-23 23:57:42 +04:00
ctx_p = & sec_ctx_stack [ 0 ] ;
2000-06-23 09:49:11 +04:00
2006-02-02 23:44:50 +03:00
ctx_p - > ut . uid = geteuid ( ) ;
ctx_p - > ut . gid = getegid ( ) ;
2000-06-23 09:49:11 +04:00
2006-02-02 23:44:50 +03:00
get_current_groups ( ctx_p - > ut . gid , & ctx_p - > ut . ngroups , & ctx_p - > ut . groups ) ;
2000-06-23 09:49:11 +04:00
2000-08-04 02:38:43 +04:00
ctx_p - > token = NULL ; /* Maps to guest user. */
2000-06-23 09:49:11 +04:00
/* Initialise current_user global */
2006-02-02 23:44:50 +03:00
current_user . ut . uid = ctx_p - > ut . uid ;
current_user . ut . gid = ctx_p - > ut . gid ;
current_user . ut . ngroups = ctx_p - > ut . ngroups ;
current_user . ut . groups = ctx_p - > ut . groups ;
2000-06-23 09:49:11 +04:00
/* The conn and vuid are usually taken care of by other modules.
We initialise them here . */
current_user . conn = NULL ;
current_user . vuid = UID_FIELD_INVALID ;
2000-08-04 02:38:43 +04:00
current_user . nt_user_token = NULL ;
2000-06-23 09:49:11 +04:00
}
2012-10-26 04:07:29 +04:00
/*************************************************************
Called when we ' re inside a become_root ( ) temporary escalation
of privileges and the nt_user_token is NULL . Return the last
active token on the context stack . We know there is at least
one valid non - NULL token on the stack so panic if we underflow .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
const struct security_token * sec_ctx_active_token ( void )
{
int stack_index = sec_ctx_stack_ndx ;
struct sec_ctx * ctx_p = & sec_ctx_stack [ stack_index ] ;
while ( ctx_p - > token = = NULL ) {
stack_index - - ;
if ( stack_index < 0 ) {
DEBUG ( 0 , ( " Security context active token "
" stack underflow! \n " ) ) ;
smb_panic ( " Security context active token "
" stack underflow! " ) ;
}
ctx_p = & sec_ctx_stack [ stack_index ] ;
}
return ctx_p - > token ;
}