2004-11-03 13:09:48 +03:00
/*
Unix SMB / CIFS implementation .
gain / lose root privileges
Copyright ( C ) Andrew Tridgell 2004
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-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2004-11-03 13:09:48 +03:00
( 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
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-11-03 13:09:48 +03:00
*/
2022-04-19 22:17:17 +03:00
# include "replace.h"
# include <talloc.h>
# include "lib/util/fault.h"
2010-01-30 16:25:51 +03:00
# include "system/passwd.h"
2014-04-07 18:29:21 +04:00
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
2008-10-20 20:59:51 +04:00
# include "../lib/util/unix_privs.h"
2012-06-28 22:59:51 +04:00
# include "../lib/util/setid.h"
2004-11-03 13:09:48 +03:00
2006-02-28 16:12:39 +03:00
/**
* @ file
* @ brief Gaining / losing root privileges
*/
2004-11-03 13:09:48 +03:00
/*
there are times when smbd needs to temporarily gain root privileges
to do some operation . To do this you call root_privileges ( ) , which
returns a talloc handle . To restore your previous privileges
talloc_free ( ) this pointer .
Note that this call is considered successful even if it does not
2005-08-24 21:01:23 +04:00
manage to gain root privileges , but it will call smb_abort ( ) if it
2004-11-03 13:09:48 +03:00
fails to restore the privileges afterwards . The logic is that
failing to gain root access can be caught by whatever operation
needs to be run as root failing , but failing to lose the root
privileges is dangerous .
This also means that this code is safe to be called from completely
unprivileged processes .
*/
struct saved_state {
uid_t uid ;
} ;
2006-05-24 11:34:11 +04:00
static int privileges_destructor ( struct saved_state * s )
2004-11-03 13:09:48 +03:00
{
if ( geteuid ( ) ! = s - > uid & &
2012-06-28 22:59:51 +04:00
samba_seteuid ( s - > uid ) ! = 0 ) {
2004-11-03 13:09:48 +03:00
smb_panic ( " Failed to restore privileges " ) ;
}
return 0 ;
}
2006-03-06 03:24:51 +03:00
/**
* Obtain root privileges for the current process .
*
* The privileges can be dropped by talloc_free ( ) - ing the
* token returned by this function
*/
2004-11-03 13:09:48 +03:00
void * root_privileges ( void )
{
struct saved_state * s ;
2005-01-27 10:08:20 +03:00
s = talloc ( NULL , struct saved_state ) ;
2004-11-03 13:09:48 +03:00
if ( ! s ) return NULL ;
s - > uid = geteuid ( ) ;
if ( s - > uid ! = 0 ) {
2012-06-28 22:59:51 +04:00
samba_seteuid ( 0 ) ;
2004-11-03 13:09:48 +03:00
}
talloc_set_destructor ( s , privileges_destructor ) ;
return s ;
}
2010-03-05 09:49:11 +03:00
uid_t root_privileges_original_uid ( void * s )
{
struct saved_state * saved = talloc_get_type_abort ( s , struct saved_state ) ;
return saved - > uid ;
}