Changeset 524 in openpam for trunk


Ignore:
Timestamp:
Jan 11, 2012, 12:29:48 AM (8 years ago)
Author:
Dag-Erling Smørgrav
Message:

Fix a regression introduced by r487. The count was actually used to
determine whether to stop searching for a policy. After r487,
multiple policies for the same service would be concatenated, whereas
the intention was that the one that came first in the policy path
should eclipse the others.

While there, take the time to reorganize the front end of the policy
loading code, both to clarify the logic and to produce better log
messages in case of errors. The most important change is that
openpam_load_chain() now opens and vets the policy file before calling
openpam_parse_chain(), so it is better able to distinguish between
errors relating to the file itself and errors relating to its
contents.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/openpam_configure.c

    r500 r524  
    3939# include "config.h"
    4040#endif
     41
     42#include <sys/param.h>
    4143
    4244#include <ctype.h>
     
    350352/*
    351353 * Extracts given chains from a policy file.
     354 *
     355 * Returns the number of policy entries which were found for the specified
     356 * service and facility, or -1 if a system error occurred or a syntax
     357 * error was encountered.
    352358 */
    353359static int
     
    355361        const char *service,
    356362        pam_facility_t facility,
     363        FILE *f,
    357364        const char *filename,
    358365        openpam_style_t style)
     
    363370        char *line, *str, *name;
    364371        char *option, **optv;
    365         int len, lineno, ret;
    366         FILE *f;
    367 
    368         if ((f = fopen(filename, "r")) == NULL) {
    369                 openpam_log(errno == ENOENT ? PAM_LOG_DEBUG : PAM_LOG_NOTICE,
    370                     "%s: %m", filename);
    371                 return (PAM_SUCCESS);
    372         }
    373         if (openpam_check_desc_owner_perms(filename, fileno(f)) != 0) {
    374                 fclose(f);
    375                 return (PAM_SYSTEM_ERR);
    376         }
     372        int count, len, lineno, ret, serrno;
     373
     374        count = 0;
    377375        this = NULL;
    378376        name = NULL;
     
    424422                        ret = openpam_load_chain(pamh, name, fclt);
    425423                        FREE(name);
    426                         if (ret != PAM_SUCCESS)
     424                        if (ret < 0)
    427425                                goto fail;
    428426                        FREE(line);
     
    485483                *next = this;
    486484                this = NULL;
     485                ++count;
    487486
    488487                /* next please... */
     
    492491                goto syserr;
    493492        fclose(f);
    494         return (PAM_SUCCESS);
     493        return (count);
    495494syserr:
     495        serrno = errno;
    496496        openpam_log(PAM_LOG_ERROR, "%s: %m", filename);
     497        errno = serrno;
     498        /* fall through */
    497499fail:
     500        serrno = errno;
    498501        if (this && this->optc) {
    499502                while (this->optc--)
     
    504507        FREE(line);
    505508        FREE(name);
    506         fclose(f);
    507         return (PAM_SYSTEM_ERR);
     509        errno = serrno;
     510        return (-1);
    508511}
    509512
     
    519522 * Locates the policy file for a given service and reads the given chains
    520523 * from it.
     524 *
     525 * Returns the number of policy entries which were found for the specified
     526 * service and facility, or -1 if a system error occurred or a syntax
     527 * error was encountered.
    521528 */
    522529static int
     
    526533{
    527534        const char **path;
    528         char *filename;
     535        char filename[PATH_MAX];
    529536        size_t len;
    530         int ret;
    531 
     537        openpam_style_t style;
     538        FILE *f;
     539        int ret, serrno;
     540
     541        ENTERS(facility < 0 ? "any" : pam_facility_name[facility]);
    532542        for (path = openpam_policy_path; *path != NULL; ++path) {
    533                 len = strlen(*path);
    534                 if ((*path)[len - 1] == '/') {
    535                         if (asprintf(&filename, "%s%s", *path, service) < 0) {
    536                                 openpam_log(PAM_LOG_ERROR, "asprintf(): %m");
    537                                 return (PAM_BUF_ERR);
     543                /* construct filename */
     544                len = strlcpy(filename, *path, sizeof filename);
     545                if (filename[len - 1] == '/') {
     546                        len = strlcat(filename, service, sizeof filename);
     547                        if (len >= sizeof filename) {
     548                                errno = ENAMETOOLONG;
     549                                RETURNN(-1);
    538550                        }
    539                         ret = openpam_parse_chain(pamh, service, facility,
    540                             filename, pam_d_style);
    541                         FREE(filename);
     551                        style = pam_d_style;
    542552                } else {
    543                         ret = openpam_parse_chain(pamh, service, facility,
    544                             *path, pam_conf_style);
    545                 }
    546                 if (ret != PAM_SUCCESS)
    547                         return (ret);
    548         }
    549         return (PAM_SUCCESS);
     553                        style = pam_conf_style;
     554                }
     555
     556                /* attempt to open the file */
     557                if ((f = fopen(filename, "r")) == NULL) {
     558                        if (errno == ENOENT || errno == ENOTDIR) {
     559                                openpam_log(PAM_LOG_DEBUG, "%s: %m", filename);
     560                                continue;
     561                        } else {
     562                                serrno = errno;
     563                                openpam_log(PAM_LOG_ERROR, "%s: %m", filename);
     564                                errno = serrno;
     565                                RETURNN(-1);
     566                        }
     567                } else {
     568                        openpam_log(PAM_LOG_DEBUG, "found %s", filename);
     569                }
     570
     571                /* verify type, ownership and permissions */
     572                if (openpam_check_desc_owner_perms(filename, fileno(f)) != 0) {
     573                        serrno = errno;
     574                        fclose(f);
     575                        errno = serrno;
     576                        RETURNN(-1);
     577                }
     578
     579                /* parse the file */
     580                ret = openpam_parse_chain(pamh, service, facility,
     581                    f, filename, style);
     582
     583                /* in pam.d style, an empty file counts as a hit */
     584                if (ret != 0 || style == pam_d_style)
     585                        RETURNN(ret);
     586        }
     587        RETURNN(0);
    550588}
    551589
     
    562600        pam_facility_t fclt;
    563601        const char *p;
    564 
     602        int serrno;
     603
     604        ENTERS(service);
    565605        for (p = service; *p; ++p)
    566606                if (!is_pfcs(*p))
    567                         return (PAM_SYSTEM_ERR);
    568 
    569         if (openpam_load_chain(pamh, service, PAM_FACILITY_ANY) != PAM_SUCCESS)
     607                        RETURNC(PAM_SYSTEM_ERR);
     608        if (openpam_load_chain(pamh, service, PAM_FACILITY_ANY) < 0)
    570609                goto load_err;
    571 
    572610        for (fclt = 0; fclt < PAM_NUM_FACILITIES; ++fclt) {
    573611                if (pamh->chains[fclt] != NULL)
    574612                        continue;
    575                 if (openpam_load_chain(pamh, PAM_OTHER, fclt) != PAM_SUCCESS)
     613                if (openpam_load_chain(pamh, PAM_OTHER, fclt) < 0)
    576614                        goto load_err;
    577615        }
    578         return (PAM_SUCCESS);
     616        RETURNC(PAM_SUCCESS);
    579617load_err:
     618        serrno = errno;
    580619        openpam_clear_chains(pamh->chains);
    581         return (PAM_SYSTEM_ERR);
     620        errno = serrno;
     621        RETURNC(PAM_SYSTEM_ERR);
    582622}
    583623
Note: See TracChangeset for help on using the changeset viewer.