From 4d12729aa4026229e4e118b924cc3b1c75ca214b Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Fri, 17 Jun 2016 20:09:33 -0400 Subject: write setuid, move things around --- bin/setuid.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 bin/setuid.c (limited to 'bin/setuid.c') diff --git a/bin/setuid.c b/bin/setuid.c new file mode 100644 index 0000000..7ae1105 --- /dev/null +++ b/bin/setuid.c @@ -0,0 +1,108 @@ +/* + Copyright (C) 2006 West Consulting + Copyright (C) 2006-2015 Arthur de Jong + Copyright (C) 2015-2016 Luke Shumaker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include /* for dlopen(3), dlsym(3), and dlerror(3) */ +#include /* for errno */ +#include /* for getpwnam(3) */ +#include /* for printf(3) and fprintf(3) */ +#include /* for strerror(3) */ +#include /* for 'struct passwd' and 'struct group' */ +#include /* for SD_{WARNING,DEBUG} */ +#include /* for setuid(3), setgid(3), and dup2(3) */ + +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 +#define EXIT_INVALIDARGUMENT 2 +#define EXIT_NOPERMISSION 4 + +const char *nss_module_soname = "libnss_ldap.so.2"; +const char *nss_module_sym_version = "_nss_ldap_version"; +const char *nss_module_sym_enablelookups = "_nss_ldap_enablelookups"; + +static void disable_nss_module(void) { + char *err; + + dlerror(); + void *handle = dlopen(nss_module_soname, RTLD_LAZY | RTLD_NODELETE); + err = dlerror(); + if (handle == NULL) { + fprintf(stderr, SD_WARNING "NSS module %s not loaded: %s", nss_module_soname, err); + return; + } + + dlerror(); + char **version_info = dlsym(handle, nss_module_sym_version); + err = dlerror(); + if ((version_info != NULL) && (err == NULL)) { + fprintf(stderr, SD_DEBUG "NSS module %s version %s %s", nss_module_soname, + version_info[0], + version_info[1]); + } else { + fprintf(stderr, SD_WARNING "NSS module %s version missing: %s", nss_module_soname, err); + } + + dlerror(); + int *enable_flag = dlsym(handle, nss_module_sym_enablelookups); + err = dlerror(); + if ((enable_flag == NULL) || (err != NULL)) { + fprintf(stderr, SD_WARNING "Unable to disable NSS ldap module for nslcd process: %s", err); + dlclose(handle); + return; + } + *enable_flag = 0; + dlclose(handle); +} + +void usage(char *cmd) { + printf("Usage: %s USERNAME COMMAND...\n", cmd); + printf("A simple setuid(3) wrapper that runs with the `ldap' NSS module disabled\n"); +} + +int main(int argc, char *argv[]) { + if (argc < 3) { + dup2(2, 1); + usage(argv[0]); + return EXIT_INVALIDARGUMENT; + } + + disable_nss_module(); + + struct passwd *passwd = getpwnam(argv[1]); + if (passwd == NULL) { + fprintf(stderr, SD_ERR "Could not look up user: %s", argv[1]); + return EXIT_FAILURE; + } + + if (setgid(passwd->pw_gid) != 0) { + fprintf(stderr, SD_ERR "Could not setgid(%lu): %s", + (unsigned long int)passwd->pw_gid, strerror(errno)); + return EXIT_NOPERMISSION; + } + if (setuid(passwd->pw_uid) != 0) { + fprintf(stderr, SD_ERR "Could not setuid(%lu): %s", + (unsigned long int)passwd->pw_gid, strerror(errno)); + return EXIT_NOPERMISSION; + } + + execvp(argv[2], &argv[2]); + fprintf(stderr, SD_ERR "Could not exec: %s", strerror(errno)); + return EXIT_FAILURE; +} -- cgit v1.2.3-54-g00ecf