diff options
Diffstat (limited to '')
-rw-r--r-- | lib/prefix_flag.c (renamed from libmisc/prefix_flag.c) | 102 |
1 files changed, 61 insertions, 41 deletions
diff --git a/libmisc/prefix_flag.c b/lib/prefix_flag.c index 4eb5154..bba7102 100644 --- a/libmisc/prefix_flag.c +++ b/lib/prefix_flag.c @@ -11,7 +11,9 @@ #include <stdio.h> #include <assert.h> + #include "defines.h" +#include "alloc.h" #include "prototypes.h" /*@-exitarg@*/ #include "exitcodes.h" @@ -26,6 +28,8 @@ #endif /* ENABLE_SUBIDS */ #include "getdef.h" #include "shadowlog.h" +#include "string/sprintf.h" + static char *passwd_db_file = NULL; static char *spw_db_file = NULL; @@ -83,6 +87,15 @@ extern const char* process_prefix_flag (const char* short_opt, int argc, char ** if (prefix != NULL) { + /* Drop privileges */ + if ( (setregid (getgid (), getgid ()) != 0) + || (setreuid (getuid (), getuid ()) != 0)) { + fprintf (log_get_logfd(), + _("%s: failed to drop privileges (%s)\n"), + log_get_progname(), strerror (errno)); + exit (EXIT_FAILURE); + } + if ( prefix[0] == '\0' || !strcmp(prefix, "/")) return ""; /* if prefix is "/" then we ignore the flag option */ /* should we prevent symbolic link from being used as a prefix? */ @@ -93,50 +106,33 @@ extern const char* process_prefix_flag (const char* short_opt, int argc, char ** log_get_progname()); exit (E_BAD_ARG); } - size_t len; - len = strlen(prefix) + strlen(PASSWD_FILE) + 2; - passwd_db_file = xmalloc(len); - snprintf(passwd_db_file, len, "%s/%s", prefix, PASSWD_FILE); + + xasprintf(&passwd_db_file, "%s/%s", prefix, PASSWD_FILE); pw_setdbname(passwd_db_file); - len = strlen(prefix) + strlen(GROUP_FILE) + 2; - group_db_file = xmalloc(len); - snprintf(group_db_file, len, "%s/%s", prefix, GROUP_FILE); + xasprintf(&group_db_file, "%s/%s", prefix, GROUP_FILE); gr_setdbname(group_db_file); #ifdef SHADOWGRP - len = strlen(prefix) + strlen(SGROUP_FILE) + 2; - sgroup_db_file = xmalloc(len); - snprintf(sgroup_db_file, len, "%s/%s", prefix, SGROUP_FILE); + xasprintf(&sgroup_db_file, "%s/%s", prefix, SGROUP_FILE); sgr_setdbname(sgroup_db_file); #endif -#ifdef USE_NIS - __setspNIS(0); /* disable NIS for now, at least until it is properly supporting a "prefix" */ -#endif - len = strlen(prefix) + strlen(SHADOW_FILE) + 2; - spw_db_file = xmalloc(len); - snprintf(spw_db_file, len, "%s/%s", prefix, SHADOW_FILE); + xasprintf(&spw_db_file, "%s/%s", prefix, SHADOW_FILE); spw_setdbname(spw_db_file); #ifdef ENABLE_SUBIDS - len = strlen(prefix) + strlen("/etc/subuid") + 2; - suid_db_file = xmalloc(len); - snprintf(suid_db_file, len, "%s/%s", prefix, "/etc/subuid"); + xasprintf(&suid_db_file, "%s/%s", prefix, SUBUID_FILE); sub_uid_setdbname(suid_db_file); - len = strlen(prefix) + strlen("/etc/subgid") + 2; - sgid_db_file = xmalloc(len); - snprintf(sgid_db_file, len, "%s/%s", prefix, "/etc/subgid"); + xasprintf(&sgid_db_file, "%s/%s", prefix, SUBGID_FILE); sub_gid_setdbname(sgid_db_file); #endif #ifdef USE_ECONF setdef_config_file(prefix); #else - len = strlen(prefix) + strlen("/etc/login.defs") + 2; - def_conf_file = xmalloc(len); - snprintf(def_conf_file, len, "%s/%s", prefix, "/etc/login.defs"); + xasprintf(&def_conf_file, "%s/%s", prefix, "/etc/login.defs"); setdef_config_file(def_conf_file); #endif } @@ -227,6 +223,29 @@ extern struct passwd *prefix_getpwnam(const char* name) return getpwnam(name); } } +#if HAVE_FGETPWENT_R +extern int prefix_getpwnam_r(const char* name, struct passwd* pwd, + char* buf, size_t buflen, struct passwd** result) +{ + if (passwd_db_file) { + FILE* fg; + int ret = 0; + + fg = fopen(passwd_db_file, "rt"); + if (!fg) + return errno; + while ((ret = fgetpwent_r(fg, pwd, buf, buflen, result)) == 0) { + if (!strcmp(name, pwd->pw_name)) + break; + } + fclose(fg); + return ret; + } + else { + return getpwnam_r(name, pwd, buf, buflen, result); + } +} +#endif extern struct spwd *prefix_getspnam(const char* name) { if (spw_db_file) { @@ -315,26 +334,27 @@ extern void prefix_endgrent(void) extern struct group *prefix_getgr_nam_gid(const char *grname) { - long long int gid; - char *endptr; - struct group *g; + char *end; + long long gid; + struct group *g; if (NULL == grname) { return NULL; } - if (group_db_file) { - errno = 0; - gid = strtoll (grname, &endptr, 10); - if ( ('\0' != *grname) - && ('\0' == *endptr) - && (ERANGE != errno) - && (gid == (gid_t)gid)) { - return prefix_getgrgid ((gid_t) gid); - } - g = prefix_getgrnam (grname); - return g ? __gr_dup(g) : NULL; - } - else + if (!group_db_file) return getgr_nam_gid(grname); + + errno = 0; + gid = strtoll(grname, &end, 10); + if ( ('\0' != *grname) + && ('\0' == *end) + && (0 == errno) + && (gid == (gid_t)gid)) + { + return prefix_getgrgid(gid); + } + + g = prefix_getgrnam(grname); + return g ? __gr_dup(g) : NULL; } |