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:
parent
c16faba34e
commit
6835696a2a
|
@ -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",
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue