use existing logindefs.c and pathnames.h
I'm not sure having /usr/local in _PATH_DEFPATH_ROOT and even putting it in front is such a good idea though. /usr/local might be on NFS so could prevent root from logging in if the network is down.
This commit is contained in:
parent
f29fc7e0bb
commit
9c44ac503f
|
@ -71,8 +71,8 @@ vipw_SOURCES = \
|
|||
$(top_srcdir)/lib/fileutils.c
|
||||
su_SOURCES = \
|
||||
su.c \
|
||||
getdef.c \
|
||||
getdef.h
|
||||
logindefs.c \
|
||||
logindefs.h
|
||||
|
||||
chfn_LDADD = $(login_ldadd_common)
|
||||
chsh_LDADD = $(login_ldadd_common)
|
||||
|
|
|
@ -1,259 +0,0 @@
|
|||
/* Copyright (C) 2003, 2004, 2005 Thorsten Kukuk
|
||||
Author: Thorsten Kukuk <kukuk@suse.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2 or
|
||||
later as published by the Free Software Foundation.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "getdef.h"
|
||||
|
||||
struct item {
|
||||
char *name; /* Name of the option. */
|
||||
char *value; /* Value of the option. */
|
||||
struct item *next; /* Pointer to next option. */
|
||||
};
|
||||
|
||||
static struct item *list = NULL;
|
||||
|
||||
void
|
||||
free_getdef_data (void)
|
||||
{
|
||||
struct item *ptr;
|
||||
|
||||
ptr = list;
|
||||
while (ptr != NULL)
|
||||
{
|
||||
struct item *tmp;
|
||||
tmp = ptr->next;
|
||||
free (ptr->name);
|
||||
free (ptr->value);
|
||||
free (ptr);
|
||||
ptr = tmp;
|
||||
}
|
||||
|
||||
list = NULL;
|
||||
}
|
||||
|
||||
/* Add a new entry to the list. */
|
||||
static void
|
||||
store (const char *name, const char *value)
|
||||
{
|
||||
struct item *new = malloc (sizeof (struct item));
|
||||
|
||||
if (new == NULL)
|
||||
abort ();
|
||||
|
||||
if (name == NULL)
|
||||
abort ();
|
||||
|
||||
new->name = strdup (name);
|
||||
new->value = strdup (value ?: "");
|
||||
new->next = list;
|
||||
list = new;
|
||||
}
|
||||
|
||||
/* Search a special entry in the list and return the value. */
|
||||
static const char *
|
||||
search (const char *name)
|
||||
{
|
||||
struct item *ptr;
|
||||
|
||||
ptr = list;
|
||||
while (ptr != NULL)
|
||||
{
|
||||
if (strcasecmp (name, ptr->name) == 0)
|
||||
return ptr->value;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Load the login.defs file (/etc/login.defs). */
|
||||
static void
|
||||
load_defaults_internal (const char *filename)
|
||||
{
|
||||
FILE *fp;
|
||||
char *buf = NULL;
|
||||
size_t buflen = 0;
|
||||
|
||||
fp = fopen (filename, "r");
|
||||
if (NULL == fp)
|
||||
return;
|
||||
|
||||
while (!feof (fp))
|
||||
{
|
||||
char *tmp, *cp;
|
||||
#if defined(HAVE_GETLINE)
|
||||
ssize_t n = getline (&buf, &buflen, fp);
|
||||
#elif defined (HAVE_GETDELIM)
|
||||
ssize_t n = getdelim (&buf, &buflen, '\n', fp);
|
||||
#else
|
||||
ssize_t n;
|
||||
|
||||
if (buf == NULL)
|
||||
{
|
||||
buflen = 8096;
|
||||
buf = malloc (buflen);
|
||||
}
|
||||
buf[0] = '\0';
|
||||
fgets (buf, buflen - 1, fp);
|
||||
if (buf != NULL)
|
||||
n = strlen (buf);
|
||||
else
|
||||
n = 0;
|
||||
#endif /* HAVE_GETLINE / HAVE_GETDELIM */
|
||||
cp = buf;
|
||||
|
||||
if (n < 1)
|
||||
break;
|
||||
|
||||
tmp = strchr (cp, '#'); /* remove comments */
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
while (isspace ((unsigned char) *cp)) /* remove spaces and tabs */
|
||||
++cp;
|
||||
if (*cp == '\0') /* ignore empty lines */
|
||||
continue;
|
||||
|
||||
if (cp[strlen (cp) - 1] == '\n')
|
||||
cp[strlen (cp) - 1] = '\0';
|
||||
|
||||
tmp = strsep (&cp, " \t=");
|
||||
if (cp != NULL)
|
||||
while (isspace ((unsigned char) *cp) || *cp == '=')
|
||||
++cp;
|
||||
|
||||
store (tmp, cp);
|
||||
}
|
||||
fclose (fp);
|
||||
|
||||
if (buf)
|
||||
free (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
load_defaults (void)
|
||||
{
|
||||
load_defaults_internal ("/etc/default/su");
|
||||
load_defaults_internal ("/etc/login.defs");
|
||||
}
|
||||
|
||||
int
|
||||
getdef_bool (const char *name, int dflt)
|
||||
{
|
||||
const char *val;
|
||||
|
||||
if (list == NULL)
|
||||
load_defaults ();
|
||||
|
||||
val = search (name);
|
||||
|
||||
if (val == NULL)
|
||||
return dflt;
|
||||
|
||||
return (strcasecmp (val, "yes") == 0);
|
||||
}
|
||||
|
||||
long
|
||||
getdef_num (const char *name, long dflt)
|
||||
{
|
||||
const char *val;
|
||||
char *cp;
|
||||
long retval;
|
||||
|
||||
if (list == NULL)
|
||||
load_defaults ();
|
||||
|
||||
val = search (name);
|
||||
|
||||
if (val == NULL)
|
||||
return dflt;
|
||||
|
||||
errno = 0;
|
||||
retval = strtol (val, &cp, 0);
|
||||
if (*cp != '\0'
|
||||
|| ((retval == LONG_MAX || retval == LONG_MIN) && errno == ERANGE))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%s contains invalid numerical value: %s!\n",
|
||||
name, val);
|
||||
retval = dflt;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
getdef_unum (const char *name, unsigned long dflt)
|
||||
{
|
||||
const char *val;
|
||||
char *cp;
|
||||
unsigned long retval;
|
||||
|
||||
if (list == NULL)
|
||||
load_defaults ();
|
||||
|
||||
val = search (name);
|
||||
|
||||
if (val == NULL)
|
||||
return dflt;
|
||||
|
||||
errno = 0;
|
||||
retval = strtoul (val, &cp, 0);
|
||||
if (*cp != '\0' || (retval == ULONG_MAX && errno == ERANGE))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%s contains invalid numerical value: %s!\n",
|
||||
name, val);
|
||||
retval = dflt;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
const char *
|
||||
getdef_str (const char *name, const char *dflt)
|
||||
{
|
||||
const char *retval;
|
||||
|
||||
if (list == NULL)
|
||||
load_defaults ();
|
||||
|
||||
retval = search (name);
|
||||
|
||||
return retval ?: dflt;
|
||||
}
|
||||
|
||||
#if defined(TEST)
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
printf ("CYPT=%s\n", getdef_str ("cRypt", "no"));
|
||||
printf ("LOG_UNKFAIL_ENAB=%s\n", getdef_str ("log_unkfail_enab",""));
|
||||
printf ("DOESNOTEXIST=%s\n", getdef_str ("DOESNOTEXIST","yes"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,29 +0,0 @@
|
|||
/* Copyright (C) 2003, 2005 Thorsten Kukuk
|
||||
Author: Thorsten Kukuk <kukuk@suse.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2 or
|
||||
later as published by the Free Software Foundation.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _GETDEF_H_
|
||||
|
||||
#define _GETDEF_H_ 1
|
||||
|
||||
extern int getdef_bool (const char *name, int dflt);
|
||||
extern long getdef_num (const char *name, long dflt);
|
||||
extern unsigned long getdef_unum (const char *name, unsigned long dflt);
|
||||
extern const char *getdef_str (const char *name, const char *dflt);
|
||||
|
||||
/* Free all data allocated by getdef_* calls before. */
|
||||
extern void free_getdef_data (void);
|
||||
|
||||
#endif /* _GETDEF_H_ */
|
|
@ -45,6 +45,8 @@ struct item {
|
|||
|
||||
static struct item *list = NULL;
|
||||
|
||||
void (*logindefs_load_defaults)(void) = NULL;
|
||||
|
||||
void free_getlogindefs_data(void)
|
||||
{
|
||||
struct item *ptr;
|
||||
|
@ -77,7 +79,7 @@ static void store(const char *name, const char *value, const char *path)
|
|||
list = new;
|
||||
}
|
||||
|
||||
static void load_defaults(const char *filename)
|
||||
void logindefs_load_file(const char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
char buf[BUFSIZ];
|
||||
|
@ -139,12 +141,20 @@ static void load_defaults(const char *filename)
|
|||
fclose(f);
|
||||
}
|
||||
|
||||
static void load_defaults()
|
||||
{
|
||||
if (logindefs_load_defaults)
|
||||
logindefs_load_defaults();
|
||||
else
|
||||
logindefs_load_file(_PATH_LOGINDEFS);
|
||||
}
|
||||
|
||||
static struct item *search(const char *name)
|
||||
{
|
||||
struct item *ptr;
|
||||
|
||||
if (!list)
|
||||
load_defaults(_PATH_LOGINDEFS);
|
||||
load_defaults();
|
||||
|
||||
ptr = list;
|
||||
while (ptr != NULL) {
|
||||
|
@ -259,7 +269,7 @@ int main(int argc, char *argv[])
|
|||
errx(EXIT_FAILURE, "usage: %s <filename> "
|
||||
"[<str|num|bool> <valname>]", argv[0]);
|
||||
|
||||
load_defaults(argv[1]);
|
||||
logindefs_load_file(argv[1]);
|
||||
|
||||
if (argc != 4) { /* list all */
|
||||
struct item *ptr;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef UTIL_LINUX_LOGINDEFS_H
|
||||
#define UTIL_LINUX_LOGINDEFS_H
|
||||
|
||||
extern void logindefs_load_file(const char *filename);
|
||||
extern void (*logindefs_load_defaults)(void);
|
||||
extern int getlogindefs_bool(const char *name, int dflt);
|
||||
extern long getlogindefs_num(const char *name, long dflt);
|
||||
extern const char *getlogindefs_str(const char *name, const char *dflt);
|
||||
|
|
|
@ -69,6 +69,7 @@ enum
|
|||
#include <stdbool.h>
|
||||
#include "xalloc.h"
|
||||
#include "nls.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
/* The official name of this program (e.g., no `g' prefix). */
|
||||
#define PROGRAM_NAME "su"
|
||||
|
@ -77,13 +78,7 @@ enum
|
|||
#define PAM_SERVICE_NAME PROGRAM_NAME
|
||||
#define PAM_SERVICE_NAME_L PROGRAM_NAME "-l"
|
||||
|
||||
#include "getdef.h"
|
||||
|
||||
/* The default PATH for simulated logins to non-superuser accounts. */
|
||||
#define DEFAULT_LOGIN_PATH "/usr/local/bin:/bin:/usr/bin"
|
||||
|
||||
/* The default PATH for simulated logins to superuser accounts. */
|
||||
#define DEFAULT_ROOT_LOGIN_PATH "/usr/sbin:/bin:/usr/bin:/sbin"
|
||||
#include "logindefs.h"
|
||||
|
||||
/* The shell to run if none is given in the user's passwd entry. */
|
||||
#define DEFAULT_SHELL "/bin/sh"
|
||||
|
@ -517,8 +512,8 @@ modify_environment (const struct passwd *pw, const char *shell)
|
|||
xsetenv ("USER", pw->pw_name);
|
||||
xsetenv ("LOGNAME", pw->pw_name);
|
||||
xsetenv ("PATH", (pw->pw_uid
|
||||
? getdef_str ("PATH", DEFAULT_LOGIN_PATH)
|
||||
: getdef_str ("SUPATH", DEFAULT_ROOT_LOGIN_PATH)));
|
||||
? getlogindefs_str ("PATH", _PATH_DEFPATH)
|
||||
: getlogindefs_str ("SUPATH", _PATH_DEFPATH_ROOT)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -528,12 +523,12 @@ modify_environment (const struct passwd *pw, const char *shell)
|
|||
{
|
||||
xsetenv ("HOME", pw->pw_dir);
|
||||
xsetenv ("SHELL", shell);
|
||||
if (getdef_bool ("ALWAYS_SET_PATH", 0))
|
||||
if (getlogindefs_bool ("ALWAYS_SET_PATH", 0))
|
||||
xsetenv ("PATH", (pw->pw_uid
|
||||
? getdef_str ("PATH",
|
||||
DEFAULT_LOGIN_PATH)
|
||||
: getdef_str ("SUPATH",
|
||||
DEFAULT_ROOT_LOGIN_PATH)));
|
||||
? getlogindefs_str ("PATH",
|
||||
_PATH_DEFPATH)
|
||||
: getlogindefs_str ("SUPATH",
|
||||
_PATH_DEFPATH_ROOT)));
|
||||
else
|
||||
{
|
||||
char const *path = getenv ("PATH");
|
||||
|
@ -687,6 +682,12 @@ A mere - implies -l. If USER not given, assume root.\n\
|
|||
exit (status);
|
||||
}
|
||||
|
||||
void load_config(void)
|
||||
{
|
||||
logindefs_load_file("/etc/default/su");
|
||||
logindefs_load_file(_PATH_LOGINDEFS);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
|
@ -757,6 +758,8 @@ main (int argc, char **argv)
|
|||
if (optind < argc)
|
||||
new_user = argv[optind++];
|
||||
|
||||
logindefs_load_defaults = load_config;
|
||||
|
||||
pw = getpwnam (new_user);
|
||||
if (! (pw && pw->pw_name && pw->pw_name[0] && pw->pw_dir && pw->pw_dir[0]
|
||||
&& pw->pw_passwd))
|
||||
|
@ -781,7 +784,7 @@ main (int argc, char **argv)
|
|||
if (!correct_password (pw))
|
||||
{
|
||||
log_su (pw, false);
|
||||
sleep (getdef_num ("FAIL_DELAY", 1));
|
||||
sleep (getlogindefs_num ("FAIL_DELAY", 1));
|
||||
error (EXIT_FAIL, 0, _("incorrect password"));
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue