Revert large parts of r478. I had forgotten that the module arguments

are actually passed to each service function in the classic (argc,
argv) form.  The only place where the compiler could have caught this
used a type cast, and it did not show up in testing either because all
of the modules I tested use openpam_get_option(3) instead of
manipulating argv directly.

The cleaned-up policy parsing code remains in place, but options are
once more stored as strings, pretty much the way they appear in the
policy file, except that quotes are stripped.


git-svn-id: svn+ssh://svn.openpam.org/svn/openpam/trunk@482 185d5e19-27fe-0310-9dcf-9bff6b9f3609
This commit is contained in:
Dag-Erling Smørgrav 2011-11-03 16:33:02 +00:00
parent c16faba34e
commit 6835696a2a
4 changed files with 48 additions and 54 deletions

View File

@ -269,23 +269,17 @@ parse_filename(char **line, char **filename)
/* /*
* Parse an option. * Parse an option.
* *
* Returns a pointer to a dynamically allocated pam_opt_t with the name * Returns a dynamically allocated string containing the next module
* and value of the next module option, or NULL if the end of the string * option, or NULL if the end of the string was reached or a disallowed
* was reached or a disallowed non-whitespace character was encountered. * non-whitespace character was encountered.
*
* An option consists of an option name optionally followed by an equal
* sign and an option value.
*
* The structure and strings are allocated as a single object, so a single
* free(3) call is sufficient to release the allocated memory.
* *
* If parse_option() is successful, it updates *line to point one * If parse_option() is successful, it updates *line to point one
* character past the end of the option. If it reaches the end of the * character past the end of the option. If it reaches the end of the
* string, it updates *line to point to the terminating NUL character. In * string, it updates *line to point to the terminating NUL character. In
* all other cases, it leaves *line unmodified. * all other cases, it leaves *line unmodified.
* *
* If parse_option() fails to allocate memory for the option structure, it * If parse_option() fails to allocate memory, it will return NULL and set
* will return NULL and set errno to a non-zero value. * errno to a non-zero value.
* *
* Allowed characters for option names are all characters in the POSIX * Allowed characters for option names are all characters in the POSIX
* portable filename character set. Allowed characters for option values * portable filename character set. Allowed characters for option values
@ -294,13 +288,12 @@ parse_filename(char **line, char **filename)
* characters and whichever quote character was not used are allowed. * characters and whichever quote character was not used are allowed.
* Note that the entire value must be quoted, not just part of it. * Note that the entire value must be quoted, not just part of it.
*/ */
static pam_opt_t * static char *
parse_option(char **line) parse_option(char **line)
{ {
char *nb, *ne, *vb, *ve; char *nb, *ne, *vb, *ve;
unsigned char q = 0; unsigned char q = 0;
pam_opt_t *opt; char *option;
size_t size;
errno = 0; errno = 0;
for (nb = *line; *nb && is_lws(*nb); ++nb) for (nb = *line; *nb && is_lws(*nb); ++nb)
@ -331,17 +324,14 @@ parse_option(char **line)
} else { } else {
vb = ve = ne; vb = ve = ne;
} }
size = sizeof *opt; if ((option = malloc((ne - nb) + 1 + (ve - vb) + 1)) == NULL)
size += ne - nb + 1;
size += ve - vb + 1;
if ((opt = malloc(size)) == NULL)
return (NULL); return (NULL);
opt->name = (char *)opt + sizeof *opt; strncpy(option, nb, ne - nb);
strlcpy(opt->name, nb, ne - nb + 1); option[ne - nb] = '=';
opt->value = opt->name + (ne - nb) + 1; strncpy(option + (ne - nb), vb, ve - vb);
strlcpy(opt->value, vb, ve - vb + 1); option[(ne - nb) + 1 + (ve - vb) + 1] = '\0';
*line = q ? ve + 1 : ve; *line = q ? ve + 1 : ve;
return (opt); return (option);
} }
/* /*
@ -380,8 +370,8 @@ openpam_parse_chain(pam_handle_t *pamh,
int count, lineno; int count, lineno;
pam_facility_t fclt; pam_facility_t fclt;
pam_control_t ctlf; pam_control_t ctlf;
pam_opt_t *opt;
char *line, *str, *name; char *line, *str, *name;
char *option, **optv;
int len, ret; int len, ret;
FILE *f; FILE *f;
@ -470,12 +460,17 @@ openpam_parse_chain(pam_handle_t *pamh,
this->flag = ctlf; this->flag = ctlf;
/* get module options */ /* get module options */
/* XXX quick and dirty, may waste a few hundred bytes */ this->optv = NULL;
if ((this->optv = malloc(sizeof *opt * strlen(line))) == NULL) this->optc = 0;
goto syserr; while ((option = parse_option(&line)) != NULL) {
while ((opt = parse_option(&line)) != NULL) optv = realloc(this->optv,
this->optv[this->optc++] = opt; (this->optc + 2) * sizeof *optv);
this->optv[this->optc] = NULL; if (optv == NULL)
goto syserr;
this->optv = optv;
this->optv[this->optc++] = option;
this->optv[this->optc] = NULL;
}
if (*line != '\0') { if (*line != '\0') {
openpam_log(PAM_LOG_ERROR, openpam_log(PAM_LOG_ERROR,
"%s(%d): syntax error in module options", "%s(%d): syntax error in module options",

View File

@ -59,15 +59,22 @@ openpam_get_option(pam_handle_t *pamh,
const char *option) const char *option)
{ {
pam_chain_t *cur; pam_chain_t *cur;
size_t len;
int i; int i;
ENTERS(option); ENTERS(option);
if (pamh == NULL || pamh->current == NULL || option == NULL) if (pamh == NULL || pamh->current == NULL || option == NULL)
RETURNS(NULL); RETURNS(NULL);
cur = pamh->current; cur = pamh->current;
for (i = 0; i < cur->optc; ++i) len = strlen(option);
if (strcmp(cur->optv[i]->name, option) == 0) for (i = 0; i < cur->optc; ++i) {
RETURNS(cur->optv[i]->value); if (strncmp(cur->optv[i], option, len) == 0) {
if (cur->optv[i][len] == '\0')
RETURNS(&cur->optv[i][len]);
else if (cur->optv[i][len] == '=')
RETURNS(&cur->optv[i][len + 1]);
}
}
RETURNS(NULL); RETURNS(NULL);
} }

View File

@ -71,19 +71,12 @@ typedef enum {
PAM_NUM_FACILITIES PAM_NUM_FACILITIES
} pam_facility_t; } pam_facility_t;
typedef struct pam_opt pam_opt_t;
struct pam_opt {
char *name;
char *value;
char str[];
};
typedef struct pam_chain pam_chain_t; typedef struct pam_chain pam_chain_t;
struct pam_chain { struct pam_chain {
pam_module_t *module; pam_module_t *module;
int flag; int flag;
int optc; int optc;
pam_opt_t **optv; char **optv;
pam_chain_t *next; pam_chain_t *next;
}; };

View File

@ -62,16 +62,22 @@ openpam_set_option(pam_handle_t *pamh,
const char *value) const char *value)
{ {
pam_chain_t *cur; pam_chain_t *cur;
pam_opt_t *opt, **optv; char *opt, **optv;
int i, ol, vl; size_t len;
int i;
ENTERS(option); ENTERS(option);
if (pamh == NULL || pamh->current == NULL || option == NULL) if (pamh == NULL || pamh->current == NULL || option == NULL)
RETURNC(PAM_SYSTEM_ERR); RETURNC(PAM_SYSTEM_ERR);
cur = pamh->current; cur = pamh->current;
for (i = 0; i < cur->optc; ++i) for (len = 0; option[len] != '\0'; ++len)
if (strcmp(cur->optv[i]->name, option) == 0) if (option[len] == '=')
break; break;
for (i = 0; i < cur->optc; ++i) {
if (strncmp(cur->optv[i], option, len) == 0 &&
(cur->optv[i][len] == '\0' || cur->optv[i][len] == '='))
break;
}
if (value == NULL) { if (value == NULL) {
/* remove */ /* remove */
if (i == cur->optc) if (i == cur->optc)
@ -79,20 +85,13 @@ openpam_set_option(pam_handle_t *pamh,
for (free(cur->optv[i]); i < cur->optc; ++i) for (free(cur->optv[i]); i < cur->optc; ++i)
cur->optv[i] = cur->optv[i + 1]; cur->optv[i] = cur->optv[i + 1];
cur->optv[i] = NULL; cur->optv[i] = NULL;
cur->optc--;
RETURNC(PAM_SUCCESS); RETURNC(PAM_SUCCESS);
} }
ol = strlen(option) + 1; if (asprintf(&opt, "%.*s=%s", (int)len, option, value) < 0)
vl = strlen(value) + 1;
if ((opt = malloc(sizeof *opt + ol + vl)) == NULL)
RETURNC(PAM_BUF_ERR); RETURNC(PAM_BUF_ERR);
opt->name = (char *)opt + sizeof *opt;
strlcpy(opt->name, option, ol);
opt->value = opt->name + ol;
strlcpy(opt->value, value, vl);
if (i == cur->optc) { if (i == cur->optc) {
/* add */ /* add */
optv = realloc(cur->optv, sizeof *optv * (cur->optc + 2)); optv = realloc(cur->optv, sizeof(char *) * (cur->optc + 2));
if (optv == NULL) { if (optv == NULL) {
FREE(opt); FREE(opt);
RETURNC(PAM_BUF_ERR); RETURNC(PAM_BUF_ERR);