Add function set_thread_credentials_permanently(). Panic if fail.
authorJeremy Allison <jra@samba.org>
Tue, 3 Jul 2012 19:39:23 +0000 (12:39 -0700)
committerJeremy Allison <jra@samba.org>
Tue, 3 Jul 2012 22:34:22 +0000 (15:34 -0700)
Not yet used.

source3/include/proto.h
source3/lib/util_sec.c

index 4080f2373846e9149a3fa8b85a3d1bc62dc9a1b3..308283016c50aed92487e0fc634d27fac34761b8 100644 (file)
@@ -544,6 +544,10 @@ void save_re_gid(void);
 void restore_re_gid(void);
 int set_re_uid(void);
 void become_user_permanently(uid_t uid, gid_t gid);
+int set_thread_credentials_permanently(uid_t uid,
+                               gid_t gid,
+                               size_t setlen,
+                               const gid_t *gidset);
 bool is_setuid_root(void) ;
 
 /* The following definitions come from lib/util_sid.c  */
index 11d85a102a554687f733311395e61e7c7c98408f..7c05f17de571a0a8342fb1725a4410595772a01a 100644 (file)
@@ -410,6 +410,54 @@ void become_user_permanently(uid_t uid, gid_t gid)
        assert_gid(gid, gid);
 }
 
+/**********************************************************
+ Function to set thread specific credentials in an
+ irreversible way. Must be thread-safe code.
+**********************************************************/
+
+int set_thread_credentials_permanently(uid_t uid,
+                               gid_t gid,
+                               size_t setlen,
+                               const gid_t *gidset)
+{
+#if defined(USE_LINUX_THREAD_CREDENTIALS)
+       /*
+        * With Linux thread-specific credentials
+        * we know we have setresuid/setresgid
+        * available.
+        */
+
+       /* 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, sg=gid */
+       if (samba_setresgid(gid, gid, gid) != 0) {
+               return -1;
+       }
+       /* Set extra groups list. */
+       if (samba_setgroups(setlen, gidset) != 0) {
+               return -1;
+       }
+       /* Become the requested user. No way back after this. */
+       /* Set ru=uid, eu=uid, su=uid */
+       if (samba_setresuid(uid, uid, uid) != 0) {
+               return -1;
+       }
+       if (geteuid() != uid || getuid() != uid ||
+                       getegid() != gid || getgid() != gid) {
+               smb_panic("set_thread_credentials_permanently failed\n");
+               return -1;
+       }
+       return 0;
+#else
+       errno = ENOSYS;
+       return -1;
+#endif
+}
+
 #ifdef AUTOCONF_TEST
 
 /****************************************************************************