Incorporate patches from Dmitry V. Levin which improve the policy
loader, reducing the number of times each file is read. Also fix a few minor nits (such as making facility names and control flags case insensitive like they are in Solaris). git-svn-id: svn+ssh://svn.openpam.org/svn/openpam/trunk@243 185d5e19-27fe-0310-9dcf-9bff6b9f3609
This commit is contained in:
parent
3326a91846
commit
044448812b
|
@ -31,9 +31,10 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $P4: //depot/projects/openpam/lib/openpam_configure.c#9 $
|
||||
* $P4: //depot/projects/openpam/lib/openpam_configure.c#10 $
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -58,7 +59,7 @@ const char *_pam_control_flag_name[PAM_NUM_CONTROL_FLAGS] = {
|
|||
[PAM_SUFFICIENT] = "sufficient",
|
||||
};
|
||||
|
||||
static int openpam_load_chain(pam_chain_t **, const char *, const char *);
|
||||
static int openpam_load_chain(pam_handle_t *, const char *, pam_facility_t);
|
||||
|
||||
/*
|
||||
* Matches a word against the first one in a string.
|
||||
|
@ -68,7 +69,7 @@ static int
|
|||
match_word(const char *str, const char *word)
|
||||
{
|
||||
|
||||
while (*str && *str == *word)
|
||||
while (*str && tolower(*str) == tolower(*word))
|
||||
++str, ++word;
|
||||
return (*str == ' ' && *word == '\0');
|
||||
}
|
||||
|
@ -121,18 +122,20 @@ wordlen(const char *str)
|
|||
typedef enum { pam_conf_style, pam_d_style } openpam_style_t;
|
||||
|
||||
/*
|
||||
* Extracts a given chain from a policy file.
|
||||
* Extracts given chains from a policy file.
|
||||
*/
|
||||
static int
|
||||
openpam_read_chain(pam_chain_t **chain,
|
||||
openpam_read_chain(pam_handle_t *pamh,
|
||||
const char *service,
|
||||
const char *facility,
|
||||
pam_facility_t facility,
|
||||
const char *filename,
|
||||
openpam_style_t style)
|
||||
{
|
||||
pam_chain_t *this, **next;
|
||||
const char *p, *q;
|
||||
int count, i, lineno, ret;
|
||||
pam_facility_t fclt;
|
||||
pam_control_t ctlf;
|
||||
char *line, *name;
|
||||
FILE *f;
|
||||
|
||||
|
@ -141,8 +144,7 @@ openpam_read_chain(pam_chain_t **chain,
|
|||
"%s: %m", filename);
|
||||
return (0);
|
||||
}
|
||||
next = chain;
|
||||
this = *next = NULL;
|
||||
this = NULL;
|
||||
count = lineno = 0;
|
||||
while ((line = openpam_readline(f, &lineno, NULL)) != NULL) {
|
||||
p = line;
|
||||
|
@ -157,15 +159,16 @@ openpam_read_chain(pam_chain_t **chain,
|
|||
}
|
||||
|
||||
/* match facility name */
|
||||
for (i = 0; i < PAM_NUM_FACILITIES; ++i)
|
||||
if (match_word(p, _pam_facility_name[i]))
|
||||
for (fclt = 0; fclt < PAM_NUM_FACILITIES; ++fclt)
|
||||
if (match_word(p, _pam_facility_name[fclt]))
|
||||
break;
|
||||
if (i == PAM_NUM_FACILITIES) {
|
||||
if (fclt == PAM_NUM_FACILITIES) {
|
||||
openpam_log(PAM_LOG_NOTICE,
|
||||
"%s(%d): invalid facility '%.*s' (ignored)",
|
||||
filename, lineno, wordlen(p), p);
|
||||
goto fail;
|
||||
}
|
||||
if (!match_word(p, facility)) {
|
||||
if (facility != fclt && facility != PAM_FACILITY_ANY) {
|
||||
FREE(line);
|
||||
continue;
|
||||
}
|
||||
|
@ -180,15 +183,13 @@ openpam_read_chain(pam_chain_t **chain,
|
|||
filename, lineno);
|
||||
if ((name = dup_word(p)) == NULL)
|
||||
goto syserr;
|
||||
ret = openpam_load_chain(next, name, facility);
|
||||
ret = openpam_load_chain(pamh, name, fclt);
|
||||
fprintf(stderr, "include %s returned %d\n", name, ret);
|
||||
FREE(name);
|
||||
while (*next != NULL) {
|
||||
next = &(*next)->next;
|
||||
++count;
|
||||
}
|
||||
FREE(line);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
count += ret;
|
||||
FREE(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -197,16 +198,16 @@ openpam_read_chain(pam_chain_t **chain,
|
|||
goto syserr;
|
||||
|
||||
/* control flag */
|
||||
for (i = 0; i < PAM_NUM_CONTROL_FLAGS; ++i)
|
||||
if (match_word(p, _pam_control_flag_name[i]))
|
||||
for (ctlf = 0; ctlf < PAM_NUM_CONTROL_FLAGS; ++ctlf)
|
||||
if (match_word(p, _pam_control_flag_name[ctlf]))
|
||||
break;
|
||||
if (i == PAM_NUM_CONTROL_FLAGS) {
|
||||
if (ctlf == PAM_NUM_CONTROL_FLAGS) {
|
||||
openpam_log(PAM_LOG_ERROR,
|
||||
"%s(%d): invalid control flag '%.*s'",
|
||||
filename, lineno, wordlen(p), p);
|
||||
goto fail;
|
||||
}
|
||||
this->flag = i;
|
||||
this->flag = ctlf;
|
||||
|
||||
/* module name */
|
||||
p = next_word(p);
|
||||
|
@ -239,8 +240,10 @@ openpam_read_chain(pam_chain_t **chain,
|
|||
}
|
||||
|
||||
/* hook it up */
|
||||
for (next = &pamh->chains[fclt]; *next != NULL;
|
||||
next = &(*next)->next)
|
||||
/* nothing */ ;
|
||||
*next = this;
|
||||
next = &this->next;
|
||||
this = NULL;
|
||||
++count;
|
||||
|
||||
|
@ -269,13 +272,13 @@ static const char *openpam_policy_path[] = {
|
|||
};
|
||||
|
||||
/*
|
||||
* Locates the policy file for a given service and reads the given chain
|
||||
* Locates the policy file for a given service and reads the given chains
|
||||
* from it.
|
||||
*/
|
||||
static int
|
||||
openpam_load_chain(pam_chain_t **chain,
|
||||
openpam_load_chain(pam_handle_t *pamh,
|
||||
const char *service,
|
||||
const char *facility)
|
||||
pam_facility_t facility)
|
||||
{
|
||||
const char **path;
|
||||
char *filename;
|
||||
|
@ -289,11 +292,11 @@ openpam_load_chain(pam_chain_t **chain,
|
|||
openpam_log(PAM_LOG_ERROR, "asprintf(): %m");
|
||||
return (-PAM_BUF_ERR);
|
||||
}
|
||||
r = openpam_read_chain(chain, service, facility,
|
||||
r = openpam_read_chain(pamh, service, facility,
|
||||
filename, pam_d_style);
|
||||
FREE(filename);
|
||||
} else {
|
||||
r = openpam_read_chain(chain, service, facility,
|
||||
r = openpam_read_chain(pamh, service, facility,
|
||||
*path, pam_conf_style);
|
||||
}
|
||||
if (r != 0)
|
||||
|
@ -312,20 +315,21 @@ int
|
|||
openpam_configure(pam_handle_t *pamh,
|
||||
const char *service)
|
||||
{
|
||||
int i, ret;
|
||||
pam_facility_t fclt;
|
||||
|
||||
for (i = 0; i < PAM_NUM_FACILITIES; ++i) {
|
||||
ret = openpam_load_chain(&pamh->chains[i],
|
||||
service, _pam_facility_name[i]);
|
||||
if (ret == 0)
|
||||
ret = openpam_load_chain(&pamh->chains[i],
|
||||
PAM_OTHER, _pam_facility_name[i]);
|
||||
if (ret < 0) {
|
||||
openpam_clear_chains(pamh->chains);
|
||||
return (PAM_SYSTEM_ERR);
|
||||
}
|
||||
if (openpam_load_chain(pamh, service, PAM_FACILITY_ANY) < 0)
|
||||
goto load_err;
|
||||
|
||||
for (fclt = 0; fclt < PAM_NUM_FACILITIES; ++fclt) {
|
||||
if (pamh->chains[fclt] != NULL)
|
||||
continue;
|
||||
if (openpam_load_chain(pamh, PAM_OTHER, fclt) < 0)
|
||||
goto load_err;
|
||||
}
|
||||
return (PAM_SUCCESS);
|
||||
load_err:
|
||||
openpam_clear_chains(pamh->chains);
|
||||
return (PAM_SYSTEM_ERR);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $P4: //depot/projects/openpam/lib/openpam_impl.h#26 $
|
||||
* $P4: //depot/projects/openpam/lib/openpam_impl.h#27 $
|
||||
*/
|
||||
|
||||
#ifndef _OPENPAM_IMPL_H_INCLUDED
|
||||
|
@ -49,21 +49,26 @@ extern int _openpam_debug;
|
|||
/*
|
||||
* Control flags
|
||||
*/
|
||||
#define PAM_BINDING 0
|
||||
#define PAM_REQUIRED 1
|
||||
#define PAM_REQUISITE 2
|
||||
#define PAM_SUFFICIENT 3
|
||||
#define PAM_OPTIONAL 4
|
||||
#define PAM_NUM_CONTROL_FLAGS 5
|
||||
typedef enum {
|
||||
PAM_BINDING,
|
||||
PAM_REQUIRED,
|
||||
PAM_REQUISITE,
|
||||
PAM_SUFFICIENT,
|
||||
PAM_OPTIONAL,
|
||||
PAM_NUM_CONTROL_FLAGS
|
||||
} pam_control_t;
|
||||
|
||||
/*
|
||||
* Facilities
|
||||
*/
|
||||
#define PAM_AUTH 0
|
||||
#define PAM_ACCOUNT 1
|
||||
#define PAM_SESSION 2
|
||||
#define PAM_PASSWORD 3
|
||||
#define PAM_NUM_FACILITIES 4
|
||||
typedef enum {
|
||||
PAM_FACILITY_ANY = -1,
|
||||
PAM_AUTH = 0,
|
||||
PAM_ACCOUNT,
|
||||
PAM_SESSION,
|
||||
PAM_PASSWORD,
|
||||
PAM_NUM_FACILITIES
|
||||
} pam_facility_t;
|
||||
|
||||
typedef struct pam_chain pam_chain_t;
|
||||
struct pam_chain {
|
||||
|
|
Loading…
Reference in New Issue