diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 14:54:37 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 14:54:37 +0000 |
commit | 97c26c1924b076ef23ebe4381558e8aa025712b2 (patch) | |
tree | 109724175f07436696f51b14b5abbd3f4d704d6d /libmisc/prefix_flag.c | |
parent | Initial commit. (diff) | |
download | shadow-97c26c1924b076ef23ebe4381558e8aa025712b2.tar.xz shadow-97c26c1924b076ef23ebe4381558e8aa025712b2.zip |
Adding upstream version 1:4.13+dfsg1.upstream/1%4.13+dfsg1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libmisc/prefix_flag.c')
-rw-r--r-- | libmisc/prefix_flag.c | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/libmisc/prefix_flag.c b/libmisc/prefix_flag.c new file mode 100644 index 0000000..4eb5154 --- /dev/null +++ b/libmisc/prefix_flag.c @@ -0,0 +1,340 @@ +/* + * SPDX-FileCopyrightText: 2011 , Julian Pidancet + * SPDX-FileCopyrightText: 2011 , Nicolas François + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <config.h> + +#ident "$Id$" + +#include <stdio.h> +#include <assert.h> +#include "defines.h" +#include "prototypes.h" +/*@-exitarg@*/ +#include "exitcodes.h" +#include "groupio.h" +#include "pwio.h" +#ifdef SHADOWGRP +#include "sgroupio.h" +#endif +#include "shadowio.h" +#ifdef ENABLE_SUBIDS +#include "subordinateio.h" +#endif /* ENABLE_SUBIDS */ +#include "getdef.h" +#include "shadowlog.h" + +static char *passwd_db_file = NULL; +static char *spw_db_file = NULL; +static char *group_db_file = NULL; +static char *sgroup_db_file = NULL; +static char *suid_db_file = NULL; +static char *sgid_db_file = NULL; +static char *def_conf_file = NULL; +static FILE* fp_pwent = NULL; +static FILE* fp_grent = NULL; + +/* + * process_prefix_flag - prefix all paths if given the --prefix option + * + * This shall be called before accessing the passwd, group, shadow, + * gshadow, useradd's default, login.defs files (non exhaustive list) + * or authenticating the caller. + * + * The audit, syslog, or locale files shall be open before + */ +extern const char* process_prefix_flag (const char* short_opt, int argc, char **argv) +{ + /* + * Parse the command line options. + */ + int i; + const char *prefix = NULL, *val; + + for (i = 0; i < argc; i++) { + val = NULL; + if ( (strcmp (argv[i], "--prefix") == 0) + || ((strncmp (argv[i], "--prefix=", 9) == 0) + && (val = argv[i] + 9)) + || (strcmp (argv[i], short_opt) == 0)) { + if (NULL != prefix) { + fprintf (log_get_logfd(), + _("%s: multiple --prefix options\n"), + log_get_progname()); + exit (E_BAD_ARG); + } + + if (val) { + prefix = val; + } else if (i + 1 == argc) { + fprintf (log_get_logfd(), + _("%s: option '%s' requires an argument\n"), + log_get_progname(), argv[i]); + exit (E_BAD_ARG); + } else { + prefix = argv[++ i]; + } + } + } + + + + if (prefix != NULL) { + 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? */ + + if ( prefix[0] != '/') { + fprintf (log_get_logfd(), + _("%s: prefix must be an absolute path\n"), + 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); + 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); + 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); + 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); + 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"); + 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"); + 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"); + setdef_config_file(def_conf_file); +#endif + } + + if (prefix == NULL) + return ""; + return prefix; +} + + +extern struct group *prefix_getgrnam(const char *name) +{ + if (group_db_file) { + FILE* fg; + struct group * grp = NULL; + + fg = fopen(group_db_file, "rt"); + if (!fg) + return NULL; + while ((grp = fgetgrent(fg)) != NULL) { + if (!strcmp(name, grp->gr_name)) + break; + } + fclose(fg); + return grp; + } + + return getgrnam(name); +} + +extern struct group *prefix_getgrgid(gid_t gid) +{ + if (group_db_file) { + FILE* fg; + struct group * grp = NULL; + + fg = fopen(group_db_file, "rt"); + if (!fg) + return NULL; + while ((grp = fgetgrent(fg)) != NULL) { + if (gid == grp->gr_gid) + break; + } + fclose(fg); + return grp; + } + + return getgrgid(gid); +} + +extern struct passwd *prefix_getpwuid(uid_t uid) +{ + if (passwd_db_file) { + FILE* fg; + struct passwd *pwd = NULL; + + fg = fopen(passwd_db_file, "rt"); + if (!fg) + return NULL; + while ((pwd = fgetpwent(fg)) != NULL) { + if (uid == pwd->pw_uid) + break; + } + fclose(fg); + return pwd; + } + else { + return getpwuid(uid); + } +} +extern struct passwd *prefix_getpwnam(const char* name) +{ + if (passwd_db_file) { + FILE* fg; + struct passwd *pwd = NULL; + + fg = fopen(passwd_db_file, "rt"); + if (!fg) + return NULL; + while ((pwd = fgetpwent(fg)) != NULL) { + if (!strcmp(name, pwd->pw_name)) + break; + } + fclose(fg); + return pwd; + } + else { + return getpwnam(name); + } +} +extern struct spwd *prefix_getspnam(const char* name) +{ + if (spw_db_file) { + FILE* fg; + struct spwd *sp = NULL; + + fg = fopen(spw_db_file, "rt"); + if (!fg) + return NULL; + while ((sp = fgetspent(fg)) != NULL) { + if (!strcmp(name, sp->sp_namp)) + break; + } + fclose(fg); + return sp; + } + else { + return getspnam(name); + } +} + +extern void prefix_setpwent(void) +{ + if (!passwd_db_file) { + setpwent(); + return; + } + if (fp_pwent) + fclose (fp_pwent); + + fp_pwent = fopen(passwd_db_file, "rt"); + if (!fp_pwent) + return; +} +extern struct passwd* prefix_getpwent(void) +{ + if (!passwd_db_file) { + return getpwent(); + } + if (!fp_pwent) { + return NULL; + } + return fgetpwent(fp_pwent); +} +extern void prefix_endpwent(void) +{ + if (!passwd_db_file) { + endpwent(); + return; + } + if (fp_pwent) + fclose(fp_pwent); + fp_pwent = NULL; +} + +extern void prefix_setgrent(void) +{ + if (!group_db_file) { + setgrent(); + return; + } + if (fp_grent) + fclose (fp_grent); + + fp_grent = fopen(group_db_file, "rt"); + if (!fp_grent) + return; +} +extern struct group* prefix_getgrent(void) +{ + if (!group_db_file) { + return getgrent(); + } + return fgetgrent(fp_grent); +} +extern void prefix_endgrent(void) +{ + if (!group_db_file) { + endgrent(); + return; + } + if (fp_grent) + fclose(fp_grent); + fp_grent = NULL; +} + +extern struct group *prefix_getgr_nam_gid(const char *grname) +{ + long long int gid; + char *endptr; + 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 + return getgr_nam_gid(grname); +} |