/* * Locates the policy file for a given service and reads the given chains * from it. */ static int openpam_load_chain(pam_handle_t *pamh, const char *service, pam_facility_t facility) { const char **path; char *filename; size_t len; int ret; /* don't allow to escape from policy_path */ if (strchr(service, '/')) { openpam_log(PAM_LOG_ERROR, "invalid service name: %s", service); return (-PAM_SYSTEM_ERR); } for (path = openpam_policy_path; *path != NULL; ++path) { len = strlen(*path); if ((*path)[len - 1] == '/') { if (asprintf(&filename, "%s%s", *path, service) < 0) { openpam_log(PAM_LOG_ERROR, "asprintf(): %m"); return (PAM_BUF_ERR); } ret = openpam_parse_chain(pamh, service, facility, filename, pam_d_style); FREE(filename); } else { ret = openpam_parse_chain(pamh, service, facility, *path, pam_conf_style); } if (ret != PAM_SUCCESS) return (ret); } return (PAM_SUCCESS); }
/* * Read the specified chains from the specified file. * * Returns 0 if the file exists but does not contain any matching lines. * * Returns -1 and sets errno to ENOENT if the file does not exist. * * Returns -1 and sets errno to some other non-zero value if the file * exists but is unsafe or unreadable, or an I/O error occurs. */ static int openpam_load_file(pam_handle_t *pamh, const char *service, pam_facility_t facility, const char *filename, openpam_style_t style) { FILE *f; int ret, serrno; /* attempt to open the file */ if ((f = fopen(filename, "r")) == NULL) { serrno = errno; openpam_log(errno == ENOENT ? PAM_LOG_DEBUG : PAM_LOG_ERROR, "%s: %m", filename); errno = serrno; RETURNN(-1); } else { openpam_log(PAM_LOG_DEBUG, "found %s", filename); } /* verify type, ownership and permissions */ if (OPENPAM_FEATURE(VERIFY_POLICY_FILE) && openpam_check_desc_owner_perms(filename, fileno(f)) != 0) { /* already logged the cause */ serrno = errno; fclose(f); errno = serrno; RETURNN(-1); } /* parse the file */ ret = openpam_parse_chain(pamh, service, facility, f, filename, style); RETURNN(ret); }