static size_t internal_arraysz = 0;
static const char ** internal_array = NULL;
+static char path_login_conf[] = _PATH_LOGIN_CONF;
+
static char *
allocstr(const char *str)
{
arrayize(const char *str, const char *chars, int *size)
{
int i;
- const char *ptr;
+ char *ptr;
+ const char *cptr;
const char **res = NULL;
/* count the sub-strings */
- for (i = 0, ptr = str; *ptr; i++) {
- int count = strcspn(ptr, chars);
- ptr += count;
- if (*ptr)
- ++ptr;
+ for (i = 0, cptr = str; *cptr; i++) {
+ int count = strcspn(cptr, chars);
+ cptr += count;
+ if (*cptr)
+ ++cptr;
}
/* alloc the array */
if ((ptr = allocstr(str)) != NULL) {
if ((res = allocarray(++i)) == NULL)
- free(str);
+ free((void *)(uintptr_t)(const void *)str);
else {
/* now split the string */
i = 0;
/*
- * login_getclassbyname() get the login class by its name.
+ * login_getclassbyname()
+ * Get the login class by its name.
* If the name given is NULL or empty, the default class
- * LOGIN_DEFCLASS (ie. "default") is fetched. If the
- * 'dir' argument contains a non-NULL non-empty string,
- * then the file _FILE_LOGIN_CONF is picked up from that
- * directory instead of the system login database.
+ * LOGIN_DEFCLASS (i.e., "default") is fetched.
+ * If the name given is LOGIN_MECLASS and
+ * 'pwd' argument is non-NULL and contains an non-NULL
+ * dir entry, then the file _FILE_LOGIN_CONF is picked
+ * up from that directory and used before the system
+ * login database. In that case the system login database
+ * is looked up using LOGIN_MECLASS, too, which is a bug.
* Return a filled-out login_cap_t structure, including
* class name, and the capability record buffer.
*/
const char *dir;
char userpath[MAXPATHLEN];
- static const char *login_dbarray[] = { NULL, NULL, NULL };
+ static char *login_dbarray[] = { NULL, NULL, NULL };
me = (name != NULL && strcmp(name, LOGIN_MECLASS) == 0);
dir = (!me || pwd == NULL) ? NULL : pwd->pw_dir;
if (dir && snprintf(userpath, MAXPATHLEN, "%s/%s", dir,
_FILE_LOGIN_CONF) < MAXPATHLEN) {
- login_dbarray[i] = userpath;
if (_secure_path(userpath, pwd->pw_uid, pwd->pw_gid) != -1)
- i++; /* only use 'secure' data */
+ login_dbarray[i++] = userpath;
}
- if (_secure_path(_PATH_LOGIN_CONF, 0, 0) != -1)
- login_dbarray[i++] = _PATH_LOGIN_CONF;
+ /*
+ * XXX: Why to add the system database if the class is `me'?
+ */
+ if (_secure_path(path_login_conf, 0, 0) != -1)
+ login_dbarray[i++] = path_login_conf;
login_dbarray[i] = NULL;
memset(lc, 0, sizeof(login_cap_t));
break; /* Don't retry default on 'me' */
if (i == 0)
r = -1;
- else if ((r = open(login_dbarray[0], O_RDONLY)) >= 0)
+ else if ((r = open(login_dbarray[0], O_RDONLY | O_CLOEXEC)) >= 0)
close(r);
/*
* If there's at least one login class database,
/*
- * login_getclass()
+ * login_getpwclass()
* Get the login class for a given password entry from
* the system (only) login class database.
* If the password entry's class field is not set, or
* the class specified does not exist, then use the
- * default of LOGIN_DEFCLASS (ie. "default").
+ * default of LOGIN_DEFCLASS (i.e., "default") for an unprivileged
+ * user or that of LOGIN_DEFROOTCLASS (i.e., "root") for a super-user.
* Return a filled-out login_cap_t structure, including
* class name, and the capability record buffer.
*/
if (cls == NULL || *cls == '\0')
cls = (pwd->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS;
}
+ /*
+ * XXX: pwd should be unused by login_getclassbyname() unless cls is `me',
+ * so NULL can be passed instead of pwd for more safety.
+ */
return login_getclassbyname(cls, pwd);
}
/*
* login_getuserclass()
- * Get the login class for a given password entry, allowing user
- * overrides via ~/.login_conf.
+ * Get the `me' login class, allowing user overrides via ~/.login_conf.
+ * Note that user overrides are allowed only in the `me' class.
*/
login_cap_t *
}
-
/*
* login_getcapstr()
* Given a login_cap entry, and a capability name, return the
- * value defined for that capability, a defualt if not found, or
+ * value defined for that capability, a default if not found, or
* an error string on error.
*/