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. git-svn-id: svn+ssh://svn.openpam.org/svn/openpam/trunk@600 185d5e19-27fe-0310-9dcf-9bff6b9f3609
This commit is contained in:
parent
aa1f7162f1
commit
7ca68ffaec
|
@ -314,6 +314,53 @@ static const char *openpam_policy_path[] = {
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Locates the policy file for a given service and reads the given chains
|
* Locates the policy file for a given service and reads the given chains
|
||||||
* from it.
|
* from it.
|
||||||
|
@ -327,7 +374,7 @@ openpam_load_chain(pam_handle_t *pamh,
|
||||||
const char *service,
|
const char *service,
|
||||||
pam_facility_t facility)
|
pam_facility_t facility)
|
||||||
{
|
{
|
||||||
const char **path;
|
const char *p, **path;
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
size_t len;
|
size_t len;
|
||||||
openpam_style_t style;
|
openpam_style_t style;
|
||||||
|
@ -335,6 +382,19 @@ openpam_load_chain(pam_handle_t *pamh,
|
||||||
int ret, serrno;
|
int ret, serrno;
|
||||||
|
|
||||||
ENTERS(facility < 0 ? "any" : pam_facility_name[facility]);
|
ENTERS(facility < 0 ? "any" : pam_facility_name[facility]);
|
||||||
|
|
||||||
|
/* either absolute or relative to cwd */
|
||||||
|
if (strchr(service, '/') != NULL) {
|
||||||
|
if (p = strrchr(service, '.') && strcmp(p, ".conf") == 0)
|
||||||
|
style = pam_conf_style;
|
||||||
|
else
|
||||||
|
style = pam_d_style;
|
||||||
|
ret = openpam_load_file(pamh, service, facility,
|
||||||
|
service, style);
|
||||||
|
RETURNN(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* search standard locations */
|
||||||
for (path = openpam_policy_path; *path != NULL; ++path) {
|
for (path = openpam_policy_path; *path != NULL; ++path) {
|
||||||
/* construct filename */
|
/* construct filename */
|
||||||
len = strlcpy(filename, *path, sizeof filename);
|
len = strlcpy(filename, *path, sizeof filename);
|
||||||
|
@ -348,39 +408,17 @@ openpam_load_chain(pam_handle_t *pamh,
|
||||||
} else {
|
} else {
|
||||||
style = pam_conf_style;
|
style = pam_conf_style;
|
||||||
}
|
}
|
||||||
|
ret = openpam_load_file(pamh, service, facility,
|
||||||
/* attempt to open the file */
|
filename, style);
|
||||||
if ((f = fopen(filename, "r")) == NULL) {
|
/* the file exists, but an error occurred */
|
||||||
if (errno == ENOENT || errno == ENOTDIR) {
|
if (ret == -1 && errno != ENOENT)
|
||||||
openpam_log(PAM_LOG_DEBUG, "%s: %m", filename);
|
RETURNN(ret);
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
serrno = errno;
|
|
||||||
openpam_log(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) {
|
|
||||||
serrno = errno;
|
|
||||||
fclose(f);
|
|
||||||
errno = serrno;
|
|
||||||
RETURNN(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* parse the file */
|
|
||||||
ret = openpam_parse_chain(pamh, service, facility,
|
|
||||||
f, filename, style);
|
|
||||||
|
|
||||||
/* in pam.d style, an empty file counts as a hit */
|
/* in pam.d style, an empty file counts as a hit */
|
||||||
if (ret != 0 || style == pam_d_style)
|
if (ret == 0 && style == pam_d_style)
|
||||||
RETURNN(ret);
|
RETURNN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* no hit */
|
||||||
RETURNN(0);
|
RETURNN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue