diff options
author | Steve Langasek <steve.langasek@ubuntu.com> | 2019-01-03 12:48:14 -0800 |
---|---|---|
committer | Steve Langasek <steve.langasek@ubuntu.com> | 2019-01-03 12:48:14 -0800 |
commit | d5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c (patch) | |
tree | ba5654cffacfd2002eefc5bc3764a7971afff1dc /Linux-PAM/modules/pam_time/pam_time.c | |
parent | 4c51da22e068907adb7857d50f5109a467c94d7c (diff) | |
parent | 7cbfa335c57d068d59508c844f3957165cccfb9b (diff) | |
download | pam-d5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c.tar.gz pam-d5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c.tar.bz2 pam-d5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c.zip |
New upstream version 0.99.7.1
Diffstat (limited to 'Linux-PAM/modules/pam_time/pam_time.c')
-rw-r--r-- | Linux-PAM/modules/pam_time/pam_time.c | 193 |
1 files changed, 101 insertions, 92 deletions
diff --git a/Linux-PAM/modules/pam_time/pam_time.c b/Linux-PAM/modules/pam_time/pam_time.c index c04180f2..43b716f0 100644 --- a/Linux-PAM/modules/pam_time/pam_time.c +++ b/Linux-PAM/modules/pam_time/pam_time.c @@ -1,19 +1,12 @@ /* pam_time module */ /* - * $Id: pam_time.c,v 1.5 2004/09/22 09:37:50 kukuk Exp $ - * * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/6/22 * (File syntax and much other inspiration from the shadow package * shadow-960129) */ -static const char rcsid[] = -"$Id: pam_time.c,v 1.5 2004/09/22 09:37:50 kukuk Exp $;\n" -"\t\tVersion 0.22 for Linux-PAM\n" -"Copyright (C) Andrew G. Morgan 1996 <morgan@linux.kernel.org>\n"; - -#include <security/_pam_aconf.h> +#include "config.h" #include <sys/file.h> #include <stdio.h> @@ -27,23 +20,18 @@ static const char rcsid[] = #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#include <netdb.h> -#ifdef DEFAULT_CONF_FILE -# define PAM_TIME_CONF DEFAULT_CONF_FILE /* from external define */ -#else -# define PAM_TIME_CONF "/etc/security/time.conf" -#endif #define PAM_TIME_BUFLEN 1000 #define FIELD_SEPARATOR ';' /* this is new as of .02 */ -#ifdef TRUE -# undef TRUE -#endif -#ifdef FALSE -# undef FALSE +#ifndef TRUE +# define TRUE 1 +#endif +#ifndef FALSE +# define FALSE 0 #endif -typedef enum { FALSE, TRUE } boolean; typedef enum { AND, OR } operator; /* @@ -57,21 +45,12 @@ typedef enum { AND, OR } operator; #include <security/_pam_macros.h> #include <security/pam_modules.h> +#include <security/pam_ext.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_time", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(LOG_CRIT, format, args); - va_end(args); - closelog(); -} - -static void shift_bytes(char *mem, int from, int by) +static void +shift_bytes(char *mem, int from, int by) { while (by-- > 0) { *mem = mem[from]; @@ -79,14 +58,15 @@ static void shift_bytes(char *mem, int from, int by) } } -static int read_field(int fd, char **buf, int *from, int *to) +static int +read_field(pam_handle_t *pamh, int fd, char **buf, int *from, int *to) { /* is buf set ? */ if (! *buf) { *buf = (char *) malloc(PAM_TIME_BUFLEN); if (! *buf) { - _log_err("out of memory"); + pam_syslog(pamh, LOG_ERR, "out of memory"); D(("no memory")); return -1; } @@ -97,7 +77,7 @@ static int read_field(int fd, char **buf, int *from, int *to) /* do we have a file open ? return error */ if (fd < 0 && *to <= 0) { - _log_err( PAM_TIME_CONF " not opened"); + pam_syslog(pamh, LOG_ERR, "error opening %s: %m", PAM_TIME_CONF); memset(*buf, 0, PAM_TIME_BUFLEN); _pam_drop(*buf); return -1; @@ -126,7 +106,7 @@ static int read_field(int fd, char **buf, int *from, int *to) i = read(fd, *to + *buf, PAM_TIME_BUFLEN - *to); if (i < 0) { - _log_err("error reading " PAM_TIME_CONF); + pam_syslog(pamh, LOG_ERR, "error reading %s: %m", PAM_TIME_CONF); close(fd); return -1; } else if (!i) { @@ -134,7 +114,7 @@ static int read_field(int fd, char **buf, int *from, int *to) fd = -1; /* end of file reached */ } else *to += i; - + /* * contract the buffer. Delete any comments, and replace all * multiple spaces with single commas @@ -165,8 +145,9 @@ static int read_field(int fd, char **buf, int *from, int *to) *to -= j-i; ++i; } else { - _log_err("internal error in " __FILE__ - " at line %d", __LINE__ ); + pam_syslog(pamh, LOG_CRIT, + "internal error in file %s at line %d", + __FILE__, __LINE__); close(fd); return -1; } @@ -229,13 +210,13 @@ static int read_field(int fd, char **buf, int *from, int *to) /* read a member from a field */ -static int logic_member(const char *string, int *at) +static int +logic_member(const char *string, int *at) { - int len,c,to; + int c,to; int done=0; int token=0; - len=0; to=*at; do { c = string[to++]; @@ -258,7 +239,7 @@ static int logic_member(const char *string, int *at) default: if (isalpha(c) || c == '*' || isdigit(c) || c == '_' - || c == '-' || c == '.' || c == '/') { + || c == '-' || c == '.' || c == '/' || c == ':') { token = 1; } else if (token) { --to; @@ -274,11 +255,12 @@ static int logic_member(const char *string, int *at) typedef enum { VAL, OP } expect; -static boolean logic_field(const void *me, const char *x, int rule, - boolean (*agrees)(const void *, const char * - , int, int)) +static int +logic_field(pam_handle_t *pamh, const void *me, const char *x, int rule, + int (*agrees)(pam_handle_t *pamh, + const void *, const char *, int, int)) { - boolean left=FALSE, right, not=FALSE; + int left=FALSE, right, not=FALSE; operator oper=OR; int at=0, l; expect next=VAL; @@ -289,15 +271,18 @@ static boolean logic_field(const void *me, const char *x, int rule, if (next == VAL) { if (c == '!') not = !not; - else if (isalpha(c) || c == '*') { - right = not ^ agrees(me, x+at, l, rule); + else if (isalpha(c) || c == '*' || isdigit(c) || c == '_' + || c == '-' || c == '.' || c == '/' || c == ':') { + right = not ^ agrees(pamh, me, x+at, l, rule); if (oper == AND) left &= right; else left |= right; next = OP; } else { - _log_err("garbled syntax; expected name (rule #%d)", rule); + pam_syslog(pamh, LOG_ERR, + "garbled syntax; expected name (rule #%d)", + rule); return FALSE; } } else { /* OP */ @@ -309,8 +294,9 @@ static boolean logic_field(const void *me, const char *x, int rule, oper = OR; break; default: - _log_err("garbled syntax; expected & or | (rule #%d)" - , rule); + pam_syslog(pamh, LOG_ERR, + "garbled syntax; expected & or | (rule #%d)", + rule); D(("%c at %d",c,at)); return FALSE; } @@ -322,7 +308,9 @@ static boolean logic_field(const void *me, const char *x, int rule, return left; } -static boolean is_same(const void *A, const char *b, int len, int rule) +static int +is_same(pam_handle_t *pamh UNUSED, const void *A, const char *b, + int len, int rule UNUSED) { int i; const char *a; @@ -344,10 +332,10 @@ typedef struct { int minute; /* integer, hour*100+minute for now */ } TIME; -struct day { +static struct day { const char *d; int bit; -} static const days[11] = { +} const days[11] = { { "su", 01 }, { "mo", 02 }, { "tu", 04 }, @@ -361,7 +349,8 @@ struct day { { NULL, 0 } }; -static TIME time_now(void) +static TIME +time_now(void) { struct tm *local; time_t the_time; @@ -377,9 +366,11 @@ static TIME time_now(void) } /* take the current date and see if the range "date" passes it */ -static boolean check_time(const void *AT, const char *times, int len, int rule) +static int +check_time(pam_handle_t *pamh, const void *AT, const char *times, + int len, int rule) { - boolean not,pass; + int not,pass; int marked_day, time_start, time_end; const TIME *at; int i,j=0; @@ -389,7 +380,9 @@ static boolean check_time(const void *AT, const char *times, int len, int rule) if (times == NULL) { /* this should not happen */ - _log_err("internal error: " __FILE__ " line %d", __LINE__); + pam_syslog(pamh, LOG_CRIT, + "internal error in file %s at line %d", + __FILE__, __LINE__); return FALSE; } @@ -413,13 +406,13 @@ static boolean check_time(const void *AT, const char *times, int len, int rule) } j += 2; if (this_day == -1) { - _log_err("bad day specified (rule #%d)", rule); + pam_syslog(pamh, LOG_ERR, "bad day specified (rule #%d)", rule); return FALSE; } marked_day ^= this_day; } if (marked_day == 0) { - _log_err("no day specified"); + pam_syslog(pamh, LOG_ERR, "no day specified"); return FALSE; } D(("day range = 0%o", marked_day)); @@ -443,7 +436,7 @@ static boolean check_time(const void *AT, const char *times, int len, int rule) D(("i=%d, time_end=%d, times[j]='%c'", i, time_end, times[j])); if (i != 5 || time_end == -1) { - _log_err("no/bad times specified (rule #%d)", rule); + pam_syslog(pamh, LOG_ERR, "no/bad times specified (rule #%d)", rule); return TRUE; } D(("times(%d to %d)", time_start,time_end)); @@ -476,8 +469,9 @@ static boolean check_time(const void *AT, const char *times, int len, int rule) return (not ^ pass); } -static int check_account(const char *service - , const char *tty, const char *user) +static int +check_account(pam_handle_t *pamh, const char *service, + const char *tty, const char *user) { int from=0,to=0,fd=-1; char *buffer=NULL; @@ -487,11 +481,11 @@ static int check_account(const char *service here_and_now = time_now(); /* find current time */ do { - boolean good=TRUE,intime; + int good=TRUE,intime; /* here we get the service name field */ - fd = read_field(fd,&buffer,&from,&to); + fd = read_field(pamh, fd, &buffer, &from, &to); if (!buffer || !buffer[0]) { /* empty line .. ? */ @@ -499,43 +493,51 @@ static int check_account(const char *service } ++count; - good = logic_field(service, buffer, count, is_same); + good = logic_field(pamh, service, buffer, count, is_same); D(("with service: %s", good ? "passes":"fails" )); /* here we get the terminal name field */ - fd = read_field(fd,&buffer,&from,&to); + fd = read_field(pamh, fd, &buffer, &from, &to); if (!buffer || !buffer[0]) { - _log_err(PAM_TIME_CONF "; no tty entry #%d", count); + pam_syslog(pamh, LOG_ERR, + "%s: no tty entry #%d", PAM_TIME_CONF, count); continue; } - good &= logic_field(tty, buffer, count, is_same); + good &= logic_field(pamh, tty, buffer, count, is_same); D(("with tty: %s", good ? "passes":"fails" )); /* here we get the username field */ - fd = read_field(fd,&buffer,&from,&to); + fd = read_field(pamh, fd, &buffer, &from, &to); if (!buffer || !buffer[0]) { - _log_err(PAM_TIME_CONF "; no user entry #%d", count); + pam_syslog(pamh, LOG_ERR, + "%s: no user entry #%d", PAM_TIME_CONF, count); continue; } - good &= logic_field(user, buffer, count, is_same); + /* If buffer starts with @, we are using netgroups */ + if (buffer[0] == '@') + good &= innetgr (&buffer[1], NULL, user, NULL); + else + good &= logic_field(pamh, user, buffer, count, is_same); D(("with user: %s", good ? "passes":"fails" )); /* here we get the time field */ - fd = read_field(fd,&buffer,&from,&to); + fd = read_field(pamh, fd, &buffer, &from, &to); if (!buffer || !buffer[0]) { - _log_err(PAM_TIME_CONF "; no time entry #%d", count); + pam_syslog(pamh, LOG_ERR, + "%s: no time entry #%d", PAM_TIME_CONF, count); continue; } - intime = logic_field(&here_and_now, buffer, count, check_time); + intime = logic_field(pamh, &here_and_now, buffer, count, check_time); D(("with time: %s", intime ? "passes":"fails" )); - fd = read_field(fd,&buffer,&from,&to); + fd = read_field(pamh, fd, &buffer, &from, &to); if (buffer && buffer[0]) { - _log_err(PAM_TIME_CONF "; poorly terminated rule #%d", count); + pam_syslog(pamh, LOG_ERR, + "%s: poorly terminated rule #%d", PAM_TIME_CONF, count); continue; } @@ -555,17 +557,19 @@ static int check_account(const char *service /* --- public account management functions --- */ -PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc - ,const char **argv) +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, + int argc UNUSED, const char **argv UNUSED) { - const char *service=NULL, *tty=NULL; + const void *service=NULL, *void_tty=NULL; + const char *tty; const char *user=NULL; /* set service name */ - if (pam_get_item(pamh, PAM_SERVICE, (const void **)&service) + if (pam_get_item(pamh, PAM_SERVICE, &service) != PAM_SUCCESS || service == NULL) { - _log_err("cannot find the current service name"); + pam_syslog(pamh, LOG_ERR, "cannot find the current service name"); return PAM_ABORT; } @@ -573,28 +577,33 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL || *user == '\0') { - _log_err("cannot determine the user's name"); + pam_syslog(pamh, LOG_ERR, "can not get the username"); return PAM_USER_UNKNOWN; } /* set tty name */ - if (pam_get_item(pamh, PAM_TTY, (const void **)&tty) != PAM_SUCCESS - || tty == NULL) { + if (pam_get_item(pamh, PAM_TTY, &void_tty) != PAM_SUCCESS + || void_tty == NULL) { D(("PAM_TTY not set, probing stdin")); tty = ttyname(STDIN_FILENO); if (tty == NULL) { - _log_err("couldn't get the tty name"); - return PAM_ABORT; + tty = ""; } if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) { - _log_err("couldn't set tty name"); + pam_syslog(pamh, LOG_ERR, "couldn't set tty name"); return PAM_ABORT; } } - - if (strncmp("/dev/",tty,5) == 0) { /* strip leading /dev/ */ - tty += 5; + else + tty = void_tty; + + if (tty[0] == '/') { /* full path */ + const char *t; + tty++; + if ((t = strchr(tty, '/')) != NULL) { + tty = t + 1; + } } /* good, now we have the service name, the user and the terminal name */ @@ -603,7 +612,7 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc D(("user=%s", user)); D(("tty=%s", tty)); - return check_account(service,tty,user); + return check_account(pamh, service, tty, user); } /* end of module definition */ |