pyldb: avoid segfault when adding an element with no name
[kamenim/samba-autobuild/.git] / source3 / lib / util_sec.c
index bbb75dbbd4a2438285f41b1fa89730fafd4e7d11..974e458b06ed5d705bff6d7bc91bba0d7f08cfd8 100644 (file)
@@ -28,6 +28,7 @@
 #if defined(HAVE_UNISTD_H)
 #include <unistd.h>
 #endif
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/id.h>
 #endif
 
-/* In autoconf/test mode include the definitions of samba_setXXX. */
-#include "../lib/util/setid.c"
-
 #define DEBUG(x, y) printf y
 #define smb_panic(x) exit(1)
-#define bool int
 #endif
 
 /* are we running as non-root? This is used by the regresison test code,
@@ -63,8 +60,22 @@ void sec_init(void)
        static int initialized;
 
        if (!initialized) {
+
+#ifndef AUTOCONF_TEST
+               if (uid_wrapper_enabled()) {
+                       setenv("UID_WRAPPER_MYUID", "1", 1);
+               }
+#endif
+
                initial_uid = geteuid();
                initial_gid = getegid();
+
+#ifndef AUTOCONF_TEST
+               if (uid_wrapper_enabled()) {
+                       unsetenv("UID_WRAPPER_MYUID");
+               }
+#endif
+
                initialized = 1;
        }
 }
@@ -85,6 +96,26 @@ gid_t sec_initial_gid(void)
        return initial_gid;
 }
 
+/**
+ * @brief Check if we are running in root mode.
+ *
+ * @return If we samba root privileges it returns true, false otehrwise.
+ */
+bool root_mode(void)
+{
+       uid_t euid;
+
+       euid = geteuid();
+
+#ifndef AUTOCONF_TEST
+       if (uid_wrapper_enabled()) {
+               return (euid == initial_uid || euid == (uid_t)0);
+       }
+#endif
+
+       return (initial_uid == euid);
+}
+
 /****************************************************************************
 are we running in non-root mode?
 ****************************************************************************/
@@ -134,7 +165,7 @@ static void assert_gid(gid_t rgid, gid_t egid)
 ****************************************************************************/
 void gain_root_privilege(void)
 {      
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(HAVE_LINUX_THREAD_CREDENTIALS)
        samba_setresuid(0,0,0);
 #endif
     
@@ -164,7 +195,7 @@ void gain_root_privilege(void)
 ****************************************************************************/
 void gain_root_group_privilege(void)
 {
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(HAVE_LINUX_THREAD_CREDENTIALS)
        samba_setresgid(0,0,0);
 #endif
 
@@ -201,7 +232,7 @@ void gain_root_group_privilege(void)
 ****************************************************************************/
 void set_effective_uid(uid_t uid)
 {
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(HAVE_LINUX_THREAD_CREDENTIALS)
         /* Set the effective as well as the real uid. */
        if (samba_setresuid(uid,uid,-1) == -1) {
                if (errno == EAGAIN) {
@@ -233,7 +264,7 @@ void set_effective_uid(uid_t uid)
 ****************************************************************************/
 void set_effective_gid(gid_t gid)
 {
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(HAVE_LINUX_THREAD_CREDENTIALS)
        samba_setresgid(-1,gid,-1);
 #endif
 
@@ -272,7 +303,7 @@ void save_re_uid(void)
 
 void restore_re_uid_fromroot(void)
 {
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(HAVE_LINUX_THREAD_CREDENTIALS)
        samba_setresuid(saved_ruid, saved_euid, -1);
 #elif USE_SETREUID
        samba_setreuid(saved_ruid, -1);
@@ -311,7 +342,7 @@ void save_re_gid(void)
 ****************************************************************************/
 void restore_re_gid(void)
 {
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(HAVE_LINUX_THREAD_CREDENTIALS)
        samba_setresgid(saved_rgid, saved_egid, -1);
 #elif USE_SETREUID
        samba_setregid(saved_rgid, -1);
@@ -339,8 +370,8 @@ int set_re_uid(void)
 {
        uid_t uid = geteuid();
 
-#if USE_SETRESUID
-       samba_setresuid(geteuid(), -1, -1);
+#if defined(USE_SETRESUID) || defined(HAVE_LINUX_THREAD_CREDENTIALS)
+       samba_setresuid(uid, uid, -1);
 #endif
 
 #if USE_SETREUID
@@ -378,7 +409,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(HAVE_LINUX_THREAD_CREDENTIALS)
        samba_setresgid(gid,gid,gid);
        samba_setgid(gid);
        samba_setresuid(uid,uid,uid);
@@ -413,6 +444,81 @@ void become_user_permanently(uid_t uid, gid_t gid)
        assert_gid(gid, gid);
 }
 
+/**********************************************************
+ Function to set thread specific credentials. Leave
+ saved-set uid/gid alone.Must be thread-safe code.
+**********************************************************/
+
+int set_thread_credentials(uid_t uid,
+                       gid_t gid,
+                       size_t setlen,
+                       const gid_t *gidset)
+{
+#if defined(HAVE_LINUX_THREAD_CREDENTIALS)
+       /*
+        * With Linux thread-specific credentials
+        * we know we have setresuid/setresgid
+        * available.
+        */
+#ifdef HAVE___THREAD
+       static struct {
+               bool active;
+               uid_t uid;
+               gid_t gid;
+               size_t setlen;
+               uintptr_t gidset;
+       } __thread cache;
+
+       if (cache.active &&
+           cache.uid == uid &&
+           cache.gid == gid &&
+           cache.setlen == setlen &&
+           (const gid_t *)cache.gidset == gidset)
+       {
+               return 0;
+       }
+#endif /* HAVE___THREAD */
+
+       /* Become root. */
+       /* Set ru=0, eu=0 */
+       if (samba_setresuid(0, 0, -1) != 0) {
+               return -1;
+       }
+       /* Set our primary gid. */
+       /* Set rg=gid, eg=gid */
+       if (samba_setresgid(gid, gid, -1) != 0) {
+               return -1;
+       }
+       /* Set extra groups list. */
+       if (samba_setgroups(setlen, gidset) != 0) {
+               return -1;
+       }
+       /* Become the requested user. */
+       /* Set ru=uid, eu=uid */
+       if (samba_setresuid(uid, uid, -1) != 0) {
+               return -1;
+       }
+       if (geteuid() != uid || getuid() != uid ||
+                       getegid() != gid || getgid() != gid) {
+               smb_panic("set_thread_credentials failed\n");
+               return -1;
+       }
+
+#ifdef HAVE___THREAD
+       cache.active = true;
+       cache.uid = uid;
+       cache.gid = gid;
+       cache.setlen = setlen;
+       cache.gidset = (uintptr_t)gidset;
+#endif /* HAVE___THREAD */
+
+       return 0;
+#else
+       errno = ENOSYS;
+       return -1;
+#endif
+}
+
 #ifdef AUTOCONF_TEST
 
 /****************************************************************************
@@ -422,7 +528,7 @@ static int have_syscall(void)
 {
        errno = 0;
 
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(HAVE_LINUX_THREAD_CREDENTIALS)
        samba_setresuid(-1,-1,-1);
 #endif
 
@@ -438,12 +544,13 @@ static int have_syscall(void)
        samba_setuidx(ID_EFFECTIVE, -1);
 #endif
 
-       if (errno == ENOSYS) return -1;
-       
+       if (errno == ENOSYS) {
+               return -1;
+       }
        return 0;
 }
 
-main()
+int main(void)
 {
         if (getuid() != 0) {
 #if (defined(AIX) && defined(USE_SETREUID))