Move back to using per-thread credentials on Linux. Fixes the glibc native AIO lost...
authorJeremy Allison <jra@samba.org>
Thu, 28 Jun 2012 20:41:19 +0000 (13:41 -0700)
committerJeremy Allison <jra@samba.org>
Fri, 29 Jun 2012 01:57:45 +0000 (03:57 +0200)
See this post:

https://lists.samba.org/archive/samba-technical/2012-June/085101.html

for details.

Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Fri Jun 29 03:57:45 CEST 2012 on sn-devel-104

lib/replace/libreplace.m4
lib/replace/wscript
lib/util/setid.c
source3/configure.in
source3/lib/util_sec.c
source3/wscript
tests/summary.c

index ad0f904..d298b92 100644 (file)
@@ -124,8 +124,10 @@ AC_CHECK_HEADERS(sys/mount.h mntent.h)
 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)
index 68138cf..157296b 100644 (file)
@@ -163,7 +163,7 @@ def configure(conf):
 
     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')
@@ -207,7 +207,7 @@ def configure(conf):
     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')
 
index 8b2efc0..66c0639 100644 (file)
@@ -70,10 +70,22 @@ int samba_setgroups(size_t setlen, const gid_t *gidset);
 
 #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;
@@ -83,7 +95,9 @@ int samba_setresuid(uid_t ruid, uid_t euid, uid_t suid)
 
 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;
@@ -93,7 +107,9 @@ int samba_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
 
 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;
@@ -103,7 +119,9 @@ int samba_setreuid(uid_t ruid, uid_t euid)
 
 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;
@@ -113,7 +131,10 @@ int samba_setregid(gid_t rgid, gid_t egid)
 
 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;
@@ -123,7 +144,10 @@ int samba_seteuid(uid_t euid)
 
 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;
@@ -133,7 +157,9 @@ int samba_setegid(gid_t egid)
 
 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;
@@ -143,7 +169,9 @@ int samba_setuid(uid_t uid)
 
 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;
@@ -156,6 +184,7 @@ int samba_setuidx(int flags, uid_t uid)
 #if defined(HAVE_SETUIDX)
        return setuidx(flags, uid);
 #else
+       /* USE_LINUX_THREAD_CREDENTIALS doesn't have this. */
        errno = ENOSYS;
        return -1;
 #endif
@@ -166,6 +195,7 @@ int samba_setgidx(int flags, gid_t gid)
 #if defined(HAVE_SETGIDX)
        return setgidx(flags, gid);
 #else
+       /* USE_LINUX_THREAD_CREDENTIALS doesn't have this. */
        errno = ENOSYS;
        return -1;
 #endif
@@ -173,7 +203,9 @@ int samba_setgidx(int flags, gid_t gid)
 
 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;
index 5df54cf..ba376f0 100644 (file)
@@ -953,7 +953,7 @@ AC_CHECK_FUNCS(setsid glob strpbrk crypt16 getauthuid)
 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)
@@ -2766,6 +2766,23 @@ AC_CHECK_FUNCS(getpagesize)
 # 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([
index bbb75db..cee11d9 100644 (file)
@@ -134,7 +134,7 @@ static void assert_gid(gid_t rgid, gid_t egid)
 ****************************************************************************/
 void gain_root_privilege(void)
 {      
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
        samba_setresuid(0,0,0);
 #endif
     
@@ -164,7 +164,7 @@ void gain_root_privilege(void)
 ****************************************************************************/
 void gain_root_group_privilege(void)
 {
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
        samba_setresgid(0,0,0);
 #endif
 
@@ -201,7 +201,7 @@ void gain_root_group_privilege(void)
 ****************************************************************************/
 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) {
@@ -233,7 +233,7 @@ void set_effective_uid(uid_t uid)
 ****************************************************************************/
 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
 
@@ -272,7 +272,7 @@ void save_re_uid(void)
 
 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);
@@ -311,7 +311,7 @@ void save_re_gid(void)
 ****************************************************************************/
 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);
@@ -339,7 +339,7 @@ int set_re_uid(void)
 {
        uid_t uid = geteuid();
 
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
        samba_setresuid(geteuid(), -1, -1);
 #endif
 
@@ -378,7 +378,7 @@ void become_user_permanently(uid_t uid, gid_t gid)
        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);
@@ -422,7 +422,7 @@ static int have_syscall(void)
 {
        errno = 0;
 
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(USE_LINUX_THREAD_CREDENTIALS)
        samba_setresuid(-1,-1,-1);
 #endif
 
index 5b21c3b..449bf20 100755 (executable)
@@ -80,7 +80,7 @@ def configure(conf):
     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')
@@ -729,6 +729,16 @@ int i; i = PAM_RADIO_TYPE;
             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
index a019fbf..bd0c162 100644 (file)
@@ -13,7 +13,7 @@ main()
        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