diff --git a/contrib/openpam/lib/libpam/openpam_configure.c b/contrib/openpam/lib/libpam/openpam_configure.c --- a/contrib/openpam/lib/libpam/openpam_configure.c +++ b/contrib/openpam/lib/libpam/openpam_configure.c @@ -157,10 +157,11 @@ openpam_style_t style) { pam_chain_t *this, **next; + pam_module_t *module; pam_facility_t fclt; pam_control_t ctlf; char *name, *servicename, *modulename; - int count, lineno, ret, serrno; + int count, lineno, nonfatal, ret, serrno; char **wordv, *word; int i, wordc; @@ -186,10 +187,22 @@ } /* check facility name */ - if ((word = wordv[i++]) == NULL || - (fclt = parse_facility_name(word)) == (pam_facility_t)-1) { + if ((word = wordv[i++]) == NULL) { openpam_log(PAM_LOG_ERROR, - "%s(%d): missing or invalid facility", + "%s(%d): missing facility", + filename, lineno); + errno = EINVAL; + goto fail; + } + if (*word == '-') { + nonfatal = 1; + word++; + } else { + nonfatal = 0; + } + if ((fclt = parse_facility_name(word)) == (pam_facility_t)-1) { + openpam_log(PAM_LOG_ERROR, + "%s(%d): invalid facility", filename, lineno); errno = EINVAL; goto fail; @@ -199,13 +212,25 @@ continue; } - /* check for "include" */ - if ((word = wordv[i++]) != NULL && - strcmp(word, "include") == 0) { - if ((servicename = wordv[i++]) == NULL || - !valid_service_name(servicename)) { + /* control flag or "include" */ + if ((word = wordv[i++]) == NULL) { + openpam_log(PAM_LOG_ERROR, + "%s(%d): missing control flag", + filename, lineno); + errno = EINVAL; + goto fail; + } + if (strcmp(word, "include") == 0) { + if ((servicename = wordv[i++]) == NULL) { + openpam_log(PAM_LOG_ERROR, + "%s(%d): missing service name", + filename, lineno); + errno = EINVAL; + goto fail; + } + if (!valid_service_name(servicename)) { openpam_log(PAM_LOG_ERROR, - "%s(%d): missing or invalid service name", + "%s(%d): invalid service name", filename, lineno); errno = EINVAL; goto fail; @@ -231,39 +256,48 @@ } continue; } - - /* get control flag */ - if (word == NULL || /* same word we compared to "include" */ - (ctlf = parse_control_flag(word)) == (pam_control_t)-1) { + if ((ctlf = parse_control_flag(word)) == (pam_control_t)-1) { openpam_log(PAM_LOG_ERROR, - "%s(%d): missing or invalid control flag", + "%s(%d): invalid control flag", filename, lineno); errno = EINVAL; goto fail; } /* get module name */ - if ((modulename = wordv[i++]) == NULL || - !valid_module_name(modulename)) { + if ((modulename = wordv[i++]) == NULL) { openpam_log(PAM_LOG_ERROR, - "%s(%d): missing or invalid module name", + "%s(%d): missing module name", + filename, lineno); + errno = EINVAL; + goto fail; + } + if (!valid_module_name(modulename)) { + openpam_log(PAM_LOG_ERROR, + "%s(%d): invalid module name", filename, lineno); errno = EINVAL; goto fail; } - - /* allocate new entry */ - if ((this = calloc(1, sizeof *this)) == NULL) - goto syserr; - this->flag = ctlf; /* load module */ - if ((this->module = openpam_load_module(modulename)) == NULL) { - if (errno == ENOENT) + if ((module = openpam_load_module(modulename)) == NULL) { + if (errno == ENOENT) { + if (nonfatal) { + FREEV(wordc, wordv); + continue; + } errno = ENOEXEC; + } goto fail; } + /* allocate new entry */ + if ((this = calloc(1, sizeof *this)) == NULL) + goto syserr; + this->flag = ctlf; + this->module = module; + /* * The remaining items in wordv are the module's * arguments. We could set this->optv = wordv + i, but