2009-08-05 10:50:03 +10:00
/*
Copyright ( C ) Andrew Tridgell 2009
2011-10-08 10:52:02 +02:00
Copyright ( c ) 2011 Andreas Schneider < asn @ samba . org >
2009-08-05 10:50:03 +10: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
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/>.
*/
2010-01-30 14:25:51 +01:00
# ifdef _SAMBA_BUILD_
2009-08-05 10:50:03 +10:00
# define UID_WRAPPER_NOT_REPLACE
2011-10-27 12:00:53 +02:00
# include "replace.h"
2009-08-05 10:50:03 +10:00
# include "system/passwd.h"
2011-10-27 12:00:53 +02:00
# include <talloc.h>
2010-01-30 14:25:51 +01:00
# else /* _SAMBA_BUILD_ */
# error uid_wrapper_only_supported_in_samba_yet
# endif
2009-08-05 10:50:03 +10:00
# ifndef _PUBLIC_
# define _PUBLIC_
# endif
/*
we keep the virtualised euid / egid / groups information here
*/
static struct {
bool initialised ;
bool enabled ;
2011-10-07 18:58:58 +02:00
uid_t myuid ;
2009-08-05 10:50:03 +10:00
uid_t euid ;
2011-10-07 18:58:58 +02:00
uid_t mygid ;
2009-08-05 10:50:03 +10:00
gid_t egid ;
gid_t * groups ;
} uwrap ;
static void uwrap_init ( void )
{
if ( uwrap . initialised ) return ;
uwrap . initialised = true ;
if ( getenv ( " UID_WRAPPER " ) ) {
uwrap . enabled = true ;
2009-08-05 13:31:06 +10:00
/* put us in one group */
2011-10-07 18:58:58 +02:00
uwrap . myuid = uwrap . euid = geteuid ( ) ;
uwrap . mygid = uwrap . egid = getegid ( ) ;
2010-10-09 09:44:43 +02:00
uwrap . groups = talloc_array ( NULL , gid_t , 1 ) ;
2009-08-05 13:31:06 +10:00
uwrap . groups [ 0 ] = 0 ;
2009-08-05 10:50:03 +10:00
}
}
2009-08-05 11:21:06 +10:00
# undef uwrap_enabled
_PUBLIC_ int uwrap_enabled ( void )
{
uwrap_init ( ) ;
return uwrap . enabled ? 1 : 0 ;
}
2011-10-08 10:08:37 +02:00
# ifdef HAVE_SETEUID
2009-08-05 10:50:03 +10:00
_PUBLIC_ int uwrap_seteuid ( uid_t euid )
{
uwrap_init ( ) ;
if ( ! uwrap . enabled ) {
return seteuid ( euid ) ;
}
/* assume for now that the ruid stays as root */
2011-10-07 18:58:58 +02:00
if ( euid = = 0 ) {
uwrap . euid = uwrap . myuid ;
} else {
uwrap . euid = euid ;
}
2009-08-05 10:50:03 +10:00
return 0 ;
}
2011-10-08 10:08:37 +02:00
# endif
2009-08-05 10:50:03 +10:00
2011-10-08 10:08:37 +02:00
# ifdef HAVE_SETREUID
2011-10-06 16:25:32 +02:00
_PUBLIC_ int uwrap_setreuid ( uid_t ruid , uid_t euid )
{
uwrap_init ( ) ;
if ( ! uwrap . enabled ) {
return setreuid ( ruid , euid ) ;
}
/* assume for now that the ruid stays as root */
2011-10-07 18:58:58 +02:00
if ( euid = = 0 ) {
uwrap . euid = uwrap . myuid ;
} else {
uwrap . euid = euid ;
}
2011-10-06 16:25:32 +02:00
return 0 ;
}
2011-10-08 10:08:37 +02:00
# endif
2011-10-06 16:25:32 +02:00
2011-10-08 10:08:37 +02:00
# ifdef HAVE_SETRESUID
2011-10-07 10:30:23 +02:00
_PUBLIC_ int uwrap_setresuid ( uid_t ruid , uid_t euid , uid_t suid )
{
uwrap_init ( ) ;
if ( ! uwrap . enabled ) {
return setresuid ( ruid , euid , suid ) ;
}
/* assume for now that the ruid stays as root */
2011-10-07 18:58:58 +02:00
if ( euid = = 0 ) {
uwrap . euid = uwrap . myuid ;
} else {
uwrap . euid = euid ;
}
2011-10-07 10:30:23 +02:00
return 0 ;
}
2011-10-08 10:08:37 +02:00
# endif
2011-10-07 10:30:23 +02:00
2009-08-05 10:50:03 +10:00
_PUBLIC_ uid_t uwrap_geteuid ( void )
{
uwrap_init ( ) ;
if ( ! uwrap . enabled ) {
return geteuid ( ) ;
}
return uwrap . euid ;
}
2011-10-08 10:08:37 +02:00
# ifdef HAVE_SETEGID
2009-08-05 10:50:03 +10:00
_PUBLIC_ int uwrap_setegid ( gid_t egid )
{
uwrap_init ( ) ;
if ( ! uwrap . enabled ) {
return setegid ( egid ) ;
}
/* assume for now that the ruid stays as root */
2011-10-07 18:58:58 +02:00
if ( egid = = 0 ) {
uwrap . egid = uwrap . mygid ;
} else {
uwrap . egid = egid ;
}
2009-08-05 10:50:03 +10:00
return 0 ;
}
2011-10-08 10:08:37 +02:00
# endif
2009-08-05 10:50:03 +10:00
2011-10-08 10:08:37 +02:00
# ifdef HAVE_SETREGID
2011-10-06 16:52:03 +02:00
_PUBLIC_ int uwrap_setregid ( gid_t rgid , gid_t egid )
{
uwrap_init ( ) ;
if ( ! uwrap . enabled ) {
return setregid ( rgid , egid ) ;
}
/* assume for now that the ruid stays as root */
2011-10-07 18:58:58 +02:00
if ( egid = = 0 ) {
uwrap . egid = uwrap . mygid ;
} else {
uwrap . egid = egid ;
}
2011-10-06 16:52:03 +02:00
return 0 ;
}
2011-10-08 10:08:37 +02:00
# endif
2011-10-06 16:52:03 +02:00
2011-10-08 10:52:02 +02:00
# ifdef HAVE_SETRESGID
_PUBLIC_ int uwrap_setresgid ( gid_t rgid , gid_t egid , gid_t sgid )
{
uwrap_init ( ) ;
if ( ! uwrap . enabled ) {
return setresgid ( rgid , egid , sgid ) ;
}
/* assume for now that the ruid stays as root */
if ( egid = = 0 ) {
uwrap . egid = uwrap . mygid ;
} else {
uwrap . egid = egid ;
}
return 0 ;
}
# endif
2009-08-05 10:50:03 +10:00
_PUBLIC_ uid_t uwrap_getegid ( void )
{
uwrap_init ( ) ;
if ( ! uwrap . enabled ) {
return getegid ( ) ;
}
return uwrap . egid ;
}
_PUBLIC_ int uwrap_setgroups ( size_t size , const gid_t * list )
{
uwrap_init ( ) ;
if ( ! uwrap . enabled ) {
return setgroups ( size , list ) ;
}
talloc_free ( uwrap . groups ) ;
2009-08-05 13:31:06 +10:00
uwrap . groups = NULL ;
if ( size ! = 0 ) {
2010-10-09 09:44:43 +02:00
uwrap . groups = talloc_array ( NULL , gid_t , size ) ;
2009-08-05 13:31:06 +10:00
if ( uwrap . groups = = NULL ) {
errno = ENOMEM ;
return - 1 ;
}
memcpy ( uwrap . groups , list , size * sizeof ( gid_t ) ) ;
2009-08-05 10:50:03 +10:00
}
return 0 ;
}
_PUBLIC_ int uwrap_getgroups ( int size , gid_t * list )
{
2011-02-19 23:21:07 +01:00
size_t ngroups ;
2009-08-05 10:50:03 +10:00
uwrap_init ( ) ;
if ( ! uwrap . enabled ) {
return getgroups ( size , list ) ;
}
2011-02-19 23:21:07 +01:00
ngroups = talloc_array_length ( uwrap . groups ) ;
if ( size > ngroups ) {
size = ngroups ;
2009-08-05 10:50:03 +10:00
}
if ( size = = 0 ) {
2011-02-19 23:21:07 +01:00
return ngroups ;
2009-08-05 10:50:03 +10:00
}
2011-02-19 23:21:07 +01:00
if ( size < ngroups ) {
2009-08-05 10:50:03 +10:00
errno = EINVAL ;
return - 1 ;
}
memcpy ( list , uwrap . groups , size * sizeof ( gid_t ) ) ;
2011-02-19 23:21:07 +01:00
return ngroups ;
2009-08-05 10:50:03 +10:00
}
_PUBLIC_ uid_t uwrap_getuid ( void )
{
uwrap_init ( ) ;
if ( ! uwrap . enabled ) {
return getuid ( ) ;
}
/* we don't simulate ruid changing */
return 0 ;
}
_PUBLIC_ gid_t uwrap_getgid ( void )
{
uwrap_init ( ) ;
if ( ! uwrap . enabled ) {
return getgid ( ) ;
}
/* we don't simulate rgid changing */
return 0 ;
}