summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2022-04-23 08:00:00 +0000
committerDmitry V. Levin <ldv@altlinux.org>2022-04-24 08:00:00 +0000
commitd3b73b6cd818f4fd9c923822592eccbe8ecdd121 (patch)
treecb587ab07a57464e9b2a476efa47d85050c6bdec
parent095af08413e5a0f4b8a9f86fda8a85bcfa1d9153 (diff)
downloadlinux-pam-git-d3b73b6cd818f4fd9c923822592eccbe8ecdd121.tar.gz
pam_env: reorder definitions of static functions to avoid forward declarationsldv/pam_env-reorder-static-functions
* modules/pam_env/pam_env.c (_assemble_line, _parse_line, _check_var, _clean_var, _expand_arg, _pam_get_item_byname, _define_var, _undefine_var): Move definitions of static functions before their first use to avoid forward declarations cluttering the code.
-rw-r--r--modules/pam_env/pam_env.c531
1 files changed, 263 insertions, 268 deletions
diff --git a/modules/pam_env/pam_env.c b/modules/pam_env/pam_env.c
index c03ec3a3..66fbe240 100644
--- a/modules/pam_env/pam_env.c
+++ b/modules/pam_env/pam_env.c
@@ -53,15 +53,6 @@ typedef struct var {
#define UNDEFINE_VAR 102
#define ILLEGAL_VAR 103
-static int _assemble_line(FILE *, char *, int);
-static int _parse_line(const pam_handle_t *, const char *, VAR *);
-static int _check_var(pam_handle_t *, VAR *); /* This is the real meat */
-static void _clean_var(VAR *);
-static int _expand_arg(pam_handle_t *, char **);
-static const char * _pam_get_item_byname(pam_handle_t *, const char *);
-static int _define_var(pam_handle_t *, int, VAR *);
-static int _undefine_var(pam_handle_t *, int, VAR *);
-
/* This is a special value used to designate an empty string */
static char quote='\0';
@@ -128,166 +119,12 @@ _pam_parse (const pam_handle_t *pamh, int argc, const char **argv,
return ctrl;
}
-static int
-_parse_config_file(pam_handle_t *pamh, int ctrl, const char *file)
-{
- int retval;
- char buffer[BUF_SIZE];
- FILE *conf;
- VAR Var, *var=&Var;
-
- D(("Called."));
-
- var->name=NULL; var->defval=NULL; var->override=NULL;
-
- D(("Config file name is: %s", file));
-
- /*
- * Lets try to open the config file, parse it and process
- * any variables found.
- */
-
- if ((conf = fopen(file,"r")) == NULL) {
- pam_syslog(pamh, LOG_ERR, "Unable to open config file: %s: %m", file);
- return PAM_IGNORE;
- }
-
- /* _pam_assemble_line will provide a complete line from the config file,
- * with all comments removed and any escaped newlines fixed up
- */
-
- while (( retval = _assemble_line(conf, buffer, BUF_SIZE)) > 0) {
- D(("Read line: %s", buffer));
-
- if ((retval = _parse_line(pamh, buffer, var)) == GOOD_LINE) {
- retval = _check_var(pamh, var);
-
- if (DEFINE_VAR == retval) {
- retval = _define_var(pamh, ctrl, var);
-
- } else if (UNDEFINE_VAR == retval) {
- retval = _undefine_var(pamh, ctrl, var);
- }
- }
- if (PAM_SUCCESS != retval && ILLEGAL_VAR != retval
- && BAD_LINE != retval && PAM_BAD_ITEM != retval) break;
-
- _clean_var(var);
-
- } /* while */
-
- (void) fclose(conf);
-
- /* tidy up */
- _clean_var(var); /* We could have got here prematurely,
- * this is safe though */
- D(("Exit."));
- return (retval != 0 ? PAM_ABORT : PAM_SUCCESS);
-}
-
-static int
-_parse_env_file(pam_handle_t *pamh, int ctrl, const char *file)
-{
- int retval=PAM_SUCCESS, i, t;
- char buffer[BUF_SIZE], *key, *mark;
- FILE *conf;
-
- D(("Env file name is: %s", file));
-
- if ((conf = fopen(file,"r")) == NULL) {
- pam_syslog(pamh, LOG_ERR, "Unable to open env file: %s: %m", file);
- return PAM_IGNORE;
- }
-
- while (_assemble_line(conf, buffer, BUF_SIZE) > 0) {
- D(("Read line: %s", buffer));
- key = buffer;
-
- /* skip leading white space */
- key += strspn(key, " \n\t");
-
- /* skip blanks lines and comments */
- if (key[0] == '#')
- continue;
-
- /* skip over "export " if present so we can be compat with
- bash type declarations */
- if (strncmp(key, "export ", (size_t) 7) == 0)
- key += 7;
-
- /* now find the end of value */
- mark = key;
- while(mark[0] != '\n' && mark[0] != '#' && mark[0] != '\0')
- mark++;
- if (mark[0] != '\0')
- mark[0] = '\0';
-
- /*
- * sanity check, the key must be alphanumeric
- */
-
- if (key[0] == '=') {
- pam_syslog(pamh, LOG_ERR,
- "missing key name '%s' in %s', ignoring",
- key, file);
- continue;
- }
-
- for ( i = 0 ; key[i] != '=' && key[i] != '\0' ; i++ )
- if (!isalnum(key[i]) && key[i] != '_') {
- pam_syslog(pamh, LOG_ERR,
- "non-alphanumeric key '%s' in %s', ignoring",
- key, file);
- break;
- }
- /* non-alphanumeric key, ignore this line */
- if (key[i] != '=' && key[i] != '\0')
- continue;
-
- /* now we try to be smart about quotes around the value,
- but not too smart, we can't get all fancy with escaped
- values like bash */
- if (key[i] == '=' && (key[++i] == '\"' || key[i] == '\'')) {
- for ( t = i+1 ; key[t] != '\0' ; t++)
- if (key[t] != '\"' && key[t] != '\'')
- key[i++] = key[t];
- else if (key[t+1] != '\0')
- key[i++] = key[t];
- key[i] = '\0';
- }
-
- /* if this is a request to delete a variable, check that it's
- actually set first, so we don't get a vague error back from
- pam_putenv() */
- for (i = 0; key[i] != '=' && key[i] != '\0'; i++);
-
- if (key[i] == '\0' && !pam_getenv(pamh,key))
- continue;
-
- /* set the env var, if it fails, we break out of the loop */
- retval = pam_putenv(pamh, key);
- if (retval != PAM_SUCCESS) {
- D(("error setting env \"%s\"", key));
- break;
- } else if (ctrl & PAM_DEBUG_ARG) {
- pam_syslog(pamh, LOG_DEBUG,
- "pam_putenv(\"%s\")", key);
- }
- }
-
- (void) fclose(conf);
-
- /* tidy up */
- D(("Exit."));
- return retval;
-}
-
/*
* This is where we read a line of the PAM config file. The line may be
* preceded by lines of comments and also extended with "\\\n"
*/
-
-static int _assemble_line(FILE *f, char *buffer, int buf_len)
+static int
+_assemble_line(FILE *f, char *buffer, int buf_len)
{
char *p = buffer;
char *s, *os;
@@ -376,7 +213,7 @@ static int _assemble_line(FILE *f, char *buffer, int buf_len)
}
static int
-_parse_line (const pam_handle_t *pamh, const char *buffer, VAR *var)
+_parse_line(const pam_handle_t *pamh, const char *buffer, VAR *var)
{
/*
* parse buffer into var, legal syntax is
@@ -471,75 +308,57 @@ _parse_line (const pam_handle_t *pamh, const char *buffer, VAR *var)
return GOOD_LINE;
}
-static int _check_var(pam_handle_t *pamh, VAR *var)
+static const char *
+_pam_get_item_byname(pam_handle_t *pamh, const char *name)
{
/*
- * Examine the variable and determine what action to take.
- * Returns DEFINE_VAR, UNDEFINE_VAR depending on action to take
- * or a PAM_* error code if passed back from other routines
- *
- * if no DEFAULT provided, the empty string is assumed
- * if no OVERRIDE provided, the empty string is assumed
- * if DEFAULT= and OVERRIDE evaluates to the empty string,
- * this variable should be undefined
- * if DEFAULT="" and OVERRIDE evaluates to the empty string,
- * this variable should be defined with no value
- * if OVERRIDE=value and value turns into the empty string, DEFAULT is used
- *
- * If DEFINE_VAR is to be returned, the correct value to define will
- * be pointed to by var->value
+ * This function just allows me to use names as given in the config
+ * file and translate them into the appropriate PAM_ITEM macro
*/
- int retval;
+ int item;
+ const void *itemval;
D(("Called."));
-
- /*
- * First thing to do is to expand any arguments, but only
- * if they are not the special quote values (cause expand_arg
- * changes memory).
- */
-
- if (var->defval && (&quote != var->defval) &&
- ((retval = _expand_arg(pamh, &(var->defval))) != PAM_SUCCESS)) {
- return retval;
- }
- if (var->override && (&quote != var->override) &&
- ((retval = _expand_arg(pamh, &(var->override))) != PAM_SUCCESS)) {
- return retval;
+ if (strcmp(name, "PAM_USER") == 0 || strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0) {
+ item = PAM_USER;
+ } else if (strcmp(name, "PAM_USER_PROMPT") == 0) {
+ item = PAM_USER_PROMPT;
+ } else if (strcmp(name, "PAM_TTY") == 0) {
+ item = PAM_TTY;
+ } else if (strcmp(name, "PAM_RUSER") == 0) {
+ item = PAM_RUSER;
+ } else if (strcmp(name, "PAM_RHOST") == 0) {
+ item = PAM_RHOST;
+ } else {
+ D(("Unknown PAM_ITEM: <%s>", name));
+ pam_syslog (pamh, LOG_ERR, "Unknown PAM_ITEM: <%s>", name);
+ return NULL;
}
- /* Now its easy */
-
- if (var->override && *(var->override)) {
- /* if there is a non-empty string in var->override, we use it */
- D(("OVERRIDE variable <%s> being used: <%s>", var->name, var->override));
- var->value = var->override;
- retval = DEFINE_VAR;
- } else {
+ if (pam_get_item(pamh, item, &itemval) != PAM_SUCCESS) {
+ D(("pam_get_item failed"));
+ return NULL; /* let pam_get_item() log the error */
+ }
- var->value = var->defval;
- if (&quote == var->defval) {
- /*
- * This means that the empty string was given for defval value
- * which indicates that a variable should be defined with no value
- */
- D(("An empty variable: <%s>", var->name));
- retval = DEFINE_VAR;
- } else if (var->defval) {
- D(("DEFAULT variable <%s> being used: <%s>", var->name, var->defval));
- retval = DEFINE_VAR;
- } else {
- D(("UNDEFINE variable <%s>", var->name));
- retval = UNDEFINE_VAR;
+ if (itemval && (strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0)) {
+ struct passwd *user_entry;
+ user_entry = pam_modutil_getpwnam (pamh, itemval);
+ if (!user_entry) {
+ pam_syslog(pamh, LOG_ERR, "No such user!?");
+ return NULL;
}
+ return (strcmp(name, "SHELL") == 0) ?
+ user_entry->pw_shell :
+ user_entry->pw_dir;
}
D(("Exit."));
- return retval;
+ return itemval;
}
-static int _expand_arg(pam_handle_t *pamh, char **value)
+static int
+_expand_arg(pam_handle_t *pamh, char **value)
{
const char *orig=*value, *tmpptr=NULL;
char *ptr; /*
@@ -679,55 +498,96 @@ static int _expand_arg(pam_handle_t *pamh, char **value)
return PAM_SUCCESS;
}
-static const char * _pam_get_item_byname(pam_handle_t *pamh, const char *name)
+static int
+_check_var(pam_handle_t *pamh, VAR *var)
{
/*
- * This function just allows me to use names as given in the config
- * file and translate them into the appropriate PAM_ITEM macro
+ * Examine the variable and determine what action to take.
+ * Returns DEFINE_VAR, UNDEFINE_VAR depending on action to take
+ * or a PAM_* error code if passed back from other routines
+ *
+ * if no DEFAULT provided, the empty string is assumed
+ * if no OVERRIDE provided, the empty string is assumed
+ * if DEFAULT= and OVERRIDE evaluates to the empty string,
+ * this variable should be undefined
+ * if DEFAULT="" and OVERRIDE evaluates to the empty string,
+ * this variable should be defined with no value
+ * if OVERRIDE=value and value turns into the empty string, DEFAULT is used
+ *
+ * If DEFINE_VAR is to be returned, the correct value to define will
+ * be pointed to by var->value
*/
- int item;
- const void *itemval;
+ int retval;
D(("Called."));
- if (strcmp(name, "PAM_USER") == 0 || strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0) {
- item = PAM_USER;
- } else if (strcmp(name, "PAM_USER_PROMPT") == 0) {
- item = PAM_USER_PROMPT;
- } else if (strcmp(name, "PAM_TTY") == 0) {
- item = PAM_TTY;
- } else if (strcmp(name, "PAM_RUSER") == 0) {
- item = PAM_RUSER;
- } else if (strcmp(name, "PAM_RHOST") == 0) {
- item = PAM_RHOST;
- } else {
- D(("Unknown PAM_ITEM: <%s>", name));
- pam_syslog (pamh, LOG_ERR, "Unknown PAM_ITEM: <%s>", name);
- return NULL;
- }
- if (pam_get_item(pamh, item, &itemval) != PAM_SUCCESS) {
- D(("pam_get_item failed"));
- return NULL; /* let pam_get_item() log the error */
+ /*
+ * First thing to do is to expand any arguments, but only
+ * if they are not the special quote values (cause expand_arg
+ * changes memory).
+ */
+
+ if (var->defval && (&quote != var->defval) &&
+ ((retval = _expand_arg(pamh, &(var->defval))) != PAM_SUCCESS)) {
+ return retval;
+ }
+ if (var->override && (&quote != var->override) &&
+ ((retval = _expand_arg(pamh, &(var->override))) != PAM_SUCCESS)) {
+ return retval;
}
- if (itemval && (strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0)) {
- struct passwd *user_entry;
- user_entry = pam_modutil_getpwnam (pamh, itemval);
- if (!user_entry) {
- pam_syslog(pamh, LOG_ERR, "No such user!?");
- return NULL;
+ /* Now its easy */
+
+ if (var->override && *(var->override)) {
+ /* if there is a non-empty string in var->override, we use it */
+ D(("OVERRIDE variable <%s> being used: <%s>", var->name, var->override));
+ var->value = var->override;
+ retval = DEFINE_VAR;
+ } else {
+
+ var->value = var->defval;
+ if (&quote == var->defval) {
+ /*
+ * This means that the empty string was given for defval value
+ * which indicates that a variable should be defined with no value
+ */
+ D(("An empty variable: <%s>", var->name));
+ retval = DEFINE_VAR;
+ } else if (var->defval) {
+ D(("DEFAULT variable <%s> being used: <%s>", var->name, var->defval));
+ retval = DEFINE_VAR;
+ } else {
+ D(("UNDEFINE variable <%s>", var->name));
+ retval = UNDEFINE_VAR;
}
- return (strcmp(name, "SHELL") == 0) ?
- user_entry->pw_shell :
- user_entry->pw_dir;
}
D(("Exit."));
- return itemval;
+ return retval;
+}
+
+static void
+_clean_var(VAR *var)
+{
+ if (var->name) {
+ free(var->name);
+ }
+ if (var->defval && (&quote != var->defval)) {
+ free(var->defval);
+ }
+ if (var->override && (&quote != var->override)) {
+ free(var->override);
+ }
+ var->name = NULL;
+ var->value = NULL; /* never has memory specific to it */
+ var->defval = NULL;
+ var->override = NULL;
+ return;
}
-static int _define_var(pam_handle_t *pamh, int ctrl, VAR *var)
+static int
+_define_var(pam_handle_t *pamh, int ctrl, VAR *var)
{
/* We have a variable to define, this is a simple function */
@@ -749,7 +609,8 @@ static int _define_var(pam_handle_t *pamh, int ctrl, VAR *var)
return retval;
}
-static int _undefine_var(pam_handle_t *pamh, int ctrl, VAR *var)
+static int
+_undefine_var(pam_handle_t *pamh, int ctrl, VAR *var)
{
/* We have a variable to undefine, this is a simple function */
@@ -760,25 +621,159 @@ static int _undefine_var(pam_handle_t *pamh, int ctrl, VAR *var)
return pam_putenv(pamh, var->name);
}
-static void _clean_var(VAR *var)
+static int
+_parse_config_file(pam_handle_t *pamh, int ctrl, const char *file)
{
- if (var->name) {
- free(var->name);
+ int retval;
+ char buffer[BUF_SIZE];
+ FILE *conf;
+ VAR Var, *var=&Var;
+
+ D(("Called."));
+
+ var->name=NULL; var->defval=NULL; var->override=NULL;
+
+ D(("Config file name is: %s", file));
+
+ /*
+ * Lets try to open the config file, parse it and process
+ * any variables found.
+ */
+
+ if ((conf = fopen(file,"r")) == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to open config file: %s: %m", file);
+ return PAM_IGNORE;
}
- if (var->defval && (&quote != var->defval)) {
- free(var->defval);
+
+ /* _pam_assemble_line will provide a complete line from the config file,
+ * with all comments removed and any escaped newlines fixed up
+ */
+
+ while (( retval = _assemble_line(conf, buffer, BUF_SIZE)) > 0) {
+ D(("Read line: %s", buffer));
+
+ if ((retval = _parse_line(pamh, buffer, var)) == GOOD_LINE) {
+ retval = _check_var(pamh, var);
+
+ if (DEFINE_VAR == retval) {
+ retval = _define_var(pamh, ctrl, var);
+
+ } else if (UNDEFINE_VAR == retval) {
+ retval = _undefine_var(pamh, ctrl, var);
+ }
+ }
+ if (PAM_SUCCESS != retval && ILLEGAL_VAR != retval
+ && BAD_LINE != retval && PAM_BAD_ITEM != retval) break;
+
+ _clean_var(var);
+
+ } /* while */
+
+ (void) fclose(conf);
+
+ /* tidy up */
+ _clean_var(var); /* We could have got here prematurely,
+ * this is safe though */
+ D(("Exit."));
+ return (retval != 0 ? PAM_ABORT : PAM_SUCCESS);
+}
+
+static int
+_parse_env_file(pam_handle_t *pamh, int ctrl, const char *file)
+{
+ int retval=PAM_SUCCESS, i, t;
+ char buffer[BUF_SIZE], *key, *mark;
+ FILE *conf;
+
+ D(("Env file name is: %s", file));
+
+ if ((conf = fopen(file,"r")) == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to open env file: %s: %m", file);
+ return PAM_IGNORE;
}
- if (var->override && (&quote != var->override)) {
- free(var->override);
+
+ while (_assemble_line(conf, buffer, BUF_SIZE) > 0) {
+ D(("Read line: %s", buffer));
+ key = buffer;
+
+ /* skip leading white space */
+ key += strspn(key, " \n\t");
+
+ /* skip blanks lines and comments */
+ if (key[0] == '#')
+ continue;
+
+ /* skip over "export " if present so we can be compat with
+ bash type declarations */
+ if (strncmp(key, "export ", (size_t) 7) == 0)
+ key += 7;
+
+ /* now find the end of value */
+ mark = key;
+ while(mark[0] != '\n' && mark[0] != '#' && mark[0] != '\0')
+ mark++;
+ if (mark[0] != '\0')
+ mark[0] = '\0';
+
+ /*
+ * sanity check, the key must be alphanumeric
+ */
+
+ if (key[0] == '=') {
+ pam_syslog(pamh, LOG_ERR,
+ "missing key name '%s' in %s', ignoring",
+ key, file);
+ continue;
+ }
+
+ for ( i = 0 ; key[i] != '=' && key[i] != '\0' ; i++ )
+ if (!isalnum(key[i]) && key[i] != '_') {
+ pam_syslog(pamh, LOG_ERR,
+ "non-alphanumeric key '%s' in %s', ignoring",
+ key, file);
+ break;
+ }
+ /* non-alphanumeric key, ignore this line */
+ if (key[i] != '=' && key[i] != '\0')
+ continue;
+
+ /* now we try to be smart about quotes around the value,
+ but not too smart, we can't get all fancy with escaped
+ values like bash */
+ if (key[i] == '=' && (key[++i] == '\"' || key[i] == '\'')) {
+ for ( t = i+1 ; key[t] != '\0' ; t++)
+ if (key[t] != '\"' && key[t] != '\'')
+ key[i++] = key[t];
+ else if (key[t+1] != '\0')
+ key[i++] = key[t];
+ key[i] = '\0';
+ }
+
+ /* if this is a request to delete a variable, check that it's
+ actually set first, so we don't get a vague error back from
+ pam_putenv() */
+ for (i = 0; key[i] != '=' && key[i] != '\0'; i++);
+
+ if (key[i] == '\0' && !pam_getenv(pamh,key))
+ continue;
+
+ /* set the env var, if it fails, we break out of the loop */
+ retval = pam_putenv(pamh, key);
+ if (retval != PAM_SUCCESS) {
+ D(("error setting env \"%s\"", key));
+ break;
+ } else if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "pam_putenv(\"%s\")", key);
+ }
}
- var->name = NULL;
- var->value = NULL; /* never has memory specific to it */
- var->defval = NULL;
- var->override = NULL;
- return;
-}
+ (void) fclose(conf);
+ /* tidy up */
+ D(("Exit."));
+ return retval;
+}
/* --- authentication management functions (only) --- */