MDJVU_IMPLEMENT void mdjvu_pattern_destroy(mdjvu_pattern_t p)/*{{{*/ { Image *img = (Image *) p; FREEV(img->pixels[0]); FREEV(img->pixels); FREE(img); }/*}}}*/
/* * Read a line from the temp file and verify that the result matches our * expectations: whether a line was read at all, how many and which words * it contained, how many lines were read (in case of quoted or escaped * newlines) and whether we reached the end of the file. */ static int orlv_expect(const char **expectedv, int lines, int eof) { int expectedc, gotc, i, lineno = 0; char **gotv; expectedc = 0; if (expectedv != NULL) while (expectedv[expectedc] != NULL) ++expectedc; gotv = openpam_readlinev(f, &lineno, &gotc); if (ferror(f)) err(1, "%s(): %s", __func__, filename); if (expectedv != NULL && gotv == NULL) { t_verbose("expected %d words, got nothing\n", expectedc); return (0); } if (expectedv == NULL && gotv != NULL) { t_verbose("expected nothing, got %d words\n", gotc); FREEV(gotc, gotv); return (0); } if (expectedv != NULL && gotv != NULL) { if (expectedc != gotc) { t_verbose("expected %d words, got %d\n", expectedc, gotc); FREEV(gotc, gotv); return (0); } for (i = 0; i < gotc; ++i) { if (strcmp(expectedv[i], gotv[i]) != 0) { t_verbose("word %d: expected <<%s>>, " "got <<%s>>\n", i, expectedv[i], gotv[i]); FREEV(gotc, gotv); return (0); } } FREEV(gotc, gotv); } if (lineno != lines) { t_verbose("expected to advance %d lines, advanced %d lines\n", lines, lineno); return (0); } if (eof && !feof(f)) { t_verbose("expected EOF, but didn't get it\n"); return (0); } if (!eof && feof(f)) { t_verbose("didn't expect EOF, but got it anyway\n"); return (0); } return (1); }
static void openpam_destroy_chain(pam_chain_t *chain) { if (chain == NULL) return; openpam_destroy_chain(chain->next); chain->next = NULL; FREEV(chain->optc, chain->optv); openpam_release_module(chain->module); chain->module = NULL; FREE(chain); }
/* * Extracts given chains from a policy file. * * Returns the number of policy entries which were found for the specified * service and facility, or -1 if a system error occurred or a syntax * error was encountered. */ static int openpam_parse_chain(pam_handle_t *pamh, const char *service, pam_facility_t facility, FILE *f, const char *filename, openpam_style_t style) { pam_chain_t *this, **next; pam_facility_t fclt; pam_control_t ctlf; char *name, *servicename, *modulename; int count, lineno, ret, serrno; char **wordv, *word; int i, wordc; count = 0; this = NULL; name = NULL; lineno = 0; wordc = 0; wordv = NULL; while ((wordv = openpam_readlinev(f, &lineno, &wordc)) != NULL) { /* blank line? */ if (wordc == 0) { FREEV(wordc, wordv); continue; } i = 0; /* check service name if necessary */ if (style == pam_conf_style && strcmp(wordv[i++], service) != 0) { FREEV(wordc, wordv); continue; } /* check facility name */ if ((word = wordv[i++]) == NULL || (fclt = parse_facility_name(word)) == (pam_facility_t)-1) { openpam_log(PAM_LOG_ERROR, "%s(%d): missing or invalid facility", filename, lineno); errno = EINVAL; goto fail; } if (facility != fclt && facility != PAM_FACILITY_ANY) { FREEV(wordc, wordv); continue; } /* check for "include" */ if ((word = wordv[i++]) != NULL && strcmp(word, "include") == 0) { if ((servicename = wordv[i++]) == NULL || !valid_service_name(servicename)) { openpam_log(PAM_LOG_ERROR, "%s(%d): missing or invalid service name", filename, lineno); errno = EINVAL; goto fail; } if (wordv[i] != NULL) { openpam_log(PAM_LOG_ERROR, "%s(%d): garbage at end of line", filename, lineno); errno = EINVAL; goto fail; } ret = openpam_load_chain(pamh, servicename, fclt); FREEV(wordc, wordv); if (ret < 0) { /* * Bogus errno, but this ensures that the * outer loop does not just ignore the * error and keep searching. */ if (errno == ENOENT) errno = EINVAL; goto fail; } continue; } /* get control flag */ if (word == NULL || /* same word we compared to "include" */ (ctlf = parse_control_flag(word)) == (pam_control_t)-1) { openpam_log(PAM_LOG_ERROR, "%s(%d): missing or invalid control flag", filename, lineno); errno = EINVAL; goto fail; } /* get module name */ if ((modulename = wordv[i++]) == NULL || !valid_module_name(modulename)) { openpam_log(PAM_LOG_ERROR, "%s(%d): missing or 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) errno = ENOEXEC; goto fail; } /* * The remaining items in wordv are the module's * arguments. We could set this->optv = wordv + i, but * then free(this->optv) wouldn't work. Instead, we free * the words we've already consumed, shift the rest up, * and clear the tail end of the array. */ this->optc = wordc - i; for (i = 0; i < wordc - this->optc; ++i) { FREE(wordv[i]); } for (i = 0; i < this->optc; ++i) { wordv[i] = wordv[wordc - this->optc + i]; wordv[wordc - this->optc + i] = NULL; } this->optv = wordv; wordv = NULL; wordc = 0; /* hook it up */ for (next = &pamh->chains[fclt]; *next != NULL; next = &(*next)->next) /* nothing */ ; *next = this; this = NULL; ++count; } /* * The loop ended because openpam_readword() returned NULL, which * can happen for four different reasons: an I/O error (ferror(f) * is true), a memory allocation failure (ferror(f) is false, * feof(f) is false, errno is non-zero), the file ended with an * unterminated quote or backslash escape (ferror(f) is false, * feof(f) is true, errno is non-zero), or the end of the file was * reached without error (ferror(f) is false, feof(f) is true, * errno is zero). */ if (ferror(f) || errno != 0) goto syserr; if (!feof(f)) goto fail; fclose(f); return (count); syserr: serrno = errno; openpam_log(PAM_LOG_ERROR, "%s: %m", filename); errno = serrno; /* fall through */ fail: serrno = errno; if (this && this->optc && this->optv) FREEV(this->optc, this->optv); FREE(this); FREEV(wordc, wordv); FREE(wordv); FREE(name); fclose(f); errno = serrno; return (-1); }