summaryrefslogtreecommitdiff
path: root/contrib/libpam/modules/pam_access/pam_access.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libpam/modules/pam_access/pam_access.c')
-rw-r--r--contrib/libpam/modules/pam_access/pam_access.c153
1 files changed, 111 insertions, 42 deletions
diff --git a/contrib/libpam/modules/pam_access/pam_access.c b/contrib/libpam/modules/pam_access/pam_access.c
index 121333928a26..87ad708d81ed 100644
--- a/contrib/libpam/modules/pam_access/pam_access.c
+++ b/contrib/libpam/modules/pam_access/pam_access.c
@@ -5,12 +5,27 @@
* (I took login_access from logdaemon-5.6 and converted it to PAM
* using parts of pam_time code.)
*
+ ************************************************************************
+ * Copyright message from logdaemon-5.6 (original file name DISCLAIMER)
+ ************************************************************************
+ * Copyright 1995 by Wietse Venema. All rights reserved. Individual files
+ * may be covered by other copyrights (as noted in the file itself.)
+ *
+ * This material was originally written and compiled by Wietse Venema at
+ * Eindhoven University of Technology, The Netherlands, in 1990, 1991,
+ * 1992, 1993, 1994 and 1995.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this entire copyright notice is duplicated in all such
+ * copies.
+ *
+ * This software is provided "as is" and without any expressed or implied
+ * warranties, including, without limitation, the implied warranties of
+ * merchantibility and fitness for any particular purpose.
+ *************************************************************************
*/
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdio.h>
#include <stdlib.h>
@@ -46,21 +61,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();
-}
-
-#define PAM_ACCESS_CONFIG CONFILE
-
int strcasecmp(const char *s1, const char *s2);
/* login_access.c from logdaemon-5.6 with several changes by A.Nogin: */
@@ -79,10 +79,16 @@ int strcasecmp(const char *s1, const char *s2);
#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... */
@@ -96,8 +102,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 *,
@@ -108,23 +156,16 @@ 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 */
- char *users; /* becomes list of login names */
- char *froms; /* becomes list of terminals or hosts */
+ char *perm; /* becomes permission field */
+ char *users; /* becomes list of login names */
+ char *froms; /* becomes list of terminals or hosts */
int match = NO;
int end;
- int lineno = 0; /* for diagnostics */
-
- /*
- * Bundle up the arguments to avoid unnecessary clumsiness lateron.
- */
- item.user = user;
- item.from = from;
+ int lineno = 0; /* for diagnostics */
/*
* Process the table one line at a time and stop at the first match.
@@ -134,12 +175,12 @@ static int login_access(struct passwd *user, char *from)
* non-existing table means no access control.
*/
- if ((fp = fopen(PAM_ACCESS_CONFIG, "r"))!=NULL) {
+ if ((fp = fopen(item->config_file, "r"))!=NULL) {
while (!match && fgets(line, sizeof(line), fp)) {
lineno++;
if (line[end = strlen(line) - 1] != '\n') {
_log_err("%s: line %d: missing newline or line too long",
- PAM_ACCESS_CONFIG, lineno);
+ item->config_file, lineno);
continue;
}
if (line[0] == '#')
@@ -153,19 +194,21 @@ static int login_access(struct passwd *user, char *from)
|| !(users = strtok((char *) 0, fs))
|| !(froms = strtok((char *) 0, fs))
|| strtok((char *) 0, fs)) {
- _log_err("%s: line %d: bad field count", PAM_ACCESS_CONFIG, lineno);
+ _log_err("%s: line %d: bad field count",
+ item->config_file, lineno);
continue;
}
if (perm[0] != '+' && perm[0] != '-') {
- _log_err("%s: line %d: bad first field", PAM_ACCESS_CONFIG, lineno);
+ _log_err("%s: line %d: bad first field",
+ item->config_file, 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) {
- _log_err("cannot open %s: %m", PAM_ACCESS_CONFIG);
+ _log_err("cannot open %s: %m", item->config_file);
}
return (match == 0 || (line[0] == '+'));
}
@@ -356,10 +399,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
@@ -398,8 +448,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 later on.
+ */
+ 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);
}