summaryrefslogtreecommitdiffstats
path: root/lib/prefix_flag.c
diff options
context:
space:
mode:
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;
}