diff options
-rw-r--r-- | lib/uid_wrapper/config.m4 | 16 | ||||
-rw-r--r-- | lib/uid_wrapper/config.mk | 9 | ||||
-rw-r--r-- | lib/uid_wrapper/uid_wrapper.c | 147 | ||||
-rw-r--r-- | lib/uid_wrapper/uid_wrapper.h | 61 | ||||
-rw-r--r-- | lib/util/config.mk | 1 | ||||
-rw-r--r-- | lib/util/util.c | 2 | ||||
-rw-r--r-- | nsswitch/config.mk | 3 | ||||
-rw-r--r-- | selftest/target/Samba4.pm | 5 | ||||
-rw-r--r-- | source4/Makefile | 1 | ||||
-rw-r--r-- | source4/auth/ntlm/config.mk | 2 | ||||
-rw-r--r-- | source4/configure.ac | 1 | ||||
-rw-r--r-- | source4/heimdal_build/config.h | 5 | ||||
-rw-r--r-- | source4/heimdal_build/internal.mk | 3 | ||||
-rw-r--r-- | source4/include/includes.h | 5 | ||||
-rw-r--r-- | source4/main.mk | 1 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_acl.c | 8 | ||||
-rw-r--r-- | source4/ntvfs/unixuid/config.mk | 2 |
17 files changed, 265 insertions, 7 deletions
diff --git a/lib/uid_wrapper/config.m4 b/lib/uid_wrapper/config.m4 new file mode 100644 index 0000000000..db6537bf95 --- /dev/null +++ b/lib/uid_wrapper/config.m4 @@ -0,0 +1,16 @@ +AC_ARG_ENABLE(uid-wrapper, +AS_HELP_STRING([--enable-uid-wrapper], [Turn on uid wrapper library (default=no)])) + +HAVE_UID_WRAPPER=no + +if eval "test x$developer = xyes"; then + enable_uid_wrapper=yes +fi + +if eval "test x$enable_uid_wrapper = xyes"; then + AC_DEFINE(UID_WRAPPER,1,[Use uid wrapper library]) + HAVE_UID_WRAPPER=yes +fi + +AC_SUBST(HAVE_UID_WRAPPER) +AC_SUBST(UID_WRAPPER_OBJS) diff --git a/lib/uid_wrapper/config.mk b/lib/uid_wrapper/config.mk new file mode 100644 index 0000000000..1bebc68118 --- /dev/null +++ b/lib/uid_wrapper/config.mk @@ -0,0 +1,9 @@ +############################## +# Start SUBSYSTEM UID_WRAPPER +[SUBSYSTEM::UID_WRAPPER] +PRIVATE_DEPENDENCIES = LIBTALLOC +# End SUBSYSTEM UID_WRAPPER +############################## + +UID_WRAPPER_OBJ_FILES = $(uidwrappersrcdir)/uid_wrapper.o + diff --git a/lib/uid_wrapper/uid_wrapper.c b/lib/uid_wrapper/uid_wrapper.c new file mode 100644 index 0000000000..e009fa0b5c --- /dev/null +++ b/lib/uid_wrapper/uid_wrapper.c @@ -0,0 +1,147 @@ +/* + Copyright (C) Andrew Tridgell 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#define UID_WRAPPER_NOT_REPLACE +#include "includes.h" +#include "system/passwd.h" +#include "system/filesys.h" + +#ifndef _PUBLIC_ +#define _PUBLIC_ +#endif + +/* + we keep the virtualised euid/egid/groups information here + */ +static struct { + bool initialised; + bool enabled; + uid_t euid; + gid_t egid; + unsigned ngroups; + gid_t *groups; +} uwrap; + +static void uwrap_init(void) +{ + if (uwrap.initialised) return; + uwrap.initialised = true; + if (getenv("UID_WRAPPER")) { + uwrap.enabled = true; + } +} + +_PUBLIC_ int uwrap_seteuid(uid_t euid) +{ + uwrap_init(); + if (!uwrap.enabled) { + return seteuid(euid); + } + /* assume for now that the ruid stays as root */ + uwrap.euid = euid; + return 0; +} + +_PUBLIC_ uid_t uwrap_geteuid(void) +{ + uwrap_init(); + if (!uwrap.enabled) { + return geteuid(); + } + return uwrap.euid; +} + +_PUBLIC_ int uwrap_setegid(gid_t egid) +{ + uwrap_init(); + if (!uwrap.enabled) { + return setegid(egid); + } + /* assume for now that the ruid stays as root */ + uwrap.egid = egid; + return 0; +} + +_PUBLIC_ uid_t uwrap_getegid(void) +{ + uwrap_init(); + if (!uwrap.enabled) { + return getegid(); + } + return uwrap.egid; +} + +_PUBLIC_ int uwrap_setgroups(size_t size, const gid_t *list) +{ + uwrap_init(); + if (!uwrap.enabled) { + return setgroups(size, list); + } + + talloc_free(uwrap.groups); + uwrap.ngroups = 0; + + uwrap.groups = talloc_array(talloc_autofree_context(), gid_t, size); + if (uwrap.groups == NULL) { + errno = ENOMEM; + return -1; + } + memcpy(uwrap.groups, list, size*sizeof(gid_t)); + uwrap.ngroups = size; + return 0; +} + +_PUBLIC_ int uwrap_getgroups(int size, gid_t *list) +{ + uwrap_init(); + if (!uwrap.enabled) { + return getgroups(size, list); + } + + if (size > uwrap.ngroups) { + size = uwrap.ngroups; + } + if (size == 0) { + return uwrap.ngroups; + } + if (size < uwrap.ngroups) { + errno = EINVAL; + return -1; + } + memcpy(list, uwrap.groups, size*sizeof(gid_t)); + return 0; +} + +_PUBLIC_ uid_t uwrap_getuid(void) +{ + uwrap_init(); + if (!uwrap.enabled) { + return getuid(); + } + /* we don't simulate ruid changing */ + return 0; +} + +_PUBLIC_ gid_t uwrap_getgid(void) +{ + uwrap_init(); + if (!uwrap.enabled) { + return getgid(); + } + /* we don't simulate rgid changing */ + return 0; +} diff --git a/lib/uid_wrapper/uid_wrapper.h b/lib/uid_wrapper/uid_wrapper.h new file mode 100644 index 0000000000..e2df613f50 --- /dev/null +++ b/lib/uid_wrapper/uid_wrapper.h @@ -0,0 +1,61 @@ +/* + Copyright (C) Andrew Tridgell 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __UID_WRAPPER_H__ +#define __UID_WRAPPER_H__ + +#ifdef seteuid +#undef seteuid +#endif +#define seteuid uwrap_seteuid + +#ifdef setegid +#undef setegid +#endif +#define setegid uwrap_setegid + +#ifdef geteuid +#undef geteuid +#endif +#define geteuid uwrap_geteuid + +#ifdef getegid +#undef getegid +#endif +#define getegid uwrap_getegid + +#ifdef setgroups +#undef setgroups +#endif +#define setgroups uwrap_setgroups + +#ifdef getgroups +#undef getgroups +#endif +#define getgroups uwrap_getgroups + +#ifdef getuid +#undef getuid +#endif +#define getuid uwrap_getuid + +#ifdef getgid +#undef getgid +#endif +#define getgid uwrap_getgid + +#endif /* __UID_WRAPPER_H__ */ diff --git a/lib/util/config.mk b/lib/util/config.mk index ad39096c56..47e026865e 100644 --- a/lib/util/config.mk +++ b/lib/util/config.mk @@ -54,6 +54,7 @@ PUBLIC_HEADERS += $(addprefix $(libutilsrcdir)/, util.h \ ASN1_UTIL_OBJ_FILES = $(libutilsrcdir)/asn1.o [SUBSYSTEM::UNIX_PRIVS] +PRIVATE_DEPENDENCIES = UID_WRAPPER UNIX_PRIVS_OBJ_FILES = $(libutilsrcdir)/unix_privs.o diff --git a/lib/util/util.c b/lib/util/util.c index f49d25865c..dea140148f 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -135,10 +135,12 @@ _PUBLIC_ bool directory_create_or_exist(const char *dname, uid_t uid, } if ((st.st_uid != uid) || ((st.st_mode & 0777) != dir_perms)) { +#ifndef UID_WRAPPER_REPLACE DEBUG(0, ("invalid permissions on directory " "%s\n", dname)); umask(old_umask); return false; +#endif } } return true; diff --git a/nsswitch/config.mk b/nsswitch/config.mk index 264032e530..9a04f3bc37 100644 --- a/nsswitch/config.mk +++ b/nsswitch/config.mk @@ -30,7 +30,8 @@ PRIVATE_DEPENDENCIES = \ LIBWBCLIENT \ LIBTEVENT \ UTIL_TEVENT \ - LIBASYNC_REQ + LIBASYNC_REQ \ + UID_WRAPPER # End BINARY nsstest ################################# diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index d2c11e4f32..db5900d0ae 100644 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -113,6 +113,8 @@ sub check_or_start($$$) $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD}; $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP}; + $ENV{UID_WRAPPER} = "1"; + # Start slapd before samba, but with the fifo on stdin if (defined($self->{ldap})) { $self->slapd_start($env_vars) or @@ -773,7 +775,6 @@ sub provision($$$$$$$) [tmp] path = $ctx->{tmpdir} read only = no - ntvfs handler = posix posix:sharedelay = 100000 posix:eadb = $ctx->{lockdir}/eadb.tdb posix:oplocktimeout = 3 @@ -782,7 +783,6 @@ sub provision($$$$$$$) [test1] path = $ctx->{tmpdir}/test1 read only = no - ntvfs handler = posix posix:sharedelay = 100000 posix:eadb = $ctx->{lockdir}/eadb.tdb posix:oplocktimeout = 3 @@ -791,7 +791,6 @@ sub provision($$$$$$$) [test2] path = $ctx->{tmpdir}/test2 read only = no - ntvfs handler = posix posix:sharedelay = 100000 posix:eadb = $ctx->{lockdir}/eadb.tdb posix:oplocktimeout = 3 diff --git a/source4/Makefile b/source4/Makefile index d6ae887066..24e58bc37a 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -75,6 +75,7 @@ libcmdlinesrcdir := lib/cmdline poptsrcdir := ../lib/popt socketwrappersrcdir := ../lib/socket_wrapper nsswrappersrcdir := ../lib/nss_wrapper +uidwrappersrcdir := ../lib/uid_wrapper appwebsrcdir := lib/appweb libstreamsrcdir := lib/stream libutilsrcdir := ../lib/util diff --git a/source4/auth/ntlm/config.mk b/source4/auth/ntlm/config.mk index 561d14ad10..cb9c3b6cc9 100644 --- a/source4/auth/ntlm/config.mk +++ b/source4/auth/ntlm/config.mk @@ -57,7 +57,7 @@ auth_developer_OBJ_FILES = $(addprefix $(authsrcdir)/ntlm/, auth_developer.o) [MODULE::auth_unix] INIT_FUNCTION = auth_unix_init SUBSYSTEM = auth -PRIVATE_DEPENDENCIES = CRYPT PAM PAM_ERRORS NSS_WRAPPER +PRIVATE_DEPENDENCIES = CRYPT PAM PAM_ERRORS NSS_WRAPPER UID_WRAPPER auth_unix_OBJ_FILES = $(addprefix $(authsrcdir)/ntlm/, auth_unix.o) diff --git a/source4/configure.ac b/source4/configure.ac index 7c5f310aa9..3f10419a42 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -125,6 +125,7 @@ m4_include(ntvfs/posix/config.m4) m4_include(ntvfs/unixuid/config.m4) m4_include(../lib/socket_wrapper/config.m4) m4_include(../lib/nss_wrapper/config.m4) +m4_include(../lib/uid_wrapper/config.m4) m4_include(auth/config.m4) m4_include(kdc/config.m4) m4_include(ntvfs/sysdep/config.m4) diff --git a/source4/heimdal_build/config.h b/source4/heimdal_build/config.h index 6a82637b2d..8830942e30 100644 --- a/source4/heimdal_build/config.h +++ b/source4/heimdal_build/config.h @@ -27,4 +27,9 @@ #undef HAVE_KRB5_ENCRYPT_BLOCK +#if defined(UID_WRAPPER) && !defined(UID_WRAPPER_REPLACE) && !defined(UID_WRAPPER_NOT_REPLACE) +#define UID_WRAPPER_REPLACE +#include "../uid_wrapper/uid_wrapper.h" +#endif + #endif diff --git a/source4/heimdal_build/internal.mk b/source4/heimdal_build/internal.mk index c0f3b6be99..52281807b5 100644 --- a/source4/heimdal_build/internal.mk +++ b/source4/heimdal_build/internal.mk @@ -598,7 +598,8 @@ PRIVATE_DEPENDENCIES = \ HEIMDAL_ROKEN_PROGNAME \ HEIMDAL_ROKEN_CLOSEFROM \ RESOLV \ - LIBREPLACE_NETWORK + LIBREPLACE_NETWORK \ + UID_WRAPPER # End SUBSYSTEM HEIMDAL_ROKEN ####################### diff --git a/source4/include/includes.h b/source4/include/includes.h index 4862a62e22..37c6115f0f 100644 --- a/source4/include/includes.h +++ b/source4/include/includes.h @@ -73,4 +73,9 @@ #define TALLOC_ABORT(reason) smb_panic(reason) #endif +#if defined(UID_WRAPPER) && !defined(UID_WRAPPER_REPLACE) && !defined(UID_WRAPPER_NOT_REPLACE) +#define UID_WRAPPER_REPLACE +#include "../uid_wrapper/uid_wrapper.h" +#endif + #endif /* _INCLUDES_H */ diff --git a/source4/main.mk b/source4/main.mk index b4a82017c8..4d7fd584f8 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -19,6 +19,7 @@ mkinclude lib/events/config.mk mkinclude lib/cmdline/config.mk mkinclude ../lib/socket_wrapper/config.mk mkinclude ../lib/nss_wrapper/config.mk +mkinclude ../lib/uid_wrapper/config.mk mkinclude lib/stream/config.mk mkinclude ../lib/util/config.mk mkinclude ../lib/tdr/config.mk diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 1adced44aa..f5a00c08a8 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -473,6 +473,14 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, max_bits |= SEC_STD_ALL; } +#ifdef UID_WRAPPER_REPLACE + /* when running with the uid wrapper, files will be created + owned by the ruid, but we may have a different simulated + euid. We need to force the permission bits as though the + files owner matches the euid */ + max_bits |= SEC_STD_ALL; +#endif + if (*access_mask == SEC_FLAG_MAXIMUM_ALLOWED) { *access_mask = max_bits; return NT_STATUS_OK; diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index 6377657cec..105ba2f535 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -3,7 +3,7 @@ [MODULE::ntvfs_unixuid] INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = ntvfs -PRIVATE_DEPENDENCIES = SAMDB NSS_WRAPPER +PRIVATE_DEPENDENCIES = SAMDB NSS_WRAPPER UID_WRAPPER # End MODULE ntvfs_unixuid ################################################ |