AC_CHECK_HEADERS(stropts.h)
AC_CHECK_HEADERS(unix.h)
AC_CHECK_HEADERS(malloc.h)
+AC_CHECK_HEADERS(syscall.h)
+AC_CHECK_HEADERS(sys/syscall.h)
-AC_CHECK_FUNCS(seteuid setreuid setresuid setegid setregid setresgid)
+AC_CHECK_FUNCS(syscall setuid seteuid setreuid setresuid setgid setegid setregid setresgid setgroups)
AC_CHECK_FUNCS(chroot bzero strerror strerror_r memalign posix_memalign getpagesize)
AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename)
AC_CHECK_FUNCS(waitpid wait4 strlcpy strlcat initgroups memmove strdup)
conf.CHECK_FUNCS('shl_load shl_unload shl_findsym')
conf.CHECK_FUNCS('pipe strftime srandom random srand rand usleep setbuffer')
- conf.CHECK_FUNCS('lstat getpgrp utime utimes seteuid setreuid setresuid setegid')
+ conf.CHECK_FUNCS('lstat getpgrp utime utimes setuid seteuid setreuid setresuid setgid setegid')
conf.CHECK_FUNCS('setregid setresgid chroot strerror vsyslog setlinebuf mktime')
conf.CHECK_FUNCS('ftruncate chsize rename waitpid wait4')
conf.CHECK_FUNCS('initgroups pread pwrite strndup strcasestr')
conf.CHECK_FUNCS('if_nametoindex strerror_r')
conf.CHECK_FUNCS('getdirentries getdents syslog')
conf.CHECK_FUNCS('gai_strerror get_current_dir_name')
- conf.CHECK_FUNCS('timegm getifaddrs freeifaddrs mmap setgroups setsid')
+ conf.CHECK_FUNCS('timegm getifaddrs freeifaddrs mmap setgroups syscall setsid')
conf.CHECK_FUNCS('getgrent_r getgrgid_r getgrnam_r getgrouplist getpagesize')
conf.CHECK_FUNCS('getpwent_r getpwnam_r getpwuid_r epoll_create')
#include "../lib/util/setid.h"
+#if defined(USE_LINUX_THREAD_CREDENTIALS)
+#if defined(HAVE_SYSCALL_H)
+#include <syscall.h>
+#endif
+
+#if defined(HAVE_SYS_SYSCALL_H)
+#include <sys/syscall.h>
+#endif
+#endif
+
/* All the setXX[ug]id functions and setgroups Samba uses. */
int samba_setresuid(uid_t ruid, uid_t euid, uid_t suid)
{
-#if defined(HAVE_SETRESUID)
+#if defined(USE_LINUX_THREAD_CREDENTIALS)
+ return syscall(SYS_setresuid, ruid, euid, suid);
+#elif defined(HAVE_SETRESUID)
return setresuid(ruid, euid, suid);
#else
errno = ENOSYS;
int samba_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
{
-#if defined(HAVE_SETRESGID)
+#if defined(USE_LINUX_THREAD_CREDENTIALS)
+ return syscall(SYS_setresgid, rgid, egid, sgid);
+#elif defined(HAVE_SETRESGID)
return setresgid(rgid, egid, sgid);
#else
errno = ENOSYS;
int samba_setreuid(uid_t ruid, uid_t euid)
{
-#if defined(HAVE_SETREUID)
+#if defined(USE_LINUX_THREAD_CREDENTIALS)
+ return syscall(SYS_setreuid, ruid, euid);
+#elif defined(HAVE_SETREUID)
return setreuid(ruid, euid);
#else
errno = ENOSYS;
int samba_setregid(gid_t rgid, gid_t egid)
{
-#if defined(HAVE_SETREGID)
+#if defined(USE_LINUX_THREAD_CREDENTIALS)
+ return syscall(SYS_setregid, rgid, egid);
+#elif defined(HAVE_SETREGID)
return setregid(rgid, egid);
#else
errno = ENOSYS;
int samba_seteuid(uid_t euid)
{
-#if defined(HAVE_SETEUID)
+#if defined(USE_LINUX_THREAD_CREDENTIALS)
+ /* seteuid is not a separate system call. */
+ return syscall(SYS_setresuid, -1, euid, -1);
+#elif defined(HAVE_SETEUID)
return seteuid(euid);
#else
errno = ENOSYS;
int samba_setegid(gid_t egid)
{
-#if defined(HAVE_SETEGID)
+#if defined(USE_LINUX_THREAD_CREDENTIALS)
+ /* setegid is not a separate system call. */
+ return syscall(SYS_setresgid, -1, egid, -1);
+#elif defined(HAVE_SETEGID)
return setegid(egid);
#else
errno = ENOSYS;
int samba_setuid(uid_t uid)
{
-#if defined(HAVE_SETUID)
+#if defined(USE_LINUX_THREAD_CREDENTIALS)
+ return syscall(SYS_setuid, uid);
+#elif defined(HAVE_SETUID)
return setuid(uid);
#else
errno = ENOSYS;
int samba_setgid(gid_t gid)
{
-#if defined(HAVE_SETGID)
+#if defined(USE_LINUX_THREAD_CREDENTIALS)
+ return syscall(SYS_setgid, gid);
+#elif defined(HAVE_SETGID)
return setgid(gid);
#else
errno = ENOSYS;
#if defined(HAVE_SETUIDX)
return setuidx(flags, uid);
#else
+ /* USE_LINUX_THREAD_CREDENTIALS doesn't have this. */
errno = ENOSYS;
return -1;
#endif
#if defined(HAVE_SETGIDX)
return setgidx(flags, gid);
#else
+ /* USE_LINUX_THREAD_CREDENTIALS doesn't have this. */
errno = ENOSYS;
return -1;
#endif
int samba_setgroups(size_t setlen, const gid_t *gidset)
{
-#if defined(HAVE_SETGROUPS)
+#if defined(USE_LINUX_THREAD_CREDENTIALS)
+ return syscall(SYS_setgroups, setlen, gidset);
+#elif defined(HAVE_SETGROUPS)
return setgroups(setlen, gidset);
#else
errno = ENOSYS;
AC_CHECK_FUNCS(sigprocmask sigblock sigaction sigset innetgr setnetgrent getnetgrent endnetgrent)
AC_CHECK_FUNCS(initgroups select rdchk getgrnam getgrent pathconf)
AC_CHECK_FUNCS(getgrset)
-AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf)
+AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups syscall sysconf)
AC_CHECK_FUNCS(atexit grantpt posix_fallocate)
AC_CHECK_FUNCS(fallocate)
AC_CHECK_FUNCS(fseeko setluid getpwanam)
# look for a method of setting the effective uid
seteuid=no;
+case "$host_os" in
+*linux*)
+if test $seteuid = no; then
+AC_CACHE_CHECK([for Linux thread-specific credentials],samba_cv_USE_LINUX_THREAD_CREDENTIALS,[
+AC_TRY_RUN([
+#define AUTOCONF_TEST 1
+#define USE_LINUX_THREAD_CREDENTIALS 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/util_sec.c"],
+ samba_cv_USE_LINUX_THREAD_CREDENTIALS=yes,samba_cv_USE_LINUX_THREAD_CREDENTIALS=no,samba_cv_USE_LINUX_THREAD_CREDENTIALS=cross)])
+if test x"$samba_cv_USE_LINUX_THREAD_CREDENTIALS" = x"yes"; then
+ seteuid=yes;AC_DEFINE(USE_SETREUID,1,[Whether we can use Linux thread-specific credentials])
+fi
+fi
+;;
+esac
+
if test $seteuid = no; then
AC_CACHE_CHECK([for setreuid],samba_cv_USE_SETREUID,[
AC_TRY_RUN([
****************************************************************************/
void gain_root_privilege(void)
{
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
samba_setresuid(0,0,0);
#endif
****************************************************************************/
void gain_root_group_privilege(void)
{
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
samba_setresgid(0,0,0);
#endif
****************************************************************************/
void set_effective_uid(uid_t uid)
{
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
/* Set the effective as well as the real uid. */
if (samba_setresuid(uid,uid,-1) == -1) {
if (errno == EAGAIN) {
****************************************************************************/
void set_effective_gid(gid_t gid)
{
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
samba_setresgid(-1,gid,-1);
#endif
void restore_re_uid_fromroot(void)
{
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
samba_setresuid(saved_ruid, saved_euid, -1);
#elif USE_SETREUID
samba_setreuid(saved_ruid, -1);
****************************************************************************/
void restore_re_gid(void)
{
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
samba_setresgid(saved_rgid, saved_egid, -1);
#elif USE_SETREUID
samba_setregid(saved_rgid, -1);
{
uid_t uid = geteuid();
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
samba_setresuid(geteuid(), -1, -1);
#endif
gain_root_privilege();
gain_root_group_privilege();
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
samba_setresgid(gid,gid,gid);
samba_setgid(gid);
samba_setresuid(uid,uid,uid);
{
errno = 0;
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
samba_setresuid(-1,-1,-1);
#endif
conf.CHECK_FUNCS('setsid glob strpbrk crypt16 getauthuid')
conf.CHECK_FUNCS('sigprocmask sigblock sigaction sigset innetgr')
conf.CHECK_FUNCS('initgroups select poll rdchk getgrnam getgrent pathconf')
- conf.CHECK_FUNCS('setpriv setgidx setuidx setgroups sysconf')
+ conf.CHECK_FUNCS('setpriv setgidx setuidx setgroups syscall sysconf')
conf.CHECK_FUNCS('atexit grantpt fallocate posix_fallocate')
conf.CHECK_FUNCS('fseeko setluid')
conf.CHECK_FUNCS('getpwnam', headers='sys/types.h pwd.h')
conf.DEFINE('WITH_PAM_MODULES', 1)
seteuid = False
+ if not seteuid:
+ seteuid = conf.CHECK_CODE('''
+ #define AUTOCONF_TEST 1
+ #define USE_LINUX_THREAD_CREDENTIALS 1
+ #include "./lib/util_sec.c"
+ ''',
+ 'USE_LINUX_THREAD_CREDENTIALS',
+ addmain=False,
+ execute=True,
+ msg="Checking whether we can use Linux thread-specific credentials")
if not seteuid:
seteuid = conf.CHECK_CODE('''
#define AUTOCONF_TEST 1
printf("WARNING: No automated network interface determination\n");
#endif
-#if !(defined(USE_SETEUID) || defined(USE_SETREUID) || defined(USE_SETRESUID) || defined(USE_SETUIDX))
+#if !(defined(USE_SETEUID) || defined(USE_SETREUID) || defined(USE_SETRESUID) || defined(USE_SETUIDX) || defined(USE_LINUX_THREAD_CREDENTIALS))
printf("ERROR: no seteuid method available\n");
exit(1);
#endif