summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2012-07-03 12:39:23 -0700
committerJeremy Allison <jra@samba.org>2012-07-03 15:34:22 -0700
commita559fcf156f4ee8c98daac52fcf3447993b9ba14 (patch)
tree00c7331860f3931648f37a7a17efa717a635ecf9
parented8525265dae72b7e910a371559db585a4ef55db (diff)
downloadsamba-a559fcf156f4ee8c98daac52fcf3447993b9ba14.tar.gz
samba-a559fcf156f4ee8c98daac52fcf3447993b9ba14.tar.bz2
samba-a559fcf156f4ee8c98daac52fcf3447993b9ba14.zip
Add function set_thread_credentials_permanently(). Panic if fail.
Not yet used.
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/lib/util_sec.c48
2 files changed, 52 insertions, 0 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 4080f23738..308283016c 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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 */
diff --git a/source3/lib/util_sec.c b/source3/lib/util_sec.c
index 11d85a102a..7c05f17de5 100644
--- a/source3/lib/util_sec.c
+++ b/source3/lib/util_sec.c
@@ -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
/****************************************************************************