summaryrefslogtreecommitdiff
path: root/modules/pam_group
diff options
context:
space:
mode:
authorSteve Langasek <steve.langasek@ubuntu.com>2019-01-03 12:44:11 -0800
committerSteve Langasek <steve.langasek@ubuntu.com>2019-01-03 12:44:11 -0800
commitefd31890b5ed496a5a00c08a262da240e66a4ddc (patch)
tree22a7aab22b3a491bb58df250d7d6409e0c160bcc /modules/pam_group
parent067affee9267fa0d1c21835182ba639ba33e820f (diff)
New upstream version 0.76
Diffstat (limited to 'modules/pam_group')
-rw-r--r--modules/pam_group/.cvsignore1
-rw-r--r--modules/pam_group/Makefile21
-rw-r--r--modules/pam_group/group.conf60
-rw-r--r--modules/pam_group/pam_group.c856
4 files changed, 0 insertions, 938 deletions
diff --git a/modules/pam_group/.cvsignore b/modules/pam_group/.cvsignore
deleted file mode 100644
index 380a834a..00000000
--- a/modules/pam_group/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-dynamic
diff --git a/modules/pam_group/Makefile b/modules/pam_group/Makefile
deleted file mode 100644
index cb3c4c89..00000000
--- a/modules/pam_group/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# $Id$
-#
-# This Makefile controls a build process of $(TITLE) module for
-# Linux-PAM. You should not modify this Makefile (unless you know
-# what you are doing!).
-#
-
-include ../../Make.Rules
-
-TITLE=pam_group
-LOCAL_CONFILE=./group.conf
-INSTALLED_CONFILE=$(SCONFIGD)/group.conf
-
-DEFS=-DDEFAULT_CONF_FILE=\"$(CONFILE)\"
-CFLAGS += $(DEFS)
-
-MODULE_SIMPLE_INSTALL=bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONFILE)" "$(TITLE)" "$(LOCAL_CONFILE)"
-MODULE_SIMPLE_REMOVE=rm -f $(FAKEROOT)$(INSTALLED_CONFILE)
-MODULE_SIMPLE_CLEAN=rm -f ./.ignore_age
-
-include ../Simple.Rules
diff --git a/modules/pam_group/group.conf b/modules/pam_group/group.conf
deleted file mode 100644
index e721b990..00000000
--- a/modules/pam_group/group.conf
+++ /dev/null
@@ -1,60 +0,0 @@
-##
-## Note, to get this to work as it is currently typed you need
-##
-## 1. to run an application as root
-## 2. add the following groups to the /etc/group file:
-## floppy, games, sound
-##
-#
-# *** Please note that giving group membership on a session basis is
-# *** NOT inherently secure. If a user can create an executable that
-# *** is setgid a group that they are infrequently given membership
-# *** of, they can basically obtain group membership any time they
-# *** like. Example: games are allowed between the hours of 6pm and 6am
-# *** user joe logs in at 7pm writes a small C-program toplay.c that
-# *** invokes their favorite shell, compiles it and does
-# *** "chgrp games toplay; chmod g+s toplay". They are basically able
-# *** to play games any time... You have been warned. AGM
-#
-# this is an example configuration file for the pam_group module. Its
-# syntax is based on that of the pam_time module and (at some point in
-# the distant past was inspired by the 'shadow' package)
-#
-# the syntax of the lines is as follows:
-#
-# services;ttys;users;times;groups
-#
-# white space is ignored and lines maybe extended with '\\n' (escaped
-# newlines). From reading these comments, it is clear that
-# text following a '#' is ignored to the end of the line.
-#
-# the first four fields are described in the pam_time directory.
-# The only difference for these is how the time field is interpretted:
-# it is used to indicate "when" these groups are to be given to the user.
-#
-# groups
-# The (comma or space separated) list of groups that the user
-# inherits membership of. These groups are added if the previous
-# fields are satisfied by the user's request
-#
-
-#
-# Here is a simple example: running 'xsh' on tty* (any ttyXXX device),
-# the user 'us' is given access to the floppy (through membership of
-# the floppy group)
-#
-
-#xsh;tty*&!ttyp*;us;Al0000-2400;floppy
-
-#
-# another example: running 'xsh' on tty* (any ttyXXX device),
-# the user 'sword' is given access to games (through membership of
-# the floppy group) after work hours
-#
-
-#xsh; tty* ;sword;!Wk0900-1800;games, sound
-#xsh; tty* ;*;Al0900-1800;floppy
-
-#
-# End of group.conf file
-#
diff --git a/modules/pam_group/pam_group.c b/modules/pam_group/pam_group.c
deleted file mode 100644
index 4f6f34fb..00000000
--- a/modules/pam_group/pam_group.c
+++ /dev/null
@@ -1,856 +0,0 @@
-/* pam_group module */
-
-/*
- * $Id$
- *
- * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/7/6
- */
-
-const static char rcsid[] =
-"$Id$;\n"
-"Version 0.5 for Linux-PAM\n"
-"Copyright (c) Andrew G. Morgan 1996 <morgan@linux.kernel.org>\n";
-
-#define _BSD_SOURCE
-
-#include <sys/file.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <time.h>
-#include <syslog.h>
-#include <string.h>
-
-#include <grp.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#ifdef DEFAULT_CONF_FILE
-# define PAM_GROUP_CONF DEFAULT_CONF_FILE /* from external define */
-#else
-# define PAM_GROUP_CONF "/etc/security/group.conf"
-#endif
-#define PAM_GROUP_BUFLEN 1000
-#define FIELD_SEPARATOR ';' /* this is new as of .02 */
-
-#ifdef TRUE
-# undef TRUE
-#endif
-#ifdef FALSE
-# undef FALSE
-#endif
-
-typedef enum { FALSE, TRUE } boolean;
-typedef enum { AND, OR } operator;
-
-/*
- * here, we make definitions for the externally accessible functions
- * in this file (these definitions are required for static modules
- * but strongly encouraged generally) they are used to instruct the
- * modules include file to define their prototypes.
- */
-
-#define PAM_SM_AUTH
-
-#include <security/pam_modules.h>
-#include <security/_pam_macros.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_group", 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)
-{
- while (by-- > 0) {
- *mem = mem[from];
- ++mem;
- }
-}
-
-static int read_field(int fd, char **buf, int *from, int *to)
-{
- /* is buf set ? */
-
- if (! *buf) {
- *buf = (char *) malloc(PAM_GROUP_BUFLEN);
- if (! *buf) {
- _log_err("out of memory");
- return -1;
- }
- *from = *to = 0;
- fd = open(PAM_GROUP_CONF, O_RDONLY);
- }
-
- /* do we have a file open ? return error */
-
- if (fd < 0 && *to <= 0) {
- _log_err( PAM_GROUP_CONF " not opened");
- memset(*buf, 0, PAM_GROUP_BUFLEN);
- _pam_drop(*buf);
- return -1;
- }
-
- /* check if there was a newline last time */
-
- if ((*to > *from) && (*to > 0)
- && ((*buf)[*from] == '\0')) { /* previous line ended */
- (*from)++;
- (*buf)[0] = '\0';
- return fd;
- }
-
- /* ready for more data: first shift the buffer's remaining data */
-
- *to -= *from;
- shift_bytes(*buf, *from, *to);
- *from = 0;
- (*buf)[*to] = '\0';
-
- while (fd >= 0 && *to < PAM_GROUP_BUFLEN) {
- int i;
-
- /* now try to fill the remainder of the buffer */
-
- i = read(fd, *to + *buf, PAM_GROUP_BUFLEN - *to);
- if (i < 0) {
- _log_err("error reading " PAM_GROUP_CONF);
- return -1;
- } else if (!i) {
- close(fd);
- fd = -1; /* end of file reached */
- } else
- *to += i;
-
- /*
- * contract the buffer. Delete any comments, and replace all
- * multiple spaces with single commas
- */
-
- i = 0;
-#ifdef DEBUG_DUMP
- D(("buffer=<%s>",*buf));
-#endif
- while (i < *to) {
- if ((*buf)[i] == ',') {
- int j;
-
- for (j=++i; j<*to && (*buf)[j] == ','; ++j);
- if (j!=i) {
- shift_bytes(i + (*buf), j-i, (*to) - j);
- *to -= j-i;
- }
- }
- switch ((*buf)[i]) {
- int j,c;
- case '#':
- for (j=i; j < *to && (c = (*buf)[j]) != '\n'; ++j);
- if (j >= *to) {
- (*buf)[*to = ++i] = '\0';
- } else if (c == '\n') {
- shift_bytes(i + (*buf), j-i, (*to) - j);
- *to -= j-i;
- ++i;
- } else {
- _log_err("internal error in " __FILE__
- " at line %d", __LINE__ );
- return -1;
- }
- break;
- case '\\':
- if ((*buf)[i+1] == '\n') {
- shift_bytes(i + *buf, 2, *to - (i+2));
- *to -= 2;
- } else {
- ++i; /* we don't escape non-newline characters */
- }
- break;
- case '!':
- case ' ':
- case '\t':
- if ((*buf)[i] != '!')
- (*buf)[i] = ',';
- /* delete any trailing spaces */
- for (j=++i; j < *to && ( (c = (*buf)[j]) == ' '
- || c == '\t' ); ++j);
- shift_bytes(i + *buf, j-i, (*to)-j );
- *to -= j-i;
- break;
- default:
- ++i;
- }
- }
- }
-
- (*buf)[*to] = '\0';
-
- /* now return the next field (set the from/to markers) */
- {
- int i;
-
- for (i=0; i<*to; ++i) {
- switch ((*buf)[i]) {
- case '#':
- case '\n': /* end of the line/file */
- (*buf)[i] = '\0';
- *from = i;
- return fd;
- case FIELD_SEPARATOR: /* end of the field */
- (*buf)[i] = '\0';
- *from = ++i;
- return fd;
- }
- }
- *from = i;
- (*buf)[*from] = '\0';
- }
-
- if (*to <= 0) {
- D(("[end of text]"));
- *buf = NULL;
- }
- return fd;
-}
-
-/* read a member from a field */
-
-static int logic_member(const char *string, int *at)
-{
- int len,c,to;
- int done=0;
- int token=0;
-
- len=0;
- to=*at;
- do {
- c = string[to++];
-
- switch (c) {
-
- case '\0':
- --to;
- done = 1;
- break;
-
- case '&':
- case '|':
- case '!':
- if (token) {
- --to;
- }
- done = 1;
- break;
-
- default:
- if (isalpha(c) || c == '*' || isdigit(c) || c == '_'
- || c == '-' || c == '.' || c == '/') {
- token = 1;
- } else if (token) {
- --to;
- done = 1;
- } else {
- ++*at;
- }
- }
- } while (!done);
-
- return to - *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))
-{
- boolean left=FALSE, right, not=FALSE;
- operator oper=OR;
- int at=0, l;
- expect next=VAL;
-
- while ((l = logic_member(x,&at))) {
- int c = x[at];
-
- if (next == VAL) {
- if (c == '!')
- not = !not;
- else if (isalpha(c) || c == '*') {
- right = not ^ agrees(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);
- return FALSE;
- }
- } else { /* OP */
- switch (c) {
- case '&':
- oper = AND;
- break;
- case '|':
- oper = OR;
- break;
- default:
- _log_err("garbled syntax; expected & or | (rule #%d)"
- , rule);
- D(("%c at %d",c,at));
- return FALSE;
- }
- next = VAL;
- }
- at += l;
- }
-
- return left;
-}
-
-static boolean is_same(const void *A, const char *b, int len, int rule)
-{
- int i;
- const char *a;
-
- a = A;
- for (i=0; len > 0; ++i, --len) {
- if (b[i] != a[i]) {
- if (b[i++] == '*') {
- return (!--len || !strncmp(b+i,a+strlen(a)-len,len));
- } else
- return FALSE;
- }
- }
- return ( !len );
-}
-
-typedef struct {
- int day; /* array of 7 bits, one set for today */
- int minute; /* integer, hour*100+minute for now */
-} TIME;
-
-struct day {
- const char *d;
- int bit;
-} static const days[11] = {
- { "su", 01 },
- { "mo", 02 },
- { "tu", 04 },
- { "we", 010 },
- { "th", 020 },
- { "fr", 040 },
- { "sa", 0100 },
- { "wk", 076 },
- { "wd", 0101 },
- { "al", 0177 },
- { NULL, 0 }
-};
-
-static TIME time_now(void)
-{
- struct tm *local;
- time_t the_time;
- TIME this;
-
- the_time = time((time_t *)0); /* get the current time */
- local = localtime(&the_time);
- this.day = days[local->tm_wday].bit;
- this.minute = local->tm_hour*100 + local->tm_min;
-
- D(("day: 0%o, time: %.4d", this.day, this.minute));
- return this;
-}
-
-/* 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)
-{
- boolean not,pass;
- int marked_day, time_start, time_end;
- const TIME *at;
- int i,j=0;
-
- at = AT;
- D(("checking: 0%o/%.4d vs. %s", at->day, at->minute, times));
-
- if (times == NULL) {
- /* this should not happen */
- _log_err("internal error: " __FILE__ " line %d", __LINE__);
- return FALSE;
- }
-
- if (times[j] == '!') {
- ++j;
- not = TRUE;
- } else {
- not = FALSE;
- }
-
- for (marked_day = 0; len > 0 && isalpha(times[j]); --len) {
- int this_day=-1;
-
- D(("%c%c ?", times[j], times[j+1]));
- for (i=0; days[i].d != NULL; ++i) {
- if (tolower(times[j]) == days[i].d[0]
- && tolower(times[j+1]) == days[i].d[1] ) {
- this_day = days[i].bit;
- break;
- }
- }
- j += 2;
- if (this_day == -1) {
- _log_err("bad day specified (rule #%d)", rule);
- return FALSE;
- }
- marked_day ^= this_day;
- }
- if (marked_day == 0) {
- _log_err("no day specified");
- return FALSE;
- }
- D(("day range = 0%o", marked_day));
-
- time_start = 0;
- for (i=0; len > 0 && i < 4 && isdigit(times[i+j]); ++i, --len) {
- time_start *= 10;
- time_start += times[i+j]-'0'; /* is this portable? */
- }
- j += i;
-
- if (times[j] == '-') {
- time_end = 0;
- for (i=1; len > 0 && i < 5 && isdigit(times[i+j]); ++i, --len) {
- time_end *= 10;
- time_end += times[i+j]-'0'; /* is this portable? */
- }
- j += i;
- } else
- time_end = -1;
-
- 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);
- return TRUE;
- }
- D(("times(%d to %d)", time_start,time_end));
- D(("marked_day = 0%o", marked_day));
-
- /* compare with the actual time now */
-
- pass = FALSE;
- if (time_start < time_end) { /* start < end ? --> same day */
- if ((at->day & marked_day) && (at->minute >= time_start)
- && (at->minute < time_end)) {
- D(("time is listed"));
- pass = TRUE;
- }
- } else { /* spans two days */
- if ((at->day & marked_day) && (at->minute >= time_start)) {
- D(("caught on first day"));
- pass = TRUE;
- } else {
- marked_day <<= 1;
- marked_day |= (marked_day & 0200) ? 1:0;
- D(("next day = 0%o", marked_day));
- if ((at->day & marked_day) && (at->minute <= time_end)) {
- D(("caught on second day"));
- pass = TRUE;
- }
- }
- }
-
- return (not ^ pass);
-}
-
-static int find_member(const char *string, int *at)
-{
- int len,c,to;
- int done=0;
- int token=0;
-
- len=0;
- to=*at;
- do {
- c = string[to++];
-
- switch (c) {
-
- case '\0':
- --to;
- done = 1;
- break;
-
- case '&':
- case '|':
- case '!':
- if (token) {
- --to;
- }
- done = 1;
- break;
-
- default:
- if (isalpha(c) || isdigit(c) || c == '_' || c == '*'
- || c == '-') {
- token = 1;
- } else if (token) {
- --to;
- done = 1;
- } else {
- ++*at;
- }
- }
- } while (!done);
-
- return to - *at;
-}
-
-#define GROUP_BLK 10
-#define blk_size(len) (((len-1 + GROUP_BLK)/GROUP_BLK)*GROUP_BLK)
-
-static int mkgrplist(char *buf, gid_t **list, int len)
-{
- int l,at=0;
- int blks;
-
- blks = blk_size(len);
- D(("cf. blks=%d and len=%d", blks,len));
-
- while ((l = find_member(buf,&at))) {
- int edge;
-
- if (len >= blks) {
- gid_t *tmp;
-
- D(("allocating new block"));
- tmp = (gid_t *) realloc((*list)
- , sizeof(gid_t) * (blks += GROUP_BLK));
- if (tmp != NULL) {
- (*list) = tmp;
- } else {
- _log_err("out of memory for group list");
- free(*list);
- (*list) = NULL;
- return -1;
- }
- }
-
- /* '\0' terminate the entry */
-
- edge = (buf[at+l]) ? 1:0;
- buf[at+l] = '\0';
- D(("found group: %s",buf+at));
-
- /* this is where we convert a group name to a gid_t */
-#ifdef WANT_PWDB
- {
- int retval;
- const struct pwdb *pw=NULL;
-
- retval = pwdb_locate("group", PWDB_DEFAULT, buf+at
- , PWDB_ID_UNKNOWN, &pw);
- if (retval != PWDB_SUCCESS) {
- _log_err("bad group: %s; %s", buf+at, pwdb_strerror(retval));
- } else {
- const struct pwdb_entry *pwe=NULL;
-
- D(("group %s exists", buf+at));
- retval = pwdb_get_entry(pw, "gid", &pwe);
- if (retval == PWDB_SUCCESS) {
- D(("gid = %d [%p]",* (const gid_t *) pwe->value,list));
- (*list)[len++] = * (const gid_t *) pwe->value;
- pwdb_entry_delete(&pwe); /* tidy up */
- } else {
- _log_err("%s group entry is bad; %s"
- , pwdb_strerror(retval));
- }
- pw = NULL; /* break link - cached for later use */
- }
- }
-#else
- {
- const struct group *grp;
-
- grp = getgrnam(buf+at);
- if (grp == NULL) {
- _log_err("bad group: %s", buf+at);
- } else {
- D(("group %s exists", buf+at));
- (*list)[len++] = grp->gr_gid;
- }
- }
-#endif
-
- /* next entry along */
-
- at += l + edge;
- }
- D(("returning with [%p/len=%d]->%p",list,len,*list));
- return len;
-}
-
-
-static int check_account(const char *service, const char *tty
- , const char *user)
-{
- int from=0,to=0,fd=-1;
- char *buffer=NULL;
- int count=0;
- TIME here_and_now;
- int retval=PAM_SUCCESS;
- gid_t *grps;
- int no_grps;
-
- /*
- * first we get the current list of groups - the application
- * will have previously done an initgroups(), or equivalent.
- */
-
- D(("counting supplementary groups"));
- no_grps = getgroups(0, NULL); /* find the current number of groups */
- if (no_grps > 0) {
- grps = calloc( blk_size(no_grps) , sizeof(gid_t) );
- D(("copying current list into grps [%d big]",blk_size(no_grps)));
- (void) getgroups(no_grps, grps);
-#ifdef DEBUG
- {
- int z;
- for (z=0; z<no_grps; ++z) {
- D(("gid[%d]=%d", z, grps[z]));
- }
- }
-#endif
- } else {
- D(("no supplementary groups known"));
- no_grps = 0;
- grps = NULL;
- }
-
- here_and_now = time_now(); /* find current time */
-
- /* parse the rules in the configuration file */
- do {
- int good=TRUE;
-
- /* here we get the service name field */
-
- fd = read_field(fd,&buffer,&from,&to);
- if (!buffer || !buffer[0]) {
- /* empty line .. ? */
- continue;
- }
- ++count;
- D(("working on rule #%d",count));
-
- good = logic_field(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);
- if (!buffer || !buffer[0]) {
- _log_err(PAM_GROUP_CONF "; no tty entry #%d", count);
- continue;
- }
- good &= logic_field(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);
- if (!buffer || !buffer[0]) {
- _log_err(PAM_GROUP_CONF "; no user entry #%d", count);
- continue;
- }
- good &= logic_field(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);
- if (!buffer || !buffer[0]) {
- _log_err(PAM_GROUP_CONF "; no time entry #%d", count);
- continue;
- }
-
- good &= logic_field(&here_and_now, buffer, count, check_time);
- D(("with time: %s", good ? "passes":"fails" ));
-
- fd = read_field(fd,&buffer,&from,&to);
- if (!buffer || !buffer[0]) {
- _log_err(PAM_GROUP_CONF "; no listed groups for rule #%d"
- , count);
- continue;
- }
-
- /*
- * so we have a list of groups, we need to turn it into
- * something to send to setgroups(2)
- */
-
- if (good) {
- D(("adding %s to gid list", buffer));
- good = mkgrplist(buffer, &grps, no_grps);
- if (good < 0) {
- no_grps = 0;
- } else {
- no_grps = good;
- }
- }
-
- /* check the line is terminated correctly */
-
- fd = read_field(fd,&buffer,&from,&to);
- if (buffer && buffer[0]) {
- _log_err(PAM_GROUP_CONF "; poorly terminated rule #%d", count);
- }
-
- if (good > 0) {
- D(("rule #%d passed, added %d groups", count, good));
- } else if (good < 0) {
- retval = PAM_BUF_ERR;
- } else {
- D(("rule #%d failed", count));
- }
-
- } while (buffer);
-
- /* now set the groups for the user */
-
- if (no_grps > 0) {
- int err;
- D(("trying to set %d groups", no_grps));
-#ifdef DEBUG
- for (err=0; err<no_grps; ++err) {
- D(("gid[%d]=%d", err, grps[err]));
- }
-#endif
- if ((err = setgroups(no_grps, grps))) {
- D(("but couldn't set groups %d", err));
- _log_err("unable to set the group membership for user (err=%d)"
- , err);
- retval = PAM_CRED_ERR;
- }
- }
-
- if (grps) { /* tidy up */
- memset(grps, 0, sizeof(gid_t) * blk_size(no_grps));
- _pam_drop(grps);
- no_grps = 0;
- }
-
- return retval;
-}
-
-/* --- public authentication management functions --- */
-
-PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags
- , int argc, const char **argv)
-{
- return PAM_IGNORE;
-}
-
-PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags
- , int argc, const char **argv)
-{
- const char *service=NULL, *tty=NULL;
- const char *user=NULL;
- int retval;
- unsigned setting;
-
- /* only interested in establishing credentials */
-
- setting = flags;
- if (!(setting & PAM_ESTABLISH_CRED)) {
- D(("ignoring call - not for establishing credentials"));
- return PAM_SUCCESS; /* don't fail because of this */
- }
-
- /* set service name */
-
- if (pam_get_item(pamh, PAM_SERVICE, (const void **)&service)
- != PAM_SUCCESS || service == NULL) {
- _log_err("cannot find the current service name");
- return PAM_ABORT;
- }
-
- /* set username */
-
- if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL
- || *user == '\0') {
- _log_err("cannot determine the user's name");
- return PAM_USER_UNKNOWN;
- }
-
- /* set tty name */
-
- if (pam_get_item(pamh, PAM_TTY, (const void **)&tty) != PAM_SUCCESS
- || 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;
- }
- if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) {
- _log_err("couldn't set tty name");
- return PAM_ABORT;
- }
- }
-
- if (strncmp("/dev/",tty,5) == 0) { /* strip leading /dev/ */
- tty += 5;
- }
-
- /* good, now we have the service name, the user and the terminal name */
-
- D(("service=%s", service));
- D(("user=%s", user));
- D(("tty=%s", tty));
-
-#ifdef WANT_PWDB
-
- /* We initialize the pwdb library and check the account */
- retval = pwdb_start(); /* initialize */
- if (retval == PWDB_SUCCESS) {
- retval = check_account(service,tty,user); /* get groups */
- (void) pwdb_end(); /* tidy up */
- } else {
- D(("failed to initialize pwdb; %s", pwdb_strerror(retval)));
- _log_err("unable to initialize libpwdb");
- retval = PAM_ABORT;
- }
-
-#else /* WANT_PWDB */
- retval = check_account(service,tty,user); /* get groups */
-#endif /* WANT_PWDB */
-
- return retval;
-}
-
-/* end of module definition */
-
-#ifdef PAM_STATIC
-
-/* static module data */
-
-struct pam_module _pam_group_modstruct = {
- "pam_group",
- pam_sm_authenticate,
- pam_sm_setcred,
- NULL,
- NULL,
- NULL,
- NULL
-};
-#endif