pam_access patch part 4 of 5
patches for check_login_access test program
p07-Linux-PAM-0.99.2.1-modules-pam_access-check_login_access.8
p08-Linux-PAM-0.99.2.1-modules-pam_access-check_login_access.c
short description:
-----------------
These patches enable:
* convert_hostname feature
* IPv4(/) IPv6 support
* the network(address) / netmask feature
* external helper feature
* manual support
best regards,
mike
-----------------------------------------------------------------------------
Mike Becher Mike.Becher@xxxxxxxxxxxxxxx
Leibniz-Rechenzentrum der http://www.lrz.de
Bayerischen Akademie der Wissenschaften phone: +49-89-289-28721
Gruppe Hochleistungssysteme fax: +49-89-280-9460
Barer Strasse 21
D-80333 Muenchen
Germany
-----------------------------------------------------------------------------
diff -u -r -N Linux-PAM-0.99.2.1.orig/modules/pam_access/check_login_access.8 Linux-PAM-0.99.2.1/modules/pam_access/check_login_access.8
--- Linux-PAM-0.99.2.1.orig/modules/pam_access/check_login_access.8 1970-01-01 01:00:00.000000000 +0100
+++ Linux-PAM-0.99.2.1/modules/pam_access/check_login_access.8 2006-01-02 17:24:32.000000000 +0100
@@ -0,0 +1,84 @@
+.\" -*- nroff -*-
+.\" @(#)check_login_access.8 1.0.4 2006/01/02 15:06:34 mibe
+.\"
+.TH check_login_access 8 "2 January 2006" "Version 1.0.4" "Reference Manual"
+
+.SH NAME
+check_login_access \- Helper tool to verify access rights of a user to a service
+
+.SH SYNOPSIS
+.B check_login_access
+.RB [ "\-W \fIMODULE_OPTIONS\fP" ]
+.I user
+.I from
+
+.SH DESCRIPTION
+The
+.B check_login_access
+helper tool is for testing if a user is allowed or forbidden to get
+access to a host or service depending on rules supplied by either
+an access control table which will be read from config file or by
+calling an external program that delivers this answer or both.
+It can also be used to check if syntax of access control file is
+correct.
+
+.SH OPTIONS
+The following options may be specified on command line:
+.TP
+.B \-h
+Print help message and exit.
+.TP
+.B \-W \fIMODULE_OPTIONS
+Comma separated list of options that can be used by PAM module
+.BR pam_access (8) .
+Please have a look at manual page
+.BR pam_access (8)
+to find out what options you can use.
+
+.B Comment:
+If you want use PAM module options with arguments you
+.B MUST
+use the version of options with equal signs.
+
+.SH EXAMPLES
+Here are some examples of usage:
+
+Check if user
+.B john
+gets access from host
+.B localhost
+using the default access control file:
+
+ check_login_access john localhost
+
+Check if user
+.B john
+gets access from host
+.B localhost
+using the access control file
+.B /path/to/other/access.conf
+and enable debugging:
+
+ check_login_access -W file=/path/to/other/access.conf,debug john localhost
+
+Check if user
+.B john
+gets access from host
+.B localhost
+using the default access control file,
+convert hostname to address,
+ask helper program
+.B /path/to/verify_access
+and enable debugging output:
+
+ check_login_access -W convert_hostname,helperfile=/path/to/verify_access,debug john localhost
+
+.SH SEE ALSO
+.BR access.conf (5) ,
+.BR login.access (5) ,
+.BR pam_access (8) ,
+.BR pam.d (8) ,
+and
+.BR pam (8)
+.SH AUTHOR
+Mike Becher <mike.becher@xxxxxxxxxxxxxxx>
diff -u -r -N Linux-PAM-0.99.2.1.orig/modules/pam_access/check_login_access.c Linux-PAM-0.99.2.1/modules/pam_access/check_login_access.c
--- Linux-PAM-0.99.2.1.orig/modules/pam_access/check_login_access.c 1970-01-01 01:00:00.000000000 +0100
+++ Linux-PAM-0.99.2.1/modules/pam_access/check_login_access.c 2006-01-03 19:38:28.000000000 +0100
@@ -0,0 +1,274 @@
+#define PAM_ACCESS_COMPILE_PROGRAM 1
+
+#include "pam_access.c"
+
+static void
+usage(const char *prog_name, unsigned char use_stderr)
+{
+ FILE *out = stderr;
+
+ if (use_stderr == 0) {
+ out = stdout;
+ }
+ fprintf(out, "usage: %s [options] user from\n", prog_name);
+ fprintf(out,
+ "options:\n"
+ " -h\n"
+ " Print this message and exit.\n"
+ " -W \"pam_access module options\"\n"
+ " Comma separated list of options that can be used by PAM"
+ " module pam_access.\n Please have a look at manual page "
+#if defined(COMPILE_AS_LOGIN_ACCESS)
+ "pam_login_access(8)"
+#else
+ "pam_access(8)"
+#endif
+ ".\n\n Access control table that will be used by default will be"
+ " read from file:\n"
+ " %s\n\n",
+ pam_access_default_config_file);
+ return;
+}
+
+static int
+try(struct passwd *user, const char *from, const char *filename)
+{
+ int retval;
+
+ if (filename == NULL) {
+ fprintf(stderr,
+ "error: There was no login access filename specified.\n"
+ );
+ return(-1);
+ }
+
+ retval = pam_access_login_access(0, user, from, filename);
+
+ if (retval < 0) {
+ fprintf(stderr,
+ "internal error: Could not verify access rights for "
+ "user %s (gid %d) from \"%s\" -> access %s\n",
+ user->pw_name, user->pw_gid, from,
+ (pam_access_opt_onerr == SUCCESS) ? "granted" : "denied"
+ );
+ } else {
+ fprintf(stdout,
+ " User %s (gid %d) from \"%s\" -> access %s\n",
+ user->pw_name, user->pw_gid, from,
+ (retval == YES) ? "granted" : "denied"
+ );
+ return(0);
+ }
+
+ return(retval);
+}
+
+static char **
+split_into_argv(char *opt_str, int *opt_cnt)
+{
+ char **my_argv = NULL;
+ char *opt_str_cpy = NULL;
+ size_t opt_str_len = 0;
+ int my_argc = 0;
+ char *c_ptr;
+ int i;
+
+ if ((opt_str == NULL) || (opt_cnt == NULL)) {
+ if (opt_cnt != NULL) {
+ *opt_cnt = 0;
+ }
+ return(my_argv);
+ }
+
+ /* copy argument string */
+ opt_str_len = strlen(opt_str);
+ opt_str_cpy = (char *)malloc(sizeof(char) * (opt_str_len + 1));
+ if (opt_str_cpy == NULL) {
+ *opt_cnt = 0;
+ return(my_argv);
+ }
+ strcpy(opt_str_cpy, opt_str);
+
+ /* split array */
+ my_argc = 1;
+ c_ptr = opt_str_cpy;
+ for (c_ptr = strchr(c_ptr, ',');
+ c_ptr != NULL;
+ c_ptr = strchr(c_ptr, ',')) {
+ my_argc++;
+ c_ptr++;
+ }
+
+ my_argv = (char **)malloc(sizeof(char *) * (my_argc + 1));
+ if (my_argv == NULL) {
+ *opt_cnt = 0;
+ free(opt_str_cpy);
+ return(my_argv);
+ }
+
+ c_ptr = opt_str_cpy;
+ my_argv[0] = c_ptr;
+ for (i=1; i <= my_argc; i++) {
+ c_ptr = strchr(c_ptr, ',');
+ if (c_ptr == NULL) {
+ break;
+ }
+ *c_ptr = '\0';
+ c_ptr++;
+ my_argv[i] = c_ptr;
+ }
+ my_argv[i] = NULL;
+
+ *opt_cnt = my_argc;
+ return(my_argv);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *prog_str = argv[0];
+ const char *user_str = NULL;
+ const char *from_str = NULL;
+ const char *my_from_str = NULL;
+ const char *filename = pam_access_default_config_file;
+ struct passwd *user = NULL;
+#ifdef OLD_PROGRAM_STYLE
+ struct hostent *hp = NULL;
+#endif
+ int pam_argc = 0;
+ char **pam_argv = NULL;
+
+ /* call this program with at least 2 additional options */
+ if (argc < 3) {
+ usage(prog_str, 1);
+ exit(1);
+ }
+
+ /* pipe output to stdout */
+ pam_access_opt_msg_to_stdout = YES;
+
+ /* process options */
+ while (1) {
+ int c;
+
+ c = getopt(argc, argv, "hW:");
+ switch (c) {
+ case 'h':
+ usage(prog_str, 0);
+ exit(0);
+ break;
+ case 'W':
+ pam_argv = split_into_argv(optarg, &pam_argc);
+ if (pam_argv == NULL) {
+ fprintf(stderr, "warning: PAM options will be ignored.\n");
+ } else {
+ pam_access_getopt(NULL, pam_argc, (const char **)pam_argv);
+ }
+ break;
+ default:
+ if (optind < (argc - 2)) {
+ fprintf(stderr, "error: No user and/or from was specified.\n");
+ usage(prog_str, 1);
+ exit(1);
+ }
+ user_str = argv[argc - 2];
+ from_str = argv[argc - 1];
+ break;
+ }
+ if (c == -1) {
+ break;
+ }
+
+ }
+
+ /* check if we got a user and from */
+ if (user_str == NULL) {
+ fprintf(stderr, "error: No user was specified.\n");
+ usage(prog_str, 1);
+ if (pam_argv != NULL) {
+ free(pam_argv[0]);
+ free(pam_argv);
+ }
+ exit(1);
+ } else
+ if (from_str == NULL) {
+ fprintf(stderr, "error: No from was specified.\n");
+ usage(prog_str, 1);
+ if (pam_argv != NULL) {
+ free(pam_argv[0]);
+ free(pam_argv);
+ }
+ exit(1);
+ }
+
+ /* set filename of login.access that we should use. */
+ if (pam_access_opt_config_file != NULL) {
+ filename = pam_access_opt_config_file;
+ }
+
+ /* Is this a valid user? */
+ if ((user = getpwnam(user_str)) == 0) {
+ fprintf(stderr, "error: unknown user \"%s\"\n", user_str);
+ if (pam_argv != NULL) {
+ free(pam_argv[0]);
+ free(pam_argv);
+ }
+ exit(1);
+ }
+
+ fprintf(stdout, "info: checking user %s from %s,%s\n",
+ user_str,
+ from_str,
+ convert_hostname(from_str));
+
+ /* module should pipe its output to stdout */
+ pam_access_opt_msg_to_stdout = YES;
+
+#ifdef OLD_PROGRAM_STYLE
+ if ((hp = gethostbyname(from_str)) != 0) {
+#ifdef NEW_INET_SUPPORT
+ static char ipaddr_buf[MAXHOSTNAMELEN + 1] = "";
+#endif /* NEW_INET_SUPPORT */
+
+ fprintf(stdout, "Trying hostname:\n");
+ try(user, hp->h_name, filename);
+ fprintf(stdout, "Trying address:\n");
+ try(user, convert_hostname(hp->h_name), filename);
+
+ while (*hp->h_addr_list) {
+ fprintf(stdout, "Trying other addresses:\n");
+ try(user,
+#ifdef NEW_INET_SUPPORT
+ inet_ntop(hp->h_addrtype, *hp->h_addr_list,
+ (char *)ipaddr_buf, MAXHOSTNAMELEN),
+#else
+ inet_ntoa(*(struct in_addr *) * hp->h_addr_list),
+#endif /* NEW_INET_SUPPORT */
+ filename);
+ hp->h_addr_list++;
+ }
+ } else {
+ fprintf(stdout, "Trying from=\"%s\" string:\n", from_str);
+ try(user, from_str, filename);
+ }
+#else /* OLD_PROGRAM_STYLE */
+ fprintf(stdout, "Trying tty/service/rhost=\"%s\" string ", from_str);
+ if (pam_access_opt_convert_hostname == YES) {
+ static char ipaddr_buf[MAXHOSTNAMELEN + 1] = "";
+ my_from_str = convert_hostname_r(from_str, ipaddr_buf, MAXHOSTNAMELEN);
+ fprintf(stdout, "(converted to tty/service/rhost=\"%s\")", my_from_str);
+ } else {
+ my_from_str = from_str;
+ }
+ fprintf(stdout, "\n");
+
+ try(user, my_from_str, filename);
+#endif /* OLD_PROGRAM_STYLE */
+
+ if (pam_argv != NULL) {
+ free(pam_argv[0]);
+ free(pam_argv);
+ }
+ return (0);
+}
+
_______________________________________________
Pam-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/pam-list