]> granicus.if.org Git - linux-pam/commitdiff
Relevant BUGIDs: 111927, 117240
authorAndrew G. Morgan <morgan@kernel.org>
Sat, 25 Nov 2000 01:48:05 +0000 (01:48 +0000)
committerAndrew G. Morgan <morgan@kernel.org>
Sat, 25 Nov 2000 01:48:05 +0000 (01:48 +0000)
Purpose of commit: new feature

Commit summary:
---------------
Added accessconf= option to the module to override the
default access.conf file.
Feature request from Aldrin Martoq and Meelis Roos.

CHANGELOG
modules/pam_access/README
modules/pam_access/pam_access.c

index 2420907cb619227d2efcd2d1e35841b581430976..3be5741b540c03b698979beef082a630210303df 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -35,6 +35,7 @@ Where you should replace XXXXX with a bug-id.
 0.73: please submit patches for this section with actual code/doc
       patches!
 
+* added accessconf=<filename> feature to pam_access - request from Aldrin Martoq (Bug 111927 - agmorgan)
 * fix for pam_limit module not dealing with all limits Adam J. Richter
   (Bug 119554 - agmorgan)
 * comment fix describing fail_delay callback in _pam_types.h (Bug
index df10c269ec0421369c9acedb7c254ae975d4f7c5..ddd4725f0e042ae7b52d3dd5ce38e70f5dd01dfd 100644 (file)
@@ -1,4 +1,8 @@
-# Description of its configuration file (/etc/security/access.conf):
+# Description of its configuration file
+#
+# (The default config file is "/etc/security/access.conf". This
+#  default can be overridden with a module config argument
+#  'accessfile=<full-path>'):
 #
 # Login access control table.
 # 
index b87226463711698ac9fc46ee80a4b4f418514b3c..b13c515fb6e4cee23e97a8519162b7d63d0bd53b 100644 (file)
@@ -43,25 +43,6 @@ extern int gethostname(char *name, size_t len);
 #include <security/_pam_macros.h>
 #include <security/pam_modules.h>
 
-/* --- static functions for checking whether the user should be let in --- */
-
-static void _log_err(const char *format, ... )
-{
-    va_list args;
-
-    va_start(args, format);
-    openlog("pam_access", LOG_CONS|LOG_PID, LOG_AUTH);
-    vsyslog(LOG_ERR, format, args);
-    va_end(args);
-    closelog();
-}
-
-#ifdef DEFAULT_CONF_FILE
-# define PAM_ACCESS_CONFIG DEFAULT_CONF_FILE
-#else
-# define PAM_ACCESS_CONFIG "/etc/security/access.conf"
-#endif
-
 int strcasecmp(const char *s1, const char *s2);
 
 /* login_access.c from logdaemon-5.6 with several changes by A.Nogin: */
@@ -78,12 +59,18 @@ int strcasecmp(const char *s1, const char *s2);
 #if !defined(MAXHOSTNAMELEN) || (MAXHOSTNAMELEN < 64)
 #undef MAXHOSTNAMELEN
 #define MAXHOSTNAMELEN 256
+#endif
+
+#ifdef DEFAULT_CONF_FILE
+# define PAM_ACCESS_CONFIG DEFAULT_CONF_FILE
+#else
+# define PAM_ACCESS_CONFIG "/etc/security/access.conf"
 #endif
 
  /* Delimiters for fields and for lists of users, ttys or hosts. */
 
-static char fs[] = ":";                        /* field separator */
-static char sep[] = ", \t";            /* list-element separator */
+static const char fs[] = ":";                  /* field separator */
+static const char sep[] = ", \t";              /* list-element separator */
 
  /* Constants to be used in assignments only, not in comparisons... */
 
@@ -97,8 +84,50 @@ static char sep[] = ", \t";          /* list-element separator */
 struct login_info {
     struct passwd *user;
     char   *from;
+    const char *config_file;
+    const char *service;
 };
 
+/* --- static functions for checking whether the user should be let in --- */
+
+static void _log_err(const char *format, ... )
+{
+    va_list args;
+
+    va_start(args, format);
+    openlog("pam_access", LOG_CONS|LOG_PID, LOG_AUTH);
+    vsyslog(LOG_ERR, format, args);
+    va_end(args);
+    closelog();
+}
+
+/* Parse module config arguments */
+
+static int parse_args(struct login_info *loginfo, int argc, const char **argv)
+{
+    int i;
+
+    for (i=0; i<argc; ++i) {
+       if (!strncmp("accessfile=", argv[i], 11)) {
+           FILE *fp = fopen(11 + argv[i], "r");
+
+           if (fp) {
+               loginfo->config_file = 11 + argv[i];
+               fclose(fp);
+           } else {
+               _log_err("for service [%s] failed to open accessfile=[%s]"
+                        , loginfo->service, 11 + argv[i]);
+               return 0;
+           }
+           
+       } else {
+           _log_err("unrecognized option [%s]", argv[i]);
+       }
+    }
+    
+    return 1;  /* OK */
+}
+
 typedef int match_func (char *, struct login_info *); 
 
 static int list_match (char *, struct login_info *,
@@ -109,9 +138,8 @@ static int string_match (char *, char *);
 
 /* login_access - match username/group and host/tty with access control file */
 
-static int login_access(struct passwd *user, char *from)
+static int login_access(struct login_info *item)
 {
-    struct login_info item;
     FILE   *fp;
     char    line[BUFSIZ];
     char   *perm;                      /* becomes permission field */
@@ -121,12 +149,6 @@ static int login_access(struct passwd *user, char *from)
     int     end;
     int     lineno = 0;                        /* for diagnostics */
 
-    /*
-     * Bundle up the arguments to avoid unnecessary clumsiness lateron.
-     */
-    item.user = user;
-    item.from = from;
-
     /*
      * Process the table one line at a time and stop at the first match.
      * Blank lines and lines that begin with a '#' character are ignored.
@@ -161,8 +183,8 @@ static int login_access(struct passwd *user, char *from)
                _log_err("%s: line %d: bad first field", PAM_ACCESS_CONFIG, lineno);
                continue;
            }
-           match = (list_match(froms, &item, from_match)
-                    && list_match(users, &item, user_match));
+           match = (list_match(froms, item, from_match)
+                    && list_match(users, item, user_match));
        }
        (void) fclose(fp);
     } else if (errno != ENOENT) {
@@ -357,10 +379,17 @@ int strcasecmp(const char *s1, const char *s2)
 PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc
                     ,const char **argv)
 {
-    const char *user=NULL;
+    struct login_info loginfo;
+    const char *user=NULL, *service=NULL;
     char *from=NULL;
     struct passwd *user_pw;
 
+    if ((pam_get_item(pamh, PAM_SERVICE, (const void **)&service)
+       != PAM_SUCCESS) || (service == NULL) || (*service == ' ')) {
+       _log_err("cannot find the service name");
+       return PAM_ABORT;
+    }
+
     /* set username */
 
     if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL
@@ -399,8 +428,27 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc
         }
 
     }
+
     if ((user_pw=getpwnam(user))==NULL) return (PAM_USER_UNKNOWN);
-    if (login_access(user_pw,from)) return (PAM_SUCCESS); else {
+
+    /*
+     * Bundle up the arguments to avoid unnecessary clumsiness lateron.
+     */
+    loginfo.user = user_pw;
+    loginfo.from = from;
+    loginfo.service = service;
+    loginfo.config_file = PAM_ACCESS_CONFIG;
+
+    /* parse the argument list */
+
+    if (!parse_args(&loginfo, argc, argv)) {
+       _log_err("failed to parse the module arguments");
+       return PAM_ABORT;
+    }
+
+    if (login_access(&loginfo)) {
+       return (PAM_SUCCESS);
+    } else {
        _log_err("access denied for user `%s' from `%s'",user,from);
        return (PAM_PERM_DENIED);
     }