#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,
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;
}
}
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?
****************************************************************************/
****************************************************************************/
void gain_root_privilege(void)
{
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(HAVE_LINUX_THREAD_CREDENTIALS)
samba_setresuid(0,0,0);
#endif
****************************************************************************/
void gain_root_group_privilege(void)
{
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(HAVE_LINUX_THREAD_CREDENTIALS)
samba_setresgid(0,0,0);
#endif
****************************************************************************/
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) {
****************************************************************************/
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
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);
****************************************************************************/
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);
{
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
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);
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
/****************************************************************************
{
errno = 0;
-#if USE_SETRESUID
+#if defined(USE_SETRESUID) || defined(HAVE_LINUX_THREAD_CREDENTIALS)
samba_setresuid(-1,-1,-1);
#endif
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))