Changeset 600 in openpam for trunk/lib


Ignore:
Timestamp:
Apr 14, 2012, 4:11:39 PM (9 years ago)
Author:
Dag-Erling Smørgrav
Message:

Separate the code that opens and validates the policy file from the code
that searches for it. If the service name contains a path separator
character, treat it is a relative or absolute path to the policy file.

This need to be documented either in pam.conf(5) or in pam_start(3) once
the feature mechanism is no longer experimental.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/openpam_configure.c

    r594 r600  
    316316
    317317/*
     318 * Read the specified chains from the specified file.
     319 *
     320 * Returns 0 if the file exists but does not contain any matching lines.
     321 *
     322 * Returns -1 and sets errno to ENOENT if the file does not exist.
     323 *
     324 * Returns -1 and sets errno to some other non-zero value if the file
     325 * exists but is unsafe or unreadable, or an I/O error occurs.
     326 */
     327static int
     328openpam_load_file(pam_handle_t *pamh,
     329        const char *service,
     330        pam_facility_t facility,
     331        const char *filename,
     332        openpam_style_t style)
     333{
     334        FILE *f;
     335        int ret, serrno;
     336
     337        /* attempt to open the file */
     338        if ((f = fopen(filename, "r")) == NULL) {
     339                serrno = errno;
     340                openpam_log(errno == ENOENT ? PAM_LOG_DEBUG : PAM_LOG_ERROR,
     341                    "%s: %m", filename);
     342                errno = serrno;
     343                RETURNN(-1);
     344        } else {
     345                openpam_log(PAM_LOG_DEBUG, "found %s", filename);
     346        }
     347
     348        /* verify type, ownership and permissions */
     349        if (OPENPAM_FEATURE(VERIFY_POLICY_FILE) &&
     350            openpam_check_desc_owner_perms(filename, fileno(f)) != 0) {
     351                /* already logged the cause */
     352                serrno = errno;
     353                fclose(f);
     354                errno = serrno;
     355                RETURNN(-1);
     356        }
     357
     358        /* parse the file */
     359        ret = openpam_parse_chain(pamh, service, facility,
     360            f, filename, style);
     361        RETURNN(ret);
     362}
     363
     364/*
    318365 * Locates the policy file for a given service and reads the given chains
    319366 * from it.
     
    328375        pam_facility_t facility)
    329376{
    330         const char **path;
     377        const char *p, **path;
    331378        char filename[PATH_MAX];
    332379        size_t len;
     
    336383
    337384        ENTERS(facility < 0 ? "any" : pam_facility_name[facility]);
     385
     386        /* either absolute or relative to cwd */
     387        if (strchr(service, '/') != NULL) {
     388                if (p = strrchr(service, '.') && strcmp(p, ".conf") == 0)
     389                        style = pam_conf_style;
     390                else
     391                        style = pam_d_style;
     392                ret = openpam_load_file(pamh, service, facility,
     393                    service, style);
     394                RETURNN(ret);
     395        }
     396
     397        /* search standard locations */
    338398        for (path = openpam_policy_path; *path != NULL; ++path) {
    339399                /* construct filename */
     
    349409                        style = pam_conf_style;
    350410                }
    351 
    352                 /* attempt to open the file */
    353                 if ((f = fopen(filename, "r")) == NULL) {
    354                         if (errno == ENOENT || errno == ENOTDIR) {
    355                                 openpam_log(PAM_LOG_DEBUG, "%s: %m", filename);
    356                                 continue;
    357                         } else {
    358                                 serrno = errno;
    359                                 openpam_log(PAM_LOG_ERROR, "%s: %m", filename);
    360                                 errno = serrno;
    361                                 RETURNN(-1);
    362                         }
    363                 } else {
    364                         openpam_log(PAM_LOG_DEBUG, "found %s", filename);
    365                 }
    366 
    367                 /* verify type, ownership and permissions */
    368                 if (OPENPAM_FEATURE(VERIFY_POLICY_FILE) &&
    369                     openpam_check_desc_owner_perms(filename, fileno(f)) != 0) {
    370                         serrno = errno;
    371                         fclose(f);
    372                         errno = serrno;
    373                         RETURNN(-1);
    374                 }
    375 
    376                 /* parse the file */
    377                 ret = openpam_parse_chain(pamh, service, facility,
    378                     f, filename, style);
    379 
     411                ret = openpam_load_file(pamh, service, facility,
     412                    filename, style);
     413                /* the file exists, but an error occurred */
     414                if (ret == -1 && errno != ENOENT)
     415                        RETURNN(ret);
    380416                /* in pam.d style, an empty file counts as a hit */
    381                 if (ret != 0 || style == pam_d_style)
     417                if (ret == 0 && style == pam_d_style)
    382418                        RETURNN(ret);
    383419        }
     420
     421        /* no hit */
    384422        RETURNN(0);
    385423}
Note: See TracChangeset for help on using the changeset viewer.