diff options
Diffstat (limited to 'modules')
195 files changed, 0 insertions, 25802 deletions
diff --git a/modules/Makefile b/modules/Makefile deleted file mode 100644 index d16dedcf..00000000 --- a/modules/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# $Id$ -# -# Makefile -# -# This makefile controls the build process of shared and static PAM modules. -# -# - -include ../Make.Rules - -MODDIRS=$(shell /bin/ls -d pam_*/Makefile | cut -f1 -d/) - -all: - @echo building the static modutil library - make -C pammodutil all - @echo modules sources available are: - @ls -d $(MODDIRS) 2>/dev/null ; echo :-------- - @echo -ifdef STATIC - rm -f ./_static_module_* -endif - @for i in $(MODDIRS) ; do \ - if [ -d $$i ]; then { \ - $(MAKE) -C $$i all ; \ - if [ $$? -ne 0 ]; then exit 1 ; fi ; \ - } elif [ -f ./.$$i ]; then { \ - cat ./.$$i ; \ - } fi ; \ - done - -download: - @./download-all - -install: - for i in $(MODDIRS) ; do \ - if [ -d $$i ]; then { \ - $(MAKE) -C $$i install ; \ - if [ $$? -ne 0 ]; then exit 1 ; fi ; \ - } fi ; \ - done - -remove: - for i in $(MODDIRS) ; do \ - if [ -d $$i ]; then { \ - $(MAKE) -C $$i remove ; \ - } fi ; \ - done - -lclean: - rm -f _static_module_* - -clean: lclean - for i in $(MODDIRS) ; do \ - if [ -d $$i ]; then { \ - $(MAKE) -C $$i clean ; \ - } fi ; \ - done - make -C pammodutil clean diff --git a/modules/README b/modules/README deleted file mode 100644 index 73d3cf0c..00000000 --- a/modules/README +++ /dev/null @@ -1,55 +0,0 @@ -This directory contains the modules. - -If you want to reserve a module name please email <pam-list@redhat.com> -and announce its name. Andrew Morgan, <morgan@linux.kernel.org>, will -add it to the Makefile in the next release of Linux-PAM. - -As of Linux-PAM-0.40 modules can optionally conform to the static -modules conventions. - -This file was updated for Linux-PAM-0.53. - -The conventions are as follows: - -There are only 6 functions that a module may declare as "public" they -fall into 4 managment groups as follows: - - functions Management group - ------------------------------------------ ---------------- - pam_sm_authenticate, pam_sm_setcred, PAM_SM_AUTH - pam_sm_acct_mgmt, PAM_SM_ACCOUNT - pam_sm_open_session, pam_sm_close_session, PAM_SM_SESSION - pam_sm_chauthtok PAM_SM_PASSWORD - -If a module contains definitions for any of the above functions, it -must supply definitions for all of the functions in the corresponding -management group. - -The header file that defines the ANSI prototypes for these functions -is <security/pam_modules.h> . In the case that the module wishes to -offer the functions of a given managment group, it must #define -PAM_SM_XXX, where XXX is one of the above four tokens. These -definitions must occur *prior* to the -#include <security/pam_modules.h> line. - -The pam_sm_... functions should be defined to be of type 'PAM_EXTERN int'. - -In the case that a module is being compiled with PAM_STATIC #define'd -it should also define a globally accessible structure -_"NAME"_modstruct containing references to each of the functions -defined by the module. (this structure is defined in -<security/pam_modules.h>. "NAME" is the title of the module -(eg. "pam_deny") - -If a module wants to be included in the static libpam.a its Makefile -should execute "register_static" with appropriate arguments (in this -directory). - -[ -For SIMPLE working examples, see - - ./modules/pam_deny/* and ./modules/pam_rootok/* -.] - -Andrew Morgan -96/11/10 diff --git a/modules/Simple.Rules b/modules/Simple.Rules deleted file mode 100644 index c12ede3a..00000000 --- a/modules/Simple.Rules +++ /dev/null @@ -1,109 +0,0 @@ -# $Id$ -# -# For simple modules with no significant dependencies, set $(TITLE) -# and include this file. -# -# There are a few ways to customize this set of rules. Namely, define -# -# $(MODULE_SIMPLE_EXTRACLEAN) -# $(MODULE_SIMPLE_CLEAN) -# $(MODULE_SIMPLE_REMOVE) -# $(MODULE_SIMPLE_INSTALL) -# $(MODULE_SIMPLE_EXTRALIBS) - other things to link with the module -# $(MODULE_SIMPLE_EXTRAFILES) - other files to build (no .c suffix) -# - --include ../Make.Rules - -LIBFILES = $(TITLE) $(MODULE_SIMPLE_EXTRAFILES) -LIBSRC = $(addsuffix .c,$(LIBFILES)) -LIBOBJ = $(addsuffix .o,$(LIBFILES)) -LIBOBJD = $(addprefix dynamic/,$(LIBOBJ)) -LIBOBJS = $(addprefix static/,$(LIBOBJ)) - -LINK_PAMMODUTILS = -L../pammodutil -lpammodutil -L../../libpam -lpam -INCLUDE_PAMMODUTILS = -I../pammodutil/include - -ifdef DYNAMIC -LIBSHARED = $(TITLE).so -endif - -ifdef STATIC -LIBSTATIC = lib$(TITLE).o -endif - -####################### don't edit below ####################### - -all: dirs $(LIBSHARED) $(LIBSTATIC) register - -dynamic/%.o : %.c - $(CC) $(CFLAGS) $(INCLUDE_PAMMODUTILS) $(DYNAMIC) $(TARGET_ARCH) -c $< -o $@ - -static/%.o : %.c - $(CC) $(CFLAGS) $(INCLUDE_PAMMODUTILS) $(STATIC) $(TARGET_ARCH) -c $< -o $@ - -dirs: -ifdef DYNAMIC - $(MKDIR) ./dynamic -endif -ifdef STATIC - $(MKDIR) ./static -endif - -register: -ifdef STATIC - ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) ) -endif - -ifdef DYNAMIC -$(LIBOBJD): $(LIBSRC) -endif - -ifdef DYNAMIC -$(LIBSHARED): $(LIBOBJD) - $(LD_D) -o $@ $(LIBOBJD) $(MODULE_SIMPLE_EXTRALIBS) $(NEED_LINK_LIB_C) $(LINK_PAMMODUTILS) - -endif - -ifdef STATIC -$(LIBOBJS): $(LIBSRC) -endif - -ifdef STATIC -$(LIBSTATIC): $(LIBOBJS) - $(LD) -r -o $@ $(LIBOBJS) $(MODULE_SIMPLE_EXTRALIBS) $(LINK_PAMMODUTILS) -endif - -install: all - $(MKDIR) $(FAKEROOT)$(SECUREDIR) -ifdef DYNAMIC - $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR) -endif -ifdef MAN3 - test -d $(FAKEROOT)$(mandir)/man3 || $(MKDIR) $(FAKEROOT)$(mandir)/man3 - $(INSTALL) -m $(MANMODE) $(MAN3) $(FAKEROOT)$(mandir)/man3/ -endif -ifdef MAN5 - test -d $(FAKEROOT)$(mandir)/man5 || $(MKDIR) $(FAKEROOT)$(mandir)/man5 - $(INSTALL) -m $(MANMODE) $(MAN5) $(FAKEROOT)$(mandir)/man5/ -endif -ifdef MAN8 - test -d $(FAKEROOT)$(mandir)/man8 || $(MKDIR) $(FAKEROOT)$(mandir)/man8 - $(INSTALL) -m $(MANMODE) $(MAN8) $(FAKEROOT)$(mandir)/man8/ -endif - $(MODULE_SIMPLE_INSTALL) - -remove: - rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so - $(MODULE_SIMPLE_REMOVE) - -clean: - rm -f $(LIBOBJD) $(LIBOBJS) core *~ - $(MODULE_SIMPLE_CLEAN) - rm -f *.a *.o *.so *.bak - rm -rf dynamic static - $(MODULE_SIMPLE_EXTRACLEAN) - -.c.o: - $(CC) $(CFLAGS) -c $< - diff --git a/modules/dont_makefile b/modules/dont_makefile deleted file mode 100644 index b7e11834..00000000 --- a/modules/dont_makefile +++ /dev/null @@ -1,21 +0,0 @@ -######################################################################### -# $Id$ -######################################################################### -# This is a makefile that does nothing. It is designed to be included -# by module Makefile-s when they are not compatable with the local -# system -######################################################################### - -all: - @echo "This module will not be compiled on this system" - -remove: clean - -install: clean - -clean: - @echo "Nothing to do" - -######################################################################### -# all over.. -######################################################################### diff --git a/modules/download-all b/modules/download-all deleted file mode 100755 index 427d0bba..00000000 --- a/modules/download-all +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -# -# $Id$ -# -cat <<EOT -For a number of reasons it is not practical for Linux-PAM to be -distributed with every module out there. However, this shell script -is intended as a convenient way for users to download modules from the -'net in some semiautomated fashion. - -Please feel free to send (pam-list@redhat.com) snippets of code that -will help others to download and unpack your favorite module into the -Linux-PAM source tree. Especially welcome are snippets of the -following form: - -ncftp ftp://my.ftpsite.org/pub/fluff/pam_fluff.tar.gz -rm -fr pam_fluff -tar zvfx pam_fluff.tar.gz - -Cheers - -Andrew -morgan@linux.kernel.org -EOT - -# --- insert your snippets below --- - -# --- insert your snippets above --- - -exit 0 diff --git a/modules/install_conf b/modules/install_conf deleted file mode 100755 index 80f6be29..00000000 --- a/modules/install_conf +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -FAKEROOT=$1 -CONFD=$1$2 -CONFILE=$1$3 -MODULE=$4 -CONF=$5 - -IGNORE_AGE=./.ignore_age -QUIET_INSTALL=../../.quiet_install - -echo - -if [ -f "$QUIET_INSTALL" ]; then - if [ ! -f "$CONFILE" ]; then - yes="y" - else - yes="skip" - fi -elif [ -f "$IGNORE_AGE" ]; then - echo "you don't want to be bothered with the age of your $CONFILE file" - yes="n" -elif [ ! -f "$CONFILE" ] || [ "$CONF" -nt "$CONFILE" ]; then - if [ -f "$CONFILE" ]; then - echo "An older $MODULE configuration file already exists ($CONFILE)" - echo "Do you wish to copy the $CONF file in this distribution" - echo "to $CONFILE ? (y/n) [skip] " - read yes - else - yes="y" - fi -else - yes="skip" -fi - -if [ "$yes" = "y" ]; then - mkdir -p $CONFD - echo " copying $CONF to $CONFILE" - cp $CONF $CONFILE -else - echo " Skipping $CONF installation" - if [ "$yes" = "n" ]; then - touch "$IGNORE_AGE" - fi -fi - -echo - -exit 0 diff --git a/modules/pam_access/.cvsignore b/modules/pam_access/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_access/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_access/Makefile b/modules/pam_access/Makefile deleted file mode 100644 index 87b2b3e6..00000000 --- a/modules/pam_access/Makefile +++ /dev/null @@ -1,24 +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_access -LOCAL_CONFILE=./access.conf -INSTALLED_CONFILE=$(SCONFIGD)/access.conf -ifeq ($(HAVE_LIBNSL),yes) -MODULE_SIMPLE_EXTRALIBS=-lnsl -endif - -DEFS=-DDEFAULT_CONF_FILE=\"$(INSTALLED_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_access/README b/modules/pam_access/README deleted file mode 100644 index ddd4725f..00000000 --- a/modules/pam_access/README +++ /dev/null @@ -1,44 +0,0 @@ -# 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. -# -# When someone logs in, the table is scanned for the first entry that -# matches the (user, host) combination, or, in case of non-networked -# logins, the first entry that matches the (user, tty) combination. The -# permissions field of that table entry determines whether the login will -# be accepted or refused. -# -# Format of the login access control table is three fields separated by a -# ":" character: -# -# permission : users : origins -# -# The first field should be a "+" (access granted) or "-" (access denied) -# character. -# -# The second field should be a list of one or more login names, group -# names, or ALL (always matches). A pattern of the form user@host is -# matched when the login name matches the "user" part, and when the -# "host" part matches the local machine name. -# -# The third field should be a list of one or more tty names (for -# non-networked logins), host names, domain names (begin with "."), host -# addresses, internet network numbers (end with "."), ALL (always -# matches) or LOCAL (matches any string that does not contain a "." -# character). -# -# If you run NIS you can use @netgroupname in host or user patterns; this -# even works for @usergroup@@hostgroup patterns. Weird. -# -# The EXCEPT operator makes it possible to write very compact rules. -# -# The group file is searched only when a name does not match that of the -# logged-in user. Both the user's primary group is matched, as well as -# groups in which users are explicitly listed. -# -# Alexei Nogin <alexei@nogin.dnttm.ru> 1997/06/15 -############################################################################ diff --git a/modules/pam_access/access.conf b/modules/pam_access/access.conf deleted file mode 100644 index cec2be0c..00000000 --- a/modules/pam_access/access.conf +++ /dev/null @@ -1,65 +0,0 @@ -# Login access control table. -# -# When someone logs in, the table is scanned for the first entry that -# matches the (user, host) combination, or, in case of non-networked -# logins, the first entry that matches the (user, tty) combination. The -# permissions field of that table entry determines whether the login will -# be accepted or refused. -# -# Format of the login access control table is three fields separated by a -# ":" character: -# -# [Note, if you supply a 'fieldsep=|' argument to the pam_access.so -# module, you can change the field separation character to be -# '|'. This is useful for configurations where you are trying to use -# pam_access with X applications that provide PAM_TTY values that are -# the display variable like "host:0".] -# -# permission : users : origins -# -# The first field should be a "+" (access granted) or "-" (access denied) -# character. -# -# The second field should be a list of one or more login names, group -# names, or ALL (always matches). A pattern of the form user@host is -# matched when the login name matches the "user" part, and when the -# "host" part matches the local machine name. -# -# The third field should be a list of one or more tty names (for -# non-networked logins), host names, domain names (begin with "."), host -# addresses, internet network numbers (end with "."), ALL (always -# matches) or LOCAL (matches any string that does not contain a "." -# character). -# -# If you run NIS you can use @netgroupname in host or user patterns; this -# even works for @usergroup@@hostgroup patterns. Weird. -# -# The EXCEPT operator makes it possible to write very compact rules. -# -# The group file is searched only when a name does not match that of the -# logged-in user. Both the user's primary group is matched, as well as -# groups in which users are explicitly listed. -# -# TTY NAMES: Must be in the form returned by ttyname(3) less the initial -# "/dev" (e.g. tty1 or vc/1) -# -############################################################################## -# -# Disallow non-root logins on tty1 -# -#-:ALL EXCEPT root:tty1 -# -# Disallow console logins to all but a few accounts. -# -#-:ALL EXCEPT wheel shutdown sync:LOCAL -# -# Disallow non-local logins to privileged accounts (group wheel). -# -#-:wheel:ALL EXCEPT LOCAL .win.tue.nl -# -# Some accounts are not allowed to login from anywhere: -# -#-:wsbscaro wsbsecr wsbspac wsbsym wscosor wstaiwde:ALL -# -# All other accounts are allowed to login from anywhere. -# diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c deleted file mode 100644 index 4f6cf574..00000000 --- a/modules/pam_access/pam_access.c +++ /dev/null @@ -1,490 +0,0 @@ -/* pam_access module */ - -/* - * Written by Alexei Nogin <alexei@nogin.dnttm.ru> 1997/06/15 - * (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. - ************************************************************************* - */ - -#include <security/_pam_aconf.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include <stdarg.h> -#include <syslog.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <pwd.h> -#include <grp.h> -#include <errno.h> -#include <ctype.h> -#include <sys/utsname.h> -#include <rpcsvc/ypclnt.h> - -#ifndef BROKEN_NETWORK_MATCH -# include <netdb.h> -# include <sys/socket.h> -#endif - -/* - * 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_ACCOUNT - -#include <security/_pam_macros.h> -#include <security/pam_modules.h> -#include <security/_pam_modutil.h> - -/* login_access.c from logdaemon-5.6 with several changes by A.Nogin: */ - - /* - * This module implements a simple but effective form of login access - * control based on login names and on host (or domain) names, internet - * addresses (or network numbers), or on terminal line names in case of - * non-networked logins. Diagnostics are reported through syslog(3). - * - * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. - */ - -#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 const char *fs = ":"; /* field separator */ -static const char sep[] = ", \t"; /* list-element separator */ - - /* Constants to be used in assignments only, not in comparisons... */ - -#define YES 1 -#define NO 0 - - /* - * A structure to bundle up all login-related information to keep the - * functional interfaces as generic as possible. - */ -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("fieldsep=", argv[i], 9)) { - - /* the admin wants to override the default field separators */ - fs = argv[i]+9; - - } else 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 (pam_handle_t *, char *, struct login_info *); - -static int list_match (pam_handle_t *, char *, struct login_info *, - match_func *); -static int user_match (pam_handle_t *, char *, struct login_info *); -static int from_match (pam_handle_t *, char *, struct login_info *); -static int string_match (pam_handle_t *, char *, char *); - -/* login_access - match username/group and host/tty with access control file */ - -static int -login_access (pam_handle_t *pamh, 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 */ - int match = NO; - int end; - int lineno = 0; /* for diagnostics */ - - /* - * 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. - * Non-comment lines are broken at the ':' character. All fields are - * mandatory. The first field should be a "+" or "-" character. A - * non-existing table means no access control. - */ - - 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", - item->config_file, lineno); - continue; - } - if (line[0] == '#') - continue; /* comment line */ - while (end > 0 && isspace(line[end - 1])) - end--; - line[end] = 0; /* strip trailing whitespace */ - if (line[0] == 0) /* skip blank lines */ - continue; - - /* Allow trailing: in last field fo froms */ - if (!(perm = strtok(line, fs)) - || !(users = strtok((char *) 0, fs)) - || !(froms = strtok((char *) 0, fs))) { - _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", - item->config_file, lineno); - continue; - } - match = (list_match(pamh, froms, item, from_match) - && list_match(pamh, users, item, user_match)); - } - (void) fclose(fp); - } else if (errno != ENOENT) { - _log_err("cannot open %s: %m", item->config_file); - return NO; - } - return (match == 0 || (line[0] == '+')); -} - -/* list_match - match an item against a list of tokens with exceptions */ - -static int list_match(pam_handle_t *pamh, - char *list, struct login_info *item, match_func *match_fn) -{ - char *tok; - int match = NO; - - /* - * Process tokens one at a time. We have exhausted all possible matches - * when we reach an "EXCEPT" token or the end of the list. If we do find - * a match, look for an "EXCEPT" list and recurse to determine whether - * the match is affected by any exceptions. - */ - - for (tok = strtok(list, sep); tok != 0; tok = strtok((char *) 0, sep)) { - if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */ - break; - if ((match = (*match_fn) (pamh, tok, item))) /* YES */ - break; - } - /* Process exceptions to matches. */ - - if (match != NO) { - while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT")) - /* VOID */ ; - if (tok == 0 || list_match(pamh, (char *) 0, item, match_fn) == NO) - return (match); - } - return (NO); -} - -/* myhostname - figure out local machine name */ - -static char * myhostname(void) -{ - static char name[MAXHOSTNAMELEN + 1]; - - if (gethostname(name, MAXHOSTNAMELEN) == 0) { - name[MAXHOSTNAMELEN] = 0; - return (name); - } - return NULL; -} - -/* netgroup_match - match group against machine or user */ - -static int netgroup_match(char *group, char *machine, char *user) -{ - static char *mydomain = NULL; - - if (mydomain == 0) - yp_get_default_domain(&mydomain); - return (innetgr(group, machine, user, mydomain)); -} - -/* user_match - match a username against one token */ - -static int user_match(pam_handle_t *pamh, char *tok, struct login_info *item) -{ - char *string = item->user->pw_name; - struct login_info fake_item; - char *at; - - /* - * If a token has the magic value "ALL" the match always succeeds. - * Otherwise, return YES if the token fully matches the username, if the - * token is a group that contains the username, or if the token is the - * name of the user's primary group. - */ - - if ((at = strchr(tok + 1, '@')) != 0) { /* split user@host pattern */ - *at = 0; - fake_item.from = myhostname(); - if (fake_item.from == NULL) - return NO; - return (user_match (pamh, tok, item) && from_match (pamh, at + 1, &fake_item)); - } else if (tok[0] == '@') /* netgroup */ - return (netgroup_match(tok + 1, (char *) 0, string)); - else if (string_match (pamh, tok, string)) /* ALL or exact match */ - return YES; - else if (_pammodutil_user_in_group_nam_nam (pamh, item->user->pw_name, tok)) - /* try group membership */ - return YES; - - return NO; -} - -/* from_match - match a host or tty against a list of tokens */ - -static int -from_match (pam_handle_t *pamh, char *tok, struct login_info *item) -{ - char *string = item->from; - int tok_len; - int str_len; - - /* - * If a token has the magic value "ALL" the match always succeeds. Return - * YES if the token fully matches the string. If the token is a domain - * name, return YES if it matches the last fields of the string. If the - * token has the magic value "LOCAL", return YES if the string does not - * contain a "." character. If the token is a network number, return YES - * if it matches the head of the string. - */ - - if (tok[0] == '@') { /* netgroup */ - return (netgroup_match(tok + 1, string, (char *) 0)); - } else if (string_match (pamh, tok, string)) /* ALL or exact match */ - return YES; - else if (tok[0] == '.') { /* domain: match last fields */ - if ((str_len = strlen(string)) > (tok_len = strlen(tok)) - && strcasecmp(tok, string + str_len - tok_len) == 0) - return (YES); - } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */ - if (strchr(string, '.') == 0) - return (YES); -#ifdef BROKEN_NETWORK_MATCH - } else if (tok[(tok_len = strlen(tok)) - 1] == '.' /* network */ - && strncmp(tok, string, tok_len) == 0) { - return (YES); -#else /* BROKEN_NETWORK_MATCH */ - } else if (tok[(tok_len = strlen(tok)) - 1] == '.') { - /* - The code below does a more correct check if the address specified - by "string" starts from "tok". - 1998/01/27 Andrey V. Savochkin <saw@msu.ru> - */ - - struct hostent *h; - char hn[3+1+3+1+3+1+3+1+1]; - int r; - - h = gethostbyname(string); - if (h == NULL) - return (NO); - if (h->h_addrtype != AF_INET) - return (NO); - if (h->h_length != 4) - return (NO); /* only IPv4 addresses (SAW) */ - r = snprintf(hn, sizeof(hn), "%u.%u.%u.%u.", - (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], - (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]); - if (r < 0 || r >= sizeof(hn)) - return (NO); - if (!strncmp(tok, hn, tok_len)) - return (YES); -#endif /* BROKEN_NETWORK_MATCH */ - } - return (NO); -} - -/* string_match - match a string against one token */ - -static int -string_match (pam_handle_t *pamh, char *tok, char *string) -{ - - /* - * If the token has the magic value "ALL" the match always succeeds. - * Otherwise, return YES if the token fully matches the string. - */ - - if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */ - return (YES); - } else if (strcasecmp(tok, string) == 0) { /* try exact match */ - return (YES); - } - return (NO); -} - -/* --- public account management functions --- */ - -PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - 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 - || *user == '\0') { - _log_err("cannot determine the user's name"); - return PAM_USER_UNKNOWN; - } - - /* remote host name */ - - if (pam_get_item(pamh, PAM_RHOST, (const void **)&from) - != PAM_SUCCESS) { - _log_err("cannot find the remote host name"); - return PAM_ABORT; - } - - if ((from==NULL) || (*from=='\0')) { - - /* local login, set tty name */ - - if (pam_get_item(pamh, PAM_TTY, (const void **)&from) != PAM_SUCCESS - || from == NULL) { - D(("PAM_TTY not set, probing stdin")); - from = ttyname(STDIN_FILENO); - if (from == NULL) { - _log_err("couldn't get the tty name"); - return PAM_ABORT; - } - if (pam_set_item(pamh, PAM_TTY, from) != PAM_SUCCESS) { - _log_err("couldn't set tty name"); - return PAM_ABORT; - } - } - - if (from[0] == '/') { /* full path */ - from++; - from = strchr(from, '/'); - from++; - } - } - - if ((user_pw=_pammodutil_getpwnam(pamh, user))==NULL) return (PAM_USER_UNKNOWN); - - /* - * 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(pamh, &loginfo)) { - return (PAM_SUCCESS); - } else { - _log_err("access denied for user `%s' from `%s'",user,from); - return (PAM_PERM_DENIED); - } -} - -/* end of module definition */ - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_access_modstruct = { - "pam_access", - NULL, - NULL, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL -}; -#endif diff --git a/modules/pam_cracklib/.cvsignore b/modules/pam_cracklib/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_cracklib/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_cracklib/Makefile b/modules/pam_cracklib/Makefile deleted file mode 100644 index 5f6371ef..00000000 --- a/modules/pam_cracklib/Makefile +++ /dev/null @@ -1,32 +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!). -# -# Created by Andrew Morgan <morgan@kernel.org> 2000/10/08 -# - -include ../../Make.Rules - -TITLE=pam_cracklib - -ifeq ($(HAVE_LIBCRACK),yes) -BUILD_THIS_MODULE=yes -MODULE_SIMPLE_EXTRALIBS=-lcrack - -# These two should really be provided by ../../pam_aconf.h -CFLAGS+=-DCRACKLIB_DICTPATH=\"$(CRACKLIB_DICTPATH)\" - -ifeq ($(HAVE_LIBCRYPT),yes) - MODULE_SIMPLE_EXTRALIBS += -lcrypt -endif - -endif - -ifeq ($(BUILD_THIS_MODULE),yes) - include ../Simple.Rules -else - include ../dont_makefile -endif diff --git a/modules/pam_cracklib/README b/modules/pam_cracklib/README deleted file mode 100644 index 69662f73..00000000 --- a/modules/pam_cracklib/README +++ /dev/null @@ -1,37 +0,0 @@ - -pam_cracklib: - check the passwd against dictionary words. - -RECOGNIZED ARGUMENTS: - debug verbose log - - type=XXX alter the message printed as a prompt to the user. - the message printed is in the form - "New XXX password: ". - Default XXX=UNIX - - retry=N Prompt user at most N times before returning with - error. Default N=1. - - difok=N How many characters can be the same in the new - password relative to the old - difignore=N How many characters long should the password be - before we ignore difok. - - minlen=N The minimum simplicity count for a good password. - - dcredit=N - ucredit=N - lcredit=N - ocredit=N Weight, digits, upper, lower, other characters with - count N. Use these values to compute the - 'unsimplicity' of the password. - - use_authtok Get the proposed password from PAM_AUTHTOK - -MODULE SERVICES PROVIDED: - passwd chauthtok - -AUTHOR: - Cristian Gafton <gafton@redhat.com> - diff --git a/modules/pam_cracklib/pam_cracklib.c b/modules/pam_cracklib/pam_cracklib.c deleted file mode 100644 index 5ddf7f2c..00000000 --- a/modules/pam_cracklib/pam_cracklib.c +++ /dev/null @@ -1,891 +0,0 @@ -/* - * pam_cracklib module - * $Id$ - */ - -/* - * 0.9. switch to using a distance algorithm in similar() - * 0.86. added support for setting minimum numbers of digits, uppers, - * lowers, and others - * 0.85. added six new options to use this with long passwords. - * 0.8. tidied output and improved D(()) usage for debugging. - * 0.7. added support for more obscure checks for new passwd. - * 0.6. root can reset user passwd to any values (it's only warned) - * 0.5. supports retries - 'retry=N' argument - * 0.4. added argument 'type=XXX' for 'New XXX password' prompt - * 0.3. Added argument 'debug' - * 0.2. new password is feeded to cracklib for verify after typed once - * 0.1. First release - */ - -/* - * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10 - * Long password support by Philip W. Dalrymple <pwd@mdtsoft.com> 1997/07/18 - * See the end of the file for Copyright Information - * - * Modification for long password systems (>8 chars). The original - * module had problems when used in a md5 password system in that it - * allowed too short passwords but required that at least half of the - * bytes in the new password did not appear in the old one. this - * action is still the default and the changes should not break any - * current user. This modification adds 6 new options, one to set the - * number of bytes in the new password that are not in the old one, - * the other five to control the length checking, these are all - * documented (or will be before anyone else sees this code) in the PAM - * S.A.G. in the section on the cracklib module. - */ - -#include <security/_pam_aconf.h> - -#include <stdio.h> -#ifdef HAVE_CRYPT_H -# include <crypt.h> -#endif -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <ctype.h> - -extern char *FascistCheck(char *pw, const char *dictpath); - -#ifndef CRACKLIB_DICTPATH -#define CRACKLIB_DICTPATH "/usr/share/dict/cracklib_dict" -#endif - -#define PROMPT1 "New %s%spassword: " -#define PROMPT2 "Retype new %s%spassword: " -#define MISTYPED_PASS "Sorry, passwords do not match" - -#ifdef MIN -#undef MIN -#endif -#define MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b)) - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> - -#ifndef LINUX_PAM -#include <security/pam_appl.h> -#endif /* LINUX_PAM */ - -/* some syslogging */ - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-Cracklib", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -/* argument parsing */ -#define PAM_DEBUG_ARG 0x0001 - -struct cracklib_options { - int retry_times; - int diff_ok; - int diff_ignore; - int min_length; - int dig_credit; - int up_credit; - int low_credit; - int oth_credit; - int use_authtok; - char prompt_type[BUFSIZ]; -}; - -#define CO_RETRY_TIMES 1 -#define CO_DIFF_OK 5 -#define CO_DIFF_IGNORE 23 -#define CO_MIN_LENGTH 9 -# define CO_MIN_LENGTH_BASE 5 -#define CO_DIG_CREDIT 1 -#define CO_UP_CREDIT 1 -#define CO_LOW_CREDIT 1 -#define CO_OTH_CREDIT 1 -#define CO_USE_AUTHTOK 0 - -static int _pam_parse(struct cracklib_options *opt, int argc, const char **argv) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - char *ep = NULL; - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strncmp(*argv,"type=",5)) - strncpy(opt->prompt_type, *argv+5, sizeof(opt->prompt_type) - 1); - else if (!strncmp(*argv,"retry=",6)) { - opt->retry_times = strtol(*argv+6,&ep,10); - if (!ep || (opt->retry_times < 1)) - opt->retry_times = CO_RETRY_TIMES; - } else if (!strncmp(*argv,"difok=",6)) { - opt->diff_ok = strtol(*argv+6,&ep,10); - if (!ep || (opt->diff_ok < 0)) - opt->diff_ok = CO_DIFF_OK; - } else if (!strncmp(*argv,"difignore=",10)) { - opt->diff_ignore = strtol(*argv+10,&ep,10); - if (!ep || (opt->diff_ignore < 0)) - opt->diff_ignore = CO_DIFF_IGNORE; - } else if (!strncmp(*argv,"minlen=",7)) { - opt->min_length = strtol(*argv+7,&ep,10); - if (!ep || (opt->min_length < CO_MIN_LENGTH_BASE)) - opt->min_length = CO_MIN_LENGTH_BASE; - } else if (!strncmp(*argv,"dcredit=",8)) { - opt->dig_credit = strtol(*argv+8,&ep,10); - if (!ep) - opt->dig_credit = 0; - } else if (!strncmp(*argv,"ucredit=",8)) { - opt->up_credit = strtol(*argv+8,&ep,10); - if (!ep) - opt->up_credit = 0; - } else if (!strncmp(*argv,"lcredit=",8)) { - opt->low_credit = strtol(*argv+8,&ep,10); - if (!ep) - opt->low_credit = 0; - } else if (!strncmp(*argv,"ocredit=",8)) { - opt->oth_credit = strtol(*argv+8,&ep,10); - if (!ep) - opt->oth_credit = 0; - } else if (!strncmp(*argv,"use_authtok",11)) { - opt->use_authtok = 1; - } else { - _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv); - } - } - opt->prompt_type[sizeof(opt->prompt_type) - 1] = '\0'; - - return ctrl; -} - -/* Helper functions */ - -/* this is a front-end for module-application conversations */ -static int converse(pam_handle_t *pamh, int ctrl, int nargs, - struct pam_message **message, - struct pam_response **response) -{ - int retval; - struct pam_conv *conv = NULL; - - retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv); - - if ( retval == PAM_SUCCESS && conv ) { - retval = conv->conv(nargs, (const struct pam_message **)message, - response, conv->appdata_ptr); - if (retval != PAM_SUCCESS && (ctrl && PAM_DEBUG_ARG)) { - _pam_log(LOG_DEBUG, "conversation failure [%s]", - pam_strerror(pamh, retval)); - } - } else { - _pam_log(LOG_ERR, "couldn't obtain coversation function [%s]", - pam_strerror(pamh, retval)); - if ( retval == PAM_SUCCESS ) - retval = PAM_BAD_ITEM; /* conv was NULL */ - } - - return retval; /* propagate error status */ -} - -static int make_remark(pam_handle_t *pamh, unsigned int ctrl, - int type, const char *text) -{ - struct pam_message *pmsg[1], msg[1]; - struct pam_response *resp; - int retval; - - pmsg[0] = &msg[0]; - msg[0].msg = text; - msg[0].msg_style = type; - resp = NULL; - - retval = converse(pamh, ctrl, 1, pmsg, &resp); - if (retval == PAM_SUCCESS) - _pam_drop_reply(resp, 1); - - return retval; -} - -/* use this to free strings. ESPECIALLY password strings */ -static char *_pam_delete(register char *xx) -{ - _pam_overwrite(xx); - free(xx); - return NULL; -} - -/* - * can't be a palindrome - like `R A D A R' or `M A D A M' - */ -static int palindrome(const char *old, const char *new) -{ - int i, j; - - i = strlen (new); - - for (j = 0;j < i;j++) - if (new[i - j - 1] != new[j]) - return 0; - - return 1; -} - -/* - * Calculate how different two strings are in terms of the number of - * character removals, additions, and changes needed to go from one to - * the other - */ - -static int distdifferent(const char *old, const char *new, int i, int j) -{ - char c, d; - - if ((i == 0) || (strlen(old) < i)) { - c = 0; - } else { - c = old[i - 1]; - } - if ((j == 0) || (strlen(new) < j)) { - d = 0; - } else { - d = new[j - 1]; - } - return (c != d); -} - -static int distcalculate(int **distances, const char *old, const char *new, - int i, int j) -{ - int tmp = 0; - - if (distances[i][j] != -1) { - return distances[i][j]; - } - - tmp = distcalculate(distances, old, new, i - 1, j - 1); - tmp = MIN(tmp, distcalculate(distances, old, new, i, j - 1)); - tmp = MIN(tmp, distcalculate(distances, old, new, i - 1, j)); - tmp += distdifferent(old, new, i, j); - - distances[i][j] = tmp; - - return tmp; -} - -static int distance(const char *old, const char *new) -{ - int **distances = NULL; - int m, n, i, j, r; - - m = strlen(old); - n = strlen(new); - distances = malloc(sizeof(int*) * (m + 1)); - - for (i = 0; i <= m; i++) { - distances[i] = malloc(sizeof(int) * (n + 1)); - for(j = 0; j <= n; j++) { - distances[i][j] = -1; - } - } - for (i = 0; i <= m; i++) { - distances[i][0] = i; - } - for (j = 0; j <= n; j++) { - distances[0][j] = j; - } - distances[0][0] = 0; - - r = distcalculate(distances, old, new, m, n); - - for (i = 0; i <= m; i++) { - memset(distances[i], 0, sizeof(int) * (n + 1)); - free(distances[i]); - } - free(distances); - - return r; -} - -static int similar(struct cracklib_options *opt, - const char *old, const char *new) -{ - if (distance(old, new) >= opt->diff_ok) { - return 0; - } - - if (strlen(new) >= (strlen(old) * 2)) { - return 0; - } - - /* passwords are too similar */ - return 1; -} - -/* - * a nice mix of characters. - */ -static int simple(struct cracklib_options *opt, - const char *old, const char *new) -{ - int digits = 0; - int uppers = 0; - int lowers = 0; - int others = 0; - int size; - int i; - - for (i = 0;new[i];i++) { - if (isdigit (new[i])) - digits++; - else if (isupper (new[i])) - uppers++; - else if (islower (new[i])) - lowers++; - else - others++; - } - - /* - * The scam was this - a password of only one character type - * must be 8 letters long. Two types, 7, and so on. - * This is now changed, the base size and the credits or defaults - * see the docs on the module for info on these parameters, the - * defaults cause the effect to be the same as before the change - */ - - if ((opt->dig_credit >= 0) && (digits > opt->dig_credit)) - digits = opt->dig_credit; - - if ((opt->up_credit >= 0) && (uppers > opt->up_credit)) - uppers = opt->up_credit; - - if ((opt->low_credit >= 0) && (lowers > opt->low_credit)) - lowers = opt->low_credit; - - if ((opt->oth_credit >= 0) && (others > opt->oth_credit)) - others = opt->oth_credit; - - size = opt->min_length; - - if (opt->dig_credit >= 0) - size -= digits; - else if (digits < opt->dig_credit * -1) - return 1; - - if (opt->up_credit >= 0) - size -= uppers; - else if (uppers < opt->up_credit * -1) - return 1; - - if (opt->low_credit >= 0) - size -= lowers; - else if (lowers < opt->low_credit * -1) - return 1; - - if (opt->oth_credit >= 0) - size -= others; - else if (others < opt->oth_credit * -1) - return 1; - - if (size <= i) - return 0; - - return 1; -} - -static char * str_lower(char *string) -{ - char *cp; - - for (cp = string; *cp; cp++) - *cp = tolower(*cp); - return string; -} - -static const char * password_check(struct cracklib_options *opt, const char *old, const char *new) -{ - const char *msg = NULL; - char *oldmono, *newmono, *wrapped; - - if (strcmp(new, old) == 0) { - msg = "is the same as the old one"; - return msg; - } - - newmono = str_lower(x_strdup(new)); - oldmono = str_lower(x_strdup(old)); - wrapped = malloc(strlen(oldmono) * 2 + 1); - strcpy (wrapped, oldmono); - strcat (wrapped, oldmono); - - if (palindrome(oldmono, newmono)) - msg = "is a palindrome"; - - if (!msg && strcmp(oldmono, newmono) == 0) - msg = "case changes only"; - - if (!msg && similar(opt, oldmono, newmono)) - msg = "is too similar to the old one"; - - if (!msg && simple(opt, old, new)) - msg = "is too simple"; - - if (!msg && strstr(wrapped, newmono)) - msg = "is rotated"; - - memset(newmono, 0, strlen(newmono)); - memset(oldmono, 0, strlen(oldmono)); - memset(wrapped, 0, strlen(wrapped)); - free(newmono); - free(oldmono); - free(wrapped); - - return msg; -} - - -#define OLD_PASSWORDS_FILE "/etc/security/opasswd" - -static const char * check_old_password(const char *forwho, const char *newpass) -{ - static char buf[16384]; - char *s_luser, *s_uid, *s_npas, *s_pas; - const char *msg = NULL; - FILE *opwfile; - - opwfile = fopen(OLD_PASSWORDS_FILE, "r"); - if (opwfile == NULL) - return NULL; - - while (fgets(buf, 16380, opwfile)) { - if (!strncmp(buf, forwho, strlen(forwho))) { - buf[strlen(buf)-1] = '\0'; - s_luser = strtok(buf, ":,"); - s_uid = strtok(NULL, ":,"); - s_npas = strtok(NULL, ":,"); - s_pas = strtok(NULL, ":,"); - while (s_pas != NULL) { - if (!strcmp(crypt(newpass, s_pas), s_pas)) { - msg = "has been already used"; - break; - } - s_pas = strtok(NULL, ":,"); - } - break; - } - } - fclose(opwfile); - - return msg; -} - - -static int _pam_unix_approve_pass(pam_handle_t *pamh, - unsigned int ctrl, - struct cracklib_options *opt, - const char *pass_old, - const char *pass_new) -{ - const char *msg = NULL; - const char *user; - int retval; - - if (pass_new == NULL || (pass_old && !strcmp(pass_old,pass_new))) { - if (ctrl && PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG, "bad authentication token"); - make_remark(pamh, ctrl, PAM_ERROR_MSG, - pass_new == NULL ? - "No password supplied":"Password unchanged" ); - return PAM_AUTHTOK_ERR; - } - - /* - * if one wanted to hardwire authentication token strength - * checking this would be the place - */ - msg = password_check(opt, pass_old,pass_new); - if (!msg) { - retval = pam_get_item(pamh, PAM_USER, (const void **)&user); - if (retval != PAM_SUCCESS || user == NULL) { - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_ERR,"Can not get username"); - return PAM_AUTHTOK_ERR; - } - } - msg = check_old_password(user, pass_new); - } - - if (msg) { - char remark[BUFSIZ]; - - memset(remark,0,sizeof(remark)); - snprintf(remark,sizeof(remark),"BAD PASSWORD: %s",msg); - if (ctrl && PAM_DEBUG_ARG) - _pam_log(LOG_NOTICE, "new passwd fails strength check: %s", - msg); - make_remark(pamh, ctrl, PAM_ERROR_MSG, remark); - return PAM_AUTHTOK_ERR; - }; - return PAM_SUCCESS; - -} - -/* The Main Thing (by Cristian Gafton, CEO at this module :-) - * (stolen from http://home.netscape.com) - */ -PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - unsigned int ctrl; - struct cracklib_options options; - - D(("called.")); - - memset(&options, 0, sizeof(options)); - options.retry_times = CO_RETRY_TIMES; - options.diff_ok = CO_DIFF_OK; - options.diff_ignore = CO_DIFF_IGNORE; - options.min_length = CO_MIN_LENGTH; - options.dig_credit = CO_DIG_CREDIT; - options.up_credit = CO_UP_CREDIT; - options.low_credit = CO_LOW_CREDIT; - options.oth_credit = CO_OTH_CREDIT; - options.use_authtok = CO_USE_AUTHTOK; - memset(options.prompt_type, 0, BUFSIZ); - strcpy(options.prompt_type,"UNIX"); - - ctrl = _pam_parse(&options, argc, argv); - - if (flags & PAM_PRELIM_CHECK) { - /* Check for passwd dictionary */ - struct stat st; - char buf[sizeof(CRACKLIB_DICTPATH)+10]; - - D(("prelim check")); - - memset(buf,0,sizeof(buf)); /* zero the buffer */ - snprintf(buf,sizeof(buf),"%s.pwd",CRACKLIB_DICTPATH); - - if (!stat(buf,&st) && st.st_size) - return PAM_SUCCESS; - else { - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_NOTICE,"dict path '%s'[.pwd] is invalid", - CRACKLIB_DICTPATH); - return PAM_ABORT; - } - - /* Not reached */ - return PAM_SERVICE_ERR; - - } else if (flags & PAM_UPDATE_AUTHTOK) { - int retval; - char *token1, *token2, *oldtoken; - struct pam_message msg[1],*pmsg[1]; - struct pam_response *resp; - const char *cracklib_dictpath = CRACKLIB_DICTPATH; - char prompt[BUFSIZ]; - - D(("do update")); - retval = pam_get_item(pamh, PAM_OLDAUTHTOK, - (const void **)&oldtoken); - if (retval != PAM_SUCCESS) { - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_ERR,"Can not get old passwd"); - oldtoken=NULL; - retval = PAM_SUCCESS; - } - - do { - /* - * make sure nothing inappropriate gets returned - */ - token1 = token2 = NULL; - - if (!options.retry_times) { - D(("returning %s because maxtries reached", - pam_strerror(pamh, retval))); - return retval; - } - - /* Planned modus operandi: - * Get a passwd. - * Verify it against cracklib. - * If okay get it a second time. - * Check to be the same with the first one. - * set PAM_AUTHTOK and return - */ - - if (options.use_authtok == 1) { - const char *item = NULL; - - retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **) &item); - if (retval != PAM_SUCCESS) { - /* very strange. */ - _pam_log(LOG_ALERT - ,"pam_get_item returned error to pam_cracklib" - ); - } else if (item != NULL) { /* we have a password! */ - token1 = x_strdup(item); - item = NULL; - } else { - retval = PAM_AUTHTOK_RECOVER_ERR; /* didn't work */ - } - - } else { - /* Prepare to ask the user for the first time */ - memset(prompt,0,sizeof(prompt)); - snprintf(prompt,sizeof(prompt),PROMPT1, - options.prompt_type, options.prompt_type[0]?" ":""); - pmsg[0] = &msg[0]; - msg[0].msg_style = PAM_PROMPT_ECHO_OFF; - msg[0].msg = prompt; - - resp = NULL; - retval = converse(pamh, ctrl, 1, pmsg, &resp); - if (resp != NULL) { - /* interpret the response */ - if (retval == PAM_SUCCESS) { /* a good conversation */ - token1 = x_strdup(resp[0].resp); - if (token1 == NULL) { - _pam_log(LOG_NOTICE, - "could not recover authentication token 1"); - retval = PAM_AUTHTOK_RECOVER_ERR; - } - } - /* - * tidy up the conversation (resp_retcode) is ignored - */ - _pam_drop_reply(resp, 1); - } else { - retval = (retval == PAM_SUCCESS) ? - PAM_AUTHTOK_RECOVER_ERR:retval ; - } - } - - if (retval != PAM_SUCCESS) { - if (ctrl && PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG,"unable to obtain a password"); - continue; - } - - D(("testing password, retval = %s", pam_strerror(pamh, retval))); - /* now test this passwd against cracklib */ - { - char *crack_msg; - char remark[BUFSIZ]; - - bzero(remark,sizeof(remark)); - D(("against cracklib")); - if ((crack_msg = FascistCheck(token1, cracklib_dictpath))) { - if (ctrl && PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG,"bad password: %s",crack_msg); - snprintf(remark,sizeof(remark),"BAD PASSWORD: %s", crack_msg); - make_remark(pamh, ctrl, PAM_ERROR_MSG, remark); - if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK)) - retval = PAM_AUTHTOK_ERR; - else - retval = PAM_SUCCESS; - } else { - /* check it for strength too... */ - D(("for strength")); - if (oldtoken) { - retval = _pam_unix_approve_pass(pamh,ctrl,&options, - oldtoken,token1); - if (retval != PAM_SUCCESS) { - if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK)) - retval = PAM_AUTHTOK_ERR; - else - retval = PAM_SUCCESS; - } - } - } - } - - D(("after testing: retval = %s", pam_strerror(pamh, retval))); - /* if cracklib/strength check said it is a bad passwd... */ - if ((retval != PAM_SUCCESS) && (retval != PAM_IGNORE)) { - int temp_unused; - - temp_unused = pam_set_item(pamh, PAM_AUTHTOK, NULL); - token1 = _pam_delete(token1); - continue; - } - - /* Now we have a good passwd. Ask for it once again */ - - if (options.use_authtok == 0) { - bzero(prompt,sizeof(prompt)); - snprintf(prompt,sizeof(prompt),PROMPT2, - options.prompt_type, options.prompt_type[0]?" ":""); - pmsg[0] = &msg[0]; - msg[0].msg_style = PAM_PROMPT_ECHO_OFF; - msg[0].msg = prompt; - - resp = NULL; - retval = converse(pamh, ctrl, 1, pmsg, &resp); - if (resp != NULL) { - /* interpret the response */ - if (retval == PAM_SUCCESS) { /* a good conversation */ - token2 = x_strdup(resp[0].resp); - if (token2 == NULL) { - _pam_log(LOG_NOTICE, - "could not recover authentication token 2"); - retval = PAM_AUTHTOK_RECOVER_ERR; - } - } - /* - * tidy up the conversation (resp_retcode) is ignored - */ - _pam_drop_reply(resp, 1); - } else { - retval = (retval == PAM_SUCCESS) ? - PAM_AUTHTOK_RECOVER_ERR:retval ; - } - - if (retval != PAM_SUCCESS) { - if (ctrl && PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG - ,"unable to obtain the password a second time"); - continue; - } - - /* Hopefully now token1 and token2 the same password ... */ - if (strcmp(token1,token2) != 0) { - /* tell the user */ - make_remark(pamh, ctrl, PAM_ERROR_MSG, MISTYPED_PASS); - token1 = _pam_delete(token1); - token2 = _pam_delete(token2); - pam_set_item(pamh, PAM_AUTHTOK, NULL); - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_NOTICE,"Password mistyped"); - retval = PAM_AUTHTOK_RECOVER_ERR; - continue; - } - - /* Yes, the password was typed correct twice - * we store this password as an item - */ - - { - const char *item = NULL; - - retval = pam_set_item(pamh, PAM_AUTHTOK, token1); - - /* clean up */ - token1 = _pam_delete(token1); - token2 = _pam_delete(token2); - - if ( (retval != PAM_SUCCESS) || - ((retval = pam_get_item(pamh, PAM_AUTHTOK, - (const void **)&item) - ) != PAM_SUCCESS) ) { - _pam_log(LOG_CRIT, "error manipulating password"); - continue; - } - item = NULL; /* break link to password */ - return PAM_SUCCESS; - } - } - - } while (options.retry_times--); - - } else { - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_NOTICE, "UNKNOWN flags setting %02X",flags); - return PAM_SERVICE_ERR; - } - - /* Not reached */ - return PAM_SERVICE_ERR; -} - - - -#ifdef PAM_STATIC -/* static module data */ -struct pam_module _pam_cracklib_modstruct = { - "pam_cracklib", - NULL, - NULL, - NULL, - NULL, - NULL, - pam_sm_chauthtok -}; -#endif - -/* - * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1996. - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The following copyright was appended for the long password support - * added with the libpam 0.58 release: - * - * Modificaton Copyright (c) Philip W. Dalrymple III <pwd@mdtsoft.com> - * 1997. All rights reserved - * - * THE MODIFICATION THAT PROVIDES SUPPORT FOR LONG PASSWORD TYPE CHECKING TO - * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_debug/.cvsignore b/modules/pam_debug/.cvsignore deleted file mode 100644 index dd17fdcf..00000000 --- a/modules/pam_debug/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -dynamic -static diff --git a/modules/pam_debug/Makefile b/modules/pam_debug/Makefile deleted file mode 100644 index ae22cade..00000000 --- a/modules/pam_debug/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_debug - -include ../Simple.Rules diff --git a/modules/pam_debug/README b/modules/pam_debug/README deleted file mode 100644 index b537e3a7..00000000 --- a/modules/pam_debug/README +++ /dev/null @@ -1,15 +0,0 @@ -# $Id$ -# - -This module returns what its module arguments tell it to return. It -can be used for debugging libpam and/or an application. - -Here are some example ways to use it: - -auth requisite pam_permit.so -auth [success=2 default=ok] pam_debug.so auth=perm_denied cred=success -auth [default=reset] pam_debug.so auth=success cred=perm_denied -auth [success=done default=die] pam_debug.so -auth optional pam_debug.so auth=perm_denied cred=perm_denied -auth sufficient pam_debug.so auth=success cred=success - diff --git a/modules/pam_debug/pam_debug.c b/modules/pam_debug/pam_debug.c deleted file mode 100644 index a6f3538c..00000000 --- a/modules/pam_debug/pam_debug.c +++ /dev/null @@ -1,177 +0,0 @@ -/* pam_permit module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@kernel.org> 2001/02/04 - * - */ - -#define DEFAULT_USER "nobody" - -#include <stdio.h> - -/* - * This module is intended as a debugging aide for determining how - * the PAM stack is operating. - * - * 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 -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> - -#define _PAM_ACTION_UNDEF (-10) -#include "../../libpam/pam_tokens.h" - -/* --- authentication management functions --- */ - -static int state(pam_handle_t *pamh, const char *text) -{ - int retval; - struct pam_conv *conv; - struct pam_message msg[1], *mesg[1]; - struct pam_response *response; - - retval = pam_get_item(pamh, PAM_CONV, (const void **)&conv); - if ((retval != PAM_SUCCESS) || (conv == NULL)) { - D(("failed to obtain conversation function")); - return PAM_ABORT; - } - - msg[0].msg_style = PAM_TEXT_INFO; - msg[0].msg = text; - mesg[0] = &msg[0]; - - retval = conv->conv(1, (const struct pam_message **) mesg, - &response, conv->appdata_ptr); - if (retval != PAM_SUCCESS) { - D(("conversation failed")); - } - - return retval; -} - -static int parse_args(int retval, const char *event, - pam_handle_t *pamh, int argc, const char **argv) -{ - int i; - - for (i=0; i<argc; ++i) { - int length = strlen(event); - if (!strncmp(event, argv[i], length) && (argv[i][length] == '=')) { - int j; - const char *return_string = argv[i] + (length+1); - - for (j=0; j<_PAM_RETURN_VALUES; ++j) { - if (!strcmp(return_string, _pam_token_returns[j])) { - retval = j; - state(pamh, argv[i]); - break; - } - } - break; - } - } - - return retval; -} - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - int retval; - const char *user=NULL; - - /* - * authentication requires we know who the user wants to be - */ - retval = pam_get_user(pamh, &user, NULL); - if (retval != PAM_SUCCESS) { - D(("get user returned error: %s", pam_strerror(pamh,retval))); - return retval; - } - if (user == NULL || *user == '\0') { - D(("username not known")); - retval = pam_set_item(pamh, PAM_USER, (const void *) DEFAULT_USER); - if (retval != PAM_SUCCESS) - return retval; - } - user = NULL; /* clean up */ - - retval = parse_args(PAM_SUCCESS, "auth", pamh, argc, argv); - - return retval; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return parse_args(PAM_SUCCESS, "cred", pamh, argc, argv); -} - -/* --- account management functions --- */ - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return parse_args(PAM_SUCCESS, "acct", pamh, argc, argv); -} - -/* --- password management --- */ - -PAM_EXTERN -int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - if (flags & PAM_PRELIM_CHECK) { - return parse_args(PAM_SUCCESS, "prechauthtok", pamh, argc, argv); - } else { - return parse_args(PAM_SUCCESS, "chauthtok", pamh, argc, argv); - } -} - -/* --- session management --- */ - -PAM_EXTERN -int pam_sm_open_session(pam_handle_t *pamh,int flags,int argc, - const char **argv) -{ - return parse_args(PAM_SUCCESS, "open_session", pamh, argc, argv); -} - -PAM_EXTERN -int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return parse_args(PAM_SUCCESS, "close_session", pamh, argc, argv); -} - -/* end of module definition */ - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_permit_modstruct = { - "pam_debug", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; - -#endif diff --git a/modules/pam_deny/.cvsignore b/modules/pam_deny/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_deny/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_deny/Makefile b/modules/pam_deny/Makefile deleted file mode 100644 index 7dd7b4fd..00000000 --- a/modules/pam_deny/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_deny - -include ../Simple.Rules diff --git a/modules/pam_deny/README b/modules/pam_deny/README deleted file mode 100644 index 6683bdcc..00000000 --- a/modules/pam_deny/README +++ /dev/null @@ -1,4 +0,0 @@ -# $Id$ -# - -this module always fails, it ignores all options. diff --git a/modules/pam_deny/pam_deny.c b/modules/pam_deny/pam_deny.c deleted file mode 100644 index b474751d..00000000 --- a/modules/pam_deny/pam_deny.c +++ /dev/null @@ -1,81 +0,0 @@ -/* pam_permit module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11 - * - */ - -/* - * 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 -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> - -/* --- authentication management functions --- */ - -PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_AUTH_ERR; -} - -PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_CRED_UNAVAIL; -} - -/* --- account management functions --- */ - -PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_ACCT_EXPIRED; -} - -/* --- password management --- */ - -PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_AUTHTOK_ERR; -} - -/* --- session management --- */ - -PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_SYSTEM_ERR; -} - -PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_SYSTEM_ERR; -} - -/* end of module definition */ - -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_deny_modstruct = { - "pam_deny", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; -#endif diff --git a/modules/pam_env/.cvsignore b/modules/pam_env/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_env/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_env/Makefile b/modules/pam_env/Makefile deleted file mode 100644 index fa711ce3..00000000 --- a/modules/pam_env/Makefile +++ /dev/null @@ -1,22 +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_env -LOCAL_CONFILE=./pam_env.conf-example -INSTALLED_CONFILE=$(SCONFIGD)/pam_env.conf - -DEFS=-DDEFAULT_CONF_FILE=\"$(INSTALLED_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_env/README b/modules/pam_env/README deleted file mode 100644 index 04df323b..00000000 --- a/modules/pam_env/README +++ /dev/null @@ -1,72 +0,0 @@ -# $Date$ -# $Author$ -# $Id$ -# -# This is the configuration file for pam_env, a PAM module to load in -# a configurable list of environment variables for a -# -# The original idea for this came from Andrew G. Morgan ... -#<quote> -# Mmm. Perhaps you might like to write a pam_env module that reads a -# default environment from a file? I can see that as REALLY -# useful... Note it would be an "auth" module that returns PAM_IGNORE -# for the auth part and sets the environment returning PAM_SUCCESS in -# the setcred function... -#</quote> -# -# What I wanted was the REMOTEHOST variable set, purely for selfish -# reasons, and AGM didn't want it added to the SimpleApps login -# program (which is where I added the patch). So, my first concern is -# that variable, from there there are numerous others that might/would -# be useful to be set: NNTPSERVER, LESS, PATH, PAGER, MANPAGER ..... -# -# Of course, these are a different kind of variable than REMOTEHOST in -# that they are things that are likely to be configured by -# administrators rather than set by logging in, how to treat them both -# in the same config file? -# -# Here is my idea: -# -# Each line starts with the variable name, there are then two possible -# options for each variable DEFAULT and OVERRIDE. -# DEFAULT allows and administrator to set the value of the -# variable to some default value, if none is supplied then the empty -# string is assumed. The OVERRIDE option tells pam_env that it should -# enter in its value (overriding the default value) if there is one -# to use. OVERRIDE is not used, "" is assumed and no override will be -# done. -# -# VARIABLE [DEFAULT=[value]] [OVERRIDE=[value]] -# -# (Possibly non-existent) environment variables may be used in values -# using the ${string} syntax and (possibly non-existent) PAM_ITEMs may -# be used in values using the @{string} syntax. Both the $ and @ -# characters can be backslash escaped to be used as literal values -# values can be delimited with "", escaped " not supported. -# -# -# First, some special variables -# -# Set the REMOTEHOST variable for any hosts that are remote, default -# to "localhost" rather than not being set at all -REMOTEHOST DEFAULT=localhost OVERRIDE=@{PAM_RHOST} -# -# Set the DISPLAY variable if it seems reasonable -DISPLAY DEFAULT=${REMOTEHOST}:0.0 OVERRIDE=${DISPLAY} -# -# -# Now some simple variables -# -PAGER DEFAULT=less -MANPAGER DEFAULT=less -LESS DEFAULT="M q e h15 z23 b80" -NNTPSERVER DEFAULT=localhost -PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\ -:/usr/bin:/usr/local/bin/X11:/usr/bin/X11 -# -# silly examples of escaped variables, just to show how they work. -# -DOLLAR DEFAULT=\$ -DOLLARDOLLAR DEFAULT= OVERRIDE=\$${DOLLAR} -DOLLARPLUS DEFAULT=\${REMOTEHOST}${REMOTEHOST} -ATSIGN DEFAULT="" OVERRIDE=\@ diff --git a/modules/pam_env/pam_env.c b/modules/pam_env/pam_env.c deleted file mode 100644 index 2c93ebab..00000000 --- a/modules/pam_env/pam_env.c +++ /dev/null @@ -1,843 +0,0 @@ -/* pam_mail module */ - -/* - * $Id$ - * - * Written by Dave Kinchlea <kinch@kinch.ark.com> 1997/01/31 - * Inspired by Andrew Morgan <morgan@kernel.org>, who also supplied the - * template for this file (via pam_mail) - */ - -#ifndef DEFAULT_CONF_FILE -#define DEFAULT_CONF_FILE "/etc/security/pam_env.conf" -#endif - -#define DEFAULT_ETC_ENVFILE "/etc/environment" -#define DEFAULT_READ_ENVFILE 0 - -#include <security/_pam_aconf.h> - -#include <ctype.h> -#include <errno.h> -#include <pwd.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH /* This is primarily a AUTH_SETCRED module */ -#define PAM_SM_SESSION /* But I like to be friendly */ -#define PAM_SM_PASSWORD /* "" */ -#define PAM_SM_ACCOUNT /* "" */ - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> - -/* This little structure makes it easier to keep variables together */ - -typedef struct var { - char *name; - char *value; - char *defval; - char *override; -} VAR; - -#define BUF_SIZE 1024 -#define MAX_ENV 8192 - -#define GOOD_LINE 0 -#define BAD_LINE 100 /* This must be > the largest PAM_* error code */ - -#define DEFINE_VAR 101 -#define UNDEFINE_VAR 102 -#define ILLEGAL_VAR 103 - -static int _assemble_line(FILE *, char *, int); -static int _parse_line(char *, VAR *); -static int _check_var(pam_handle_t *, VAR *); /* This is the real meat */ -static void _clean_var(VAR *); -static int _expand_arg(pam_handle_t *, char **); -static const char * _pam_get_item_byname(pam_handle_t *, const char *); -static int _define_var(pam_handle_t *, VAR *); -static int _undefine_var(pam_handle_t *, VAR *); - -/* This is a flag used to designate an empty string */ -static char quote='Z'; - -/* some syslogging */ - -static void _log_err(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-env", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -/* argument parsing */ - -#define PAM_DEBUG_ARG 0x01 -#define PAM_NEW_CONF_FILE 0x02 -#define PAM_ENV_SILENT 0x04 -#define PAM_NEW_ENV_FILE 0x10 - -static int _pam_parse(int flags, int argc, const char **argv, char **conffile, - char **envfile, int *readenv) -{ - int ctrl=0; - - - /* step through arguments */ - for (; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strncmp(*argv,"conffile=",9)) { - *conffile = x_strdup(9+*argv); - if (*conffile != NULL) { - D(("new Configuration File: %s", *conffile)); - ctrl |= PAM_NEW_CONF_FILE; - } else { - _log_err(LOG_CRIT, - "Configuration file specification missing argument - ignored"); - } - } else if (!strncmp(*argv,"envfile=",8)) { - *envfile = x_strdup(8+*argv); - if (*envfile != NULL) { - D(("new Env File: %s", *envfile)); - ctrl |= PAM_NEW_ENV_FILE; - } else { - _log_err(LOG_CRIT, - "Env file specification missing argument - ignored"); - } - } else if (!strncmp(*argv,"readenv=",8)) - *readenv = atoi(8+*argv); - else - _log_err(LOG_ERR,"pam_parse: unknown option; %s",*argv); - } - - return ctrl; -} - -static int _parse_config_file(pam_handle_t *pamh, int ctrl, char **conffile) -{ - int retval; - const char *file; - char buffer[BUF_SIZE]; - FILE *conf; - VAR Var, *var=&Var; - - var->name=NULL; var->defval=NULL; var->override=NULL; - D(("Called.")); - - if (ctrl & PAM_NEW_CONF_FILE) { - file = *conffile; - } else { - file = DEFAULT_CONF_FILE; - } - - D(("Config file name is: %s", file)); - - /* - * Lets try to open the config file, parse it and process - * any variables found. - */ - - if ((conf = fopen(file,"r")) == NULL) { - _log_err(LOG_ERR, "Unable to open config file: %s", - strerror(errno)); - return PAM_IGNORE; - } - - /* _pam_assemble_line will provide a complete line from the config file, - * with all comments removed and any escaped newlines fixed up - */ - - while (( retval = _assemble_line(conf, buffer, BUF_SIZE)) > 0) { - D(("Read line: %s", buffer)); - - if ((retval = _parse_line(buffer, var)) == GOOD_LINE) { - retval = _check_var(pamh, var); - - if (DEFINE_VAR == retval) { - retval = _define_var(pamh, var); - - } else if (UNDEFINE_VAR == retval) { - retval = _undefine_var(pamh, var); - } - } - if (PAM_SUCCESS != retval && ILLEGAL_VAR != retval - && BAD_LINE != retval && PAM_BAD_ITEM != retval) break; - - _clean_var(var); - - } /* while */ - - (void) fclose(conf); - - /* tidy up */ - _clean_var(var); /* We could have got here prematurely, - * this is safe though */ - _pam_overwrite(*conffile); - _pam_drop(*conffile); - file = NULL; - D(("Exit.")); - return (retval != 0 ? PAM_ABORT : PAM_SUCCESS); -} - -static int _parse_env_file(pam_handle_t *pamh, int ctrl, char **env_file) -{ - int retval=PAM_SUCCESS, i, t; - const char *file; - char buffer[BUF_SIZE], *key, *mark; - FILE *conf; - - if (ctrl & PAM_NEW_ENV_FILE) - file = *env_file; - else - file = DEFAULT_ETC_ENVFILE; - - D(("Env file name is: %s", file)); - - if ((conf = fopen(file,"r")) == NULL) { - D(("Unable to open env file: %s", strerror(errno))); - return PAM_ABORT; - } - - while (_assemble_line(conf, buffer, BUF_SIZE) > 0) { - D(("Read line: %s", buffer)); - key = buffer; - - /* skip leading white space */ - key += strspn(key, " \n\t"); - - /* skip blanks lines and comments */ - if (!key || key[0] == '#') - continue; - - /* skip over "export " if present so we can be compat with - bash type declarations */ - if (strncmp(key, "export ", (size_t) 7) == 0) - key += 7; - - /* now find the end of value */ - mark = key; - while(mark[0] != '\n' && mark[0] != '#' && mark[0] != '\0') - mark++; - if (mark[0] != '\0') - mark[0] = '\0'; - - /* - * sanity check, the key must be alpha-numeric - */ - - for ( i = 0 ; key[i] != '=' && key[i] != '\0' ; i++ ) - if (!isalnum(key[i]) && key[i] != '_') { - D(("key is not alpha numeric - '%s', ignoring", key)); - continue; - } - - /* now we try to be smart about quotes around the value, - but not too smart, we can't get all fancy with escaped - values like bash */ - if (key[i] == '=' && (key[++i] == '\"' || key[i] == '\'')) { - for ( t = i+1 ; key[t] != '\0' ; t++) - if (key[t] != '\"' && key[t] != '\'') - key[i++] = key[t]; - else if (key[t+1] != '\0') - key[i++] = key[t]; - key[i] = '\0'; - } - - /* set the env var, if it fails, we break out of the loop */ - retval = pam_putenv(pamh, key); - if (retval != PAM_SUCCESS) { - D(("error setting env \"%s\"", key)); - break; - } - } - - (void) fclose(conf); - - /* tidy up */ - _pam_overwrite(*env_file); - _pam_drop(*env_file); - file = NULL; - D(("Exit.")); - return (retval != 0 ? PAM_IGNORE : PAM_SUCCESS); -} - -/* - * This is where we read a line of the PAM config file. The line may be - * preceeded by lines of comments and also extended with "\\\n" - */ - -static int _assemble_line(FILE *f, char *buffer, int buf_len) -{ - char *p = buffer; - char *s, *os; - int used = 0; - - /* loop broken with a 'break' when a non-'\\n' ended line is read */ - - D(("called.")); - for (;;) { - if (used >= buf_len) { - /* Overflow */ - D(("_assemble_line: overflow")); - return -1; - } - if (fgets(p, buf_len - used, f) == NULL) { - if (used) { - /* Incomplete read */ - return -1; - } else { - /* EOF */ - return 0; - } - } - - /* skip leading spaces --- line may be blank */ - - s = p + strspn(p, " \n\t"); - if (*s && (*s != '#')) { - os = s; - - /* - * we are only interested in characters before the first '#' - * character - */ - - while (*s && *s != '#') - ++s; - if (*s == '#') { - *s = '\0'; - used += strlen(os); - break; /* the line has been read */ - } - - s = os; - - /* - * Check for backslash by scanning back from the end of - * the entered line, the '\n' has been included since - * normally a line is terminated with this - * character. fgets() should only return one though! - */ - - s += strlen(s); - while (s > os && ((*--s == ' ') || (*s == '\t') - || (*s == '\n'))); - - /* check if it ends with a backslash */ - if (*s == '\\') { - *s = '\0'; /* truncate the line here */ - used += strlen(os); - p = s; /* there is more ... */ - } else { - /* End of the line! */ - used += strlen(os); - break; /* this is the complete line */ - } - - } else { - /* Nothing in this line */ - /* Don't move p */ - } - } - - return used; -} - -static int _parse_line(char *buffer, VAR *var) -{ - /* - * parse buffer into var, legal syntax is - * VARIABLE [DEFAULT=[[string]] [OVERRIDE=[value]] - * - * Any other options defined make this a bad line, - * error logged and no var set - */ - - int length, quoteflg=0; - char *ptr, **valptr, *tmpptr; - - D(("Called buffer = <%s>", buffer)); - - length = strcspn(buffer," \t\n"); - - if ((var->name = malloc(length + 1)) == NULL) { - _log_err(LOG_ERR, "Couldn't malloc %d bytes", length+1); - return PAM_BUF_ERR; - } - - /* - * The first thing on the line HAS to be the variable name, - * it may be the only thing though. - */ - strncpy(var->name, buffer, length); - var->name[length] = '\0'; - D(("var->name = <%s>, length = %d", var->name, length)); - - /* - * Now we check for arguments, we only support two kinds and ('cause I am lazy) - * each one can actually be listed any number of times - */ - - ptr = buffer+length; - while ((length = strspn(ptr, " \t")) > 0) { - ptr += length; /* remove leading whitespace */ - D((ptr)); - if (strncmp(ptr,"DEFAULT=",8) == 0) { - ptr+=8; - D(("Default arg found: <%s>", ptr)); - valptr=&(var->defval); - } else if (strncmp(ptr, "OVERRIDE=", 9) == 0) { - ptr+=9; - D(("Override arg found: <%s>", ptr)); - valptr=&(var->override); - } else { - D(("Unrecognized options: <%s> - ignoring line", ptr)); - _log_err(LOG_ERR, "Unrecognized Option: %s - ignoring line", ptr); - return BAD_LINE; - } - - if ('"' != *ptr) { /* Escaped quotes not supported */ - length = strcspn(ptr, " \t\n"); - tmpptr = ptr+length; - } else { - tmpptr = strchr(++ptr, '"'); - if (!tmpptr) { - D(("Unterminated quoted string: %s", ptr-1)); - _log_err(LOG_ERR, "Unterminated quoted string: %s", ptr-1); - return BAD_LINE; - } - length = tmpptr - ptr; - if (*++tmpptr && ' ' != *tmpptr && '\t' != *tmpptr && '\n' != *tmpptr) { - D(("Quotes must cover the entire string: <%s>", ptr)); - _log_err(LOG_ERR, "Quotes must cover the entire string: <%s>", ptr); - return BAD_LINE; - } - quoteflg++; - } - if (length) { - if ((*valptr = malloc(length + 1)) == NULL) { - D(("Couldn't malloc %d bytes", length+1)); - _log_err(LOG_ERR, "Couldn't malloc %d bytes", length+1); - return PAM_BUF_ERR; - } - (void)strncpy(*valptr,ptr,length); - (*valptr)[length]='\0'; - } else if (quoteflg--) { - *valptr = "e; /* a quick hack to handle the empty string */ - } - ptr = tmpptr; /* Start the search where we stopped */ - } /* while */ - - /* - * The line is parsed, all is well. - */ - - D(("Exit.")); - ptr = NULL; tmpptr = NULL; valptr = NULL; - return GOOD_LINE; -} - -static int _check_var(pam_handle_t *pamh, VAR *var) -{ - /* - * Examine the variable and determine what action to take. - * Returns DEFINE_VAR, UNDEFINE_VAR depending on action to take - * or a PAM_* error code if passed back from other routines - * - * if no DEFAULT provided, the empty string is assumed - * if no OVERRIDE provided, the empty string is assumed - * if DEFAULT= and OVERRIDE evaluates to the empty string, - * this variable should be undefined - * if DEFAULT="" and OVERRIDE evaluates to the empty string, - * this variable should be defined with no value - * if OVERRIDE=value and value turns into the empty string, DEFAULT is used - * - * If DEFINE_VAR is to be returned, the correct value to define will - * be pointed to by var->value - */ - - int retval; - - D(("Called.")); - - /* - * First thing to do is to expand any arguments, but only - * if they are not the special quote values (cause expand_arg - * changes memory). - */ - - if (var->defval && ("e != var->defval) && - ((retval = _expand_arg(pamh, &(var->defval))) != PAM_SUCCESS)) { - return retval; - } - if (var->override && ("e != var->override) && - ((retval = _expand_arg(pamh, &(var->override))) != PAM_SUCCESS)) { - return retval; - } - - /* Now its easy */ - - if (var->override && *(var->override) && "e != var->override) { - /* if there is a non-empty string in var->override, we use it */ - D(("OVERRIDE variable <%s> being used: <%s>", var->name, var->override)); - var->value = var->override; - retval = DEFINE_VAR; - } else { - - var->value = var->defval; - if ("e == var->defval) { - /* - * This means that the empty string was given for defval value - * which indicates that a variable should be defined with no value - */ - *var->defval = '\0'; - D(("An empty variable: <%s>", var->name)); - retval = DEFINE_VAR; - } else if (var->defval) { - D(("DEFAULT variable <%s> being used: <%s>", var->name, var->defval)); - retval = DEFINE_VAR; - } else { - D(("UNDEFINE variable <%s>", var->name)); - retval = UNDEFINE_VAR; - } - } - - D(("Exit.")); - return retval; -} - -static int _expand_arg(pam_handle_t *pamh, char **value) -{ - const char *orig=*value, *tmpptr=NULL; - char *ptr; /* - * Sure would be nice to use tmpptr but it needs to be - * a constant so that the compiler will shut up when I - * call pam_getenv and _pam_get_item_byname -- sigh - */ - - /* No unexpanded variable can be bigger than BUF_SIZE */ - char type, tmpval[BUF_SIZE]; - - /* I know this shouldn't be hard-coded but it's so much easier this way */ - char tmp[MAX_ENV]; - - D(("Remember to initialize tmp!")); - memset(tmp, 0, MAX_ENV); - - /* - * (possibly non-existent) environment variables can be used as values - * by prepending a "$" and wrapping in {} (ie: ${HOST}), can escape with "\" - * (possibly non-existent) PAM items can be used as values - * by prepending a "@" and wrapping in {} (ie: @{PAM_RHOST}, can escape - * - */ - D(("Expanding <%s>",orig)); - while (*orig) { /* while there is some input to deal with */ - if ('\\' == *orig) { - ++orig; - if ('$' != *orig && '@' != *orig) { - D(("Unrecognized escaped character: <%c> - ignoring", *orig)); - _log_err(LOG_ERR, "Unrecognized escaped character: <%c> - ignoring", - *orig); - } else if ((strlen(tmp) + 1) < MAX_ENV) { - tmp[strlen(tmp)] = *orig++; /* Note the increment */ - } else { - /* is it really a good idea to try to log this? */ - D(("Variable buffer overflow: <%s> + <%s>", tmp, tmpptr)); - _log_err(LOG_ERR, "Variable buffer overflow: <%s> + <%s>", - tmp, tmpptr); - } - continue; - } - if ('$' == *orig || '@' == *orig) { - if ('{' != *(orig+1)) { - D(("Expandable variables must be wrapped in {}" - " <%s> - ignoring", orig)); - _log_err(LOG_ERR, "Expandable variables must be wrapped in {}" - " <%s> - ignoring", orig); - if ((strlen(tmp) + 1) < MAX_ENV) { - tmp[strlen(tmp)] = *orig++; /* Note the increment */ - } - continue; - } else { - D(("Expandable argument: <%s>", orig)); - type = *orig; - orig+=2; /* skip the ${ or @{ characters */ - ptr = strchr(orig, '}'); - if (ptr) { - *ptr++ = '\0'; - } else { - D(("Unterminated expandable variable: <%s>", orig-2)); - _log_err(LOG_ERR, "Unterminated expandable variable: <%s>", orig-2); - return PAM_ABORT; - } - strncpy(tmpval, orig, sizeof(tmpval)); - tmpval[sizeof(tmpval)-1] = '\0'; - orig=ptr; - /* - * so, we know we need to expand tmpval, it is either - * an environment variable or a PAM_ITEM. type will tell us which - */ - switch (type) { - - case '$': - D(("Expanding env var: <%s>",tmpval)); - tmpptr = pam_getenv(pamh, tmpval); - D(("Expanded to <%s>", tmpptr)); - break; - - case '@': - D(("Expanding pam item: <%s>",tmpval)); - tmpptr = _pam_get_item_byname(pamh, tmpval); - D(("Expanded to <%s>", tmpptr)); - break; - - default: - D(("Impossible error, type == <%c>", type)); - _log_err(LOG_CRIT, "Impossible error, type == <%c>", type); - return PAM_ABORT; - } /* switch */ - - if (tmpptr) { - if ((strlen(tmp) + strlen(tmpptr)) < MAX_ENV) { - strcat(tmp, tmpptr); - } else { - /* is it really a good idea to try to log this? */ - D(("Variable buffer overflow: <%s> + <%s>", tmp, tmpptr)); - _log_err(LOG_ERR, "Variable buffer overflow: <%s> + <%s>", tmp, tmpptr); - } - } - } /* if ('{' != *orig++) */ - } else { /* if ( '$' == *orig || '@' == *orig) */ - if ((strlen(tmp) + 1) < MAX_ENV) { - tmp[strlen(tmp)] = *orig++; /* Note the increment */ - } else { - /* is it really a good idea to try to log this? */ - D(("Variable buffer overflow: <%s> + <%s>", tmp, tmpptr)); - _log_err(LOG_ERR, "Variable buffer overflow: <%s> + <%s>", tmp, tmpptr); - } - } - } /* for (;*orig;) */ - - if (strlen(tmp) > strlen(*value)) { - free(*value); - if ((*value = malloc(strlen(tmp) +1)) == NULL) { - D(("Couldn't malloc %d bytes for expanded var", strlen(tmp)+1)); - _log_err(LOG_ERR,"Couldn't malloc %d bytes for expanded var", - strlen(tmp)+1); - return PAM_BUF_ERR; - } - } - strcpy(*value, tmp); - memset(tmp,'\0',sizeof(tmp)); - D(("Exit.")); - - return PAM_SUCCESS; -} - -static const char * _pam_get_item_byname(pam_handle_t *pamh, const char *name) -{ - /* - * This function just allows me to use names as given in the config - * file and translate them into the appropriate PAM_ITEM macro - */ - - int item; - const char *itemval; - - D(("Called.")); - if (strcmp(name, "PAM_USER") == 0) { - item = PAM_USER; - } else if (strcmp(name, "PAM_USER_PROMPT") == 0) { - item = PAM_USER_PROMPT; - } else if (strcmp(name, "PAM_TTY") == 0) { - item = PAM_TTY; - } else if (strcmp(name, "PAM_RUSER") == 0) { - item = PAM_RUSER; - } else if (strcmp(name, "PAM_RHOST") == 0) { - item = PAM_RHOST; - } else { - D(("Unknown PAM_ITEM: <%s>", name)); - _log_err(LOG_ERR, "Unknown PAM_ITEM: <%s>", name); - return NULL; - } - - if (pam_get_item(pamh, item, (const void **)&itemval) != PAM_SUCCESS) { - D(("pam_get_item failed")); - return NULL; /* let pam_get_item() log the error */ - } - D(("Exit.")); - return itemval; -} - -static int _define_var(pam_handle_t *pamh, VAR *var) -{ - /* We have a variable to define, this is a simple function */ - - char *envvar; - int size, retval=PAM_SUCCESS; - - D(("Called.")); - size = strlen(var->name)+strlen(var->value)+2; - if ((envvar = malloc(size)) == NULL) { - D(("Malloc fail, size = %d", size)); - _log_err(LOG_ERR, "Malloc fail, size = %d", size); - return PAM_BUF_ERR; - } - (void) sprintf(envvar,"%s=%s",var->name,var->value); - retval = pam_putenv(pamh, envvar); - free(envvar); envvar=NULL; - D(("Exit.")); - return retval; -} - -static int _undefine_var(pam_handle_t *pamh, VAR *var) -{ - /* We have a variable to undefine, this is a simple function */ - - D(("Called and exit.")); - return pam_putenv(pamh, var->name); -} - -static void _clean_var(VAR *var) -{ - if (var->name) { - free(var->name); - } - if (var->defval && ("e != var->defval)) { - free(var->defval); - } - if (var->override && ("e != var->override)) { - free(var->override); - } - var->name = NULL; - var->value = NULL; /* never has memory specific to it */ - var->defval = NULL; - var->override = NULL; - return; -} - - - -/* --- authentication management functions (only) --- */ - -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) -{ - int retval, ctrl, readenv=DEFAULT_READ_ENVFILE; - char *conf_file=NULL, *env_file=NULL; - - /* - * this module sets environment variables read in from a file - */ - - D(("Called.")); - ctrl = _pam_parse(flags, argc, argv, &conf_file, &env_file, &readenv); - - retval = _parse_config_file(pamh, ctrl, &conf_file); - - if(readenv && retval == PAM_SUCCESS) - retval = _parse_env_file(pamh, ctrl, &env_file); - - /* indicate success or failure */ - - D(("Exit.")); - return retval; -} - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - _log_err(LOG_NOTICE, "pam_sm_acct_mgmt called inappropriatly"); - return PAM_SERVICE_ERR; -} - -PAM_EXTERN -int pam_sm_open_session(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - int retval, ctrl, readenv=DEFAULT_READ_ENVFILE; - char *conf_file=NULL, *env_file=NULL; - - /* - * this module sets environment variables read in from a file - */ - - D(("Called.")); - ctrl = _pam_parse(flags, argc, argv, &conf_file, &env_file, &readenv); - - retval = _parse_config_file(pamh, ctrl, &conf_file); - - if(readenv && retval == PAM_SUCCESS) - retval = _parse_env_file(pamh, ctrl, &env_file); - - /* indicate success or failure */ - - D(("Exit.")); - return retval; -} - -PAM_EXTERN -int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc, - const char **argv) -{ - D(("Called and Exit")); - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - _log_err(LOG_NOTICE, "pam_sm_chauthtok called inappropriatly"); - return PAM_SERVICE_ERR; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_env_modstruct = { - "pam_env", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_env/pam_env.conf-example b/modules/pam_env/pam_env.conf-example deleted file mode 100644 index 02116639..00000000 --- a/modules/pam_env/pam_env.conf-example +++ /dev/null @@ -1,76 +0,0 @@ -# $Date$ -# $Author$ -# $Id$ -# -# This is the configuration file for pam_env, a PAM module to load in -# a configurable list of environment variables for a -# -# The original idea for this came from Andrew G. Morgan ... -#<quote> -# Mmm. Perhaps you might like to write a pam_env module that reads a -# default environment from a file? I can see that as REALLY -# useful... Note it would be an "auth" module that returns PAM_IGNORE -# for the auth part and sets the environment returning PAM_SUCCESS in -# the setcred function... -#</quote> -# -# What I wanted was the REMOTEHOST variable set, purely for selfish -# reasons, and AGM didn't want it added to the SimpleApps login -# program (which is where I added the patch). So, my first concern is -# that variable, from there there are numerous others that might/would -# be useful to be set: NNTPSERVER, LESS, PATH, PAGER, MANPAGER ..... -# -# Of course, these are a different kind of variable than REMOTEHOST in -# that they are things that are likely to be configured by -# administrators rather than set by logging in, how to treat them both -# in the same config file? -# -# Here is my idea: -# -# Each line starts with the variable name, there are then two possible -# options for each variable DEFAULT and OVERRIDE. -# DEFAULT allows and administrator to set the value of the -# variable to some default value, if none is supplied then the empty -# string is assumed. The OVERRIDE option tells pam_env that it should -# enter in its value (overriding the default value) if there is one -# to use. OVERRIDE is not used, "" is assumed and no override will be -# done. -# -# VARIABLE [DEFAULT=[value]] [OVERRIDE=[value]] -# -# (Possibly non-existent) environment variables may be used in values -# using the ${string} syntax and (possibly non-existent) PAM_ITEMs may -# be used in values using the @{string} syntax. Both the $ and @ -# characters can be backslash escaped to be used as literal values -# values can be delimited with "", escaped " not supported. -# Note that many environment variables that you would like to use -# may not be set by the time the module is called. -# For example, HOME is used below several times, but -# many PAM applications don't make it available by the time you need it. -# -# -# First, some special variables -# -# Set the REMOTEHOST variable for any hosts that are remote, default -# to "localhost" rather than not being set at all -#REMOTEHOST DEFAULT=localhost OVERRIDE=@{PAM_RHOST} -# -# Set the DISPLAY variable if it seems reasonable -#DISPLAY DEFAULT=${REMOTEHOST}:0.0 OVERRIDE=${DISPLAY} -# -# -# Now some simple variables -# -#PAGER DEFAULT=less -#MANPAGER DEFAULT=less -#LESS DEFAULT="M q e h15 z23 b80" -#NNTPSERVER DEFAULT=localhost -#PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\ -#:/usr/bin:/usr/local/bin/X11:/usr/bin/X11 -# -# silly examples of escaped variables, just to show how they work. -# -#DOLLAR DEFAULT=\$ -#DOLLARDOLLAR DEFAULT= OVERRIDE=\$${DOLLAR} -#DOLLARPLUS DEFAULT=\${REMOTEHOST}${REMOTEHOST} -#ATSIGN DEFAULT="" OVERRIDE=\@ diff --git a/modules/pam_filter/.cvsignore b/modules/pam_filter/.cvsignore deleted file mode 100644 index 877dafe0..00000000 --- a/modules/pam_filter/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -dynamic -security diff --git a/modules/pam_filter/.upperLOWER b/modules/pam_filter/.upperLOWER deleted file mode 100644 index 2531b468..00000000 --- a/modules/pam_filter/.upperLOWER +++ /dev/null @@ -1 +0,0 @@ -a test filter that transposes upper and lower case characters diff --git a/modules/pam_filter/Makefile b/modules/pam_filter/Makefile deleted file mode 100644 index 48411497..00000000 --- a/modules/pam_filter/Makefile +++ /dev/null @@ -1,126 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11 -# - -ifeq ($(OS),solaris) - -include ../dont_makefile - -else - -include ../../Make.Rules - -TITLE=pam_filter -FILTERS=upperLOWER -FILTERSDIR=$(SECUREDIR)/pam_filter -export FILTERSDIR - -CFLAGS += -Iinclude - -LIBSRC = $(TITLE).c -LIBOBJ = $(TITLE).o -LIBOBJD = $(addprefix dynamic/,$(LIBOBJ)) -LIBOBJS = $(addprefix static/,$(LIBOBJ)) - -dynamic/%.o : %.c - $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ - -static/%.o : %.c - $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ - -ifdef DYNAMIC -LIBSHARED = $(TITLE).so -endif - -ifdef STATIC -LIBSTATIC = lib$(TITLE).o -endif - -####################### don't edit below ####################### - -# -# this is where we compile this module -# - -all: dirs $(LIBSHARED) $(LIBSTATIC) register filters - -dirs: - if [ ! -r include/security ]; then ln -sf . include/security ; fi -ifdef DYNAMIC - $(MKDIR) ./dynamic -endif -ifdef STATIC - $(MKDIR) ./static -endif - -register: -ifdef STATIC - ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) ) -endif - -filters: - @for i in $(FILTERS) ; do \ - if [ -d $$i ]; then \ - $(MAKE) -C $$i all ; \ - fi ; \ - done - - -ifdef DYNAMIC -$(LIBOBJD): $(LIBSRC) -endif - -ifdef DYNAMIC -$(LIBSHARED): $(LIBOBJD) - $(LD_D) -o $@ $(LIBOBJD) -endif - -ifdef STATIC -$(LIBOBJS): $(LIBSRC) -endif - -ifdef STATIC -$(LIBSTATIC): $(LIBOBJS) - $(LD) -r -o $@ $(LIBOBJS) -endif - -remove: - rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so - rm -f $(FAKEROOT)$(INCLUDED)/pam_filter.h - @for i in $(FILTERS) ; do \ - if [ -d $$i ]; then \ - $(MAKE) -C $$i remove ; \ - fi ; \ - done - -install: all - @for i in $(FILTERS) ; do \ - if [ -d $$i ]; then \ - $(MAKE) -C $$i install ; \ - fi ; \ - done - $(MKDIR) $(FAKEROOT)$(SECUREDIR) -ifdef DYNAMIC - $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR) -endif - $(MKDIR) $(FAKEROOT)$(INCLUDED) - $(INSTALL) -m 644 include/pam_filter.h $(FAKEROOT)$(INCLUDED) - -clean: - @for i in $(FILTERS) ; do \ - if [ -d $$i ]; then \ - $(MAKE) -C $$i clean ; \ - fi ; \ - done - rm -f $(LIBSHARED) $(LIBOBJD) $(LIBOBJS) core *~ - rm -f include/security - rm -fr dynamic static - rm -f *.a *.o *.so *.bak - -endif diff --git a/modules/pam_filter/README b/modules/pam_filter/README deleted file mode 100644 index 850f1145..00000000 --- a/modules/pam_filter/README +++ /dev/null @@ -1,94 +0,0 @@ -# -# $Id$ -# -# This describes the behavior of this module with respect to the -# /etc/pam.conf file. -# -# writen by Andrew Morgan <morgan@parc.power.net> -# - -This module is intended to be a platform for providing access to all -of the input/output that passes between the user and the application. -It is only suitable for tty-based and (stdin/stdout) applications. And -is only known to work on Linux based systems. - -The action of the module is dictated by the arguments it is given in -the pam.conf file. - -recognized flags are: - - debug print some information to syslog(3) - - new_term set the PAM_TTY item to the new filtered - terminal (the default is to set it - to be that of the users terminal) - - non_term don't try to set the PAM_TTY item - - run1/run2 these arguments indicate that the - module should separate the application - from the user and insert a filter - program between them. The pathname of - the filter program follows the 'runN' - argument. Arguments that follow this - pathname are passed as arguments to - the filter program. - - The distinction between run1 and run2 - is which of the two functions of - the given management-type triggers the - execution of the indicated filter. - - type: run1 run2 - ----- ---- ---- - - auth pam_sm_authenticate pam_sm_setcred - - account [ pam_sm_acct_mgmt (either is good) ] - - session pam_sm_open_session pam_sm_close_session - - password pam_sm_chauthtok/PRELIM pam_sm_chauthtok/UPDATE - -Note, in the case of 'password' PRELIM/UPDATE indicates which of the -two calls to pam_sm_chauthtok from libpam (not the application) will -trigger the filter. - -What a filter program should expect: ------------------------------------- - -Definitions for filter programs (which may be locally designed) are -contained in the <security/pam_filter.h> file. - -Arguments are not passed to the filter on the command line, since this -is plainly visible when a user types 'ps -a'. Instead they are passed -as the filter's environment. Other information is passed in this way -too. - -Here is a list of the environment variables that a filter should -expect: - - ARGS="filter_path_name argument list" - SERVICE="service_name" (as it appears in /etc/pam.conf) - USER="username" - TYPE="module_fn" (the name of the function in pam_filter.so - that invoked the filter) - -[This list is likely to grow. If you want something added, email me!] - -Among other things this module is intended to provide a useful means -of logging the activity of users in as discrete a manner as possible. - -Existing filters: ------------------ - -Currently, there is a single supplied filter (upperLOWER). The effect -of using this filter is to transpose upper and lower case letters -between the user and the application. This is really annoying when you -try the 'xsh' example application! ;) - -TODO: provide more filters... - Decide if providing stderr interception is really overkill. - -Andrew G. Morgan <morgan@parc.power.net> 1996/5/27 - diff --git a/modules/pam_filter/include/pam_filter.h b/modules/pam_filter/include/pam_filter.h deleted file mode 100644 index 630198ee..00000000 --- a/modules/pam_filter/include/pam_filter.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * $Id$ - * - * this file is associated with the Linux-PAM filter module. - * it was written by Andrew G. Morgan <morgan@linux.kernel.org> - * - */ - -#ifndef PAM_FILTER_H -#define PAM_FILTER_H - -#include <sys/file.h> - -/* - * this will fail if there is some problem with these file descriptors - * being allocated by the pam_filter Linux-PAM module. The numbers - * here are thought safe, but the filter developer should use the - * macros, as these numbers are subject to change. - * - * The APPXXX_FILENO file descriptors are the STDIN/OUT/ERR_FILENO of the - * application. The filter uses the STDIN/OUT/ERR_FILENO's to converse - * with the user, passes (modified) user input to the application via - * APPIN_FILENO, and receives application output from APPOUT_FILENO/ERR. - */ - -#define APPIN_FILENO 3 /* write here to give application input */ -#define APPOUT_FILENO 4 /* read here to get application output */ -#define APPERR_FILENO 5 /* read here to get application errors */ - -#define APPTOP_FILE 6 /* used by select */ - -#endif diff --git a/modules/pam_filter/pam_filter.c b/modules/pam_filter/pam_filter.c deleted file mode 100644 index 328fec87..00000000 --- a/modules/pam_filter/pam_filter.c +++ /dev/null @@ -1,744 +0,0 @@ -/* - * $Id$ - * - * written by Andrew Morgan <morgan@transmeta.com> with much help from - * Richard Stevens' UNIX Network Programming book. - */ - -#include <security/_pam_aconf.h> - -#include <stdlib.h> -#include <syslog.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> - -#include <stdio.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <termios.h> - -#include <signal.h> - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/pam_filter.h> - -/* ------ some tokens used for convenience throughout this file ------- */ - -#define FILTER_DEBUG 01 -#define FILTER_RUN1 02 -#define FILTER_RUN2 04 -#define NEW_TERM 010 -#define NON_TERM 020 - -/* -------------------------------------------------------------------- */ - -/* log errors */ - -#include <stdarg.h> - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("pam_filter", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -#define TERMINAL_LEN 12 - -static int master(char *terminal) -/* - * try to open all of the terminals in sequence return first free one, - * or -1 - */ -{ - const char ptys[] = "pqrs", *pty = ptys; - const char hexs[] = "0123456789abcdef", *hex; - struct stat tstat; - int fd; - - strcpy(terminal, "/dev/pty??"); - - while (*pty) { /* step through four types */ - terminal[8] = *pty++; - terminal[9] = '0'; - if (stat(terminal,&tstat) < 0) { - _pam_log(LOG_WARNING, "unknown pseudo terminal; %s", terminal); - break; - } - for (hex = hexs; *hex; ) { /* step through 16 of these */ - terminal[9] = *hex++; - if ((fd = open(terminal, O_RDWR)) >= 0) { - return fd; - } - } - } - - /* no terminal found */ - - return -1; -} - -static int process_args(pam_handle_t *pamh - , int argc, const char **argv, const char *type - , char ***evp, const char **filtername) -{ - int ctrl=0; - - while (argc-- > 0) { - if (strcmp("debug",*argv) == 0) { - ctrl |= FILTER_DEBUG; - } else if (strcmp("new_term",*argv) == 0) { - ctrl |= NEW_TERM; - } else if (strcmp("non_term",*argv) == 0) { - ctrl |= NON_TERM; - } else if (strcmp("run1",*argv) == 0) { - ctrl |= FILTER_RUN1; - if (argc <= 0) { - _pam_log(LOG_ALERT,"no run filter supplied"); - } else - break; - } else if (strcmp("run2",*argv) == 0) { - ctrl |= FILTER_RUN2; - if (argc <= 0) { - _pam_log(LOG_ALERT,"no run filter supplied"); - } else - break; - } else { - _pam_log(LOG_ERR, "unrecognized option: %s (ignored)", *argv); - } - ++argv; /* step along list */ - } - - if (argc < 0) { - /* there was no reference to a filter */ - *filtername = NULL; - *evp = NULL; - } else { - char **levp; - const char *tmp; - int i,size, retval; - - *filtername = *++argv; - if (ctrl & FILTER_DEBUG) { - _pam_log(LOG_DEBUG,"will run filter %s\n", *filtername); - } - - levp = (char **) malloc(5*sizeof(char *)); - if (levp == NULL) { - _pam_log(LOG_CRIT,"no memory for environment of filter"); - return -1; - } - - for (size=i=0; i<argc; ++i) { - size += strlen(argv[i])+1; - } - - /* the "ARGS" variable */ - -#define ARGS_OFFSET 5 /* strlen('ARGS='); */ -#define ARGS_NAME "ARGS=" - - size += ARGS_OFFSET; - - levp[0] = (char *) malloc(size); - if (levp[0] == NULL) { - _pam_log(LOG_CRIT,"no memory for filter arguments"); - if (levp) { - free(levp); - } - return -1; - } - - strncpy(levp[0],ARGS_NAME,ARGS_OFFSET); - for (i=0,size=ARGS_OFFSET; i<argc; ++i) { - strcpy(levp[0]+size, argv[i]); - size += strlen(argv[i]); - levp[0][size++] = ' '; - } - levp[0][--size] = '\0'; /* <NUL> terminate */ - - /* the "SERVICE" variable */ - -#define SERVICE_OFFSET 8 /* strlen('SERVICE='); */ -#define SERVICE_NAME "SERVICE=" - - retval = pam_get_item(pamh, PAM_SERVICE, (const void **)&tmp); - if (retval != PAM_SUCCESS || tmp == NULL) { - _pam_log(LOG_CRIT,"service name not found"); - if (levp) { - free(levp[0]); - free(levp); - } - return -1; - } - size = SERVICE_OFFSET+strlen(tmp); - - levp[1] = (char *) malloc(size+1); - if (levp[1] == NULL) { - _pam_log(LOG_CRIT,"no memory for service name"); - if (levp) { - free(levp[0]); - free(levp); - } - return -1; - } - - strncpy(levp[1],SERVICE_NAME,SERVICE_OFFSET); - strcpy(levp[1]+SERVICE_OFFSET, tmp); - levp[1][size] = '\0'; /* <NUL> terminate */ - - /* the "USER" variable */ - -#define USER_OFFSET 5 /* strlen('USER='); */ -#define USER_NAME "USER=" - - tmp = NULL; - pam_get_user(pamh, &tmp, NULL); - if (tmp == NULL) { - tmp = "<unknown>"; - } - size = USER_OFFSET+strlen(tmp); - - levp[2] = (char *) malloc(size+1); - if (levp[2] == NULL) { - _pam_log(LOG_CRIT,"no memory for user's name"); - if (levp) { - free(levp[1]); - free(levp[0]); - free(levp); - } - return -1; - } - - strncpy(levp[2],USER_NAME,USER_OFFSET); - strcpy(levp[2]+USER_OFFSET, tmp); - levp[2][size] = '\0'; /* <NUL> terminate */ - - /* the "USER" variable */ - -#define TYPE_OFFSET 5 /* strlen('TYPE='); */ -#define TYPE_NAME "TYPE=" - - size = TYPE_OFFSET+strlen(type); - - levp[3] = (char *) malloc(size+1); - if (levp[3] == NULL) { - _pam_log(LOG_CRIT,"no memory for type"); - if (levp) { - free(levp[2]); - free(levp[1]); - free(levp[0]); - free(levp); - } - return -1; - } - - strncpy(levp[3],TYPE_NAME,TYPE_OFFSET); - strcpy(levp[3]+TYPE_OFFSET, type); - levp[3][size] = '\0'; /* <NUL> terminate */ - - levp[4] = NULL; /* end list */ - - *evp = levp; - } - - if ((ctrl & FILTER_DEBUG) && *filtername) { - char **e; - - _pam_log(LOG_DEBUG,"filter[%s]: %s",type,*filtername); - _pam_log(LOG_DEBUG,"environment:"); - for (e=*evp; e && *e; ++e) { - _pam_log(LOG_DEBUG," %s",*e); - } - } - - return ctrl; -} - -static void free_evp(char *evp[]) -{ - int i; - - if (evp) - for (i=0; i<4; ++i) { - if (evp[i]) - free(evp[i]); - } - free(evp); -} - -static int set_filter(pam_handle_t *pamh, int flags, int ctrl - , const char **evp, const char *filtername) -{ - int status=-1; - char terminal[TERMINAL_LEN]; - struct termios stored_mode; /* initial terminal mode settings */ - int fd[2], child=0, child2=0, aterminal; - - if (filtername == NULL || *filtername != '/') { - _pam_log(LOG_ALERT, "filtername not permitted; require full path"); - return PAM_ABORT; - } - - if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) { - aterminal = 0; - } else { - aterminal = 1; - } - - if (aterminal) { - - /* open the master pseudo terminal */ - - fd[0] = master(terminal); - if (fd[0] < 0) { - _pam_log(LOG_CRIT,"no master terminal"); - return PAM_AUTH_ERR; - } - - /* set terminal into raw mode.. remember old mode so that we can - revert to it after the child has quit. */ - - /* this is termios terminal handling... */ - - if ( tcgetattr(STDIN_FILENO, &stored_mode) < 0 ) { - /* in trouble, so close down */ - close(fd[0]); - _pam_log(LOG_CRIT, "couldn't copy terminal mode"); - return PAM_ABORT; - } else { - struct termios t_mode = stored_mode; - - t_mode.c_iflag = 0; /* no input control */ - t_mode.c_oflag &= ~OPOST; /* no ouput post processing */ - - /* no signals, canonical input, echoing, upper/lower output */ - t_mode.c_lflag &= ~(ISIG|ICANON|ECHO|XCASE); - t_mode.c_cflag &= ~(CSIZE|PARENB); /* no parity */ - t_mode.c_cflag |= CS8; /* 8 bit chars */ - - t_mode.c_cc[VMIN] = 1; /* number of chars to satisfy a read */ - t_mode.c_cc[VTIME] = 0; /* 0/10th second for chars */ - - if ( tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_mode) < 0 ) { - close(fd[0]); - _pam_log(LOG_WARNING, "couldn't put terminal in RAW mode"); - return PAM_ABORT; - } - - /* - * NOTE: Unlike the stream socket case here the child - * opens the slave terminal as fd[1] *after* the fork... - */ - } - } else { - - /* - * not a terminal line so just open a stream socket fd[0-1] - * both set... - */ - - if ( socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0 ) { - _pam_log(LOG_CRIT,"couldn't open a stream pipe"); - return PAM_ABORT; - } - } - - /* start child process */ - - if ( (child = fork()) < 0 ) { - - _pam_log(LOG_WARNING,"first fork failed"); - if (aterminal) { - (void) tcsetattr(STDIN_FILENO, TCSAFLUSH, &stored_mode); - } - - return PAM_AUTH_ERR; - } - - if ( child == 0 ) { /* child process *is* application */ - - if (aterminal) { - - /* close the controlling tty */ - -#if defined(__hpux) && defined(O_NOCTTY) - int t = open("/dev/tty", O_RDWR|O_NOCTTY); -#else - int t = open("/dev/tty",O_RDWR); - if (t > 0) { - (void) ioctl(t, TIOCNOTTY, NULL); - close(t); - } -#endif /* defined(__hpux) && defined(O_NOCTTY) */ - - /* make this process it's own process leader */ - if (setsid() == -1) { - _pam_log(LOG_WARNING,"child cannot become new session"); - return PAM_ABORT; - } - - /* find slave's name */ - terminal[5] = 't'; /* want to open slave terminal */ - fd[1] = open(terminal, O_RDWR); - close(fd[0]); /* process is the child -- uses line fd[1] */ - - if (fd[1] < 0) { - _pam_log(LOG_WARNING,"cannot open slave terminal; %s" - ,terminal); - return PAM_ABORT; - } - - /* initialize the child's terminal to be the way the - parent's was before we set it into RAW mode */ - - if ( tcsetattr(fd[1], TCSANOW, &stored_mode) < 0 ) { - _pam_log(LOG_WARNING,"cannot set slave terminal mode; %s" - ,terminal); - close(fd[1]); - return PAM_ABORT; - } - - } else { - - /* nothing to do for a simple stream socket */ - - } - - /* re-assign the stdin/out to fd[1] <- (talks to filter). */ - - if ( dup2(fd[1],STDIN_FILENO) != STDIN_FILENO || - dup2(fd[1],STDOUT_FILENO) != STDOUT_FILENO || - dup2(fd[1],STDERR_FILENO) != STDERR_FILENO ) { - _pam_log(LOG_WARNING - ,"unable to re-assign STDIN/OUT/ERR...'s"); - close(fd[1]); - return PAM_ABORT; - } - - /* make sure that file descriptors survive 'exec's */ - - if ( fcntl(STDIN_FILENO, F_SETFD, 0) || - fcntl(STDOUT_FILENO,F_SETFD, 0) || - fcntl(STDERR_FILENO,F_SETFD, 0) ) { - _pam_log(LOG_WARNING - ,"unable to re-assign STDIN/OUT/ERR...'s"); - return PAM_ABORT; - } - - /* now the user input is read from the parent/filter: forget fd */ - - close(fd[1]); - - /* the current process is now aparently working with filtered - stdio/stdout/stderr --- success! */ - - return PAM_SUCCESS; - } - - /* - * process is the parent here. So we can close the application's - * input/output - */ - - close(fd[1]); - - /* Clear out passwords... there is a security problem here in - * that this process never executes pam_end. Consequently, any - * other sensitive data in this process is *not* explicitly - * overwritten, before the process terminates */ - - (void) pam_set_item(pamh, PAM_AUTHTOK, NULL); - (void) pam_set_item(pamh, PAM_OLDAUTHTOK, NULL); - - /* fork a copy of process to run the actual filter executable */ - - if ( (child2 = fork()) < 0 ) { - - _pam_log(LOG_WARNING,"filter fork failed"); - child2 = 0; - - } else if ( child2 == 0 ) { /* exec the child filter */ - - if ( dup2(fd[0],APPIN_FILENO) != APPIN_FILENO || - dup2(fd[0],APPOUT_FILENO) != APPOUT_FILENO || - dup2(fd[0],APPERR_FILENO) != APPERR_FILENO ) { - _pam_log(LOG_WARNING - ,"unable to re-assign APPIN/OUT/ERR...'s"); - close(fd[0]); - exit(1); - } - - /* make sure that file descriptors survive 'exec's */ - - if ( fcntl(APPIN_FILENO, F_SETFD, 0) == -1 || - fcntl(APPOUT_FILENO,F_SETFD, 0) == -1 || - fcntl(APPERR_FILENO,F_SETFD, 0) == -1 ) { - _pam_log(LOG_WARNING - ,"unable to retain APPIN/OUT/ERR...'s"); - close(APPIN_FILENO); - close(APPOUT_FILENO); - close(APPERR_FILENO); - exit(1); - } - - /* now the user input is read from the parent through filter */ - - execle(filtername, "<pam_filter>", NULL, evp); - - /* getting to here is an error */ - - _pam_log(LOG_ALERT, "filter: %s, not executable", filtername); - - } else { /* wait for either of the two children to exit */ - - while (child && child2) { /* loop if there are two children */ - int lstatus=0; - int chid; - - chid = wait(&lstatus); - if (chid == child) { - - if (WIFEXITED(lstatus)) { /* exited ? */ - status = WEXITSTATUS(lstatus); - } else if (WIFSIGNALED(lstatus)) { /* killed ? */ - status = -1; - } else - continue; /* just stopped etc.. */ - child = 0; /* the child has exited */ - - } else if (chid == child2) { - /* - * if the filter has exited. Let the child die - * naturally below - */ - if (WIFEXITED(lstatus) || WIFSIGNALED(lstatus)) - child2 = 0; - } else { - - _pam_log(LOG_ALERT - ,"programming error <chid=%d,lstatus=%x>: " - __FILE__ " line %d" - , lstatus, __LINE__ ); - child = child2 = 0; - status = -1; - - } - } - } - - close(fd[0]); - - /* if there is something running, wait for it to exit */ - - while (child || child2) { - int lstatus=0; - int chid; - - chid = wait(&lstatus); - - if (child && chid == child) { - - if (WIFEXITED(lstatus)) { /* exited ? */ - status = WEXITSTATUS(lstatus); - } else if (WIFSIGNALED(lstatus)) { /* killed ? */ - status = -1; - } else - continue; /* just stopped etc.. */ - child = 0; /* the child has exited */ - - } else if (child2 && chid == child2) { - - if (WIFEXITED(lstatus) || WIFSIGNALED(lstatus)) - child2 = 0; - - } else { - - _pam_log(LOG_ALERT - ,"programming error <chid=%d,lstatus=%x>: " - __FILE__ " line %d" - , lstatus, __LINE__ ); - child = child2 = 0; - status = -1; - - } - } - - if (aterminal) { - /* reset to initial terminal mode */ - (void) tcsetattr(STDIN_FILENO, TCSANOW, &stored_mode); - } - - if (ctrl & FILTER_DEBUG) { - _pam_log(LOG_DEBUG,"parent process exited"); /* clock off */ - } - - /* quit the parent process, returning the child's exit status */ - - exit(status); -} - -static int set_the_terminal(pam_handle_t *pamh) -{ - const char *tty; - - if (pam_get_item(pamh, PAM_TTY, (const void **)&tty) != PAM_SUCCESS - || tty == NULL) { - tty = ttyname(STDIN_FILENO); - if (tty == NULL) { - _pam_log(LOG_ERR, "couldn't get the tty name"); - return PAM_ABORT; - } - if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) { - _pam_log(LOG_ERR, "couldn't set tty name"); - return PAM_ABORT; - } - } - return PAM_SUCCESS; -} - -static int need_a_filter(pam_handle_t *pamh - , int flags, int argc, const char **argv - , const char *name, int which_run) -{ - int ctrl; - char **evp; - const char *filterfile; - int retval; - - ctrl = process_args(pamh, argc, argv, name, &evp, &filterfile); - if (ctrl == -1) { - return PAM_AUTHINFO_UNAVAIL; - } - - /* set the tty to the old or the new one? */ - - if (!(ctrl & NON_TERM) && !(ctrl & NEW_TERM)) { - retval = set_the_terminal(pamh); - if (retval != PAM_SUCCESS) { - _pam_log(LOG_ERR, "tried and failed to set PAM_TTY"); - } - } else { - retval = PAM_SUCCESS; /* nothing to do which is always a success */ - } - - if (retval == PAM_SUCCESS && (ctrl & which_run)) { - retval = set_filter(pamh, flags, ctrl - , (const char **)evp, filterfile); - } - - if (retval == PAM_SUCCESS - && !(ctrl & NON_TERM) && (ctrl & NEW_TERM)) { - retval = set_the_terminal(pamh); - if (retval != PAM_SUCCESS) { - _pam_log(LOG_ERR - , "tried and failed to set new terminal as PAM_TTY"); - } - } - - free_evp(evp); - - if (ctrl & FILTER_DEBUG) { - _pam_log(LOG_DEBUG, "filter/%s, returning %d", name, retval); - _pam_log(LOG_DEBUG, "[%s]", pam_strerror(pamh, retval)); - } - - return retval; -} - -/* ----------------- public functions ---------------- */ - -/* - * here are the advertised access points ... - */ - -/* ------------------ authentication ----------------- */ - -PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh - , int flags, int argc, const char **argv) -{ - return need_a_filter(pamh, flags, argc, argv - , "authenticate", FILTER_RUN1); -} - -PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags - , int argc, const char **argv) -{ - return need_a_filter(pamh, flags, argc, argv, "setcred", FILTER_RUN2); -} - -/* --------------- account management ---------------- */ - -PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return need_a_filter(pamh, flags, argc, argv - , "setcred", FILTER_RUN1|FILTER_RUN2 ); -} - -/* --------------- session management ---------------- */ - -PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags - , int argc, const char **argv) -{ - return need_a_filter(pamh, flags, argc, argv - , "open_session", FILTER_RUN1); -} - -PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags - , int argc, const char **argv) -{ - return need_a_filter(pamh, flags, argc, argv - , "close_session", FILTER_RUN2); -} - -/* --------- updating authentication tokens --------- */ - - -PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags - , int argc, const char **argv) -{ - int runN; - - if (flags & PAM_PRELIM_CHECK) - runN = FILTER_RUN1; - else if (flags & PAM_UPDATE_AUTHTOK) - runN = FILTER_RUN2; - else { - _pam_log(LOG_ERR, "unknown flags for chauthtok (0x%X)", flags); - return PAM_TRY_AGAIN; - } - - return need_a_filter(pamh, flags, argc, argv, "chauthtok", runN); -} - -#ifdef PAM_STATIC - -/* ------------ stuff for static modules ------------ */ - -struct pam_module _pam_filter_modstruct = { - "pam_filter", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok, -}; - -#endif diff --git a/modules/pam_filter/upperLOWER/.cvsignore b/modules/pam_filter/upperLOWER/.cvsignore deleted file mode 100644 index bcd63650..00000000 --- a/modules/pam_filter/upperLOWER/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -upperLOWER diff --git a/modules/pam_filter/upperLOWER/Makefile b/modules/pam_filter/upperLOWER/Makefile deleted file mode 100644 index 60c6d08c..00000000 --- a/modules/pam_filter/upperLOWER/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -# -# $Id$ -# -# This directory contains a pam_filter filter executable -# -# Created by Andrew Morgan <morgan@transmeta.com> 1996/3/11 -# - -include ../../../Make.Rules - -TITLE=upperLOWER - -# - -CFLAGS += -I../include -I../../pammodutil/include - -OBJS = $(TITLE).o - -LIBS += $(GLIB_LIBS) -L../../pammodutil -lpammodutil -LDFLAGS = $(LIBS) - -####################### don't edit below ####################### - -all: $(TITLE) - -$(TITLE): $(OBJS) - $(CC) $(CFLAGS) -o $(TITLE) $(OBJS) $(LDFLAGS) - $(STRIP) $(TITLE) - -install: - $(MKDIR) $(FAKEROOT)$(FILTERSDIR) - $(INSTALL) -m 511 $(TITLE) $(FAKEROOT)$(FILTERSDIR) - -remove: - cd $(FAKEROOT)$(FILTERSDIR) && rm -f $(TITLE) - -clean: - rm -f $(TITLE) $(OBJS) core *~ - -.c.o: - $(CC) $(CFLAGS) -c $< - diff --git a/modules/pam_filter/upperLOWER/upperLOWER.c b/modules/pam_filter/upperLOWER/upperLOWER.c deleted file mode 100644 index 72f9dab5..00000000 --- a/modules/pam_filter/upperLOWER/upperLOWER.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * $Id$ - * - * This is a sample filter program, for use with pam_filter (a module - * provided with Linux-PAM). This filter simply transposes upper and - * lower case letters, it is intended for demonstration purposes and - * it serves no purpose other than to annoy the user... - */ - -#include <security/_pam_aconf.h> - -#ifdef MEMORY_DEBUG -# undef exit -#endif /* MEMORY_DEBUG */ - -#include <stdio.h> -#include <stdlib.h> -#include <syslog.h> -#include <sys/time.h> -#include <sys/types.h> -#include <unistd.h> - -#include <security/pam_filter.h> -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/_pam_modutil.h> - -/* ---------------------------------------------------------------- */ - -#include <stdarg.h> -#ifdef hpux -# define log_this syslog -#else -static void log_this(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("upperLOWER", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} -#endif - -#include <ctype.h> - -static void do_transpose(char *buffer,int len) -{ - int i; - for (i=0; i<len; ++i) { - if (islower(buffer[i])) { - buffer[i] = toupper(buffer[i]); - } else { - buffer[i] = tolower(buffer[i]); - } - } -} - -extern char **environ; - -int main(int argc, char **argv) -{ - char buffer[BUFSIZ]; - fd_set readers; - void (*before_user)(char *,int); - void (*before_app)(char *,int); - -#ifdef DEBUG - { - int i; - - fprintf(stderr,"environment :[\r\n"); - for (i=0; environ[i]; ++i) { - fprintf(stderr,"-> %s\r\n",environ[i]); - } - fprintf(stderr,"]: end\r\n"); - } -#endif - - if (argc != 1) { -#ifdef DEBUG - fprintf(stderr,"filter invoked as conventional executable\n"); -#else - log_this(LOG_ERR, "filter invoked as conventional executable"); -#endif - exit(1); - } - - before_user = before_app = do_transpose; /* assign filter functions */ - - /* enter a loop that deals with the input and output of the - user.. passing it to and from the application */ - - FD_ZERO(&readers); /* initialize reading mask */ - - for (;;) { - - FD_SET(APPOUT_FILENO, &readers); /* wake for output */ - FD_SET(APPERR_FILENO, &readers); /* wake for error */ - FD_SET(STDIN_FILENO, &readers); /* wake for input */ - - if ( select(APPTOP_FILE,&readers,NULL,NULL,NULL) < 0 ) { -#ifdef DEBUG - fprintf(stderr,"select failed\n"); -#else - log_this(LOG_WARNING,"select failed"); -#endif - break; - } - - /* application errors */ - - if ( FD_ISSET(APPERR_FILENO,&readers) ) { - int got = _pammodutil_read(APPERR_FILENO, buffer, BUFSIZ); - if (got <= 0) { - break; - } else { - /* translate to give to real terminal */ - if (before_user != NULL) - before_user(buffer, got); - if (_pammodutil_write(STDERR_FILENO, buffer, got) != got ) { - log_this(LOG_WARNING,"couldn't write %d bytes?!",got); - break; - } - } - } else if ( FD_ISSET(APPOUT_FILENO,&readers) ) { /* app output */ - int got = _pammodutil_read(APPOUT_FILENO, buffer, BUFSIZ); - if (got <= 0) { - break; - } else { - /* translate to give to real terminal */ - if (before_user != NULL) - before_user(buffer, got); - if (_pammodutil_write(STDOUT_FILENO, buffer, got) != got ) { - log_this(LOG_WARNING,"couldn't write %d bytes!?",got); - break; - } - } - } - - if ( FD_ISSET(STDIN_FILENO, &readers) ) { /* user input */ - int got = _pammodutil_read(STDIN_FILENO, buffer, BUFSIZ); - if (got < 0) { - log_this(LOG_WARNING,"user input junked"); - break; - } else if (got) { - /* translate to give to application */ - if (before_app != NULL) - before_app(buffer, got); - if (_pammodutil_write(APPIN_FILENO, buffer, got) != got ) { - log_this(LOG_WARNING,"couldn't pass %d bytes!?",got); - break; - } - } else { - /* nothing received -- an error? */ - log_this(LOG_WARNING,"user input null?"); - break; - } - } - } - - exit(0); -} - - - diff --git a/modules/pam_ftp/.cvsignore b/modules/pam_ftp/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_ftp/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_ftp/Makefile b/modules/pam_ftp/Makefile deleted file mode 100644 index fb61ac16..00000000 --- a/modules/pam_ftp/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_ftp - -include ../Simple.Rules diff --git a/modules/pam_ftp/README b/modules/pam_ftp/README deleted file mode 100644 index 6d03330c..00000000 --- a/modules/pam_ftp/README +++ /dev/null @@ -1,18 +0,0 @@ -This is the README for pam_ftp ------------------------------- - -This module is an authentication module that does simple ftp -authentication. - -Recognized arguments: - - "debug" print debug messages - "users=" comma separated list of users which - could login only with email adress - "ignore" allow invalid email adresses - -Options for: -auth: for authentication it provides pam_authenticate() and - pam_setcred() hooks. - -Thorsten Kukuk <kukuk@suse.de>, 17. June 1999 diff --git a/modules/pam_ftp/pam_ftp.c b/modules/pam_ftp/pam_ftp.c deleted file mode 100644 index e95b7d78..00000000 --- a/modules/pam_ftp/pam_ftp.c +++ /dev/null @@ -1,299 +0,0 @@ -/* pam_ftp module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11 - * - */ - -#define PLEASE_ENTER_PASSWORD "Password required for %s." -#define GUEST_LOGIN_PROMPT "Guest login ok, " \ -"send your complete e-mail address as password." - -/* the following is a password that "can't be correct" */ -#define BLOCK_PASSWORD "\177BAD PASSWPRD\177" - -#include <security/_pam_aconf.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <stdarg.h> -#include <string.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> - -/* some syslogging */ - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-ftp", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -static int converse(pam_handle_t *pamh, int nargs - , struct pam_message **message - , struct pam_response **response) -{ - int retval; - struct pam_conv *conv; - - D(("begin to converse\n")); - - retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ; - if ( retval == PAM_SUCCESS && conv ) { - - retval = conv->conv(nargs, ( const struct pam_message ** ) message - , response, conv->appdata_ptr); - - D(("returned from application's conversation function\n")); - - if ((retval != PAM_SUCCESS) && (retval != PAM_CONV_AGAIN)) { - _pam_log(LOG_DEBUG, "conversation failure [%s]" - , pam_strerror(pamh, retval)); - } - - } else { - _pam_log(LOG_ERR, "couldn't obtain coversation function [%s]" - , pam_strerror(pamh, retval)); - if (retval == PAM_SUCCESS) - retval = PAM_BAD_ITEM; /* conv was NULL */ - } - - D(("ready to return from module conversation\n")); - - return retval; /* propagate error status */ -} - -/* argument parsing */ - -#define PAM_DEBUG_ARG 01 -#define PAM_IGNORE_EMAIL 02 -#define PAM_NO_ANON 04 - -static int _pam_parse(int argc, const char **argv, char **users) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strncmp(*argv,"users=",6)) { - *users = x_strdup(6+*argv); - if (*users == NULL) { - ctrl |= PAM_NO_ANON; - _pam_log(LOG_CRIT, "failed to duplicate user list - anon off"); - } - } else if (!strcmp(*argv,"ignore")) { - ctrl |= PAM_IGNORE_EMAIL; - } else { - _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv); - } - } - - return ctrl; -} - -/* - * check if name is in list or default list. place users name in *_user - * return 1 if listed 0 if not. - */ - -static int lookup(const char *name, char *list, const char **_user) -{ - int anon = 0; - - *_user = name; /* this is the default */ - if (list) { - const char *l; - char *x; - - x = list; - while ((l = strtok(x, ","))) { - x = NULL; - if (!strcmp(name, l)) { - *_user = list; - anon = 1; - } - } - } else { -#define MAX_L 2 - static const char *l[MAX_L] = { "ftp", "anonymous" }; - int i; - - for (i=0; i<MAX_L; ++i) { - if (!strcmp(l[i], name)) { - *_user = l[0]; - anon = 1; - break; - } - } - } - - return anon; -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - int retval, anon=0, ctrl; - const char *user; - char *users=NULL; - - /* - * this module checks if the user name is ftp or annonymous. If - * this is the case, it can set the PAM_RUSER to the entered email - * address and SUCCEEDS, otherwise it FAILS. - */ - - ctrl = _pam_parse(argc, argv, &users); - - retval = pam_get_user(pamh, &user, NULL); - if (retval != PAM_SUCCESS || user == NULL) { - _pam_log(LOG_ERR, "no user specified"); - return PAM_USER_UNKNOWN; - } - - if (!(ctrl & PAM_NO_ANON)) { - anon = lookup(user, users, &user); - } - - if (anon) { - retval = pam_set_item(pamh, PAM_USER, (const void *)user); - if (retval != PAM_SUCCESS || user == NULL) { - _pam_log(LOG_ERR, "user resetting failed"); - return PAM_USER_UNKNOWN; - } - } - - /* - * OK. we require an email address for user or the user's password. - * - build conversation and get their input. - */ - - { - struct pam_message msg[1], *mesg[1]; - struct pam_response *resp=NULL; - const char *token; - char *prompt=NULL; - int i=0; - - if (!anon) { - prompt = malloc(strlen(PLEASE_ENTER_PASSWORD) + strlen(user)); - if (prompt == NULL) { - D(("out of memory!?")); - return PAM_BUF_ERR; - } else { - sprintf(prompt, PLEASE_ENTER_PASSWORD, user); - msg[i].msg = prompt; - } - } else { - msg[i].msg = GUEST_LOGIN_PROMPT; - } - - msg[i].msg_style = PAM_PROMPT_ECHO_OFF; - mesg[i] = &msg[i]; - - retval = converse(pamh, ++i, mesg, &resp); - if (prompt) { - _pam_overwrite(prompt); - _pam_drop(prompt); - } - - if (retval != PAM_SUCCESS) { - if (resp != NULL) - _pam_drop_reply(resp,i); - return ((retval == PAM_CONV_AGAIN) - ? PAM_INCOMPLETE:PAM_AUTHINFO_UNAVAIL); - } - - if (anon) { - /* XXX: Some effort should be made to verify this email address! */ - - if (!(ctrl & PAM_IGNORE_EMAIL)) { - token = strtok(resp->resp, "@"); - retval = pam_set_item(pamh, PAM_RUSER, token); - - if ((token) && (retval == PAM_SUCCESS)) { - token = strtok(NULL, "@"); - retval = pam_set_item(pamh, PAM_RHOST, token); - } - } - - /* we are happy to grant annonymous access to the user */ - retval = PAM_SUCCESS; - - } else { - /* - * we have a password so set AUTHTOK - */ - - (void) pam_set_item(pamh, PAM_AUTHTOK, resp->resp); - - /* - * this module failed, but the next one might succeed with - * this password. - */ - - retval = PAM_AUTH_ERR; - } - - if (resp) { /* clean up */ - _pam_drop_reply(resp, i); - } - - /* success or failure */ - - return retval; - } -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_IGNORE; -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_ftp_modstruct = { - "pam_ftp", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL, -}; - -#endif - -/* end of module definition */ 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 44464089..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=\"$(INSTALLED_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 e07a932e..00000000 --- a/modules/pam_group/pam_group.c +++ /dev/null @@ -1,865 +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> -#include <security/_pam_modutil.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; - } -} - -/* This function should initially be called with buf = NULL. If - * an error occurs, the file descriptor is closed. Subsequent - * calls with a closed descriptor will cause buf to be deallocated. - * Therefore, always check buf after calling this to see if an error - * occurred. - */ -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); - close(fd); - 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__ ); - close(fd); - 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(pam_handle_t *pamh, 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 = _pammodutil_getgrnam(pamh, 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(pam_handle_t *pamh, 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(pamh, 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 | PAM_REINITIALIZE_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(pamh, 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(pamh,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 diff --git a/modules/pam_issue/.cvsignore b/modules/pam_issue/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_issue/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_issue/Makefile b/modules/pam_issue/Makefile deleted file mode 100644 index d73710e1..00000000 --- a/modules/pam_issue/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_issue - -include ../Simple.Rules diff --git a/modules/pam_issue/pam_issue.c b/modules/pam_issue/pam_issue.c deleted file mode 100644 index 5665966e..00000000 --- a/modules/pam_issue/pam_issue.c +++ /dev/null @@ -1,327 +0,0 @@ -/* pam_issue module - a simple /etc/issue parser to set PAM_USER_PROMPT - * - * Copyright 1999 by Ben Collins <bcollins@debian.org> - * - * Needs to be called before any other auth modules so we can setup the - * user prompt before it's first used. Allows one argument option, which - * is the full path to a file to be used for issue (uses /etc/issue as a - * default) such as "issue=/etc/issue.telnet". - * - * We can also parse escapes within the the issue file (enabled by - * default, but can be disabled with the "noesc" option). It's the exact - * same parsing as util-linux's agetty program performs. - * - * Released under the GNU LGPL version 2 or later - */ - -#define _GNU_SOURCE -#define _BSD_SOURCE - -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include <sys/utsname.h> -#include <utmp.h> -#include <malloc.h> -#include <time.h> - -#include <security/_pam_macros.h> - -#define PAM_SM_AUTH - -#include <security/pam_modules.h> - -static int _user_prompt_set = 0; - -static char *do_prompt (FILE *); - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - int retval = PAM_SUCCESS; - FILE *fd; - int parse_esc = 1; - char *prompt_tmp = NULL; - const char *cur_prompt = NULL; - struct stat st; - char *issue_file = NULL; - - /* If we've already set the prompt, don't set it again */ - if(_user_prompt_set) - return PAM_IGNORE; - else - /* we set this here so if we fail below, we wont get further - than this next time around (only one real failure) */ - _user_prompt_set = 1; - - for ( ; argc-- > 0 ; ++argv ) { - if (!strncmp(*argv,"issue=",6)) { - issue_file = (char *) strdup(6+*argv); - if (issue_file != NULL) { - D(("set issue_file to: %s", issue_file)); - } else { - D(("failed to strdup issue_file - ignored")); - return PAM_IGNORE; - } - } else if (!strcmp(*argv,"noesc")) { - parse_esc = 0; - D(("turning off escape parsing by request")); - } else - D(("unknown option passed: %s", *argv)); - } - - if (issue_file == NULL) - issue_file = strdup("/etc/issue"); - - if ((fd = fopen(issue_file, "r")) != NULL) { - int tot_size = 0; - - if (fstat(fileno(fd), &st) < 0) { - fclose(fd); - if (issue_file) - free(issue_file); - return PAM_IGNORE; - } - - retval = pam_get_item(pamh, PAM_USER_PROMPT, - (const void **) &cur_prompt); - if (retval != PAM_SUCCESS) { - fclose(fd); - if (issue_file) - free(issue_file); - return PAM_IGNORE; - } - if (cur_prompt == NULL) { - cur_prompt = ""; - } - - /* first read in the issue file */ - - if (parse_esc) { - prompt_tmp = do_prompt(fd); - if (prompt_tmp == NULL) { - fclose(fd); - if (issue_file) - free(issue_file); - return PAM_IGNORE; - } - } else { - int count = 0; - - prompt_tmp = malloc(st.st_size + 1); - if (prompt_tmp == NULL) { - fclose(fd); - if (issue_file) - free(issue_file); - return PAM_IGNORE; - } - memset (prompt_tmp, '\0', st.st_size + 1); - count = fread(prompt_tmp, 1, st.st_size, fd); - if (count != st.st_size) { - fclose(fd); - retval = PAM_IGNORE; - goto cleanup; - } - prompt_tmp[st.st_size] = '\0'; - } - - fclose(fd); - - tot_size = strlen(prompt_tmp) + strlen(cur_prompt) + 1; - - /* - * alloc some extra space for the original prompt - * and postpend it to the buffer - */ - { - char *prompt_tmp_tmp = prompt_tmp; - - prompt_tmp = realloc(prompt_tmp, tot_size + 1); - if (prompt_tmp == NULL) { - prompt_tmp = prompt_tmp_tmp; - retval = PAM_IGNORE; - goto cleanup; - } - } - - strcpy(prompt_tmp+strlen(prompt_tmp), cur_prompt); - - prompt_tmp[tot_size] = '\0'; - - retval = pam_set_item(pamh, PAM_USER_PROMPT, - (const char *) prompt_tmp); - - cleanup: - free(issue_file); - free(prompt_tmp); - - } else { - D(("could not open issue_file: %s", issue_file)); - free(issue_file); - return PAM_IGNORE; - } - - return retval; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return PAM_IGNORE; -} - -static char *do_prompt(FILE *fd) -{ - int c, size = 1024; - char *issue; - char buf[1024]; - struct utsname uts; - - if (fd == NULL) - return NULL; - - issue = (char *)malloc(size); - if (issue == NULL) - return NULL; - - issue[0] = '\0'; /* zero this, for strcat to work on first buf */ - (void) uname(&uts); - - while ((c = getc(fd)) != EOF) { - if (c == '\\') { - c = getc(fd); - switch (c) { - case 's': - snprintf (buf, 1024, "%s", uts.sysname); - break; - case 'n': - snprintf (buf, 1024, "%s", uts.nodename); - break; - case 'r': - snprintf (buf, 1024, "%s", uts.release); - break; - case 'v': - snprintf (buf, 1024, "%s", uts.version); - break; - case 'm': - snprintf (buf, 1024, "%s", uts.machine); - break; - case 'o': - { - char domainname[256]; - - getdomainname(domainname, sizeof(domainname)); - domainname[sizeof(domainname)-1] = '\0'; - snprintf (buf, 1024, "%s", domainname); - } - break; - - case 'd': - case 't': - { - const char *weekday[] = { - "Sun", "Mon", "Tue", "Wed", "Thu", - "Fri", "Sat" }; - const char *month[] = { - "Jan", "Feb", "Mar", "Apr", "May", - "Jun", "Jul", "Aug", "Sep", "Oct", - "Nov", "Dec" }; - time_t now; - struct tm *tm; - - (void) time (&now); - tm = localtime(&now); - - if (c == 'd') - snprintf (buf, 1024, "%s %s %d %d", - weekday[tm->tm_wday], month[tm->tm_mon], - tm->tm_mday, - tm->tm_year + 1900); - else - snprintf (buf, 1024, "%02d:%02d:%02d", - tm->tm_hour, tm->tm_min, tm->tm_sec); - } - break; - case 'l': - { - char *ttyn = ttyname(1); - if (!strncmp(ttyn, "/dev/", 5)) - ttyn += 5; - snprintf (buf, 1024, "%s", ttyn); - } - break; - case 'u': - case 'U': - { - int users = 0; - struct utmp *ut; - setutent(); - while ((ut = getutent())) - if (ut->ut_type == USER_PROCESS) - users++; - endutent(); - printf ("%d ", users); - if (c == 'U') - snprintf (buf, 1024, "%s", (users == 1) ? - " user" : " users"); - break; - } - default: - buf[0] = c; buf[1] = '\0'; - } - if ((strlen(issue) + strlen(buf)) < size + 1) { - char *old_issue = issue; - - size += strlen(buf) + 1; - issue = (char *) realloc (issue, size); - if (issue == NULL) { - free(old_issue); - return NULL; - } - } - strcat(issue, buf); - } else { - buf[0] = c; buf[1] = '\0'; - if ((strlen(issue) + strlen(buf)) < size + 1) { - char *old_issue = issue; - - size += strlen(buf) + 1; - issue = (char *) realloc (issue, size); - if (issue == NULL) { - free(old_issue); - return NULL; - } - } - strcat(issue, buf); - } - } - - return issue; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_issue_modstruct = { - "pam_issue", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_lastlog/.cvsignore b/modules/pam_lastlog/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_lastlog/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_lastlog/Makefile b/modules/pam_lastlog/Makefile deleted file mode 100644 index 333ecd93..00000000 --- a/modules/pam_lastlog/Makefile +++ /dev/null @@ -1,19 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -ifeq ($(HAVE_LIBUTIL),yes) - MODULE_SIMPLE_EXTRALIBS += -lutil -endif - -TITLE=pam_lastlog - -include ../Simple.Rules diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c deleted file mode 100644 index e9eeac4e..00000000 --- a/modules/pam_lastlog/pam_lastlog.c +++ /dev/null @@ -1,470 +0,0 @@ -/* pam_lastlog module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11 - * - * This module does the necessary work to display the last login - * time+date for this user, it then updates this entry for the - * present (login) service. - */ - -#include <security/_pam_aconf.h> - -#include <fcntl.h> -#include <time.h> -#ifdef HAVE_UTMP_H -# include <utmp.h> -#else -# include <lastlog.h> -#endif -#include <pwd.h> -#include <stdlib.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <syslog.h> -#include <unistd.h> - -#ifdef WANT_PWDB -#include <pwdb/pwdb_public.h> /* use POSIX front end */ -#endif - -#if defined(hpux) || defined(sunos) || defined(solaris) -# ifndef _PATH_LASTLOG -# define _PATH_LASTLOG "/usr/adm/lastlog" -# endif /* _PATH_LASTLOG */ -# ifndef UT_HOSTSIZE -# define UT_HOSTSIZE 16 -# endif /* UT_HOSTSIZE */ -# ifndef UT_LINESIZE -# define UT_LINESIZE 12 -# endif /* UT_LINESIZE */ -#endif -#if defined(hpux) -struct lastlog { - time_t ll_time; - char ll_line[UT_LINESIZE]; - char ll_host[UT_HOSTSIZE]; /* same as in utmp */ -}; -#endif /* hpux */ - -/* XXX - time before ignoring lock. Is 1 sec enough? */ -#define LASTLOG_IGNORE_LOCK_TIME 1 - -#define DEFAULT_HOST "" /* "[no.where]" */ -#define DEFAULT_TERM "" /* "tt???" */ -#define LASTLOG_NEVER_WELCOME "Welcome to your new account!" -#define LASTLOG_INTRO "Last login:" -#define LASTLOG_TIME " %s" -#define _LASTLOG_HOST_FORMAT " from %%.%ds" -#define _LASTLOG_LINE_FORMAT " on %%.%ds" -#define LASTLOG_TAIL "" -#define LASTLOG_MAXSIZE (sizeof(LASTLOG_INTRO)+0 \ - +sizeof(LASTLOG_TIME)+strlen(the_time) \ - +sizeof(_LASTLOG_HOST_FORMAT)+UT_HOSTSIZE \ - +sizeof(_LASTLOG_LINE_FORMAT)+UT_LINESIZE \ - +sizeof(LASTLOG_TAIL)) - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_SESSION - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/_pam_modutil.h> - -/* some syslogging */ - -static void _log_err(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-lastlog", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -/* argument parsing */ - -#define LASTLOG_DATE 01 /* display the date of the last login */ -#define LASTLOG_HOST 02 /* display the last host used (if set) */ -#define LASTLOG_LINE 04 /* display the last terminal used */ -#define LASTLOG_NEVER 010 /* display a welcome message for first login */ -#define LASTLOG_DEBUG 020 /* send info to syslog(3) */ -#define LASTLOG_QUIET 040 /* keep quiet about things */ - -static int _pam_parse(int flags, int argc, const char **argv) -{ - int ctrl=(LASTLOG_DATE|LASTLOG_HOST|LASTLOG_LINE); - - /* does the appliction require quiet? */ - if (flags & PAM_SILENT) { - ctrl |= LASTLOG_QUIET; - } - - /* step through arguments */ - for (; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) { - ctrl |= LASTLOG_DEBUG; - } else if (!strcmp(*argv,"nodate")) { - ctrl |= ~LASTLOG_DATE; - } else if (!strcmp(*argv,"noterm")) { - ctrl |= ~LASTLOG_LINE; - } else if (!strcmp(*argv,"nohost")) { - ctrl |= ~LASTLOG_HOST; - } else if (!strcmp(*argv,"silent")) { - ctrl |= LASTLOG_QUIET; - } else if (!strcmp(*argv,"never")) { - ctrl |= LASTLOG_NEVER; - } else { - _log_err(LOG_ERR,"unknown option; %s",*argv); - } - } - - D(("ctrl = %o", ctrl)); - return ctrl; -} - -/* a front end for conversations */ - -static int converse(pam_handle_t *pamh, int ctrl, int nargs - , struct pam_message **message - , struct pam_response **response) -{ - int retval; - struct pam_conv *conv; - - D(("begin to converse")); - - retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ; - if ( retval == PAM_SUCCESS && conv) { - - retval = conv->conv(nargs, ( const struct pam_message ** ) message - , response, conv->appdata_ptr); - - D(("returned from application's conversation function")); - - if (retval != PAM_SUCCESS && (ctrl & LASTLOG_DEBUG) ) { - _log_err(LOG_DEBUG, "conversation failure [%s]" - , pam_strerror(pamh, retval)); - } - - } else { - _log_err(LOG_ERR, "couldn't obtain coversation function [%s]" - , pam_strerror(pamh, retval)); - if (retval == PAM_SUCCESS) - retval = PAM_BAD_ITEM; /* conv was NULL */ - } - - D(("ready to return from module conversation")); - - return retval; /* propagate error status */ -} - -static int make_remark(pam_handle_t *pamh, int ctrl, const char *remark) -{ - int retval; - - if (!(ctrl & LASTLOG_QUIET)) { - struct pam_message msg[1], *mesg[1]; - struct pam_response *resp=NULL; - - mesg[0] = &msg[0]; - msg[0].msg_style = PAM_TEXT_INFO; - msg[0].msg = remark; - - retval = converse(pamh, ctrl, 1, mesg, &resp); - - msg[0].msg = NULL; - if (resp) { - _pam_drop_reply(resp, 1); - } - } else { - D(("keeping quiet")); - retval = PAM_SUCCESS; - } - - D(("returning %s", pam_strerror(pamh, retval))); - return retval; -} - -/* - * Values for the announce flags.. - */ - -static int last_login_date(pam_handle_t *pamh, int announce, uid_t uid) -{ - struct flock last_lock; - struct lastlog last_login; - int retval = PAM_SESSION_ERR; - int last_fd; - - /* obtain the last login date and all the relevant info */ - last_fd = open(_PATH_LASTLOG, O_RDWR); - if (last_fd < 0) { - D(("unable to open the %s file", _PATH_LASTLOG)); - if (announce & LASTLOG_DEBUG) { - _log_err(LOG_DEBUG, "unable to open %s file", _PATH_LASTLOG); - } - retval = PAM_PERM_DENIED; - } else { - int win; - - /* read the lastlogin file - for this uid */ - (void) lseek(last_fd, sizeof(last_login) * (off_t) uid, SEEK_SET); - - memset(&last_lock, 0, sizeof(last_lock)); - last_lock.l_type = F_RDLCK; - last_lock.l_whence = SEEK_SET; - last_lock.l_start = sizeof(last_login) * (off_t) uid; - last_lock.l_len = sizeof(last_login); - - if ( fcntl(last_fd, F_SETLK, &last_lock) < 0 ) { - D(("locking %s failed..(waiting a little)", _PATH_LASTLOG)); - _log_err(LOG_ALERT, "%s file is locked/read", _PATH_LASTLOG); - sleep(LASTLOG_IGNORE_LOCK_TIME); - } - - win = (_pammodutil_read (last_fd, (char *) &last_login, - sizeof(last_login)) == sizeof(last_login)); - - last_lock.l_type = F_UNLCK; - (void) fcntl(last_fd, F_SETLK, &last_lock); /* unlock */ - - if (!win) { - D(("First login for user uid=%d", _PATH_LASTLOG, uid)); - if (announce & LASTLOG_DEBUG) { - _log_err(LOG_DEBUG, "creating lastlog for uid %d", uid); - } - memset(&last_login, 0, sizeof(last_login)); - } - - /* rewind */ - (void) lseek(last_fd, sizeof(last_login) * (off_t) uid, SEEK_SET); - - if (!(announce & LASTLOG_QUIET)) { - if (last_login.ll_time) { - time_t ll_time; - char *the_time; - char *remark; - - ll_time = last_login.ll_time; - the_time = ctime(&ll_time); - the_time[-1+strlen(the_time)] = '\0'; /* delete '\n' */ - - remark = malloc(LASTLOG_MAXSIZE); - if (remark == NULL) { - D(("no memory for last login remark")); - retval = PAM_BUF_ERR; - } else { - int at; - - /* printing prefix */ - at = sprintf(remark, "%s", LASTLOG_INTRO); - - /* we want the date? */ - if (announce & LASTLOG_DATE) { - at += sprintf(remark+at, LASTLOG_TIME, the_time); - } - - /* we want & have the host? */ - if ((announce & LASTLOG_HOST) - && (last_login.ll_host[0] != '\0')) { - char format[2*sizeof(_LASTLOG_HOST_FORMAT)]; - - (void) sprintf(format, _LASTLOG_HOST_FORMAT - , UT_HOSTSIZE); - D(("format: %s", format)); - at += sprintf(remark+at, format, last_login.ll_host); - _pam_overwrite(format); - } - - /* we want and have the terminal? */ - if ((announce & LASTLOG_LINE) - && (last_login.ll_line[0] != '\0')) { - char format[2*sizeof(_LASTLOG_LINE_FORMAT)]; - - (void) sprintf(format, _LASTLOG_LINE_FORMAT - , UT_LINESIZE); - D(("format: %s", format)); - at += sprintf(remark+at, format, last_login.ll_line); - _pam_overwrite(format); - } - - /* display requested combo */ - sprintf(remark+at, "%s", LASTLOG_TAIL); - - retval = make_remark(pamh, announce, remark); - - /* free all the stuff malloced */ - _pam_overwrite(remark); - _pam_drop(remark); - } - } else if ((!last_login.ll_time) && (announce & LASTLOG_NEVER)) { - D(("this is the first time this user has logged in")); - retval = make_remark(pamh, announce, LASTLOG_NEVER_WELCOME); - } - } else { - D(("no text was requested")); - retval = PAM_SUCCESS; - } - - /* write latest value */ - { - time_t ll_time; - const char *remote_host=NULL - , *terminal_line=DEFAULT_TERM; - - /* set this login date */ - D(("set the most recent login time")); - - (void) time(&ll_time); /* set the time */ - last_login.ll_time = ll_time; - - /* set the remote host */ - (void) pam_get_item(pamh, PAM_RHOST, (const void **)&remote_host); - if (remote_host == NULL) { - remote_host = DEFAULT_HOST; - } - - /* copy to last_login */ - strncpy(last_login.ll_host, remote_host, - sizeof(last_login.ll_host)); - last_login.ll_host[sizeof(last_login.ll_host) - 1] = '\0'; - remote_host = NULL; - - /* set the terminal line */ - (void) pam_get_item(pamh, PAM_TTY, (const void **)&terminal_line); - D(("terminal = %s", terminal_line)); - if (terminal_line == NULL) { - terminal_line = DEFAULT_TERM; - } else if ( !strncmp("/dev/", terminal_line, 5) ) { - /* strip leading "/dev/" from tty.. */ - terminal_line += 5; - } - D(("terminal = %s", terminal_line)); - - /* copy to last_login */ - strncpy(last_login.ll_line, terminal_line, - sizeof(last_login.ll_line)); - last_login.ll_host[sizeof(last_login.ll_host) - 1] = '\0'; - terminal_line = NULL; - - D(("locking last_log file")); - - /* now we try to lock this file-record exclusively; non-blocking */ - memset(&last_lock, 0, sizeof(last_lock)); - last_lock.l_type = F_WRLCK; - last_lock.l_whence = SEEK_SET; - last_lock.l_start = sizeof(last_login) * (off_t) uid; - last_lock.l_len = sizeof(last_login); - - if ( fcntl(last_fd, F_SETLK, &last_lock) < 0 ) { - D(("locking %s failed..(waiting a little)", _PATH_LASTLOG)); - _log_err(LOG_ALERT, "%s file is locked/write", _PATH_LASTLOG); - sleep(LASTLOG_IGNORE_LOCK_TIME); - } - - D(("writing to the last_log file")); - _pammodutil_write (last_fd, (char *) &last_login, - sizeof (last_login)); - - last_lock.l_type = F_UNLCK; - (void) fcntl(last_fd, F_SETLK, &last_lock); /* unlock */ - D(("unlocked")); - - close(last_fd); /* all done */ - } - D(("all done with last login")); - } - - /* reset the last login structure */ - memset(&last_login, 0, sizeof(last_login)); - - return retval; -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc - , const char **argv) -{ - int retval, ctrl; - const char *user; - const struct passwd *pwd; - uid_t uid; - - /* - * this module gets the uid of the PAM_USER. Uses it to display - * last login info and then updates the lastlog for that user. - */ - - ctrl = _pam_parse(flags, argc, argv); - - /* which user? */ - - retval = pam_get_item(pamh, PAM_USER, (const void **)&user); - if (retval != PAM_SUCCESS || user == NULL || *user == '\0') { - _log_err(LOG_NOTICE, "user unknown"); - return PAM_USER_UNKNOWN; - } - - /* what uid? */ - - pwd = _pammodutil_getpwnam (pamh, user); - if (pwd == NULL) { - D(("couldn't identify user %s", user)); - return PAM_CRED_INSUFFICIENT; - } - uid = pwd->pw_uid; - pwd = NULL; /* tidy up */ - - /* process the current login attempt (indicate last) */ - - retval = last_login_date(pamh, ctrl, uid); - - /* indicate success or failure */ - - uid = -1; /* forget this */ - - return retval; -} - -PAM_EXTERN -int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_SUCCESS; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_lastlog_modstruct = { - "pam_lastlog", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_limits/.cvsignore b/modules/pam_limits/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_limits/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_limits/Makefile b/modules/pam_limits/Makefile deleted file mode 100644 index 5aeb73ce..00000000 --- a/modules/pam_limits/Makefile +++ /dev/null @@ -1,37 +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_limits - -ifeq ($(OS),linux) - -LOCAL_CONFILE=./limits.skel -INSTALLED_CONFILE=$(SCONFIGD)/limits.conf - -DEFS=-DDEFAULT_CONF_FILE=\"$(INSTALLED_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 -ifeq ($(HAVE_LIBCAP),yes) -MODULE_SIMPLE_EXTRALIBS=-lcap -endif - -include ../Simple.Rules - -#else -#include ../dont_makefile -#endif -else - -include ../dont_makefile - -endif diff --git a/modules/pam_limits/README b/modules/pam_limits/README deleted file mode 100644 index 32afb197..00000000 --- a/modules/pam_limits/README +++ /dev/null @@ -1,110 +0,0 @@ - -pam_limits module: - Imposing user limits on login. - -THEORY OF OPERATION: - -First, make a root-only-readable file (/etc/security/limits.conf by -default or INSTALLED_CONFILE defined Makefile) that describes the -resource limits you wish to impose. No limits are imposed on UID 0 -accounts. - -Each line describes a limit for a user in the form: - -<domain> <type> <item> <value> - -Where: -<domain> can be: - - an user name - - a group name, with @group syntax - - the wildcard *, for default entry - -<type> can have the three values: - - "soft" for enforcing the soft limits - - "hard" for enforcing hard limits - - "-" for enforcing both soft and hard limits - -<item> can be one of the following: - - core - limits the core file size (KB) - - data - max data size (KB) - - fsize - maximum filesize (KB) - - memlock - max locked-in-memory address space (KB) - - nofile - max number of open files - - rss - max resident set size (KB) - - stack - max stack size (KB) - - cpu - max CPU time (MIN) - - nproc - max number of processes - - as - address space limit - - maxlogins - max number of logins for this user - - maxsyslogins - max number of logins on the system - - priority - lower the priority by given value (value can be -ve) - - locks - max locked files (Linux 2.4 and higher) - - sigpending - max number of pending signals (Linux 2.6 and higher) - - msgqueue - max memory used by POSIX message queues (bytes) - (Linux 2.6 and higher) - -Note, if you specify a type of '-' but neglect to supply the item and -value fields then the module will never enforce any limits on the -specified user/group etc. . - -Please remember that individual limits have priority over group -limits, so if you impose no limits for admin group, but one of the -members in this group has a limits line, the user will have its limits -set according to this line. - -Also, please note that all limit settings are set PER LOGIN. They are -not global, nor are they permanent (they apply for the session only). - -In the LIMITS_FILE, the # character introduces a comment - the rest of the -line is ignored. - -The pam_limits module does its best to report configuration problems found -in LIMITS_FILE via syslog. - -EXAMPLE configuration file: -=========================== -* soft core 0 -* hard rss 10000 -@student hard nproc 20 -@faculty soft nproc 20 -@faculty hard nproc 50 -ftp hard nproc 0 -@student - maxlogins 4 - - -ARGUMENTS RECOGNIZED: - debug verbose logging - - conf=/path/to/file the limits configuration file if different from the - one set at compile time. - - change_uid change real uid to the user for who the limits - are set up. Use this option if you have problems - like login not forking a shell for user who has - no processes. Be warned that something else - may break when you do this. - - utmp_early some broken applications actually allocate a - utmp entry for the user before the user is - admitted to the system. If the service you are - configuring PAM for does this, you can use - this module argument to compensate for this - brokenness. - -MODULE SERVICES PROVIDED: - session _open_session and _close_session (blank) - -USAGE: - For the services you need resources limits (login for example) put a - the following line in /etc/pam.conf as the last line for that - service (usually after the pam_unix session line: - - login session required /lib/security/pam_limits.so - - Replace "login" for each service you are using this module, replace - "/lib/security" path with your real modules path. - -AUTHOR: - Cristian Gafton <gafton@redhat.com> - Thanks to Elliot Lee <sopwith@redhat.com> for his comments on - improving this module, and Jens Sorensen for Linux 2.4 updates. diff --git a/modules/pam_limits/limits.skel b/modules/pam_limits/limits.skel deleted file mode 100644 index 9ba31b19..00000000 --- a/modules/pam_limits/limits.skel +++ /dev/null @@ -1,47 +0,0 @@ -# /etc/security/limits.conf -# -#Each line describes a limit for a user in the form: -# -#<domain> <type> <item> <value> -# -#Where: -#<domain> can be: -# - an user name -# - a group name, with @group syntax -# - the wildcard *, for default entry -# - the wildcard %, can be also used with %group syntax, -# for maxlogin limit -# -#<type> can have the two values: -# - "soft" for enforcing the soft limits -# - "hard" for enforcing hard limits -# -#<item> can be one of the following: -# - core - limits the core file size (KB) -# - data - max data size (KB) -# - fsize - maximum filesize (KB) -# - memlock - max locked-in-memory address space (KB) -# - nofile - max number of open files -# - rss - max resident set size (KB) -# - stack - max stack size (KB) -# - cpu - max CPU time (MIN) -# - nproc - max number of processes -# - as - address space limit -# - maxlogins - max number of logins for this user -# - priority - the priority to run user process with -# - locks - max number of file locks the user can hold -# - sigpending - max number of pending signals -# - msgqueue - max memory used by POSIX message queues (bytes) -# -#<domain> <type> <item> <value> -# - -#* soft core 0 -#* hard rss 10000 -#@student hard nproc 20 -#@faculty soft nproc 20 -#@faculty hard nproc 50 -#ftp hard nproc 0 -#@student - maxlogins 4 - -# End of file diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c deleted file mode 100644 index 1482833a..00000000 --- a/modules/pam_limits/pam_limits.c +++ /dev/null @@ -1,685 +0,0 @@ -/* - * pam_limits - impose resource limits when opening a user session - * - * 1.6 - modified for PLD (added process priority settings) - * by Marcin Korzonek <mkorz@shadow.eu.org> - * 1.5 - Elliot Lee's "max system logins patch" - * 1.4 - addressed bug in configuration file parser - * 1.3 - modified the configuration file format - * 1.2 - added 'debug' and 'conf=' arguments - * 1.1 - added @group support - * 1.0 - initial release - Linux ONLY - * - * See end for Copyright information - */ - -#if !(defined(linux)) -#error THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!! -#endif - -#include <security/_pam_aconf.h> - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> -#include <stdlib.h> -#include <errno.h> -#include <syslog.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/resource.h> - -#include <utmp.h> -#ifndef UT_USER /* some systems have ut_name instead of ut_user */ -#define UT_USER ut_user -#endif - -#include <grp.h> -#include <pwd.h> - -/* Module defines */ -#define LINE_LENGTH 1024 - -#define LIMITS_DEF_USER 0 /* limit was set by an user entry */ -#define LIMITS_DEF_GROUP 1 /* limit was set by a group entry */ -#define LIMITS_DEF_ALLGROUP 2 /* limit was set by a group entry */ -#define LIMITS_DEF_ALL 3 /* limit was set by an default entry */ -#define LIMITS_DEF_DEFAULT 4 /* limit was set by an default entry */ -#define LIMITS_DEF_NONE 5 /* this limit was not set yet */ - -static const char *limits_def_names[] = { - "USER", - "GROUP", - "ALLGROUP", - "ALL", - "DEFAULT", - "NONE", - NULL -}; - -struct user_limits_struct { - int src_soft; - int src_hard; - struct rlimit limit; -}; - -/* internal data */ -struct pam_limit_s { - int login_limit; /* the max logins limit */ - int login_limit_def; /* which entry set the login limit */ - int flag_numsyslogins; /* whether to limit logins only for a - specific user or to count all logins */ - int priority; /* the priority to run user process with */ - int supported[RLIM_NLIMITS]; - struct user_limits_struct limits[RLIM_NLIMITS]; - char conf_file[BUFSIZ]; - int utmp_after_pam_call; - char login_group[LINE_LENGTH]; -}; - -#define LIMIT_LOGIN RLIM_NLIMITS+1 -#define LIMIT_NUMSYSLOGINS RLIM_NLIMITS+2 - -#define LIMIT_PRI RLIM_NLIMITS+3 - -#define LIMIT_SOFT 1 -#define LIMIT_HARD 2 - -#define PAM_SM_SESSION - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/_pam_modutil.h> - -/* logging */ -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("pam_limits", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -/* argument parsing */ - -#define PAM_DEBUG_ARG 0x0001 -#define PAM_DO_SETREUID 0x0002 -#define PAM_UTMP_EARLY 0x0004 - -static int _pam_parse(int argc, const char **argv, struct pam_limit_s *pl) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) { - ctrl |= PAM_DEBUG_ARG; - } else if (!strncmp(*argv,"conf=",5)) { - strncpy(pl->conf_file,*argv+5,sizeof(pl->conf_file)-1); - } else if (!strncmp(*argv,"change_uid",10)) { - ctrl |= PAM_DO_SETREUID; - } else if (!strcmp(*argv,"utmp_early")) { - ctrl |= PAM_UTMP_EARLY; - } else { - _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv); - } - } - pl->conf_file[sizeof(pl->conf_file) - 1] = '\0'; - - return ctrl; -} - - -/* limits stuff */ -#ifdef DEFAULT_CONF_FILE -# define LIMITS_FILE DEFAULT_CONF_FILE -#else -# define LIMITS_FILE "/etc/security/limits.conf" -#endif - -#define LIMITED_OK 0 /* limit setting appeared to work */ -#define LIMIT_ERR 1 /* error setting a limit */ -#define LOGIN_ERR 2 /* too many logins err */ - -/* Counts the number of user logins and check against the limit*/ -static int -check_logins (pam_handle_t *pamh, const char *name, int limit, int ctrl, - struct pam_limit_s *pl) -{ - struct utmp *ut; - unsigned int count; - - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_DEBUG, "checking logins for '%s' (maximum of %d)\n", - name, limit); - } - - if (limit < 0) - return 0; /* no limits imposed */ - if (limit == 0) /* maximum 0 logins ? */ { - _pam_log(LOG_WARNING, "No logins allowed for '%s'\n", name); - return LOGIN_ERR; - } - - setutent(); - - /* Because there is no definition about when an application - actually adds a utmp entry, some applications bizarrely do the - utmp call before the have PAM authenticate them to the system: - you're logged it, sort of...? Anyway, you can use the - "utmp_early" module argument in your PAM config file to make - allowances for this sort of problem. (There should be a PAM - standard for this, since if a module wants to actually map a - username then any early utmp entry will be for the unmapped - name = broken.) */ - - if (ctrl & PAM_UTMP_EARLY) { - count = 0; - } else { - count = 1; - } - - while((ut = getutent())) { -#ifdef USER_PROCESS - if (ut->ut_type != USER_PROCESS) { - continue; - } -#endif - if (ut->UT_USER[0] == '\0') { - continue; - } - if (!pl->flag_numsyslogins) { - if (((pl->login_limit_def == LIMITS_DEF_USER) - || (pl->login_limit_def == LIMITS_DEF_GROUP) - || (pl->login_limit_def == LIMITS_DEF_DEFAULT)) - && strncmp(name, ut->UT_USER, sizeof(ut->UT_USER)) != 0) { - continue; - } - if ((pl->login_limit_def == LIMITS_DEF_ALLGROUP) - && !_pammodutil_user_in_group_nam_nam(pamh, ut->UT_USER, pl->login_group)) { - continue; - } - } - if (++count > limit) { - break; - } - } - endutent(); - if (count > limit) { - if (name) { - _pam_log(LOG_WARNING, "Too many logins (max %d) for %s", - limit, name); - } else { - _pam_log(LOG_WARNING, "Too many system logins (max %d)", limit); - } - return LOGIN_ERR; - } - return 0; -} - -static int init_limits(struct pam_limit_s *pl) -{ - int i; - int retval = PAM_SUCCESS; - - D(("called.")); - - for(i = 0; i < RLIM_NLIMITS; i++) { - int r = getrlimit(i, &pl->limits[i].limit); - if (r == -1) { - if (errno == EINVAL) { - pl->supported[i] = 0; - } else { - retval = !PAM_SUCCESS; - } - } else { - pl->supported[i] = 1; - pl->limits[i].src_soft = LIMITS_DEF_NONE; - pl->limits[i].src_hard = LIMITS_DEF_NONE; - } - } - - pl->priority = 0; - pl->login_limit = -2; - pl->login_limit_def = LIMITS_DEF_NONE; - - return retval; -} - -static void process_limit(int source, const char *lim_type, - const char *lim_item, const char *lim_value, - int ctrl, struct pam_limit_s *pl) -{ - int limit_item; - int limit_type = 0; - long limit_value; - char *endptr; - const char *value_orig = lim_value; - - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG, "%s: processing %s %s %s for %s\n", - __FUNCTION__,lim_type,lim_item,lim_value, - limits_def_names[source]); - - if (strcmp(lim_item, "cpu") == 0) - limit_item = RLIMIT_CPU; - else if (strcmp(lim_item, "fsize") == 0) - limit_item = RLIMIT_FSIZE; - else if (strcmp(lim_item, "data") == 0) - limit_item = RLIMIT_DATA; - else if (strcmp(lim_item, "stack") == 0) - limit_item = RLIMIT_STACK; - else if (strcmp(lim_item, "core") == 0) - limit_item = RLIMIT_CORE; - else if (strcmp(lim_item, "rss") == 0) - limit_item = RLIMIT_RSS; - else if (strcmp(lim_item, "nproc") == 0) - limit_item = RLIMIT_NPROC; - else if (strcmp(lim_item, "nofile") == 0) - limit_item = RLIMIT_NOFILE; - else if (strcmp(lim_item, "memlock") == 0) - limit_item = RLIMIT_MEMLOCK; - else if (strcmp(lim_item, "as") == 0) - limit_item = RLIMIT_AS; -#ifdef RLIMIT_LOCKS - else if (strcmp(lim_item, "locks") == 0) - limit_item = RLIMIT_LOCKS; -#endif -#ifdef RLIMIT_SIGPENDING - else if (strcmp(lim_item, "sigpending") == 0) - limit_item = RLIMIT_SIGPENDING; -#endif -#ifdef RLIMIT_MSGQUEUE - else if (strcmp(lim_item, "msgqueue") == 0) - limit_item = RLIMIT_MSGQUEUE; -#endif - else if (strcmp(lim_item, "maxlogins") == 0) { - limit_item = LIMIT_LOGIN; - pl->flag_numsyslogins = 0; - } else if (strcmp(lim_item, "maxsyslogins") == 0) { - limit_item = LIMIT_NUMSYSLOGINS; - pl->flag_numsyslogins = 1; - } else if (strcmp(lim_item, "priority") == 0) { - limit_item = LIMIT_PRI; - } else { - _pam_log(LOG_DEBUG,"unknown limit item '%s'", lim_item); - return; - } - - if (strcmp(lim_type,"soft")==0) - limit_type=LIMIT_SOFT; - else if (strcmp(lim_type, "hard")==0) - limit_type=LIMIT_HARD; - else if (strcmp(lim_type,"-")==0) - limit_type=LIMIT_SOFT | LIMIT_HARD; - else if (limit_item != LIMIT_LOGIN && limit_item != LIMIT_NUMSYSLOGINS) { - _pam_log(LOG_DEBUG,"unknown limit type '%s'", lim_type); - return; - } - - limit_value = strtol (lim_value, &endptr, 10); - - /* special case value when limiting logins */ - if (limit_value == 0 && value_orig == endptr) { /* no chars read */ - if (strcmp(lim_value,"-") != 0) { - _pam_log(LOG_DEBUG,"wrong limit value '%s'", lim_value); - return; - } else - if (limit_item != LIMIT_LOGIN) { - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG, - "'-' limit value valid for maxlogins type only"); - return; - } else - limit_value = -1; - } - - /* one more special case when limiting logins */ - if ((source == LIMITS_DEF_ALL || source == LIMITS_DEF_ALLGROUP) - && (limit_item != LIMIT_LOGIN)) { - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG, - "'%%' domain valid for maxlogins type only"); - return; - } - - switch(limit_item) { - case RLIMIT_CPU: - limit_value *= 60; - break; - case RLIMIT_FSIZE: - case RLIMIT_DATA: - case RLIMIT_STACK: - case RLIMIT_CORE: - case RLIMIT_RSS: - case RLIMIT_MEMLOCK: - case RLIMIT_AS: - limit_value *= 1024; - break; - } - - if ( (limit_item != LIMIT_LOGIN) - && (limit_item != LIMIT_NUMSYSLOGINS) - && (limit_item != LIMIT_PRI) ) { - if (limit_type & LIMIT_SOFT) { - if (pl->limits[limit_item].src_soft < source) { - return; - } else { - pl->limits[limit_item].limit.rlim_cur = limit_value; - pl->limits[limit_item].src_soft = source; - } - } - if (limit_type & LIMIT_HARD) { - if (pl->limits[limit_item].src_hard < source) { - return; - } else { - pl->limits[limit_item].limit.rlim_max = limit_value; - pl->limits[limit_item].src_hard = source; - } - } - } else { - /* recent kernels support negative priority limits (=raise priority) */ - - if (limit_item == LIMIT_PRI) { - pl->priority = limit_value; - } else { - if (pl->login_limit_def < source) { - return; - } else { - pl->login_limit = limit_value; - pl->login_limit_def = source; - } - } - } - return; -} - -static int parse_config_file(pam_handle_t *pamh, const char *uname, int ctrl, - struct pam_limit_s *pl) -{ - FILE *fil; - char buf[LINE_LENGTH]; - -#define CONF_FILE (pl->conf_file[0])?pl->conf_file:LIMITS_FILE - /* check for the LIMITS_FILE */ - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG,"reading settings from '%s'", CONF_FILE); - fil = fopen(CONF_FILE, "r"); - if (fil == NULL) { - _pam_log (LOG_WARNING, "can not read settings from %s", CONF_FILE); - return PAM_SERVICE_ERR; - } -#undef CONF_FILE - - /* init things */ - memset(buf, 0, sizeof(buf)); - /* start the show */ - while (fgets(buf, LINE_LENGTH, fil) != NULL) { - char domain[LINE_LENGTH]; - char ltype[LINE_LENGTH]; - char item[LINE_LENGTH]; - char value[LINE_LENGTH]; - int i,j; - char *tptr; - - tptr = buf; - /* skip the leading white space */ - while (*tptr && isspace(*tptr)) - tptr++; - strncpy(buf, tptr, sizeof(buf)-1); - buf[sizeof(buf)-1] = '\0'; - - /* Rip off the comments */ - tptr = strchr(buf,'#'); - if (tptr) - *tptr = '\0'; - /* Rip off the newline char */ - tptr = strchr(buf,'\n'); - if (tptr) - *tptr = '\0'; - /* Anything left ? */ - if (!strlen(buf)) { - memset(buf, 0, sizeof(buf)); - continue; - } - - memset(domain, 0, sizeof(domain)); - memset(ltype, 0, sizeof(ltype)); - memset(item, 0, sizeof(item)); - memset(value, 0, sizeof(value)); - - i = sscanf(buf,"%s%s%s%s", domain, ltype, item, value); - D(("scanned line[%d]: domain[%s], ltype[%s], item[%s], value[%s]", - i, domain, ltype, item, value)); - - for(j=0; j < strlen(domain); j++) - domain[j]=tolower(domain[j]); - for(j=0; j < strlen(ltype); j++) - ltype[j]=tolower(ltype[j]); - for(j=0; j < strlen(item); j++) - item[j]=tolower(item[j]); - for(j=0; j < strlen(value); j++) - value[j]=tolower(value[j]); - - if (i == 4) { /* a complete line */ - if (strcmp(uname, domain) == 0) /* this user have a limit */ - process_limit(LIMITS_DEF_USER, ltype, item, value, ctrl, pl); - else if (domain[0]=='@') { - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_DEBUG, "checking if %s is in group %s", - uname, domain + 1); - } - if (_pammodutil_user_in_group_nam_nam(pamh, uname, domain+1)) - process_limit(LIMITS_DEF_GROUP, ltype, item, value, ctrl, - pl); - } else if (domain[0]=='%') { - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_DEBUG, "checking if %s is in group %s", - uname, domain + 1); - } - if (strcmp(domain,"%") == 0) - process_limit(LIMITS_DEF_ALL, ltype, item, value, ctrl, - pl); - else if (_pammodutil_user_in_group_nam_nam(pamh, uname, domain+1)) { - strcpy(pl->login_group, domain+1); - process_limit(LIMITS_DEF_ALLGROUP, ltype, item, value, ctrl, - pl); - } - } else if (strcmp(domain, "*") == 0) - process_limit(LIMITS_DEF_DEFAULT, ltype, item, value, ctrl, - pl); - } else if (i == 2 && ltype[0] == '-') { /* Probably a no-limit line */ - if (strcmp(uname, domain) == 0) { - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_DEBUG, "no limits for '%s'", uname); - } - fclose(fil); - return PAM_IGNORE; - } else if (domain[0] == '@' && _pammodutil_user_in_group_nam_nam(pamh, uname, domain+1)) { - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_DEBUG, "no limits for '%s' in group '%s'", - uname, domain+1); - } - fclose(fil); - return PAM_IGNORE; - } - } else { - _pam_log(LOG_DEBUG,"invalid line '%s' - skipped", buf); - } - } - fclose(fil); - return PAM_SUCCESS; -} - -static int setup_limits(pam_handle_t *pamh, - const char *uname, uid_t uid, int ctrl, - struct pam_limit_s *pl) -{ - int i; - int status; - int retval = LIMITED_OK; - - if (uid == 0) { - /* do not impose limits (+ve limits anyway) on the superuser */ - if (pl->priority > 0) { - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_DEBUG, "user '%s' has UID 0 - no limits imposed", - uname); - } - pl->priority = 0; - } - } - - for (i=0, status=LIMITED_OK; i<RLIM_NLIMITS; i++) { - if (pl->limits[i].limit.rlim_cur > pl->limits[i].limit.rlim_max) - pl->limits[i].limit.rlim_cur = pl->limits[i].limit.rlim_max; - if (!pl->supported[i]) { - /* skip it if its not known to the system */ - continue; - } - status |= setrlimit(i, &pl->limits[i].limit); - } - - if (status) { - retval = LIMIT_ERR; - } - - status = setpriority(PRIO_PROCESS, 0, pl->priority); - if (status != 0) { - retval = LIMIT_ERR; - } - - if (uid == 0) { - D(("skip login limit check for uid=0")); - } else if (pl->login_limit > 0) { - if (check_logins(pamh, uname, pl->login_limit, ctrl, pl) == LOGIN_ERR) { - retval |= LOGIN_ERR; - } - } else if (pl->login_limit == 0) { - retval |= LOGIN_ERR; - } - - return retval; -} - -/* now the session stuff */ -PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int retval; - char *user_name; - struct passwd *pwd; - int ctrl; - struct pam_limit_s pl; - - D(("called.")); - - memset(&pl, 0, sizeof(pl)); - - ctrl = _pam_parse(argc, argv, &pl); - retval = pam_get_item( pamh, PAM_USER, (void*) &user_name ); - if ( user_name == NULL || retval != PAM_SUCCESS ) { - _pam_log(LOG_CRIT, "open_session - error recovering username"); - return PAM_SESSION_ERR; - } - - pwd = getpwnam(user_name); - if (!pwd) { - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_WARNING, "open_session username '%s' does not exist", - user_name); - return PAM_SESSION_ERR; - } - - retval = init_limits(&pl); - if (retval != PAM_SUCCESS) { - _pam_log(LOG_WARNING, "cannot initialize"); - return PAM_IGNORE; - } - - retval = parse_config_file(pamh, pwd->pw_name, ctrl, &pl); - if (retval == PAM_IGNORE) { - D(("the configuration file has an applicable '<domain> -' entry")); - return PAM_SUCCESS; - } - if (retval != PAM_SUCCESS) { - _pam_log(LOG_WARNING, "error parsing the configuration file"); - return PAM_IGNORE; - } - - if (ctrl & PAM_DO_SETREUID) { - setreuid(pwd->pw_uid, -1); - } - retval = setup_limits(pamh, pwd->pw_name, pwd->pw_uid, ctrl, &pl); - if (retval != LIMITED_OK) { - return PAM_PERM_DENIED; - } - - return PAM_SUCCESS; -} - -PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - /* nothing to do */ - return PAM_SUCCESS; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_limits_modstruct = { - "pam_limits", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL -}; -#endif - -/* - * Copyright (c) Cristian Gafton, 1996-1997, <gafton@redhat.com> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_listfile/.cvsignore b/modules/pam_listfile/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_listfile/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_listfile/Makefile b/modules/pam_listfile/Makefile deleted file mode 100644 index 18315256..00000000 --- a/modules/pam_listfile/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_listfile - -include ../Simple.Rules diff --git a/modules/pam_listfile/README b/modules/pam_listfile/README deleted file mode 100644 index b65e7dbb..00000000 --- a/modules/pam_listfile/README +++ /dev/null @@ -1,25 +0,0 @@ -SUMMARY: - pam_listfile: - Checks a specified item against a list in a file. - Options: - * item=[tty|user|rhost|ruser|group|shell] - * sense=[allow|deny] (action to take if found in file, - if the item is NOT found in the file, then - the opposite action is requested) - * file=/the/file/to/get/the/list/from - * onerr=[succeed|fail] (if something weird happens - such as unable to open the file, what to do?) - * apply=[user|@group] - restrict the user class for which the restriction - apply. Note that with item=[user|ruser|group] this - does not make sense, but for item=[tty|rhost|shell] - it have a meaning. (Cristian Gafton) - - Also checks to make sure that the list file is a plain - file and not world writable. - - - Elliot Lee <sopwith@redhat.com>, Red Hat Software. - v0.9 August 16, 1996. - -BUGS: - Bugs? diff --git a/modules/pam_listfile/pam_listfile.c b/modules/pam_listfile/pam_listfile.c deleted file mode 100644 index 0ce3e0b1..00000000 --- a/modules/pam_listfile/pam_listfile.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * $Id$ - * - */ - -/* - * by Elliot Lee <sopwith@redhat.com>, Red Hat Software. July 25, 1996. - * log refused access error christopher mccrory <chrismcc@netus.com> 1998/7/11 - * - * This code began life as the pam_rootok module. - */ - -#include <security/_pam_aconf.h> - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <syslog.h> -#include <stdarg.h> -#include <string.h> -#include <pwd.h> -#include <grp.h> - -#ifdef DEBUG -#include <assert.h> -#endif - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/_pam_modutil.h> - -/* some syslogging */ - -#define LOCAL_LOG_PREFIX "PAM-listfile: " - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - vsyslog(LOG_AUTH | err, format, args); - va_end(args); -} - -/* checks if a user is on a list of members */ -static int is_on_list(char * const *list, const char *member) -{ - while (*list) { - if (strcmp(*list, member) == 0) - return 1; - list++; - } - return 0; -} - -/* --- authentication management functions (only) --- */ - -/* Extended Items that are not directly available via pam_get_item() */ -#define EI_GROUP (1 << 0) -#define EI_SHELL (1 << 1) - -/* Constants for apply= parameter */ -#define APPLY_TYPE_NULL 0 -#define APPLY_TYPE_NONE 1 -#define APPLY_TYPE_USER 2 -#define APPLY_TYPE_GROUP 3 - -#define LESSER(a, b) ((a) < (b) ? (a) : (b)) - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - int retval, i, citem=0, extitem=0, onerr=PAM_SERVICE_ERR, sense=2; - const char *citemp; - char *ifname=NULL; - char aline[256]; - char mybuf[256],myval[256]; - struct stat fileinfo; - FILE *inf; - char apply_val[256]; - int apply_type; - - /* Stuff for "extended" items */ - struct passwd *userinfo; - struct group *grpinfo; - char *itemlist[256]; /* Maximum of 256 items */ - - apply_type=APPLY_TYPE_NULL; - memset(apply_val,0,sizeof(apply_val)); - - for(i=0; i < argc; i++) { - { - const char *junk; - - memset(mybuf,'\0',sizeof(mybuf)); - memset(myval,'\0',sizeof(mybuf)); - junk = strchr(argv[i], '='); - if((junk == NULL) || (junk - argv[i]) >= sizeof(mybuf)) { - _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "Bad option: \"%s\"", - argv[i]); - continue; - } - strncpy(mybuf, argv[i], LESSER(junk - argv[i], sizeof(mybuf) - 1)); - strncpy(myval, junk + 1, sizeof(myval) - 1); - } - if(!strcmp(mybuf,"onerr")) - if(!strcmp(myval,"succeed")) - onerr = PAM_SUCCESS; - else if(!strcmp(myval,"fail")) - onerr = PAM_SERVICE_ERR; - else - return PAM_SERVICE_ERR; - else if(!strcmp(mybuf,"sense")) - if(!strcmp(myval,"allow")) - sense=0; - else if(!strcmp(myval,"deny")) - sense=1; - else - return onerr; - else if(!strcmp(mybuf,"file")) { - ifname = (char *)malloc(strlen(myval)+1); - strcpy(ifname,myval); - } else if(!strcmp(mybuf,"item")) - if(!strcmp(myval,"user")) - citem = PAM_USER; - else if(!strcmp(myval,"tty")) - citem = PAM_TTY; - else if(!strcmp(myval,"rhost")) - citem = PAM_RHOST; - else if(!strcmp(myval,"ruser")) - citem = PAM_RUSER; - else { /* These items are related to the user, but are not - directly gettable with pam_get_item */ - citem = PAM_USER; - if(!strcmp(myval,"group")) - extitem = EI_GROUP; - else if(!strcmp(myval,"shell")) - extitem = EI_SHELL; - else - citem = 0; - } else if(!strcmp(mybuf,"apply")) { - apply_type=APPLY_TYPE_NONE; - memset(apply_val,'\0',sizeof(apply_val)); - if (myval[0]=='@') { - apply_type=APPLY_TYPE_GROUP; - strncpy(apply_val,myval+1,sizeof(apply_val)-1); - } else { - apply_type=APPLY_TYPE_USER; - strncpy(apply_val,myval,sizeof(apply_val)-1); - } - } else { - _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "Unknown option: %s",mybuf); - return onerr; - } - } - - if(!citem) { - _pam_log(LOG_ERR, - LOCAL_LOG_PREFIX "Unknown item or item not specified"); - return onerr; - } else if(!ifname) { - _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "List filename not specified"); - return onerr; - } else if(sense == 2) { - _pam_log(LOG_ERR, - LOCAL_LOG_PREFIX "Unknown sense or sense not specified"); - return onerr; - } else if( - (apply_type==APPLY_TYPE_NONE) || - ((apply_type!=APPLY_TYPE_NULL) && (*apply_val=='\0')) - ) { - _pam_log(LOG_ERR, - LOCAL_LOG_PREFIX "Invalid usage for apply= parameter"); - return onerr; - } - - /* Check if it makes sense to use the apply= parameter */ - if (apply_type != APPLY_TYPE_NULL) { - if((citem==PAM_USER) || (citem==PAM_RUSER)) { - _pam_log(LOG_WARNING, - LOCAL_LOG_PREFIX "Non-sense use for apply= parameter"); - apply_type=APPLY_TYPE_NULL; - } - if(extitem && (extitem==EI_GROUP)) { - _pam_log(LOG_WARNING, - LOCAL_LOG_PREFIX "Non-sense use for apply= parameter"); - apply_type=APPLY_TYPE_NULL; - } - } - - /* Short-circuit - test if this session apply for this user */ - { - const char *user_name; - int rval; - - rval=pam_get_user(pamh,&user_name,NULL); - if((rval==PAM_SUCCESS) && user_name[0]) { - /* Got it ? Valid ? */ - if(apply_type==APPLY_TYPE_USER) { - if(strcmp(user_name, apply_val)) { - /* Does not apply to this user */ -#ifdef DEBUG - _pam_log(LOG_DEBUG, - LOCAL_LOG_PREFIX "don't apply: apply=%s, user=%s", - apply_val,user_name); -#endif /* DEBUG */ - return PAM_IGNORE; - } - } else if(apply_type==APPLY_TYPE_GROUP) { - if(!_pammodutil_user_in_group_nam_nam(pamh,user_name,apply_val)) { - /* Not a member of apply= group */ -#ifdef DEBUG - _pam_log(LOG_DEBUG, - LOCAL_LOG_PREFIX - "don't apply: %s not a member of group %s", - user_name,apply_val); -#endif /* DEBUG */ - return PAM_IGNORE; - } - } - } - } - - retval = pam_get_item(pamh,citem,(const void **)&citemp); - if(retval != PAM_SUCCESS) { - return onerr; - } - if((citem == PAM_USER) && !citemp) { - pam_get_user(pamh,&citemp,NULL); - if (retval != PAM_SUCCESS) - return PAM_SERVICE_ERR; - } - if((citem == PAM_TTY) && citemp) { - /* Normalize the TTY name. */ - if(strncmp(citemp, "/dev/", 5) == 0) { - citemp += 5; - } - } - - if(!citemp || (strlen(citemp) == 0)) { - /* The item was NULL - we are sure not to match */ - return sense?PAM_SUCCESS:PAM_AUTH_ERR; - } - - if(extitem) { - switch(extitem) { - case EI_GROUP: - userinfo = _pammodutil_getpwnam(pamh, citemp); - if (userinfo == NULL) { - _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "getpwnam(%s) failed", - citemp); - return onerr; - } - grpinfo = _pammodutil_getgrgid(pamh, userinfo->pw_gid); - if (grpinfo == NULL) { - _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "getgrgid(%d) failed", - (int)userinfo->pw_gid); - return onerr; - } - itemlist[0] = x_strdup(grpinfo->gr_name); - setgrent(); - for (i=1; (i < sizeof(itemlist)/sizeof(itemlist[0])-1) && - (grpinfo = getgrent()); ) { - if (is_on_list(grpinfo->gr_mem,citemp)) { - itemlist[i++] = x_strdup(grpinfo->gr_name); - } - } - endgrent(); - itemlist[i] = NULL; - break; - case EI_SHELL: - /* Assume that we have already gotten PAM_USER in - pam_get_item() - a valid assumption since citem - gets set to PAM_USER in the extitem switch */ - userinfo = _pammodutil_getpwnam(pamh, citemp); - if (userinfo == NULL) { - _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "getpwnam(%s) failed", - citemp); - return onerr; - } - citemp = userinfo->pw_shell; - break; - default: - _pam_log(LOG_ERR, - LOCAL_LOG_PREFIX - "Internal weirdness, unknown extended item %d", - extitem); - return onerr; - } - } -#ifdef DEBUG - _pam_log(LOG_INFO, - LOCAL_LOG_PREFIX - "Got file = %s, item = %d, value = %s, sense = %d", - ifname, citem, citemp, sense); -#endif - if(lstat(ifname,&fileinfo)) { - _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "Couldn't open %s",ifname); - return onerr; - } - - if((fileinfo.st_mode & S_IWOTH) - || !S_ISREG(fileinfo.st_mode)) { - /* If the file is world writable or is not a - normal file, return error */ - _pam_log(LOG_ERR,LOCAL_LOG_PREFIX - "%s is either world writable or not a normal file", - ifname); - return PAM_AUTH_ERR; - } - - inf = fopen(ifname,"r"); - if(inf == NULL) { /* Check that we opened it successfully */ - if (onerr == PAM_SERVICE_ERR) { - /* Only report if it's an error... */ - _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "Error opening %s", ifname); - } - return onerr; - } - /* There should be no more errors from here on */ - retval=PAM_AUTH_ERR; - /* This loop assumes that PAM_SUCCESS == 0 - and PAM_AUTH_ERR != 0 */ -#ifdef DEBUG - assert(PAM_SUCCESS == 0); - assert(PAM_AUTH_ERR != 0); -#endif - if(extitem == EI_GROUP) { - while((fgets(aline,sizeof(aline),inf) != NULL) - && retval) { - if(strlen(aline) == 0) - continue; - if(aline[strlen(aline) - 1] == '\n') - aline[strlen(aline) - 1] = '\0'; - for(i=0;itemlist[i];) - /* If any of the items match, strcmp() == 0, and we get out - of this loop */ - retval = (strcmp(aline,itemlist[i++]) && retval); - } - for(i=0;itemlist[i];) - free(itemlist[i++]); - } else { - while((fgets(aline,sizeof(aline),inf) != NULL) - && retval) { - char *a = aline; - if(strlen(aline) == 0) - continue; - if(aline[strlen(aline) - 1] == '\n') - aline[strlen(aline) - 1] = '\0'; - if(strlen(aline) == 0) - continue; - if(aline[strlen(aline) - 1] == '\r') - aline[strlen(aline) - 1] = '\0'; - if(citem == PAM_TTY) - if(strncmp(a, "/dev/", 5) == 0) - a += 5; - retval = strcmp(a,citemp); - } - } - fclose(inf); - free(ifname); - if ((sense && retval) || (!sense && !retval)) { -#ifdef DEBUG - _pam_log(LOG_INFO, LOCAL_LOG_PREFIX - "Returning PAM_SUCCESS, retval = %d", retval); -#endif - return PAM_SUCCESS; - } - else { - const char *service, *user_name; -#ifdef DEBUG - _pam_log(LOG_INFO,LOCAL_LOG_PREFIX - "Returning PAM_AUTH_ERR, retval = %d", retval); -#endif - (void) pam_get_item(pamh, PAM_SERVICE, (const void **)&service); - (void) pam_get_user(pamh, &user_name, NULL); - _pam_log(LOG_ALERT,LOCAL_LOG_PREFIX "Refused user %s for service %s", - user_name, service); - return PAM_AUTH_ERR; - } -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return pam_sm_authenticate(pamh, 0, argc, argv); -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_listfile_modstruct = { - "pam_listfile", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; - -#endif /* PAM_STATIC */ - -/* end of module definition */ - diff --git a/modules/pam_localuser/Makefile b/modules/pam_localuser/Makefile deleted file mode 100644 index 13946eb4..00000000 --- a/modules/pam_localuser/Makefile +++ /dev/null @@ -1,14 +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_localuser -MAN8=pam_localuser.8 - -include ../Simple.Rules diff --git a/modules/pam_localuser/README b/modules/pam_localuser/README deleted file mode 100644 index b8cdf524..00000000 --- a/modules/pam_localuser/README +++ /dev/null @@ -1,17 +0,0 @@ -pam_localuser: - Succeeds iff the PAM_USER is listed in /etc/passwd. This seems to be a - common policy need (allowing only a subset of network-wide users, and - any locally-defined users, to access services). Simpler than using - awk to generate a file for use with pam_listfile (-F: '{print $1}'), - I guess. - -RECOGNIZED ARGUMENTS: - debug write debugging messages to syslog - file=FILE scan FILE instead of /etc/passwd - -MODULE SERVICES PROVIDED: - auth,account scan the FILE (/etc/passwd by default) and return - a success code if an entry is found for the user - -AUTHOR: - Nalin Dahyabhai <nalin@redhat.com> diff --git a/modules/pam_localuser/pam_localuser.8 b/modules/pam_localuser/pam_localuser.8 deleted file mode 100644 index ce0a9465..00000000 --- a/modules/pam_localuser/pam_localuser.8 +++ /dev/null @@ -1,36 +0,0 @@ -.\" Copyright 2000 Red Hat, Inc. -.TH pam_localuser 8 2000/7/21 "Red Hat" "System Administrator's Manual" - -.SH NAME -pam_localuser \- require users to be listed in /etc/passwd - -.SH SYNOPSIS -.B account sufficient /lib/security/pam_localuser.so \fIargs\fP -.br -.B account required /lib/security/pam_wheel.so group=devel - -.SH DESCRIPTION -pam_localuser.so exists to help implement site-wide login policies, where -they typically include a subset of the network's users and a few accounts -that are local to a particular workstation. Using pam_localuser.so and -pam_wheel.so or pam_listfile.so is an effective way to restrict access to -either local users and/or a subset of the network's users. - -This could also be implemented using pam_listfile.so and a very short awk -script invoked by cron, but it's common enough to have been separated out. - -.SH ARGUMENTS -.IP debug -turns on debugging -.IP file=\fBFILE\fP -uses a file other than \fB/etc/passwd\fP. - -.SH FILES -/etc/passwd - -.SH BUGS -Let's hope not, but if you find any, please report them via the "Bug Track" -link at http://bugzilla.redhat.com/bugzilla/ - -.SH AUTHOR -Nalin Dahyabhai <nalin@redhat.com> diff --git a/modules/pam_localuser/pam_localuser.c b/modules/pam_localuser/pam_localuser.c deleted file mode 100644 index e5496089..00000000 --- a/modules/pam_localuser/pam_localuser.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2001, 2004 Red Hat, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "../../_pam_aconf.h" - -#include <errno.h> -#include <limits.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <stdio.h> -#include <stdarg.h> -#include <time.h> -#include <unistd.h> -#include <sys/stat.h> -#include <sys/types.h> - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#include "../../libpam/include/security/pam_modules.h" -#include "../../libpam/include/security/_pam_macros.h" - -#define MODULE_NAME "pam_localuser" - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - int i, ret = PAM_SUCCESS; - FILE *fp; - int debug = 0; - const char *filename = "/etc/passwd"; - char line[LINE_MAX], name[LINE_MAX]; - const char* user; - - /* process arguments */ - for(i = 0; i < argc; i++) { - if(strcmp("debug", argv[i]) == 0) { - debug = 1; - } - } - for(i = 0; i < argc; i++) { - if(strncmp("file=", argv[i], 5) == 0) { - filename = argv[i] + 5; - if(debug) { - openlog(MODULE_NAME, LOG_PID, LOG_AUTHPRIV); - syslog(LOG_DEBUG, "set filename to \"%s\"", - filename); - closelog(); - } - } - } - - /* open the file */ - fp = fopen(filename, "r"); - if(fp == NULL) { - openlog(MODULE_NAME, LOG_PID, LOG_AUTHPRIV); - syslog(LOG_ERR, "error opening \"%s\": %s", filename, - strerror(errno)); - closelog(); - return PAM_SYSTEM_ERR; - } - - if(pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) { - openlog(MODULE_NAME, LOG_PID, LOG_AUTHPRIV); - syslog(LOG_ERR, "user name not specified yet"); - closelog(); - fclose(fp); - return PAM_SYSTEM_ERR; - } - - if ((user == NULL) || (strlen(user) == 0)) { - openlog(MODULE_NAME, LOG_PID, LOG_AUTHPRIV); - syslog(LOG_ERR, "user name not valid"); - closelog(); - fclose(fp); - return PAM_SYSTEM_ERR; - } - - /* scan the file, using fgets() instead of fgetpwent() because i - * don't want to mess with applications which call fgetpwent() */ - ret = PAM_PERM_DENIED; - snprintf(name, sizeof(name), "%s:", user); - i = strlen(name); - while(fgets(line, sizeof(line), fp) != NULL) { - if(debug) { - openlog(MODULE_NAME, LOG_PID, LOG_AUTHPRIV); - syslog(LOG_DEBUG, "checking \"%s\"", line); - closelog(); - } - if(strncmp(name, line, i) == 0) { - ret = PAM_SUCCESS; - break; - } - } - - /* okay, we're done */ - fclose(fp); - return ret; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_localuser_modstruct = { - "pam_localuser", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; - -#endif diff --git a/modules/pam_mail/.cvsignore b/modules/pam_mail/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_mail/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_mail/Makefile b/modules/pam_mail/Makefile deleted file mode 100644 index 93ca429b..00000000 --- a/modules/pam_mail/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_mail - -include ../Simple.Rules diff --git a/modules/pam_mail/README b/modules/pam_mail/README deleted file mode 100644 index 155bd1db..00000000 --- a/modules/pam_mail/README +++ /dev/null @@ -1,17 +0,0 @@ -This is the README for pam_mail -------------------------------- - -This PAM module tells the User that he has new/unread email. - -Options for: -auth: for authentication it provides pam_authenticate() and - pam_setcred() hooks. - - "debug" write more information to syslog - "dir=maildir" users mailbox is maildir/<login> - "hash=count" mail directory hash depth - "close" print message also on logout - "nopen" print message not on login - "noenv" don't set the MAIL environment variable - "empty" also print message if user has no mail - diff --git a/modules/pam_mail/pam_mail.c b/modules/pam_mail/pam_mail.c deleted file mode 100644 index 2c4b641a..00000000 --- a/modules/pam_mail/pam_mail.c +++ /dev/null @@ -1,504 +0,0 @@ -/* pam_mail module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11 - * $HOME additions by David Kinchlea <kinch@kinch.ark.com> 1997/1/7 - * mailhash additions by Chris Adams <cadams@ro.com> 1998/7/11 - */ - -#include <security/_pam_aconf.h> - -#include <ctype.h> -#include <pwd.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> -#include <dirent.h> - -#ifdef WANT_PWDB -#include <pwdb/pwdb_public.h> -#endif - -#define DEFAULT_MAIL_DIRECTORY PAM_PATH_MAILDIR -#define MAIL_FILE_FORMAT "%s%s/%s" -#define MAIL_ENV_NAME "MAIL" -#define MAIL_ENV_FORMAT MAIL_ENV_NAME "=%s" -#define YOUR_MAIL_VERBOSE_FORMAT "You have %s mail in %s." -#define YOUR_MAIL_STANDARD_FORMAT "You have %smail." -#define NO_MAIL_STANDARD_FORMAT "No mail." - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_SESSION -#define PAM_SM_AUTH - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/_pam_modutil.h> - -/* some syslogging */ - -static void _log_err(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-mail", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -/* argument parsing */ - -#define PAM_DEBUG_ARG 0x0001 -#define PAM_NO_LOGIN 0x0002 -#define PAM_LOGOUT_TOO 0x0004 -#define PAM_NEW_MAIL_DIR 0x0010 -#define PAM_MAIL_SILENT 0x0020 -#define PAM_NO_ENV 0x0040 -#define PAM_HOME_MAIL 0x0100 -#define PAM_EMPTY_TOO 0x0200 -#define PAM_STANDARD_MAIL 0x0400 -#define PAM_QUIET_MAIL 0x1000 - -static int _pam_parse(int flags, int argc, const char **argv, char **maildir, - int *hashcount) -{ - int ctrl=0; - - if (flags & PAM_SILENT) { - ctrl |= PAM_MAIL_SILENT; - } - - *hashcount = 0; - - /* step through arguments */ - for (; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strcmp(*argv,"quiet")) - ctrl |= PAM_QUIET_MAIL; - else if (!strcmp(*argv,"standard")) - ctrl |= PAM_STANDARD_MAIL | PAM_EMPTY_TOO; - else if (!strncmp(*argv,"dir=",4)) { - *maildir = x_strdup(4+*argv); - if (*maildir != NULL) { - D(("new mail directory: %s", *maildir)); - ctrl |= PAM_NEW_MAIL_DIR; - } else { - _log_err(LOG_CRIT, - "failed to duplicate mail directory - ignored"); - } - } else if (!strncmp(*argv,"hash=",5)) { - char *ep = NULL; - *hashcount = strtol(*argv+5,&ep,10); - if (!ep || (*hashcount < 0)) { - *hashcount = 0; - } - } else if (!strcmp(*argv,"close")) { - ctrl |= PAM_LOGOUT_TOO; - } else if (!strcmp(*argv,"nopen")) { - ctrl |= PAM_NO_LOGIN; - } else if (!strcmp(*argv,"noenv")) { - ctrl |= PAM_NO_ENV; - } else if (!strcmp(*argv,"empty")) { - ctrl |= PAM_EMPTY_TOO; - } else { - _log_err(LOG_ERR,"pam_parse: unknown option; %s",*argv); - } - } - - if ((*hashcount != 0) && !(ctrl & PAM_NEW_MAIL_DIR)) { - *maildir = x_strdup(DEFAULT_MAIL_DIRECTORY); - ctrl |= PAM_NEW_MAIL_DIR; - } - - return ctrl; -} - -/* a front end for conversations */ - -static int converse(pam_handle_t *pamh, int ctrl, int nargs - , struct pam_message **message - , struct pam_response **response) -{ - int retval; - struct pam_conv *conv; - - D(("begin to converse")); - - retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ; - if ( retval == PAM_SUCCESS && conv ) { - - retval = conv->conv(nargs, ( const struct pam_message ** ) message - , response, conv->appdata_ptr); - - D(("returned from application's conversation function")); - - if (retval != PAM_SUCCESS && (PAM_DEBUG_ARG & ctrl) ) { - _log_err(LOG_DEBUG, "conversation failure [%s]" - , pam_strerror(pamh, retval)); - } - - } else { - _log_err(LOG_ERR, "couldn't obtain coversation function [%s]" - , pam_strerror(pamh, retval)); - if (retval == PAM_SUCCESS) - retval = PAM_BAD_ITEM; /* conv was NULL */ - } - - D(("ready to return from module conversation")); - - return retval; /* propagate error status */ -} - -static int get_folder(pam_handle_t *pamh, int ctrl, - char **path_mail, char **folder_p, int hashcount) -{ - int retval; - const char *user, *path; - char *folder; - const struct passwd *pwd=NULL; - - retval = pam_get_user(pamh, &user, NULL); - if (retval != PAM_SUCCESS || user == NULL) { - _log_err(LOG_ERR, "no user specified"); - return PAM_USER_UNKNOWN; - } - - if (ctrl & PAM_NEW_MAIL_DIR) { - path = *path_mail; - if (*path == '~') { /* support for $HOME delivery */ - pwd = _pammodutil_getpwnam(pamh, user); - if (pwd == NULL) { - _log_err(LOG_ERR, "user [%s] unknown", user); - _pam_overwrite(*path_mail); - _pam_drop(*path_mail); - return PAM_USER_UNKNOWN; - } - /* - * "~/xxx" and "~xxx" are treated as same - */ - if (!*++path || (*path == '/' && !*++path)) { - _log_err(LOG_ALERT, "badly formed mail path [%s]", *path_mail); - _pam_overwrite(*path_mail); - _pam_drop(*path_mail); - return PAM_ABORT; - } - ctrl |= PAM_HOME_MAIL; - if (hashcount != 0) { - _log_err(LOG_ALERT, "can't do hash= and home directory mail"); - } - } - } else { - path = DEFAULT_MAIL_DIRECTORY; - } - - /* put folder together */ - - if (ctrl & PAM_HOME_MAIL) { - folder = malloc(sizeof(MAIL_FILE_FORMAT) - +strlen(pwd->pw_dir)+strlen(path)); - } else { - folder = malloc(sizeof(MAIL_FILE_FORMAT)+strlen(path)+strlen(user) - +2*hashcount); - } - - if (folder != NULL) { - if (ctrl & PAM_HOME_MAIL) { - sprintf(folder, MAIL_FILE_FORMAT, pwd->pw_dir, "", path); - } else { - int i; - char *hash = malloc(2*hashcount+1); - - if (hash) { - for (i = 0; i < hashcount; i++) { - hash[2*i] = '/'; - hash[2*i+1] = user[i]; - } - hash[2*i] = '\0'; - sprintf(folder, MAIL_FILE_FORMAT, path, hash, user); - _pam_overwrite(hash); - _pam_drop(hash); - } else { - _pam_drop(folder); - _log_err(LOG_CRIT, "out of memory for mail folder"); - return PAM_BUF_ERR; - } - } - D(("folder =[%s]", folder)); - } - - /* tidy up */ - - _pam_overwrite(*path_mail); - _pam_drop(*path_mail); - user = NULL; - - if (folder == NULL) { - _log_err(LOG_CRIT, "out of memory for mail folder"); - return PAM_BUF_ERR; - } - - *folder_p = folder; - folder = NULL; - - return PAM_SUCCESS; -} - -static const char *get_mail_status(int ctrl, const char *folder) -{ - const char *type = NULL; - static char dir[256]; - struct stat mail_st; - struct dirent **namelist; - int i; - - if (stat(folder, &mail_st) == 0) { - if (S_ISDIR(mail_st.st_mode)) { /* Assume Maildir format */ - sprintf(dir, "%.250s/new", folder); - i = scandir(dir, &namelist, 0, alphasort); - if (i > 2) { - type = "new"; - while (--i) - free(namelist[i]); - } else { - while (--i >= 0) - free(namelist[i]); - sprintf(dir, "%.250s/cur", folder); - i = scandir(dir, &namelist, 0, alphasort); - if (i > 2) { - type = "old"; - while (--i) - free(namelist[i]); - } else if (ctrl & PAM_EMPTY_TOO) { - while (--i >= 0) - free(namelist[i]); - type = "no"; - } else { - type = NULL; - } - } - } else { - if (mail_st.st_size > 0) { - if (mail_st.st_atime < mail_st.st_mtime) /* new */ - type = (ctrl & PAM_STANDARD_MAIL) ? "new " : "new"; - else /* old */ - type = (ctrl & PAM_STANDARD_MAIL) ? "" : "old"; - } else if (ctrl & PAM_EMPTY_TOO) { - type = "no"; - } else { - type = NULL; - } - } - } - - memset(dir, 0, 256); - memset(&mail_st, 0, sizeof(mail_st)); - D(("user has %s mail in %s folder", type, folder)); - return type; -} - -static int report_mail(pam_handle_t *pamh, int ctrl - , const char *type, const char *folder) -{ - int retval; - - if (!(ctrl & PAM_MAIL_SILENT) || ((ctrl & PAM_QUIET_MAIL) && strcmp(type, "new"))) { - char *remark; - - if (ctrl & PAM_STANDARD_MAIL) - if (!strcmp(type, "no")) - remark = malloc(strlen(NO_MAIL_STANDARD_FORMAT)+1); - else - remark = malloc(strlen(YOUR_MAIL_STANDARD_FORMAT)+strlen(type)+1); - else - remark = malloc(strlen(YOUR_MAIL_VERBOSE_FORMAT)+strlen(type)+strlen(folder)+1); - if (remark == NULL) { - retval = PAM_BUF_ERR; - } else { - struct pam_message msg[1], *mesg[1]; - struct pam_response *resp=NULL; - - if (ctrl & PAM_STANDARD_MAIL) - if (!strcmp(type, "no")) - sprintf(remark, NO_MAIL_STANDARD_FORMAT); - else - sprintf(remark, YOUR_MAIL_STANDARD_FORMAT, type); - else - sprintf(remark, YOUR_MAIL_VERBOSE_FORMAT, type, folder); - - mesg[0] = &msg[0]; - msg[0].msg_style = PAM_TEXT_INFO; - msg[0].msg = remark; - - retval = converse(pamh, ctrl, 1, mesg, &resp); - - _pam_overwrite(remark); - _pam_drop(remark); - if (resp) - _pam_drop_reply(resp, 1); - } - } else { - D(("keeping quiet")); - retval = PAM_SUCCESS; - } - - D(("returning %s", pam_strerror(pamh, retval))); - return retval; -} - -static int _do_mail(pam_handle_t *, int, int, const char **, int); - -/* --- authentication functions --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc, - const char **argv) -{ - return PAM_IGNORE; -} - -/* Checking mail as part of authentication */ -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - if (!(flags & (PAM_ESTABLISH_CRED|PAM_DELETE_CRED))) - return PAM_IGNORE; - return _do_mail(pamh,flags,argc,argv,(flags & PAM_ESTABLISH_CRED)); -} - -/* --- session management functions --- */ - -PAM_EXTERN -int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return _do_mail(pamh,flags,argc,argv,0); -} - -/* Checking mail as part of the session management */ -PAM_EXTERN -int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return _do_mail(pamh,flags,argc,argv,1); -} - - -/* --- The Beaf (Tm) --- */ - -static int _do_mail(pam_handle_t *pamh, int flags, int argc, - const char **argv, int est) -{ - int retval, ctrl, hashcount; - char *path_mail=NULL, *folder; - const char *type; - - /* - * this module (un)sets the MAIL environment variable, and checks if - * the user has any new mail. - */ - - ctrl = _pam_parse(flags, argc, argv, &path_mail, &hashcount); - - /* Do we have anything to do? */ - - if (flags & PAM_SILENT) - return PAM_SUCCESS; - - /* which folder? */ - - retval = get_folder(pamh, ctrl, &path_mail, &folder, hashcount); - if (retval != PAM_SUCCESS) { - D(("failed to find folder")); - return retval; - } - - /* set the MAIL variable? */ - - if (!(ctrl & PAM_NO_ENV) && est) { - char *tmp; - - tmp = malloc(strlen(folder)+sizeof(MAIL_ENV_FORMAT)); - if (tmp != NULL) { - sprintf(tmp, MAIL_ENV_FORMAT, folder); - D(("setting env: %s", tmp)); - retval = pam_putenv(pamh, tmp); - _pam_overwrite(tmp); - _pam_drop(tmp); - if (retval != PAM_SUCCESS) { - _pam_overwrite(folder); - _pam_drop(folder); - _log_err(LOG_CRIT, "unable to set " MAIL_ENV_NAME " variable"); - return retval; - } - } else { - _log_err(LOG_CRIT, "no memory for " MAIL_ENV_NAME " variable"); - _pam_overwrite(folder); - _pam_drop(folder); - return retval; - } - } else { - D(("not setting " MAIL_ENV_NAME " variable")); - } - - /* - * OK. we've got the mail folder... what about its status? - */ - - if ((est && !(ctrl & PAM_NO_LOGIN)) - || (!est && (ctrl & PAM_LOGOUT_TOO))) { - type = get_mail_status(ctrl, folder); - if (type != NULL) { - retval = report_mail(pamh, ctrl, type, folder); - type = NULL; - } - } - - /* Delete environment variable? */ - if ( ! est && ! (ctrl & PAM_NO_ENV) ) - (void) pam_putenv(pamh, MAIL_ENV_NAME); - - _pam_overwrite(folder); /* clean up */ - _pam_drop(folder); - - /* indicate success or failure */ - - return retval; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_mail_modstruct = { - "pam_mail", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_mkhomedir/.cvsignore b/modules/pam_mkhomedir/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_mkhomedir/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_mkhomedir/Makefile b/modules/pam_mkhomedir/Makefile deleted file mode 100644 index d518c26f..00000000 --- a/modules/pam_mkhomedir/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_mkhomedir - -include ../Simple.Rules diff --git a/modules/pam_mkhomedir/README b/modules/pam_mkhomedir/README deleted file mode 100644 index 2a3e705e..00000000 --- a/modules/pam_mkhomedir/README +++ /dev/null @@ -1,25 +0,0 @@ -PAM Make Home Dir module - -This module will create a users home directory if it does not exist -when the session begins. This allows users to be present in central -database (such as nis, kerb or ldap) without using a distributed -file system or pre-creating a large number of directories. - -Here is a sample /etc/pam.d/login file: - - auth requisite pam_securetty.so - auth sufficient pam_ldap.so - auth required pam_unix.so - auth optional pam_group.so - auth optional pam_mail.so - account requisite pam_time.so - account sufficient pam_ldap.so - account required pam_unix.so - session required pam_mkhomedir.so skel=/etc/skel/ umask=0022 - session required pam_unix.so - session optional pam_lastlog.so - password required pam_unix.so - -Released under the GNU LGPL version 2 or later -Originally written by Jason Gunthorpe <jgg@debian.org> Feb 1999 - diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c deleted file mode 100644 index f63177bf..00000000 --- a/modules/pam_mkhomedir/pam_mkhomedir.c +++ /dev/null @@ -1,521 +0,0 @@ -/* PAM Make Home Dir module - - This module will create a users home directory if it does not exist - when the session begins. This allows users to be present in central - database (such as nis, kerb or ldap) without using a distributed - file system or pre-creating a large number of directories. - - Here is a sample /etc/pam.d/login file for Debian GNU/Linux - 2.1: - - auth requisite pam_securetty.so - auth sufficient pam_ldap.so - auth required pam_pwdb.so - auth optional pam_group.so - auth optional pam_mail.so - account requisite pam_time.so - account sufficient pam_ldap.so - account required pam_pwdb.so - session required pam_mkhomedir.so skel=/etc/skel/ umask=0022 - session required pam_pwdb.so - session optional pam_lastlog.so - password required pam_pwdb.so - - Released under the GNU LGPL version 2 or later - Originally written by Jason Gunthorpe <jgg@debian.org> Feb 1999 - Structure taken from pam_lastlogin by Andrew Morgan - <morgan@parc.power.net> 1996 - */ - -/* I want snprintf dammit */ -#define _GNU_SOURCE 1 -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <pwd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <dirent.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_SESSION - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/_pam_modutil.h> - - -/* argument parsing */ -#define MKHOMEDIR_DEBUG 020 /* keep quiet about things */ -#define MKHOMEDIR_QUIET 040 /* keep quiet about things */ - -static unsigned int UMask = 0022; -static char SkelDir[BUFSIZ] = "/etc/skel"; /* THIS MODULE IS NOT THREAD SAFE */ - -/* some syslogging */ -static void _log_err(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-mkhomedir", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -static int _pam_parse(int flags, int argc, const char **argv) -{ - int ctrl = 0; - - /* does the appliction require quiet? */ - if ((flags & PAM_SILENT) == PAM_SILENT) - ctrl |= MKHOMEDIR_QUIET; - - /* step through arguments */ - for (; argc-- > 0; ++argv) - { - if (!strcmp(*argv, "silent")) { - ctrl |= MKHOMEDIR_QUIET; - } else if (!strncmp(*argv,"umask=",6)) { - UMask = strtol(*argv+6,0,0); - } else if (!strncmp(*argv,"skel=",5)) { - strncpy(SkelDir,*argv+5,sizeof(SkelDir)); - SkelDir[sizeof(SkelDir)-1] = '\0'; - } else { - _log_err(LOG_ERR, "unknown option; %s", *argv); - } - } - - D(("ctrl = %o", ctrl)); - return ctrl; -} - -/* This common function is used to send a message to the applications - conversion function. Our only use is to ask the application to print - an informative message that we are creating a home directory */ -static int converse(pam_handle_t * pamh, int ctrl, int nargs - ,struct pam_message **message - ,struct pam_response **response) -{ - int retval; - struct pam_conv *conv; - - D(("begin to converse")); - - retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv); - if (retval == PAM_SUCCESS && conv) - { - - retval = conv->conv(nargs, (const struct pam_message **) message - ,response, conv->appdata_ptr); - - D(("returned from application's conversation function")); - - if (retval != PAM_SUCCESS && (ctrl & MKHOMEDIR_DEBUG)) - { - _log_err(LOG_DEBUG, "conversation failure [%s]" - ,pam_strerror(pamh, retval)); - } - - } - else - { - _log_err(LOG_ERR, "couldn't obtain coversation function [%s]" - ,pam_strerror(pamh, retval)); - if (retval == PAM_SUCCESS) - retval = PAM_BAD_ITEM; /* conv was NULL */ - } - - D(("ready to return from module conversation")); - - return retval; /* propagate error status */ -} - -/* Ask the application to display a short text string for us. */ -static int make_remark(pam_handle_t * pamh, int ctrl, const char *remark) -{ - int retval; - - if ((ctrl & MKHOMEDIR_QUIET) != MKHOMEDIR_QUIET) - { - struct pam_message msg[1], *mesg[1]; - struct pam_response *resp = NULL; - - mesg[0] = &msg[0]; - msg[0].msg_style = PAM_TEXT_INFO; - msg[0].msg = remark; - - retval = converse(pamh, ctrl, 1, mesg, &resp); - - msg[0].msg = NULL; - if (resp) - { - _pam_drop_reply(resp, 1); - } - } - else - { - D(("keeping quiet")); - retval = PAM_SUCCESS; - } - - D(("returning %s", pam_strerror(pamh, retval))); - return retval; -} - -/* Do the actual work of creating a home dir */ -static int create_homedir(pam_handle_t * pamh, int ctrl, - const struct passwd *pwd, - const char *source, const char *dest) -{ - char remark[BUFSIZ]; - DIR *D; - struct dirent *Dir; - - /* Mention what is happening, if the notification fails that is OK */ - if (snprintf(remark,sizeof(remark),"Creating directory '%s'.", dest) == -1) - return PAM_PERM_DENIED; - - make_remark(pamh, ctrl, remark); - - /* Create the new directory */ - if (mkdir(dest,0700) != 0) - { - _log_err(LOG_DEBUG, "unable to create directory %s",dest); - return PAM_PERM_DENIED; - } - if (chmod(dest,0777 & (~UMask)) != 0 || - chown(dest,pwd->pw_uid,pwd->pw_gid) != 0) - { - _log_err(LOG_DEBUG, "unable to change perms on directory %s",dest); - return PAM_PERM_DENIED; - } - - /* See if we need to copy the skel dir over. */ - if ((source == NULL) || (strlen(source) == 0)) - { - return PAM_SUCCESS; - } - - /* Scan the directory */ - D = opendir(source); - if (D == 0) - { - _log_err(LOG_DEBUG, "unable to read directory %s",source); - return PAM_PERM_DENIED; - } - - for (Dir = readdir(D); Dir != 0; Dir = readdir(D)) - { - int SrcFd; - int DestFd; - int Res; - struct stat St; -#ifndef PATH_MAX - char *newsource = NULL, *newdest = NULL; - /* track length of buffers */ - int nslen = 0, ndlen = 0; - int slen = strlen(source), dlen = strlen(dest); -#else - char newsource[PATH_MAX], newdest[PATH_MAX]; -#endif - - /* Skip some files.. */ - if (strcmp(Dir->d_name,".") == 0 || - strcmp(Dir->d_name,"..") == 0) - continue; - - /* Determine what kind of file it is. */ -#ifndef PATH_MAX - nslen = slen + strlen(Dir->d_name) + 2; - - if (nslen <= 0) - return PAM_BUF_ERR; - - if ( (newsource = malloc(nslen)) == NULL ) - return PAM_BUF_ERR; - - sprintf(newsource, "%s/%s", source, Dir->d_name); -#else - snprintf(newsource,sizeof(newsource),"%s/%s",source,Dir->d_name); -#endif - - if (lstat(newsource,&St) != 0) -#ifndef PATH_MAX - { - free(newsource); - newsource = NULL; - continue; - } -#else - continue; -#endif - - - /* We'll need the new file's name. */ -#ifndef PATH_MAX - ndlen = dlen + strlen(Dir->d_name)+2; - - if (ndlen <= 0) - return PAM_BUF_ERR; - - if ( (newdest = malloc(ndlen)) == NULL ) { - free(newsource); - return PAM_BUF_ERR; - } - - sprintf(newdest, "%s/%s", dest, Dir->d_name); -#else - snprintf(newdest,sizeof(newdest),"%s/%s",dest,Dir->d_name); -#endif - - /* If it's a directory, recurse. */ - if (S_ISDIR(St.st_mode)) - { - int retval = create_homedir(pamh, ctrl, pwd, newsource, newdest); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - if (retval != PAM_SUCCESS) { - closedir(D); - return retval; - } - continue; - } - - /* If it's a symlink, create a new link. */ - if (S_ISLNK(St.st_mode)) - { - int pointedlen = 0; -#ifndef PATH_MAX - char *pointed = NULL; - { - int size = 100; - - while (1) { - pointed = (char *) malloc(size); - if ( ! pointed ) { - free(newsource); - free(newdest); - return PAM_BUF_ERR; - } - pointedlen = readlink (newsource, pointed, size); - if ( pointedlen < 0 ) break; - if ( pointedlen < size ) break; - free (pointed); - size *= 2; - } - } - if ( pointedlen < 0 ) - free(pointed); - else - pointed[pointedlen] = 0; -#else - char pointed[PATH_MAX]; - memset(pointed, 0, sizeof(pointed)); - - pointedlen = readlink(newsource, pointed, sizeof(pointed) - 1); -#endif - - if ( pointedlen >= 0 ) { - if(symlink(pointed, newdest) == 0) - { - if (lchown(newdest,pwd->pw_uid,pwd->pw_gid) != 0) - { - closedir(D); - _log_err(LOG_DEBUG, "unable to change perms on link %s", - newdest); -#ifndef PATH_MAX - free(pointed); - free(newsource); - free(newdest); -#endif - return PAM_PERM_DENIED; - } - } -#ifndef PATH_MAX - free(pointed); -#endif - } -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - continue; - } - - /* If it's not a regular file, it's probably not a good idea to create - * the new device node, FIFO, or whatever it is. */ - if (!S_ISREG(St.st_mode)) - { -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - continue; - } - - /* Open the source file */ - if ((SrcFd = open(newsource,O_RDONLY)) < 0 || fstat(SrcFd,&St) != 0) - { - closedir(D); - _log_err(LOG_DEBUG, "unable to open src file %s",newsource); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - return PAM_PERM_DENIED; - } - stat(newsource,&St); - - /* Open the dest file */ - if ((DestFd = open(newdest,O_WRONLY | O_TRUNC | O_CREAT,0600)) < 0) - { - close(SrcFd); - closedir(D); - _log_err(LOG_DEBUG, "unable to open dest file %s",newdest); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - return PAM_PERM_DENIED; - } - - /* Set the proper ownership and permissions for the module. We make - the file a+w and then mask it with the set mask. This preseves - execute bits */ - if (fchmod(DestFd,(St.st_mode | 0222) & (~UMask)) != 0 || - fchown(DestFd,pwd->pw_uid,pwd->pw_gid) != 0) - { - close(SrcFd); - close(DestFd); - closedir(D); - _log_err(LOG_DEBUG, "unable to chang perms on copy %s",newdest); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - return PAM_PERM_DENIED; - } - - /* Copy the file */ - do - { - Res = _pammodutil_read(SrcFd,remark,sizeof(remark)); - - if (Res == 0) - continue; - - if (Res > 0) { - if (_pammodutil_write(DestFd,remark,Res) == Res) - continue; - } - - /* If we get here, pammodutil_read returned a -1 or - _pammodutil_write returned something unexpected. */ - close(SrcFd); - close(DestFd); - closedir(D); - _log_err(LOG_DEBUG, "unable to perform IO"); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - return PAM_PERM_DENIED; - } - while (Res != 0); - close(SrcFd); - close(DestFd); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - } - closedir(D); - - return PAM_SUCCESS; -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_open_session(pam_handle_t * pamh, int flags, int argc - ,const char **argv) -{ - int retval, ctrl; - const char *user; - const struct passwd *pwd; - struct stat St; - - /* Parse the flag values */ - ctrl = _pam_parse(flags, argc, argv); - - /* Determine the user name so we can get the home directory */ - retval = pam_get_item(pamh, PAM_USER, (const void **) &user); - if (retval != PAM_SUCCESS || user == NULL || *user == '\0') - { - _log_err(LOG_NOTICE, "user unknown"); - return PAM_USER_UNKNOWN; - } - - /* Get the password entry */ - pwd = _pammodutil_getpwnam (pamh, user); - if (pwd == NULL) - { - D(("couldn't identify user %s", user)); - return PAM_CRED_INSUFFICIENT; - } - - /* Stat the home directory, if something exists then we assume it is - correct and return a success*/ - if (stat(pwd->pw_dir,&St) == 0) - return PAM_SUCCESS; - - return create_homedir(pamh,ctrl,pwd,SkelDir,pwd->pw_dir); -} - -/* Ignore */ -PAM_EXTERN -int pam_sm_close_session(pam_handle_t * pamh, int flags, int argc - ,const char **argv) -{ - return PAM_SUCCESS; -} - -#ifdef PAM_STATIC - -/* static module data */ -struct pam_module _pam_mkhomedir_modstruct = -{ - "pam_mkhomedir", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL, -}; - -#endif diff --git a/modules/pam_motd/.cvsignore b/modules/pam_motd/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_motd/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_motd/Makefile b/modules/pam_motd/Makefile deleted file mode 100644 index ae4acb8c..00000000 --- a/modules/pam_motd/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_motd - -include ../Simple.Rules diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c deleted file mode 100644 index b1d9c9d9..00000000 --- a/modules/pam_motd/pam_motd.c +++ /dev/null @@ -1,133 +0,0 @@ -/* pam_motd module */ - -/* - * Modified for pam_motd by Ben Collins <bcollins@debian.org> - * - * Based off of: - * $Id$ - * - * Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24 - * - */ - -#include <security/_pam_aconf.h> - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <pwd.h> - -#include <security/_pam_macros.h> -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_SESSION -#define DEFAULT_MOTD "/etc/motd" - -#include <security/pam_modules.h> -#include <security/_pam_modutil.h> - -/* --- session management functions (only) --- */ - -PAM_EXTERN -int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return PAM_IGNORE; -} - -PAM_EXTERN -int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - int retval = PAM_IGNORE; - int fd; - char *mtmp=NULL; - const char *motd_path=NULL; - struct pam_conv *conversation; - struct pam_message message; - struct pam_message *pmessage = &message; - struct pam_response *resp = NULL; - struct stat st; - - if (flags & PAM_SILENT) { - return retval; - } - - for (; argc-- > 0; ++argv) { - if (!strncmp(*argv,"motd=",5)) { - - motd_path = (char *) strdup(5+*argv); - if (motd_path != NULL) { - D(("set motd path: %s (and a memory leak)", motd_path)); - } else { - D(("failed to duplicate motd path - ignored")); - } - } - } - - if (motd_path == NULL) - motd_path = DEFAULT_MOTD; - - message.msg_style = PAM_TEXT_INFO; - - if ((fd = open(motd_path, O_RDONLY, 0)) >= 0) { - /* fill in message buffer with contents of motd */ - if ((fstat(fd, &st) < 0) || !st.st_size) { - close(fd); - return retval; - } - message.msg = mtmp = malloc(st.st_size+1); - /* if malloc failed... */ - if (!message.msg) { - close(fd); - return retval; - } - if (_pammodutil_read(fd, mtmp, st.st_size) == st.st_size) { - if (mtmp[st.st_size-1] == '\n') - mtmp[st.st_size-1] = '\0'; - else - mtmp[st.st_size] = '\0'; - close(fd); - - /* Use conversation function to give user contents of motd */ - if (pam_get_item(pamh, PAM_CONV, (const void **)&conversation) == - PAM_SUCCESS && conversation) { - conversation->conv(1, (const struct pam_message **)&pmessage, - &resp, conversation->appdata_ptr); - if (resp) - _pam_drop_reply(resp, 1); - } - } - free(mtmp); - } - - return retval; -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_motd_modstruct = { - "pam_motd", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_nologin/.cvsignore b/modules/pam_nologin/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_nologin/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_nologin/Makefile b/modules/pam_nologin/Makefile deleted file mode 100644 index 130787e7..00000000 --- a/modules/pam_nologin/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_nologin - -include ../Simple.Rules diff --git a/modules/pam_nologin/README b/modules/pam_nologin/README deleted file mode 100644 index 11dc7635..00000000 --- a/modules/pam_nologin/README +++ /dev/null @@ -1,23 +0,0 @@ -# $Id$ -# - -This module always lets root in; it lets other users in only if the file -/etc/nologin doesn't exist. In any case, if /etc/nologin exists, it's -contents are displayed to the user. - -The default return value for this module is PAM_IGNORE, you can -override this with the successok module argument. - -module services provided: - - auth _authenticate and _setcred - account _acct_mgmt - -optional arguments: - - file=<alternative-nologin-pathname> - choose a different file - successok - return PAM_SUCCESS if no file - -[Original README by Michael K. Johnson] - - diff --git a/modules/pam_nologin/pam_nologin.c b/modules/pam_nologin/pam_nologin.c deleted file mode 100644 index bfd17753..00000000 --- a/modules/pam_nologin/pam_nologin.c +++ /dev/null @@ -1,206 +0,0 @@ -/* pam_nologin module */ - -/* - * $Id$ - * - * Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24 - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <pwd.h> - -#include <security/_pam_macros.h> -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> - -#include <security/_pam_modutil.h> - -/* - * parse some command line options - */ -struct opt_s { - int retval_when_nofile; - const char *nologin_file; -}; - -static void parse_args(pam_handle_t *pamh, int argc, const char **argv, - struct opt_s *opts) -{ - int i; - - memset(opts, 0, sizeof(*opts)); - - opts->retval_when_nofile = PAM_IGNORE; - opts->nologin_file = "/etc/nologin"; - - for (i=0; i<argc; ++i) { - if (!strcmp("successok", argv[i])) { - opts->retval_when_nofile = PAM_SUCCESS; - } else if (!memcmp("file=", argv[i], 5)) { - opts->nologin_file = argv[i] + 5; - } else { - /* XXX - ignore for now. Later, we'll use the logging - function in pammodutils */ - } - } -} - -/* - * do the meat of the work for this module - */ - -static int perform_check(pam_handle_t *pamh, struct opt_s *opts) -{ - const char *username; - int retval = PAM_SUCCESS; - int fd; - - retval = opts->retval_when_nofile; - - if ((pam_get_user(pamh, &username, NULL) != PAM_SUCCESS) || !username) { - return PAM_USER_UNKNOWN; - } - - if ((fd = open(opts->nologin_file, O_RDONLY, 0)) >= 0) { - - char *mtmp=NULL; - struct passwd *user_pwd; - struct pam_conv *conversation; - struct pam_message message; - struct pam_message *pmessage = &message; - struct pam_response *resp = NULL; - struct stat st; - - user_pwd = _pammodutil_getpwnam(pamh, username); - if (user_pwd == NULL) { - - retval = PAM_USER_UNKNOWN; - message.msg_style = PAM_ERROR_MSG; - - } else if (user_pwd->pw_uid) { - - retval = PAM_AUTH_ERR; - message.msg_style = PAM_ERROR_MSG; - - } else { - - /* root can still log in; lusers cannot */ - message.msg_style = PAM_TEXT_INFO; - - } - - /* fill in message buffer with contents of /etc/nologin */ - if (fstat(fd, &st) < 0) { - /* give up trying to display message */ - goto clean_up_fd; - } - - message.msg = mtmp = malloc(st.st_size+1); - if (!message.msg) { - /* if malloc failed... */ - retval = PAM_BUF_ERR; - goto clean_up_fd; - } - - if (_pammodutil_read(fd, mtmp, st.st_size) == st.st_size) { - mtmp[st.st_size] = '\000'; - - /* - * Use conversation function to give user contents - * of /etc/nologin - */ - - if (pam_get_item(pamh, PAM_CONV, (const void **)&conversation) - == PAM_SUCCESS && conversation && conversation->conv) { - (void) conversation->conv(1, - (const struct pam_message **)&pmessage, - &resp, conversation->appdata_ptr); - - if (resp) { - _pam_drop_reply(resp, 1); - } - } - } - else - retval = PAM_SYSTEM_ERR; - - free(mtmp); - - clean_up_fd: - - close(fd); - } - - return retval; -} - -/* --- authentication management functions --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - struct opt_s opts; - - parse_args(pamh, argc, argv, &opts); - - return perform_check(pamh, &opts); -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - struct opt_s opts; - - parse_args(pamh, argc, argv, &opts); - - return opts.retval_when_nofile; -} - -/* --- account management function --- */ - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - struct opt_s opts; - - parse_args(pamh, argc, argv, &opts); - - return perform_check(pamh, &opts); -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_nologin_modstruct = { - "pam_nologin", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; - -#endif /* PAM_STATIC */ - -/* end of module definition */ diff --git a/modules/pam_permit/.cvsignore b/modules/pam_permit/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_permit/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_permit/Makefile b/modules/pam_permit/Makefile deleted file mode 100644 index b4cc3b5b..00000000 --- a/modules/pam_permit/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_permit - -include ../Simple.Rules diff --git a/modules/pam_permit/README b/modules/pam_permit/README deleted file mode 100644 index c399710c..00000000 --- a/modules/pam_permit/README +++ /dev/null @@ -1,4 +0,0 @@ -# $Id$ -# - -this module always returns PAM_SUCCESS, it ignores all options. diff --git a/modules/pam_permit/pam_permit.c b/modules/pam_permit/pam_permit.c deleted file mode 100644 index 9eee5611..00000000 --- a/modules/pam_permit/pam_permit.c +++ /dev/null @@ -1,114 +0,0 @@ -/* pam_permit module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11 - * - */ - -#define DEFAULT_USER "nobody" - -#include <stdio.h> - -/* - * 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 -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> - -/* --- authentication management functions --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - int retval; - const char *user=NULL; - - /* - * authentication requires we know who the user wants to be - */ - retval = pam_get_user(pamh, &user, NULL); - if (retval != PAM_SUCCESS) { - D(("get user returned error: %s", pam_strerror(pamh,retval))); - return retval; - } - if (user == NULL || *user == '\0') { - D(("username not known")); - retval = pam_set_item(pamh, PAM_USER, (const void *) DEFAULT_USER); - if (retval != PAM_SUCCESS) - return PAM_USER_UNKNOWN; - } - user = NULL; /* clean up */ - - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_SUCCESS; -} - -/* --- account management functions --- */ - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_SUCCESS; -} - -/* --- password management --- */ - -PAM_EXTERN -int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_SUCCESS; -} - -/* --- session management --- */ - -PAM_EXTERN -int pam_sm_open_session(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_SUCCESS; -} - -/* end of module definition */ - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_permit_modstruct = { - "pam_permit", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; - -#endif diff --git a/modules/pam_pwdb/.cvsignore b/modules/pam_pwdb/.cvsignore deleted file mode 100644 index f0420bac..00000000 --- a/modules/pam_pwdb/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -dynamic -pwdb_chkpwd diff --git a/modules/pam_pwdb/BUGS b/modules/pam_pwdb/BUGS deleted file mode 100644 index a3608a7c..00000000 --- a/modules/pam_pwdb/BUGS +++ /dev/null @@ -1,3 +0,0 @@ -$Id$ - -As of Linux-PAM-0.52 this is new. No known bugs yet. diff --git a/modules/pam_pwdb/CHANGELOG b/modules/pam_pwdb/CHANGELOG deleted file mode 100644 index 7bad5cd8..00000000 --- a/modules/pam_pwdb/CHANGELOG +++ /dev/null @@ -1,10 +0,0 @@ -$Id$ - -Tue Apr 23 12:28:09 EDT 1996 (Alexander O. Yuriev alex@bach.cis.temple.edu) - - * PAM_DISALLOW_NULL_AUTHTOK implemented in the authentication module - * pam_sm_open_session() and pam_sm_close_session() implemented - A new "trace" flag added to flags of /etc/pam.conf. Using this - flag system administrator is able to make pam_unix module provide - very extensive audit trail sent so syslog with LOG_AUTHPRIV level. - * pam_sm_set_cred() is done diff --git a/modules/pam_pwdb/Makefile b/modules/pam_pwdb/Makefile deleted file mode 100644 index fa0e1b02..00000000 --- a/modules/pam_pwdb/Makefile +++ /dev/null @@ -1,127 +0,0 @@ -# $Id$ -# -# This Makefile controls a build process of the pam_unix module -# for Linux-PAM. You should not modify this Makefile. -# -# rewritten to compile new module Andrew Morgan -# <morgan@parc.power.net> 1996/11/6 -# - -include ../../Make.Rules - -ifeq ($(HAVE_LIBPWDB),yes) - -EXTRALS += -lpwdb -EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\" - -ifeq ($(HAVE_LIBCRYPT),yes) - EXTRALS += -lcrypt -endif -ifeq ($(HAVE_LIBNSL),yes) - EXTRALS += -lnsl -endif - -TITLE=pam_pwdb -CHKPWD=pwdb_chkpwd - -LIBSRC = $(TITLE).c -LIBOBJ = $(TITLE).o -LIBOBJD = $(addprefix dynamic/,$(LIBOBJ)) -#LIBOBJS = $(addprefix static/,$(LIBOBJ)) -LIBDEPS = pam_unix_acct.-c pam_unix_auth.-c pam_unix_passwd.-c \ - pam_unix_sess.-c pam_unix_pwupd.-c support.-c bigcrypt.-c - -PLUS += md5_good.o md5_broken.o md5_crypt_good.o md5_crypt_broken.o -CFLAGS += $(EXTRAS) - -ifdef DYNAMIC -LIBSHARED = $(TITLE).so -endif -#ifdef STATIC -#LIBSTATIC = lib$(TITLE).o -#endif - -all: info dirs $(PLUS) $(LIBSHARED) $(LIBSTATIC) register $(CHKPWD) - -dynamic/$(LIBOBJ) : $(LIBSRC) $(LIBDEPS) - $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ - -#static/$(LIBOBJ) : $(LIBSRC) $(LIBDEPS) -# $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ - -info: - @echo - @echo "*** Building PAM_pwdb module..." - @echo - -$(CHKPWD): pwdb_chkpwd.o md5_good.o md5_broken.o \ - md5_crypt_good.o md5_crypt_broken.o - $(CC) $(CFLAGS) -o $(CHKPWD) $^ $(LDFLAGS) -lpwdb $(EXTRALS) - -pwdb_chkpwd.o: pwdb_chkpwd.c pam_unix_md.-c bigcrypt.-c - -md5_good.o: md5.c - $(CC) $(CFLAGS) $(CPPFLAGS) -DHIGHFIRST -D'MD5Name(x)=Good##x' \ - $(TARGET_ARCH) -c $< -o $@ - -md5_broken.o: md5.c - $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \ - $(TARGET_ARCH) -c $< -o $@ - -md5_crypt_good.o: md5_crypt.c - $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Good##x' \ - $(TARGET_ARCH) -c $< -o $@ - -md5_crypt_broken.o: md5_crypt.c - $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \ - $(TARGET_ARCH) -c $< -o $@ - -dirs: -ifdef DYNAMIC - @$(MKDIR) ./dynamic -endif -#ifdef STATIC -# @$(MKDIR) ./static -#endif - -register: -#ifdef STATIC -# ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) ) -#endif - -ifdef DYNAMIC -$(LIBOBJD): $(LIBSRC) - -$(LIBSHARED): $(LIBOBJD) - $(LD_D) -o $@ $(LIBOBJD) $(PLUS) $(EXTRALS) -endif - -#ifdef STATIC -#$(LIBOBJS): $(LIBSRC) -# -#$(LIBSTATIC): $(LIBOBJS) -# $(LD) -r -o $@ $(LIBOBJS) $(PLUS) $(EXTRALS) -#endif - -install: all - $(MKDIR) $(FAKEROOT)$(SECUREDIR) -ifdef DYNAMIC - $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR) -endif - $(MKDIR) $(FAKEROOT)$(SUPLEMENTED) - $(INSTALL) -m 4555 $(CHKPWD) $(FAKEROOT)$(SUPLEMENTED) - -remove: - rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so - rm -f $(FAKEROOT)$(SUPLEMENTED)/$(CHKPWD) - -clean: - rm -f $(CHKPWD) $(LIBOBJD) $(LIBOBJS) $(MOREDELS) core *~ *.o *.so - rm -f *.a *.o *.so *.bak - rm -fr dynamic static - -else - -include ../dont_makefile - -endif diff --git a/modules/pam_pwdb/README b/modules/pam_pwdb/README deleted file mode 100644 index 4f420855..00000000 --- a/modules/pam_pwdb/README +++ /dev/null @@ -1,41 +0,0 @@ -This is the pam_unix module. It has been significantly rewritten since -.51 was released (due mostly to the efforts of Cristian Gafton), and -now takes more options and correctly updates vanilla UNIX/shadow/md5 -passwords. - -[Please read the source and make a note of all the warnings there, as -the license suggests -- use at your own risk.] - -So far as I am concerned this module is now pretty stable. If you find -any bugs, PLEASE tell me! <morgan@linux.kernel.org> - -Options recognized by this module are as follows: - - debug - log more debugging info - audit - a little more extreme than debug - use_first_pass - don't prompt the user for passwords - take them from PAM_ items instead - try_first_pass - don't prompt the user for the passwords - unless PAM_(OLD)AUTHTOK is unset - use_authtok - like try_first_pass, but *fail* if the new - PAM_AUTHTOK has not been previously set. - (intended for stacking password modules only) - not_set_pass - don't set the PAM_ items with the passwords - used by this module. - shadow - try to maintian a shadow based system. - unix - when changing passwords, they are placed - in the /etc/passwd file - md5 - when a user changes their password next, - encrypt it with the md5 algorithm. - bigcrypt - when a user changes their password next, - excrypt it with the DEC C2-algorithm(0). - nodelay - used to prevent failed authentication - resulting in a delay of about 1 second. - -There is some support for building a shadow file on-the-fly from an -/etc/passwd file. This is VERY alpha. If you want to play with it you -should read the source to find the appropriate #define that you will -need. - ---------------------- -Andrew Morgan <morgan@linux.kernel.org> diff --git a/modules/pam_pwdb/TODO b/modules/pam_pwdb/TODO deleted file mode 100644 index 9dc7fc7e..00000000 --- a/modules/pam_pwdb/TODO +++ /dev/null @@ -1,34 +0,0 @@ -$Id$ - - * get NIS working - * .. including "nonis" argument - * add helper binary - -Wed Sep 4 23:40:09 PDT 1996 Andrew G. Morgan - - * verify that it works for everyone - * look more seriously at the issue of generating a shadow - system on the fly - * add some more password flavors - -Thu Aug 29 06:26:42 PDT 1996 Andrew G. Morgan - - * check that complete rewrite works! ;^) - * complete shadow support to the password changing code. - Also some code needed here for session managment? - (both pam.conf argument to turn it on/off, and some - conditional compilation.) - * md5 passwords... - * make the exclusive nature of the arguments work. That is, - only recognize the flags when appropriate. - -Wed May 8 19:08:49 EDT 1996 Alexander O. Yuriev - - * support.c should go. - -Tue Apr 23 21:43:55 EDT 1996 Alexander O. Yuriev - - * pam_sm_chauth_tok() should be written - * QUICK FIX: pam_sm_setcred() probably returns incorrect error code - - diff --git a/modules/pam_pwdb/bigcrypt.-c b/modules/pam_pwdb/bigcrypt.-c deleted file mode 100644 index 321f2491..00000000 --- a/modules/pam_pwdb/bigcrypt.-c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * This function implements the "bigcrypt" algorithm specifically for - * Linux-PAM. - * - * This algorithm is algorithm 0 (default) shipped with the C2 secure - * implementation of Digital UNIX. - * - * Disclaimer: This work is not based on the source code to Digital - * UNIX, nor am I connected to Digital Equipment Corp, in any way - * other than as a customer. This code is based on published - * interfaces and reasonable guesswork. - * - * Description: The cleartext is divided into blocks of SEGMENT_SIZE=8 - * characters or less. Each block is encrypted using the standard UNIX - * libc crypt function. The result of the encryption for one block - * provides the salt for the suceeding block. - * - * Restrictions: The buffer used to hold the encrypted result is - * statically allocated. (see MAX_PASS_LEN below). This is necessary, - * as the returned pointer points to "static data that are overwritten - * by each call", (XPG3: XSI System Interface + Headers pg 109), and - * this is a drop in replacement for crypt(); - * - * Andy Phillips <atp@mssl.ucl.ac.uk> - */ - -/* - * Max cleartext password length in segments of 8 characters this - * function can deal with (16 segments of 8 chars= max 128 character - * password). - */ - -#define MAX_PASS_LEN 16 -#define SEGMENT_SIZE 8 -#define SALT_SIZE 2 -#define KEYBUF_SIZE ((MAX_PASS_LEN*SEGMENT_SIZE)+SALT_SIZE) -#define ESEGMENT_SIZE 11 -#define CBUF_SIZE ((MAX_PASS_LEN*ESEGMENT_SIZE)+SALT_SIZE+1) - -static char *bigcrypt(const char *key, const char *salt) -{ - static char dec_c2_cryptbuf[CBUF_SIZE]; /* static storage area */ - - unsigned long int keylen,n_seg,j; - char *cipher_ptr,*plaintext_ptr,*tmp_ptr,*salt_ptr; - char keybuf[KEYBUF_SIZE+1]; - - D(("called with key='%s', salt='%s'.", key, salt)); - - /* reset arrays */ - memset(keybuf, 0, KEYBUF_SIZE+1); - memset(dec_c2_cryptbuf, 0, CBUF_SIZE); - - /* fill KEYBUF_SIZE with key */ - strncpy(keybuf, key, KEYBUF_SIZE); - - /* deal with case that we are doing a password check for a - conventially encrypted password: the salt will be - SALT_SIZE+ESEGMENT_SIZE long. */ - if (strlen(salt) == (SALT_SIZE+ESEGMENT_SIZE)) - keybuf[SEGMENT_SIZE] = '\0'; /* terminate password early(?) */ - - keylen = strlen(keybuf); - - if (!keylen) { - n_seg = 1; - } else { - /* work out how many segments */ - n_seg = 1 + ((keylen-1)/SEGMENT_SIZE); - } - - if (n_seg > MAX_PASS_LEN) - n_seg = MAX_PASS_LEN; /* truncate at max length */ - - /* set up some pointers */ - cipher_ptr = dec_c2_cryptbuf; - plaintext_ptr = keybuf; - - /* do the first block with supplied salt */ - tmp_ptr = crypt(plaintext_ptr,salt); /* libc crypt() */ - - /* and place in the static area */ - strncpy(cipher_ptr, tmp_ptr, 13); - cipher_ptr += ESEGMENT_SIZE + SALT_SIZE; - plaintext_ptr += SEGMENT_SIZE; /* first block of SEGMENT_SIZE */ - - /* change the salt (1st 2 chars of previous block) - this was found - by dowsing */ - - salt_ptr = cipher_ptr - ESEGMENT_SIZE; - - /* so far this is identical to "return crypt(key, salt);", if - there is more than one block encrypt them... */ - - if (n_seg > 1) { - for (j=2; j <= n_seg; j++) { - - tmp_ptr = crypt(plaintext_ptr, salt_ptr); - - /* skip the salt for seg!=0 */ - strncpy(cipher_ptr, (tmp_ptr+SALT_SIZE), ESEGMENT_SIZE); - - cipher_ptr += ESEGMENT_SIZE; - plaintext_ptr += SEGMENT_SIZE; - salt_ptr = cipher_ptr - ESEGMENT_SIZE; - } - } - - D(("key=|%s|, salt=|%s|\nbuf=|%s|\n", key, salt, dec_c2_cryptbuf)); - - /* this is the <NUL> terminated encrypted password */ - - return dec_c2_cryptbuf; -} diff --git a/modules/pam_pwdb/md5.c b/modules/pam_pwdb/md5.c deleted file mode 100644 index 335908df..00000000 --- a/modules/pam_pwdb/md5.c +++ /dev/null @@ -1,255 +0,0 @@ -/* $Id$ - * - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - * - */ - -#include <string.h> -#include "md5.h" - -#ifndef HIGHFIRST -#define byteReverse(buf, len) /* Nothing */ -#else -static void byteReverse(unsigned char *buf, unsigned longs); - -#ifndef ASM_MD5 -/* - * Note: this code is harmless on little-endian machines. - */ -static void byteReverse(unsigned char *buf, unsigned longs) -{ - uint32 t; - do { - t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | - ((unsigned) buf[1] << 8 | buf[0]); - *(uint32 *) buf = t; - buf += 4; - } while (--longs); -} -#endif -#endif - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void MD5Name(MD5Init)(struct MD5Context *ctx) -{ - ctx->buf[0] = 0x67452301U; - ctx->buf[1] = 0xefcdab89U; - ctx->buf[2] = 0x98badcfeU; - ctx->buf[3] = 0x10325476U; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len) -{ - uint32 t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if (t) { - unsigned char *p = (unsigned char *) ctx->in + t; - - t = 64 - t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx) -{ - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset(p, 0, count - 8); - } - byteReverse(ctx->in, 14); - - /* Append length in bits and transform */ - ((uint32 *) ctx->in)[14] = ctx->bits[0]; - ((uint32 *) ctx->in)[15] = ctx->bits[1]; - - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - byteReverse((unsigned char *) ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ -} - -#ifndef ASM_MD5 - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16]) -{ - register uint32 a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478U, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756U, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbU, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeU, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aU, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613U, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501U, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8U, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afU, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1U, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beU, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122U, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193U, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eU, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821U, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562U, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340U, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51U, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaU, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dU, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453U, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681U, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8U, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6U, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6U, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87U, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edU, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905U, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8U, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9U, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aU, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942U, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681U, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122U, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cU, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44U, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9U, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60U, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70U, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6U, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faU, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085U, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05U, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039U, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5U, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8U, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665U, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244U, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97U, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7U, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039U, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3U, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92U, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dU, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1U, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0U, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314U, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1U, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82U, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235U, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbU, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391U, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -#endif diff --git a/modules/pam_pwdb/md5.h b/modules/pam_pwdb/md5.h deleted file mode 100644 index 75c4dbac..00000000 --- a/modules/pam_pwdb/md5.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef MD5_H -#define MD5_H - -typedef unsigned int uint32; - -struct MD5Context { - uint32 buf[4]; - uint32 bits[2]; - unsigned char in[64]; -}; - -void GoodMD5Init(struct MD5Context *); -void GoodMD5Update(struct MD5Context *, unsigned const char *, unsigned); -void GoodMD5Final(unsigned char digest[16], struct MD5Context *); -void GoodMD5Transform(uint32 buf[4], uint32 const in[16]); -void BrokenMD5Init(struct MD5Context *); -void BrokenMD5Update(struct MD5Context *, unsigned const char *, unsigned); -void BrokenMD5Final(unsigned char digest[16], struct MD5Context *); -void BrokenMD5Transform(uint32 buf[4], uint32 const in[16]); - -char *Goodcrypt_md5(const char *pw, const char *salt); -char *Brokencrypt_md5(const char *pw, const char *salt); - -/* -* This is needed to make RSAREF happy on some MS-DOS compilers. -*/ - -typedef struct MD5Context MD5_CTX; - -#endif /* MD5_H */ diff --git a/modules/pam_pwdb/md5_crypt.c b/modules/pam_pwdb/md5_crypt.c deleted file mode 100644 index 4226dd1e..00000000 --- a/modules/pam_pwdb/md5_crypt.c +++ /dev/null @@ -1,138 +0,0 @@ -/* $Id$ - * - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * Origin: Id: crypt.c,v 1.3 1995/05/30 05:42:22 rgrimes Exp - * - */ - -#include <string.h> -#include "md5.h" - -static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -static void -to64(char *s, unsigned long v, int n) -{ - while (--n >= 0) { - *s++ = itoa64[v&0x3f]; - v >>= 6; - } -} - -/* - * UNIX password - * - * Use MD5 for what it is best at... - */ - -char * MD5Name(crypt_md5)(const char *pw, const char *salt) -{ - const char *magic = "$1$"; - /* This string is magic for this algorithm. Having - * it this way, we can get get better later on */ - static char passwd[120], *p; - static const char *sp,*ep; - unsigned char final[16]; - int sl,pl,i,j; - MD5_CTX ctx,ctx1; - unsigned long l; - - /* Refine the Salt first */ - sp = salt; - - /* If it starts with the magic string, then skip that */ - if(!strncmp(sp,magic,strlen(magic))) - sp += strlen(magic); - - /* It stops at the first '$', max 8 chars */ - for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++) - continue; - - /* get the length of the true salt */ - sl = ep - sp; - - MD5Name(MD5Init)(&ctx); - - /* The password first, since that is what is most unknown */ - MD5Name(MD5Update)(&ctx,(unsigned const char *)pw,strlen(pw)); - - /* Then our magic string */ - MD5Name(MD5Update)(&ctx,(unsigned const char *)magic,strlen(magic)); - - /* Then the raw salt */ - MD5Name(MD5Update)(&ctx,(unsigned const char *)sp,sl); - - /* Then just as many characters of the MD5(pw,salt,pw) */ - MD5Name(MD5Init)(&ctx1); - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl); - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - MD5Name(MD5Final)(final,&ctx1); - for(pl = strlen(pw); pl > 0; pl -= 16) - MD5Name(MD5Update)(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl); - - /* Don't leave anything around in vm they could use. */ - memset(final,0,sizeof final); - - /* Then something really weird... */ - for (j=0,i = strlen(pw); i ; i >>= 1) - if(i&1) - MD5Name(MD5Update)(&ctx, (unsigned const char *)final+j, 1); - else - MD5Name(MD5Update)(&ctx, (unsigned const char *)pw+j, 1); - - /* Now make the output string */ - strcpy(passwd,magic); - strncat(passwd,sp,sl); - strcat(passwd,"$"); - - MD5Name(MD5Final)(final,&ctx); - - /* - * and now, just to make sure things don't run too fast - * On a 60 Mhz Pentium this takes 34 msec, so you would - * need 30 seconds to build a 1000 entry dictionary... - */ - for(i=0;i<1000;i++) { - MD5Name(MD5Init)(&ctx1); - if(i & 1) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - else - MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16); - - if(i % 3) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl); - - if(i % 7) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - - if(i & 1) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16); - else - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - MD5Name(MD5Final)(final,&ctx1); - } - - p = passwd + strlen(passwd); - - l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4; - l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4; - l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4; - l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4; - l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4; - l = final[11] ; to64(p,l,2); p += 2; - *p = '\0'; - - /* Don't leave anything around in vm they could use. */ - memset(final,0,sizeof final); - - return passwd; -} - diff --git a/modules/pam_pwdb/pam_pwdb.c b/modules/pam_pwdb/pam_pwdb.c deleted file mode 100644 index d736c6a8..00000000 --- a/modules/pam_pwdb/pam_pwdb.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * $Id$ - * - * This is the single file that will be compiled for pam_unix. - * it includes each of the modules that have beed defined in the .-c - * files in this directory. - * - * It is a little ugly to do it this way, but it is a simple way of - * defining static functions only once, and yet keeping the separate - * files modular. If you can think of something better, please email - * Andrew Morgan <morgan@linux.kernel.org> - * - * See the end of this file for Copyright information. - */ - -static const char rcsid[] = -"$Id$\n" -" - PWDB Pluggable Authentication module. <morgan@linux.kernel.org>" -; - -/* #define DEBUG */ - -#include <security/_pam_aconf.h> - -#include <sys/types.h> -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <syslog.h> -#include <time.h> /* for time() */ -#include <fcntl.h> -#include <ctype.h> - -#include <sys/time.h> -#include <unistd.h> - -#include <pwdb/pwdb_public.h> - -/* indicate the following groups are defined */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/_pam_macros.h> -#include <security/pam_modules.h> - -#ifndef LINUX_PAM -#include <security/pam_appl.h> -#endif /* LINUX_PAM */ - -#include "./support.-c" - -/* - * PAM framework looks for these entry-points to pass control to the - * authentication module. - */ - -#include "./pam_unix_auth.-c" - -PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags - , int argc, const char **argv) -{ - unsigned int ctrl; - int retval; - - D(("called.")); - - pwdb_start(); - ctrl = set_ctrl(flags, argc, argv); - retval = _unix_auth( pamh, ctrl ); - pwdb_end(); - - if ( on(UNIX_LIKE_AUTH, ctrl) ) { - D(("recording return code for next time [%d]", retval)); - pam_set_data(pamh, "pwdb_setcred_return", (void *) retval, NULL); - } - - D(("done. [%s]", pam_strerror(pamh, retval))); - - return retval; -} - -PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags - , int argc, const char **argv) -{ - unsigned int ctrl; - int retval; - - D(("called.")); - - pwdb_start(); - ctrl = set_ctrl(flags, argc, argv); - retval = _unix_set_credentials(pamh, ctrl); - pwdb_end(); - - if ( on(UNIX_LIKE_AUTH, ctrl) ) { - int *pretval = &retval; - - D(("recovering return code from auth call")); - pam_get_data(pamh, "pwdb_setcred_return", (const void **) pretval); - D(("recovered data indicates that old retval was %d", retval)); - } - - return retval; -} - -/* - * PAM framework looks for these entry-points to pass control to the - * account management module. - */ - -#include "./pam_unix_acct.-c" - -PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - unsigned int ctrl; - int retval; - - D(("called.")); - - pwdb_start(); - ctrl = set_ctrl(flags, argc, argv); - retval = _unix_acct_mgmt(pamh, ctrl); - pwdb_end(); - - D(("done.")); - - return retval; -} - -/* - * PAM framework looks for these entry-points to pass control to the - * session module. - */ - -#include "./pam_unix_sess.-c" - -PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - unsigned int ctrl; - int retval; - - D(("called.")); - - pwdb_start(); - ctrl = set_ctrl(flags, argc, argv); - retval = _unix_open_session(pamh, ctrl); - pwdb_end(); - - return retval; -} - -PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - unsigned int ctrl; - int retval; - - D(("called.")); - - pwdb_start(); - ctrl = set_ctrl(flags, argc, argv); - retval = _unix_close_session(pamh, ctrl); - pwdb_end(); - - return retval; -} - -/* - * PAM framework looks for these entry-points to pass control to the - * password changing module. - */ - -#include "./pam_unix_passwd.-c" - -PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - unsigned int ctrl; - int retval; - - D(("called.")); - - pwdb_start(); - ctrl = set_ctrl(flags, argc, argv); - retval = _unix_chauthtok(pamh, ctrl); - pwdb_end(); - - D(("done.")); - - return retval; -} - -/* static module data */ - -#ifdef PAM_STATIC -struct pam_module _pam_pwdb_modstruct = { - "pam_pwdb", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; - -#endif - -/* - * Copyright (c) Andrew G. Morgan, 1996. All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_pwdb/pam_unix_acct.-c b/modules/pam_pwdb/pam_unix_acct.-c deleted file mode 100644 index 0ee3b3d5..00000000 --- a/modules/pam_pwdb/pam_unix_acct.-c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * $Id$ - * - * See end of file for copyright information - */ - -static const char rcsid_acct[] = -"$Id$\n" -" - PAM_PWDB account management <gafton@redhat.com>"; - -/* the shadow suite has accout managment.. */ - -static int _shadow_acct_mgmt_exp(pam_handle_t *pamh, unsigned int ctrl, - const struct pwdb *pw, const char *uname) -{ - const struct pwdb_entry *pwe = NULL; - time_t curdays; - int last_change, max_change; - int retval; - - D(("called.")); - - /* Now start the checks */ - - curdays = time(NULL)/(60*60*24); /* today */ - - /* First: has account expired ? (CG) - * - expire < curdays - * - or (last_change + max_change + defer_change) < curdays - * - in both cases, deny access - */ - - D(("pwdb_get_entry")); - retval = pwdb_get_entry(pw, "expire", &pwe); - if (retval == PWDB_SUCCESS) { - int expire; - - expire = *( (const int *) pwe->value ); - (void) pwdb_entry_delete(&pwe); /* no longer needed */ - - if ((curdays > expire) && (expire > 0)) { - - _log_err(LOG_NOTICE - , "acct: account %s has expired (account expired)" - , uname); - make_remark(pamh, ctrl, PAM_ERROR_MSG - , "Your account has expired; " - "please contact your system administrator"); - - D(("account expired")); - return PAM_ACCT_EXPIRED; - } - } - - D(("pwdb_get_entry")); - retval = pwdb_get_entry(pw, "last_change", &pwe); - if ( retval == PWDB_SUCCESS ) { - last_change = *( (const int *) pwe->value ); - } else { - last_change = curdays; - } - (void) pwdb_entry_delete(&pwe); - - D(("pwdb_get_entry")); - retval = pwdb_get_entry(pw, "max_change", &pwe); - if ( retval == PWDB_SUCCESS ) { - max_change = *( (const int *) pwe->value ); - } else { - max_change = -1; - } - (void) pwdb_entry_delete(&pwe); - - D(("pwdb_get_entry")); - retval = pwdb_get_entry(pw, "defer_change", &pwe); - if (retval == PWDB_SUCCESS) { - int defer_change; - - defer_change = *( (const int *) pwe->value ); - (void) pwdb_entry_delete(&pwe); - - if ((curdays > (last_change + max_change + defer_change)) - && (max_change != -1) && (defer_change != -1) - && (last_change > 0)) { - - if ( on(UNIX_DEBUG, ctrl) ) { - _log_err(LOG_NOTICE, "acct: account %s has expired " - "(failed to change password)", uname); - } - make_remark(pamh, ctrl, PAM_ERROR_MSG - , "Your password has expired; " - "please see your system administrator"); - - D(("account expired2")); - return PAM_ACCT_EXPIRED; - } - } - - /* Now test if the password is expired, but the user still can - * change their password. (CG) - * - last_change = 0 - * - last_change + max_change < curdays - */ - - D(("when was the last change")); - if (last_change == 0) { - - if ( on(UNIX_DEBUG, ctrl) ) { - _log_err(LOG_NOTICE - , "acct: expired password for user %s (root enforced)" - , uname); - } - make_remark(pamh, ctrl, PAM_ERROR_MSG - , "You are required to change your password immediately" - ); - - D(("need a new password")); - return PAM_NEW_AUTHTOK_REQD; - } - - if (((last_change + max_change) < curdays) && - (max_change < 99999) && (max_change > 0)) { - - if ( on(UNIX_DEBUG, ctrl) ) { - _log_err(LOG_DEBUG - , "acct: expired password for user %s (password aged)" - , uname); - } - make_remark(pamh, ctrl, PAM_ERROR_MSG - , "Your password has expired; please change it!"); - - D(("need a new password 2")); - return PAM_NEW_AUTHTOK_REQD; - } - - /* - * Now test if the password is about to expire (CG) - * - last_change + max_change - curdays <= warn_change - */ - - retval = pwdb_get_entry(pw, "warn_change", &pwe); - if ( retval == PWDB_SUCCESS ) { - int warn_days, daysleft; - - daysleft = last_change + max_change - curdays; - warn_days = *((const int *) pwe->value); - (void) pwdb_entry_delete(&pwe); - - if ((daysleft <= warn_days) && (warn_days > 0)) { - char *s; - - if ( on(UNIX_DEBUG, ctrl) ) { - _log_err(LOG_DEBUG - , "acct: password for user %s will expire in %d days" - , uname, daysleft); - } - -#define LocalComment "Warning: your password will expire in %d day%s" - if ((s = (char *) malloc(30+sizeof(LocalComment))) == NULL) { - _log_err(LOG_CRIT, "malloc failure in " __FILE__); - retval = PAM_BUF_ERR; - } else { - - sprintf(s, LocalComment, daysleft, daysleft == 1 ? "":"s"); - - make_remark(pamh, ctrl, PAM_TEXT_INFO, s); - free(s); - } -#undef LocalComment - } - } else { - retval = PAM_SUCCESS; - } - - D(("all done")); - return retval; -} - - -/* - * this function checks for the account details. The user may not be - * permitted to log in at this time etc.. Within the context of - * vanilla Unix, this function simply does nothing. The shadow suite - * added password/account expiry, but PWDB takes care of this - * transparently. - */ - -static int _unix_acct_mgmt(pam_handle_t *pamh, unsigned int ctrl) -{ - const struct pwdb *pw = NULL; - - char *uname=NULL; - int retval; - - D(("called.")); - - /* identify user */ - - retval = pam_get_item(pamh,PAM_USER,(const void **)&uname); - D(("user = `%s'", uname)); - if (retval != PAM_SUCCESS || uname == NULL) { - _log_err(LOG_ALERT - , "acct; could not identify user (from uid=%d)" - , getuid()); - return PAM_USER_UNKNOWN; - } - - /* get database information for user */ - - retval = pwdb_locate("user", PWDB_DEFAULT, uname, PWDB_ID_UNKNOWN, &pw); - if (retval != PWDB_SUCCESS || pw == NULL) { - - _log_err(LOG_ALERT, "acct; %s (%s from uid=%d)" - , pwdb_strerror(retval), uname, getuid()); - if ( pw ) { - (void) pwdb_delete(&pw); - } - return PAM_USER_UNKNOWN; - } - - /* now check the user's times etc.. */ - - retval = _shadow_acct_mgmt_exp(pamh, ctrl, pw, uname); - if (retval != PAM_SUCCESS) { - _log_err(LOG_NOTICE, "expiry check failed for '%s'", uname); - } - - /* Done with pw */ - - (void) pwdb_delete(&pw); - - /* all done */ - - D(("done.")); - return retval; -} - -/* - * Copyright (c) Elliot Lee, 1996. - * Copyright (c) Andrew Morgan <morgan@parc.power.net> 1996. - * Copyright (c) Cristian Gafton <gafton@redhat.com> 1996. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_pwdb/pam_unix_auth.-c b/modules/pam_pwdb/pam_unix_auth.-c deleted file mode 100644 index e4dfe136..00000000 --- a/modules/pam_pwdb/pam_unix_auth.-c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * $Id$ - * - * See end of file for Copyright information. - */ - -static const char rcsid_auth[] = -"$Id$: pam_unix_auth.-c,v 1.2 1996/09/05 06:46:53 morgan Exp morgan $\n" -" - PAM_PWDB authentication functions. <morgan@parc.power.net>"; - -/* - * _unix_auth() is a front-end for UNIX/shadow authentication - * - * First, obtain the password from the user. Then use a - * routine in 'support.-c' to authenticate the user. - */ - -#define _UNIX_AUTHTOK "-UN*X-PASS" - -static int _unix_auth(pam_handle_t *pamh, unsigned int ctrl) -{ - int retval; - const char *name, *p; - - D(("called.")); - - /* get the user'name' */ - - retval = _unix_get_user(pamh, ctrl, NULL, &name); - if (retval != PAM_SUCCESS ) { - if (retval != PAM_CONV_AGAIN) { - if ( on(UNIX_DEBUG,ctrl) ) { - _log_err(LOG_DEBUG, "auth could not identify user"); - } - } else { - D(("pam_get_user/conv() function is not ready yet")); - /* it is safe to resume this function so we translate this - retval to the value that indicates we're happy to resume. */ - retval = PAM_INCOMPLETE; - } - return retval; - } - - /* if this user does not have a password... */ - - if ( _unix_blankpasswd(ctrl, name) ) { - D(("user '%s' has blank passwd", name)); - name = NULL; - return PAM_SUCCESS; - } - - /* get this user's authentication token */ - - retval = _unix_read_password(pamh, ctrl, NULL, "Password: ", NULL - , _UNIX_AUTHTOK, &p); - if (retval != PAM_SUCCESS) { - if (retval != PAM_CONV_AGAIN) { - _log_err(LOG_CRIT, "auth could not identify password for [%s]" - , name); - } else { - D(("conversation function is not ready yet")); - /* it is safe to resume this function so we translate this - retval to the value that indicates we're happy to resume. */ - retval = PAM_INCOMPLETE; - } - name = NULL; - return retval; - } - D(("user=%s, password=[%s]", name, p)); - - /* verify the password of this user */ - retval = _unix_verify_password(pamh, name, p, ctrl); - name = p = NULL; - - D(("done [%d]", retval)); - - return retval; -} - -/* - * This function is for setting unix credentials. Sun has indicated - * that there are *NO* authentication credentials for unix. The - * obvious credentials would be the group membership of the user as - * listed in the /etc/group file. However, Sun indicates that it is - * the responsibility of the application to set these. - */ - -static int _unix_set_credentials(pam_handle_t *pamh, unsigned int ctrl) -{ - D(("called <empty function> returning.")); - - return PAM_SUCCESS; -} - -/******************************************************************** - * Copyright (c) Alexander O. Yuriev, 1996. - * Copyright (c) Andrew G. Morgan <morgan@parc.power.net> 1996 - * Copyright (c) Cristian Gafton <gafton@redhat.com> 1996, 1997 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - diff --git a/modules/pam_pwdb/pam_unix_md.-c b/modules/pam_pwdb/pam_unix_md.-c deleted file mode 100644 index 65476732..00000000 --- a/modules/pam_pwdb/pam_unix_md.-c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This function is a front-end for the message digest algorithms used - * to compute the user's encrypted passwords. No reversible encryption - * is used here and I intend to keep it that way. - * - * While there are many sources of encryption outside the United - * States, it *may* be illegal to re-export reversible encryption - * computer code. Until such time as it is legal to export encryption - * software freely from the US, please do not send me any. (AGM) - */ - -/* this should have been defined in a header file.. Why wasn't it? AGM */ -extern char *crypt(const char *key, const char *salt); - -#include "md5.h" -#include "bigcrypt.-c" - -struct cfns { - const char *salt; - int len; - char * (* mdfn)(const char *key, const char *salt); -}; - -/* array of non-standard digest algorithms available */ - -#define N_MDS 1 -const static struct cfns cfn_list[N_MDS] = { - { "$1$", 3, Goodcrypt_md5 }, -}; - -static char *_pam_md(const char *key, const char *salt) -{ - char *x,*e=NULL; - int i; - - D(("called with key='%s', salt='%s'", key, salt)); - - /* check for non-standard salts */ - - for (i=0; i<N_MDS; ++i) { - if ( !strncmp(cfn_list[i].salt, salt, cfn_list[i].len) ) { - e = cfn_list[i].mdfn(key, salt); - break; - } - } - - if ( i >= N_MDS ) { - e = bigcrypt(key, salt); /* (defaults to standard algorithm) */ - } - - x = x_strdup(e); /* put e in malloc()ed memory */ - _pam_overwrite(e); /* clean up */ - return x; /* this must be deleted elsewhere */ -} - -#ifndef PWDB_NO_MD_COMPAT -static char *_pam_md_compat(const char *key, const char *salt) -{ - char *x,*e=NULL; - - D(("called with key='%s', salt='%s'", key, salt)); - - if ( !strncmp("$1$", salt, 3) ) { - e = Brokencrypt_md5(key, salt); - x = x_strdup(e); /* put e in malloc()ed memory */ - _pam_overwrite(e); /* clean up */ - } else { - x = x_strdup(""); /* called from only one place so this is safe */ - } - - return x; /* this must be deleted elsewhere */ -} -#endif /* PWDB_NO_MD_COMPAT */ diff --git a/modules/pam_pwdb/pam_unix_passwd.-c b/modules/pam_pwdb/pam_unix_passwd.-c deleted file mode 100644 index 0949af7f..00000000 --- a/modules/pam_pwdb/pam_unix_passwd.-c +++ /dev/null @@ -1,373 +0,0 @@ -/* $Id$ */ - -static const char rcsid_pass[] = -"$Id$\n" -" - PAM_PWDB password module <morgan@parc.power.net>" -; - -#include "pam_unix_pwupd.-c" - -/* passwd/salt conversion macros */ - -#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.') -#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') - -/* data tokens */ - -#define _UNIX_OLD_AUTHTOK "-UN*X-OLD-PASS" -#define _UNIX_NEW_AUTHTOK "-UN*X-NEW-PASS" - -/* Implementation */ - -/* - * i64c - convert an integer to a radix 64 character - */ -static int i64c(int i) -{ - if (i < 0) - return ('.'); - else if (i > 63) - return ('z'); - if (i == 0) - return ('.'); - if (i == 1) - return ('/'); - if (i >= 2 && i <= 11) - return ('0' - 2 + i); - if (i >= 12 && i <= 37) - return ('A' - 12 + i); - if (i >= 38 && i <= 63) - return ('a' - 38 + i); - return ('\0'); -} - -/* - * FUNCTION: _pam_unix_chauthtok() - * - * this function works in two passes. The first, when UNIX__PRELIM is - * set, obtains the previous password. It sets the PAM_OLDAUTHTOK item - * or stores it as a data item. The second function obtains a new - * password (verifying if necessary, that the user types it the same a - * second time.) depending on the 'ctrl' flags this new password may - * be stored in the PAM_AUTHTOK item or a private data item. - * - * Having obtained a new password. The function updates the - * /etc/passwd (and optionally the /etc/shadow) file(s). - * - * Provision is made for the creation of a blank shadow file if none - * is available, but one is required to update the shadow file -- the - * intention being for shadow passwords to be seamlessly implemented - * from the generic UNIX scheme. -- THIS BIT IS PRE-ALPHA.. and included - * in this release (.52) mostly for the purpose of discussion. - */ - -static int _unix_chauthtok(pam_handle_t *pamh, unsigned int ctrl) -{ - int retval; - unsigned int lctrl; - - /* <DO NOT free() THESE> */ - const char *user; - const char *pass_old, *pass_new; - /* </DO NOT free() THESE> */ - - D(("called")); - - /* - * First get the name of a user - */ - - retval = _unix_get_user( pamh, ctrl, "Username: ", &user ); - if ( retval != PAM_SUCCESS ) { - if ( on(UNIX_DEBUG,ctrl) ) { - _log_err(LOG_DEBUG, "password - could not identify user"); - } - return retval; - } - - if ( on(UNIX__PRELIM, ctrl) ) { - /* - * obtain and verify the current password (OLDAUTHTOK) for - * the user. - */ - - char *Announce; - - D(("prelim check")); - - if ( _unix_blankpasswd(ctrl, user) ) { - - return PAM_SUCCESS; - - } else if ( off(UNIX__IAMROOT, ctrl) ) { - - /* instruct user what is happening */ -#define greeting "Changing password for " - Announce = (char *) malloc(sizeof(greeting)+strlen(user)); - if (Announce == NULL) { - _log_err(LOG_CRIT, "password - out of memory"); - return PAM_BUF_ERR; - } - (void) strcpy(Announce, greeting); - (void) strcpy(Announce+sizeof(greeting)-1, user); -#undef greeting - - lctrl = ctrl; - set(UNIX__OLD_PASSWD, lctrl); - retval = _unix_read_password( pamh, lctrl - , Announce - , "(current) UNIX password: " - , NULL - , _UNIX_OLD_AUTHTOK - , &pass_old ); - free(Announce); - - if ( retval != PAM_SUCCESS ) { - _log_err(LOG_NOTICE - , "password - (old) token not obtained"); - return retval; - } - - /* verify that this is the password for this user */ - - retval = _unix_verify_password(pamh, user, pass_old, ctrl); - } else { - D(("process run by root so do nothing this time around")); - pass_old = NULL; - retval = PAM_SUCCESS; /* root doesn't have too */ - } - - if ( retval != PAM_SUCCESS ) { - D(("Authentication failed")); - pass_old = NULL; - return retval; - } - - retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old); - pass_old = NULL; - if ( retval != PAM_SUCCESS ) { - _log_err(LOG_CRIT, "failed to set PAM_OLDAUTHTOK"); - } - - } else if ( on( UNIX__UPDATE, ctrl ) ) { - /* tpass is used below to store the _pam_md() return; it - * should be _pam_delete()'d. */ - - char *tpass=NULL; - - /* - * obtain the proposed password - */ - - D(("do update")); - - /* - * get the old token back. NULL was ok only if root [at this - * point we assume that this has already been enforced on a - * previous call to this function]. - */ - - if ( off(UNIX_NOT_SET_PASS, ctrl) ) { - retval = pam_get_item(pamh, PAM_OLDAUTHTOK - , (const void **)&pass_old); - } else { - retval = pam_get_data(pamh, _UNIX_OLD_AUTHTOK - , (const void **)&pass_old); - if (retval == PAM_NO_MODULE_DATA) { - retval = PAM_SUCCESS; - pass_old = NULL; - } - } - - if (retval != PAM_SUCCESS) { - _log_err(LOG_NOTICE, "user not authenticated"); - return retval; - } - - D(("get new password now")); - - lctrl = ctrl; - - /* - * use_authtok is to force the use of a previously entered - * password -- needed for pluggable password strength checking - */ - - if ( on(UNIX_USE_AUTHTOK, lctrl) ) { - set(UNIX_USE_FIRST_PASS, lctrl); - } - - retval = _unix_read_password( pamh, lctrl - , NULL - , "Enter new UNIX password: " - , "Retype new UNIX password: " - , _UNIX_NEW_AUTHTOK - , &pass_new ); - - if ( retval != PAM_SUCCESS ) { - if ( on(UNIX_DEBUG,ctrl) ) { - _log_err(LOG_ALERT - , "password - new password not obtained"); - } - pass_old = NULL; /* tidy up */ - return retval; - } - - D(("returned to _unix_chauthtok")); - - /* - * At this point we know who the user is and what they - * propose as their new password. Verify that the new - * password is acceptable. - */ - - if (pass_new[0] == '\0') { /* "\0" password = NULL */ - pass_new = NULL; - } - - retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new); - - if (retval != PAM_SUCCESS) { - _log_err(LOG_NOTICE, "new password not acceptable"); - pass_new = pass_old = NULL; /* tidy up */ - return retval; - } - - /* - * By reaching here we have approved the passwords and must now - * rebuild the password database file. - * - * This includes the fact that the password is _not_ NULL. - */ - - /* - * First we encrypt the new password. - * - * XXX - this is where we might need some code for RADIUS types - * of password handling... no encryption needed.. - */ - - if ( on(UNIX_MD5_PASS, ctrl) ) { - - /* - * Code lifted from Marek Michalkiewicz's shadow suite. (CG) - * removed use of static variables (AGM) - */ - - struct timeval tv; - MD5_CTX ctx; - unsigned char result[16]; - char *cp = (char *)result; - unsigned char tmp[16]; - int i; - - GoodMD5Init(&ctx); - gettimeofday(&tv, (struct timezone *) 0); - GoodMD5Update(&ctx, (void *) &tv, sizeof tv); - i = getpid(); - GoodMD5Update(&ctx, (void *) &i, sizeof i); - i = clock(); - GoodMD5Update(&ctx, (void *) &i, sizeof i); - GoodMD5Update(&ctx, result, sizeof result); - GoodMD5Final(tmp, &ctx); - strcpy(cp, "$1$"); /* magic for the MD5 */ - cp += strlen(cp); - for (i = 0; i < 8; i++) - *cp++ = i64c(tmp[i] & 077); - *cp = '\0'; - - /* no longer need cleartext */ - pass_new = tpass = _pam_md(pass_new, (const char *)result); - - } else { - /* - * Salt manipulation is stolen from Rick Faith's passwd - * program. Sorry Rick :) -- alex - */ - - time_t tm; - char salt[3]; - - time(&tm); - salt[0] = bin_to_ascii(tm & 0x3f); - salt[1] = bin_to_ascii((tm >> 6) & 0x3f); - salt[2] = '\0'; - - if ( off(UNIX_BIGCRYPT, ctrl) && strlen(pass_new) > 8 ) { - /* to avoid using the _extensions_ of the bigcrypt() - function we truncate the newly entered password */ - char *temp = malloc(9); - - if (temp == NULL) { - _log_err(LOG_CRIT, "out of memory for password"); - pass_new = pass_old = NULL; /* tidy up */ - return PAM_BUF_ERR; - } - - /* copy first 8 bytes of password */ - strncpy(temp, pass_new, 8); - temp[8] = '\0'; - - /* no longer need cleartext */ - pass_new = tpass = _pam_md( temp, salt ); - - _pam_delete(temp); /* tidy up */ - } else { - /* no longer need cleartext */ - pass_new = tpass = _pam_md( pass_new, salt ); - } - } - - D(("password processed")); - - /* update the password database(s) -- race conditions..? */ - - retval = unix_update_db(pamh, ctrl, user, pass_old, pass_new); - pass_old = pass_new = NULL; - - } else { /* something has broken with the module */ - - _log_err(LOG_ALERT, "password received unknown request"); - retval = PAM_ABORT; - - } - - return retval; -} - -/* ****************************************************************** - * Copyright (c) Alexander O. Yuriev (alex@bach.cis.temple.edu), 1996. - * Copyright (c) Andrew Morgan <morgan@parc.power.net> 1996, 1997. - * Copyright (c) Cristian Gafton, <gafton@redhat.com> 1996, 1997. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_pwdb/pam_unix_pwupd.-c b/modules/pam_pwdb/pam_unix_pwupd.-c deleted file mode 100644 index 0f646369..00000000 --- a/modules/pam_pwdb/pam_unix_pwupd.-c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * $Id$ - * - * This file contains the routines to update the passwd databases. - */ - -/* Implementation */ - -static int unix_update_db(pam_handle_t *pamh, int ctrl, const char *user, - const char *pass_old, const char *pass_new) -{ - const struct pwdb *pw=NULL; - const struct pwdb_entry *pwe=NULL; - pwdb_flag flag; - int retval, i; - - D(("called.")); - - /* obtain default user record */ - - retval = pwdb_locate("user", PWDB_DEFAULT, user, PWDB_ID_UNKNOWN, &pw); - if (retval == PWDB_PASS_PHRASE_REQD) { - retval = pwdb_set_entry(pw, "pass_phrase" - , pass_old, 1+strlen(pass_old) - , NULL, NULL, 0); - if (retval == PWDB_SUCCESS) - retval = pwdb_locate("user", pw->source, user - , PWDB_ID_UNKNOWN, &pw); - } - pass_old = NULL; - - if ( retval != PWDB_SUCCESS ) { - _log_err(LOG_ALERT, "cannot identify user %s (uid=%d)" - , user, getuid() ); - pass_new = NULL; - if (pw) - (void) pwdb_delete(&pw); - return PAM_USER_UNKNOWN; - } - - /* check that we can update all of the default databases */ - - retval = pwdb_flags("user", pw->source, &flag); - - if ( retval != PWDB_SUCCESS || ( pwdb_on(flag,PWDB_F_NOUPDATE) ) ) { - _log_err(LOG_ERR, "cannot update default database for user %s" - , user ); - pass_new = NULL; - if (pw) - (void) pwdb_delete(&pw); - return PAM_PERM_DENIED; - } - - /* If there was one, we delete the "last_change" entry */ - retval = pwdb_get_entry(pw, "last_change", &pwe); - if (retval == PWDB_SUCCESS) { - (void) pwdb_entry_delete(&pwe); - pwdb_set_entry(pw, "last_change", NULL, -1, NULL, NULL, 0); - } - - /* - * next check for pam.conf specified databases: shadow etc... [In - * other words, pam.conf indicates which database the password is - * to be subsequently placed in: this is password migration]. - */ - - if ( on(UNIX__SET_DB, ctrl) ) { - const char *db_token; - pwdb_type pt = _PWDB_MAX_TYPES; - - if ( on(UNIX_UNIX, ctrl) ) { - db_token = "U"; /* XXX - should be macro */ - pt = PWDB_UNIX; - } else if ( on(UNIX_SHADOW, ctrl) ) { - db_token = "x"; /* XXX - should be macro */ - pt = PWDB_SHADOW; - } else if ( on(UNIX_RADIUS, ctrl) ) { - db_token = "R"; /* XXX - is this ok? */ - pt = PWDB_RADIUS; - } else { - _log_err(LOG_ALERT - , "cannot determine database to use for authtok"); - pass_new = NULL; - if (pw) - (void) pwdb_delete(&pw); - return PAM_ABORT; /* we're in trouble */ - } - - /* - * Attempt to update the indicated database (only) - */ - - { - pwdb_type tpt[2]; - tpt[0] = pt; - tpt[1] = _PWDB_MAX_TYPES; - - /* Can we set entry in database? */ - retval = pwdb_flags("user", tpt, &flag); - if (retval == PWDB_SUCCESS && !pwdb_on(flag,PWDB_F_NOUPDATE)) { - /* YES. This database is available.. */ - - /* Only update if it is not already in the default list */ - for (i=0; pw->source[i] != _PWDB_MAX_TYPES - && pw->source[i] != pt ; ++i); - if (pw->source[i] == _PWDB_MAX_TYPES) { - const struct pwdb *tpw=NULL; - - /* copy database entry */ - if ((retval = pwdb_new(&tpw, 10)) != PWDB_SUCCESS - || (retval = pwdb_merge(tpw, pw, PWDB_TRUE)) - != PWDB_SUCCESS) { - _log_err(LOG_CRIT, "failed to obtain new pwdb: %s" - , pwdb_strerror(retval)); - retval = PAM_ABORT; - } else - retval = PAM_SUCCESS; - - /* set db_token */ - if (retval == PAM_SUCCESS) { - retval = pwdb_set_entry(tpw, "defer_pass", db_token - , 1+strlen(db_token) - , NULL, NULL, 0); - if (retval != PWDB_SUCCESS) { - _log_err(LOG_ALERT, "set defer_pass -> %s" - , pwdb_strerror(retval)); - retval = PAM_PERM_DENIED; - } else - retval = PAM_SUCCESS; - } - - /* update specific database */ - if (retval == PAM_SUCCESS) { - retval = pwdb_replace("user", tpt - , user, PWDB_ID_UNKNOWN, &tpw); - if (retval != PWDB_SUCCESS) { - const char *service=NULL; - (void) pam_get_item(pamh, PAM_SERVICE - , (const void **)&service); - _log_err(LOG_ALERT - , "(%s) specified database failed: %s" - , service - , pwdb_strerror(retval)); - retval = PAM_PERM_DENIED; - } else { - retval = PAM_SUCCESS; - } - } - - /* clean up temporary pwdb */ - if (tpw) - (void) pwdb_delete(&tpw); - } - - /* we can properly adopt new defer_pass */ - if (retval == PAM_SUCCESS) { - /* failing here will mean we go back to former - password location */ - (void) pwdb_set_entry(pw, "defer_pass", db_token - , 1+strlen(db_token), NULL, NULL, 0); - } - } - } - } - - /* - * the password will now be placed in appropriate (perhaps original) db - */ - - retval = pwdb_get_entry(pw, "uid", &pwe); - if (retval != PWDB_SUCCESS) { - _log_err(LOG_ALERT, "no uid!? (%s); %s", user, pwdb_strerror(retval)); - pass_new = NULL; - if (pw) - (void) pwdb_delete(&pw); - return PAM_USER_UNKNOWN; - } - - /* insert the passwd into the 'pw' structure */ - - retval = pwdb_set_entry(pw, "passwd", pass_new, 1+strlen(pass_new) - , NULL, NULL, 0); - pass_new = NULL; - if (retval != PWDB_SUCCESS) { - _log_err(LOG_ALERT, "set2 failed; %s", pwdb_strerror(retval)); - if (pw) - (void) pwdb_delete(&pw); - return PAM_AUTHTOK_LOCK_BUSY; - } - - retval = pwdb_replace("user", pw->source, user - , *((uid_t *)pwe->value), &pw); - if (retval != PWDB_SUCCESS) { - _log_err(LOG_ALERT, "user (%s/%d) update failed; %s" - , user, *((uid_t *)pwe->value), pwdb_strerror(retval)); - if (pw) - (void) pwdb_delete(&pw); - (void) pwdb_entry_delete(&pwe); - return PAM_ABORT; - } - - if (retval != PWDB_SUCCESS) { - - _log_err(LOG_ALERT, "user (%s/%d) update failed; %s" - , user, *((uid_t *)pwe->value), pwdb_strerror(retval)); - retval = PAM_ABORT; - - } else { - /* password updated */ - - _log_err(LOG_INFO, "password for (%s/%d) changed by (%s/%d)" - , user, *((uid_t *)pwe->value), getlogin(), getuid()); - retval = PAM_SUCCESS; - } - - /* tidy up */ - - (void) pwdb_entry_delete(&pwe); - if (pw) - (void) pwdb_delete(&pw); - - return retval; -} - -/* ****************************************************************** - * Copyright (c) Andrew Morgan <morgan@parc.power.net> 1996,1997. - * Copyright (c) Cristian Gafton, <gafton@redhat.com> 1996, 1997. - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_pwdb/pam_unix_sess.-c b/modules/pam_pwdb/pam_unix_sess.-c deleted file mode 100644 index 8f862eae..00000000 --- a/modules/pam_pwdb/pam_unix_sess.-c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * $Id$ - * - * See end for Copyright information - */ - -static const char rcsid_sess[] = -"$Id$\n" -" - PAM_PWDB session management. morgan@parc.power.net"; - -/* Define internal functions */ - -static int _unix_open_session(pam_handle_t *pamh, unsigned int ctrl) -{ - int retval; - char *user_name, *service; - - D(("called.")); - - retval = pam_get_item( pamh, PAM_USER, (void *) &user_name ); - if ( user_name == NULL || retval != PAM_SUCCESS ) { - _log_err(LOG_CRIT, "open_session - error recovering username"); - return PAM_SESSION_ERR; - } - - retval = pam_get_item( pamh, PAM_SERVICE, (void*) &service ); - if ( service == NULL || retval != PAM_SUCCESS ) { - _log_err(LOG_CRIT, "open_session - error recovering service"); - return PAM_SESSION_ERR; - } - - _log_err(LOG_INFO, "(%s) session opened for user %s by %s(uid=%d)" - , service, user_name - , getlogin() == NULL ? "":getlogin(), getuid() ); - - return PAM_SUCCESS; -} - -static int _unix_close_session(pam_handle_t *pamh, unsigned int ctrl) -{ - int retval; - char *user_name, *service; - - D(("called.")); - - retval = pam_get_item( pamh, PAM_USER, (void*) &user_name ); - if ( user_name == NULL || retval != PAM_SUCCESS ) { - _log_err(LOG_CRIT, "close_session - error recovering username"); - return PAM_SESSION_ERR; - } - - retval = pam_get_item( pamh, PAM_SERVICE, (void*) &service ); - if ( service == NULL || retval != PAM_SUCCESS ) { - _log_err(LOG_CRIT, "close_session - error recovering service"); - return PAM_SESSION_ERR; - } - - _log_err(LOG_INFO, "(%s) session closed for user %s" - , service, user_name ); - - return PAM_SUCCESS; -} - -/* - * Copyright (c) Alexander O. Yuriev, 1996. All rights reserved. - * Copyright (c) Andrew G. Morgan, 1996, <morgan@parc.power.net> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_pwdb/pwdb_chkpwd.c b/modules/pam_pwdb/pwdb_chkpwd.c deleted file mode 100644 index e4fe38f8..00000000 --- a/modules/pam_pwdb/pwdb_chkpwd.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * $Id$ - * - * This program is designed to run setuid(root) or with sufficient - * privilege to read all of the unix password databases. It is designed - * to provide a mechanism for the current user (defined by this - * process' real uid) to verify their own password. - * - * The password is read from the standard input. The exit status of - * this program indicates whether the user is authenticated or not. - * - * Copyright information is located at the end of the file. - * - */ - -#include <security/_pam_aconf.h> - -#ifdef MEMORY_DEBUG -# undef exit -# undef strdup -# undef free -#endif /* MEMORY_DEBUG */ - -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> - -#include <security/_pam_macros.h> - -#define MAXPASS 200 /* the maximum length of a password */ - -#define UNIX_PASSED (PWDB_SUCCESS) -#define UNIX_FAILED (PWDB_SUCCESS+1) - -#include <pwdb/pwdb_public.h> - -/* syslogging function for errors and other information */ - -static void _log_err(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("pwdb_chkpwd", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -#define PWDB_NO_MD_COMPAT -#include "pam_unix_md.-c" - -static int _unix_verify_passwd(const char *salt, const char *p) -{ - char *pp=NULL; - int retval; - - if (p == NULL) { - if (*salt == '\0') { - retval = UNIX_PASSED; - } else { - retval = UNIX_FAILED; - } - } else { - pp = _pam_md(p, salt); - p = NULL; /* no longer needed here */ - - if ( strcmp( pp, salt ) == 0 ) { - retval = UNIX_PASSED; - } else { - retval = UNIX_FAILED; - } - } - - /* clean up */ - { - char *tp = pp; - if (pp != NULL) { - while(tp && *tp) - *tp++ = '\0'; - free(pp); - pp = tp = NULL; - } - } - - return retval; -} - -int main(int argc, char **argv) -{ - const struct pwdb *pw=NULL; - const struct pwdb_entry *pwe=NULL; - char pass[MAXPASS+1]; - int npass, force_failure=0; - int retval=UNIX_FAILED; - - /* - * we establish that this program is running with non-tty stdin. - * this is to discourage casual use. It does *NOT* prevent an - * intruder from repeatadly running this program to determine the - * password of the current user (brute force attack, but one for - * which the attacker must already have gained access to the user's - * account). - */ - - if ( isatty(STDIN_FILENO) ) { - _log_err(LOG_NOTICE - , "inappropriate use of PWDB helper binary [UID=%d]" - , getuid() ); - fprintf(stderr, - "This program is not designed for running in this way\n" - "-- the system administrator has been informed\n"); - exit(UNIX_FAILED); - } - - /* - * determine the current user's name: - */ - - retval = pwdb_start(); - if (retval != PWDB_SUCCESS) { - _log_err(LOG_ALERT, "failed to open pwdb"); - retval = UNIX_FAILED; - } - if (retval != UNIX_FAILED) { - retval = pwdb_locate("user", PWDB_DEFAULT, PWDB_NAME_UNKNOWN, - getuid(), &pw); - } - if (retval != PWDB_SUCCESS) { - _log_err(LOG_ALERT, "could not identify user"); - while (pwdb_end() != PWDB_SUCCESS); - exit(UNIX_FAILED); - } - if (argc == 2) { - if (pwdb_get_entry(pw, "user", &pwe) == PWDB_SUCCESS) { - if (pwe == NULL) { - force_failure = 1; - } else { - if (strcmp((const char *) pwe->value, argv[1])) { - force_failure = 1; - } - pwdb_entry_delete(&pwe); - } - } - } - - /* read the password from stdin (a pipe from the pam_pwdb module) */ - - npass = read(STDIN_FILENO, pass, MAXPASS); - - if (npass < 0) { /* is it a valid password? */ - _log_err(LOG_DEBUG, "no password supplied"); - retval = UNIX_FAILED; - } else if (npass >= MAXPASS-1) { - _log_err(LOG_DEBUG, "password too long"); - retval = UNIX_FAILED; - } else if (pwdb_get_entry(pw, "passwd", &pwe) != PWDB_SUCCESS) { - _log_err(LOG_WARNING, "password not found"); - retval = UNIX_FAILED; - } else { - if (npass <= 0) { - /* the password is NULL */ - - retval = _unix_verify_passwd((const char *)(pwe->value), NULL); - } else { - /* does pass agree with the official one? */ - - pass[npass] = '\0'; /* NUL terminate */ - retval = _unix_verify_passwd((const char *)(pwe->value), pass); - } - } - - memset(pass, '\0', MAXPASS); /* clear memory of the password */ - while (pwdb_end() != PWDB_SUCCESS); - - if ((retval != UNIX_FAILED) && force_failure) { - retval = UNIX_FAILED; - } - - /* return pass or fail */ - - exit(retval); -} - -/* - * Copyright (c) Andrew G. Morgan, 1997. All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_pwdb/support.-c b/modules/pam_pwdb/support.-c deleted file mode 100644 index 45867ce8..00000000 --- a/modules/pam_pwdb/support.-c +++ /dev/null @@ -1,963 +0,0 @@ -/* - * $Id$ - * - * Copyright information at end of file. - */ - -/* - * here is the string to inform the user that the new passwords they - * typed were not the same. - */ - -#define MISTYPED_PASS "Sorry, passwords do not match" - -/* type definition for the control options */ - -typedef struct { - const char *token; - unsigned int mask; /* shall assume 32 bits of flags */ - unsigned int flag; -} UNIX_Ctrls; - -/* - * macro to determine if a given flag is on - */ - -#define on(x,ctrl) (unix_args[x].flag & ctrl) - -/* - * macro to determine that a given flag is NOT on - */ - -#define off(x,ctrl) (!on(x,ctrl)) - -/* - * macro to turn on/off a ctrl flag manually - */ - -#define set(x,ctrl) (ctrl = ((ctrl)&unix_args[x].mask)|unix_args[x].flag) -#define unset(x,ctrl) (ctrl &= ~(unix_args[x].flag)) - -/* the generic mask */ - -#define _ALL_ON_ (~0U) - -/* end of macro definitions definitions for the control flags */ - -/* ****************************************************************** * - * ctrl flags proper.. - */ - -/* - * here are the various options recognized by the unix module. They - * are enumerated here and then defined below. Internal arguments are - * given NULL tokens. - */ - -#define UNIX__OLD_PASSWD 0 /* internal */ -#define UNIX__VERIFY_PASSWD 1 /* internal */ -#define UNIX__IAMROOT 2 /* internal */ - -#define UNIX_AUDIT 3 /* print more things than debug.. - some information may be sensitive */ -#define UNIX_USE_FIRST_PASS 4 -#define UNIX_TRY_FIRST_PASS 5 -#define UNIX_NOT_SET_PASS 6 /* don't set the AUTHTOK items */ - -#define UNIX__PRELIM 7 /* internal */ -#define UNIX__UPDATE 8 /* internal */ -#define UNIX__NONULL 9 /* internal */ -#define UNIX__QUIET 10 /* internal */ -#define UNIX_USE_AUTHTOK 11 /* insist on reading PAM_AUTHTOK */ -#define UNIX_SHADOW 12 /* signal shadow on */ -#define UNIX_MD5_PASS 13 /* force the use of MD5 passwords */ -#define UNIX__NULLOK 14 /* Null token ok */ -#define UNIX_RADIUS 15 /* wish to use RADIUS for password */ -#define UNIX__SET_DB 16 /* internal - signals redirect to db */ -#define UNIX_DEBUG 17 /* send more info to syslog(3) */ -#define UNIX_NODELAY 18 /* admin does not want a fail-delay */ -#define UNIX_UNIX 19 /* wish to use /etc/passwd for pwd */ -#define UNIX_BIGCRYPT 20 /* use DEC-C2 crypt()^x function */ -#define UNIX_LIKE_AUTH 21 /* need to auth for setcred to work */ -#define UNIX_NOREAP 22 /* don't reap child process */ -/* -------------- */ -#define UNIX_CTRLS_ 23 /* number of ctrl arguments defined */ - - -static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = { -/* symbol token name ctrl mask ctrl * - * ------------------ ------------------ -------------- ---------- */ - -/* UNIX__OLD_PASSWD */ { NULL, _ALL_ON_, 01 }, -/* UNIX__VERIFY_PASSWD */ { NULL, _ALL_ON_, 02 }, -/* UNIX__IAMROOT */ { NULL, _ALL_ON_, 04 }, -/* UNIX_AUDIT */ { "audit", _ALL_ON_, 010 }, -/* UNIX_USE_FIRST_PASS */ { "use_first_pass", _ALL_ON_^(060), 020 }, -/* UNIX_TRY_FIRST_PASS */ { "try_first_pass", _ALL_ON_^(060), 040 }, -/* UNIX_NOT_SET_PASS */ { "not_set_pass", _ALL_ON_, 0100 }, -/* UNIX__PRELIM */ { NULL, _ALL_ON_^(0600), 0200 }, -/* UNIX__UPDATE */ { NULL, _ALL_ON_^(0600), 0400 }, -/* UNIX__NONULL */ { NULL, _ALL_ON_, 01000 }, -/* UNIX__QUIET */ { NULL, _ALL_ON_, 02000 }, -/* UNIX_USE_AUTHTOK */ { "use_authtok", _ALL_ON_, 04000 }, -/* UNIX_SHADOW */ { "shadow", _ALL_ON_^(0140000), 010000 }, -/* UNIX_MD5_PASS */ { "md5", _ALL_ON_^(02000000), 020000 }, -/* UNIX__NULLOK */ { "nullok", _ALL_ON_^(01000), 0 }, -/* UNIX_RADIUS */ { "radius", _ALL_ON_^(0110000), 040000 }, -/* UNIX__SET_DB */ { NULL, _ALL_ON_, 0100000 }, -/* UNIX_DEBUG */ { "debug", _ALL_ON_, 0200000 }, -/* UNIX_NODELAY */ { "nodelay", _ALL_ON_, 0400000 }, -/* UNIX_UNIX */ { "unix", _ALL_ON_^(050000), 01000000 }, -/* UNIX_BIGCRYPT */ { "bigcrypt", _ALL_ON_^(020000), 02000000 }, -/* UNIX_LIKE_AUTH */ { "likeauth", _ALL_ON_, 04000000 }, -/* UNIX_NOREAP */ {"noreap", _ALL_ON_, 010000000 }, -}; - -#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag) - -/* syslogging function for errors and other information */ - -static void _log_err(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM_pwdb", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -/* this is a front-end for module-application conversations */ - -static int converse(pam_handle_t *pamh, int ctrl, int nargs - , struct pam_message **message - , struct pam_response **response) -{ - int retval; - struct pam_conv *conv; - - D(("begin to converse")); - - retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ; - if ( retval == PAM_SUCCESS ) { - - retval = conv->conv(nargs, ( const struct pam_message ** ) message - , response, conv->appdata_ptr); - - D(("returned from application's conversation function")); - - if (retval != PAM_SUCCESS && on(UNIX_DEBUG,ctrl) ) { - _log_err(LOG_DEBUG, "conversation failure [%s]" - , pam_strerror(pamh, retval)); - } - - } else if (retval != PAM_CONV_AGAIN) { - _log_err(LOG_ERR, "couldn't obtain coversation function [%s]" - , pam_strerror(pamh, retval)); - } - - D(("ready to return from module conversation")); - - return retval; /* propagate error status */ -} - -static int make_remark(pam_handle_t *pamh, unsigned int ctrl - , int type, const char *text) -{ - int retval=PAM_SUCCESS; - - if ( off(UNIX__QUIET, ctrl) ) { - struct pam_message *pmsg[1], msg[1]; - struct pam_response *resp; - - pmsg[0] = &msg[0]; - msg[0].msg = text; - msg[0].msg_style = type; - - resp = NULL; - retval = converse(pamh, ctrl, 1, pmsg, &resp); - - if (resp) { - _pam_drop_reply(resp, 1); - } - } - return retval; -} - -/* - * set the control flags for the UNIX module. - */ - -static int set_ctrl(int flags, int argc, const char **argv) -{ - unsigned int ctrl; - - D(("called.")); - - ctrl = UNIX_DEFAULTS; /* the default selection of options */ - - /* set some flags manually */ - - if ( getuid() == 0 && !(flags & PAM_CHANGE_EXPIRED_AUTHTOK) ) { - set(UNIX__IAMROOT, ctrl); - } - if ( flags & PAM_UPDATE_AUTHTOK ) { - set(UNIX__UPDATE, ctrl); - } - if ( flags & PAM_PRELIM_CHECK ) { - set(UNIX__PRELIM, ctrl); - } - if ( flags & PAM_DISALLOW_NULL_AUTHTOK ) { - set(UNIX__NONULL, ctrl); - } - if ( flags & PAM_SILENT ) { - set(UNIX__QUIET, ctrl); - } - - /* now parse the arguments to this module */ - - while (argc-- > 0) { - int j; - - D(("pam_pwdb arg: %s",*argv)); - - for (j=0; j<UNIX_CTRLS_; ++j) { - if (unix_args[j].token - && ! strcmp(*argv, unix_args[j].token) ) { - break; - } - } - - if ( j >= UNIX_CTRLS_ ) { - _log_err(LOG_ERR, "unrecognized option [%s]",*argv); - } else { - ctrl &= unix_args[j].mask; /* for turning things off */ - ctrl |= unix_args[j].flag; /* for turning things on */ - } - - ++argv; /* step to next argument */ - } - - /* these are used for updating passwords in specific places */ - - if (on(UNIX_SHADOW,ctrl) || on(UNIX_RADIUS,ctrl) || on(UNIX_UNIX,ctrl)) { - set(UNIX__SET_DB, ctrl); - } - - /* auditing is a more sensitive version of debug */ - - if ( on(UNIX_AUDIT,ctrl) ) { - set(UNIX_DEBUG, ctrl); - } - - /* return the set of flags */ - - D(("done.")); - return ctrl; -} - -/* use this to free strings. ESPECIALLY password strings */ - -static char *_pam_delete(register char *xx) -{ - _pam_overwrite(xx); - _pam_drop(xx); - return NULL; -} - -static void _cleanup(pam_handle_t *pamh, void *x, int error_status) -{ - x = _pam_delete( (char *) x ); -} - -/* ************************************************************** * - * Useful non-trivial functions * - * ************************************************************** */ - -#include "pam_unix_md.-c" - -/* - * the following is used to keep track of the number of times a user fails - * to authenticate themself. - */ - -#define FAIL_PREFIX "-UN*X-FAIL-" -#define UNIX_MAX_RETRIES 3 - -struct _pam_failed_auth { - char *user; /* user that's failed to be authenticated */ - char *name; /* attempt from user with name */ - int id; /* uid of name'd user */ - int count; /* number of failures so far */ -}; - -#ifndef PAM_DATA_REPLACE -#error "Need to get an updated libpam 0.52 or better" -#endif - -static void _cleanup_failures(pam_handle_t *pamh, void *fl, int err) -{ - int quiet; - const char *service=NULL; - struct _pam_failed_auth *failure; - - D(("called")); - - quiet = err & PAM_DATA_SILENT; /* should we log something? */ - err &= PAM_DATA_REPLACE; /* are we just replacing data? */ - failure = (struct _pam_failed_auth *) fl; - - if ( failure != NULL ) { - - if ( !quiet && !err ) { /* under advisement from Sun,may go away */ - - /* log the number of authentication failures */ - if ( failure->count > 1 ) { - (void) pam_get_item(pamh, PAM_SERVICE - , (const void **)&service); - _log_err(LOG_NOTICE - , "%d more authentication failure%s; %s(uid=%d) -> " - "%s for %s service" - , failure->count-1, failure->count==2 ? "":"s" - , failure->name - , failure->id - , failure->user - , service == NULL ? "**unknown**":service - ); - if ( failure->count > UNIX_MAX_RETRIES ) { - _log_err(LOG_ALERT - , "service(%s) ignoring max retries; %d > %d" - , service == NULL ? "**unknown**":service - , failure->count - , UNIX_MAX_RETRIES ); - } - } - } - failure->user = _pam_delete(failure->user); /* tidy up */ - failure->name = _pam_delete(failure->name); /* tidy up */ - free(failure); - } -} - -/* - * verify the password of a user - */ - -#include <signal.h> -#include <sys/types.h> -#include <sys/wait.h> - -static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd, - unsigned int ctrl, const char *user) -{ - int retval, child, fds[2]; - void (*sighandler)(int) = NULL; - - D(("called.")); - /* create a pipe for the password */ - if (pipe(fds) != 0) { - D(("could not make pipe")); - return PAM_AUTH_ERR; - } - - if (off(UNIX_NOREAP, ctrl)) { - /* - * This code arranges that the demise of the child does not cause - * the application to receive a signal it is not expecting - which - * may kill the application or worse. - * - * The "noreap" module argument is provided so that the admin can - * override this behavior. - */ - sighandler = signal(SIGCHLD, SIG_DFL); - } - - /* fork */ - child = fork(); - if (child == 0) { - static char *args[] = { NULL, NULL, NULL }; - static char *envp[] = { NULL }; - - /* XXX - should really tidy up PAM here too */ - while (pwdb_end() == PWDB_SUCCESS); - - /* reopen stdin as pipe */ - close(fds[1]); - dup2(fds[0], STDIN_FILENO); - - /* exec binary helper */ - args[0] = x_strdup(CHKPWD_HELPER); - args[1] = x_strdup(user); - - execve(CHKPWD_HELPER, args, envp); - - /* should not get here: exit with error */ - D(("helper binary is not available")); - exit(PWDB_SUCCESS+1); - } else if (child > 0) { - /* wait for child */ - if (passwd != NULL) { /* send the password to the child */ - write(fds[1], passwd, strlen(passwd)+1); - passwd = NULL; - } else { - write(fds[1], "", 1); /* blank password */ - } - close(fds[0]); /* we close this after the write because we want - to avoid a possible SIGPIPE. */ - close(fds[1]); - (void) waitpid(child, &retval, 0); /* wait for helper to complete */ - retval = (retval == PWDB_SUCCESS) ? PAM_SUCCESS:PAM_AUTH_ERR; - } else { - D(("fork failed")); - retval = PAM_AUTH_ERR; - } - - if (sighandler != NULL) { - (void) signal(SIGCHLD, sighandler); /* restore old signal handler */ - } - - D(("returning %d", retval)); - return retval; -} - -static int _unix_verify_password(pam_handle_t *pamh, const char *name, - const char *p, unsigned int ctrl) -{ - const struct pwdb *pw=NULL; - const struct pwdb_entry *pwe=NULL; - - const char *salt; - char *pp; - char *data_name; - int retval; - int verify_result; - - D(("called")); - -#ifdef HAVE_PAM_FAIL_DELAY - if ( off(UNIX_NODELAY, ctrl) ) { - D(("setting delay")); - (void) pam_fail_delay(pamh, 1000000); /* 1 sec delay for on failure */ - } -#endif - - /* locate the entry for this user */ - - D(("locating user's record")); - retval = pwdb_locate("user", PWDB_DEFAULT, name, PWDB_ID_UNKNOWN, &pw); - if (retval == PWDB_PASS_PHRASE_REQD) { - /* - * give the password to the pwdb library. It may be needed to - * access the database - */ - - retval = pwdb_set_entry( pw, "pass_phrase", p, 1+strlen(p) - , NULL, NULL, 0); - if (retval != PWDB_SUCCESS) { - _log_err(LOG_ALERT, "find pass; %s", pwdb_strerror(retval)); - (void) pwdb_delete(&pw); - p = NULL; - return PAM_CRED_INSUFFICIENT; - } - - retval = pwdb_locate("user", pw->source, name, PWDB_ID_UNKNOWN, &pw); - } - - if (retval != PWDB_SUCCESS) { - D(("user's record unavailable")); - if ( on(UNIX_AUDIT, ctrl) ) { - /* this might be a typo and the user has given a password - instead of a username. Careful with this. */ - _log_err(LOG_ALERT, "check pass; user (%s) unknown", name); - } else { - _log_err(LOG_ALERT, "check pass; user unknown"); - } - (void) pwdb_delete(&pw); - p = NULL; - return PAM_USER_UNKNOWN; - } - - /* - * courtesy of PWDB the password for the user is stored in - * encrypted form in the "passwd" entry of pw. - */ - - retval = pwdb_get_entry(pw, "passwd", &pwe); - if (retval != PWDB_SUCCESS) { - if (geteuid()) { - /* we are not root perhaps this is the reason? Run helper */ - D(("running helper binary")); - retval = pwdb_run_helper_binary(pamh, p, ctrl, name); - } else { - retval = PAM_AUTHINFO_UNAVAIL; - _log_err(LOG_ALERT, "get passwd; %s", pwdb_strerror(retval)); - } - (void) pwdb_delete(&pw); - p = NULL; - return retval; - } - salt = (const char *) pwe->value; - - /* - * XXX: Cristian, the above is not the case for RADIUS(?) Some - * lines should be added for RADIUS to verify the password in - * clear text... - */ - - data_name = (char *) malloc(sizeof(FAIL_PREFIX)+strlen(name)); - if ( data_name == NULL ) { - _log_err(LOG_CRIT, "no memory for data-name"); - } - strcpy(data_name, FAIL_PREFIX); - strcpy(data_name + sizeof(FAIL_PREFIX)-1, name); - - if ( !( (salt && *salt) || (p && *p) ) ) { - - D(("two null passwords to compare")); - - /* the stored password is NULL */ - pp = NULL; - if ( off(UNIX__NONULL, ctrl ) ) { /* this means we've succeeded */ - verify_result = PAM_SUCCESS; - } else { - verify_result = PAM_AUTH_ERR; - } - - } else if ( !( salt && p ) ) { - - D(("one of the two to compare are NULL")); - - pp = NULL; - verify_result = PAM_AUTH_ERR; - - } else { - - /* there is no way that p can be NULL (one can be "") */ - pp = _pam_md(p, salt); - - /* the moment of truth -- do we agree with the password? */ - D(("comparing state of pp[%s] and salt[%s]", pp, salt)); - - if ( strcmp( pp, salt ) == 0 ) { - verify_result = PAM_SUCCESS; - } else { - _pam_delete(pp); - pp = _pam_md_compat(p, salt); - if ( strcmp( pp, salt ) == 0 ) { - verify_result = PAM_SUCCESS; - } else { - verify_result = PAM_AUTH_ERR; - } - } - - p = NULL; /* no longer needed here */ - - } - - if ( verify_result == PAM_SUCCESS ) { - - retval = PAM_SUCCESS; - if (data_name) { /* reset failures */ - pam_set_data(pamh, data_name, NULL, _cleanup_failures); - } - - } else { - - retval = PAM_AUTH_ERR; - if (data_name != NULL) { - struct _pam_failed_auth *new=NULL; - const struct _pam_failed_auth *old=NULL; - - /* get a failure recorder */ - - new = (struct _pam_failed_auth *) - malloc(sizeof(struct _pam_failed_auth)); - - if (new != NULL) { - - new->user = x_strdup(name); - new->id = getuid(); - new->name = x_strdup(getlogin() ? getlogin():"" ); - - /* any previous failures for this user ? */ - pam_get_data(pamh, data_name, (const void **)&old ); - - if (old != NULL) { - new->count = old->count +1; - if (new->count >= UNIX_MAX_RETRIES) { - retval = PAM_MAXTRIES; - } - } else { - const char *service=NULL; - (void) pam_get_item(pamh, PAM_SERVICE - , (const void **)&service); - _log_err(LOG_NOTICE - , "authentication failure; %s(uid=%d) -> " - "%s for %s service" - , new->name - , new->id - , new->user - , service == NULL ? "**unknown**":service - ); - new->count = 1; - } - - pam_set_data(pamh, data_name, new, _cleanup_failures); - - } else { - _log_err(LOG_CRIT, "no memory for failure recorder"); - } - } - - } - - (void) pwdb_entry_delete(&pwe); - (void) pwdb_delete(&pw); - salt = NULL; - _pam_delete(data_name); - _pam_delete(pp); - - D(("done [%d].", retval)); - - return retval; -} - -/* - * this function obtains the name of the current user and ensures - * that the PAM_USER item is set to this value - */ - -static int _unix_get_user(pam_handle_t *pamh, unsigned int ctrl - , const char *prompt, const char **user) -{ - int retval; - - D(("called")); - - retval = pam_get_user(pamh, user, prompt); - if (retval != PAM_SUCCESS) { - D(("trouble reading username")); - return retval; - } - - /* - * Various libraries at various times have had bugs related to - * '+' or '-' as the first character of a user name. Don't take - * any chances here. Require that the username starts with an - * alphanumeric character. - */ - - if (*user == NULL || !isalnum(**user)) { - D(("bad username")); - if (on(UNIX_DEBUG,ctrl)) { - _log_err(LOG_ERR, "bad username [%s]", *user); - } - return PAM_USER_UNKNOWN; - } - - if (retval == PAM_SUCCESS && on(UNIX_DEBUG,ctrl)) { - _log_err(LOG_DEBUG, "username [%s] obtained", *user); - } - - return retval; -} - -/* - * _unix_blankpasswd() is a quick check for a blank password - * - * returns TRUE if user does not have a password - * - to avoid prompting for one in such cases (CG) - */ - -static int _unix_blankpasswd(unsigned int ctrl, const char *name) -{ - const struct pwdb *pw=NULL; - const struct pwdb_entry *pwe=NULL; - int retval; - - D(("called")); - - /* - * This function does not have to be too smart if something goes - * wrong, return FALSE and let this case to be treated somewhere - * else (CG) - */ - - if ( on(UNIX__NONULL, ctrl) ) - return 0; /* will fail but don't let on yet */ - - /* find the user's database entry */ - - retval = pwdb_locate("user", PWDB_DEFAULT, name, PWDB_ID_UNKNOWN, &pw); - if (retval != PWDB_SUCCESS || pw == NULL ) { - - retval = 0; - - } else { - - /* Does this user have a password? */ - - retval = pwdb_get_entry(pw, "passwd", &pwe); - if ( retval != PWDB_SUCCESS || pwe == NULL ) - retval = 0; - else if ( pwe->value == NULL || ((char *)pwe->value)[0] == '\0' ) - retval = 1; - else - retval = 0; - - } - - /* tidy up */ - - if ( pw ) { - (void) pwdb_delete(&pw); - if ( pwe ) - (void) pwdb_entry_delete(&pwe); - } - - return retval; -} - -/* - * obtain a password from the user - */ - -static int _unix_read_password( pam_handle_t *pamh - , unsigned int ctrl - , const char *comment - , const char *prompt1 - , const char *prompt2 - , const char *data_name - , const char **pass ) -{ - int authtok_flag; - int retval; - const char *item; - char *token; - - D(("called")); - - /* - * make sure nothing inappropriate gets returned - */ - - *pass = token = NULL; - - /* - * which authentication token are we getting? - */ - - authtok_flag = on(UNIX__OLD_PASSWD,ctrl) ? PAM_OLDAUTHTOK:PAM_AUTHTOK ; - - /* - * should we obtain the password from a PAM item ? - */ - - if ( on(UNIX_TRY_FIRST_PASS,ctrl) || on(UNIX_USE_FIRST_PASS,ctrl) ) { - retval = pam_get_item(pamh, authtok_flag, (const void **) &item); - if (retval != PAM_SUCCESS ) { - /* very strange. */ - _log_err(LOG_ALERT - , "pam_get_item returned error to unix-read-password" - ); - return retval; - } else if (item != NULL) { /* we have a password! */ - *pass = item; - item = NULL; - return PAM_SUCCESS; - } else if (on(UNIX_USE_FIRST_PASS,ctrl)) { - return PAM_AUTHTOK_RECOVER_ERR; /* didn't work */ - } else if (on(UNIX_USE_AUTHTOK, ctrl) - && off(UNIX__OLD_PASSWD, ctrl)) { - return PAM_AUTHTOK_RECOVER_ERR; - } - } - - /* - * getting here implies we will have to get the password from the - * user directly. - */ - - { - struct pam_message msg[3],*pmsg[3]; - struct pam_response *resp; - int i, replies; - - /* prepare to converse */ - - if ( comment != NULL && off(UNIX__QUIET, ctrl) ) { - pmsg[0] = &msg[0]; - msg[0].msg_style = PAM_TEXT_INFO; - msg[0].msg = comment; - i = 1; - } else { - i = 0; - } - - pmsg[i] = &msg[i]; - msg[i].msg_style = PAM_PROMPT_ECHO_OFF; - msg[i++].msg = prompt1; - replies = 1; - - if ( prompt2 != NULL ) { - pmsg[i] = &msg[i]; - msg[i].msg_style = PAM_PROMPT_ECHO_OFF; - msg[i++].msg = prompt2; - ++replies; - } - - /* so call the conversation expecting i responses */ - resp = NULL; - retval = converse(pamh, ctrl, i, pmsg, &resp); - - if (resp != NULL) { - - /* interpret the response */ - - if (retval == PAM_SUCCESS) { /* a good conversation */ - - token = x_strdup(resp[i-replies].resp); - if (token != NULL) { - if (replies == 2) { - - /* verify that password entered correctly */ - if (!resp[i-1].resp - || strcmp(token,resp[i-1].resp)) { - token = _pam_delete(token); /* mistyped */ - retval = PAM_AUTHTOK_RECOVER_ERR; - make_remark(pamh, ctrl - , PAM_ERROR_MSG, MISTYPED_PASS); - } - } - - } else { - _log_err(LOG_NOTICE - , "could not recover authentication token"); - } - - } - - /* - * tidy up the conversation (resp_retcode) is ignored - * -- what is it for anyway? AGM - */ - - _pam_drop_reply(resp, i); - - } else { - retval = (retval == PAM_SUCCESS) - ? PAM_AUTHTOK_RECOVER_ERR:retval ; - } - } - - if (retval != PAM_SUCCESS) { - if ( on(UNIX_DEBUG,ctrl) ) - _log_err(LOG_DEBUG,"unable to obtain a password"); - return retval; - } - - /* 'token' is the entered password */ - - if ( off(UNIX_NOT_SET_PASS, ctrl) ) { - - /* we store this password as an item */ - - retval = pam_set_item(pamh, authtok_flag, token); - token = _pam_delete(token); /* clean it up */ - if ( retval != PAM_SUCCESS - || (retval = pam_get_item(pamh, authtok_flag - , (const void **)&item)) - != PAM_SUCCESS ) { - - _log_err(LOG_CRIT, "error manipulating password"); - return retval; - - } - - } else { - /* - * then store it as data specific to this module. pam_end() - * will arrange to clean it up. - */ - - retval = pam_set_data(pamh, data_name, (void *) token, _cleanup); - if (retval != PAM_SUCCESS) { - _log_err(LOG_CRIT, "error manipulating password data [%s]" - , pam_strerror(pamh, retval) ); - token = _pam_delete(token); - return retval; - } - item = token; - token = NULL; /* break link to password */ - } - - *pass = item; - item = NULL; /* break link to password */ - - return PAM_SUCCESS; -} - -static int _pam_unix_approve_pass(pam_handle_t *pamh - , unsigned int ctrl - , const char *pass_old - , const char *pass_new) -{ - D(("&new=%p, &old=%p",pass_old,pass_new)); - D(("new=[%s]",pass_new)); - D(("old=[%s]",pass_old)); - - if (pass_new == NULL || (pass_old && !strcmp(pass_old,pass_new))) { - if ( on(UNIX_DEBUG, ctrl) ) { - _log_err(LOG_DEBUG, "bad authentication token"); - } - make_remark(pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ? - "No password supplied":"Password unchanged" ); - return PAM_AUTHTOK_ERR; - } - - /* - * if one wanted to hardwire authentication token strength - * checking this would be the place - AGM - */ - - return PAM_SUCCESS; -} - -/* ****************************************************************** * - * Copyright (c) Andrew G. Morgan 1996-8. - * Copyright (c) Alex O. Yuriev, 1996. - * Copyright (c) Cristian Gafton 1996. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - diff --git a/modules/pam_radius/.cvsignore b/modules/pam_radius/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_radius/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_radius/Makefile b/modules/pam_radius/Makefile deleted file mode 100644 index aa149d3e..00000000 --- a/modules/pam_radius/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -# -# 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!). -# -# Created by Cristian Gafton <gafton@redhat.com> 1996/09/10 -# -# STATIC modules are not supported -# - -include ../../Make.Rules - -TITLE=pam_radius -CONFD=$(CONFIGED)/security -export CONFD -CONFILE=$(CONFD)/radius.conf -export CONFILE - -ifeq ($(HAVE_LIBPWDB),yes) - -# - -LIBSRC = $(TITLE).c -LIBOBJ = $(TITLE).o - -LIBOBJD = $(addprefix dynamic/,$(LIBOBJ)) -#LIBOBJS = $(addprefix static/,$(LIBOBJ)) - -dynamic/%.o : %.c - $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ - -#static/%.o : %.c -# $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ - - -ifdef DYNAMIC -LIBSHARED = $(TITLE).so -endif - -#ifdef STATIC -#LIBSTATIC = lib$(TITLE).o -#endif - -####################### don't edit below ####################### - -all: dirs $(LIBSHARED) $(LIBSTATIC) register - -dirs: -ifdef DYNAMIC - $(MKDIR) ./dynamic -endif -#ifdef STATIC -# $(MKDIR) ./static -#endif - -register: -#ifdef STATIC -# ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) ) -#endif - -ifdef DYNAMIC -$(LIBOBJD): $(LIBSRC) - -$(LIBSHARED): $(LIBOBJD) - $(LD_D) -o $@ $(LIBOBJD) -lpwdb -endif - -#ifdef STATIC -#$(LIBOBJS): $(LIBSRC) -# -#$(LIBSTATIC): $(LIBOBJS) -# $(LD) -r -o $@ $(LIBOBJS) -lpwdb -#endif - -install: all -ifdef DYNAMIC - $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR) -endif - -remove: - rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so - -clean: - rm -f $(LIBOBJD) $(LIBOBJS) core *~ - rm -f *.a *.o *.so *.bak dynamic/* static/* - rm -rf dynamic static - -.c.o: - $(CC) $(CFLAGS) -c $< - -else - -include ../dont_makefile - -endif diff --git a/modules/pam_radius/README b/modules/pam_radius/README deleted file mode 100644 index 253308fd..00000000 --- a/modules/pam_radius/README +++ /dev/null @@ -1,58 +0,0 @@ - -pam_radius module: - RADIUS session module. - -WHAT IT DOES: - This module is intended to provide the session service for users -autheticated with a RADIUS server. At the present stage, the only option -supported is the use of the RADIUS server as an accounting server. There are -few things which needs to be cleared out first in the PAM project until one -will be able to use this module and expect it to magically start pppd in -response to a RADIUS server command to use PPP for this user, or to initiate -a telnet connection to another host, or to hang and call back the user using -parameters provided in the RADIUS server response. Most of these things are -better suited for the radius login application. I hope to make available -Real Soon (tm) patches for the login apps to make it work this way. - - -ARGUMENTS RECOGNIZED: - debug verbose logging - -MODULE SERVICES PROVIDED: - session _open_session and _close_session - - When opening a session, this module sends an Accounting-Start -message to the RADIUS server, which will log/update/whatever a database for -this user. On close, an Accounting-Stop message is sent to the RADIUS -server. - -This module have no other pre-requisites for making it work. One can install -a RADIUS server just for fun and use it as a centralized accounting server and -forget about wtmp/last/sac&comp :-) - -USAGE: - For the services you need this module (login for example) put - the following line in /etc/pam.conf as the last line for that - service (usually after the pam_unix session line): - - login session required /lib/security/pam_radius.so - - Replace "login" for each service you are using this module. - - This module make extensive use of the API provided in libpwdb - 0.54preB or later. By default, it will read the radius server - configuration (hostname and secret) from /etc/raddb/server. This is - a default compiled into libpwdb, and curently there is no way to - modify this default without recompiling libpwdb. I am working on - extending the radius support from libpwdb to provide a possibility - to make this runtime-configurable. - - Also please note that libpwdb will require also the RADIUS - dictionary to be present (/etc/raddb/dictionary). - -TODO: - The work is far from complete. Deal with "real" session things. - -AUTHOR: - Cristian Gafton <gafton@redhat.com> - diff --git a/modules/pam_radius/pam_radius.c b/modules/pam_radius/pam_radius.c deleted file mode 100644 index b412edf9..00000000 --- a/modules/pam_radius/pam_radius.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * pam_radius - * Process an user session according to a RADIUS server response - * - * 1.0 - initial release - Linux ONLY - * 1.1 - revised and reorganized for libpwdb 0.54preB or higher - * - removed the conf= parameter, since we use libpwdb exclusively now - * - * See end for Copyright information - */ - -#if !(defined(linux)) -#error THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!! -#endif - -/* Module defines */ -#define BUFFER_SIZE 1024 -#define LONG_VAL_PTR(ptr) ((*(ptr)<<24)+(*((ptr)+1)<<16)+(*((ptr)+2)<<8)+(*((ptr)+3))) - -#define PAM_SM_SESSION - -#include "pam_radius.h" - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> - -static time_t session_time; - -/* we need to save these from open_session to close_session, since - * when close_session will be called we won't be root anymore and - * won't be able to access again the radius server configuration file - * -- cristiang */ - -static RADIUS_SERVER rad_server; -static char hostname[BUFFER_SIZE]; -static char secret[BUFFER_SIZE]; - -/* logging */ -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("pam_radius", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -/* argument parsing */ - -#define PAM_DEBUG_ARG 0x0001 - -static int _pam_parse(int argc, const char **argv) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else { - _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv); - } - } - - return ctrl; -} - -/* now the session stuff */ -PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int retval; - char *user_name; - int ctrl; - - ctrl = _pam_parse(argc, argv); - retval = pam_get_item( pamh, PAM_USER, (void*) &user_name ); - if ( user_name == NULL || retval != PAM_SUCCESS ) { - _pam_log(LOG_CRIT, "open_session - error recovering username"); - return PAM_SESSION_ERR; - } - - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG, "starting RADIUS user session for '%s'", - user_name); - - retval = get_server_entries(hostname, secret); - if ((retval != PWDB_RADIUS_SUCCESS) || - !strlen(hostname) || !strlen(secret)) { - _pam_log(LOG_CRIT, "Could not determine the radius server to talk to"); - return PAM_IGNORE; - } - session_time = time(NULL); - rad_server.hostname = hostname; - rad_server.secret = secret; - retval = radius_acct_start(rad_server, user_name); - if (retval != PWDB_RADIUS_SUCCESS) { - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG, "ERROR communicating with the RADIUS server"); - return PAM_IGNORE; - } - - return PAM_SUCCESS; -} - -PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int ctrl; - char *user_name; - int retval; - - ctrl = _pam_parse(argc, argv); - retval = pam_get_item( pamh, PAM_USER, (void*) &user_name ); - if ( user_name == NULL || retval != PAM_SUCCESS ) { - _pam_log(LOG_CRIT, "open_session - error recovering username"); - return PAM_SESSION_ERR; - } - - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG, "closing RADIUS user session for '%s'", - user_name); - - if (!strlen(hostname) || !strlen(secret)) { - _pam_log(LOG_CRIT, "Could not determine the radius server to talk to"); - return PAM_IGNORE; - } - retval = radius_acct_stop(rad_server, user_name, - time(NULL) - session_time); - if (retval != PWDB_RADIUS_SUCCESS) { - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG, "ERROR communicating with the RADIUS server"); - return PAM_IGNORE; - } - - return PAM_SUCCESS; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_radius_modstruct = { - "pam_radius", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL -}; -#endif - -/* - * Copyright (c) Cristian Gafton, 1996, <gafton@redhat.com> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_radius/pam_radius.h b/modules/pam_radius/pam_radius.h deleted file mode 100644 index 8cee7ff1..00000000 --- a/modules/pam_radius/pam_radius.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * $Id$ - */ - -#ifndef PAM_RADIUS_H -#define PAM_RADIUS_H - -#include <security/_pam_aconf.h> - -#include <stdio.h> - -#ifndef __USE_POSIX2 -#define __USE_POSIX2 -#endif /* __USE_POSIX2 */ - -#include <stdlib.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/resource.h> - -#include <unistd.h> -#include <string.h> -#include <ctype.h> -#include <syslog.h> -#include <stdarg.h> -#include <utmp.h> -#include <time.h> -#include <netdb.h> - -#include <netinet/in.h> -#include <rpcsvc/ypclnt.h> -#include <rpc/rpc.h> - -#include <pwdb/radius.h> -#include <pwdb/pwdb_radius.h> - -/******************************************************************/ - -#endif /* PAM_RADIUS_H */ diff --git a/modules/pam_rhosts/.cvsignore b/modules/pam_rhosts/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_rhosts/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_rhosts/Makefile b/modules/pam_rhosts/Makefile deleted file mode 100644 index 46d75d6a..00000000 --- a/modules/pam_rhosts/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_rhosts_auth - -include ../Simple.Rules diff --git a/modules/pam_rhosts/README b/modules/pam_rhosts/README deleted file mode 100644 index d2e93d1d..00000000 --- a/modules/pam_rhosts/README +++ /dev/null @@ -1,57 +0,0 @@ -arguments recognized: - -"no_hosts_equiv" -"no_rhosts" -"debug" -"nowarn" -"suppress" -"promiscuous" - -.rhosts/hosts.equiv format: - -There are positive entries, when one is matched authentication -succeeds and terminates. There are negative entries, when one is -matched authentication fails and terminates. Thus order is -significant. - -Entry hosts.equiv .rhosts -<host> All users on <host> are ok Same username from <host> is ok -<host> <user> <user> from <host> is ok ditto --<host> No users from <host> are ok ditto -<host> -<user> <user> from <host> is not ok ditto - -<host> can be ip (IPv4) numbers. - -Netgroups may be used in either host or user fields, and then applies -to all hosts, or users, in the netgroup. The syntax is - - +@<ng> - -The entries - - <host> +@<ng> - +@<ng> +@<ng> - +@<ng> <user> - -means exactly what you think it does. Negative entries are of the -form - - -@<ng> - -When the "promiscuous" option is given the special character + may be -used as a wildcard in any field. - - + Allow anyone from any host to connect. DANGEROUS. - + + Ditto. - + <user> Allow the user to connect from anywhere. DANGEROUS. - <host> + Allow any user from the host. Dangerous. - -These, perhaps more useful, forms of the + form is also disallowed -unless "promiscuous" is specified: - - + -<user> Disallow the user from any host - + -@<ng> Disallow all members of the netgroup from any host - -When "promiscuous" is not specified a '+' is handled as a negative -match. - diff --git a/modules/pam_rhosts/pam_rhosts_auth.c b/modules/pam_rhosts/pam_rhosts_auth.c deleted file mode 100644 index 979580ec..00000000 --- a/modules/pam_rhosts/pam_rhosts_auth.c +++ /dev/null @@ -1,802 +0,0 @@ -/*---------------------------------------------------------------------- - * Modified for Linux-PAM by Al Longyear <longyear@netcom.com> 96/5/5 - * Modifications, Cristian Gafton 97/2/8 - * Modifications, Peter Allgeyer 97/3 - * Modifications (netgroups and fixes), Nicolai Langfeldt 97/3/21 - * Security fix: 97/10/2 - gethostbyname called repeatedly without care - * Modification (added privategroup option) Andrew <morgan@transmeta.com> - *---------------------------------------------------------------------- - * Copyright (c) 1983, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <security/_pam_aconf.h> - -#define USER_RHOSTS_FILE "/.rhosts" /* prefixed by user's home dir */ - -#ifdef __linux__ -#include <endian.h> -#endif - -#ifdef HAVE_SYS_FSUID_H -#include <sys/fsuid.h> -#endif /* HAVE_SYS_FSUID_H */ - -#ifdef HAVE_NET_IF_H -#include <sys/if.h> -#endif - -#include <sys/types.h> -#include <sys/uio.h> -#include <string.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netdb.h> /* This is supposed(?) to contain the following */ -int innetgr(const char *, const char *, const char *,const char *); - -#include <stdio.h> -#include <errno.h> -#include <sys/time.h> -#include <arpa/inet.h> - -#ifndef MAXDNAME -#define MAXDNAME 256 -#endif - -#include <stdarg.h> -#include <ctype.h> - -#include <net/if.h> - -#include <pwd.h> -#include <grp.h> -#include <sys/file.h> -#include <sys/signal.h> -#include <sys/stat.h> -#include <stdint.h> -#include <syslog.h> -#ifndef _PATH_HEQUIV -#define _PATH_HEQUIV "/etc/hosts.equiv" -#endif /* _PATH_HEQUIV */ - -#define PAM_SM_AUTH /* only defines this management group */ - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/_pam_modutil.h> - -#ifdef _ISOC9X_SOURCE -#include <inttypes.h> -#define U32 uint32_t -#else -/* to the best of my knowledge, all modern UNIX boxes have 32 bits integers */ -#define U32 unsigned int -#endif /* _ISOC9X_SOURCE */ - -/* Use the C99 type; older platforms will need this to be typedef'ed - elsewhere */ -#define U32 uint32_t - - -/* - * Options for this module - */ - -struct _options { - int opt_no_hosts_equiv; - int opt_hosts_equiv_rootok; - int opt_no_rhosts; - int opt_debug; - int opt_nowarn; - int opt_disallow_null_authtok; - int opt_silent; - int opt_promiscuous; - int opt_suppress; - int opt_private_group; - int opt_no_uid_check; - const char *superuser; - const char *last_error; -}; - -/* logging */ -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("pam_rhosts_auth", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -static void set_option (struct _options *opts, const char *arg) -{ - if (strcmp(arg, "no_hosts_equiv") == 0) { - opts->opt_no_hosts_equiv = 1; - return; - } - - if (strcmp(arg, "hosts_equiv_rootok") == 0) { - opts->opt_hosts_equiv_rootok = 1; - return; - } - - if (strcmp(arg, "no_rhosts") == 0) { - opts->opt_no_rhosts = 1; - return; - } - - if (strcmp(arg, "debug") == 0) { - D(("debugging enabled")); - opts->opt_debug = 1; - return; - } - - if (strcmp(arg, "no_warn") == 0) { - opts->opt_nowarn = 1; - return; - } - - if (strcmp(arg, "promiscuous") == 0) { - opts->opt_promiscuous = 1; /* used to permit '+' in ...hosts file */ - return; - } - - if (strcmp(arg, "suppress") == 0) { - opts->opt_suppress = 1; /* used to suppress failure warning message */ - return; - } - - if (strcmp(arg, "privategroup") == 0) { - opts->opt_private_group = 1; /* used to permit group write on .rhosts - file if group has same name as owner */ - return; - } - - if (strcmp(arg, "no_uid_check") == 0) { - opts->opt_no_uid_check = 1; /* NIS optimization */ - return; - } - - if (strncmp(arg, "superuser=", sizeof("superuser=")-1) == 0) { - opts->superuser = arg+sizeof("superuser=")-1; - return; - } - /* - * All other options are ignored at the present time. - */ - _pam_log(LOG_WARNING, "unrecognized option '%s'", arg); -} - -static void set_parameters (struct _options *opts, int flags, - int argc, const char **argv) -{ - opts->opt_silent = flags & PAM_SILENT; - opts->opt_disallow_null_authtok = flags & PAM_DISALLOW_NULL_AUTHTOK; - - while (argc-- > 0) { - set_option (opts, *argv); - ++argv; - } -} - -/* - * Obtain the name of the remote host. Currently, this is simply by - * requesting the contents of the PAM_RHOST item. - */ - -static int pam_get_rhost(pam_handle_t *pamh, const char **rhost - , const char *prompt) -{ - int retval; - const char *current; - - retval = pam_get_item (pamh, PAM_RHOST, (const void **)¤t); - if (retval != PAM_SUCCESS) - return retval; - - if (current == NULL) { - return PAM_AUTH_ERR; - } - *rhost = current; - - return retval; /* pass on any error from conversation */ -} - -/* - * Obtain the name of the remote user. Currently, this is simply by - * requesting the contents of the PAM_RUSER item. - */ - -static int pam_get_ruser(pam_handle_t *pamh, const char **ruser, - const char *prompt) -{ - int retval; - const char *current; - - retval = pam_get_item (pamh, PAM_RUSER, (const void **)¤t); - if (retval != PAM_SUCCESS) { - return retval; - } - - if (current == NULL) { - return PAM_AUTH_ERR; - } - *ruser = current; - - return retval; /* pass on any error from conversation */ -} - -/* - * Returns 1 if positive match, 0 if no match, -1 if negative match. - */ - -static int -__icheckhost (pam_handle_t *pamh, struct _options *opts, U32 raddr - , register char *lhost, const char *rhost) -{ - struct hostent *hp; - U32 laddr; - int negate=1; /* Multiply return with this to get -1 instead of 1 */ - char **pp, *user; - - /* Check nis netgroup. We assume that pam has done all needed - paranoia checking before we are handed the rhost */ - if (strncmp("+@",lhost,2) == 0) - return(innetgr(&lhost[2],rhost,NULL,NULL)); - - if (strncmp("-@",lhost,2) == 0) - return(-innetgr(&lhost[2],rhost,NULL,NULL)); - - /* -host */ - if (strncmp("-",lhost,1) == 0) { - negate=-1; - lhost++; - } else if (strcmp("+",lhost) == 0) { - (void) pam_get_item(pamh, PAM_USER, (const void **)&user); - D(("user %s has a `+' host entry", user)); - if (opts->opt_promiscuous) - return (1); /* asking for trouble, but ok.. */ - /* If not promiscuous: handle as negative */ - return (-1); - } else if (strncmp("+",lhost,1) == 0) { - /* '+hostname' is supposed to be equivalent to 'hostname' */ - lhost++; - } - - - /* Try for raw ip address first. */ - if (isdigit(*lhost) && (long)(laddr = inet_addr(lhost)) != -1) - return (negate*(! (raddr ^ laddr))); - - /* Better be a hostname. */ - hp = gethostbyname(lhost); - if (hp == NULL) - return (0); - - /* Spin through ip addresses. */ - for (pp = hp->h_addr_list; *pp; ++pp) - if (!memcmp (&raddr, *pp, sizeof (U32))) - return (negate); - - /* No match. */ - return (0); -} - -/* Returns 1 on positive match, 0 on no match, -1 on negative match */ - -static int __icheckuser(pam_handle_t *pamh, struct _options *opts - , const char *luser, const char *ruser - , const char *rhost) -{ - /* - luser is user entry from .rhosts/hosts.equiv file - ruser is user id on remote host - rhost is the remote host name - */ - char *user; - - /* [-+]@netgroup */ - if (strncmp("+@",luser,2) == 0) - return (innetgr(&luser[2],NULL,ruser,NULL)); - - if (strncmp("-@",luser,2) == 0) - return (-innetgr(&luser[2],NULL,ruser,NULL)); - - /* -user */ - if (strncmp("-",luser,1) == 0) - return(-(strcmp(&luser[1],ruser) == 0)); - - /* + */ - if (strcmp("+",luser) == 0) { - (void) pam_get_item(pamh, PAM_USER, (const void **)&user); - _pam_log(LOG_WARNING, "user %s has a `+' user entry", user); - if (opts->opt_promiscuous) - return(1); - /* If not promiscuous we handle it as a negative match */ - return(-1); - } - - /* simple string match */ - return (strcmp(ruser, luser) == 0); -} - -/* - * Returns 1 for blank lines (or only comment lines) and 0 otherwise - */ - -static int __isempty(char *p) -{ - while (*p && isspace(*p)) { - ++p; - } - - return (*p == '\0' || *p == '#') ? 1:0 ; -} - -/* - * Returns 0 if positive match, 1 if _not_ ok. - */ - -static int -__ivaliduser (pam_handle_t *pamh, struct _options *opts, - FILE *hostf, U32 raddr, - const char *luser, const char *ruser, const char *rhost) -{ - register const char *user; - register char *p; - int hcheck, ucheck; - char buf[MAXHOSTNAMELEN + 128]; /* host + login */ - - buf[sizeof (buf)-1] = '\0'; /* terminate line */ - - while (fgets(buf, sizeof(buf), hostf) != NULL) { /* hostf file line */ - p = buf; /* from beginning of file.. */ - - /* Skip empty or comment lines */ - if (__isempty(p)) { - continue; - } - - /* Skip lines that are too long. */ - if (strchr(p, '\n') == NULL) { - int ch = getc(hostf); - - while (ch != '\n' && ch != EOF) - ch = getc(hostf); - continue; - } - - /* - * If there is a hostname at the start of the line. Set it to - * lower case. A leading ' ' or '\t' indicates no hostname - */ - - for (;*p && !isspace(*p); ++p) { - *p = tolower(*p); - } - - /* - * next we want to find the permitted name for the remote user - */ - - if (*p == ' ' || *p == '\t') { - - /* <nul> terminate hostname and skip spaces */ - for (*p++='\0'; *p && isspace(*p); ++p); - - user = p; /* this is the user's name */ - while (*p && !isspace(*p)) - ++p; /* find end of user's name */ - } else - user = p; - - *p = '\0'; /* <nul> terminate username (+host?) */ - - /* buf -> host(?) ; user -> username(?) */ - - /* First check host part */ - hcheck=__icheckhost(pamh, opts, raddr, buf, rhost); - - if (hcheck<0) - return(1); - - if (hcheck) { - /* Then check user part */ - if (! (*user)) - user = luser; - - ucheck=__icheckuser(pamh, opts, user, ruser, rhost); - - /* Positive 'host user' match? */ - if (ucheck>0) - return(0); - - /* Negative 'host -user' match? */ - if (ucheck<0) - return(1); - - /* Neither, go on looking for match */ - } - } - - return (1); -} - -/* - * New .rhosts strategy: We are passed an ip address. We spin through - * hosts.equiv and .rhosts looking for a match. When the .rhosts only - * has ip addresses, we don't have to trust a nameserver. When it - * contains hostnames, we spin through the list of addresses the nameserver - * gives us and look for a match. - * - * Returns 0 if ok, -1 if not ok. - */ - -static int -pam_iruserok(pam_handle_t *pamh, - struct _options *opts, U32 raddr, int superuser, - const char *ruser, const char *luser, const char *rhost) -{ - const char *cp; - struct stat sbuf; - struct passwd *pwd; - FILE *hostf; - uid_t uid; - int answer; - char pbuf[MAXPATHLEN]; /* potential buffer overrun */ - - if ((!superuser||opts->opt_hosts_equiv_rootok) && !opts->opt_no_hosts_equiv ) { - - /* try to open system hosts.equiv file */ - hostf = fopen (_PATH_HEQUIV, "r"); - if (hostf) { - answer = __ivaliduser(pamh, opts, hostf, raddr, luser - , ruser, rhost); - (void) fclose(hostf); - if (answer == 0) - return 0; /* remote host is equivalent to localhost */ - } /* else { - No hosts.equiv file on system. - } */ - } - - if ( opts->opt_no_rhosts ) - return 1; - - /* - * Identify user's local .rhosts file - */ - - pwd = _pammodutil_getpwnam(pamh, luser); - if (pwd == NULL) { - /* - * luser is assumed to be valid because of an earlier check for uid = 0 - * we don't log this error twice. However, this shouldn't happen ! - * --cristiang - */ - return(1); - } - - /* check for buffer overrun */ - if (strlen(pwd->pw_dir) + sizeof(USER_RHOSTS_FILE) + 2 >= MAXPATHLEN) { - if (opts->opt_debug) - _pam_log(LOG_DEBUG,"home directory for `%s' is too long", luser); - return 1; /* to dangerous to try */ - } - - (void) strcpy(pbuf, pwd->pw_dir); - (void) strcat(pbuf, USER_RHOSTS_FILE); - - /* - * Change effective uid while _reading_ .rhosts. (not just - * opening). If root and reading an NFS mounted file system, - * can't read files that are 0600 as .rhosts files should be. - */ - - /* We are root, this will not fail */ -#ifdef __linux__ - /* If we are on linux the better way is setfsuid */ - uid = setfsuid(pwd->pw_uid); - hostf = fopen(pbuf, "r"); -#else - uid = geteuid(); - (void) seteuid(pwd->pw_uid); - hostf = fopen(pbuf, "r"); -#endif - - if (hostf == NULL) { - if (opts->opt_debug) - _pam_log(LOG_DEBUG,"Could not open %s file",pbuf); - answer = 1; - goto exit_function; - } - - /* - * If not a regular file, or is owned by someone other than - * user or root or if writeable by anyone but the owner, quit. - */ - - cp = NULL; - if (lstat(pbuf, &sbuf) < 0 || !S_ISREG(sbuf.st_mode)) - cp = ".rhosts not regular file"; - else if (fstat(fileno(hostf), &sbuf) < 0) - cp = ".rhosts fstat failed"; - else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) - cp = "bad .rhosts owner"; - else if (sbuf.st_mode & S_IWOTH) - cp = ".rhosts writable by other!"; - else if (sbuf.st_mode & S_IWGRP) { - - /* private group caveat */ - if (opts->opt_private_group) { - struct group *grp = _pammodutil_getgrgid(pamh, sbuf.st_gid); - - if (NULL == grp || NULL == grp->gr_name - || strcmp(luser,grp->gr_name)) { - cp = ".rhosts writable by public group"; - } else if (grp->gr_mem) { - int gcount; - - /* require at most one member (luser) of this group */ - for (gcount=0; grp->gr_mem[gcount]; ++gcount) { - if (strcmp(grp->gr_mem[gcount], luser)) { - gcount = -1; - break; - } - } - if (gcount < 0) { - cp = ".rhosts writable by other members of group"; - } - } - } else { - cp = ".rhosts writable by group"; - } - - } /* It is _NOT_ safe to append an else here... Do so prior to - * S_IWGRP check */ - - /* If there were any problems, quit. */ - if (cp) { - opts->last_error = cp; - answer = 1; - goto exit_function; - } - - answer = __ivaliduser (pamh, opts, hostf, raddr, luser, ruser, rhost); - -exit_function: - /* - * Go here to exit after the fsuid/euid has been adjusted so that - * they are reset before we exit. - */ - -#ifdef __linux__ - setfsuid(uid); -#else - (void)seteuid(uid); -#endif - - if (hostf != NULL) - (void) fclose(hostf); - - return answer; -} - -static int -pam_ruserok (pam_handle_t *pamh, - struct _options *opts, const char *rhost, int superuser, - const char *ruser, const char *luser) -{ - struct hostent *hp; - int answer = 1; /* default to failure */ - U32 *addrs; - int n, i; - - opts->last_error = (char *) 0; - hp = gethostbyname(rhost); /* identify host */ - - if (hp != NULL) { - /* First of all check the address length */ - if (hp->h_length != 4) { - _pam_log(LOG_ALERT, "pam_rhosts module can't work with not IPv4 " - "addresses"); - return 1; /* not allowed */ - } - - /* loop though address list */ - for (n = 0; hp->h_addr_list[n]; n++); - D(("rhosts: %d addresses", n)); - - if (n) { - addrs = calloc (n, hp->h_length); - for (i = 0; i < n; i++) - memcpy (addrs+i, hp->h_addr_list[i], hp->h_length); - - for (i = 0; i < n && answer; i++) { - D(("rhosts: address %d is %04x", i, addrs[i])); - answer = pam_iruserok(pamh, opts, addrs[i], superuser, - ruser, luser, rhost); - /* answer == 0 means success */ - } - - free (addrs); - } - } - - return answer; -} - -/* - * Internal function to do authentication - */ - -static int _pam_auth_rhosts (pam_handle_t *pamh, - int flags, - int argc, - const char **argv) -{ - int retval; - const char *luser = NULL; - const char *ruser = NULL, *rhost = NULL; - struct _options opts; - int as_root = 0; - - /* - * Look at the options and set the flags accordingly. - */ - memset (&opts, 0, sizeof (opts)); - set_parameters (&opts, flags, argc, argv); - /* - * Obtain the parameters for the various items - */ - for (;;) { /* abuse loop to avoid goto */ - - /* get the remotehost */ - D(("getting rhost")); - retval = pam_get_rhost(pamh, &rhost, NULL); - (void) pam_set_item(pamh, PAM_RHOST, rhost); - if (retval != PAM_SUCCESS) { - if (opts.opt_debug) { - _pam_log(LOG_DEBUG, "could not get the remote host name"); - } - break; - } - - /* get the remote user */ - D(("getting ruser")); - retval = pam_get_ruser(pamh, &ruser, NULL); - (void) pam_set_item(pamh, PAM_RUSER, ruser); - if (retval != PAM_SUCCESS) { - if (opts.opt_debug) - _pam_log(LOG_DEBUG, "could not get the remote username"); - break; - } - - /* get the local user */ - D(("getting user")); - retval = pam_get_user(pamh, &luser, NULL); - if (retval != PAM_SUCCESS) { - if (opts.opt_debug) - _pam_log(LOG_DEBUG, "could not determine name of local user"); - break; - } - - if (opts.superuser && !strcmp(opts.superuser, luser)) { - as_root = 1; - } - - /* check if the luser uid == 0... --cristiang */ - if (! opts.opt_no_uid_check) { - struct passwd *luser_pwd; - - luser_pwd = _pammodutil_getpwnam(pamh, luser); - if (luser_pwd == NULL) { - if (opts.opt_debug) - _pam_log(LOG_DEBUG, "user '%s' unknown to this system", - luser); - retval = PAM_AUTH_ERR; - break; - } - if (luser_pwd->pw_uid == 0) - as_root = 1; - luser_pwd = NULL; /* forget */ - } -/* - * Validate the account information. - */ - if (pam_ruserok (pamh, &opts, rhost, as_root, ruser, luser) != 0) { - if ( !opts.opt_suppress ) { - _pam_log(LOG_WARNING, "denied to %s@%s as %s: %s", - ruser, rhost, luser, (opts.last_error==NULL) ? - "access not allowed":opts.last_error); - } - retval = PAM_AUTH_ERR; - } else { - _pam_log(LOG_NOTICE, "allowed to %s@%s as %s", - ruser, rhost, luser); - } - break; - } - - return retval; -} - -/* --- authentication management functions --- */ - -PAM_EXTERN -int pam_sm_authenticate (pam_handle_t *pamh, - int flags, - int argc, - const char **argv) -{ - int retval; - - if (sizeof(U32) != 4) { - _pam_log (LOG_ALERT, "pam_rhosts module can\'t work on this hardware " - "(yet)"); - return PAM_AUTH_ERR; - } - sethostent(1); - retval = _pam_auth_rhosts (pamh, flags, argc, argv); - endhostent(); - return retval; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc, - const char **argv) -{ - return PAM_SUCCESS; -} - -/* end of module definition */ - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_rhosts_auth_modstruct = { - "pam_rhosts_auth", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL, -}; - -#endif diff --git a/modules/pam_rootok/.cvsignore b/modules/pam_rootok/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_rootok/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_rootok/Makefile b/modules/pam_rootok/Makefile deleted file mode 100644 index 3460c2a2..00000000 --- a/modules/pam_rootok/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_rootok - -include ../Simple.Rules diff --git a/modules/pam_rootok/README b/modules/pam_rootok/README deleted file mode 100644 index cccb5ce1..00000000 --- a/modules/pam_rootok/README +++ /dev/null @@ -1,18 +0,0 @@ -# $Id$ -# - -this module is an authentication module that performs one task: if the -id of the user is '0' then it returns 'PAM_SUCCESS' with the -'sufficient' /etc/pam.conf control flag it can be used to allow -password free access to some service for 'root' - -Recognized arguments: - - debug write a message to syslog indicating success or - failure. - -module services provided: - - auth _authentication and _setcred (blank) - -Andrew Morgan diff --git a/modules/pam_rootok/pam_rootok.c b/modules/pam_rootok/pam_rootok.c deleted file mode 100644 index a7342104..00000000 --- a/modules/pam_rootok/pam_rootok.c +++ /dev/null @@ -1,110 +0,0 @@ -/* pam_rootok module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11 - */ - -#define _GNU_SOURCE - -#include <stdio.h> -#include <unistd.h> -#include <syslog.h> -#include <stdarg.h> -#include <string.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH - -#include <security/pam_modules.h> - -/* some syslogging */ - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-rootok", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - - -/* argument parsing */ - -#define PAM_DEBUG_ARG 01 - -static int _pam_parse(int argc, const char **argv) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else { - _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv); - } - } - - return ctrl; -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - int ctrl; - int retval = PAM_AUTH_ERR; - - ctrl = _pam_parse(argc, argv); - if (getuid() == 0) - retval = PAM_SUCCESS; - - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_DEBUG, "authentication %s" - , retval==PAM_SUCCESS ? "succeeded":"failed" ); - } - - return retval; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_SUCCESS; -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_rootok_modstruct = { - "pam_rootok", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_securetty/.cvsignore b/modules/pam_securetty/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_securetty/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_securetty/Makefile b/modules/pam_securetty/Makefile deleted file mode 100644 index 9b80d2e9..00000000 --- a/modules/pam_securetty/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_securetty - -include ../Simple.Rules diff --git a/modules/pam_securetty/README b/modules/pam_securetty/README deleted file mode 100644 index 1df095c9..00000000 --- a/modules/pam_securetty/README +++ /dev/null @@ -1,9 +0,0 @@ -pam_securetty: - Allows root logins only if the user is logging in on a - "secure" tty, as defined by the listing in /etc/securetty - - Also checks to make sure that /etc/securetty is a plain - file and not world writable. - - - Elliot Lee <sopwith@redhat.com>, Red Hat Software. - July 25, 1996. diff --git a/modules/pam_securetty/pam_securetty.c b/modules/pam_securetty/pam_securetty.c deleted file mode 100644 index 3a9ae421..00000000 --- a/modules/pam_securetty/pam_securetty.c +++ /dev/null @@ -1,232 +0,0 @@ -/* pam_securetty module */ - -#define SECURETTY_FILE "/etc/securetty" -#define TTY_PREFIX "/dev/" - -/* - * by Elliot Lee <sopwith@redhat.com>, Red Hat Software. - * July 25, 1996. - * This code shamelessly ripped from the pam_rootok module. - * Slight modifications AGM. 1996/12/3 - */ - -#define _GNU_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <syslog.h> -#include <stdarg.h> -#include <pwd.h> -#include <string.h> -#include <ctype.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> -#include <security/_pam_modutil.h> - -/* some syslogging */ - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-securetty", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -/* argument parsing */ - -#define PAM_DEBUG_ARG 0x0001 - -static int _pam_parse(int argc, const char **argv) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else { - _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv); - } - } - - return ctrl; -} - -static int securetty_perform_check(pam_handle_t *pamh, int flags, int ctrl, - const char *function_name) -{ - int retval = PAM_AUTH_ERR; - const char *username; - char *uttyname; - char ttyfileline[256]; - char ptname[256]; - struct stat ttyfileinfo; - struct passwd *user_pwd; - FILE *ttyfile; - - /* log a trail for debugging */ - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_DEBUG, "pam_securetty called via %s function", - function_name); - } - - retval = pam_get_user(pamh, &username, NULL); - if (retval != PAM_SUCCESS || username == NULL) { - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_WARNING, "cannot determine username"); - } - return (retval == PAM_CONV_AGAIN ? PAM_INCOMPLETE:PAM_SERVICE_ERR); - } - - user_pwd = _pammodutil_getpwnam(pamh, username); - if (user_pwd == NULL) { - return PAM_IGNORE; - } else if (user_pwd->pw_uid != 0) { /* If the user is not root, - securetty's does not apply - to them */ - return PAM_SUCCESS; - } - - retval = pam_get_item(pamh, PAM_TTY, (const void **)&uttyname); - if (retval != PAM_SUCCESS || uttyname == NULL) { - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_WARNING, "cannot determine user's tty"); - } - return PAM_SERVICE_ERR; - } - - /* The PAM_TTY item may be prefixed with "/dev/" - skip that */ - if (strncmp(TTY_PREFIX, uttyname, sizeof(TTY_PREFIX)-1) == 0) { - uttyname += sizeof(TTY_PREFIX)-1; - } - - if (stat(SECURETTY_FILE, &ttyfileinfo)) { - _pam_log(LOG_NOTICE, "Couldn't open " SECURETTY_FILE); - return PAM_SUCCESS; /* for compatibility with old securetty handling, - this needs to succeed. But we still log the - error. */ - } - - if ((ttyfileinfo.st_mode & S_IWOTH) || !S_ISREG(ttyfileinfo.st_mode)) { - /* If the file is world writable or is not a - normal file, return error */ - _pam_log(LOG_ERR, SECURETTY_FILE - " is either world writable or not a normal file"); - return PAM_AUTH_ERR; - } - - ttyfile = fopen(SECURETTY_FILE,"r"); - if (ttyfile == NULL) { /* Check that we opened it successfully */ - _pam_log(LOG_ERR, - "Error opening " SECURETTY_FILE); - return PAM_SERVICE_ERR; - } - - if (isdigit(uttyname[0])) { - snprintf(ptname, sizeof(ptname), "pts/%s", uttyname); - } else { - ptname[0] = '\0'; - } - - retval = 1; - - while ((fgets(ttyfileline, sizeof(ttyfileline)-1, ttyfile) != NULL) - && retval) { - if (ttyfileline[strlen(ttyfileline) - 1] == '\n') - ttyfileline[strlen(ttyfileline) - 1] = '\0'; - - retval = ( strcmp(ttyfileline, uttyname) - && (!ptname[0] || strcmp(ptname, uttyname)) ); - } - fclose(ttyfile); - - if (retval) { - _pam_log(LOG_WARNING, "access denied: tty '%s' is not secure !", - uttyname); - - retval = PAM_AUTH_ERR; - } else { - if ((retval == PAM_SUCCESS) && (ctrl & PAM_DEBUG_ARG)) { - _pam_log(LOG_DEBUG, "access allowed for '%s' on '%s'", - username, uttyname); - } - retval = PAM_SUCCESS; - - } - - return retval; -} - -/* --- authentication management functions --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - int ctrl; - - /* parse the arguments */ - ctrl = _pam_parse(argc, argv); - - return securetty_perform_check(pamh, flags, ctrl, __FUNCTION__); -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return PAM_SUCCESS; -} - -/* --- account management functions --- */ - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - int ctrl; - - /* parse the arguments */ - ctrl = _pam_parse(argc, argv); - - /* take the easy route */ - return securetty_perform_check(pamh, flags, ctrl, __FUNCTION__); -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_securetty_modstruct = { - "pam_securetty", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; - -#endif /* PAM_STATIC */ - -/* end of module definition */ diff --git a/modules/pam_shells/.cvsignore b/modules/pam_shells/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_shells/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_shells/Makefile b/modules/pam_shells/Makefile deleted file mode 100644 index b057dc00..00000000 --- a/modules/pam_shells/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_shells - -include ../Simple.Rules diff --git a/modules/pam_shells/README b/modules/pam_shells/README deleted file mode 100644 index aa63a827..00000000 --- a/modules/pam_shells/README +++ /dev/null @@ -1,9 +0,0 @@ -pam_shells: - Authentication is granted if the users shell is listed in - /etc/shells. - - Also checks to make sure that /etc/shells is a plain - file and not world writable. - - - Erik Troan <ewt@redhat.com>, Red Hat Software. - August 5, 1996. diff --git a/modules/pam_shells/pam_shells.c b/modules/pam_shells/pam_shells.c deleted file mode 100644 index 64359eac..00000000 --- a/modules/pam_shells/pam_shells.c +++ /dev/null @@ -1,158 +0,0 @@ -/* pam_shells module */ - -#define SHELL_FILE "/etc/shells" - -/* - * by Erik Troan <ewt@redhat.com>, Red Hat Software. - * August 5, 1996. - * This code shamelessly ripped from the pam_securetty module. - */ - -#define _BSD_SOURCE - -#include <pwd.h> -#include <stdarg.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <syslog.h> -#include <unistd.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> -#include <security/_pam_modutil.h> - -/* some syslogging */ - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-shells", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -static int perform_check(pam_handle_t *pamh, int flags) -{ - int retval = PAM_AUTH_ERR; - const char *userName; - char *userShell; - char shellFileLine[256]; - struct stat sb; - struct passwd * pw; - FILE * shellFile; - - retval = pam_get_user(pamh, &userName, NULL); - if (retval != PAM_SUCCESS) { - return PAM_SERVICE_ERR; - } - - if (!userName || (userName[0] == '\0')) { - - /* Don't let them use a NULL username... */ - retval = pam_get_user(pamh,&userName,NULL); - if (retval != PAM_SUCCESS) - return PAM_SERVICE_ERR; - - /* It could still be NULL the second time. */ - if (!userName || (userName[0] == '\0')) - return PAM_SERVICE_ERR; - } - - pw = _pammodutil_getpwnam(pamh, userName); - if (!pw) { - return PAM_AUTH_ERR; /* user doesn't exist */ - } - userShell = pw->pw_shell; - - if (stat(SHELL_FILE,&sb)) { - _pam_log(LOG_ERR, "%s cannot be stat'd (it probably does not exist)", - SHELL_FILE); - return PAM_AUTH_ERR; /* must have /etc/shells */ - } - - if ((sb.st_mode & S_IWOTH) || !S_ISREG(sb.st_mode)) { - _pam_log(LOG_ERR, "%s is either world writable or not a normal file", - SHELL_FILE); - return PAM_AUTH_ERR; - } - - shellFile = fopen(SHELL_FILE,"r"); - if (shellFile == NULL) { /* Check that we opened it successfully */ - _pam_log(LOG_ERR, - "Error opening %s", SHELL_FILE); - return PAM_SERVICE_ERR; - } - - retval = 1; - - while(retval && (fgets(shellFileLine, 255, shellFile) != NULL)) { - if (shellFileLine[strlen(shellFileLine) - 1] == '\n') - shellFileLine[strlen(shellFileLine) - 1] = '\0'; - retval = strcmp(shellFileLine, userShell); - } - - fclose(shellFile); - - if (retval) { - return PAM_AUTH_ERR; - } else { - return PAM_SUCCESS; - } -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return perform_check(pamh, flags); -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,const char **argv) -{ - return PAM_SUCCESS; -} - -/* --- account management functions (only) --- */ - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return perform_check(pamh, flags); -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_shells_modstruct = { - "pam_shells", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; - -#endif /* PAM_STATIC */ - -/* end of module definition */ diff --git a/modules/pam_stress/.cvsignore b/modules/pam_stress/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_stress/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_stress/Makefile b/modules/pam_stress/Makefile deleted file mode 100644 index 598809a5..00000000 --- a/modules/pam_stress/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_stress - -include ../Simple.Rules diff --git a/modules/pam_stress/README b/modules/pam_stress/README deleted file mode 100644 index 74a297b2..00000000 --- a/modules/pam_stress/README +++ /dev/null @@ -1,66 +0,0 @@ -# -# $Id$ -# -# This describes the behavior of this module with respect to the -# /etc/pam.conf file. -# -# writen by Andrew Morgan <morgan@parc.power.net> -# - -This module recognizes the following arguments. - -debug put lots of information in syslog. - *NOTE* this option writes passwords to syslog, so - don't use anything sensitive when testing. - -no_warn don't give warnings about things (otherwise warnings are issued - via the conversation function) - -use_first_pass don't prompt for a password, for pam_sm_authentication - function just use item PAM_AUTHTOK. - -try_first_pass don't prompt for a password unless there has been no - previous authentication token (item PAM_AUTHTOK is NULL) - -rootok This is intended for the pam_sm_chauthtok function and - it instructs this function to permit root to change - the user's password without entering the old password. - -The following arguments are acted on by the module. They are intended -to make the module give the impression of failing as a fully -functioning module might. - -expired an argument intended for the account and chauthtok module - parts. It instructs the module to act as if the user's - password has expired - -fail_1 this instructs the module to make its first function fail. - -fail_2 this instructs the module to make its second function (if there - is one) fail. - - The function break up is indicated in the Module - Developers' Guide. Listed here it is: - - service function 1 function 2 - ------- ---------- ---------- - auth pam_sm_authenticate pam_sm_setcred - password pam_sm_chauthtok - session pam_sm_open_session pam_sm_close_session - account pam_sm_acct_mgmt - -prelim for pam_sm_chauthtok, means fail on PAM_PRELIM_CHECK. - -required for pam_sm_chauthtok, means fail if the user hasn't already - been authenticated by this module. (See stress_new_pwd data - item below.) - -# -# data strings that this module uses are the following: -# - -data name value(s) Comments ---------- -------- -------- -stress_new_pwd yes tells pam_sm_chauthtok that - pam_sm_acct_mgmt says we need a new - password diff --git a/modules/pam_stress/pam_stress.c b/modules/pam_stress/pam_stress.c deleted file mode 100644 index d45ad300..00000000 --- a/modules/pam_stress/pam_stress.c +++ /dev/null @@ -1,567 +0,0 @@ -/* pam_stress module */ - -/* $Id$ - * - * created by Andrew Morgan <morgan@linux.kernel.org> 1996/3/12 - */ - -#include <security/_pam_aconf.h> - -#include <stdlib.h> -#include <stdio.h> - -#include <syslog.h> - -#include <stdarg.h> -#include <string.h> -#include <unistd.h> - -/* - * 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 -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> - - -/* log errors */ - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-stress", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -/* ---------- */ - -/* an internal function to turn all possible test arguments into bits - of a ctrl number */ - -/* generic options */ - -#define PAM_ST_DEBUG 01 -#define PAM_ST_NO_WARN 02 -#define PAM_ST_USE_PASS1 04 -#define PAM_ST_TRY_PASS1 010 -#define PAM_ST_ROOTOK 020 - -/* simulation options */ - -#define PAM_ST_EXPIRED 040 -#define PAM_ST_FAIL_1 0100 -#define PAM_ST_FAIL_2 0200 -#define PAM_ST_PRELIM 0400 -#define PAM_ST_REQUIRE_PWD 01000 - -/* some syslogging */ - -static void _pam_report(int ctrl, const char *name, int flags, - int argc, const char **argv) -{ - if (ctrl & PAM_ST_DEBUG) { - _pam_log(LOG_DEBUG, "CALLED: %s", name); - _pam_log(LOG_DEBUG, "FLAGS : 0%o%s", flags, - (flags & PAM_SILENT) ? " (silent)":""); - _pam_log(LOG_DEBUG, "CTRL = 0%o",ctrl); - _pam_log(LOG_DEBUG, "ARGV :"); - while (argc--) { - _pam_log(LOG_DEBUG, " \"%s\"", *argv++); - } - } -} - -static int _pam_parse(int argc, const char **argv) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_ST_DEBUG; - else if (!strcmp(*argv,"no_warn")) - ctrl |= PAM_ST_NO_WARN; - else if (!strcmp(*argv,"use_first_pass")) - ctrl |= PAM_ST_USE_PASS1; - else if (!strcmp(*argv,"try_first_pass")) - ctrl |= PAM_ST_TRY_PASS1; - else if (!strcmp(*argv,"rootok")) - ctrl |= PAM_ST_ROOTOK; - - /* simulation options */ - - else if (!strcmp(*argv,"expired")) /* signal password needs - renewal */ - ctrl |= PAM_ST_EXPIRED; - else if (!strcmp(*argv,"fail_1")) /* instruct fn 1 to fail */ - ctrl |= PAM_ST_FAIL_1; - else if (!strcmp(*argv,"fail_2")) /* instruct fn 2 to fail */ - ctrl |= PAM_ST_FAIL_2; - else if (!strcmp(*argv,"prelim")) /* instruct pam_sm_setcred - to fail on first call */ - ctrl |= PAM_ST_PRELIM; - else if (!strcmp(*argv,"required")) /* module is fussy about the - user being authenticated */ - ctrl |= PAM_ST_REQUIRE_PWD; - - else { - _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv); - } - } - - return ctrl; -} - -static int converse(pam_handle_t *pamh, int nargs - , struct pam_message **message - , struct pam_response **response) -{ - int retval; - struct pam_conv *conv; - - retval = pam_get_item(pamh,PAM_CONV,(const void **)&conv); - if (retval == PAM_SUCCESS && conv) { - retval = conv->conv(nargs, (const struct pam_message **) message - , response, conv->appdata_ptr); - if (retval != PAM_SUCCESS) { - _pam_log(LOG_ERR,"(pam_stress) converse returned %d",retval); - _pam_log(LOG_ERR,"that is: %s",pam_strerror(pamh, retval)); - } - } else { - _pam_log(LOG_ERR,"(pam_stress) converse failed to get pam_conv"); - if (retval == PAM_SUCCESS) - retval = PAM_BAD_ITEM; /* conv was null */ - } - - return retval; -} - -/* authentication management functions */ - -static int stress_get_password(pam_handle_t *pamh, int flags - , int ctrl, char **password) -{ - char *pass; - - if ( (ctrl & (PAM_ST_TRY_PASS1|PAM_ST_USE_PASS1)) - && (pam_get_item(pamh,PAM_AUTHTOK,(const void **)&pass) - == PAM_SUCCESS) - && (pass != NULL) ) { - if ((pass = strdup(pass)) == NULL) - return PAM_BUF_ERR; - } else if ((ctrl & PAM_ST_USE_PASS1)) { - _pam_log(LOG_WARNING, "pam_stress: no forwarded password"); - return PAM_PERM_DENIED; - } else { /* we will have to get one */ - struct pam_message msg[1],*pmsg[1]; - struct pam_response *resp; - int retval; - - /* set up conversation call */ - - pmsg[0] = &msg[0]; - msg[0].msg_style = PAM_PROMPT_ECHO_OFF; - msg[0].msg = "STRESS Password: "; - resp = NULL; - - if ((retval = converse(pamh,1,pmsg,&resp)) != PAM_SUCCESS) { - return retval; - } - - if (resp) { - if ((resp[0].resp == NULL) && (ctrl & PAM_ST_DEBUG)) { - _pam_log(LOG_DEBUG, - "pam_sm_authenticate: NULL authtok given"); - } - if ((flags & PAM_DISALLOW_NULL_AUTHTOK) - && resp[0].resp == NULL) { - free(resp); - return PAM_AUTH_ERR; - } - - pass = resp[0].resp; /* remember this! */ - - resp[0].resp = NULL; - } else if (ctrl & PAM_ST_DEBUG) { - _pam_log(LOG_DEBUG,"pam_sm_authenticate: no error reported"); - _pam_log(LOG_DEBUG,"getting password, but NULL returned!?"); - return PAM_CONV_ERR; - } - if (resp) - free(resp); - } - - *password = pass; /* this *MUST* be free()'d by this module */ - - return PAM_SUCCESS; -} - -/* function to clean up data items */ - -static void wipe_up(pam_handle_t *pamh, void *data, int error) -{ - free(data); -} - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - const char *username; - int retval=PAM_SUCCESS; - char *pass; - int ctrl; - - D(("called.")); - - ctrl = _pam_parse(argc,argv); - _pam_report(ctrl, "pam_sm_authenticate", flags, argc, argv); - - /* try to get the username */ - - retval = pam_get_user(pamh, &username, "username: "); - if (retval != PAM_SUCCESS || !username) { - _pam_log(LOG_WARNING, "pam_sm_authenticate: failed to get username"); - if (retval == PAM_SUCCESS) - retval = PAM_USER_UNKNOWN; /* username was null */ - return retval; - } - else if ((ctrl & PAM_ST_DEBUG) && (retval == PAM_SUCCESS)) { - _pam_log(LOG_DEBUG, "pam_sm_authenticate: username = %s", username); - } - - /* now get the password */ - - retval = stress_get_password(pamh,flags,ctrl,&pass); - if (retval != PAM_SUCCESS) { - _pam_log(LOG_WARNING, "pam_sm_authenticate: " - "failed to get a password"); - return retval; - } - - /* try to set password item */ - - retval = pam_set_item(pamh,PAM_AUTHTOK,pass); - _pam_overwrite(pass); /* clean up local copy of password */ - free(pass); - pass = NULL; - if (retval != PAM_SUCCESS) { - _pam_log(LOG_WARNING, "pam_sm_authenticate: " - "failed to store new password"); - return retval; - } - - /* if we are debugging then we print the password */ - - if (ctrl & PAM_ST_DEBUG) { - (void) pam_get_item(pamh,PAM_AUTHTOK,(const void **)&pass); - _pam_log(LOG_DEBUG, - "pam_st_authenticate: password entered is: [%s]\n",pass); - pass = NULL; - } - - /* if we signal a fail for this function then fail */ - - if ((ctrl & PAM_ST_FAIL_1) && retval == PAM_SUCCESS) - return PAM_PERM_DENIED; - - return retval; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int ctrl = _pam_parse(argc,argv); - - D(("called. [post parsing]")); - - _pam_report(ctrl, "pam_sm_setcred", flags, argc, argv); - - if (ctrl & PAM_ST_FAIL_2) - return PAM_CRED_ERR; - - return PAM_SUCCESS; -} - -/* account management functions */ - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int ctrl = _pam_parse(argc,argv); - - D(("called. [post parsing]")); - - _pam_report(ctrl,"pam_sm_acct_mgmt", flags, argc, argv); - - if (ctrl & PAM_ST_FAIL_1) - return PAM_PERM_DENIED; - else if (ctrl & PAM_ST_EXPIRED) { - int retval; - void *text = strdup("yes"); - if (!text) - return PAM_BUF_ERR; - retval = pam_set_data(pamh,"stress_new_pwd",text,wipe_up); - if (retval != PAM_SUCCESS) { - _pam_log(LOG_DEBUG, - "pam_sm_acct_mgmt: failed setting stress_new_pwd"); - free(text); - return retval; - } - - if (ctrl & PAM_ST_DEBUG) { - _pam_log(LOG_DEBUG,"pam_sm_acct_mgmt: need a new password"); - } - return PAM_NEW_AUTHTOK_REQD; - } - - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_open_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - char *username,*service; - int ctrl = _pam_parse(argc,argv); - - D(("called. [post parsing]")); - - _pam_report(ctrl,"pam_sm_open_session", flags, argc, argv); - - if ((pam_get_item(pamh, PAM_USER, (const void **) &username) - != PAM_SUCCESS || !username) - || (pam_get_item(pamh, PAM_SERVICE, (const void **) &service) - != PAM_SUCCESS || !service)) { - _pam_log(LOG_WARNING,"pam_sm_open_session: for whom?"); - return PAM_SESSION_ERR; - } - - _pam_log(LOG_NOTICE,"pam_stress: opened [%s] session for user [%s]" - , service, username); - - if (ctrl & PAM_ST_FAIL_1) - return PAM_SESSION_ERR; - - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_close_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - const char *username,*service; - int ctrl = _pam_parse(argc,argv); - - D(("called. [post parsing]")); - - _pam_report(ctrl,"pam_sm_close_session", flags, argc, argv); - - if ((pam_get_item(pamh, PAM_USER, (const void **)&username) - != PAM_SUCCESS || !username) - || (pam_get_item(pamh, PAM_SERVICE, (const void **)&service) - != PAM_SUCCESS || !service)) { - _pam_log(LOG_WARNING,"pam_sm_close_session: for whom?"); - return PAM_SESSION_ERR; - } - - _pam_log(LOG_NOTICE,"pam_stress: closed [%s] session for user [%s]" - , service, username); - - if (ctrl & PAM_ST_FAIL_2) - return PAM_SESSION_ERR; - - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_chauthtok(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int retval; - int ctrl = _pam_parse(argc,argv); - - D(("called. [post parsing]")); - - _pam_report(ctrl,"pam_sm_chauthtok", flags, argc, argv); - - /* this function should be called twice by the Linux-PAM library */ - - if (flags & PAM_PRELIM_CHECK) { /* first call */ - if (ctrl & PAM_ST_DEBUG) { - _pam_log(LOG_DEBUG,"pam_sm_chauthtok: prelim check"); - } - if (ctrl & PAM_ST_PRELIM) - return PAM_TRY_AGAIN; - - return PAM_SUCCESS; - } else if (flags & PAM_UPDATE_AUTHTOK) { /* second call */ - struct pam_message msg[3],*pmsg[3]; - struct pam_response *resp; - const char *text; - char *txt=NULL; - int i; - - if (ctrl & PAM_ST_DEBUG) { - _pam_log(LOG_DEBUG,"pam_sm_chauthtok: alter password"); - } - - if (ctrl & PAM_ST_FAIL_1) - return PAM_AUTHTOK_LOCK_BUSY; - - if ( !(ctrl && PAM_ST_EXPIRED) - && (flags & PAM_CHANGE_EXPIRED_AUTHTOK) - && (pam_get_data(pamh,"stress_new_pwd",(const void **)&text) - != PAM_SUCCESS || strcmp(text,"yes"))) { - return PAM_SUCCESS; /* the token has not expired */ - } - - /* the password should be changed */ - - if ((ctrl & PAM_ST_REQUIRE_PWD) - && !(getuid() == 0 && (ctrl & PAM_ST_ROOTOK)) - ) { /* first get old one? */ - char *pass; - - if (ctrl & PAM_ST_DEBUG) { - _pam_log(LOG_DEBUG - ,"pam_sm_chauthtok: getting old password"); - } - retval = stress_get_password(pamh,flags,ctrl,&pass); - if (retval != PAM_SUCCESS) { - _pam_log(LOG_DEBUG - ,"pam_sm_chauthtok: no password obtained"); - return retval; - } - retval = pam_set_item(pamh, PAM_OLDAUTHTOK, pass); - _pam_overwrite(pass); - free(pass); - pass = NULL; - if (retval != PAM_SUCCESS) { - _pam_log(LOG_DEBUG - ,"pam_sm_chauthtok: could not set OLDAUTHTOK"); - return retval; - } - } - - /* set up for conversation */ - - if (!(flags & PAM_SILENT)) { - char *username; - - if ( pam_get_item(pamh, PAM_USER, (const void **)&username) - || username == NULL ) { - _pam_log(LOG_ERR,"no username set"); - return PAM_USER_UNKNOWN; - } - pmsg[0] = &msg[0]; - msg[0].msg_style = PAM_TEXT_INFO; -#define _LOCAL_STRESS_COMMENT "Changing STRESS password for " - txt = (char *) malloc(sizeof(_LOCAL_STRESS_COMMENT) - +strlen(username)+1); - strcpy(txt, _LOCAL_STRESS_COMMENT); -#undef _LOCAL_STRESS_COMMENT - strcat(txt, username); - msg[0].msg = txt; - i = 1; - } else { - i = 0; - } - - pmsg[i] = &msg[i]; - msg[i].msg_style = PAM_PROMPT_ECHO_OFF; - msg[i++].msg = "Enter new STRESS password: "; - pmsg[i] = &msg[i]; - msg[i].msg_style = PAM_PROMPT_ECHO_OFF; - msg[i++].msg = "Retype new STRESS password: "; - resp = NULL; - - retval = converse(pamh,i,pmsg,&resp); - if (txt) { - free(txt); - txt = NULL; /* clean up */ - } - if (retval != PAM_SUCCESS) { - return retval; - } - - if (resp == NULL) { - _pam_log(LOG_ERR, "pam_sm_chauthtok: no response from conv"); - return PAM_CONV_ERR; - } - - /* store the password */ - - if (resp[i-2].resp && resp[i-1].resp) { - if (strcmp(resp[i-2].resp,resp[i-1].resp)) { - /* passwords are not the same; forget and return error */ - - _pam_drop_reply(resp, i); - - if (!(flags & PAM_SILENT) && !(ctrl & PAM_ST_NO_WARN)) { - pmsg[0] = &msg[0]; - msg[0].msg_style = PAM_ERROR_MSG; - msg[0].msg = "Verification mis-typed; " - "password unchanged"; - resp = NULL; - (void) converse(pamh,1,pmsg,&resp); - if (resp) { - _pam_drop_reply(resp, 1); - } - } - return PAM_AUTHTOK_ERR; - } - - if (pam_get_item(pamh,PAM_AUTHTOK,(const void **)&text) - == PAM_SUCCESS) { - (void) pam_set_item(pamh,PAM_OLDAUTHTOK,text); - text = NULL; - } - (void) pam_set_item(pamh,PAM_AUTHTOK,resp[0].resp); - } else { - _pam_log(LOG_DEBUG,"pam_sm_chauthtok: problem with resp"); - retval = PAM_SYSTEM_ERR; - } - - _pam_drop_reply(resp, i); /* clean up the passwords */ - } else { - _pam_log(LOG_ERR,"pam_sm_chauthtok: this must be a Linux-PAM error"); - return PAM_SYSTEM_ERR; - } - - return retval; -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_stress_modstruct = { - "pam_stress", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; - -#endif diff --git a/modules/pam_succeed_if/Makefile b/modules/pam_succeed_if/Makefile deleted file mode 100644 index 51e18c81..00000000 --- a/modules/pam_succeed_if/Makefile +++ /dev/null @@ -1,16 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_succeed_if -MAN8=$(TITLE).8 - -include ../Simple.Rules diff --git a/modules/pam_succeed_if/README b/modules/pam_succeed_if/README deleted file mode 100644 index fdb278ef..00000000 --- a/modules/pam_succeed_if/README +++ /dev/null @@ -1,68 +0,0 @@ -pam_succeed_if: - Succeed or fail based on account characteristics. - - pam_succeed_if.so is designed to succeed or fail authentication based - on characteristics of the account belonging to the user being - authenticated. - - The module can be given one or more conditions as module arguments, and - authentication will succeed only if all of the conditions are met. - - Conditions are expressed in the form - - ATTRIBUTE OPERATOR VALUE - - Recognized attributes: - - LOGIN - The user's login name. - UID - The user's UID. - GID - The user's primary GID. - SHELL - The user's shell. - HOME - The user's home directory. - - Recognized operators: - - < - Arithmetic less-than. - <= - Arithmetic less-than-or-equal-to. - > - Arithmetic greater-than. - >= - Arithmetic greater-than-or-equal-to. - eq - Arithmetic equality. - = - String equality. - ne - Arithmetic inequality. - != - String inequality. - =~ - Wildcard match. - !~ - Wildcard mismatch. - ingroup - Group membership check. [*] - notingroup - Group non-membership check. [*] - - * The "ingroup" and "notingroup" operators should only be - used with the USER attribute. - - Examples: - - Deny authentication to all users except those in the wheel - group, before even asking for a password: - auth requisite pam_succeed_if.so user ingroup wheel - - Assume all users with UID less than 500 ("system users") have - valid accounts. - account sufficient pam_succeed_if.so uid < 500 - - Deny login to all nologin users. - auth requisite pam_succeed_if.so shell !~ nologin - -RECOGNIZED ARGUMENTS: - debug write debugging messages to syslog - use_uid perform checks on the account of the user under whose - UID the application is running instead of the user - being authenticated - quiet don't log failure or success to syslog - quiet_fail don't log failure to syslog - quiet_success don't log success to syslog - - -MODULE SERVICES PROVIDED: - authentication, account management - -AUTHOR: - Nalin Dahyabhai <nalin@redhat.com> diff --git a/modules/pam_succeed_if/pam_succeed_if.8 b/modules/pam_succeed_if/pam_succeed_if.8 deleted file mode 100644 index da95a033..00000000 --- a/modules/pam_succeed_if/pam_succeed_if.8 +++ /dev/null @@ -1,37 +0,0 @@ -.\" Copyright 2003, 2004 Red Hat, Inc. -.\" Written by Nalin Dahyabhai <nalin@redhat.com> -.TH pam_succeed_if 8 2004/12/27 "Linux-PAM" "System Administrator's Manual" - -.SH NAME -pam_succeed_if \- succeed or fail based on account characteristics - -.SH SYNOPSIS -.B account sufficient pam_succeed_if.so uid < 500 - -.SH DESCRIPTION -pam_succeed_if.so is designed to succeed or fail authentication based on -characteristics of the account belonging to the user being authenticated. - -The module can be given one or more conditions as module arguments, and -authentication will succeed only if all of the conditions are met. - -.SH ARGUMENTS -.IP debug -Turns on debugging messages sent to syslog. -.IP use_uid -Evaluate conditions using the account of the user whose UID the application -is running under instead of the user being authenticated. -.IP quiet -Don't log failure or success to the system log. -.IP quiet_fail -Don't log failure to the system log. -.IP quiet_success -Don't log success to the system log. - - -.SH BUGS -Let's hope not, but if you find any, please report them via the "Bug Track" -link at http://bugzilla.redhat.com/bugzilla/ - -.SH AUTHOR -Nalin Dahyabhai <nalin@redhat.com> diff --git a/modules/pam_succeed_if/pam_succeed_if.c b/modules/pam_succeed_if/pam_succeed_if.c deleted file mode 100644 index 23974afa..00000000 --- a/modules/pam_succeed_if/pam_succeed_if.c +++ /dev/null @@ -1,470 +0,0 @@ -/****************************************************************************** - * A simple user-attribute based module for PAM. - * - * Copyright (c) 2003 Red Hat, Inc. - * Written by Nalin Dahyabhai <nalin@redhat.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#define _GNU_SOURCE - -#include <sys/types.h> -#include <errno.h> -#include <fcntl.h> -#include <fnmatch.h> -#include <limits.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> -#include <pwd.h> -#include <grp.h> -#include <security/pam_modules.h> -#include <security/_pam_modutil.h> - -#define MODULE "pam_succeed_if" - -static void -log_error(int priority, const char *fmt, ...) -{ - va_list va; - char *fmt2; - fmt2 = malloc(strlen(fmt) + strlen(MODULE) + 3); - va_start(va, fmt); - if (fmt2 == NULL) { - vsyslog(LOG_AUTHPRIV | priority, fmt, va); - } else { - snprintf(fmt2, strlen(fmt) + strlen(MODULE) + 3, - "%s: %s", MODULE, fmt); - vsyslog(LOG_AUTHPRIV | priority, fmt2, va); - free(fmt2); - } - va_end(va); -} - -/* Basically, run cmp(atol(left), atol(right)), returning PAM_SUCCESS if - * the function returns non-zero, PAM_AUTH_ERR if it returns zero, and - * PAM_SYSTEM_ERR if the arguments can't be parsed as numbers. */ -static int -evaluate_num(const char *left, const char *right, int (*cmp)(int, int)) -{ - long l, r; - char *p; - int ret = PAM_SUCCESS; - - errno = 0; - l = strtol(left, &p, 0); - if ((p == NULL) || (*p != '\0') || errno) { - log_error(LOG_INFO, "\"%s\" is not a number", left); - ret = PAM_SERVICE_ERR; - } - - r = strtol(right, &p, 0); - if ((p == NULL) || (*p != '\0') || errno) { - log_error(LOG_INFO, "\"%s\" is not a number", right); - ret = PAM_SERVICE_ERR; - } - - if (ret != PAM_SUCCESS) { - return ret; - } - - return cmp(l, r) ? PAM_SUCCESS : PAM_AUTH_ERR; -} - -/* Simple numeric comparison callbacks. */ -static int -eq(int i, int j) -{ - return i == j; -} -static int -ne(int i, int j) -{ - return i != j; -} -static int -lt(int i, int j) -{ - return i < j; -} -static int -le(int i, int j) -{ - return lt(i, j) || eq(i, j); -} -static int -gt(int i, int j) -{ - return i > j; -} -static int -ge(int i, int j) -{ - return gt(i, j) || eq(i, j); -} - -/* Test for numeric equality. */ -static int -evaluate_eqn(const char *left, const char *right) -{ - return evaluate_num(left, right, eq); -} -/* Test for string equality. */ -static int -evaluate_eqs(const char *left, const char *right) -{ - return (strcmp(left, right) == 0) ? PAM_SUCCESS : PAM_AUTH_ERR; -} -/* Test for numeric inequality. */ -static int -evaluate_nen(const char *left, const char *right) -{ - return evaluate_num(left, right, ne); -} -/* Test for string inequality. */ -static int -evaluate_nes(const char *left, const char *right) -{ - return (strcmp(left, right) != 0) ? PAM_SUCCESS : PAM_AUTH_ERR; -} -/* Test for numeric less-than-ness(?) */ -static int -evaluate_lt(const char *left, const char *right) -{ - return evaluate_num(left, right, lt); -} -/* Test for numeric less-than-or-equal-ness(?) */ -static int -evaluate_le(const char *left, const char *right) -{ - return evaluate_num(left, right, le); -} -/* Test for numeric greater-than-ness(?) */ -static int -evaluate_gt(const char *left, const char *right) -{ - return evaluate_num(left, right, gt); -} -/* Test for numeric greater-than-or-equal-ness(?) */ -static int -evaluate_ge(const char *left, const char *right) -{ - return evaluate_num(left, right, ge); -} -/* Check for file glob match. */ -static int -evaluate_glob(const char *left, const char *right) -{ - return (fnmatch(right, left, 0) == 0) ? PAM_SUCCESS : PAM_AUTH_ERR; -} -/* Check for file glob mismatch. */ -static int -evaluate_noglob(const char *left, const char *right) -{ - return (fnmatch(right, left, 0) != 0) ? PAM_SUCCESS : PAM_AUTH_ERR; -} -/* Return PAM_SUCCESS if the user is in the group. */ -static int -evaluate_ingroup(pam_handle_t *pamh, const char *user, const char *group) -{ - int ret; - ret = _pammodutil_user_in_group_nam_nam(pamh, user, group); - switch (ret) { - case 1: - return PAM_SUCCESS; - break; - default: - break; - } - return PAM_AUTH_ERR; -} -/* Return PAM_SUCCESS if the user is NOT in the group. */ -static int -evaluate_notingroup(pam_handle_t *pamh, const char *user, const char *group) -{ - int ret; - ret = _pammodutil_user_in_group_nam_nam(pamh, user, group); - switch (ret) { - case 0: - return PAM_SUCCESS; - break; - default: - break; - } - return PAM_AUTH_ERR; -} - -/* Match a triple. */ -static int -evaluate(pam_handle_t *pamh, int debug, - const char *left, const char *qual, const char *right, - struct passwd *pwd) -{ - char buf[LINE_MAX] = ""; - const char *attribute = left; - /* Figure out what we're evaluating here, and convert it to a string.*/ - if ((strcasecmp(left, "login") == 0) || - (strcasecmp(left, "name") == 0) || - (strcasecmp(left, "user") == 0)) { - snprintf(buf, sizeof(buf), "%s", pwd->pw_name); - left = buf; - } - if (strcasecmp(left, "uid") == 0) { - snprintf(buf, sizeof(buf), "%lu", (unsigned long) pwd->pw_uid); - left = buf; - } - if (strcasecmp(left, "gid") == 0) { - snprintf(buf, sizeof(buf), "%lu", (unsigned long) pwd->pw_gid); - left = buf; - } - if (strcasecmp(left, "shell") == 0) { - snprintf(buf, sizeof(buf), "%s", pwd->pw_shell); - left = buf; - } - if ((strcasecmp(left, "home") == 0) || - (strcasecmp(left, "dir") == 0) || - (strcasecmp(left, "homedir") == 0)) { - snprintf(buf, sizeof(buf), "%s", pwd->pw_dir); - left = buf; - } - /* If we have no idea what's going on, return an error. */ - if (left != buf) { - log_error(LOG_CRIT, "unknown attribute \"%s\"", left); - return PAM_SERVICE_ERR; - } - if (debug) { - log_error(LOG_DEBUG, "'%s' resolves to '%s'", attribute, left); - } - - /* Attribute value < some threshold. */ - if ((strcasecmp(qual, "<") == 0) || - (strcasecmp(qual, "lt") == 0)) { - return evaluate_lt(left, right); - } - /* Attribute value <= some threshold. */ - if ((strcasecmp(qual, "<=") == 0) || - (strcasecmp(qual, "le") == 0)) { - return evaluate_le(left, right); - } - /* Attribute value > some threshold. */ - if ((strcasecmp(qual, ">") == 0) || - (strcasecmp(qual, "gt") == 0)) { - return evaluate_gt(left, right); - } - /* Attribute value >= some threshold. */ - if ((strcasecmp(qual, ">=") == 0) || - (strcasecmp(qual, "ge") == 0)) { - return evaluate_ge(left, right); - } - /* Attribute value == some threshold. */ - if (strcasecmp(qual, "eq") == 0) { - return evaluate_eqn(left, right); - } - /* Attribute value = some string. */ - if (strcasecmp(qual, "=") == 0) { - return evaluate_eqs(left, right); - } - /* Attribute value != some threshold. */ - if (strcasecmp(qual, "ne") == 0) { - return evaluate_nen(left, right); - } - /* Attribute value != some string. */ - if (strcasecmp(qual, "!=") == 0) { - return evaluate_nes(left, right); - } - /* Attribute value matches some pattern. */ - if ((strcasecmp(qual, "=~") == 0) || - (strcasecmp(qual, "glob") == 0)) { - return evaluate_glob(left, right); - } - if ((strcasecmp(qual, "!~") == 0) || - (strcasecmp(qual, "noglob") == 0)) { - return evaluate_noglob(left, right); - } - /* User is in this group. */ - if (strcasecmp(qual, "ingroup") == 0) { - return evaluate_ingroup(pamh, pwd->pw_name, right); - } - /* User is not in this group. */ - if (strcasecmp(qual, "notingroup") == 0) { - return evaluate_notingroup(pamh, pwd->pw_name, right); - } - /* Fail closed. */ - return PAM_SERVICE_ERR; -} - -int -pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - const char *prompt; - const char *user; - struct passwd *pwd; - int ret, i, count, use_uid, debug; - const char *left, *right, *qual; - int quiet_fail, quiet_succ; - - /* Get the user prompt. */ - ret = pam_get_item(pamh, PAM_USER_PROMPT, (const void**) &prompt); - if ((ret != PAM_SUCCESS) || (prompt == NULL) || (strlen(prompt) == 0)) { - prompt = "login: "; - } - - quiet_fail = 0; - quiet_succ = 0; - for (use_uid = 0, debug = 0, i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) { - debug++; - } - if (strcmp(argv[i], "use_uid") == 0) { - use_uid++; - } - if (strcmp(argv[i], "quiet") == 0) { - quiet_fail++; - quiet_succ++; - } - if (strcmp(argv[i], "quiet_fail") == 0) { - quiet_fail++; - } - if (strcmp(argv[i], "quiet_success") == 0) { - quiet_succ++; - } - } - - if (use_uid) { - /* Get information about the user. */ - pwd = _pammodutil_getpwuid(pamh, getuid()); - if (pwd == NULL) { - log_error(LOG_CRIT, - "error retrieving information about user %ld", - (long)getuid()); - return PAM_SERVICE_ERR; - } - } else { - /* Get the user's name. */ - ret = pam_get_user(pamh, &user, prompt); - if ((ret != PAM_SUCCESS) || (user == NULL)) { - log_error(LOG_CRIT, "error retrieving user name: %s", - pam_strerror(pamh, ret)); - return ret; - } - - /* Get information about the user. */ - pwd = _pammodutil_getpwnam(pamh, user); - if (pwd == NULL) { - log_error(LOG_CRIT, - "error retrieving information about user %s", - user); - return PAM_SERVICE_ERR; - } - } - - /* Walk the argument list. */ - i = count = 0; - left = qual = right = NULL; - while (i <= argc) { - if ((left != NULL) && (qual != NULL) && (right != NULL)) { - ret = evaluate(pamh, debug, - left, qual, right, - pwd); - if (ret != PAM_SUCCESS) { - if(!quiet_fail) - log_error(LOG_INFO, - "requirement \"%s %s %s\" " - "not met by user \"%s\"", - left, qual, right, user); - break; - } - else - if(!quiet_succ) - log_error(LOG_INFO, - "requirement \"%s %s %s\" " - "was met by user \"%s\"", - left, qual, right, user); - left = qual = right = NULL; - } - if ((i < argc) && (strcmp(argv[i], "debug") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "use_uid") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "quiet") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "quiet_fail") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "quiet_success") == 0)) { - i++; - continue; - } - if ((i < argc) && (left == NULL)) { - left = argv[i++]; - count++; - continue; - } - if ((i < argc) && (qual == NULL)) { - qual = argv[i++]; - count++; - continue; - } - if ((i < argc) && (right == NULL)) { - right = argv[i++]; - count++; - continue; - } - i++; - } - - return ret; -} - -int -pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return PAM_SUCCESS; -} - -int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} diff --git a/modules/pam_tally/.cvsignore b/modules/pam_tally/.cvsignore deleted file mode 100644 index e1a4f48f..00000000 --- a/modules/pam_tally/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -dynamic -pam_tally diff --git a/modules/pam_tally/Makefile b/modules/pam_tally/Makefile deleted file mode 100644 index 718d3b30..00000000 --- a/modules/pam_tally/Makefile +++ /dev/null @@ -1,109 +0,0 @@ -# -# $Id$ -# -# This Makefile controls a build process of $(TITLE) module and -# application for Linux-PAM. You should not modify this Makefile -# (unless you know what you are doing!). -# -# - -include ../../Make.Rules - -TITLE=pam_tally - -# -## Additional rules for making (and moving) the application added. -## Assuming that all modules' applications are called $TITLE -# - -LIBSRC = $(TITLE).c -LIBOBJ = $(TITLE).o -LIBOBJD = $(addprefix dynamic/,$(LIBOBJ)) -LIBOBJS = $(addprefix static/,$(LIBOBJ)) - -APPSRC = $(TITLE)_app.c -APPOBJ = $(TITLE)_app.o -APPOBJD = $(addprefix dynamic/,$(APPOBJ)) -APPOBJS = $(addprefix static/,$(APPOBJ)) - -dynamic/%.o : %.c - $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ - -static/%.o : %.c - $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ - - -ifdef DYNAMIC -LIBSHARED = $(TITLE).so -endif - -ifdef STATIC -LIBSTATIC = lib$(TITLE).o -endif - -APPLICATION = $(TITLE) -APPMODE = 755 - -LINK_PAMMODUTILS = -L../pammodutil -lpammodutil -L../../libpam -lpam -INCLUDE_PAMMODUTILS = -I../pammodutil/include - -LDFLAGS += $(LINK_PAMMODUTILS) -CFLAGS += $(INCLUDE_PAMMODUTILS) - -####################### don't edit below ####################### - -all: dirs $(LIBSHARED) $(LIBSTATIC) register $(APPLICATION) - -dirs: -ifdef DYNAMIC - $(MKDIR) ./dynamic -endif -ifdef STATIC - $(MKDIR) ./static -endif - -register: -ifdef STATIC - ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) ) -endif - -ifdef DYNAMIC -$(LIBOBJD): $(LIBSRC) - -$(LIBSHARED): $(LIBOBJD) - $(LD_D) -o $@ $(LIBOBJD) $(LDFLAGS) - -$(APPLICATION): $(APPOBJD) $(TITLE).c - $(CC) $(CFLAGS) -o $@ $(APPOBJD) $(LDFLAGS) $(LOADLIBES) - -endif - -ifdef STATIC -$(LIBOBJS): $(LIBSRC) - -$(LIBSTATIC): $(LIBOBJS) - $(LD) -r -o $@ $(LIBOBJS) - -$(APPLICATION): $(APPOBJS) $(TITLE).c - $(CC) $(CFLAGS) -o $@ $(APPOBJS) $(LOADLIBES) -endif - -install: all - $(MKDIR) $(FAKEROOT)$(SECUREDIR) -ifdef DYNAMIC - $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR) -endif - $(MKDIR) $(FAKEROOT)$(SUPLEMENTED) - $(INSTALL) -m $(APPMODE) $(APPLICATION) $(FAKEROOT)$(SUPLEMENTED) - -remove: - rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so - rm -f $(FAKEROOT)$(SUPLEMENTED)/$(TITLE) - -clean: - rm -f $(LIBOBJD) $(LIBOBJS) $(APPOBJD) $(APPOBJS) core *~ - rm -f *.a *.o *.so *.bak dynamic/* static/* $(APPLICATION) - rm -rf dynamic static - -.c.o: - $(CC) $(CFLAGS) -c $< diff --git a/modules/pam_tally/README b/modules/pam_tally/README deleted file mode 100644 index c8b715bd..00000000 --- a/modules/pam_tally/README +++ /dev/null @@ -1,116 +0,0 @@ -SUMMARY: - pam_tally.so: - - Maintains a count of attempted accesses, can reset count on success, - can deny access if too many attempts fail. - - Options: - - * onerr=[succeed|fail] (if something weird happens - such as unable to open the file, what to do?) - * file=/where/to/keep/counts (default /var/log/faillog) - * audit (will display the username typed if the user is not found) - - (auth) - Authentication phase first checks if user should be denied access - and if not it increments attempted login counter. Then on call to - pam_setcred it resets the attempts counter if the user is NOT - magic root. - * deny=n (deny access if tally for this user exceeds n) - - * lock_time=n (always deny for n seconds after failed attempt) - - * unlock_time=n (allow access after n seconds after the last - failed attempt with exceeded tally) - - * magic_root (access attempts by root as requesting user ignore - deny and don't change counter. - Use this for su and similar services.) - - * even_deny_root_account (Root can become unavailable. BEWARE. - Note that magic root trying to gain root bypasses this, - but normal users can be locked out.) - - * per_user (If /var/log/faillog contains a non-zero - .fail_max/.fail_locktime field for this user then use it - instead of deny=n/lock_time=n parameter.) - - * no_lock_time (Don't use .fail_locktime filed in - /var/log/faillog for this user) - - * no_reset (don't reset count on successful entry, - only decrement) - - - (account) - Account phase resets attempts counter if the user is NOT magic root. - This phase can be used optionaly for services which don't call - pam_setcred correctly or if the reset should be done regardless - of the failure of the account phase of other modules. - - * magic_root (access attempts by root as requesting user - don't change counter. - Use this for su and similar services.) - - * no_reset (don't reset count on successful entry, - only decrement) - - Also checks to make sure that the counts file is a plain - file and not world writable. - - - Tim Baverstock <warwick@sable.demon.co.uk>, v0.1 5 March 1997 - - Tomas Mraz <tmraz@redhat.com>, v0.2 5 January 2005 - -LONGER: - -pam_tally comes in two parts: pam_tally.so and pam_tally. - -pam_tally.so sits in a pam config file, in the auth and account sections. - -In the auth section, it denies access if attempted logins exceed some -threshold and it increments a per-uid counter for each attempted login, -in the account section, it resets that counter to zero on successful -login. If the module isn't used in the account section it resets the counter -to zero on call to pam_setcred. - -Root is treated specially: - -1. When a process already running as root tries to access some service and the -'magic_root' flag is set, the access is `magic', and bypasses pam_tally's -checks: handy for `su'ing from root into an account otherwise blocked. -NOTE: This was changed from the previous version of pam_tally where the default -was to treat root as magic and there were the 'no_magic_root' flag. However -for most of services the current default make sense. - -2. Normally, failed attempts to access root will NOT cause the root -account to become blocked, to prevent denial-of-service: if your users aren't -given shell accounts and root may only login via `su' or at the machine -console (not telnet/rsh, etc), this is safe. If you really want root to be -blocked for some given service, use even_deny_root_account. - -pam_tally is an (optional) application which can be used to interrogate and -manipulate the counter file. It can display users' counts, set individual -counts, or clear all counts. Setting artificially high counts may be useful -for blocking users without changing their passwords. I found it useful to -clear all counts every midnight from a cron.. - -The counts file is organised as a binary-word array, indexed by uid. You -can probably make sense of it with `od', if you don't want to use the -supplied application. - -BUGS: - -pam_tally is very dependant on getpw*(): a database of usernames -would be much more flexible. - -The (4.0 Redhat) utilities seem to do funny things with uid, and I'm -not wholly sure I understood what I should have been doing anyway so -the `keep a count of current logins' bit has been #ifdef'd out and you -can only reset the counter on successful authentication, for now. - -IMPORTANT NOTICE: -In the original version of pam_tally there was a bug where the information -if the password was correct or not was leaked by returning error from -different pam management phases. This was solved by moving the denying -functionality to the auth phase. However it's necessary to update the pam -configuration by moving the required options (as deny=N) to the auth phase. diff --git a/modules/pam_tally/faillog.h b/modules/pam_tally/faillog.h deleted file mode 100644 index 7f704713..00000000 --- a/modules/pam_tally/faillog.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 1989 - 1994, Julianne Frances Haugh - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Julianne F. Haugh nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * faillog.h - login failure logging file format - * - * $Id$ - * - * The login failure file is maintained by login(1) and faillog(8) - * Each record in the file represents a separate UID and the file - * is indexed in that fashion. - */ - -#ifndef _FAILLOG_H -#define _FAILLOG_H - -struct faillog { - short fail_cnt; /* failures since last success */ - short fail_max; /* failures before turning account off */ - char fail_line[12]; /* last failure occured here */ - time_t fail_time; /* last failure occured then */ - /* - * If nonzero, the account will be re-enabled if there are no - * failures for fail_locktime seconds since last failure. - */ - long fail_locktime; -}; - -#endif diff --git a/modules/pam_tally/pam_tally.c b/modules/pam_tally/pam_tally.c deleted file mode 100644 index 57fa611a..00000000 --- a/modules/pam_tally/pam_tally.c +++ /dev/null @@ -1,840 +0,0 @@ -/* - * pam_tally.c - * - * $Id$ - */ - - -/* By Tim Baverstock <warwick@mmm.co.uk>, Multi Media Machine Ltd. - * 5 March 1997 - * - * Stuff stolen from pam_rootok and pam_listfile - * - * Changes by Tomas Mraz <tmraz@redhat.com> 5 January 2005 - * Audit option added for Tomas patch by Sebastien Tricaud <toady@gscore.org> 13 January 2005 - */ - -#include <security/_pam_aconf.h> - -#if defined(MAIN) && defined(MEMORY_DEBUG) -# undef exit -#endif /* defined(MAIN) && defined(MEMORY_DEBUG) */ - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <stdlib.h> -#include <syslog.h> -#include <pwd.h> -#include <time.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include "faillog.h" - -#ifndef TRUE -#define TRUE 1L -#define FALSE 0L -#endif - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -/* #define PAM_SM_SESSION */ -/* #define PAM_SM_PASSWORD */ - -#include <security/pam_modules.h> -#include <security/_pam_modutil.h> - -/*---------------------------------------------------------------------*/ - -#define DEFAULT_LOGFILE "/var/log/faillog" -#define MODULE_NAME "pam_tally" - -#define tally_t unsigned short int -#define TALLY_FMT "%hu" -#define TALLY_HI ((tally_t)~0L) - -#define UID_FMT "%hu" - -#ifndef FILENAME_MAX -# define FILENAME_MAX MAXPATHLEN -#endif - -struct fail_s { - struct faillog fs_faillog; -#ifndef MAIN - time_t fs_fail_time; -#endif /* ndef MAIN */ -}; - -struct tally_options { - const char *filename; - tally_t deny; - long lock_time; - long unlock_time; - unsigned int ctrl; -}; - -#define PHASE_UNKNOWN 0 -#define PHASE_AUTH 1 -#define PHASE_ACCOUNT 2 -#define PHASE_SESSION 3 - -#define OPT_MAGIC_ROOT 01 -#define OPT_FAIL_ON_ERROR 02 -#define OPT_DENY_ROOT 04 -#define OPT_PER_USER 010 -#define OPT_NO_LOCK_TIME 020 -#define OPT_NO_RESET 040 -#define OPT_AUDIT 100 - - -/*---------------------------------------------------------------------*/ - -/* some syslogging */ - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - va_start(args, format); - -#ifdef MAIN - vfprintf(stderr,format,args); - fprintf(stderr,"\n"); -#else - openlog(MODULE_NAME, LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - closelog(); -#endif - va_end(args); -} - -/*---------------------------------------------------------------------*/ - -/* --- Support function: parse arguments --- */ - -static void log_phase_no_auth( int phase, const char *argv ) -{ - if ( phase != PHASE_AUTH ) { - _pam_log(LOG_ERR, - MODULE_NAME ": option %s allowed in auth phase only", argv); - } -} - -static int tally_parse_args( struct tally_options *opts, int phase, - int argc, const char **argv ) -{ - memset(opts, 0, sizeof(*opts)); - opts->filename = DEFAULT_LOGFILE; - - for ( ; argc-- > 0; ++argv ) { - - if ( ! strncmp( *argv, "file=", 5 ) ) { - const char *from = *argv + 5; - if ( *from!='/' || strlen(from)>FILENAME_MAX-1 ) { - _pam_log(LOG_ERR, - MODULE_NAME ": filename not /rooted or too long; ", - *argv); - return PAM_AUTH_ERR; - } - opts->filename = from; - } - else if ( ! strcmp( *argv, "onerr=fail" ) ) { - opts->ctrl |= OPT_FAIL_ON_ERROR; - } - else if ( ! strcmp( *argv, "onerr=succeed" ) ) { - opts->ctrl &= ~OPT_FAIL_ON_ERROR; - } - else if ( ! strcmp( *argv, "magic_root" ) ) { - opts->ctrl |= OPT_MAGIC_ROOT; - } - else if ( ! strcmp( *argv, "even_deny_root_account" ) ) { - log_phase_no_auth(phase, *argv); - opts->ctrl |= OPT_DENY_ROOT; - } - else if ( ! strncmp( *argv, "deny=", 5 ) ) { - log_phase_no_auth(phase, *argv); - if ( sscanf((*argv)+5,TALLY_FMT,&opts->deny) != 1 ) { - _pam_log(LOG_ERR,"bad number supplied; %s",*argv); - return PAM_AUTH_ERR; - } - } - else if ( ! strncmp( *argv, "lock_time=", 10 ) ) { - log_phase_no_auth(phase, *argv); - if ( sscanf((*argv)+10,"%ld",&opts->lock_time) != 1 ) { - _pam_log(LOG_ERR,"bad number supplied; %s",*argv); - return PAM_AUTH_ERR; - } - } - else if ( ! strncmp( *argv, "unlock_time=", 12 ) ) { - log_phase_no_auth(phase, *argv); - if ( sscanf((*argv)+12,"%ld",&opts->unlock_time) != 1 ) { - _pam_log(LOG_ERR,"bad number supplied; %s",*argv); - return PAM_AUTH_ERR; - } - } - else if ( ! strcmp( *argv, "per_user" ) ) - { - log_phase_no_auth(phase, *argv); - opts->ctrl |= OPT_PER_USER; - } - else if ( ! strcmp( *argv, "no_lock_time") ) - { - log_phase_no_auth(phase, *argv); - opts->ctrl |= OPT_NO_LOCK_TIME; - } - else if ( ! strcmp( *argv, "no_reset" ) ) { - opts->ctrl |= OPT_NO_RESET; - } - else if ( ! strcmp ( *argv, "audit") ) { - opts->ctrl |= OPT_AUDIT; - } - else { - _pam_log(LOG_ERR, MODULE_NAME ": unknown option; %s",*argv); - } - } - - return PAM_SUCCESS; -} - -/*---------------------------------------------------------------------*/ - -/* --- Support function: get uid (and optionally username) from PAM or - cline_user --- */ - -#ifdef MAIN -static char *cline_user=0; /* cline_user is used in the administration prog */ -#endif - -static int pam_get_uid( pam_handle_t *pamh, uid_t *uid, const char **userp, struct tally_options *opts) - { - const char *user = NULL; - struct passwd *pw; - -#ifdef MAIN - user = cline_user; -#else - pam_get_user( pamh, &user, NULL ); -#endif - - if ( !user || !*user ) { - _pam_log(LOG_ERR, MODULE_NAME ": pam_get_uid; user?"); - return PAM_AUTH_ERR; - } - - if ( ! ( pw = _pammodutil_getpwnam( pamh, user ) ) ) { - opts->ctrl & OPT_AUDIT ? - _pam_log(LOG_ERR,MODULE_NAME ": pam_get_uid; no such user %s",user) : - _pam_log(LOG_ERR,MODULE_NAME ": pam_get_uid; no such user"); - return PAM_USER_UNKNOWN; - } - - if ( uid ) *uid = pw->pw_uid; - if ( userp ) *userp = user; - return PAM_SUCCESS; - } - -/*---------------------------------------------------------------------*/ - -/* --- Support functions: set/get tally data --- */ - -static void _cleanup( pam_handle_t *pamh, void *data, int error_status ) - { - free(data); - } - -static void tally_set_data( pam_handle_t *pamh, time_t oldtime ) - { - time_t *data; - - if ( (data=malloc(sizeof(time_t))) != NULL ) { - *data = oldtime; - pam_set_data(pamh, MODULE_NAME, (void *)data, _cleanup); - } - } - -static int tally_get_data( pam_handle_t *pamh, time_t *oldtime ) - { - int rv; - const void *data; - - rv = pam_get_data(pamh, MODULE_NAME, &data); - if ( rv == PAM_SUCCESS && oldtime != NULL ) { - *oldtime = *(const time_t *)data; - pam_set_data(pamh, MODULE_NAME, NULL, NULL); - } - else { - rv = -1; - *oldtime = 0; - } - return rv; - } - -/*---------------------------------------------------------------------*/ - -/* --- Support function: open/create tallyfile and return tally for uid --- */ - -/* If on entry *tally==TALLY_HI, tallyfile is opened READONLY */ -/* Otherwise, if on entry tallyfile doesn't exist, creation is attempted. */ - -static int get_tally( tally_t *tally, - uid_t uid, - const char *filename, - FILE **TALLY, - struct fail_s *fsp) - { - struct stat fileinfo; - int lstat_ret = lstat(filename,&fileinfo); - - if ( lstat_ret && *tally!=TALLY_HI ) { - int oldmask = umask(077); - *TALLY=fopen(filename, "a"); - /* Create file, or append-open in pathological case. */ - umask(oldmask); - if ( !*TALLY ) { - _pam_log(LOG_ALERT, "Couldn't create %s",filename); - return PAM_AUTH_ERR; - } - lstat_ret = fstat(fileno(*TALLY),&fileinfo); - fclose(*TALLY); - } - - if ( lstat_ret ) { - _pam_log(LOG_ALERT, "Couldn't stat %s",filename); - return PAM_AUTH_ERR; - } - - if((fileinfo.st_mode & S_IWOTH) || !S_ISREG(fileinfo.st_mode)) { - /* If the file is world writable or is not a - normal file, return error */ - _pam_log(LOG_ALERT, - "%s is either world writable or not a normal file", - filename); - return PAM_AUTH_ERR; - } - - if ( ! ( *TALLY = fopen(filename,(*tally!=TALLY_HI)?"r+":"r") ) ) { - _pam_log(LOG_ALERT, "Error opening %s for update", filename); - -/* Discovering why account service fails: e/uid are target user. - * - * perror(MODULE_NAME); - * fprintf(stderr,"uid %d euid %d\n",getuid(), geteuid()); - */ - return PAM_AUTH_ERR; - } - - if ( fseek( *TALLY, uid * sizeof(struct faillog), SEEK_SET ) ) { - _pam_log(LOG_ALERT, "fseek failed %s", filename); - fclose(*TALLY); - return PAM_AUTH_ERR; - } - - if ( fileinfo.st_size <= uid * sizeof(struct faillog) ) { - - memset(fsp, 0, sizeof(struct faillog)); - *tally=0; - fsp->fs_faillog.fail_time = time(NULL); - - } else if (( fread((char *) &fsp->fs_faillog, - sizeof(struct faillog), 1, *TALLY) )==0 ) { - - *tally=0; /* Assuming a gappy filesystem */ - - } else { - - *tally = fsp->fs_faillog.fail_cnt; - - } - - return PAM_SUCCESS; - } - -/*---------------------------------------------------------------------*/ - -/* --- Support function: update and close tallyfile with tally!=TALLY_HI --- */ - -static int set_tally( tally_t tally, - uid_t uid, - const char *filename, - FILE **TALLY, - struct fail_s *fsp) - { - if ( tally!=TALLY_HI ) - { - if ( fseek( *TALLY, uid * sizeof(struct faillog), SEEK_SET ) ) { - _pam_log(LOG_ALERT, "fseek failed %s", filename); - return PAM_AUTH_ERR; - } - fsp->fs_faillog.fail_cnt = tally; - if (fwrite((char *) &fsp->fs_faillog, - sizeof(struct faillog), 1, *TALLY)==0 ) { - _pam_log(LOG_ALERT, "tally update (fwrite) failed.", filename); - return PAM_AUTH_ERR; - } - } - - if ( fclose(*TALLY) ) { - _pam_log(LOG_ALERT, "tally update (fclose) failed.", filename); - return PAM_AUTH_ERR; - } - *TALLY=NULL; - return PAM_SUCCESS; - } - -/*---------------------------------------------------------------------*/ - -/* --- PAM bits --- */ - -#ifndef MAIN - -#define PAM_FUNCTION(name) \ - PAM_EXTERN int name (pam_handle_t *pamh,int flags,int argc,const char **argv) - -#define RETURN_ERROR(i) return ((opts->ctrl & OPT_FAIL_ON_ERROR)?(i):(PAM_SUCCESS)) - -/*---------------------------------------------------------------------*/ - -/* --- tally bump function: bump tally for uid by (signed) inc --- */ - -static int tally_bump (int inc, time_t *oldtime, - pam_handle_t *pamh, - uid_t uid, - const char *user, - struct tally_options *opts) { - tally_t - tally = 0; /* !TALLY_HI --> Log opened for update */ - - FILE - *TALLY = NULL; - const char - *remote_host = NULL, - *cur_tty = NULL; - struct fail_s fs, *fsp = &fs; - int i; - - i=get_tally( &tally, uid, opts->filename, &TALLY, fsp ); - - /* to remember old fail time (for locktime) */ - fsp->fs_fail_time = fsp->fs_faillog.fail_time; - if ( inc > 0 ) { - if ( oldtime ) { - *oldtime = fsp->fs_faillog.fail_time; - } - fsp->fs_faillog.fail_time = time(NULL); - } else { - if ( oldtime ) { - fsp->fs_faillog.fail_time = *oldtime; - } - } - (void) pam_get_item(pamh, PAM_RHOST, (const void **)&remote_host); - if (!remote_host) { - - (void) pam_get_item(pamh, PAM_TTY, (const void **)&cur_tty); - if (!cur_tty) { - strncpy(fsp->fs_faillog.fail_line, "unknown", - sizeof(fsp->fs_faillog.fail_line) - 1); - fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0; - } else { - strncpy(fsp->fs_faillog.fail_line, cur_tty, - sizeof(fsp->fs_faillog.fail_line)-1); - fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0; - } - - } else { - strncpy(fsp->fs_faillog.fail_line, remote_host, - (size_t)sizeof(fsp->fs_faillog.fail_line)); - fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0; - } - if ( i != PAM_SUCCESS ) { if (TALLY) fclose(TALLY); RETURN_ERROR( i ); } - - if ( !(opts->ctrl & OPT_MAGIC_ROOT) || getuid() ) { /* magic_root doesn't change tally */ - - tally+=inc; - - if ( tally==TALLY_HI ) { /* Overflow *and* underflow. :) */ - tally-=inc; - _pam_log(LOG_ALERT,"Tally %sflowed for user %s", - (inc<0)?"under":"over",user); - } - } - - i=set_tally( tally, uid, opts->filename, &TALLY, fsp ); - if ( i != PAM_SUCCESS ) { if (TALLY) fclose(TALLY); RETURN_ERROR( i ); } - - return PAM_SUCCESS; -} - -static int tally_check (time_t oldtime, - pam_handle_t *pamh, - uid_t uid, - const char *user, - struct tally_options *opts) { - tally_t - deny = opts->deny; - tally_t - tally = 0; /* !TALLY_HI --> Log opened for update */ - long - lock_time = opts->lock_time; - - struct fail_s fs, *fsp = &fs; - FILE *TALLY=0; - int i; - - i=get_tally( &tally, uid, opts->filename, &TALLY, fsp ); - if (TALLY) fclose(TALLY); - if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); } - - if ( !(opts->ctrl & OPT_MAGIC_ROOT) || getuid() ) { /* magic_root skips tally check */ - - /* To deny or not to deny; that is the question */ - - /* if there's .fail_max entry and per_user=TRUE then deny=.fail_max */ - - if ( (fsp->fs_faillog.fail_max) && (opts->ctrl & OPT_PER_USER) ) { - deny = fsp->fs_faillog.fail_max; - } - if ( (fsp->fs_faillog.fail_locktime) && (opts->ctrl & OPT_PER_USER) ) { - lock_time = fsp->fs_faillog.fail_locktime; - } - if (lock_time && oldtime - && !(opts->ctrl & OPT_NO_LOCK_TIME) ) - { - if ( lock_time + oldtime > time(NULL) ) - { - _pam_log(LOG_NOTICE, - "user %s ("UID_FMT") has time limit [%lds left]" - " since last failure.", - user,uid, - oldtime+lock_time - -time(NULL)); - return PAM_AUTH_ERR; - } - } - if (opts->unlock_time && oldtime) - { - if ( opts->unlock_time + oldtime <= time(NULL) ) - { /* ignore deny check after unlock_time elapsed */ - return PAM_SUCCESS; - } - } - if ( - ( deny != 0 ) && /* deny==0 means no deny */ - ( tally > deny ) && /* tally>deny means exceeded */ - ( ((opts->ctrl & OPT_DENY_ROOT) || uid) ) /* even_deny stops uid check */ - ) { - _pam_log(LOG_NOTICE,"user %s ("UID_FMT") tally "TALLY_FMT", deny "TALLY_FMT, - user, uid, tally, deny); - return PAM_AUTH_ERR; /* Only unconditional failure */ - } - } - - return PAM_SUCCESS; -} - -static int tally_reset (pam_handle_t *pamh, - uid_t uid, - const char *user, - struct tally_options *opts) { - tally_t - tally = 0; /* !TALLY_HI --> Log opened for update */ - - struct fail_s fs, *fsp = &fs; - FILE *TALLY=0; - int i; - - i=get_tally( &tally, uid, opts->filename, &TALLY, fsp ); - if ( i != PAM_SUCCESS ) { if (TALLY) fclose(TALLY); RETURN_ERROR( i ); } - - /* resets if not magic root - */ - - if ( (!(opts->ctrl & OPT_MAGIC_ROOT) || getuid()) - && !(opts->ctrl & OPT_NO_RESET) ) - { tally=0; } - - if (tally == 0) - { - fsp->fs_faillog.fail_time = (time_t) 0; - strcpy(fsp->fs_faillog.fail_line, ""); - } - - i=set_tally( tally, uid, opts->filename, &TALLY, fsp ); - if ( i != PAM_SUCCESS ) { if (TALLY) fclose(TALLY); RETURN_ERROR( i ); } - - return PAM_SUCCESS; -} - -/*---------------------------------------------------------------------*/ - -/* --- authentication management functions (only) --- */ - -#ifdef PAM_SM_AUTH - -PAM_FUNCTION( pam_sm_authenticate ) { - int - rvcheck, rvbump; - time_t - oldtime = 0; - struct tally_options - options, *opts = &options; - uid_t - uid; - const char - *user; - - rvcheck = tally_parse_args(opts, PHASE_AUTH, argc, argv); - if ( rvcheck != PAM_SUCCESS ) - RETURN_ERROR( rvcheck ); - - rvcheck = pam_get_uid(pamh, &uid, &user, opts); - if ( rvcheck != PAM_SUCCESS ) - RETURN_ERROR( rvcheck ); - - rvbump = tally_bump(1, &oldtime, pamh, uid, user, opts); - rvcheck = tally_check(oldtime, pamh, uid, user, opts); - - tally_set_data(pamh, oldtime); - - return rvcheck != PAM_SUCCESS ? rvcheck : rvbump; -} - -PAM_FUNCTION( pam_sm_setcred ) { - int - rv; - time_t - oldtime = 0; - struct tally_options - options, *opts = &options; - uid_t - uid; - const char - *user; - - rv = tally_parse_args(opts, PHASE_AUTH, argc, argv); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - rv = pam_get_uid(pamh, &uid, &user, opts); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - if ( tally_get_data(pamh, &oldtime) != 0 ) - /* no data found */ - return PAM_SUCCESS; - - if ( (rv=tally_bump(-1, &oldtime, pamh, uid, user, opts)) != PAM_SUCCESS ) - return rv; - return tally_reset(pamh, uid, user, opts); -} - -#endif - -/*---------------------------------------------------------------------*/ - -/* --- authentication management functions (only) --- */ - -#ifdef PAM_SM_ACCOUNT - -/* To reset failcount of user on successfull login */ - -PAM_FUNCTION( pam_sm_acct_mgmt ) { - int - rv; - time_t - oldtime = 0; - struct tally_options - options, *opts = &options; - uid_t - uid; - const char - *user; - - rv = tally_parse_args(opts, PHASE_ACCOUNT, argc, argv); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - rv = pam_get_uid(pamh, &uid, &user, opts); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - if ( tally_get_data(pamh, &oldtime) != 0 ) - /* no data found */ - return PAM_SUCCESS; - - if ( (rv=tally_bump(-1, &oldtime, pamh, uid, user, opts)) != PAM_SUCCESS ) - return rv; - return tally_reset(pamh, uid, user, opts); -} - -#endif /* #ifdef PAM_SM_ACCOUNT */ - -/*-----------------------------------------------------------------------*/ - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_tally_modstruct = { - MODULE_NAME, -#ifdef PAM_SM_AUTH - pam_sm_authenticate, - pam_sm_setcred, -#else - NULL, - NULL, -#endif -#ifdef PAM_SM_ACCOUNT - pam_sm_acct_mgmt, -#else - NULL, -#endif - NULL, - NULL, - NULL, -}; - -#endif /* #ifdef PAM_STATIC */ - -/*-----------------------------------------------------------------------*/ - -#else /* #ifndef MAIN */ - -static const char *cline_filename = DEFAULT_LOGFILE; -static tally_t cline_reset = TALLY_HI; /* Default is `interrogate only' */ -static int cline_quiet = 0; - -/* - * Not going to link with pamlib just for these.. :) - */ - -static const char * pam_errors( int i ) { - switch (i) { - case PAM_AUTH_ERR: return "Authentication error"; - case PAM_SERVICE_ERR: return "Service error"; - case PAM_USER_UNKNOWN: return "Unknown user"; - default: return "Unknown error"; - } -} - -static int getopts( int argc, char **argv ) { - const char *pname = *argv; - for ( ; *argv ; (void)(*argv && ++argv) ) { - if ( !strcmp (*argv,"--file") ) cline_filename=*++argv; - else if ( !strncmp(*argv,"--file=",7) ) cline_filename=*argv+7; - else if ( !strcmp (*argv,"--user") ) cline_user=*++argv; - else if ( !strncmp(*argv,"--user=",7) ) cline_user=*argv+7; - else if ( !strcmp (*argv,"--reset") ) cline_reset=0; - else if ( !strncmp(*argv,"--reset=",8)) { - if ( sscanf(*argv+8,TALLY_FMT,&cline_reset) != 1 ) - fprintf(stderr,"%s: Bad number given to --reset=\n",pname), exit(0); - } - else if ( !strcmp (*argv,"--quiet") ) cline_quiet=1; - else { - fprintf(stderr,"%s: Unrecognised option %s\n",pname,*argv); - return FALSE; - } - } - return TRUE; -} - -int main ( int argc, char **argv ) { - - struct fail_s fs, *fsp = &fs; - - if ( ! getopts( argc, argv+1 ) ) { - printf("%s: [--file rooted-filename] [--user username] " - "[--reset[=n]] [--quiet]\n", - *argv); - exit(0); - } - - umask(077); - - /* - * Major difference between individual user and all users: - * --user just handles one user, just like PAM. - * --user=* handles all users, sniffing cline_filename for nonzeros - */ - - if ( cline_user ) { - uid_t uid; - tally_t tally=cline_reset; - FILE *TALLY=0; - struct tally_options opts; - int i; - - memset(&opts, 0, sizeof(opts)); - opts.ctrl = OPT_AUDIT; - i=pam_get_uid( NULL, &uid, NULL, &opts); - if ( i != PAM_SUCCESS ) { - fprintf(stderr,"%s: %s\n",*argv,pam_errors(i)); - exit(0); - } - - i=get_tally( &tally, uid, cline_filename, &TALLY, fsp ); - if ( i != PAM_SUCCESS ) { - if (TALLY) fclose(TALLY); - fprintf(stderr,"%s: %s\n",*argv,pam_errors(i)); - exit(0); - } - - if ( !cline_quiet ) - printf("User %s\t("UID_FMT")\t%s "TALLY_FMT"\n",cline_user,uid, - (cline_reset!=TALLY_HI)?"had":"has",tally); - - i=set_tally( cline_reset, uid, cline_filename, &TALLY, fsp ); - if ( i != PAM_SUCCESS ) { - if (TALLY) fclose(TALLY); - fprintf(stderr,"%s: %s\n",*argv,pam_errors(i)); - exit(0); - } - } - else /* !cline_user (ie, operate on all users) */ { - FILE *TALLY=fopen(cline_filename, "r"); - uid_t uid=0; - if ( !TALLY ) perror(*argv), exit(0); - - for ( ; !feof(TALLY); uid++ ) { - tally_t tally; - struct passwd *pw; - if ( ! fread((char *) &fsp->fs_faillog, - sizeof (struct faillog), 1, TALLY) - || ! fsp->fs_faillog.fail_cnt ) { - continue; - } - tally = fsp->fs_faillog.fail_cnt; - - if ( ( pw=getpwuid(uid) ) ) { - printf("User %s\t("UID_FMT")\t%s "TALLY_FMT"\n",pw->pw_name,uid, - (cline_reset!=TALLY_HI)?"had":"has",tally); - } - else { - printf("User [NONAME]\t("UID_FMT")\t%s "TALLY_FMT"\n",uid, - (cline_reset!=TALLY_HI)?"had":"has",tally); - } - } - fclose(TALLY); - if ( cline_reset!=0 && cline_reset!=TALLY_HI ) { - fprintf(stderr,"%s: Can't reset all users to non-zero\n",*argv); - } - else if ( !cline_reset ) { - TALLY=fopen(cline_filename, "w"); - if ( !TALLY ) perror(*argv), exit(0); - fclose(TALLY); - } - } - return 0; -} - - -#endif diff --git a/modules/pam_tally/pam_tally_app.c b/modules/pam_tally/pam_tally_app.c deleted file mode 100644 index 9e6e1faf..00000000 --- a/modules/pam_tally/pam_tally_app.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - # This seemed like such a good idea at the time. :) - */ - -#define MAIN -#include "pam_tally.c" - diff --git a/modules/pam_time/.cvsignore b/modules/pam_time/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_time/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_time/Makefile b/modules/pam_time/Makefile deleted file mode 100644 index 9c2d0eb3..00000000 --- a/modules/pam_time/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_time -LOCAL_CONFILE=./time.conf -INSTALLED_CONFILE=$(SCONFIGD)/time.conf - -DEFS=-DDEFAULT_CONF_FILE=\"$(INSTALLED_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_time/README b/modules/pam_time/README deleted file mode 100644 index 38b2b3e6..00000000 --- a/modules/pam_time/README +++ /dev/null @@ -1,30 +0,0 @@ -$Id$ - -This is a help file for the pam_time module. It explains the need for -pam_time and also the syntax of the /etc/security/time.conf file. -[a lot of the syntax is freely adapted from the porttime file of the -shadow suite.] - -1. Introduction -=============== - -It is desirable to restrict access to a system and or specific -applications at various times of the day and on specific days or over -various terminal lines. - -The pam_time module is intended to offer a configurable module that -satisfies this purpose, within the context of Linux-PAM. - -2. the /etc/security/time.conf file -=================================== - -This file is the configuration script for defining time/port access -control to the system/applications. - -Its syntax is described in the sample ./time.conf provided in this -directory. - -unrecognised rules are ignored (but an error is logged to syslog(3)) - --------------------- -Bugs to Andrew <morgan@parc.power.net> or the list <pam-list@redhat.com> diff --git a/modules/pam_time/pam_time.c b/modules/pam_time/pam_time.c deleted file mode 100644 index 9858307e..00000000 --- a/modules/pam_time/pam_time.c +++ /dev/null @@ -1,624 +0,0 @@ -/* pam_time module */ - -/* - * $Id$ - * - * 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$;\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 <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 <sys/types.h> -#include <sys/stat.h> -#include <fcntl.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 -#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_ACCOUNT - -#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_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) -{ - 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_TIME_BUFLEN); - if (! *buf) { - _log_err("out of memory"); - D(("no memory")); - return -1; - } - *from = *to = 0; - fd = open(PAM_TIME_CONF, O_RDONLY); - } - - /* do we have a file open ? return error */ - - if (fd < 0 && *to <= 0) { - _log_err( PAM_TIME_CONF " not opened"); - memset(*buf, 0, PAM_TIME_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_TIME_BUFLEN) { - int i; - - /* now try to fill the remainder of the buffer */ - - i = read(fd, *to + *buf, PAM_TIME_BUFLEN - *to); - if (i < 0) { - _log_err("error reading " PAM_TIME_CONF); - close(fd); - 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__ ); - close(fd); - 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(("chcking: 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 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; - - here_and_now = time_now(); /* find current time */ - do { - boolean good=TRUE,intime; - - /* here we get the service name field */ - - fd = read_field(fd,&buffer,&from,&to); - - if (!buffer || !buffer[0]) { - /* empty line .. ? */ - continue; - } - ++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_TIME_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_TIME_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_TIME_CONF "; no time entry #%d", count); - continue; - } - - intime = logic_field(&here_and_now, buffer, count, check_time); - D(("with time: %s", intime ? "passes":"fails" )); - - fd = read_field(fd,&buffer,&from,&to); - if (buffer && buffer[0]) { - _log_err(PAM_TIME_CONF "; poorly terminated rule #%d", count); - continue; - } - - if (good && !intime) { - /* - * for security parse whole file.. also need to ensure - * that the buffer is free()'d and the file is closed. - */ - retval = PAM_PERM_DENIED; - } else { - D(("rule passed")); - } - } while (buffer); - - return retval; -} - -/* --- public account management functions --- */ - -PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - const char *service=NULL, *tty=NULL; - const char *user=NULL; - - /* 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)); - - return check_account(service,tty,user); -} - -/* end of module definition */ - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_time_modstruct = { - "pam_time", - NULL, - NULL, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL -}; -#endif diff --git a/modules/pam_time/time.conf b/modules/pam_time/time.conf deleted file mode 100644 index d2062fdb..00000000 --- a/modules/pam_time/time.conf +++ /dev/null @@ -1,64 +0,0 @@ -# this is an example configuration file for the pam_time module. Its syntax -# was initially based heavily on that of the shadow package (shadow-960129). -# -# the syntax of the lines is as follows: -# -# services;ttys;users;times -# -# white space is ignored and lines maybe extended with '\\n' (escaped -# newlines). As should be clear from reading these comments, -# text following a '#' is ignored to the end of the line. -# -# the combination of individual users/terminals etc is a logic list -# namely individual tokens that are optionally prefixed with '!' (logical -# not) and separated with '&' (logical and) and '|' (logical or). -# -# services -# is a logic list of PAM service names that the rule applies to. -# -# ttys -# is a logic list of terminal names that this rule applies to. -# -# users -# is a logic list of users to whom this rule applies. -# -# NB. For these items the simple wildcard '*' may be used only once. -# -# times -# the format here is a logic list of day/time-range -# entries the days are specified by a sequence of two character -# entries, MoTuSa for example is Monday Tuesday and Saturday. Note -# that repeated days are unset MoMo = no day, and MoWk = all weekdays -# bar Monday. The two character combinations accepted are -# -# Mo Tu We Th Fr Sa Su Wk Wd Al -# -# the last two being week-end days and all 7 days of the week -# respectively. As a final example, AlFr means all days except Friday. -# -# each day/time-range can be prefixed with a '!' to indicate "anything -# but" -# -# The time-range part is two 24-hour times HHMM separated by a hyphen -# indicating the start and finish time (if the finish time is smaller -# than the start time it is deemed to apply on the following day). -# -# for a rule to be active, ALL of service+ttys+users must be satisfied -# by the applying process. -# - -# -# Here is a simple example: running blank on tty* (any ttyXXX device), -# the users 'you' and 'me' are denied service all of the time -# - -#blank;tty* & !ttyp*;you|me;!Al0000-2400 - -# Another silly example, user 'root' is denied xsh access -# from pseudo terminals at the weekend and on mondays. - -#xsh;ttyp*;root;!WdMo0000-2400 - -# -# End of example file. -#
\ No newline at end of file diff --git a/modules/pam_unix/.cvsignore b/modules/pam_unix/.cvsignore deleted file mode 100644 index 64c5ce5c..00000000 --- a/modules/pam_unix/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -dynamic -unix_chkpwd -*.so -*~ diff --git a/modules/pam_unix/CHANGELOG b/modules/pam_unix/CHANGELOG deleted file mode 100644 index 1476b579..00000000 --- a/modules/pam_unix/CHANGELOG +++ /dev/null @@ -1,55 +0,0 @@ -$Id$ - -* Mon Aug 16 1999 Jan Rêkorajski <baggins@pld.org.pl> -- fixed reentrancy problems - -* Sun Jul 4 21:03:42 PDT 1999 - -- temporarily removed the crypt16 stuff. I'm really paranoid about - crypto stuff and exporting it, and there are a few too many 's-box' - references in the code for my liking.. - -* Wed Jun 30 1999 Steve Langasek <vorlon@netexpress.net> -- further NIS+ fixes - -* Sun Jun 27 1999 Steve Langasek <vorlon@netexpress.net> -- fix to uid-handling code for NIS+ - -* Sat Jun 26 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- merged MD5 fix and early failure syslog - by Andrey Vladimirovich Savochkin <saw@msu.ru> -- minor fixes -- added signal handler to unix_chkpwd - -* Fri Jun 25 1999 Stephen Langasek <vorlon@netexpress.net> -- reorganized the code to let it build as separate C files - -* Sun Jun 20 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- fixes in pam_unix_auth, it incorrectly saved and restored return - value when likeauth option was used - -* Tue Jun 15 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- added NIS+ support - -* Mon Jun 14 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- total rewrite based on pam_pwdb module, now there is ONE pam_unix.so - module, it accepts the same options as pam_pwdb - all of them correctly ;) - (pam_pwdb dosn't understand what DISALLOW_NULL_AUTHTOK means) - -* Tue Apr 20 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- Arghhh, pam_unix_passwd was not updating /etc/shadow when used with - pam_cracklib. - -* Mon Apr 19 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- added "remember=XXX" option that means 'remember XXX old passwords' - Old passwords are stored in /etc/security/opasswd, there can be - maximum of 400 passwords per user. - -* Sat Mar 27 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- added crypt16 to pam_unix_auth and pam_unix_passwd (check only, this algorithm - is too lame to use it in real life) - -* Sun Mar 21 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- pam_unix_auth now correctly behave when user has NULL AUTHTOK -- pam_unix_auth returns PAM_PERM_DENIED when seteuid fails - diff --git a/modules/pam_unix/Makefile b/modules/pam_unix/Makefile deleted file mode 100644 index abeb7eef..00000000 --- a/modules/pam_unix/Makefile +++ /dev/null @@ -1,191 +0,0 @@ -# $Id$ -# -# This Makefile controls a build process of the pam_unix modules -# for Linux-PAM. You should not modify this Makefile. -# - -include ../../Make.Rules - -######################################################################## -# some options... uncomment to take effect -######################################################################## - -# Unless someone wants to work out how to make this work with the new -# autoconf stuff, you should use a separate module for this type of thing -# pam_cracklib perhaps..? -# do you want cracklib? -#ifeq ($(HAVE_CRACKLIB),yes) -#USE_CRACKLIB=-D"USE_CRACKLIB" -#endif - -ifeq ($(shell if [ -f /usr/lib/cracklib_dict.hwm ]; then echo yes ; fi),yes) - CRACKLIB_DICTPATH=/usr/lib/cracklib_dict -else - CRACKLIB_DICTPATH=/usr/share/dict/cracklib_dict -endif -EXTRAS += -DCRACKLIB_DICTS=\"$(CRACKLIB_DICTPATH)\" - -ifeq ($(HAVE_LIBCRYPT),yes) - EXTRALS += -lcrypt -endif -ifeq ($(HAVE_LIBNSL),yes) - EXTRALS += -lnsl -endif -# do you want to use lckpwdf? -ifeq ($(WITH_LCKPWDF),yes) -USE_LCKPWDF=-D"USE_LCKPWDF" -# do you need to include the locking functions in the source? -ifeq ($(HAVE_LCKPWDF),no) - NEED_LCKPWDF=-D"NEED_LCKPWDF" -endif -endif - -ifeq ($(HAVE_LIBNSL),yes) - LIBNSL = -lnsl -endif - -ifeq ($(HAVE_LIBCRYPT),yes) - LIBCRYPT=-lcrypt -endif - -CHKPWD=unix_chkpwd - -BIGCRYPT=bigcrypt - -EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\" - -LINK_PAMMODUTILS = -L../pammodutil -lpammodutil -INCLUDE_PAMMODUTILS = -I../pammodutil/include - -######################################################################## - -CFLAGS += $(USE_CRACKLIB) $(USE_LCKPWDF) $(NEED_LCKPWDF) $(EXTRAS) \ - $(INCLUDE_PAMMODUTILS) - -LDLIBS = $(EXTRALS) $(LINK_PAMMODUTILS) - -ifdef USE_CRACKLIB -CRACKLIB = -lcrack -endif - - -LIBOBJ = pam_unix_auth.o pam_unix_acct.o pam_unix_sess.o pam_unix_passwd.o \ - support.o -LIBSRC = pam_unix_auth.c pam_unix_acct.c pam_unix_sess.c pam_unix_passwd.c \ - support.c -LIBOBJD = $(addprefix dynamic/,$(LIBOBJ)) -LIBOBJS = $(addprefix static/,$(LIBOBJ)) - -PLUS = md5_good.o md5_broken.o md5_crypt_good.o md5_crypt_broken.o \ - yppasswd_xdr.o bigcrypt.o - -ifdef DYNAMIC -LIBSHARED = pam_unix.so -endif -ifdef STATIC -LIBSTATIC = libpam_unix.o -endif - - -########################### don't edit below ####################### - -all: dirs info $(PLUS) $(LIBSHARED) $(LIBSTATIC) $(CHKPWD) $(BIGCRYPT) \ - register - -dynamic/%.o : %.c - $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ - -static/%.o: %.c - $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ - -dummy: - @echo "**** This is not a top-level Makefile " - exit - -info: - @echo - @echo "*** Building pam-unix module of the framework..." - @echo - -dirs: -ifdef DYNAMIC - mkdir -p ./dynamic -endif -ifdef STATIC - mkdir -p ./static -endif - -register: -ifdef STATIC - ( cd .. ; ./register_static pam_unix_auth pam_unix/$(LIBSTATIC) ; \ - ./register_static pam_unix_acct "" ; \ - ./register_static pam_unix_session "" ; \ - ./register_static pam_unix_passwd "" ; \ - ) -endif - -ifdef DYNAMIC -$(LIBOBJD): $(LIBSRC) - -$(LIBSHARED): $(LIBOBJD) - $(LD_D) -o $@ $(LIBOBJD) $(PLUS) $(CRACKLIB) $(LDLIBS) $(LIBNSL) $(LIBCRYPT) $(NEED_LINK_LIB_C) -L../../libpam -lpam -endif - -ifdef STATIC -$(LIBOBJS): $(LIBSRC) - -$(LIBSTATIC): $(LIBOBJS) - $(LD) -r -o $@ $(LIBOBJS) $(PLUS) $(CRACKLIB) $(LDLIBS) $(LIBNSL) $(LIBCRYPT) -endif - -$(CHKPWD): unix_chkpwd.o md5_good.o md5_broken.o \ - md5_crypt_good.o md5_crypt_broken.o \ - bigcrypt.o - $(CC) $(CFLAGS) -o $(CHKPWD) $^ $(LDLIBS) $(LIBCRYPT) - -$(BIGCRYPT): bigcrypt_main.o bigcrypt.o - $(CC) -o $(BIGCRYPT) $^ $(LDLIBS) $(LIBCRYPT) - -unix_chkpwd.o: unix_chkpwd.c - $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ - -md5_good.o: md5.c - $(CC) $(CFLAGS) $(CPPFLAGS) -DHIGHFIRST -D'MD5Name(x)=Good##x' \ - $(TARGET_ARCH) -c $< -o $@ - -md5_broken.o: md5.c - $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \ - $(TARGET_ARCH) -c $< -o $@ - -md5_crypt_good.o: md5_crypt.c - $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Good##x' \ - $(TARGET_ARCH) -c $< -o $@ - -md5_crypt_broken.o: md5_crypt.c - $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \ - $(TARGET_ARCH) -c $< -o $@ - -install: all - mkdir -p $(FAKEROOT)$(SECUREDIR) -ifdef DYNAMIC - install -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR) - for x in pam_unix_auth pam_unix_acct pam_unix_passwd pam_unix_session;\ - do ln -sf $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)/$$x.so ; done -endif - $(MKDIR) $(FAKEROOT)$(SUPLEMENTED) - install -m 4555 $(CHKPWD) $(FAKEROOT)$(SUPLEMENTED) - -remove: - rm -f $(FAKEROOT)$(SECUREDIR)/$(LIBSHARED) - for x in pam_unix_auth pam_unix_acct pam_unix_passwd pam_unix_session;\ - do rm -f $(FAKEROOT)$(SECUREDIR)/$$x.so ; done - rm -f $(FAKEROOT)$(SUPLEMENTED)/$(CHKPWD) - -clean: - rm -f $(LIBOBJD) $(LIBOBJS) $(CHKPWD) $(BIGCRYPT) *.o *.so core - rm -f *~ *.a *.out *.bak - rm -rf dynamic static - -.c.o: - $(CC) -c $(CFLAGS) $< - diff --git a/modules/pam_unix/README b/modules/pam_unix/README deleted file mode 100644 index afeee3da..00000000 --- a/modules/pam_unix/README +++ /dev/null @@ -1,37 +0,0 @@ -pam_unix comes as one module pam_unix.so. - -The following links are left for compatibility with old versions: -pam_unix_auth: authentication module providing - pam_authenticate() and pam_setcred() hooks -pam_unix_sess: session module, providing session logging -pam_unix_acct: account management, providing shadow account - managment features, password aging etc.. -pam_unix_passwd: password updating facilities providing - cracklib password strength checking facilities. - -The following options are recognized: - debug - log more debugging info - audit - a little more extreme than debug - use_first_pass - don't prompt the user for passwords - take them from PAM_ items instead - try_first_pass - don't prompt the user for the passwords - unless PAM_(OLD)AUTHTOK is unset - use_authtok - like try_first_pass, but * fail * if the new - PAM_AUTHTOK has not been previously set. - (intended for stacking password modules only) - not_set_pass - don't set the PAM_ items with the passwords - used by this module. - shadow - try to maintian a shadow based system. - md5 - when a user changes their password next, - encrypt it with the md5 algorithm. - bigcrypt - when a user changes their password next, - excrypt it with the DEC C2 - algorithm(0). - nodelay - used to prevent failed authentication - resulting in a delay of about 1 second. - nis - use NIS RPC for setting new password - remember=X - remember X old passwords, they are kept in - /etc/security/opasswd in MD5 crypted form - broken_shadow - ignore errors reading shadow information for - users in the account management module - - invalid arguments are logged to syslog. diff --git a/modules/pam_unix/bigcrypt.c b/modules/pam_unix/bigcrypt.c deleted file mode 100644 index 6b73f3d2..00000000 --- a/modules/pam_unix/bigcrypt.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This function implements the "bigcrypt" algorithm specifically for - * Linux-PAM. - * - * This algorithm is algorithm 0 (default) shipped with the C2 secure - * implementation of Digital UNIX. - * - * Disclaimer: This work is not based on the source code to Digital - * UNIX, nor am I connected to Digital Equipment Corp, in any way - * other than as a customer. This code is based on published - * interfaces and reasonable guesswork. - * - * Description: The cleartext is divided into blocks of SEGMENT_SIZE=8 - * characters or less. Each block is encrypted using the standard UNIX - * libc crypt function. The result of the encryption for one block - * provides the salt for the suceeding block. - * - * Restrictions: The buffer used to hold the encrypted result is - * statically allocated. (see MAX_PASS_LEN below). This is necessary, - * as the returned pointer points to "static data that are overwritten - * by each call", (XPG3: XSI System Interface + Headers pg 109), and - * this is a drop in replacement for crypt(); - * - * Andy Phillips <atp@mssl.ucl.ac.uk> - */ - -#include <string.h> -#include <stdlib.h> -#include <security/_pam_macros.h> - -char *crypt(const char *key, const char *salt); -char *bigcrypt(const char *key, const char *salt); - -/* - * Max cleartext password length in segments of 8 characters this - * function can deal with (16 segments of 8 chars= max 128 character - * password). - */ - -#define MAX_PASS_LEN 16 -#define SEGMENT_SIZE 8 -#define SALT_SIZE 2 -#define KEYBUF_SIZE ((MAX_PASS_LEN*SEGMENT_SIZE)+SALT_SIZE) -#define ESEGMENT_SIZE 11 -#define CBUF_SIZE ((MAX_PASS_LEN*ESEGMENT_SIZE)+SALT_SIZE+1) - -char *bigcrypt(const char *key, const char *salt) -{ - char *dec_c2_cryptbuf; - - unsigned long int keylen, n_seg, j; - char *cipher_ptr, *plaintext_ptr, *tmp_ptr, *salt_ptr; - char keybuf[KEYBUF_SIZE + 1]; - - D(("called with key='%s', salt='%s'.", key, salt)); - - /* reset arrays */ - dec_c2_cryptbuf = malloc(CBUF_SIZE); - if (!dec_c2_cryptbuf) { - return NULL; - } - memset(keybuf, 0, KEYBUF_SIZE + 1); - memset(dec_c2_cryptbuf, 0, CBUF_SIZE); - - /* fill KEYBUF_SIZE with key */ - strncpy(keybuf, key, KEYBUF_SIZE); - - /* deal with case that we are doing a password check for a - conventially encrypted password: the salt will be - SALT_SIZE+ESEGMENT_SIZE long. */ - if (strlen(salt) == (SALT_SIZE + ESEGMENT_SIZE)) - keybuf[SEGMENT_SIZE] = '\0'; /* terminate password early(?) */ - - keylen = strlen(keybuf); - - if (!keylen) { - n_seg = 1; - } else { - /* work out how many segments */ - n_seg = 1 + ((keylen - 1) / SEGMENT_SIZE); - } - - if (n_seg > MAX_PASS_LEN) - n_seg = MAX_PASS_LEN; /* truncate at max length */ - - /* set up some pointers */ - cipher_ptr = dec_c2_cryptbuf; - plaintext_ptr = keybuf; - - /* do the first block with supplied salt */ - tmp_ptr = crypt(plaintext_ptr, salt); /* libc crypt() */ - - /* and place in the static area */ - strncpy(cipher_ptr, tmp_ptr, 13); - cipher_ptr += ESEGMENT_SIZE + SALT_SIZE; - plaintext_ptr += SEGMENT_SIZE; /* first block of SEGMENT_SIZE */ - - /* change the salt (1st 2 chars of previous block) - this was found - by dowsing */ - - salt_ptr = cipher_ptr - ESEGMENT_SIZE; - - /* so far this is identical to "return crypt(key, salt);", if - there is more than one block encrypt them... */ - - if (n_seg > 1) { - for (j = 2; j <= n_seg; j++) { - - tmp_ptr = crypt(plaintext_ptr, salt_ptr); - - /* skip the salt for seg!=0 */ - strncpy(cipher_ptr, (tmp_ptr + SALT_SIZE), ESEGMENT_SIZE); - - cipher_ptr += ESEGMENT_SIZE; - plaintext_ptr += SEGMENT_SIZE; - salt_ptr = cipher_ptr - ESEGMENT_SIZE; - } - } - D(("key=|%s|, salt=|%s|\nbuf=|%s|\n", key, salt, dec_c2_cryptbuf)); - - /* this is the <NUL> terminated encrypted password */ - - return dec_c2_cryptbuf; -} diff --git a/modules/pam_unix/bigcrypt_main.c b/modules/pam_unix/bigcrypt_main.c deleted file mode 100644 index 70819072..00000000 --- a/modules/pam_unix/bigcrypt_main.c +++ /dev/null @@ -1,18 +0,0 @@ -#include <stdio.h> -#include <string.h> - -extern const char *bigcrypt(const char *password, const char *salt); - -int -main(int argc, char **argv) -{ - if (argc < 3) { - fprintf(stderr, "Usage: %s password salt\n", - strchr(argv[0], '/') ? - (strchr(argv[0], '/') + 1) : - argv[0]); - return 0; - } - fprintf(stdout, "%s\n", bigcrypt(argv[1], argv[2])); - return 0; -} diff --git a/modules/pam_unix/lckpwdf.-c b/modules/pam_unix/lckpwdf.-c deleted file mode 100644 index b5ff4585..00000000 --- a/modules/pam_unix/lckpwdf.-c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This is a hack, but until libc and glibc both include this function - * by default (libc only includes it if nys is not being used, at the - * moment, and glibc doesn't appear to have it at all) we need to have - * it here, too. :-( - * - * This should not become an official part of PAM. - * - * BEGIN_HACK - */ - -/* - * lckpwdf.c -- prevent simultaneous updates of password files - * - * Before modifying any of the password files, call lckpwdf(). It may block - * for up to 15 seconds trying to get the lock. Return value is 0 on success - * or -1 on failure. When you are done, call ulckpwdf() to release the lock. - * The lock is also released automatically when the process exits. Only one - * process at a time may hold the lock. - * - * These functions are supposed to be conformant with AT&T SVID Issue 3. - * - * Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>, - * public domain. - */ - -#include <fcntl.h> -#include <signal.h> - -#define LOCKFILE "/etc/.pwd.lock" -#define TIMEOUT 15 - -static int lockfd = -1; - -static int set_close_on_exec(int fd) -{ - int flags = fcntl(fd, F_GETFD, 0); - if (flags == -1) - return -1; - flags |= FD_CLOEXEC; - return fcntl(fd, F_SETFD, flags); -} - -static int do_lock(int fd) -{ - struct flock fl; - - memset(&fl, 0, sizeof fl); - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - return fcntl(fd, F_SETLKW, &fl); -} - -static void alarm_catch(int sig) -{ -/* does nothing, but fcntl F_SETLKW will fail with EINTR */ -} - -static int lckpwdf(void) -{ - struct sigaction act, oldact; - sigset_t set, oldset; - - if (lockfd != -1) - return -1; - - lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600); - if (lockfd == -1) - return -1; - if (set_close_on_exec(lockfd) == -1) - goto cleanup_fd; - - memset(&act, 0, sizeof act); - act.sa_handler = alarm_catch; - act.sa_flags = 0; - sigfillset(&act.sa_mask); - if (sigaction(SIGALRM, &act, &oldact) == -1) - goto cleanup_fd; - - sigemptyset(&set); - sigaddset(&set, SIGALRM); - if (sigprocmask(SIG_UNBLOCK, &set, &oldset) == -1) - goto cleanup_sig; - - alarm(TIMEOUT); - if (do_lock(lockfd) == -1) - goto cleanup_alarm; - alarm(0); - sigprocmask(SIG_SETMASK, &oldset, NULL); - sigaction(SIGALRM, &oldact, NULL); - return 0; - - cleanup_alarm: - alarm(0); - sigprocmask(SIG_SETMASK, &oldset, NULL); - cleanup_sig: - sigaction(SIGALRM, &oldact, NULL); - cleanup_fd: - close(lockfd); - lockfd = -1; - return -1; -} - -static int ulckpwdf(void) -{ - unlink(LOCKFILE); - if (lockfd == -1) - return -1; - - if (close(lockfd) == -1) { - lockfd = -1; - return -1; - } - lockfd = -1; - return 0; -} -/* END_HACK */ diff --git a/modules/pam_unix/md5.c b/modules/pam_unix/md5.c deleted file mode 100644 index d88d6810..00000000 --- a/modules/pam_unix/md5.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * $Id$ - * - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - * - */ - -#include <string.h> -#include "md5.h" - -#ifndef HIGHFIRST -#define byteReverse(buf, len) /* Nothing */ -#else -static void byteReverse(unsigned char *buf, unsigned longs); - -#ifndef ASM_MD5 -/* - * Note: this code is harmless on little-endian machines. - */ -static void byteReverse(unsigned char *buf, unsigned longs) -{ - uint32 t; - do { - t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | - ((unsigned) buf[1] << 8 | buf[0]); - *(uint32 *) buf = t; - buf += 4; - } while (--longs); -} -#endif -#endif - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void MD5Name(MD5Init)(struct MD5Context *ctx) -{ - ctx->buf[0] = 0x67452301U; - ctx->buf[1] = 0xefcdab89U; - ctx->buf[2] = 0x98badcfeU; - ctx->buf[3] = 0x10325476U; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len) -{ - uint32 t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if (t) { - unsigned char *p = (unsigned char *) ctx->in + t; - - t = 64 - t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx) -{ - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset(p, 0, count - 8); - } - byteReverse(ctx->in, 14); - - /* Append length in bits and transform */ - ((uint32 *) ctx->in)[14] = ctx->bits[0]; - ((uint32 *) ctx->in)[15] = ctx->bits[1]; - - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - byteReverse((unsigned char *) ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ -} - -#ifndef ASM_MD5 - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16]) -{ - register uint32 a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478U, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756U, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbU, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeU, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aU, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613U, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501U, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8U, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afU, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1U, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beU, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122U, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193U, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eU, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821U, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562U, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340U, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51U, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaU, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dU, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453U, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681U, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8U, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6U, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6U, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87U, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edU, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905U, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8U, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9U, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aU, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942U, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681U, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122U, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cU, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44U, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9U, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60U, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70U, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6U, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faU, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085U, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05U, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039U, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5U, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8U, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665U, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244U, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97U, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7U, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039U, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3U, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92U, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dU, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1U, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0U, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314U, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1U, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82U, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235U, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbU, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391U, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -#endif diff --git a/modules/pam_unix/md5.h b/modules/pam_unix/md5.h deleted file mode 100644 index 103f168a..00000000 --- a/modules/pam_unix/md5.h +++ /dev/null @@ -1,31 +0,0 @@ - -#ifndef MD5_H -#define MD5_H - -typedef unsigned int uint32; - -struct MD5Context { - uint32 buf[4]; - uint32 bits[2]; - unsigned char in[64]; -}; - -void GoodMD5Init(struct MD5Context *); -void GoodMD5Update(struct MD5Context *, unsigned const char *, unsigned); -void GoodMD5Final(unsigned char digest[16], struct MD5Context *); -void GoodMD5Transform(uint32 buf[4], uint32 const in[16]); -void BrokenMD5Init(struct MD5Context *); -void BrokenMD5Update(struct MD5Context *, unsigned const char *, unsigned); -void BrokenMD5Final(unsigned char digest[16], struct MD5Context *); -void BrokenMD5Transform(uint32 buf[4], uint32 const in[16]); - -char *Goodcrypt_md5(const char *pw, const char *salt); -char *Brokencrypt_md5(const char *pw, const char *salt); - -/* - * This is needed to make RSAREF happy on some MS-DOS compilers. - */ - -typedef struct MD5Context MD5_CTX; - -#endif /* MD5_H */ diff --git a/modules/pam_unix/md5_crypt.c b/modules/pam_unix/md5_crypt.c deleted file mode 100644 index 53972fcc..00000000 --- a/modules/pam_unix/md5_crypt.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * $Id$ - * - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * Origin: Id: crypt.c,v 1.3 1995/05/30 05:42:22 rgrimes Exp - * - */ - -#include <string.h> -#include <stdlib.h> -#include "md5.h" - -static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ -"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -static void to64(char *s, unsigned long v, int n) -{ - while (--n >= 0) { - *s++ = itoa64[v & 0x3f]; - v >>= 6; - } -} - -/* - * UNIX password - * - * Use MD5 for what it is best at... - */ - -char *MD5Name(crypt_md5)(const char *pw, const char *salt) -{ - const char *magic = "$1$"; - /* This string is magic for this algorithm. Having - * it this way, we can get get better later on */ - char *passwd, *p; - const char *sp, *ep; - unsigned char final[16]; - int sl, pl, i, j; - MD5_CTX ctx, ctx1; - unsigned long l; - - /* Refine the Salt first */ - sp = salt; - - /* TODO: now that we're using malloc'ed memory, get rid of the - strange constant buffer size. */ - passwd = malloc(120); - - /* If it starts with the magic string, then skip that */ - if (!strncmp(sp, magic, strlen(magic))) - sp += strlen(magic); - - /* It stops at the first '$', max 8 chars */ - for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++) - continue; - - /* get the length of the true salt */ - sl = ep - sp; - - MD5Name(MD5Init)(&ctx); - - /* The password first, since that is what is most unknown */ - MD5Name(MD5Update)(&ctx,(unsigned const char *)pw,strlen(pw)); - - /* Then our magic string */ - MD5Name(MD5Update)(&ctx,(unsigned const char *)magic,strlen(magic)); - - /* Then the raw salt */ - MD5Name(MD5Update)(&ctx,(unsigned const char *)sp,sl); - - /* Then just as many characters of the MD5(pw,salt,pw) */ - MD5Name(MD5Init)(&ctx1); - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl); - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - MD5Name(MD5Final)(final,&ctx1); - for (pl = strlen(pw); pl > 0; pl -= 16) - MD5Name(MD5Update)(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl); - - /* Don't leave anything around in vm they could use. */ - memset(final, 0, sizeof final); - - /* Then something really weird... */ - for (j = 0, i = strlen(pw); i; i >>= 1) - if (i & 1) - MD5Name(MD5Update)(&ctx, (unsigned const char *)final+j, 1); - else - MD5Name(MD5Update)(&ctx, (unsigned const char *)pw+j, 1); - - /* Now make the output string */ - strcpy(passwd, magic); - strncat(passwd, sp, sl); - strcat(passwd, "$"); - - MD5Name(MD5Final)(final,&ctx); - - /* - * and now, just to make sure things don't run too fast - * On a 60 Mhz Pentium this takes 34 msec, so you would - * need 30 seconds to build a 1000 entry dictionary... - */ - for (i = 0; i < 1000; i++) { - MD5Name(MD5Init)(&ctx1); - if (i & 1) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - else - MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16); - - if (i % 3) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl); - - if (i % 7) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - - if (i & 1) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16); - else - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - MD5Name(MD5Final)(final,&ctx1); - } - - p = passwd + strlen(passwd); - - l = (final[0] << 16) | (final[6] << 8) | final[12]; - to64(p, l, 4); - p += 4; - l = (final[1] << 16) | (final[7] << 8) | final[13]; - to64(p, l, 4); - p += 4; - l = (final[2] << 16) | (final[8] << 8) | final[14]; - to64(p, l, 4); - p += 4; - l = (final[3] << 16) | (final[9] << 8) | final[15]; - to64(p, l, 4); - p += 4; - l = (final[4] << 16) | (final[10] << 8) | final[5]; - to64(p, l, 4); - p += 4; - l = final[11]; - to64(p, l, 2); - p += 2; - *p = '\0'; - - /* Don't leave anything around in vm they could use. */ - memset(final, 0, sizeof final); - - return passwd; -} diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c deleted file mode 100644 index 02e07ba6..00000000 --- a/modules/pam_unix/pam_unix_acct.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright Elliot Lee, 1996. All rights reserved. - * Copyright Jan Rêkorajski, 1999. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <security/_pam_aconf.h> - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <syslog.h> -#include <pwd.h> -#include <shadow.h> -#include <time.h> /* for time() */ - -#include <security/_pam_macros.h> - -/* indicate that the following groups are defined */ - -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> -#include <security/_pam_modutil.h> - -#ifndef LINUX_PAM -#include <security/pam_appl.h> -#endif /* LINUX_PAM */ - -#include "support.h" - -/* - * PAM framework looks for this entry-point to pass control to the - * account management module. - */ - -PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags, - int argc, const char **argv) -{ - unsigned int ctrl; - const char *uname; - int retval, daysleft; - time_t curdays; - struct spwd *spent; - struct passwd *pwent; - char buf[80]; - - D(("called.")); - - ctrl = _set_ctrl(pamh, flags, NULL, argc, argv); - - retval = pam_get_item(pamh, PAM_USER, (const void **) &uname); - D(("user = `%s'", uname)); - if (retval != PAM_SUCCESS || uname == NULL) { - _log_err(LOG_ALERT, pamh - ,"could not identify user (from uid=%d)" - ,getuid()); - return PAM_USER_UNKNOWN; - } - - pwent = _pammodutil_getpwnam(pamh, uname); - if (!pwent) { - _log_err(LOG_ALERT, pamh - ,"could not identify user (from getpwnam(%s))" - ,uname); - return PAM_USER_UNKNOWN; - } - - if (!strcmp( pwent->pw_passwd, "*NP*" )) { /* NIS+ */ - uid_t save_euid, save_uid; - - save_euid = geteuid(); - save_uid = getuid(); - if (save_uid == pwent->pw_uid) - setreuid( save_euid, save_uid ); - else { - setreuid( 0, -1 ); - if (setreuid( -1, pwent->pw_uid ) == -1) { - setreuid( -1, 0 ); - setreuid( 0, -1 ); - if(setreuid( -1, pwent->pw_uid ) == -1) - return PAM_CRED_INSUFFICIENT; - } - } - spent = _pammodutil_getspnam (pamh, uname); - if (save_uid == pwent->pw_uid) - setreuid( save_uid, save_euid ); - else { - if (setreuid( -1, 0 ) == -1) - setreuid( save_uid, -1 ); - setreuid( -1, save_euid ); - } - - } else if (_unix_shadowed (pwent)) - spent = _pammodutil_getspnam (pamh, uname); - else - return PAM_SUCCESS; - - if (!spent) - if (on(UNIX_BROKEN_SHADOW,ctrl)) - return PAM_SUCCESS; - - if (!spent) - return PAM_AUTHINFO_UNAVAIL; /* Couldn't get username from shadow */ - - curdays = time(NULL) / (60 * 60 * 24); - D(("today is %d, last change %d", curdays, spent->sp_lstchg)); - if ((curdays > spent->sp_expire) && (spent->sp_expire != -1)) { - _log_err(LOG_NOTICE, pamh - ,"account %s has expired (account expired)" - ,uname); - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - "Your account has expired; please contact your system administrator"); - D(("account expired")); - return PAM_ACCT_EXPIRED; - } - if (spent->sp_lstchg == 0) { - _log_err(LOG_NOTICE, pamh - ,"expired password for user %s (root enforced)" - ,uname); - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - "You are required to change your password immediately (root enforced)"); - D(("need a new password")); - return PAM_NEW_AUTHTOK_REQD; - } - if (curdays < spent->sp_lstchg) { - _log_err(LOG_DEBUG, pamh - ,"account %s has password changed in future" - ,uname); - return PAM_SUCCESS; - } - if ((curdays - spent->sp_lstchg > spent->sp_max) - && (curdays - spent->sp_lstchg > spent->sp_inact) - && (curdays - spent->sp_lstchg > spent->sp_max + spent->sp_inact) - && (spent->sp_max != -1) && (spent->sp_inact != -1)) { - _log_err(LOG_NOTICE, pamh - ,"account %s has expired (failed to change password)" - ,uname); - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - "Your account has expired; please contact your system administrator"); - D(("account expired 2")); - return PAM_ACCT_EXPIRED; - } - if ((curdays - spent->sp_lstchg > spent->sp_max) && (spent->sp_max != -1)) { - _log_err(LOG_DEBUG, pamh - ,"expired password for user %s (password aged)" - ,uname); - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - "You are required to change your password immediately (password aged)"); - D(("need a new password 2")); - return PAM_NEW_AUTHTOK_REQD; - } - if ((curdays - spent->sp_lstchg > spent->sp_max - spent->sp_warn) - && (spent->sp_max != -1) && (spent->sp_warn != -1)) { - daysleft = (spent->sp_lstchg + spent->sp_max) - curdays; - _log_err(LOG_DEBUG, pamh - ,"password for user %s will expire in %d days" - ,uname, daysleft); - snprintf(buf, 80, "Warning: your password will expire in %d day%.2s", - daysleft, daysleft == 1 ? "" : "s"); - _make_remark(pamh, ctrl, PAM_TEXT_INFO, buf); - } - - D(("all done")); - - return PAM_SUCCESS; -} - - -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_unix_acct_modstruct = { - "pam_unix_acct", - NULL, - NULL, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; -#endif diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c deleted file mode 100644 index 39e0cde5..00000000 --- a/modules/pam_unix/pam_unix_auth.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright Alexander O. Yuriev, 1996. All rights reserved. - * NIS+ support by Thorsten Kukuk <kukuk@weber.uni-paderborn.de> - * Copyright Jan Rêkorajski, 1999. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* #define DEBUG */ - -#include <security/_pam_aconf.h> - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> - -/* indicate the following groups are defined */ - -#define PAM_SM_AUTH - -#define _PAM_EXTERN_FUNCTIONS -#include <security/_pam_macros.h> -#include <security/pam_modules.h> - -#ifndef LINUX_PAM -#include <security/pam_appl.h> -#endif /* LINUX_PAM */ - -#include "support.h" - -/* - * PAM framework looks for these entry-points to pass control to the - * authentication module. - */ - -/* Fun starts here :) - - * pam_sm_authenticate() performs UNIX/shadow authentication - * - * First, if shadow support is available, attempt to perform - * authentication using shadow passwords. If shadow is not - * available, or user does not have a shadow password, fallback - * onto a normal UNIX authentication - */ - -#define _UNIX_AUTHTOK "-UN*X-PASS" - -#define AUTH_RETURN \ -do { \ - if (on(UNIX_LIKE_AUTH, ctrl) && ret_data) { \ - D(("recording return code for next time [%d]", \ - retval)); \ - *ret_data = retval; \ - pam_set_data(pamh, "unix_setcred_return", \ - (void *) ret_data, setcred_free); \ - } else if (ret_data) \ - free (ret_data); \ - D(("done. [%s]", pam_strerror(pamh, retval))); \ - return retval; \ -} while (0) - - -static void setcred_free (pam_handle_t * pamh, void *ptr, int err) -{ - if (ptr) - free (ptr); -} - - -PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags - ,int argc, const char **argv) -{ - unsigned int ctrl; - int retval, *ret_data = NULL; - const char *name, *p; - - D(("called.")); - - ctrl = _set_ctrl(pamh, flags, NULL, argc, argv); - - /* Get a few bytes so we can pass our return value to - pam_sm_setcred(). */ - if (on(UNIX_LIKE_AUTH, ctrl)) - ret_data = malloc(sizeof(int)); - - /* get the user'name' */ - - retval = pam_get_user(pamh, &name, NULL); - if (retval == PAM_SUCCESS) { - /* - * Various libraries at various times have had bugs related to - * '+' or '-' as the first character of a user name. Don't take - * any chances here. Require that the username starts with an - * alphanumeric character. - */ - if (name == NULL || !isalnum(*name)) { - _log_err(LOG_ERR, pamh, "bad username [%s]", name); - retval = PAM_USER_UNKNOWN; - AUTH_RETURN; - } - if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl)) - D(("username [%s] obtained", name)); - } else { - D(("trouble reading username")); - if (retval == PAM_CONV_AGAIN) { - D(("pam_get_user/conv() function is not ready yet")); - /* it is safe to resume this function so we translate this - * retval to the value that indicates we're happy to resume. - */ - retval = PAM_INCOMPLETE; - } - AUTH_RETURN; - } - - /* if this user does not have a password... */ - - if (_unix_blankpasswd(pamh, ctrl, name)) { - D(("user '%s' has blank passwd", name)); - name = NULL; - retval = PAM_SUCCESS; - AUTH_RETURN; - } - /* get this user's authentication token */ - - retval = _unix_read_password(pamh, ctrl, NULL, "Password: ", NULL - ,_UNIX_AUTHTOK, &p); - if (retval != PAM_SUCCESS) { - if (retval != PAM_CONV_AGAIN) { - _log_err(LOG_CRIT, pamh, "auth could not identify password for [%s]" - ,name); - } else { - D(("conversation function is not ready yet")); - /* - * it is safe to resume this function so we translate this - * retval to the value that indicates we're happy to resume. - */ - retval = PAM_INCOMPLETE; - } - name = NULL; - AUTH_RETURN; - } - D(("user=%s, password=[%s]", name, p)); - - /* verify the password of this user */ - retval = _unix_verify_password(pamh, name, p, ctrl); - name = p = NULL; - - AUTH_RETURN; -} - - -/* - * The only thing _pam_set_credentials_unix() does is initialization of - * UNIX group IDs. - * - * Well, everybody but me on linux-pam is convinced that it should not - * initialize group IDs, so I am not doing it but don't say that I haven't - * warned you. -- AOY - */ - -PAM_EXTERN int pam_sm_setcred(pam_handle_t * pamh, int flags - ,int argc, const char **argv) -{ - int retval; - int *pretval = NULL; - - D(("called.")); - - retval = PAM_SUCCESS; - - D(("recovering return code from auth call")); - /* We will only find something here if UNIX_LIKE_AUTH is set -- - don't worry about an explicit check of argv. */ - pam_get_data(pamh, "unix_setcred_return", (const void **) &pretval); - if(pretval) { - retval = *pretval; - pam_set_data(pamh, "unix_setcred_return", NULL, NULL); - D(("recovered data indicates that old retval was %d", retval)); - } - - return retval; -} - -#ifdef PAM_STATIC -struct pam_module _pam_unix_auth_modstruct = { - "pam_unix_auth", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL, -}; -#endif diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c deleted file mode 100644 index 2ea57cc6..00000000 --- a/modules/pam_unix/pam_unix_passwd.c +++ /dev/null @@ -1,1131 +0,0 @@ -/* - * Main coding by Elliot Lee <sopwith@redhat.com>, Red Hat Software. - * Copyright (C) 1996. - * Copyright (c) Jan Rêkorajski, 1999. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <security/_pam_aconf.h> - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <malloc.h> -#include <unistd.h> -#include <errno.h> -#include <sys/types.h> -#include <pwd.h> -#include <syslog.h> -#include <shadow.h> -#include <time.h> /* for time() */ -#include <fcntl.h> -#include <ctype.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <rpc/rpc.h> -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> - -#ifdef USE_CRACKLIB -#include <crack.h> -#endif - -#include <security/_pam_macros.h> - -/* indicate the following groups are defined */ - -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> - -#ifndef LINUX_PAM -#include <security/pam_appl.h> -#endif /* LINUX_PAM */ - -#include <security/_pam_modutil.h> - -#include "yppasswd.h" -#include "md5.h" -#include "support.h" - -#if !((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1)) -extern int getrpcport(const char *host, unsigned long prognum, - unsigned long versnum, unsigned int proto); -#endif /* GNU libc 2.1 */ - -/* - * PAM framework looks for these entry-points to pass control to the - * password changing module. - */ - -#ifdef NEED_LCKPWDF -# include "./lckpwdf.-c" -#endif - -extern char *bigcrypt(const char *key, const char *salt); - -/* - How it works: - Gets in username (has to be done) from the calling program - Does authentication of user (only if we are not running as root) - Gets new password/checks for sanity - Sets it. - */ - -/* passwd/salt conversion macros */ - -#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.') -#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') - -/* data tokens */ - -#define _UNIX_OLD_AUTHTOK "-UN*X-OLD-PASS" -#define _UNIX_NEW_AUTHTOK "-UN*X-NEW-PASS" - -#define MAX_PASSWD_TRIES 3 -#define PW_TMPFILE "/etc/npasswd" -#define SH_TMPFILE "/etc/nshadow" -#ifndef CRACKLIB_DICTS -#define CRACKLIB_DICTS "/usr/share/dict/cracklib_dict" -#endif -#define OPW_TMPFILE "/etc/security/nopasswd" -#define OLD_PASSWORDS_FILE "/etc/security/opasswd" - -/* - * i64c - convert an integer to a radix 64 character - */ -static int i64c(int i) -{ - if (i < 0) - return ('.'); - else if (i > 63) - return ('z'); - if (i == 0) - return ('.'); - if (i == 1) - return ('/'); - if (i >= 2 && i <= 11) - return ('0' - 2 + i); - if (i >= 12 && i <= 37) - return ('A' - 12 + i); - if (i >= 38 && i <= 63) - return ('a' - 38 + i); - return ('\0'); -} - -static char *crypt_md5_wrapper(const char *pass_new) -{ - /* - * Code lifted from Marek Michalkiewicz's shadow suite. (CG) - * removed use of static variables (AGM) - */ - - struct timeval tv; - MD5_CTX ctx; - unsigned char result[16]; - char *cp = (char *) result; - unsigned char tmp[16]; - int i; - char *x = NULL; - - GoodMD5Init(&ctx); - gettimeofday(&tv, (struct timezone *) 0); - GoodMD5Update(&ctx, (void *) &tv, sizeof tv); - i = getpid(); - GoodMD5Update(&ctx, (void *) &i, sizeof i); - i = clock(); - GoodMD5Update(&ctx, (void *) &i, sizeof i); - GoodMD5Update(&ctx, result, sizeof result); - GoodMD5Final(tmp, &ctx); - strcpy(cp, "$1$"); /* magic for the MD5 */ - cp += strlen(cp); - for (i = 0; i < 8; i++) - *cp++ = i64c(tmp[i] & 077); - *cp = '\0'; - - /* no longer need cleartext */ - x = Goodcrypt_md5(pass_new, (const char *) result); - - return x; -} - -static char *getNISserver(pam_handle_t *pamh) -{ - char *master; - char *domainname; - int port, err; - - if ((err = yp_get_default_domain(&domainname)) != 0) { - _log_err(LOG_WARNING, pamh, "can't get local yp domain: %s\n", - yperr_string(err)); - return NULL; - } - if ((err = yp_master(domainname, "passwd.byname", &master)) != 0) { - _log_err(LOG_WARNING, pamh, "can't find the master ypserver: %s\n", - yperr_string(err)); - return NULL; - } - port = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP); - if (port == 0) { - _log_err(LOG_WARNING, pamh, - "yppasswdd not running on NIS master host\n"); - return NULL; - } - if (port >= IPPORT_RESERVED) { - _log_err(LOG_WARNING, pamh, - "yppasswd daemon running on illegal port.\n"); - return NULL; - } - return master; -} - -static int check_old_password(const char *forwho, const char *newpass) -{ - static char buf[16384]; - char *s_luser, *s_uid, *s_npas, *s_pas; - int retval = PAM_SUCCESS; - FILE *opwfile; - - opwfile = fopen(OLD_PASSWORDS_FILE, "r"); - if (opwfile == NULL) - return PAM_ABORT; - - while (fgets(buf, 16380, opwfile)) { - if (!strncmp(buf, forwho, strlen(forwho))) { - buf[strlen(buf) - 1] = '\0'; - s_luser = strtok(buf, ":,"); - s_uid = strtok(NULL, ":,"); - s_npas = strtok(NULL, ":,"); - s_pas = strtok(NULL, ":,"); - while (s_pas != NULL) { - char *md5pass = Goodcrypt_md5(newpass, s_pas); - if (!strcmp(md5pass, s_pas)) { - _pam_delete(md5pass); - retval = PAM_AUTHTOK_ERR; - break; - } - s_pas = strtok(NULL, ":,"); - _pam_delete(md5pass); - } - break; - } - } - fclose(opwfile); - - return retval; -} - -static int save_old_password(pam_handle_t *pamh, - const char *forwho, const char *oldpass, - int howmany) -{ - static char buf[16384]; - static char nbuf[16384]; - char *s_luser, *s_uid, *s_npas, *s_pas, *pass; - int npas; - FILE *pwfile, *opwfile; - int err = 0; - int oldmask; - int found = 0; - struct passwd *pwd = NULL; - struct stat st; - - if (howmany < 0) { - return PAM_SUCCESS; - } - - if (oldpass == NULL) { - return PAM_SUCCESS; - } - - oldmask = umask(077); - pwfile = fopen(OPW_TMPFILE, "w"); - umask(oldmask); - if (pwfile == NULL) { - return PAM_AUTHTOK_ERR; - } - - opwfile = fopen(OLD_PASSWORDS_FILE, "r"); - if (opwfile == NULL) { - fclose(pwfile); - return PAM_AUTHTOK_ERR; - } - - if (fstat (fileno (opwfile), &st) == -1) - { - fclose (opwfile); - fclose (pwfile); - return PAM_AUTHTOK_ERR; - } - - if (fchown (fileno (pwfile), st.st_uid, st.st_gid) == -1) - { - fclose (opwfile); - fclose (pwfile); - return PAM_AUTHTOK_ERR; - } - if (fchmod (fileno (pwfile), st.st_mode) == -1) - { - fclose (opwfile); - fclose (pwfile); - return PAM_AUTHTOK_ERR; - } - - while (fgets(buf, 16380, opwfile)) { - if (!strncmp(buf, forwho, strlen(forwho))) { - buf[strlen(buf) - 1] = '\0'; - s_luser = strtok(buf, ":"); - s_uid = strtok(NULL, ":"); - s_npas = strtok(NULL, ":"); - s_pas = strtok(NULL, ":"); - npas = strtol(s_npas, NULL, 10) + 1; - while (npas > howmany) { - s_pas = strpbrk(s_pas, ","); - if (s_pas != NULL) - s_pas++; - npas--; - } - pass = crypt_md5_wrapper(oldpass); - if (s_pas == NULL) - snprintf(nbuf, sizeof(nbuf), "%s:%s:%d:%s\n", - s_luser, s_uid, npas, pass); - else - snprintf(nbuf, sizeof(nbuf),"%s:%s:%d:%s,%s\n", - s_luser, s_uid, npas, s_pas, pass); - _pam_delete(pass); - if (fputs(nbuf, pwfile) < 0) { - err = 1; - break; - } - found = 1; - } else if (fputs(buf, pwfile) < 0) { - err = 1; - break; - } - } - fclose(opwfile); - - if (!found) { - pwd = _pammodutil_getpwnam(pamh, forwho); - if (pwd == NULL) { - err = 1; - } else { - pass = crypt_md5_wrapper(oldpass); - snprintf(nbuf, sizeof(nbuf), "%s:%d:1:%s\n", - forwho, pwd->pw_uid, pass); - _pam_delete(pass); - if (fputs(nbuf, pwfile) < 0) { - err = 1; - } - } - } - - if (fclose(pwfile)) { - D(("error writing entries to old passwords file: %s\n", - strerror(errno))); - err = 1; - } - - if (!err) { - if (!rename(OPW_TMPFILE, OLD_PASSWORDS_FILE)) { - return PAM_SUCCESS; - } - } - - unlink(OPW_TMPFILE); - return PAM_AUTHTOK_ERR; -} - -static int _update_passwd(pam_handle_t *pamh, - const char *forwho, const char *towhat) -{ - struct passwd *tmpent = NULL; - struct stat st; - FILE *pwfile, *opwfile; - int err = 1; - int oldmask; - - oldmask = umask(077); - pwfile = fopen(PW_TMPFILE, "w"); - umask(oldmask); - if (pwfile == NULL) { - return PAM_AUTHTOK_ERR; - } - - opwfile = fopen("/etc/passwd", "r"); - if (opwfile == NULL) { - fclose(pwfile); - return PAM_AUTHTOK_ERR; - } - - if (fstat (fileno (opwfile), &st) == -1) - { - fclose (opwfile); - fclose (pwfile); - return PAM_AUTHTOK_ERR; - } - - if (fchown (fileno (pwfile), st.st_uid, st.st_gid) == -1) - { - fclose (opwfile); - fclose (pwfile); - return PAM_AUTHTOK_ERR; - } - if (fchmod (fileno (pwfile), st.st_mode) == -1) - { - fclose (opwfile); - fclose (pwfile); - } - - tmpent = fgetpwent (opwfile); - while (tmpent) { - if (!strcmp(tmpent->pw_name, forwho)) { - /* To shut gcc up */ - union { - const char *const_charp; - char *charp; - } assigned_passwd; - assigned_passwd.const_charp = towhat; - - tmpent->pw_passwd = assigned_passwd.charp; - err = 0; - } - if (putpwent(tmpent, pwfile)) { - D(("error writing entry to password file: %s\n", strerror(errno))); - err = 1; - break; - } - tmpent = fgetpwent(opwfile); - } - fclose(opwfile); - - if (fclose(pwfile)) { - D(("error writing entries to password file: %s\n", strerror(errno))); - err = 1; - } - - if (!err) { - if (!rename(PW_TMPFILE, "/etc/passwd")) { - _log_err(LOG_NOTICE, pamh, "password changed for %s", forwho); - return PAM_SUCCESS; - } - } - - unlink(PW_TMPFILE); - return PAM_AUTHTOK_ERR; -} - -static int _update_shadow(pam_handle_t *pamh, const char *forwho, char *towhat) -{ - struct spwd *spwdent = NULL, *stmpent = NULL; - struct stat st; - FILE *pwfile, *opwfile; - int err = 1; - int oldmask; - - spwdent = getspnam(forwho); - if (spwdent == NULL) { - return PAM_USER_UNKNOWN; - } - oldmask = umask(077); - pwfile = fopen(SH_TMPFILE, "w"); - umask(oldmask); - if (pwfile == NULL) { - return PAM_AUTHTOK_ERR; - } - - opwfile = fopen("/etc/shadow", "r"); - if (opwfile == NULL) { - fclose(pwfile); - return PAM_AUTHTOK_ERR; - } - - if (fstat (fileno (opwfile), &st) == -1) - { - fclose (opwfile); - fclose (pwfile); - return PAM_AUTHTOK_ERR; - } - - if (fchown (fileno (pwfile), st.st_uid, st.st_gid) == -1) - { - fclose (opwfile); - fclose (pwfile); - return PAM_AUTHTOK_ERR; - } - if (fchmod (fileno (pwfile), st.st_mode) == -1) - { - fclose (opwfile); - fclose (pwfile); - return PAM_AUTHTOK_ERR; - } - - stmpent = fgetspent(opwfile); - while (stmpent) { - - if (!strcmp(stmpent->sp_namp, forwho)) { - stmpent->sp_pwdp = towhat; - stmpent->sp_lstchg = time(NULL) / (60 * 60 * 24); - err = 0; - D(("Set password %s for %s", stmpent->sp_pwdp, forwho)); - } - - if (putspent(stmpent, pwfile)) { - D(("error writing entry to shadow file: %s\n", strerror(errno))); - err = 1; - break; - } - - stmpent = fgetspent(opwfile); - } - fclose(opwfile); - - if (fclose(pwfile)) { - D(("error writing entries to shadow file: %s\n", strerror(errno))); - err = 1; - } - - if (!err) { - if (!rename(SH_TMPFILE, "/etc/shadow")) { - _log_err(LOG_NOTICE, pamh, "password changed for %s", forwho); - return PAM_SUCCESS; - } - } - - unlink(SH_TMPFILE); - return PAM_AUTHTOK_ERR; -} - -static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat, - char *towhat, unsigned int ctrl, int remember) -{ - struct passwd *pwd = NULL; - int retval = 0; - - D(("called")); - - pwd = getpwnam(forwho); - - if (pwd == NULL) { - retval = PAM_AUTHTOK_ERR; - goto done; - } - - if (_unix_comesfromsource(pamh, forwho, 1, 0)) { - /* first, save old password */ - if (save_old_password(pamh, forwho, fromwhat, remember)) { - retval = PAM_AUTHTOK_ERR; - goto done; - } - if (on(UNIX_SHADOW, ctrl) || _unix_shadowed(pwd)) { - retval = _update_shadow(pamh, forwho, towhat); - if (retval == PAM_SUCCESS) - if (!_unix_shadowed(pwd)) - retval = _update_passwd(pamh, forwho, "x"); - } else { - retval = _update_passwd(pamh, forwho, towhat); - } - } else if (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, forwho, 0, 1)) { - struct timeval timeout; - struct yppasswd yppwd; - CLIENT *clnt; - char *master; - int status; - int err = 0; - - /* Unlock passwd file to avoid deadlock */ -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif - /* Make RPC call to NIS server */ - if ((master = getNISserver(pamh)) == NULL) - return PAM_TRY_AGAIN; - - /* Initialize password information */ - yppwd.newpw.pw_passwd = pwd->pw_passwd; - yppwd.newpw.pw_name = pwd->pw_name; - yppwd.newpw.pw_uid = pwd->pw_uid; - yppwd.newpw.pw_gid = pwd->pw_gid; - yppwd.newpw.pw_gecos = pwd->pw_gecos; - yppwd.newpw.pw_dir = pwd->pw_dir; - yppwd.newpw.pw_shell = pwd->pw_shell; - yppwd.oldpass = fromwhat ? fromwhat : ""; - yppwd.newpw.pw_passwd = towhat; - - D(("Set password %s for %s", yppwd.newpw.pw_passwd, forwho)); - - /* The yppasswd.x file said `unix authentication required', - * so I added it. This is the only reason it is in here. - * My yppasswdd doesn't use it, but maybe some others out there - * do. --okir - */ - clnt = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp"); - clnt->cl_auth = authunix_create_default(); - memset((char *) &status, '\0', sizeof(status)); - timeout.tv_sec = 25; - timeout.tv_usec = 0; - err = clnt_call(clnt, YPPASSWDPROC_UPDATE, - (xdrproc_t) xdr_yppasswd, (char *) &yppwd, - (xdrproc_t) xdr_int, (char *) &status, - timeout); - - if (err) { - clnt_perrno(err); - retval = PAM_TRY_AGAIN; - } else if (status) { - D(("Error while changing NIS password.\n")); - retval = PAM_TRY_AGAIN; - } - D(("The password has%s been changed on %s.", - (err || status) ? " not" : "", master)); - _log_err(LOG_NOTICE, pamh, "password%s changed for %s on %s", - (err || status) ? " not" : "", pwd->pw_name, master); - - auth_destroy(clnt->cl_auth); - clnt_destroy(clnt); - if ((err || status) != 0) { - retval = PAM_TRY_AGAIN; - } -#ifdef DEBUG - sleep(5); -#endif - return retval; - } - -done: -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif - - return retval; -} - -static int _unix_verify_shadow(const char *user, unsigned int ctrl) -{ - struct passwd *pwd = NULL; /* Password and shadow password */ - struct spwd *spwdent = NULL; /* file entries for the user */ - time_t curdays; - int retval = PAM_SUCCESS; - - /* UNIX passwords area */ - pwd = getpwnam(user); /* Get password file entry... */ - if (pwd == NULL) - return PAM_AUTHINFO_UNAVAIL; /* We don't need to do the rest... */ - - if (_unix_shadowed(pwd)) { - /* ...and shadow password file entry for this user, if shadowing - is enabled */ - setspent(); - spwdent = getspnam(user); - endspent(); - - if (spwdent == NULL) - return PAM_AUTHINFO_UNAVAIL; - } else { - if (strcmp(pwd->pw_passwd,"*NP*") == 0) { /* NIS+ */ - uid_t save_uid; - - save_uid = geteuid(); - seteuid (pwd->pw_uid); - spwdent = getspnam( user ); - seteuid (save_uid); - - if (spwdent == NULL) - return PAM_AUTHINFO_UNAVAIL; - } else - spwdent = NULL; - } - - if (spwdent != NULL) { - /* We have the user's information, now let's check if their account - has expired (60 * 60 * 24 = number of seconds in a day) */ - - if (off(UNIX__IAMROOT, ctrl)) { - /* Get the current number of days since 1970 */ - curdays = time(NULL) / (60 * 60 * 24); - if ((curdays < (spwdent->sp_lstchg + spwdent->sp_min)) - && (spwdent->sp_min != -1)) - retval = PAM_AUTHTOK_ERR; - else if ((curdays > (spwdent->sp_lstchg + spwdent->sp_max + spwdent->sp_inact)) - && (spwdent->sp_max != -1) && (spwdent->sp_inact != -1) - && (spwdent->sp_lstchg != 0)) - /* - * Their password change has been put off too long, - */ - retval = PAM_ACCT_EXPIRED; - else if ((curdays > spwdent->sp_expire) && (spwdent->sp_expire != -1) - && (spwdent->sp_lstchg != 0)) - /* - * OR their account has just plain expired - */ - retval = PAM_ACCT_EXPIRED; - } - } - return retval; -} - -static int _pam_unix_approve_pass(pam_handle_t * pamh - ,unsigned int ctrl - ,const char *pass_old - ,const char *pass_new) -{ - const char *user; - const char *remark = NULL; - int retval = PAM_SUCCESS; - - D(("&new=%p, &old=%p", pass_old, pass_new)); - D(("new=[%s]", pass_new)); - D(("old=[%s]", pass_old)); - - if (pass_new == NULL || (pass_old && !strcmp(pass_old, pass_new))) { - if (on(UNIX_DEBUG, ctrl)) { - _log_err(LOG_DEBUG, pamh, "bad authentication token"); - } - _make_remark(pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ? - "No password supplied" : "Password unchanged"); - return PAM_AUTHTOK_ERR; - } - /* - * if one wanted to hardwire authentication token strength - * checking this would be the place - AGM - */ - - retval = pam_get_item(pamh, PAM_USER, (const void **) &user); - if (retval != PAM_SUCCESS) { - if (on(UNIX_DEBUG, ctrl)) { - _log_err(LOG_ERR, pamh, "Can not get username"); - return PAM_AUTHTOK_ERR; - } - } - if (off(UNIX__IAMROOT, ctrl)) { -#ifdef USE_CRACKLIB - remark = FascistCheck(pass_new, CRACKLIB_DICTS); - D(("called cracklib [%s]", remark)); -#else - if (strlen(pass_new) < 6) - remark = "You must choose a longer password"; - D(("length check [%s]", remark)); -#endif - if (on(UNIX_REMEMBER_PASSWD, ctrl)) { - if ((retval = check_old_password(user, pass_new)) == PAM_AUTHTOK_ERR) - remark = "Password has been already used. Choose another."; - if (retval == PAM_ABORT) { - _log_err(LOG_ERR, pamh, "can't open %s file to check old passwords", - OLD_PASSWORDS_FILE); - return retval; - } - } - } - if (remark) { - _make_remark(pamh, ctrl, PAM_ERROR_MSG, remark); - retval = PAM_AUTHTOK_ERR; - } - return retval; -} - - -PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags, - int argc, const char **argv) -{ - unsigned int ctrl, lctrl; - int retval, i; - int remember = -1; - - /* <DO NOT free() THESE> */ - const char *user; - char *pass_old, *pass_new; - /* </DO NOT free() THESE> */ - - D(("called.")); - - ctrl = _set_ctrl(pamh, flags, &remember, argc, argv); - - /* - * First get the name of a user - */ - retval = pam_get_user(pamh, &user, NULL); - if (retval == PAM_SUCCESS) { - /* - * Various libraries at various times have had bugs related to - * '+' or '-' as the first character of a user name. Don't take - * any chances here. Require that the username starts with an - * alphanumeric character. - */ - if (user == NULL || !isalnum(*user)) { - _log_err(LOG_ERR, pamh, "bad username [%s]", user); - return PAM_USER_UNKNOWN; - } - if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl)) - _log_err(LOG_DEBUG, pamh, "username [%s] obtained", - user); - } else { - if (on(UNIX_DEBUG, ctrl)) - _log_err(LOG_DEBUG, pamh, - "password - could not identify user"); - return retval; - } - - D(("Got username of %s", user)); - - /* - * Before we do anything else, check to make sure that the user's - * info is in one of the databases we can modify from this module, - * which currently is 'files' and 'nis'. We have to do this because - * getpwnam() doesn't tell you *where* the information it gives you - * came from, nor should it. That's our job. - */ - if (_unix_comesfromsource(pamh, user, 1, 1) == 0) { - _log_err(LOG_DEBUG, pamh, - "user \"%s\" does not exist in /etc/passwd or NIS", - user); - return PAM_USER_UNKNOWN; - } else { - struct passwd *pwd; - _unix_getpwnam(pamh, user, 1, 1, &pwd); - if (pwd == NULL) { - _log_err(LOG_DEBUG, pamh, - "user \"%s\" has corrupted passwd entry", - user); - return PAM_USER_UNKNOWN; - } - if (!_unix_shadowed(pwd) && - (strchr(pwd->pw_passwd, '*') != NULL)) { - _log_err(LOG_DEBUG, pamh, - "user \"%s\" does not have modifiable password", - user); - return PAM_USER_UNKNOWN; - } - } - - /* - * This is not an AUTH module! - */ - if (on(UNIX__NONULL, ctrl)) - set(UNIX__NULLOK, ctrl); - - if (on(UNIX__PRELIM, ctrl)) { - /* - * obtain and verify the current password (OLDAUTHTOK) for - * the user. - */ - char *Announce; - - D(("prelim check")); - - if (_unix_blankpasswd(pamh, ctrl, user)) { - return PAM_SUCCESS; - } else if (off(UNIX__IAMROOT, ctrl)) { - - /* instruct user what is happening */ -#define greeting "Changing password for " - Announce = (char *) malloc(sizeof(greeting) + strlen(user)); - if (Announce == NULL) { - _log_err(LOG_CRIT, pamh, - "password - out of memory"); - return PAM_BUF_ERR; - } - (void) strcpy(Announce, greeting); - (void) strcpy(Announce + sizeof(greeting) - 1, user); -#undef greeting - - lctrl = ctrl; - set(UNIX__OLD_PASSWD, lctrl); - retval = _unix_read_password(pamh, lctrl - ,Announce - ,"(current) UNIX password: " - ,NULL - ,_UNIX_OLD_AUTHTOK - ,(const char **) &pass_old); - free(Announce); - - if (retval != PAM_SUCCESS) { - _log_err(LOG_NOTICE, pamh - ,"password - (old) token not obtained"); - return retval; - } - /* verify that this is the password for this user */ - - retval = _unix_verify_password(pamh, user, pass_old, ctrl); - } else { - D(("process run by root so do nothing this time around")); - pass_old = NULL; - retval = PAM_SUCCESS; /* root doesn't have too */ - } - - if (retval != PAM_SUCCESS) { - D(("Authentication failed")); - pass_old = NULL; - return retval; - } - retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old); - pass_old = NULL; - if (retval != PAM_SUCCESS) { - _log_err(LOG_CRIT, pamh, - "failed to set PAM_OLDAUTHTOK"); - } - retval = _unix_verify_shadow(user, ctrl); - if (retval == PAM_AUTHTOK_ERR) { - if (off(UNIX__IAMROOT, ctrl)) - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - "You must wait longer to change your password"); - else - retval = PAM_SUCCESS; - } - } else if (on(UNIX__UPDATE, ctrl)) { - /* - * tpass is used below to store the _pam_md() return; it - * should be _pam_delete()'d. - */ - - char *tpass = NULL; - int retry = 0; - - /* - * obtain the proposed password - */ - - D(("do update")); - - /* - * get the old token back. NULL was ok only if root [at this - * point we assume that this has already been enforced on a - * previous call to this function]. - */ - - if (off(UNIX_NOT_SET_PASS, ctrl)) { - retval = pam_get_item(pamh, PAM_OLDAUTHTOK - ,(const void **) &pass_old); - } else { - retval = pam_get_data(pamh, _UNIX_OLD_AUTHTOK - ,(const void **) &pass_old); - if (retval == PAM_NO_MODULE_DATA) { - retval = PAM_SUCCESS; - pass_old = NULL; - } - } - D(("pass_old [%s]", pass_old)); - - if (retval != PAM_SUCCESS) { - _log_err(LOG_NOTICE, pamh, "user not authenticated"); - return retval; - } - - D(("get new password now")); - - lctrl = ctrl; - - if (on(UNIX_USE_AUTHTOK, lctrl)) { - set(UNIX_USE_FIRST_PASS, lctrl); - } - retry = 0; - retval = PAM_AUTHTOK_ERR; - while ((retval != PAM_SUCCESS) && (retry++ < MAX_PASSWD_TRIES)) { - /* - * use_authtok is to force the use of a previously entered - * password -- needed for pluggable password strength checking - */ - - retval = _unix_read_password(pamh, lctrl - ,NULL - ,"Enter new UNIX password: " - ,"Retype new UNIX password: " - ,_UNIX_NEW_AUTHTOK - ,(const char **) &pass_new); - - if (retval != PAM_SUCCESS) { - if (on(UNIX_DEBUG, ctrl)) { - _log_err(LOG_ALERT, pamh - ,"password - new password not obtained"); - } - pass_old = NULL; /* tidy up */ - return retval; - } - D(("returned to _unix_chauthtok")); - - /* - * At this point we know who the user is and what they - * propose as their new password. Verify that the new - * password is acceptable. - */ - - if (pass_new[0] == '\0') { /* "\0" password = NULL */ - pass_new = NULL; - } - retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new); - } - - if (retval != PAM_SUCCESS) { - _log_err(LOG_NOTICE, pamh, - "new password not acceptable"); - pass_new = pass_old = NULL; /* tidy up */ - return retval; - } -#ifdef USE_LCKPWDF - /* These values for the number of attempts and the sleep time - are, of course, completely arbitrary. - My reading of the PAM docs is that, once pam_chauthtok() has been - called with PAM_UPDATE_AUTHTOK, we are obliged to take any - reasonable steps to make sure the token is updated; so retrying - for 1/10 sec. isn't overdoing it. */ - i=0; - while((retval = lckpwdf()) != 0 && i < 100) { - usleep(1000); - i++; - } - if(retval != 0) { - return PAM_AUTHTOK_LOCK_BUSY; - } -#endif - - if (pass_old) { - retval = _unix_verify_password(pamh, user, pass_old, ctrl); - if (retval != PAM_SUCCESS) { - _log_err(LOG_NOTICE, pamh, "user password changed by another process"); -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif - return retval; - } - } - - retval = _unix_verify_shadow(user, ctrl); - if (retval != PAM_SUCCESS) { - _log_err(LOG_NOTICE, pamh, "user not authenticated 2"); -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif - return retval; - } - - retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new); - if (retval != PAM_SUCCESS) { - _log_err(LOG_NOTICE, pamh, - "new password not acceptable 2"); - pass_new = pass_old = NULL; /* tidy up */ -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif - return retval; - } - - /* - * By reaching here we have approved the passwords and must now - * rebuild the password database file. - */ - - /* - * First we encrypt the new password. - */ - - if (on(UNIX_MD5_PASS, ctrl)) { - tpass = crypt_md5_wrapper(pass_new); - } else { - /* - * Salt manipulation is stolen from Rick Faith's passwd - * program. Sorry Rick :) -- alex - */ - - time_t tm; - char salt[3]; - - time(&tm); - salt[0] = bin_to_ascii(tm & 0x3f); - salt[1] = bin_to_ascii((tm >> 6) & 0x3f); - salt[2] = '\0'; - - if (off(UNIX_BIGCRYPT, ctrl) && strlen(pass_new) > 8) { - /* - * to avoid using the _extensions_ of the bigcrypt() - * function we truncate the newly entered password - * [Problems that followed from this are fixed as per - * Bug 521314.] - */ - char *temp = malloc(9); - - if (temp == NULL) { - _log_err(LOG_CRIT, pamh, - "out of memory for password"); - pass_new = pass_old = NULL; /* tidy up */ -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif - return PAM_BUF_ERR; - } - /* copy first 8 bytes of password */ - strncpy(temp, pass_new, 8); - temp[8] = '\0'; - - /* no longer need cleartext */ - tpass = bigcrypt(temp, salt); - - _pam_delete(temp); /* tidy up */ - } else { - tpass = bigcrypt(pass_new, salt); - } - } - - D(("password processed")); - - /* update the password database(s) -- race conditions..? */ - - retval = _do_setpass(pamh, user, pass_old, tpass, ctrl, - remember); - /* _do_setpass has called ulckpwdf for us */ - - _pam_delete(tpass); - pass_old = pass_new = NULL; - } else { /* something has broken with the module */ - _log_err(LOG_ALERT, pamh, - "password received unknown request"); - retval = PAM_ABORT; - } - - D(("retval was %d", retval)); - - return retval; -} - - -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_unix_passwd_modstruct = { - "pam_unix_passwd", - NULL, - NULL, - NULL, - NULL, - NULL, - pam_sm_chauthtok, -}; -#endif diff --git a/modules/pam_unix/pam_unix_sess.c b/modules/pam_unix/pam_unix_sess.c deleted file mode 100644 index b888b64f..00000000 --- a/modules/pam_unix/pam_unix_sess.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * $Id$ - * - * Copyright Alexander O. Yuriev, 1996. All rights reserved. - * Copyright Jan Rêkorajski, 1999. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <security/_pam_aconf.h> - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> - -/* indicate the following groups are defined */ - -#define PAM_SM_SESSION - -#include <security/_pam_macros.h> -#include <security/pam_modules.h> -#include <security/_pam_modutil.h> - -#ifndef LINUX_PAM -#include <security/pam_appl.h> -#endif /* LINUX_PAM */ - -#include "support.h" - -/* - * PAM framework looks for these entry-points to pass control to the - * session module. - */ - -PAM_EXTERN int pam_sm_open_session(pam_handle_t * pamh, int flags, - int argc, const char **argv) -{ - char *user_name, *service; - unsigned int ctrl; - int retval; - const char *login_name; - - D(("called.")); - - ctrl = _set_ctrl(pamh, flags, NULL, argc, argv); - - retval = pam_get_item(pamh, PAM_USER, (void *) &user_name); - if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) { - _log_err(LOG_CRIT, pamh, - "open_session - error recovering username"); - return PAM_SESSION_ERR; /* How did we get authenticated with - no username?! */ - } - retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service); - if (service == NULL || *service == '\0' || retval != PAM_SUCCESS) { - _log_err(LOG_CRIT, pamh, - "open_session - error recovering service"); - return PAM_SESSION_ERR; - } - login_name = _pammodutil_getlogin(pamh); - if (login_name == NULL) { - login_name = ""; - } - _log_err(LOG_INFO, pamh, "session opened for user %s by %s(uid=%d)", - user_name, login_name, getuid()); - - return PAM_SUCCESS; -} - -PAM_EXTERN int pam_sm_close_session(pam_handle_t * pamh, int flags, - int argc, const char **argv) -{ - char *user_name, *service; - unsigned int ctrl; - int retval; - - D(("called.")); - - ctrl = _set_ctrl(pamh, flags, NULL, argc, argv); - - retval = pam_get_item(pamh, PAM_USER, (void *) &user_name); - if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) { - _log_err(LOG_CRIT, pamh, - "close_session - error recovering username"); - return PAM_SESSION_ERR; /* How did we get authenticated with - no username?! */ - } - retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service); - if (service == NULL || *service == '\0' || retval != PAM_SUCCESS) { - _log_err(LOG_CRIT, pamh, - "close_session - error recovering service"); - return PAM_SESSION_ERR; - } - _log_err(LOG_INFO, pamh, "session closed for user %s" - ,user_name); - - return PAM_SUCCESS; -} - -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_unix_session_modstruct = { - "pam_unix_session", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL, -}; -#endif - diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c deleted file mode 100644 index a9df0c5f..00000000 --- a/modules/pam_unix/support.c +++ /dev/null @@ -1,1076 +0,0 @@ -/* - * $Id$ - * - * Copyright information at end of file. - */ - -#define _BSD_SOURCE - -#include <stdlib.h> -#include <unistd.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <malloc.h> -#include <pwd.h> -#include <shadow.h> -#include <limits.h> -#include <utmp.h> -#include <errno.h> -#include <signal.h> -#include <ctype.h> -#include <rpcsvc/ypclnt.h> - -#include <security/_pam_macros.h> -#include <security/pam_modules.h> -#include <security/_pam_modutil.h> - -#include "md5.h" -#include "support.h" - -extern char *crypt(const char *key, const char *salt); -extern char *bigcrypt(const char *key, const char *salt); - -/* syslogging function for errors and other information */ - -void _log_err(int err, pam_handle_t *pamh, const char *format,...) -{ - char *service = NULL; - char logname[256]; - va_list args; - - pam_get_item(pamh, PAM_SERVICE, (const void **) &service); - if (service) { - strncpy(logname, service, sizeof(logname)); - logname[sizeof(logname) - 1 - strlen("(pam_unix)")] = '\0'; - strncat(logname, "(pam_unix)", strlen("(pam_unix)")); - } else { - strncpy(logname, "pam_unix", sizeof(logname) - 1); - } - - va_start(args, format); - openlog(logname, LOG_CONS | LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -/* this is a front-end for module-application conversations */ - -static int converse(pam_handle_t * pamh, int ctrl, int nargs - ,struct pam_message **message - ,struct pam_response **response) -{ - int retval; - struct pam_conv *conv; - - D(("begin to converse")); - - retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv); - if (retval == PAM_SUCCESS) { - - retval = conv->conv(nargs, (const struct pam_message **) message - ,response, conv->appdata_ptr); - - D(("returned from application's conversation function")); - - if (retval != PAM_SUCCESS && on(UNIX_DEBUG, ctrl)) { - _log_err(LOG_DEBUG, pamh, "conversation failure [%s]" - ,pam_strerror(pamh, retval)); - } - } else if (retval != PAM_CONV_AGAIN) { - _log_err(LOG_ERR, pamh - ,"couldn't obtain coversation function [%s]" - ,pam_strerror(pamh, retval)); - } - D(("ready to return from module conversation")); - - return retval; /* propagate error status */ -} - -int _make_remark(pam_handle_t * pamh, unsigned int ctrl - ,int type, const char *text) -{ - int retval = PAM_SUCCESS; - - if (off(UNIX__QUIET, ctrl)) { - struct pam_message *pmsg[1], msg[1]; - struct pam_response *resp; - - pmsg[0] = &msg[0]; - msg[0].msg = text; - msg[0].msg_style = type; - - resp = NULL; - retval = converse(pamh, ctrl, 1, pmsg, &resp); - - if (resp) { - _pam_drop_reply(resp, 1); - } - } - return retval; -} - -/* - * set the control flags for the UNIX module. - */ - -int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int argc, - const char **argv) -{ - unsigned int ctrl; - - D(("called.")); - - ctrl = UNIX_DEFAULTS; /* the default selection of options */ - - /* set some flags manually */ - - if (getuid() == 0 && !(flags & PAM_CHANGE_EXPIRED_AUTHTOK)) { - D(("IAMROOT")); - set(UNIX__IAMROOT, ctrl); - } - if (flags & PAM_UPDATE_AUTHTOK) { - D(("UPDATE_AUTHTOK")); - set(UNIX__UPDATE, ctrl); - } - if (flags & PAM_PRELIM_CHECK) { - D(("PRELIM_CHECK")); - set(UNIX__PRELIM, ctrl); - } - if (flags & PAM_SILENT) { - D(("SILENT")); - set(UNIX__QUIET, ctrl); - } - /* now parse the arguments to this module */ - - while (argc-- > 0) { - int j; - - D(("pam_unix arg: %s", *argv)); - - for (j = 0; j < UNIX_CTRLS_; ++j) { - if (unix_args[j].token - && !strncmp(*argv, unix_args[j].token, strlen(unix_args[j].token))) { - break; - } - } - - if (j >= UNIX_CTRLS_) { - _log_err(LOG_ERR, pamh, - "unrecognized option [%s]", *argv); - } else { - ctrl &= unix_args[j].mask; /* for turning things off */ - ctrl |= unix_args[j].flag; /* for turning things on */ - - if (remember != NULL) { - if (j == UNIX_REMEMBER_PASSWD) { - *remember = strtol(*argv + 9, NULL, 10); - if ((*remember == INT_MIN) || (*remember == INT_MAX)) - *remember = -1; - if (*remember > 400) - *remember = 400; - } - } - } - - ++argv; /* step to next argument */ - } - - if (flags & PAM_DISALLOW_NULL_AUTHTOK) { - D(("DISALLOW_NULL_AUTHTOK")); - set(UNIX__NONULL, ctrl); - } - - /* auditing is a more sensitive version of debug */ - - if (on(UNIX_AUDIT, ctrl)) { - set(UNIX_DEBUG, ctrl); - } - /* return the set of flags */ - - D(("done.")); - return ctrl; -} - -static void _cleanup(pam_handle_t * pamh, void *x, int error_status) -{ - _pam_delete(x); -} - -/* ************************************************************** * - * Useful non-trivial functions * - * ************************************************************** */ - - /* - * the following is used to keep track of the number of times a user fails - * to authenticate themself. - */ - -#define FAIL_PREFIX "-UN*X-FAIL-" -#define UNIX_MAX_RETRIES 3 - -struct _pam_failed_auth { - char *user; /* user that's failed to be authenticated */ - char *name; /* attempt from user with name */ - int uid; /* uid of calling user */ - int euid; /* euid of calling process */ - int count; /* number of failures so far */ -}; - -#ifndef PAM_DATA_REPLACE -#error "Need to get an updated libpam 0.52 or better" -#endif - -static void _cleanup_failures(pam_handle_t * pamh, void *fl, int err) -{ - int quiet; - const char *service = NULL; - const char *ruser = NULL; - const char *rhost = NULL; - const char *tty = NULL; - struct _pam_failed_auth *failure; - - D(("called")); - - quiet = err & PAM_DATA_SILENT; /* should we log something? */ - err &= PAM_DATA_REPLACE; /* are we just replacing data? */ - failure = (struct _pam_failed_auth *) fl; - - if (failure != NULL) { - - if (!quiet && !err) { /* under advisement from Sun,may go away */ - - /* log the number of authentication failures */ - if (failure->count > 1) { - (void) pam_get_item(pamh, PAM_SERVICE, - (const void **)&service); - (void) pam_get_item(pamh, PAM_RUSER, - (const void **)&ruser); - (void) pam_get_item(pamh, PAM_RHOST, - (const void **)&rhost); - (void) pam_get_item(pamh, PAM_TTY, - (const void **)&tty); - _log_err(LOG_NOTICE, pamh, - "%d more authentication failure%s; " - "logname=%s uid=%d euid=%d " - "tty=%s ruser=%s rhost=%s " - "%s%s", - failure->count - 1, failure->count == 2 ? "" : "s", - failure->name, failure->uid, failure->euid, - tty ? tty : "", ruser ? ruser : "", - rhost ? rhost : "", - (failure->user && failure->user[0] != '\0') - ? " user=" : "", failure->user - ); - - if (failure->count > UNIX_MAX_RETRIES) { - _log_err(LOG_ALERT, pamh - ,"service(%s) ignoring max retries; %d > %d" - ,service == NULL ? "**unknown**" : service - ,failure->count - ,UNIX_MAX_RETRIES); - } - } - } - _pam_delete(failure->user); /* tidy up */ - _pam_delete(failure->name); /* tidy up */ - free(failure); - } -} - -/* - * _unix_getpwnam() searches only /etc/passwd and NIS to find user information - */ -static void _unix_cleanup(pam_handle_t *pamh, void *data, int error_status) -{ - free(data); -} - -int _unix_getpwnam(pam_handle_t *pamh, const char *name, - int files, int nis, struct passwd **ret) -{ - FILE *passwd; - char buf[16384]; - int matched = 0, buflen; - char *slogin, *spasswd, *suid, *sgid, *sgecos, *shome, *sshell, *p; - - memset(buf, 0, sizeof(buf)); - - if (!matched && files) { - int userlen = strlen(name); - passwd = fopen("/etc/passwd", "r"); - if (passwd != NULL) { - while (fgets(buf, sizeof(buf), passwd) != NULL) { - if ((buf[userlen] == ':') && - (strncmp(name, buf, userlen) == 0)) { - p = buf + strlen(buf) - 1; - while (isspace(*p) && (p >= buf)) { - *p-- = '\0'; - } - matched = 1; - break; - } - } - fclose(passwd); - } - } - - if (!matched && nis) { - char *userinfo = NULL, *domain = NULL; - int len = 0, i; - len = yp_get_default_domain(&domain); - if (len == YPERR_SUCCESS) { - len = yp_bind(domain); - } - if (len == YPERR_SUCCESS) { - i = yp_match(domain, "passwd.byname", name, - strlen(name), &userinfo, &len); - yp_unbind(domain); - if ((i == YPERR_SUCCESS) && (len < sizeof(buf))) { - strncpy(buf, userinfo, sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; - matched = 1; - } - } - } - - if (matched && (ret != NULL)) { - *ret = NULL; - - slogin = buf; - - spasswd = strchr(slogin, ':'); - if (spasswd == NULL) { - return matched; - } - *spasswd++ = '\0'; - - suid = strchr(spasswd, ':'); - if (suid == NULL) { - return matched; - } - *suid++ = '\0'; - - sgid = strchr(suid, ':'); - if (sgid == NULL) { - return matched; - } - *sgid++ = '\0'; - - sgecos = strchr(sgid, ':'); - if (sgecos == NULL) { - return matched; - } - *sgecos++ = '\0'; - - shome = strchr(sgecos, ':'); - if (shome == NULL) { - return matched; - } - *shome++ = '\0'; - - sshell = strchr(shome, ':'); - if (sshell == NULL) { - return matched; - } - *sshell++ = '\0'; - - buflen = sizeof(struct passwd) + - strlen(slogin) + 1 + - strlen(spasswd) + 1 + - strlen(suid) + 1 + - strlen(sgid) + 1 + - strlen(sgecos) + 1 + - strlen(shome) + 1 + - strlen(sshell) + 1; - *ret = malloc(buflen); - if (*ret == NULL) { - return matched; - } - memset(*ret, '\0', buflen); - - (*ret)->pw_uid = strtol(suid, &p, 10); - if ((strlen(sgid) == 0) || (*p != '\0')) { - free(*ret); - *ret = NULL; - return matched; - } - - (*ret)->pw_gid = strtol(sgid, &p, 10); - if ((strlen(sgid) == 0) || (*p != '\0')) { - free(*ret); - *ret = NULL; - return matched; - } - - p = ((char*)(*ret)) + sizeof(struct passwd); - (*ret)->pw_name = strcpy(p, slogin); - p += strlen(p) + 1; - (*ret)->pw_passwd = strcpy(p, spasswd); - p += strlen(p) + 1; - (*ret)->pw_gecos = strcpy(p, sgecos); - p += strlen(p) + 1; - (*ret)->pw_dir = strcpy(p, shome); - p += strlen(p) + 1; - (*ret)->pw_shell = strcpy(p, sshell); - - snprintf(buf, sizeof(buf), "_pam_unix_getpwnam_%s", name); - - if (pam_set_data(pamh, buf, - *ret, _unix_cleanup) != PAM_SUCCESS) { - free(*ret); - *ret = NULL; - } - } - - return matched; -} - -/* - * _unix_comsefromsource() is a quick check to see if information about a given - * user comes from a particular source (just files and nis for now) - * - */ -int _unix_comesfromsource(pam_handle_t *pamh, - const char *name, int files, int nis) -{ - return _unix_getpwnam(pamh, name, files, nis, NULL); -} - -/* - * _unix_blankpasswd() is a quick check for a blank password - * - * returns TRUE if user does not have a password - * - to avoid prompting for one in such cases (CG) - */ - -int -_unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name) -{ - struct passwd *pwd = NULL; - struct spwd *spwdent = NULL; - char *salt = NULL; - int retval; - - D(("called")); - - /* - * This function does not have to be too smart if something goes - * wrong, return FALSE and let this case to be treated somewhere - * else (CG) - */ - - if (on(UNIX__NONULL, ctrl)) - return 0; /* will fail but don't let on yet */ - - /* UNIX passwords area */ - - /* Get password file entry... */ - pwd = _pammodutil_getpwnam (pamh, name); - - if (pwd != NULL) { - if (strcmp( pwd->pw_passwd, "*NP*" ) == 0) - { /* NIS+ */ - uid_t save_euid, save_uid; - - save_euid = geteuid(); - save_uid = getuid(); - if (save_uid == pwd->pw_uid) - setreuid( save_euid, save_uid ); - else { - setreuid( 0, -1 ); - if (setreuid( -1, pwd->pw_uid ) == -1) { - setreuid( -1, 0 ); - setreuid( 0, -1 ); - if(setreuid( -1, pwd->pw_uid ) == -1) - /* Will fail elsewhere. */ - return 0; - } - } - - spwdent = _pammodutil_getspnam (pamh, name); - if (save_uid == pwd->pw_uid) - setreuid( save_uid, save_euid ); - else { - if (setreuid( -1, 0 ) == -1) - setreuid( save_uid, -1 ); - setreuid( -1, save_euid ); - } - } else if (_unix_shadowed(pwd)) { - /* - * ...and shadow password file entry for this user, - * if shadowing is enabled - */ - spwdent = _pammodutil_getspnam(pamh, name); - } - if (spwdent) - salt = x_strdup(spwdent->sp_pwdp); - else - salt = x_strdup(pwd->pw_passwd); - } - /* Does this user have a password? */ - if (salt == NULL) { - retval = 0; - } else { - if (strlen(salt) == 0) - retval = 1; - else - retval = 0; - } - - /* tidy up */ - - if (salt) - _pam_delete(salt); - - return retval; -} - -/* - * verify the password of a user - */ - -#include <sys/types.h> -#include <sys/wait.h> - -static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, - unsigned int ctrl, const char *user) -{ - int retval, child, fds[2]; - void (*sighandler)(int) = NULL; - - D(("called.")); - /* create a pipe for the password */ - if (pipe(fds) != 0) { - D(("could not make pipe")); - return PAM_AUTH_ERR; - } - - if (off(UNIX_NOREAP, ctrl)) { - /* - * This code arranges that the demise of the child does not cause - * the application to receive a signal it is not expecting - which - * may kill the application or worse. - * - * The "noreap" module argument is provided so that the admin can - * override this behavior. - */ - sighandler = signal(SIGCHLD, SIG_DFL); - } - - /* fork */ - child = fork(); - if (child == 0) { - static char *envp[] = { NULL }; - char *args[] = { NULL, NULL, NULL }; - - /* XXX - should really tidy up PAM here too */ - - /* reopen stdin as pipe */ - close(fds[1]); - dup2(fds[0], STDIN_FILENO); - - /* exec binary helper */ - args[0] = x_strdup(CHKPWD_HELPER); - args[1] = x_strdup(user); - - execve(CHKPWD_HELPER, args, envp); - - /* should not get here: exit with error */ - D(("helper binary is not available")); - exit(PAM_AUTHINFO_UNAVAIL); - } else if (child > 0) { - /* wait for child */ - /* if the stored password is NULL */ - if (off(UNIX__NONULL, ctrl)) { /* this means we've succeeded */ - write(fds[1], "nullok\0\0", 8); - } else { - write(fds[1], "nonull\0\0", 8); - } - if (passwd != NULL) { /* send the password to the child */ - write(fds[1], passwd, strlen(passwd)+1); - passwd = NULL; - } else { - write(fds[1], "", 1); /* blank password */ - } - close(fds[0]); /* close here to avoid possible SIGPIPE above */ - close(fds[1]); - (void) waitpid(child, &retval, 0); /* wait for helper to complete */ - retval = (retval == 0) ? PAM_SUCCESS:PAM_AUTH_ERR; - } else { - D(("fork failed")); - retval = PAM_AUTH_ERR; - } - - if (sighandler != NULL) { - (void) signal(SIGCHLD, sighandler); /* restore old signal handler */ - } - - D(("returning %d", retval)); - return retval; -} - -int _unix_verify_password(pam_handle_t * pamh, const char *name - ,const char *p, unsigned int ctrl) -{ - struct passwd *pwd = NULL; - struct spwd *spwdent = NULL; - char *salt = NULL; - char *pp = NULL; - char *data_name; - int retval; - - D(("called")); - -#ifdef HAVE_PAM_FAIL_DELAY - if (off(UNIX_NODELAY, ctrl)) { - D(("setting delay")); - (void) pam_fail_delay(pamh, 2000000); /* 2 sec delay for on failure */ - } -#endif - - /* locate the entry for this user */ - - D(("locating user's record")); - - /* UNIX passwords area */ - pwd = _pammodutil_getpwnam (pamh, name); /* Get password file entry... */ - - if (pwd != NULL) { - if (strcmp( pwd->pw_passwd, "*NP*" ) == 0) - { /* NIS+ */ - uid_t save_euid, save_uid; - - save_euid = geteuid(); - save_uid = getuid(); - if (save_uid == pwd->pw_uid) - setreuid( save_euid, save_uid ); - else { - setreuid( 0, -1 ); - if (setreuid( -1, pwd->pw_uid ) == -1) { - setreuid( -1, 0 ); - setreuid( 0, -1 ); - if(setreuid( -1, pwd->pw_uid ) == -1) - return PAM_CRED_INSUFFICIENT; - } - } - - spwdent = _pammodutil_getspnam (pamh, name); - if (save_uid == pwd->pw_uid) - setreuid( save_uid, save_euid ); - else { - if (setreuid( -1, 0 ) == -1) - setreuid( save_uid, -1 ); - setreuid( -1, save_euid ); - } - } else if (_unix_shadowed(pwd)) { - /* - * ...and shadow password file entry for this user, - * if shadowing is enabled - */ - spwdent = _pammodutil_getspnam (pamh, name); - } - if (spwdent) - salt = x_strdup(spwdent->sp_pwdp); - else - salt = x_strdup(pwd->pw_passwd); - } - - data_name = (char *) malloc(sizeof(FAIL_PREFIX) + strlen(name)); - if (data_name == NULL) { - _log_err(LOG_CRIT, pamh, "no memory for data-name"); - } else { - strcpy(data_name, FAIL_PREFIX); - strcpy(data_name + sizeof(FAIL_PREFIX) - 1, name); - } - - retval = PAM_SUCCESS; - if (pwd == NULL || salt == NULL || !strcmp(salt, "x") || ((salt[0] == '#') && (salt[1] == '#') && !strcmp(salt + 2, name))) { - if (geteuid()) { - /* we are not root perhaps this is the reason? Run helper */ - D(("running helper binary")); - retval = _unix_run_helper_binary(pamh, p, ctrl, name); - if (pwd == NULL && !on(UNIX_AUDIT,ctrl) - && retval != PAM_SUCCESS) - { - name = NULL; - } - } else { - D(("user's record unavailable")); - p = NULL; - if (pwd == NULL) - retval = PAM_USER_UNKNOWN; - else - retval = PAM_AUTHINFO_UNAVAIL; - if (on(UNIX_AUDIT, ctrl)) { - /* this might be a typo and the user has given a password - instead of a username. Careful with this. */ - _log_err(LOG_ALERT, pamh, - "check pass; user (%s) unknown", name); - } else { - name = NULL; - if (on(UNIX_DEBUG, ctrl) || pwd == NULL) { - _log_err(LOG_ALERT, pamh, - "check pass; user unknown"); - } else { - /* don't log failure as another pam module can succeed */ - goto cleanup; - } - } - } - } else { - int salt_len = strlen(salt); - if (!salt_len) { - /* the stored password is NULL */ - if (off(UNIX__NONULL, ctrl)) {/* this means we've succeeded */ - D(("user has empty password - access granted")); - retval = PAM_SUCCESS; - } else { - D(("user has empty password - access denied")); - retval = PAM_AUTH_ERR; - } - } else if (!p || (*salt == '*') || (salt_len < 13)) { - retval = PAM_AUTH_ERR; - } else { - if (!strncmp(salt, "$1$", 3)) { - pp = Goodcrypt_md5(p, salt); - if (strcmp(pp, salt) != 0) { - _pam_delete(pp); - pp = Brokencrypt_md5(p, salt); - } - } else { - pp = bigcrypt(p, salt); - } - p = NULL; /* no longer needed here */ - - /* the moment of truth -- do we agree with the password? */ - D(("comparing state of pp[%s] and salt[%s]", pp, salt)); - - /* - * Note, we are comparing the bigcrypt of the password with - * the contents of the password field. If the latter was - * encrypted with regular crypt (and not bigcrypt) it will - * have been truncated for storage relative to the output - * of bigcrypt here. As such we need to compare only the - * stored string with the subset of bigcrypt's result. - * Bug 521314: The strncmp comparison is for legacy support. - */ - if (strncmp(pp, salt, salt_len) == 0) { - retval = PAM_SUCCESS; - } else { - retval = PAM_AUTH_ERR; - } - } - } - - if (retval == PAM_SUCCESS) { - if (data_name) /* reset failures */ - pam_set_data(pamh, data_name, NULL, _cleanup_failures); - } else { - if (data_name != NULL) { - struct _pam_failed_auth *new = NULL; - const struct _pam_failed_auth *old = NULL; - - /* get a failure recorder */ - - new = (struct _pam_failed_auth *) - malloc(sizeof(struct _pam_failed_auth)); - - if (new != NULL) { - - const char *login_name; - - login_name = _pammodutil_getlogin(pamh); - if (login_name == NULL) { - login_name = ""; - } - - new->user = x_strdup(name ? name : ""); - new->uid = getuid(); - new->euid = geteuid(); - new->name = x_strdup(login_name); - - /* any previous failures for this user ? */ - pam_get_data(pamh, data_name, (const void **) &old); - - if (old != NULL) { - new->count = old->count + 1; - if (new->count >= UNIX_MAX_RETRIES) { - retval = PAM_MAXTRIES; - } - } else { - const char *service=NULL; - const char *ruser=NULL; - const char *rhost=NULL; - const char *tty=NULL; - - (void) pam_get_item(pamh, PAM_SERVICE, - (const void **)&service); - (void) pam_get_item(pamh, PAM_RUSER, - (const void **)&ruser); - (void) pam_get_item(pamh, PAM_RHOST, - (const void **)&rhost); - (void) pam_get_item(pamh, PAM_TTY, - (const void **)&tty); - - _log_err(LOG_NOTICE, pamh, - "authentication failure; " - "logname=%s uid=%d euid=%d " - "tty=%s ruser=%s rhost=%s " - "%s%s", - new->name, new->uid, new->euid, - tty ? tty : "", - ruser ? ruser : "", - rhost ? rhost : "", - (new->user && new->user[0] != '\0') - ? " user=" : "", - new->user - ); - new->count = 1; - } - - pam_set_data(pamh, data_name, new, _cleanup_failures); - - } else { - _log_err(LOG_CRIT, pamh, - "no memory for failure recorder"); - } - } - } - -cleanup: - if (data_name) - _pam_delete(data_name); - if (salt) - _pam_delete(salt); - if (pp) - _pam_delete(pp); - - D(("done [%d].", retval)); - - return retval; -} - -/* - * obtain a password from the user - */ - -int _unix_read_password(pam_handle_t * pamh - ,unsigned int ctrl - ,const char *comment - ,const char *prompt1 - ,const char *prompt2 - ,const char *data_name - ,const char **pass) -{ - int authtok_flag; - int retval; - char *token; - - D(("called")); - - /* - * make sure nothing inappropriate gets returned - */ - - *pass = token = NULL; - - /* - * which authentication token are we getting? - */ - - authtok_flag = on(UNIX__OLD_PASSWD, ctrl) ? PAM_OLDAUTHTOK : PAM_AUTHTOK; - - /* - * should we obtain the password from a PAM item ? - */ - - if (on(UNIX_TRY_FIRST_PASS, ctrl) || on(UNIX_USE_FIRST_PASS, ctrl)) { - retval = pam_get_item(pamh, authtok_flag, (const void **) pass); - if (retval != PAM_SUCCESS) { - /* very strange. */ - _log_err(LOG_ALERT, pamh - ,"pam_get_item returned error to unix-read-password" - ); - return retval; - } else if (*pass != NULL) { /* we have a password! */ - return PAM_SUCCESS; - } else if (on(UNIX_USE_FIRST_PASS, ctrl)) { - return PAM_AUTHTOK_RECOVER_ERR; /* didn't work */ - } else if (on(UNIX_USE_AUTHTOK, ctrl) - && off(UNIX__OLD_PASSWD, ctrl)) { - return PAM_AUTHTOK_ERR; - } - } - /* - * getting here implies we will have to get the password from the - * user directly. - */ - - { - struct pam_message msg[3], *pmsg[3]; - struct pam_response *resp; - int i, replies; - - /* prepare to converse */ - - if (comment != NULL && off(UNIX__QUIET, ctrl)) { - pmsg[0] = &msg[0]; - msg[0].msg_style = PAM_TEXT_INFO; - msg[0].msg = comment; - i = 1; - } else { - i = 0; - } - - pmsg[i] = &msg[i]; - msg[i].msg_style = PAM_PROMPT_ECHO_OFF; - msg[i++].msg = prompt1; - replies = 1; - - if (prompt2 != NULL) { - pmsg[i] = &msg[i]; - msg[i].msg_style = PAM_PROMPT_ECHO_OFF; - msg[i++].msg = prompt2; - ++replies; - } - /* so call the conversation expecting i responses */ - resp = NULL; - retval = converse(pamh, ctrl, i, pmsg, &resp); - - if (resp != NULL) { - - /* interpret the response */ - - if (retval == PAM_SUCCESS) { /* a good conversation */ - - token = x_strdup(resp[i - replies].resp); - if (token != NULL) { - if (replies == 2) { - - /* verify that password entered correctly */ - if (!resp[i - 1].resp - || strcmp(token, resp[i - 1].resp)) { - _pam_delete(token); /* mistyped */ - retval = PAM_AUTHTOK_RECOVER_ERR; - _make_remark(pamh, ctrl - ,PAM_ERROR_MSG, MISTYPED_PASS); - } - } - } else { - _log_err(LOG_NOTICE, pamh - ,"could not recover authentication token"); - } - - } - /* - * tidy up the conversation (resp_retcode) is ignored - * -- what is it for anyway? AGM - */ - - _pam_drop_reply(resp, i); - - } else { - retval = (retval == PAM_SUCCESS) - ? PAM_AUTHTOK_RECOVER_ERR : retval; - } - } - - if (retval != PAM_SUCCESS) { - if (on(UNIX_DEBUG, ctrl)) - _log_err(LOG_DEBUG, pamh, - "unable to obtain a password"); - return retval; - } - /* 'token' is the entered password */ - - if (off(UNIX_NOT_SET_PASS, ctrl)) { - - /* we store this password as an item */ - - retval = pam_set_item(pamh, authtok_flag, token); - _pam_delete(token); /* clean it up */ - if (retval != PAM_SUCCESS - || (retval = pam_get_item(pamh, authtok_flag - ,(const void **) pass)) - != PAM_SUCCESS) { - - *pass = NULL; - _log_err(LOG_CRIT, pamh, "error manipulating password"); - return retval; - - } - } else { - /* - * then store it as data specific to this module. pam_end() - * will arrange to clean it up. - */ - - retval = pam_set_data(pamh, data_name, (void *) token, _cleanup); - if (retval != PAM_SUCCESS) { - _log_err(LOG_CRIT, pamh - ,"error manipulating password data [%s]" - ,pam_strerror(pamh, retval)); - _pam_delete(token); - return retval; - } - *pass = token; - token = NULL; /* break link to password */ - } - - return PAM_SUCCESS; -} - -int _unix_shadowed(const struct passwd *pwd) -{ - if (pwd != NULL) { - if (strcmp(pwd->pw_passwd, "x") == 0) { - return 1; - } - if ((pwd->pw_passwd[0] == '#') && - (pwd->pw_passwd[1] == '#') && - (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)) { - return 1; - } - } - return 0; -} - -/* ****************************************************************** * - * Copyright (c) Jan Rêkorajski 1999. - * Copyright (c) Andrew G. Morgan 1996-8. - * Copyright (c) Alex O. Yuriev, 1996. - * Copyright (c) Cristian Gafton 1996. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h deleted file mode 100644 index b2aa4b40..00000000 --- a/modules/pam_unix/support.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * $Id$ - */ - -#ifndef _PAM_UNIX_SUPPORT_H -#define _PAM_UNIX_SUPPORT_H - -#include <pwd.h> - -/* - * here is the string to inform the user that the new passwords they - * typed were not the same. - */ - -#define MISTYPED_PASS "Sorry, passwords do not match" - -/* type definition for the control options */ - -typedef struct { - const char *token; - unsigned int mask; /* shall assume 32 bits of flags */ - unsigned int flag; -} UNIX_Ctrls; - -/* - * macro to determine if a given flag is on - */ - -#define on(x,ctrl) (unix_args[x].flag & ctrl) - -/* - * macro to determine that a given flag is NOT on - */ - -#define off(x,ctrl) (!on(x,ctrl)) - -/* - * macro to turn on/off a ctrl flag manually - */ - -#define set(x,ctrl) (ctrl = ((ctrl)&unix_args[x].mask)|unix_args[x].flag) -#define unset(x,ctrl) (ctrl &= ~(unix_args[x].flag)) - -/* the generic mask */ - -#define _ALL_ON_ (~0U) - -/* end of macro definitions definitions for the control flags */ - -/* ****************************************************************** * - * ctrl flags proper.. - */ - -/* - * here are the various options recognized by the unix module. They - * are enumerated here and then defined below. Internal arguments are - * given NULL tokens. - */ - -#define UNIX__OLD_PASSWD 0 /* internal */ -#define UNIX__VERIFY_PASSWD 1 /* internal */ -#define UNIX__IAMROOT 2 /* internal */ - -#define UNIX_AUDIT 3 /* print more things than debug.. - some information may be sensitive */ -#define UNIX_USE_FIRST_PASS 4 -#define UNIX_TRY_FIRST_PASS 5 -#define UNIX_NOT_SET_PASS 6 /* don't set the AUTHTOK items */ - -#define UNIX__PRELIM 7 /* internal */ -#define UNIX__UPDATE 8 /* internal */ -#define UNIX__NONULL 9 /* internal */ -#define UNIX__QUIET 10 /* internal */ -#define UNIX_USE_AUTHTOK 11 /* insist on reading PAM_AUTHTOK */ -#define UNIX_SHADOW 12 /* signal shadow on */ -#define UNIX_MD5_PASS 13 /* force the use of MD5 passwords */ -#define UNIX__NULLOK 14 /* Null token ok */ -#define UNIX_DEBUG 15 /* send more info to syslog(3) */ -#define UNIX_NODELAY 16 /* admin does not want a fail-delay */ -#define UNIX_NIS 17 /* wish to use NIS for pwd */ -#define UNIX_BIGCRYPT 18 /* use DEC-C2 crypt()^x function */ -#define UNIX_LIKE_AUTH 19 /* need to auth for setcred to work */ -#define UNIX_REMEMBER_PASSWD 20 /* Remember N previous passwords */ -#define UNIX_NOREAP 21 /* don't reap child process */ -#define UNIX_BROKEN_SHADOW 22 /* ignore errors reading password aging - * information during acct management */ -/* -------------- */ -#define UNIX_CTRLS_ 23 /* number of ctrl arguments defined */ - - -static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = -{ -/* symbol token name ctrl mask ctrl * - * ----------------------- ------------------- --------------------- -------- */ - -/* UNIX__OLD_PASSWD */ {NULL, _ALL_ON_, 01}, -/* UNIX__VERIFY_PASSWD */ {NULL, _ALL_ON_, 02}, -/* UNIX__IAMROOT */ {NULL, _ALL_ON_, 04}, -/* UNIX_AUDIT */ {"audit", _ALL_ON_, 010}, -/* UNIX_USE_FIRST_PASS */ {"use_first_pass", _ALL_ON_^(060), 020}, -/* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(060), 040}, -/* UNIX_NOT_SET_PASS */ {"not_set_pass", _ALL_ON_, 0100}, -/* UNIX__PRELIM */ {NULL, _ALL_ON_^(0600), 0200}, -/* UNIX__UPDATE */ {NULL, _ALL_ON_^(0600), 0400}, -/* UNIX__NONULL */ {NULL, _ALL_ON_, 01000}, -/* UNIX__QUIET */ {NULL, _ALL_ON_, 02000}, -/* UNIX_USE_AUTHTOK */ {"use_authtok", _ALL_ON_, 04000}, -/* UNIX_SHADOW */ {"shadow", _ALL_ON_, 010000}, -/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(0400000), 020000}, -/* UNIX__NULLOK */ {"nullok", _ALL_ON_^(01000), 0}, -/* UNIX_DEBUG */ {"debug", _ALL_ON_, 040000}, -/* UNIX_NODELAY */ {"nodelay", _ALL_ON_, 0100000}, -/* UNIX_NIS */ {"nis", _ALL_ON_^(010000), 0200000}, -/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(020000), 0400000}, -/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000}, -/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000}, -/* UNIX_NOREAP */ {"noreap", _ALL_ON_, 04000000}, -/* UNIX_BROKEN_SHADOW */ {"broken_shadow", _ALL_ON_, 010000000}, -}; - -#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag) - - -/* use this to free strings. ESPECIALLY password strings */ - -#define _pam_delete(xx) \ -{ \ - _pam_overwrite(xx); \ - _pam_drop(xx); \ -} - -extern void _log_err(int err, pam_handle_t *pamh, const char *format,...); -extern int _make_remark(pam_handle_t * pamh, unsigned int ctrl - ,int type, const char *text); -extern int _set_ctrl(pam_handle_t * pamh, int flags, int *remember, int argc, - const char **argv); -extern int _unix_getpwnam (pam_handle_t *pamh, - const char *name, int files, int nis, - struct passwd **ret); -extern int _unix_comesfromsource (pam_handle_t *pamh, - const char *name, int files, int nis); -extern int _unix_blankpasswd(pam_handle_t *pamh,unsigned int ctrl, - const char *name); -extern int _unix_verify_password(pam_handle_t * pamh, const char *name - ,const char *p, unsigned int ctrl); -extern int _unix_read_password(pam_handle_t * pamh - ,unsigned int ctrl - ,const char *comment - ,const char *prompt1 - ,const char *prompt2 - ,const char *data_name - ,const char **pass); -extern int _unix_shadowed(const struct passwd *pwd); - -#endif /* _PAM_UNIX_SUPPORT_H */ diff --git a/modules/pam_unix/unix_chkpwd.c b/modules/pam_unix/unix_chkpwd.c deleted file mode 100644 index ff1d1bff..00000000 --- a/modules/pam_unix/unix_chkpwd.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * $Id$ - * - * This program is designed to run setuid(root) or with sufficient - * privilege to read all of the unix password databases. It is designed - * to provide a mechanism for the current user (defined by this - * process' uid) to verify their own password. - * - * The password is read from the standard input. The exit status of - * this program indicates whether the user is authenticated or not. - * - * Copyright information is located at the end of the file. - * - */ - -#include <security/_pam_aconf.h> - -#ifdef MEMORY_DEBUG -# undef exit -# undef strdup -# undef free -#endif /* MEMORY_DEBUG */ - -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> -#include <sys/types.h> -#include <pwd.h> -#include <shadow.h> -#include <signal.h> - -#define MAXPASS 200 /* the maximum length of a password */ - -#include <security/_pam_macros.h> - -#include "md5.h" - -extern char *crypt(const char *key, const char *salt); -extern char *bigcrypt(const char *key, const char *salt); - -#define UNIX_PASSED 0 -#define UNIX_FAILED 1 - -/* syslogging function for errors and other information */ - -static void _log_err(int err, const char *format,...) -{ - va_list args; - - va_start(args, format); - openlog("unix_chkpwd", LOG_CONS | LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -static int _unix_shadowed(const struct passwd *pwd) -{ - char hashpass[1024]; - if (pwd != NULL) { - if (strcmp(pwd->pw_passwd, "x") == 0) { - return 1; - } - if (strlen(pwd->pw_name) < sizeof(hashpass) - 2) { - strcpy(hashpass, "##"); - strcpy(hashpass + 2, pwd->pw_name); - if (strcmp(pwd->pw_passwd, hashpass) == 0) { - return 1; - } - } - } - return 0; -} - -static void su_sighandler(int sig) -{ -#ifndef SA_RESETHAND - /* emulate the behaviour of the SA_RESETHAND flag */ - if ( sig == SIGILL || sig == SIGTRAP || sig == SIGBUS || sig = SIGSERV ) - signal(sig, SIG_DFL); -#endif - if (sig > 0) { - _log_err(LOG_NOTICE, "caught signal %d.", sig); - exit(sig); - } -} - -static void setup_signals(void) -{ - struct sigaction action; /* posix signal structure */ - - /* - * Setup signal handlers - */ - (void) memset((void *) &action, 0, sizeof(action)); - action.sa_handler = su_sighandler; -#ifdef SA_RESETHAND - action.sa_flags = SA_RESETHAND; -#endif - (void) sigaction(SIGILL, &action, NULL); - (void) sigaction(SIGTRAP, &action, NULL); - (void) sigaction(SIGBUS, &action, NULL); - (void) sigaction(SIGSEGV, &action, NULL); - action.sa_handler = SIG_IGN; - action.sa_flags = 0; - (void) sigaction(SIGTERM, &action, NULL); - (void) sigaction(SIGHUP, &action, NULL); - (void) sigaction(SIGINT, &action, NULL); - (void) sigaction(SIGQUIT, &action, NULL); -} - -static int _unix_verify_password(const char *name, const char *p, int nullok) -{ - struct passwd *pwd = NULL; - struct spwd *spwdent = NULL; - char *salt = NULL; - char *pp = NULL; - int retval = UNIX_FAILED; - int salt_len; - - /* UNIX passwords area */ - setpwent(); - pwd = getpwnam(name); /* Get password file entry... */ - endpwent(); - if (pwd != NULL) { - if (_unix_shadowed(pwd)) { - /* - * ...and shadow password file entry for this user, - * if shadowing is enabled - */ - setspent(); - spwdent = getspnam(name); - endspent(); - if (spwdent != NULL) - salt = x_strdup(spwdent->sp_pwdp); - else - pwd = NULL; - } else { - if (strcmp(pwd->pw_passwd, "*NP*") == 0) { /* NIS+ */ - uid_t save_uid; - - save_uid = geteuid(); - seteuid(pwd->pw_uid); - spwdent = getspnam(name); - seteuid(save_uid); - - salt = x_strdup(spwdent->sp_pwdp); - } else { - salt = x_strdup(pwd->pw_passwd); - } - } - } - if (pwd == NULL || salt == NULL) { - _log_err(LOG_ALERT, "check pass; user unknown"); - p = NULL; - return retval; - } - - salt_len = strlen(salt); - if (salt_len == 0) - return (nullok == 0) ? UNIX_FAILED : UNIX_PASSED; - else if (p == NULL || strlen(p) == 0) - return UNIX_FAILED; - - /* the moment of truth -- do we agree with the password? */ - retval = UNIX_FAILED; - if (!strncmp(salt, "$1$", 3)) { - pp = Goodcrypt_md5(p, salt); - if (strcmp(pp, salt) == 0) { - retval = UNIX_PASSED; - } else { - pp = Brokencrypt_md5(p, salt); - if (strcmp(pp, salt) == 0) - retval = UNIX_PASSED; - } - } else if ((*salt == '*') || (salt_len < 13)) { - retval = UNIX_FAILED; - } else { - pp = bigcrypt(p, salt); - /* - * Note, we are comparing the bigcrypt of the password with - * the contents of the password field. If the latter was - * encrypted with regular crypt (and not bigcrypt) it will - * have been truncated for storage relative to the output - * of bigcrypt here. As such we need to compare only the - * stored string with the subset of bigcrypt's result. - * Bug 521314: the strncmp comparison is for legacy support. - */ - if (strncmp(pp, salt, salt_len) == 0) { - retval = UNIX_PASSED; - } - } - p = NULL; /* no longer needed here */ - - /* clean up */ - { - char *tp = pp; - if (pp != NULL) { - while (tp && *tp) - *tp++ = '\0'; - free(pp); - } - pp = tp = NULL; - } - - return retval; -} - -static char *getuidname(uid_t uid) -{ - struct passwd *pw; - static char username[32]; - - pw = getpwuid(uid); - if (pw == NULL) - return NULL; - - strncpy(username, pw->pw_name, sizeof(username)); - username[sizeof(username) - 1] = '\0'; - - return username; -} - -int main(int argc, char *argv[]) -{ - char pass[MAXPASS + 1]; - char option[8]; - int npass, nullok; - int force_failure = 0; - int retval = UNIX_FAILED; - char *user; - - /* - * Catch or ignore as many signal as possible. - */ - setup_signals(); - - /* - * we establish that this program is running with non-tty stdin. - * this is to discourage casual use. It does *NOT* prevent an - * intruder from repeatadly running this program to determine the - * password of the current user (brute force attack, but one for - * which the attacker must already have gained access to the user's - * account). - */ - - if (isatty(STDIN_FILENO)) { - - _log_err(LOG_NOTICE - ,"inappropriate use of Unix helper binary [UID=%d]" - ,getuid()); - fprintf(stderr - ,"This binary is not designed for running in this way\n" - "-- the system administrator has been informed\n"); - sleep(10); /* this should discourage/annoy the user */ - return UNIX_FAILED; - } - - /* - * determine the current user's name is - */ - user = getuidname(getuid()); - if (argc == 2) { - /* if the caller specifies the username, verify that user - matches it */ - if (strcmp(user, argv[1])) { - force_failure = 1; - } - } - - /* read the nullok/nonull option */ - - npass = read(STDIN_FILENO, option, 8); - - if (npass < 0) { - _log_err(LOG_DEBUG, "no option supplied"); - return UNIX_FAILED; - } else { - option[7] = '\0'; - if (strncmp(option, "nullok", 8) == 0) - nullok = 1; - else - nullok = 0; - } - - /* read the password from stdin (a pipe from the pam_unix module) */ - - npass = read(STDIN_FILENO, pass, MAXPASS); - - if (npass < 0) { /* is it a valid password? */ - - _log_err(LOG_DEBUG, "no password supplied"); - - } else if (npass >= MAXPASS) { - - _log_err(LOG_DEBUG, "password too long"); - - } else { - if (npass == 0) { - /* the password is NULL */ - - retval = _unix_verify_password(user, NULL, nullok); - - } else { - /* does pass agree with the official one? */ - - pass[npass] = '\0'; /* NUL terminate */ - retval = _unix_verify_password(user, pass, nullok); - - } - } - - memset(pass, '\0', MAXPASS); /* clear memory of the password */ - - /* return pass or fail */ - - if ((retval != UNIX_PASSED) || force_failure) { - return UNIX_FAILED; - } else { - return UNIX_PASSED; - } -} - -/* - * Copyright (c) Andrew G. Morgan, 1996. All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_unix/yppasswd.h b/modules/pam_unix/yppasswd.h deleted file mode 100644 index 6b414be0..00000000 --- a/modules/pam_unix/yppasswd.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * yppasswdd - * Copyright 1994, 1995, 1996 Olaf Kirch, <okir@monad.swb.de> - * - * This program is covered by the GNU General Public License, version 2. - * It is provided in the hope that it is useful. However, the author - * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details. - * - * This file was generated automatically by rpcgen from yppasswd.x, and - * editied manually. - */ - -#ifndef _YPPASSWD_H_ -#define _YPPASSWD_H_ - -#define YPPASSWDPROG ((u_long)100009) -#define YPPASSWDVERS ((u_long)1) -#define YPPASSWDPROC_UPDATE ((u_long)1) - -/* - * The password struct passed by the update call. I renamed it to - * xpasswd to avoid a type clash with the one defined in <pwd.h>. - */ -#ifndef __sgi -typedef struct xpasswd { - char *pw_name; - char *pw_passwd; - int pw_uid; - int pw_gid; - char *pw_gecos; - char *pw_dir; - char *pw_shell; -} xpasswd; - -#else -#include <pwd.h> -typedef struct xpasswd xpasswd; -#endif - -/* The updated password information, plus the old password. - */ -typedef struct yppasswd { - char *oldpass; - xpasswd newpw; -} yppasswd; - -/* XDR encoding/decoding routines */ -bool_t xdr_xpasswd(XDR * xdrs, xpasswd * objp); -bool_t xdr_yppasswd(XDR * xdrs, yppasswd * objp); - -#endif /* _YPPASSWD_H_ */ diff --git a/modules/pam_unix/yppasswd_xdr.c b/modules/pam_unix/yppasswd_xdr.c deleted file mode 100644 index b1a60b4c..00000000 --- a/modules/pam_unix/yppasswd_xdr.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * yppasswdd - * Copyright 1994, 1995, 1996 Olaf Kirch, <okir@monad.swb.de> - * - * This program is covered by the GNU General Public License, version 2. - * It is provided in the hope that it is useful. However, the author - * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details. - * - * This file was generated automatically by rpcgen from yppasswd.x, and - * editied manually. - */ - -#include <security/_pam_aconf.h> - -#include <rpc/rpc.h> -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> -#include "yppasswd.h" - -bool_t -xdr_xpasswd(XDR * xdrs, xpasswd * objp) -{ - return xdr_string(xdrs, &objp->pw_name, ~0) - && xdr_string(xdrs, &objp->pw_passwd, ~0) - && xdr_int(xdrs, &objp->pw_uid) - && xdr_int(xdrs, &objp->pw_gid) - && xdr_string(xdrs, &objp->pw_gecos, ~0) - && xdr_string(xdrs, &objp->pw_dir, ~0) - && xdr_string(xdrs, &objp->pw_shell, ~0); -} - - -bool_t -xdr_yppasswd(XDR * xdrs, yppasswd * objp) -{ - return xdr_string(xdrs, &objp->oldpass, ~0) - && xdr_xpasswd(xdrs, &objp->newpw); -} diff --git a/modules/pam_userdb/.cvsignore b/modules/pam_userdb/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_userdb/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_userdb/Makefile b/modules/pam_userdb/Makefile deleted file mode 100644 index bbecaae1..00000000 --- a/modules/pam_userdb/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# -# 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!). - -# $Id$ -# Created by Cristian Gafton <gafton@redhat.com> - -include ../../Make.Rules - -TITLE=pam_userdb - -ifeq ($(HAVE_NDBM_H),yes) - WHICH_DB=ndbm - ifeq ($(HAVE_LIBNDBM),yes) - MODULE_SIMPLE_EXTRALIBS = -lndbm - endif -else -ifeq ($(HAVE_LIBDB),yes) - WHICH_DB=db - MODULE_SIMPLE_EXTRALIBS = -ldb -else - WHICH_DB=none -endif -endif - -ifeq ($(HAVE_LIBCRYPT),yes) - MODULE_SIMPLE_EXTRALIBS += -lcrypt -endif - -ifeq ($(WHICH_DB),none) - -include ../dont_makefile - -else - -MODULE_SIMPLE_EXTRAFILES = conv - -include ../Simple.Rules - -endif diff --git a/modules/pam_userdb/README b/modules/pam_userdb/README deleted file mode 100644 index fc56cfa0..00000000 --- a/modules/pam_userdb/README +++ /dev/null @@ -1,61 +0,0 @@ -pam_userdb: - Look up users in a .db database and verify their password against - what is contained in that database. The database will have been - created using db_load. - -RECOGNIZED ARGUMENTS: - debug write a message to syslog indicating success or - failure. - - db=[path] use the [path] database for performing lookup. There - is no default; the module will return PAM_IGNORE if - no database is provided. Some versions of DB will - automatically append ".db" to whatever pathname you - supply here. - - crypt=[mode] indicates whether encrypted or plaintext passwords - are stored in the database. If [mode] is "crypt", - passwords should be stored in the database in - crypt(3) form. If [mode] is "none" or any other - value, passwords should be stored in the database in - plaintext. - - icase make the password verification to be case insensitive - (ie when working with registration numbers and such) - only works with plaintext password storage. - - dump dump all the entries in the database to the log (eek, - don't do this by default!) - - use_authtok use the authentication token previously obtained by - another module that did the conversation with the - application. If this token can not be obtained then - the module will try to converse again. This option can - be used for stacking different modules that need to - deal with the authentication tokens. - - unknown_ok do not return error when checking for a user that is - not in the database. This can be used to stack more - than one pam_userdb module that will check a - username/password pair in more than a database. - - key_only the username and password are concatenated together - in the database hash as 'username-password' with a - random value. if the concatenation of the username and - password with a dash in the middle returns any result, - the user is valid. this is useful in cases where - the username may not be unique but the username and - password pair are. - -MODULE SERVICES PROVIDED: - auth _authentication and _setcred (blank) - -EXAMPLE USE: - auth sufficient pam_userdb.so icase db=/tmp/dbtest.db - -AUTHOR: - Cristian Gafton <gafton@redhat.com> - - - -$Id$ diff --git a/modules/pam_userdb/conv.c b/modules/pam_userdb/conv.c deleted file mode 100644 index de5d12f2..00000000 --- a/modules/pam_userdb/conv.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Conversation related functions - */ - -/* $Id */ -/* Copyright at the end of the file */ - -#include <stdlib.h> -#include <string.h> - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> - -#include "pam_userdb.h" - -/* - * dummy conversation function sending exactly one prompt - * and expecting exactly one response from the other party - */ -static int converse(pam_handle_t *pamh, - struct pam_message **message, - struct pam_response **response) -{ - int retval; - const struct pam_conv *conv; - - retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv ) ; - if (retval == PAM_SUCCESS) - retval = conv->conv(1, (const struct pam_message **)message, - response, conv->appdata_ptr); - - return retval; /* propagate error status */ -} - - -static char *_pam_delete(register char *xx) -{ - _pam_overwrite(xx); - _pam_drop(xx); - return NULL; -} - -/* - * This is a conversation function to obtain the user's password - */ -int conversation(pam_handle_t *pamh) -{ - struct pam_message msg[2],*pmsg[2]; - struct pam_response *resp; - int retval; - char * token = NULL; - - pmsg[0] = &msg[0]; - msg[0].msg_style = PAM_PROMPT_ECHO_OFF; - msg[0].msg = "Password: "; - - /* so call the conversation expecting i responses */ - resp = NULL; - retval = converse(pamh, pmsg, &resp); - - if (resp != NULL) { - const char * item; - /* interpret the response */ - if (retval == PAM_SUCCESS) { /* a good conversation */ - token = x_strdup(resp[0].resp); - if (token == NULL) { - return PAM_AUTHTOK_RECOVER_ERR; - } - } - - /* set the auth token */ - retval = pam_set_item(pamh, PAM_AUTHTOK, token); - token = _pam_delete(token); /* clean it up */ - if ( (retval != PAM_SUCCESS) || - (retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&item)) - != PAM_SUCCESS ) { - return retval; - } - - _pam_drop_reply(resp, 1); - } else { - retval = (retval == PAM_SUCCESS) - ? PAM_AUTHTOK_RECOVER_ERR:retval ; - } - - return retval; -} - -/* - * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999 - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_userdb/create.pl b/modules/pam_userdb/create.pl deleted file mode 100644 index 224204b7..00000000 --- a/modules/pam_userdb/create.pl +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/perl -# this program creates a database in ARGV[1] from pairs given on -# stdandard input -# -# $Id$ - -use DB_File; - -my $database = $ARGV[0]; -die "Use: create.pl <database>\n" unless ($database); -print "Using database: $database\n"; - -my %lusers = (); - -tie %lusers, 'DB_File', $database, O_RDWR|O_CREAT, 0644, $DB_HASH ; -while (<STDIN>) { - my ($user, $pass) = split; - - $lusers{$user} = $pass; -} -untie %lusers; - - diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c deleted file mode 100644 index a0a5b8b5..00000000 --- a/modules/pam_userdb/pam_userdb.c +++ /dev/null @@ -1,490 +0,0 @@ -/* pam_userdb module */ - -/* - * $Id$ - * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10 - * See the end of the file for Copyright Information - */ - -#include <security/_pam_aconf.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <syslog.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> - -#include "pam_userdb.h" - -#ifdef HAVE_NDBM_H -# include <ndbm.h> -#else -# ifdef HAVE_DB_H -# define DB_DBM_HSEARCH 1 /* use the dbm interface */ -# include <db.h> -# else -# error "failed to find a libdb or equivalent" -# endif -#endif - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> - -/* some syslogging */ - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog(MODULE_NAME, LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -static int -_pam_parse (int argc, const char **argv, - char **database, char **cryptmode) -{ - int ctrl; - - *database = NULL; - *cryptmode = NULL; - - /* step through arguments */ - for (ctrl = 0; argc-- > 0; ++argv) - { - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strcasecmp(*argv, "icase")) - ctrl |= PAM_ICASE_ARG; - else if (!strcasecmp(*argv, "dump")) - ctrl |= PAM_DUMP_ARG; - else if (!strcasecmp(*argv, "unknown_ok")) - ctrl |= PAM_UNKNOWN_OK_ARG; - else if (!strcasecmp(*argv, "key_only")) - ctrl |= PAM_KEY_ONLY_ARG; - else if (!strncasecmp(*argv,"db=", 3)) - { - *database = strdup((*argv) + 3); - if ((*database == NULL) || (strlen (*database) == 0)) - _pam_log(LOG_ERR, - "pam_parse: could not parse argument \"%s\"", - *argv); - } - else if (!strncasecmp(*argv,"crypt=", 6)) - { - *cryptmode = strdup((*argv) + 6); - if ((*cryptmode == NULL) || (strlen (*cryptmode) == 0)) - _pam_log(LOG_ERR, - "pam_parse: could not parse argument \"%s\"", - *argv); - } - else - { - _pam_log(LOG_ERR, "pam_parse: unknown option; %s", *argv); - } - } - - return ctrl; -} - - -/* - * Looks up an user name in a database and checks the password - * - * return values: - * 1 = User not found - * 0 = OK - * -1 = Password incorrect - * -2 = System error - */ -static int -user_lookup (const char *database, const char *cryptmode, - const char *user, const char *pass, int ctrl) -{ - DBM *dbm; - datum key, data; - - /* Open the DB file. */ - dbm = dbm_open(database, O_RDONLY, 0644); - if (dbm == NULL) { - _pam_log(LOG_ERR, "user_lookup: could not open database `%s'", - database); - return -2; - } - - /* dump out the database contents for debugging */ - if (ctrl & PAM_DUMP_ARG) { - _pam_log(LOG_INFO, "Database dump:"); - for (key = dbm_firstkey(dbm); key.dptr != NULL; - key = dbm_nextkey(dbm)) { - data = dbm_fetch(dbm, key); - _pam_log(LOG_INFO, "key[len=%d] = `%s', data[len=%d] = `%s'", - key.dsize, key.dptr, data.dsize, data.dptr); - } - } - - /* do some more init work */ - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - if (ctrl & PAM_KEY_ONLY_ARG) { - key.dptr = malloc(strlen(user) + 1 + strlen(pass) + 1); - sprintf(key.dptr, "%s-%s", user, pass); - key.dsize = strlen(key.dptr); - } else { - key.dptr = x_strdup(user); - key.dsize = strlen(user); - } - - if (key.dptr) { - data = dbm_fetch(dbm, key); - memset(key.dptr, 0, key.dsize); - free(key.dptr); - } - - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_INFO, "password in database is [%p]`%s', len is %d", - data.dptr, (char *) data.dptr, data.dsize); - } - - if (data.dptr != NULL) { - int compare = 0; - - if (ctrl & PAM_KEY_ONLY_ARG) - { - dbm_close (dbm); - return 0; /* found it, data contents don't matter */ - } - - if (strncasecmp(cryptmode, "crypt", 5) == 0) { - - /* crypt(3) password storage */ - - char *cryptpw; - char salt[2]; - - if (data.dsize != 13) { - compare = -2; - } else if (ctrl & PAM_ICASE_ARG) { - compare = -2; - } else { - salt[0] = *data.dptr; - salt[1] = *(data.dptr + 1); - - cryptpw = crypt (pass, salt); - - if (cryptpw) { - compare = strncasecmp (data.dptr, cryptpw, data.dsize); - } else { - compare = -2; - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_INFO, "crypt() returned NULL"); - } - }; - - }; - - } else { - - /* Unknown password encryption method - - * default to plaintext password storage - */ - - if (strlen(pass) != data.dsize) { - compare = 1; /* wrong password len -> wrong password */ - } else if (ctrl & PAM_ICASE_ARG) { - compare = strncasecmp(data.dptr, pass, data.dsize); - } else { - compare = strncmp(data.dptr, pass, data.dsize); - } - - if (strncasecmp(cryptmode, "none", 4) && ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_INFO, "invalid value for crypt parameter: %s", - cryptmode); - _pam_log(LOG_INFO, "defaulting to plaintext password mode"); - } - - } - - dbm_close(dbm); - if (compare == 0) - return 0; /* match */ - else - return -1; /* wrong */ - } else { - int saw_user = 0; - - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_INFO, "error returned by dbm_fetch: %s", - strerror(errno)); - } - - /* probably we should check dbm_error() here */ - - if ((ctrl & PAM_KEY_ONLY_ARG) == 0) { - dbm_close(dbm); - return 1; /* not key_only, so no entry => no entry for the user */ - } - - /* now handle the key_only case */ - for (key = dbm_firstkey(dbm); - key.dptr != NULL; - key = dbm_nextkey(dbm)) { - int compare; - /* first compare the user portion (case sensitive) */ - compare = strncmp(key.dptr, user, strlen(user)); - if (compare == 0) { - /* assume failure */ - compare = -1; - /* if we have the divider where we expect it to be... */ - if (key.dptr[strlen(user)] == '-') { - saw_user = 1; - if (key.dsize == strlen(user) + 1 + strlen(pass)) { - if (ctrl & PAM_ICASE_ARG) { - /* compare the password portion (case insensitive)*/ - compare = strncasecmp(key.dptr + strlen(user) + 1, - pass, - strlen(pass)); - } else { - /* compare the password portion (case sensitive) */ - compare = strncmp(key.dptr + strlen(user) + 1, - pass, - strlen(pass)); - } - } - } - if (compare == 0) { - dbm_close(dbm); - return 0; /* match */ - } - } - } - dbm_close(dbm); - if (saw_user) - return -1; /* saw the user, but password mismatch */ - else - return 1; /* not found */ - } - - /* NOT REACHED */ - return -2; -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - const char *username; - const char *password; - char *database = NULL; - char *cryptmode = NULL; - int retval = PAM_AUTH_ERR, ctrl; - - /* parse arguments */ - ctrl = _pam_parse(argc, argv, &database, &cryptmode); - if ((database == NULL) || (strlen(database) == 0)) { - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG,"can not get the database name"); - return PAM_SERVICE_ERR; - } - - /* Get the username */ - retval = pam_get_user(pamh, &username, NULL); - if ((retval != PAM_SUCCESS) || (!username)) { - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG,"can not get the username"); - return PAM_SERVICE_ERR; - } - - /* Converse just to be sure we have a password */ - retval = conversation(pamh); - if (retval != PAM_SUCCESS) { - _pam_log(LOG_ERR, "could not obtain password for `%s'", - username); - return PAM_CONV_ERR; - } - - /* Check if we got a password. The docs say that if we didn't have one, - * and use_authtok was specified as an argument, that we converse with the - * user anyway, so check for one and handle a failure for that case. If - * use_authtok wasn't specified, then we've already asked once and needn't - * do so again. */ - retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **) &password); - if ((retval != PAM_SUCCESS) && ((ctrl & PAM_USE_AUTHTOK_ARG) != 0)) { - retval = conversation(pamh); - if (retval != PAM_SUCCESS) { - _pam_log(LOG_ERR, "could not obtain password for `%s'", - username); - return PAM_CONV_ERR; - } - } - - /* Get the password */ - retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&password); - if (retval != PAM_SUCCESS) { - _pam_log(LOG_ERR, "Could not retrieve user's password"); - return -2; - } - - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_INFO, "Verify user `%s' with password `%s'", - username, password); - - /* Now use the username to look up password in the database file */ - retval = user_lookup(database, cryptmode, username, password, ctrl); - switch (retval) { - case -2: - /* some sort of system error. The log was already printed */ - return PAM_SERVICE_ERR; - case -1: - /* incorrect password */ - _pam_log(LOG_WARNING, - "user `%s' denied access (incorrect password)", - username); - return PAM_AUTH_ERR; - case 1: - /* the user does not exist in the database */ - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_NOTICE, "user `%s' not found in the database", - username); - return PAM_USER_UNKNOWN; - case 0: - /* Otherwise, the authentication looked good */ - _pam_log(LOG_NOTICE, "user '%s' granted acces", username); - return PAM_SUCCESS; - default: - /* we don't know anything about this return value */ - _pam_log(LOG_ERR, - "internal module error (retval = %d, user = `%s'", - retval, username); - return PAM_SERVICE_ERR; - } - - /* should not be reached */ - return PAM_IGNORE; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - const char *username; - char *database = NULL; - char *cryptmode = NULL; - int retval = PAM_AUTH_ERR, ctrl; - - /* parse arguments */ - ctrl = _pam_parse(argc, argv, &database, &cryptmode); - - /* Get the username */ - retval = pam_get_user(pamh, &username, NULL); - if ((retval != PAM_SUCCESS) || (!username)) { - if (ctrl & PAM_DEBUG_ARG) - _pam_log(LOG_DEBUG,"can not get the username"); - return PAM_SERVICE_ERR; - } - - /* Now use the username to look up password in the database file */ - retval = user_lookup(database, cryptmode, username, "", ctrl); - switch (retval) { - case -2: - /* some sort of system error. The log was already printed */ - return PAM_SERVICE_ERR; - case -1: - /* incorrect password, but we don't care */ - /* FALL THROUGH */ - case 0: - /* authentication succeeded. dumbest password ever. */ - return PAM_SUCCESS; - case 1: - /* the user does not exist in the database */ - return PAM_USER_UNKNOWN; - default: - /* we don't know anything about this return value */ - _pam_log(LOG_ERR, - "internal module error (retval = %d, user = `%s'", - retval, username); - return PAM_SERVICE_ERR; - } - - return PAM_SUCCESS; -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_userdb_modstruct = { - "pam_userdb", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; - -#endif - -/* - * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999 - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_userdb/pam_userdb.h b/modules/pam_userdb/pam_userdb.h deleted file mode 100644 index a371fa9f..00000000 --- a/modules/pam_userdb/pam_userdb.h +++ /dev/null @@ -1,64 +0,0 @@ - -#ifndef _PAM_USERSDB_H -#define _PAM_USERSDB_H -/* $Id$ */ - -/* Header files */ -#include <security/pam_appl.h> - -/* argument parsing */ -#define PAM_DEBUG_ARG 0x0001 -#define PAM_ICASE_ARG 0x0002 -#define PAM_DUMP_ARG 0x0004 -#define PAM_USE_AUTHTOK_ARG 0x0008 -#define PAM_UNKNOWN_OK_ARG 0x0010 -#define PAM_KEY_ONLY_ARG 0x0020 - -/* Useful macros */ -#define x_strdup(s) ( (s) ? strdup(s):NULL ) - -/* The name of the module we are compiling */ -#ifndef MODULE_NAME -#define MODULE_NAME "pam_userdb" -#endif /* MODULE_NAME */ - -/* function prototypes */ -int conversation(pam_handle_t *); - -#endif /* _PAM_USERSDB_H */ - -/* - * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999 - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_warn/.cvsignore b/modules/pam_warn/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_warn/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_warn/Makefile b/modules/pam_warn/Makefile deleted file mode 100644 index 44c56f17..00000000 --- a/modules/pam_warn/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_warn - -include ../Simple.Rules diff --git a/modules/pam_warn/README b/modules/pam_warn/README deleted file mode 100644 index 6d484bdf..00000000 --- a/modules/pam_warn/README +++ /dev/null @@ -1,26 +0,0 @@ -# $Id$ -# - -This module is an authentication module that does not authenticate. -Instead it always returns PAM_IGNORE, indicating that it does not want -to affect the authentication process. - -Its purpose is to log a message to the syslog indicating the -pam_item's available at the time it was invoked. It is a diagnostic -tool. - -Recognized arguments: - - <none> - -module services provided: - - auth _authenticate and _setcred (blank) - acct _acct_mgmt [mapped to _authenticate] - session _open_session and - _close_session [mapped to _authenticate ] - password _chauthtok [mapped to _authenticate] - - -Andrew Morgan -1996/11/14 diff --git a/modules/pam_warn/pam_warn.c b/modules/pam_warn/pam_warn.c deleted file mode 100644 index f167ea91..00000000 --- a/modules/pam_warn/pam_warn.c +++ /dev/null @@ -1,127 +0,0 @@ -/* pam_warn module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11 - */ - -#define _BSD_SOURCE - -#include <stdio.h> -#include <unistd.h> -#include <syslog.h> -#include <stdarg.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> - -/* some syslogging */ - -#define OBTAIN(item, value, default_value) do { \ - (void) pam_get_item(pamh, item, (const void **) &value); \ - value = value ? value : default_value ; \ -} while (0) - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-warn", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -static void log_items(pam_handle_t *pamh, const char *function) -{ - const char *service=NULL, *user=NULL, *terminal=NULL, - *rhost=NULL, *ruser=NULL; - - OBTAIN(PAM_SERVICE, service, "<unknown>"); - OBTAIN(PAM_TTY, terminal, "<unknown>"); - OBTAIN(PAM_USER, user, "<unknown>"); - OBTAIN(PAM_RUSER, ruser, "<unknown>"); - OBTAIN(PAM_RHOST, rhost, "<unknown>"); - - _pam_log(LOG_NOTICE, "function=[%s] service=[%s] terminal=[%s] user=[%s]" - " ruser=[%s] rhost=[%s]\n", - function, service, terminal, user, ruser, rhost); -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - log_items(pamh, __FUNCTION__); - return PAM_IGNORE; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - log_items(pamh, __FUNCTION__); - return PAM_IGNORE; -} - -/* password updating functions */ - -PAM_EXTERN -int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv) -{ - log_items(pamh, __FUNCTION__); - return PAM_IGNORE; -} - -PAM_EXTERN int -pam_sm_acct_mgmt (pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - log_items(pamh, __FUNCTION__); - return PAM_IGNORE; -} - -PAM_EXTERN int -pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - log_items(pamh, __FUNCTION__); - return PAM_IGNORE; -} - -PAM_EXTERN int -pam_sm_close_session (pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - log_items(pamh, __FUNCTION__); - return PAM_IGNORE; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_warn_modstruct = { - "pam_warn", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_wheel/.cvsignore b/modules/pam_wheel/.cvsignore deleted file mode 100644 index 380a834a..00000000 --- a/modules/pam_wheel/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -dynamic diff --git a/modules/pam_wheel/Makefile b/modules/pam_wheel/Makefile deleted file mode 100644 index 66945ff5..00000000 --- a/modules/pam_wheel/Makefile +++ /dev/null @@ -1,15 +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!). -# -# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27 -# - -include ../../Make.Rules - -TITLE=pam_wheel - -include ../Simple.Rules diff --git a/modules/pam_wheel/README b/modules/pam_wheel/README deleted file mode 100644 index 2cd156c0..00000000 --- a/modules/pam_wheel/README +++ /dev/null @@ -1,39 +0,0 @@ - -pam_wheel: - only permit root authentication to members of wheel group - -RECOGNIZED ARGUMENTS: - debug Write a message to syslog indicating success or - failure. - - use_uid The check for wheel membership will be done against - the current uid instead of the original one - (useful when jumping with su from one account to - another for example). - - trust The pam_wheel module will return PAM_SUCCESS instead - of PAM_IGNORE if the user is a member of the wheel - group (thus with a little play stacking the modules - the wheel members may be able to su to root without - being prompted for a passwd). - - deny Reverse the sense of the auth operation: if the user - is trying to get UID 0 access and is a member of the - wheel group, deny access (well, kind of nonsense, but - for use in conjunction with 'group' argument... :-) - Conversely, if the user is not in the group, return - PAM_IGNORE (unless 'trust' was also specified, in - which case we return PAM_SUCCESS). - - group=xxxx Instead of checking the wheel or GID 0 groups, use - the xxxx group to perform the authentification. - - root_only The check for wheel membership is done only - if the uid of requested account is 0. - -MODULE SERVICES PROVIDED: - auth _authentication, _setcred (blank) and _acct_mgmt - -AUTHOR: - Cristian Gafton <gafton@redhat.com> - diff --git a/modules/pam_wheel/pam_wheel.c b/modules/pam_wheel/pam_wheel.c deleted file mode 100644 index 92cd44b9..00000000 --- a/modules/pam_wheel/pam_wheel.c +++ /dev/null @@ -1,327 +0,0 @@ -/* pam_wheel module */ - -/* - * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10 - * See the end of the file for Copyright Information - * - * - * 1.2 - added 'deny' and 'group=' options - * 1.1 - added 'trust' option - * 1.0 - the code is working for at least another person, so... :-) - * 0.1 - use vsyslog instead of vfprintf/syslog in _pam_log - * - return PAM_IGNORE on success (take care of sloppy sysadmins..) - * - use pam_get_user instead of pam_get_item(...,PAM_USER,...) - * - a new arg use_uid to auth the current uid instead of the - * initial (logged in) one. - * 0.0 - first release - * - * TODO: - * - try to use make_remark from pam_unix/support.c - * - consider returning on failure PAM_FAIL_NOW if the user is not - * a wheel member. - */ - -#define _BSD_SOURCE - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <syslog.h> -#include <stdarg.h> -#include <sys/types.h> -#include <pwd.h> -#include <grp.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> -#include <security/_pam_modutil.h> - -/* some syslogging */ - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-Wheel", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -/* checks if a user is on a list of members of the GID 0 group */ - -static int is_on_list(char * const *list, const char *member) -{ - while (list && *list) { - if (strcmp(*list, member) == 0) - return 1; - list++; - } - return 0; -} - -/* argument parsing */ - -#define PAM_DEBUG_ARG 0x0001 -#define PAM_USE_UID_ARG 0x0002 -#define PAM_TRUST_ARG 0x0004 -#define PAM_DENY_ARG 0x0010 -#define PAM_ROOT_ONLY_ARG 0x0020 - -static int _pam_parse(int argc, const char **argv, char *use_group, - size_t group_length) -{ - int ctrl=0; - - memset(use_group, '\0', group_length); - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strcmp(*argv,"use_uid")) - ctrl |= PAM_USE_UID_ARG; - else if (!strcmp(*argv,"trust")) - ctrl |= PAM_TRUST_ARG; - else if (!strcmp(*argv,"deny")) - ctrl |= PAM_DENY_ARG; - else if (!strcmp(*argv,"root_only")) - ctrl |= PAM_ROOT_ONLY_ARG; - else if (!strncmp(*argv,"group=",6)) - strncpy(use_group,*argv+6,group_length-1); - else { - _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv); - } - } - - return ctrl; -} - -static int perform_check(pam_handle_t *pamh, int flags, int ctrl, - const char *use_group) -{ - const char *username = NULL; - const char *fromsu; - struct passwd *pwd, *tpwd = NULL; - struct group *grp; - int retval = PAM_AUTH_ERR; - - retval = pam_get_user(pamh, &username, NULL); - if ((retval != PAM_SUCCESS) || (!username)) { - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_DEBUG,"can not get the username"); - } - return PAM_SERVICE_ERR; - } - - pwd = _pammodutil_getpwnam (pamh, username); - if (!pwd) { - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_NOTICE,"unknown user %s",username); - } - return PAM_USER_UNKNOWN; - } - if (ctrl & PAM_ROOT_ONLY_ARG) { - /* su to a non uid 0 account ? */ - if (pwd->pw_uid != 0) { - return PAM_IGNORE; - } - } - - if (ctrl & PAM_USE_UID_ARG) { - tpwd = _pammodutil_getpwuid (pamh, getuid()); - if (!tpwd) { - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_NOTICE, "who is running me ?!"); - } - return PAM_SERVICE_ERR; - } - fromsu = tpwd->pw_name; - } else { - fromsu = _pammodutil_getlogin(pamh); - if (fromsu) { - tpwd = _pammodutil_getpwnam (pamh, fromsu); - } - if (!fromsu || !tpwd) { - if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_NOTICE, "who is running me ?!"); - } - return PAM_SERVICE_ERR; - } - } - - /* - * At this point fromsu = username-of-invoker; tpwd = pwd ptr for fromsu - */ - - if (!use_group[0]) { - if ((grp = _pammodutil_getgrnam (pamh, "wheel")) == NULL) { - grp = _pammodutil_getgrgid (pamh, 0); - } - } else { - grp = _pammodutil_getgrnam (pamh, use_group); - } - - if (!grp || (!grp->gr_mem && (tpwd->pw_gid != grp->gr_gid))) { - if (ctrl & PAM_DEBUG_ARG) { - if (!use_group[0]) { - _pam_log(LOG_NOTICE,"no members in a GID 0 group"); - } else { - _pam_log(LOG_NOTICE,"no members in '%s' group", use_group); - } - } - if (ctrl & PAM_DENY_ARG) { - /* if this was meant to deny access to the members - * of this group and the group does not exist, allow - * access - */ - return PAM_IGNORE; - } else { - return PAM_AUTH_ERR; - } - } - - /* - * test if the user is a member of the group, or if the - * user has the "wheel" (sic) group as its primary group. - */ - - if (is_on_list(grp->gr_mem, fromsu) || (tpwd->pw_gid == grp->gr_gid)) { - - if (ctrl & PAM_DENY_ARG) { - retval = PAM_PERM_DENIED; - - } else if (ctrl & PAM_TRUST_ARG) { - retval = PAM_SUCCESS; /* this can be a sufficient check */ - - } else { - retval = PAM_IGNORE; - } - - } else { - - if (ctrl & PAM_DENY_ARG) { - - if (ctrl & PAM_TRUST_ARG) { - retval = PAM_SUCCESS; /* this can be a sufficient check */ - } else { - retval = PAM_IGNORE; - } - - } else { - retval = PAM_PERM_DENIED; - } - } - - if (ctrl & PAM_DEBUG_ARG) { - if (retval == PAM_IGNORE) { - _pam_log(LOG_NOTICE, "Ignoring access request '%s' for '%s'", - fromsu, username); - } else { - _pam_log(LOG_NOTICE, "Access %s to '%s' for '%s'", - (retval != PAM_SUCCESS) ? "denied":"granted", - fromsu, username); - } - } - - return retval; -} - -/* --- authentication management functions --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - char use_group[BUFSIZ]; - int ctrl; - - ctrl = _pam_parse(argc, argv, use_group, sizeof(use_group)); - - return perform_check(pamh, flags, ctrl, use_group); -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - char use_group[BUFSIZ]; - int ctrl; - - ctrl = _pam_parse(argc, argv, use_group, sizeof(use_group)); - - return perform_check(pamh, flags, ctrl, use_group); -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_wheel_modstruct = { - "pam_wheel", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, - NULL, -}; - -#endif /* PAM_STATIC */ - -/* - * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1996, 1997 - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/modules/pam_xauth/Makefile b/modules/pam_xauth/Makefile deleted file mode 100644 index 385466a2..00000000 --- a/modules/pam_xauth/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# 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_xauth -MAN8=pam_xauth.8 - -include ../Simple.Rules diff --git a/modules/pam_xauth/README b/modules/pam_xauth/README deleted file mode 100644 index dd65292f..00000000 --- a/modules/pam_xauth/README +++ /dev/null @@ -1,41 +0,0 @@ -pam_xauth: - Forward xauth cookies from user to user, normally used by su, sudo, or - userhelper. - - Primitive access control is provided by ~/.xauth/export in the invoking - user's home directory and ~/.xauth/import in the target user's home - directory. - - If a user has a ~/.xauth/import file, the user will only receive cookies - from users listed in the file. If there is no ~/.xauth/import file, - the user will accept cookies from any other user. - - If a user has a .xauth/export file, the user will only forward cookies - to users listed in the file. If there is no ~/.xauth/export file, and - the invoking user is not "root", the user will forward cookies to - any other user. If there is no ~/.xauth/export file, and the invoking - user is "root", the user will NOT forward cookies to other users. - - Both the import and export files support wildcards (such as "*"). Both - the import and export files can be empty, signifying that no users are - allowed. - -RECOGNIZED ARGUMENTS: - debug write debugging messages to syslog - xauthpath= the path to the xauth program, by default - /usr/X11R6/bin/xauth - systemuser= highest user id assigned to system users, defaults - to 499 (pam_xauth will refuse to forward creds to - target users with id equal to or below this number, - except for root and possibly another specified user) - targetuser= a target user id which is excepted from the systemuser - checks - - -MODULE SERVICES PROVIDED: - session open session copies xauth cookie to new user - close session deletes copied xauth cookie - -AUTHOR: - Nalin Dahyabhai <nalin@redhat.com>, based on original version by - Michael K. Johnson <johnsonm@redhat.com> diff --git a/modules/pam_xauth/pam_xauth.8 b/modules/pam_xauth/pam_xauth.8 deleted file mode 100644 index 9acb7249..00000000 --- a/modules/pam_xauth/pam_xauth.8 +++ /dev/null @@ -1,82 +0,0 @@ -.\" Copyright 2001,2003 Red Hat, Inc. -.\" Written by Nalin Dahyabhai <nalin@redhat.com>, based on the original -.\" version by Michael K. Johnson -.TH pam_xauth 8 2003/7/24 "Red Hat Linux" "System Administrator's Manual" -.SH NAME -pam_xauth \- forward xauth keys between users -.SH SYNOPSIS -.B session optional /lib/security/pam_xauth.so \fIarguments\fP -.SH DESCRIPTION -pam_xauth.so is designed to forward xauth keys (sometimes referred -to as "cookies") between users. - -Without pam_xauth, when xauth is enabled and a user uses the \fBsu\fP command -to assume another user's priviledges, that user is no longer able to access -the original user's X display because the new user does not have the key -needed to access the display. pam_xauth solves the problem by forwarding the -key from the user running su (the source user) to the user whose -identity the source user is assuming (the target user) when the session -is created, and destroying the key when the session is torn down. - -This means, for example, that when you run \fBsu\fP from an xterm sesssion, -you will be able to run X programs without explicitly dealing with the -xauth command or ~/.Xauthority files. - -pam_xauth will only forward keys if xauth can list a key connected -to the $DISPLAY environment variable. - -Primitive access control is provided by \fB~/.xauth/export\fP in the invoking -user's home directory and \fB~/.xauth/import\fP in the target user's home -directory. - -If a user has a \fB~/.xauth/import\fP file, the user will only receive cookies -from users listed in the file. If there is no \fB~/.xauth/import\fP file, -the user will accept cookies from any other user. - -If a user has a \fB.xauth/export\fP file, the user will only forward cookies -to users listed in the file. If there is no \fB~/.xauth/export\fP file, and -the invoking user is not \fBroot\fP, the user will forward cookies to -any other user. If there is no \fB~/.xauth/export\fP file, and the invoking -user is \fBroot\fP, the user will \fInot\fP forward cookies to other users. - -Both the import and export files support wildcards (such as \fI*\fP). Both -the import and export files can be empty, signifying that no users are allowed. - -.SH ARGUMENTS -.IP debug -Turns on debugging messages sent to syslog. -.IP xauthpath=\fI/usr/X11R6/bin/xauth\fP -Specify the path the xauth program (the default is /usr/X11R6/bin/xauth). -.IP systemuser=\fInumber\fP -Specify the highest UID which will be assumed to belong to a "system" user. -pam_xauth will refuse to forward credentials to users with UID less than or -equal to this number, except for root and the "targetuser", if specified. -.IP targetuser=\fInumber\fP -Specify a single target UID which is exempt from the systemuser check. -.SH "IMPLEMENTATION DETAILS" -pam_xauth will work \fIonly\fP if it is used from a setuid application -in which the getuid() call returns the id of the user running the -application, and for which PAM can supply the name of the account that -the user is attempting to assume. The typical application of this -type is \fBsu\fP. The application must call both pam_open_session() and -pam_close_session() with the ruid set to the uid of the calling user -and the euid set to root, and must have provided as the PAM_USER item -the name of the target user. - -pam_xauth calls \fBxauth\fP as the source user to extract the key for -$DISPLAY, then calls xauth as the target user to merge the key -into the a temporary database and later remove the database. - -pam_xauth cannot be told not to remove the keys when the session -is closed. -.SH "SEE ALSO" -\fI/usr/share/doc/pam*/html/index.html\fP -.SH FILES -\fI~/.xauth/import\fP -\fI~/.xauth/export\fP -.SH BUGS -Let's hope not, but if you find any, please report them via the "Bug Track" -link at http://bugzilla.redhat.com/bugzilla/ -.SH AUTHOR -Nalin Dahyabhai <nalin@redhat.com>, based on original version by -Michael K. Johnson <johnsonm@redhat.com> diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c deleted file mode 100644 index 700edbd3..00000000 --- a/modules/pam_xauth/pam_xauth.c +++ /dev/null @@ -1,641 +0,0 @@ -/* - * Copyright 2001-2003 Red Hat, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* "$Id$" */ - -#include "../../_pam_aconf.h" -#include <sys/types.h> -#include <sys/fsuid.h> -#include <sys/wait.h> -#include <errno.h> -#include <fnmatch.h> -#include <grp.h> -#include <limits.h> -#include <netdb.h> -#include <pwd.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/_pam_modutil.h> - -#define DATANAME "pam_xauth_cookie_file" -#define XAUTHBIN "/usr/X11R6/bin/xauth" -#define XAUTHENV "XAUTHORITY" -#define HOMEENV "HOME" -#define XAUTHDEF ".Xauthority" -#define XAUTHTMP ".xauthXXXXXX" - -/* Run a given command (with a NULL-terminated argument list), feeding it the - * given input on stdin, and storing any output it generates. */ -static int -run_coprocess(const char *input, char **output, - uid_t uid, gid_t gid, const char *command, ...) -{ - int ipipe[2], opipe[2], i; - char buf[LINE_MAX]; - pid_t child; - char *buffer = NULL; - size_t buffer_size = 0; - va_list ap; - - *output = NULL; - - /* Create stdio pipery. */ - if (pipe(ipipe) == -1) { - return -1; - } - if (pipe(opipe) == -1) { - close(ipipe[0]); - close(ipipe[1]); - return -1; - } - - /* Fork off a child. */ - child = fork(); - if (child == -1) { - close(ipipe[0]); - close(ipipe[1]); - close(opipe[0]); - close(opipe[1]); - return -1; - } - - if (child == 0) { - /* We're the child. */ - char *args[10]; - const char *tmp; - /* Drop privileges. */ - setgid(gid); - setgroups(0, NULL); - setuid(uid); - /* Initialize the argument list. */ - memset(args, 0, sizeof(args)); - /* Set the pipe descriptors up as stdin and stdout, and close - * everything else, including the original values for the - * descriptors. */ - dup2(ipipe[0], STDIN_FILENO); - dup2(opipe[1], STDOUT_FILENO); - for (i = 0; i < sysconf(_SC_OPEN_MAX); i++) { - if ((i != STDIN_FILENO) && (i != STDOUT_FILENO)) { - close(i); - } - } - /* Convert the varargs list into a regular array of strings. */ - va_start(ap, command); - args[0] = strdup(command); - for (i = 1; i < ((sizeof(args) / sizeof(args[0])) - 1); i++) { - tmp = va_arg(ap, const char*); - if (tmp == NULL) { - break; - } - args[i] = strdup(tmp); - } - /* Run the command. */ - execvp(command, args); - /* Never reached. */ - exit(1); - } - - /* We're the parent, so close the other ends of the pipes. */ - close(ipipe[0]); - close(opipe[1]); - /* Send input to the process (if we have any), then send an EOF. */ - if (input) { - (void)_pammodutil_write(ipipe[1], input, strlen(input)); - } - close(ipipe[1]); - - /* Read data output until we run out of stuff to read. */ - i = _pammodutil_read(opipe[0], buf, sizeof(buf)); - while ((i != 0) && (i != -1)) { - char *tmp; - /* Resize the buffer to hold the data. */ - tmp = realloc(buffer, buffer_size + i + 1); - if (tmp == NULL) { - /* Uh-oh, bail. */ - if (buffer != NULL) { - free(buffer); - } - close(opipe[0]); - waitpid(child, NULL, 0); - return -1; - } - /* Save the new buffer location, copy the newly-read data into - * the buffer, and make sure the result will be - * nul-terminated. */ - buffer = tmp; - memcpy(buffer + buffer_size, buf, i); - buffer[buffer_size + i] = '\0'; - buffer_size += i; - /* Try to read again. */ - i = _pammodutil_read(opipe[0], buf, sizeof(buf)); - } - /* No more data. Clean up and return data. */ - close(opipe[0]); - *output = buffer; - waitpid(child, NULL, 0); - return 0; -} - -/* Free a data item. */ -static void -cleanup(pam_handle_t *pamh, void *data, int err) -{ - free(data); -} - -/* Check if we want to allow export to the other user, or import from the - * other user. */ -static int -check_acl(pam_handle_t *pamh, - const char *sense, const char *this_user, const char *other_user, - int noent_code, int debug) -{ - char path[PATH_MAX]; - struct passwd *pwd; - FILE *fp; - int i; - uid_t euid; - /* Check this user's <sense> file. */ - pwd = _pammodutil_getpwnam(pamh, this_user); - if (pwd == NULL) { - syslog(LOG_ERR, "pam_xauth: error determining " - "home directory for '%s'", this_user); - return PAM_SESSION_ERR; - } - /* Figure out what that file is really named. */ - i = snprintf(path, sizeof(path), "%s/.xauth/%s", pwd->pw_dir, sense); - if ((i >= sizeof(path)) || (i < 0)) { - syslog(LOG_ERR, "pam_xauth: name of user's home directory " - "is too long"); - return PAM_SESSION_ERR; - } - euid = geteuid(); - setfsuid(pwd->pw_uid); - fp = fopen(path, "r"); - setfsuid(euid); - if (fp != NULL) { - char buf[LINE_MAX], *tmp; - /* Scan the file for a list of specs of users to "trust". */ - while (fgets(buf, sizeof(buf), fp) != NULL) { - tmp = memchr(buf, '\r', sizeof(buf)); - if (tmp != NULL) { - *tmp = '\0'; - } - tmp = memchr(buf, '\n', sizeof(buf)); - if (tmp != NULL) { - *tmp = '\0'; - } - if (fnmatch(buf, other_user, 0) == 0) { - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: %s %s " - "allowed by %s", - other_user, sense, path); - } - fclose(fp); - return PAM_SUCCESS; - } - } - /* If there's no match in the file, we fail. */ - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: %s not listed in %s", - other_user, path); - } - fclose(fp); - return PAM_PERM_DENIED; - } else { - /* Default to okay if the file doesn't exist. */ - switch (errno) { - case ENOENT: - if (noent_code == PAM_SUCCESS) { - if (debug) { - syslog(LOG_DEBUG, "%s does not exist, " - "ignoring", path); - } - } else { - if (debug) { - syslog(LOG_DEBUG, "%s does not exist, " - "failing", path); - } - } - return noent_code; - default: - if (debug) { - syslog(LOG_ERR, "%s opening %s", - strerror(errno), path); - } - return PAM_PERM_DENIED; - } - } -} - -int -pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - char xauthpath[] = XAUTHBIN; - char *cookiefile = NULL, *xauthority = NULL, - *cookie = NULL, *display = NULL, *tmp = NULL; - const char *user, *xauth = xauthpath; - struct passwd *tpwd, *rpwd; - int fd, i, debug = 0; - uid_t systemuser = 499, targetuser = 0, euid; - - /* Parse arguments. We don't understand many, so no sense in breaking - * this into a separate function. */ - for (i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) { - debug = 1; - continue; - } - if (strncmp(argv[i], "xauthpath=", 10) == 0) { - xauth = argv[i] + 10; - continue; - } - if (strncmp(argv[i], "targetuser=", 11) == 0) { - long l = strtol(argv[i] + 11, &tmp, 10); - if ((strlen(argv[i] + 11) > 0) && (*tmp == '\0')) { - targetuser = l; - } else { - syslog(LOG_WARNING, "pam_xauth: invalid value " - "for targetuser (`%s')", argv[i] + 11); - } - continue; - } - if (strncmp(argv[i], "systemuser=", 11) == 0) { - long l = strtol(argv[i] + 11, &tmp, 10); - if ((strlen(argv[i] + 11) > 0) && (*tmp == '\0')) { - systemuser = l; - } else { - syslog(LOG_WARNING, "pam_xauth: invalid value " - "for systemuser (`%s')", argv[i] + 11); - } - continue; - } - syslog(LOG_WARNING, "pam_xauth: unrecognized option `%s'", - argv[i]); - } - - /* If DISPLAY isn't set, we don't really care, now do we? */ - if ((display = getenv("DISPLAY")) == NULL) { - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: user has no DISPLAY," - " doing nothing"); - } - return PAM_SUCCESS; - } - - /* Read the target user's name. */ - if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) { - syslog(LOG_ERR, "pam_xauth: error determining target " - "user's name"); - return PAM_SESSION_ERR; - } - rpwd = _pammodutil_getpwuid(pamh, getuid()); - if (rpwd == NULL) { - syslog(LOG_ERR, "pam_xauth: error determining invoking " - "user's name"); - return PAM_SESSION_ERR; - } - - /* Get the target user's UID and primary GID, which we'll need to set - * on the xauthority file we create later on. */ - tpwd = _pammodutil_getpwnam(pamh, user); - if (tpwd == NULL) { - syslog(LOG_ERR, "pam_xauth: error determining target " - "user's UID"); - return PAM_SESSION_ERR; - } - - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: requesting user %lu/%lu, " - "target user %lu/%lu", - (unsigned long) rpwd->pw_uid, - (unsigned long) rpwd->pw_gid, - (unsigned long) tpwd->pw_uid, - (unsigned long) tpwd->pw_gid); - } - - /* If the UID is a system account (and not the superuser), forget - * about forwarding keys. */ - if ((tpwd->pw_uid != 0) && - (tpwd->pw_uid != targetuser) && - (tpwd->pw_uid <= systemuser)) { - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: not forwarding cookies " - "to user ID %ld", (long) tpwd->pw_uid); - } - return PAM_SESSION_ERR; - } - - /* Check that both users are amenable to this. By default, this - * boils down to this policy: - * export(ruser=root): only if <user> is listed in .xauth/export - * export(ruser=*) if <user> is listed in .xauth/export, or - * if .xauth/export does not exist - * import(user=*): if <ruser> is listed in .xauth/import, or - * if .xauth/import does not exist */ - i = (getuid() != 0) ? PAM_SUCCESS : PAM_PERM_DENIED; - i = check_acl(pamh, "export", rpwd->pw_name, user, i, debug); - if (i != PAM_SUCCESS) { - return PAM_SESSION_ERR; - } - i = PAM_SUCCESS; - i = check_acl(pamh, "import", user, rpwd->pw_name, i, debug); - if (i != PAM_SUCCESS) { - return PAM_SESSION_ERR; - } - - /* Figure out where the source user's .Xauthority file is. */ - if (getenv(XAUTHENV) != NULL) { - cookiefile = strdup(getenv(XAUTHENV)); - } else { - cookiefile = malloc(strlen(rpwd->pw_dir) + 1 + - strlen(XAUTHDEF) + 1); - if (cookiefile == NULL) { - return PAM_SESSION_ERR; - } - strcpy(cookiefile, rpwd->pw_dir); - strcat(cookiefile, "/"); - strcat(cookiefile, XAUTHDEF); - } - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: reading keys from `%s'", - cookiefile); - } - - /* Read the user's .Xauthority file. Because the current UID is - * the original user's UID, this will only fail if something has - * gone wrong, or we have no cookies. */ - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: running \"%s %s %s %s %s\" as " - "%lu/%lu", - xauth, - "-f", - cookiefile, - "nlist", - display, - (unsigned long) getuid(), - (unsigned long) getgid()); - } - if (run_coprocess(NULL, &cookie, - getuid(), getgid(), - xauth, "-f", cookiefile, "nlist", display, - NULL) == 0) { - /* Check that we got a cookie. If not, we get creative. */ - if (((cookie == NULL) || (strlen(cookie) == 0)) && - ((strncmp(display, "localhost:", 10) == 0) || - (strncmp(display, "localhost/unix:", 15) == 0))) { - char *t, *screen; - size_t tlen, slen; - /* Free the useless cookie string. */ - if (cookie != NULL) { - free(cookie); - cookie = NULL; - } - /* Allocate enough space to hold an adjusted name. */ - tlen = strlen(display) + LINE_MAX + 1; - t = malloc(tlen); - if (t != NULL) { - memset(t, 0, tlen); - if (gethostname(t, tlen - 1) != -1) { - /* Append the protocol and then the - * screen number. */ - if (strlen(t) < tlen - 6) { - strcat(t, "/unix:"); - } - screen = strchr(display, ':'); - if (screen != NULL) { - screen++; - slen = strlen(screen); - if (strlen(t) + slen < tlen) { - strcat(t, screen); - } - } - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: " - "no key for `%s', trying" - " `%s'", display, t); - } - /* Read the cookie for this display. */ - if (debug) { - syslog(LOG_DEBUG, - "pam_xauth: running " - "\"%s %s %s %s %s\" as " - "%lu/%lu", - xauth, - "-f", - cookiefile, - "nlist", - t, - (unsigned long) getuid(), - (unsigned long) getgid()); - } - run_coprocess(NULL, &cookie, - getuid(), getgid(), - xauth, "-f", cookiefile, - "nlist", t, NULL); - } - free(t); - t = NULL; - } - } - - /* Check that we got a cookie, this time for real. */ - if ((cookie == NULL) || (strlen(cookie) == 0)) { - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: no key"); - } - return PAM_SESSION_ERR; - } - - /* Generate the environment variable - * "XAUTHORITY=<homedir>/filename". */ - xauthority = malloc(strlen(XAUTHENV) + 1 + - strlen(tpwd->pw_dir) + 1 + - strlen(XAUTHTMP) + 1); - if (xauthority == NULL) { - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: no free memory"); - } - free(cookiefile); - free(cookie); - return PAM_SESSION_ERR; - } - strcpy(xauthority, XAUTHENV); - strcat(xauthority, "="); - strcat(xauthority, tpwd->pw_dir); - strcat(xauthority, "/"); - strcat(xauthority, XAUTHTMP); - - /* Generate a new file to hold the data. */ - euid = geteuid(); - setfsuid(tpwd->pw_uid); - fd = mkstemp(xauthority + strlen(XAUTHENV) + 1); - setfsuid(euid); - if (fd == -1) { - syslog(LOG_ERR, "pam_xauth: error creating " - "temporary file `%s': %s", - xauthority + strlen(XAUTHENV) + 1, - strerror(errno)); - free(cookiefile); - free(cookie); - free(xauthority); - return PAM_SESSION_ERR; - } - /* Set permissions on the new file and dispose of the - * descriptor. */ - fchown(fd, tpwd->pw_uid, tpwd->pw_gid); - close(fd); - - /* Get a copy of the filename to save as a data item for - * removal at session-close time. */ - free(cookiefile); - cookiefile = strdup(xauthority + strlen(XAUTHENV) + 1); - - /* Save the filename. */ - if (pam_set_data(pamh, DATANAME, cookiefile, cleanup) != PAM_SUCCESS) { - syslog(LOG_ERR, "pam_xauth: error saving name of " - "temporary file `%s'", cookiefile); - unlink(cookiefile); - free(xauthority); - free(cookiefile); - free(cookie); - return PAM_SESSION_ERR; - } - - /* Unset any old XAUTHORITY variable in the environment. */ - if (getenv (XAUTHENV)) - unsetenv (XAUTHENV); - - /* Set the new variable in the environment. */ - if (pam_putenv (pamh, xauthority) != PAM_SUCCESS) - syslog (LOG_DEBUG, "pam_xauth: can't set environment variable '%s'", - xauthority); - putenv (xauthority); /* The environment owns this string now. */ - - /* set $DISPLAY in pam handle to make su - work */ - { - char *d = (char *) malloc (strlen ("DISPLAY=") + - strlen (display) + 1); - if (d == NULL) - { - syslog (LOG_DEBUG, "pam_xauth: memory exhausted\n"); - return PAM_SESSION_ERR; - } - strcpy (d, "DISPLAY="); - strcat (d, display); - - if (pam_putenv (pamh, d) != PAM_SUCCESS) - syslog (LOG_DEBUG, - "pam_xauth: can't set environment variable '%s'", - d); - free (d); - } - - /* Merge the cookie we read before into the new file. */ - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: writing key `%s' to " - "temporary file `%s'", cookie, cookiefile); - } - if (debug) { - syslog(LOG_DEBUG, - "pam_xauth: running \"%s %s %s %s %s\" as " - "%lu/%lu", - xauth, - "-f", - cookiefile, - "nmerge", - "-", - (unsigned long) tpwd->pw_uid, - (unsigned long) tpwd->pw_gid); - } - run_coprocess(cookie, &tmp, - tpwd->pw_uid, tpwd->pw_gid, - xauth, "-f", cookiefile, "nmerge", "-", NULL); - - /* We don't need to keep a copy of these around any more. */ - free(cookie); - cookie = NULL; - } - return PAM_SUCCESS; -} - -int -pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - void *cookiefile; - int i, debug = 0; - - /* Parse arguments. We don't understand many, so no sense in breaking - * this into a separate function. */ - for (i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) { - debug = 1; - continue; - } - if (strncmp(argv[i], "xauthpath=", 10) == 0) { - continue; - } - if (strncmp(argv[i], "systemuser=", 11) == 0) { - continue; - } - if (strncmp(argv[i], "targetuser=", 11) == 0) { - continue; - } - syslog(LOG_WARNING, "pam_xauth: unrecognized option `%s'", - argv[i]); - } - - /* Try to retrieve the name of a file we created when the session was - * opened. */ - if (pam_get_data(pamh, DATANAME, (const void**) &cookiefile) == PAM_SUCCESS) { - /* We'll only try to remove the file once. */ - if (strlen((char*)cookiefile) > 0) { - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: removing `%s'", - (char*)cookiefile); - } - unlink((char*)cookiefile); - *((char*)cookiefile) = '\0'; - } - } - return PAM_SUCCESS; -} diff --git a/modules/pammodutil/.cvsignore b/modules/pammodutil/.cvsignore deleted file mode 100644 index 7b4d4ba2..00000000 --- a/modules/pammodutil/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -static diff --git a/modules/pammodutil/Makefile b/modules/pammodutil/Makefile deleted file mode 100644 index c9cd0062..00000000 --- a/modules/pammodutil/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# -# $Id$ -# -# - -include ../../Make.Rules - -LIBNAME=libpammodutil - -# --------------------------------------------- - -dummy: all - -# --------------------------------------------- - -CFLAGS += $(PIC) $(STATIC) $(MOREFLAGS) \ - -DLIBPAM_VERSION_MAJOR=$(MAJOR_REL) \ - -DLIBPAM_VERSION_MINOR=$(MINOR_REL) - -# all the object files we care about -LIBOBJECTS = modutil_cleanup.o modutil_getpwnam.o modutil_getpwuid.o \ - modutil_getspnam.o modutil_getgrnam.o modutil_getgrgid.o \ - modutil_ingroup.o modutil_getlogin.o modutil_ioloop.o - -# static library name -LIBSTATIC = $(LIBNAME).a - -SLIBOBJECTS = $(addprefix static/,$(LIBOBJECTS) $(STATICOBJ)) - -# --------------------------------------------- -## rules - -all: dirs $(LIBSTATIC) ../../Make.Rules - -dirs: - $(MKDIR) static - -static/%.o : %.c - $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ - -$(LIBSTATIC): $(SLIBOBJECTS) - ar cr $@ $(SLIBOBJECTS) - $(RANLIB) $@ - -install: - @echo "at this time, we're not installing $(LIBSTATIC)" - -remove: - @echo "at this time, there is nothing to remove" - -clean: - rm -f a.out core *~ static/*.o - rm -f *.a *.o - if [ -d dynamic ]; then rmdir dynamic ; fi - if [ -d static ]; then rmdir static ; fi diff --git a/modules/pammodutil/README b/modules/pammodutil/README deleted file mode 100644 index 241f83a7..00000000 --- a/modules/pammodutil/README +++ /dev/null @@ -1,15 +0,0 @@ -$Id$ - -This is a libarary of routines for use by modules. The routines seem -to have a common use for modules, but are not part of libpam and never -will be. They are also a convenient layer of abstraction for providing -thread-safe functions that may require use of pam_handle_t 'data' -items to make their thread-safeness tied to the use of a single -pam_handle_t per thread. - -Functions provided so far are all listed in - - include/security/_pam_modutil.h - -. - diff --git a/modules/pammodutil/include/security/_pam_modutil.h b/modules/pammodutil/include/security/_pam_modutil.h deleted file mode 100644 index c2ac24c2..00000000 --- a/modules/pammodutil/include/security/_pam_modutil.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _PAM_MODUTIL_H -#define _PAM_MODUTIL_H - -/* - * $Id$ - * - * This file is a list of handy libc wrappers that attempt to provide some - * thread-safe and other convenient functionality to modules in a form that - * is common, but not dynamically linked with yet another dynamic pam - * library extension. - * - * A number of these functions reserve space in a pam_[sg]et_data item. - * In all cases, the name of the item is prefixed with "_pammodutil_*". - * - * On systems that simply can't support thread safe programming, these - * functions don't support it either - sorry. - * - * Copyright (c) 2001-2002 Andrew Morgan <morgan@kernel.org> - */ - -#include <pwd.h> -#include <grp.h> -#include <shadow.h> -#include <sys/types.h> - -extern struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh, - const char *user); - -extern struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh, - uid_t uid); - -extern struct group *_pammodutil_getgrnam(pam_handle_t *pamh, - const char *group); - -extern struct group *_pammodutil_getgrgid(pam_handle_t *pamh, - gid_t gid); - -extern struct spwd *_pammodutil_getspnam(pam_handle_t *pamh, - const char *user); - -extern int _pammodutil_user_in_group_nam_nam(pam_handle_t *pamh, - const char *user, - const char *group); - -extern int _pammodutil_user_in_group_nam_gid(pam_handle_t *pamh, - const char *user, - gid_t group); - -extern int _pammodutil_user_in_group_uid_nam(pam_handle_t *pamh, - uid_t user, - const char *group); - -extern int _pammodutil_user_in_group_uid_gid(pam_handle_t *pamh, - uid_t user, - gid_t group); - -extern void _pammodutil_cleanup(pam_handle_t *pamh, void *data, - int error_status); - -extern const char *_pammodutil_getlogin(pam_handle_t *pamh); - -extern int _pammodutil_read(int fd, char *buffer, int count); - -extern int _pammodutil_write(int fd, const char *buffer, int count); - -#endif /* _PAM_MODUTIL_H */ diff --git a/modules/pammodutil/modutil_cleanup.c b/modules/pammodutil/modutil_cleanup.c deleted file mode 100644 index e95d6100..00000000 --- a/modules/pammodutil/modutil_cleanup.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * $Id$ - * - * This function provides a common pam_set_data() friendly version of free(). - */ - -#include "pammodutil.h" - -void _pammodutil_cleanup(pam_handle_t *pamh, void *data, int error_status) -{ - if (data) { - /* junk it */ - (void) free(data); - } -} - diff --git a/modules/pammodutil/modutil_getgrgid.c b/modules/pammodutil/modutil_getgrgid.c deleted file mode 100644 index 179df3b2..00000000 --- a/modules/pammodutil/modutil_getgrgid.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * $Id$ - * - * This function provides a thread safer version of getgrgid() for use - * with PAM modules that care about this sort of thing. - * - * XXX - or at least it should provide a thread-safe alternative. - */ - -#include "pammodutil.h" - -#include <errno.h> -#include <limits.h> -#include <grp.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> - -static pthread_mutex_t _pammodutil_mutex = PTHREAD_MUTEX_INITIALIZER; -static void _pammodutil_lock(void) -{ - pthread_mutex_lock(&_pammodutil_mutex); -} -static void _pammodutil_unlock(void) -{ - pthread_mutex_unlock(&_pammodutil_mutex); -} - -static int intlen(int number) -{ - int len = 2; - while (number != 0) { - number /= 10; - len++; - } - return len; -} - -static int longlen(long number) -{ - int len = 2; - while (number != 0) { - number /= 10; - len++; - } - return len; -} - -struct group *_pammodutil_getgrgid(pam_handle_t *pamh, gid_t gid) -{ -#ifdef HAVE_GETGRGID_R - - void *buffer=NULL; - size_t length = PWD_INITIAL_LENGTH; - - do { - int status; - void *new_buffer; - struct group *result = NULL; - - new_buffer = realloc(buffer, sizeof(struct group) + length); - if (new_buffer == NULL) { - - D(("out of memory")); - - /* no memory for the user - so delete the memory */ - if (buffer) { - free(buffer); - } - return NULL; - } - buffer = new_buffer; - - /* make the re-entrant call to get the grp structure */ - errno = 0; - status = getgrgid_r(gid, buffer, - sizeof(struct group) + (char *) buffer, - length, &result); - if (!status && (result == buffer)) { - char *data_name; - const void *ignore; - int i; - - data_name = malloc(strlen("_pammodutil_getgrgid") + 1 + - longlen((long)gid) + 1 + intlen(INT_MAX) + 1); - if ((pamh != NULL) && (data_name == NULL)) { - D(("was unable to register the data item [%s]", - pam_strerror(pamh, status))); - free(buffer); - return NULL; - } - - if (pamh != NULL) { - for (i = 0; i < INT_MAX; i++) { - sprintf(data_name, "_pammodutil_getgrgid_%ld_%d", - (long) gid, i); - _pammodutil_lock(); - status = PAM_NO_MODULE_DATA; - if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) { - status = pam_set_data(pamh, data_name, - result, _pammodutil_cleanup); - } - _pammodutil_unlock(); - if (status == PAM_SUCCESS) { - break; - } - } - } else { - status = PAM_SUCCESS; - } - - free(data_name); - - if (status == PAM_SUCCESS) { - D(("success")); - return result; - } - - D(("was unable to register the data item [%s]", - pam_strerror(pamh, status))); - - free(buffer); - return NULL; - - } else if (errno != ERANGE && errno != EINTR) { - /* no sense in repeating the call */ - break; - } - - length <<= 2; - - } while (length < PWD_ABSURD_PWD_LENGTH); - - D(("grp structure took %u bytes or so of memory", - length+sizeof(struct group))); - - free(buffer); - return NULL; - -#else /* ie. ifndef HAVE_GETGRGID_R */ - - /* - * Sorry, there does not appear to be a reentrant version of - * getgrgid(). So, we use the standard libc function. - */ - - return getgrgid(gid); - -#endif /* def HAVE_GETGRGID_R */ -} diff --git a/modules/pammodutil/modutil_getgrnam.c b/modules/pammodutil/modutil_getgrnam.c deleted file mode 100644 index e34d4c45..00000000 --- a/modules/pammodutil/modutil_getgrnam.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * $Id$ - * - * This function provides a thread safer version of getgrnam() for use - * with PAM modules that care about this sort of thing. - * - * XXX - or at least it should provide a thread-safe alternative. - */ - -#include "pammodutil.h" - -#include <errno.h> -#include <limits.h> -#include <grp.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> - -static pthread_mutex_t _pammodutil_mutex = PTHREAD_MUTEX_INITIALIZER; -static void _pammodutil_lock(void) -{ - pthread_mutex_lock(&_pammodutil_mutex); -} -static void _pammodutil_unlock(void) -{ - pthread_mutex_unlock(&_pammodutil_mutex); -} - -static int intlen(int number) -{ - int len = 2; - while (number != 0) { - number /= 10; - len++; - } - return len; -} - -struct group *_pammodutil_getgrnam(pam_handle_t *pamh, const char *group) -{ -#ifdef HAVE_GETGRNAM_R - - void *buffer=NULL; - size_t length = PWD_INITIAL_LENGTH; - - do { - int status; - void *new_buffer; - struct group *result = NULL; - - new_buffer = realloc(buffer, sizeof(struct group) + length); - if (new_buffer == NULL) { - - D(("out of memory")); - - /* no memory for the group - so delete the memory */ - if (buffer) { - free(buffer); - } - return NULL; - } - buffer = new_buffer; - - /* make the re-entrant call to get the grp structure */ - errno = 0; - status = getgrnam_r(group, buffer, - sizeof(struct group) + (char *) buffer, - length, &result); - if (!status && (result == buffer)) { - char *data_name; - const void *ignore; - int i; - - data_name = malloc(strlen("_pammodutil_getgrnam") + 1 + - strlen(group) + 1 + intlen(INT_MAX) + 1); - if ((pamh != NULL) && (data_name == NULL)) { - D(("was unable to register the data item [%s]", - pam_strerror(pamh, status))); - free(buffer); - return NULL; - } - - if (pamh != NULL) { - for (i = 0; i < INT_MAX; i++) { - sprintf(data_name, "_pammodutil_getgrnam_%s_%d", group, i); - _pammodutil_lock(); - status = PAM_NO_MODULE_DATA; - if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) { - status = pam_set_data(pamh, data_name, - result, _pammodutil_cleanup); - } - _pammodutil_unlock(); - if (status == PAM_SUCCESS) { - break; - } - } - } else { - status = PAM_SUCCESS; - } - - free(data_name); - - if (status == PAM_SUCCESS) { - D(("success")); - return result; - } - - D(("was unable to register the data item [%s]", - pam_strerror(pamh, status))); - - free(buffer); - return NULL; - - } else if (errno != ERANGE && errno != EINTR) { - /* no sense in repeating the call */ - break; - } - - length <<= 2; - - } while (length < PWD_ABSURD_PWD_LENGTH); - - D(("grp structure took %u bytes or so of memory", - length+sizeof(struct group))); - - free(buffer); - return NULL; - -#else /* ie. ifndef HAVE_GETGRNAM_R */ - - /* - * Sorry, there does not appear to be a reentrant version of - * getgrnam(). So, we use the standard libc function. - */ - - return getgrnam(group); - -#endif /* def HAVE_GETGRNAM_R */ -} diff --git a/modules/pammodutil/modutil_getlogin.c b/modules/pammodutil/modutil_getlogin.c deleted file mode 100644 index ef09d031..00000000 --- a/modules/pammodutil/modutil_getlogin.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * $Id$ - * - * A central point for invoking getlogin(). Hopefully, this is a - * little harder to spoof than all the other versions that are out - * there. - */ - -#include "pammodutil.h" - -#include <stdlib.h> -#include <unistd.h> -#include <utmp.h> - -#define _PAMMODUTIL_GETLOGIN "_pammodutil_getlogin" - -const char *_pammodutil_getlogin(pam_handle_t *pamh) -{ - int status; - char *logname; - const char *curr_tty; - char *curr_user; - struct utmp *ut, line; - - status = pam_get_data(pamh, _PAMMODUTIL_GETLOGIN, - (const void **) &logname); - if (status == PAM_SUCCESS) { - return logname; - } - - status = pam_get_item(pamh, PAM_TTY, (const void **) &curr_tty); - if ((status != PAM_SUCCESS) || (curr_tty == NULL)) { - curr_tty = ttyname(0); - } - - if ((curr_tty == NULL) || memcmp(curr_tty, "/dev/", 5)) { - return NULL; - } - - curr_tty += 5; /* strlen("/dev/") */ - logname = NULL; - - setutent(); - strncpy(line.ut_line, curr_tty, sizeof(line.ut_line)); - - if ((ut = getutline(&line)) == NULL) { - goto clean_up_and_go_home; - } - - curr_user = calloc(sizeof(line.ut_user)+1, 1); - if (curr_user == NULL) { - goto clean_up_and_go_home; - } - - strncpy(curr_user, ut->ut_user, sizeof(ut->ut_user)); - /* calloc already zeroed the memory */ - - status = pam_set_data(pamh, _PAMMODUTIL_GETLOGIN, curr_user, - _pammodutil_cleanup); - if (status != PAM_SUCCESS) { - free(curr_user); - goto clean_up_and_go_home; - } - - logname = curr_user; - -clean_up_and_go_home: - - endutent(); - - return logname; -} diff --git a/modules/pammodutil/modutil_getpwnam.c b/modules/pammodutil/modutil_getpwnam.c deleted file mode 100644 index e0dfdca3..00000000 --- a/modules/pammodutil/modutil_getpwnam.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * $Id$ - * - * This function provides a thread safer version of getpwnam() for use - * with PAM modules that care about this sort of thing. - * - * XXX - or at least it should provide a thread-safe alternative. - */ - -#include "pammodutil.h" - -#include <errno.h> -#include <limits.h> -#include <pthread.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> - -static pthread_mutex_t _pammodutil_mutex = PTHREAD_MUTEX_INITIALIZER; -static void _pammodutil_lock(void) -{ - pthread_mutex_lock(&_pammodutil_mutex); -} -static void _pammodutil_unlock(void) -{ - pthread_mutex_unlock(&_pammodutil_mutex); -} - -static int intlen(int number) -{ - int len = 2; - while (number != 0) { - number /= 10; - len++; - } - return len; -} - -struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh, const char *user) -{ -#ifdef HAVE_GETPWNAM_R - - void *buffer=NULL; - size_t length = PWD_INITIAL_LENGTH; - - do { - int status; - void *new_buffer; - struct passwd *result = NULL; - - new_buffer = realloc(buffer, sizeof(struct passwd) + length); - if (new_buffer == NULL) { - - D(("out of memory")); - - /* no memory for the user - so delete the memory */ - if (buffer) { - free(buffer); - } - return NULL; - } - buffer = new_buffer; - - /* make the re-entrant call to get the pwd structure */ - errno = 0; - status = getpwnam_r(user, buffer, - sizeof(struct passwd) + (char *) buffer, - length, &result); - if (!status && (result == buffer)) { - char *data_name; - const void *ignore; - int i; - - data_name = malloc(strlen("_pammodutil_getpwnam") + 1 + - strlen(user) + 1 + intlen(INT_MAX) + 1); - if ((pamh != NULL) && (data_name == NULL)) { - D(("was unable to register the data item [%s]", - pam_strerror(pamh, status))); - free(buffer); - return NULL; - } - - if (pamh != NULL) { - for (i = 0; i < INT_MAX; i++) { - sprintf(data_name, "_pammodutil_getpwnam_%s_%d", user, i); - _pammodutil_lock(); - status = PAM_NO_MODULE_DATA; - if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) { - status = pam_set_data(pamh, data_name, - result, _pammodutil_cleanup); - } - _pammodutil_unlock(); - if (status == PAM_SUCCESS) { - break; - } - } - } else { - status = PAM_SUCCESS; - } - - free(data_name); - - if (status == PAM_SUCCESS) { - D(("success")); - return result; - } - - D(("was unable to register the data item [%s]", - pam_strerror(pamh, status))); - - free(buffer); - return NULL; - - } else if (errno != ERANGE && errno != EINTR) { - /* no sense in repeating the call */ - break; - } - - length <<= 2; - - } while (length < PWD_ABSURD_PWD_LENGTH); - - D(("pwd structure took %u bytes or so of memory", - length+sizeof(struct passwd))); - - free(buffer); - return NULL; - -#else /* ie. ifndef HAVE_GETPWNAM_R */ - - /* - * Sorry, there does not appear to be a reentrant version of - * getpwnam(). So, we use the standard libc function. - */ - - return getpwnam(user); - -#endif /* def HAVE_GETPWNAM_R */ -} diff --git a/modules/pammodutil/modutil_getpwuid.c b/modules/pammodutil/modutil_getpwuid.c deleted file mode 100644 index aadd817b..00000000 --- a/modules/pammodutil/modutil_getpwuid.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * $Id$ - * - * This function provides a thread safer version of getpwuid() for use - * with PAM modules that care about this sort of thing. - * - * XXX - or at least it should provide a thread-safe alternative. - */ - -#include "pammodutil.h" - -#include <errno.h> -#include <limits.h> -#include <pthread.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> - -static pthread_mutex_t _pammodutil_mutex = PTHREAD_MUTEX_INITIALIZER; -static void _pammodutil_lock(void) -{ - pthread_mutex_lock(&_pammodutil_mutex); -} -static void _pammodutil_unlock(void) -{ - pthread_mutex_unlock(&_pammodutil_mutex); -} - -static int intlen(int number) -{ - int len = 2; - while (number != 0) { - number /= 10; - len++; - } - return len; -} - -static int longlen(long number) -{ - int len = 2; - while (number != 0) { - number /= 10; - len++; - } - return len; -} - -struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh, uid_t uid) -{ -#ifdef HAVE_GETPWUID_R - - void *buffer=NULL; - size_t length = PWD_INITIAL_LENGTH; - - do { - int status; - void *new_buffer; - struct passwd *result = NULL; - - new_buffer = realloc(buffer, sizeof(struct passwd) + length); - if (new_buffer == NULL) { - - D(("out of memory")); - - /* no memory for the user - so delete the memory */ - if (buffer) { - free(buffer); - } - return NULL; - } - buffer = new_buffer; - - /* make the re-entrant call to get the pwd structure */ - errno = 0; - status = getpwuid_r(uid, buffer, - sizeof(struct passwd) + (char *) buffer, - length, &result); - if (!status && (result == buffer)) { - char *data_name; - const void *ignore; - int i; - - data_name = malloc(strlen("_pammodutil_getpwuid") + 1 + - longlen((long) uid) + 1 + intlen(INT_MAX) + 1); - if ((pamh != NULL) && (data_name == NULL)) { - D(("was unable to register the data item [%s]", - pam_strerror(pamh, status))); - free(buffer); - return NULL; - } - - if (pamh != NULL) { - for (i = 0; i < INT_MAX; i++) { - sprintf(data_name, "_pammodutil_getpwuid_%ld_%d", - (long) uid, i); - _pammodutil_lock(); - status = PAM_NO_MODULE_DATA; - if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) { - status = pam_set_data(pamh, data_name, - result, _pammodutil_cleanup); - } - _pammodutil_unlock(); - if (status == PAM_SUCCESS) { - break; - } - } - } else { - status = PAM_SUCCESS; - } - - free(data_name); - - if (status == PAM_SUCCESS) { - D(("success")); - return result; - } - - D(("was unable to register the data item [%s]", - pam_strerror(pamh, status))); - - free(buffer); - return NULL; - - } else if (errno != ERANGE && errno != EINTR) { - /* no sense in repeating the call */ - break; - } - - length <<= 2; - - } while (length < PWD_ABSURD_PWD_LENGTH); - - D(("pwd structure took %u bytes or so of memory", - length+sizeof(struct passwd))); - - free(buffer); - return NULL; - -#else /* ie. ifndef HAVE_GETPWUID_R */ - - /* - * Sorry, there does not appear to be a reentrant version of - * getpwuid(). So, we use the standard libc function. - */ - - return getpwuid(uid); - -#endif /* def HAVE_GETPWUID_R */ -} diff --git a/modules/pammodutil/modutil_getspnam.c b/modules/pammodutil/modutil_getspnam.c deleted file mode 100644 index e069d009..00000000 --- a/modules/pammodutil/modutil_getspnam.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * $Id$ - * - * This function provides a thread safer version of getspnam() for use - * with PAM modules that care about this sort of thing. - * - * XXX - or at least it should provide a thread-safe alternative. - */ - -#include "pammodutil.h" - -#include <errno.h> -#include <limits.h> -#include <pthread.h> -#include <shadow.h> -#include <stdio.h> -#include <stdlib.h> - -static pthread_mutex_t _pammodutil_mutex = PTHREAD_MUTEX_INITIALIZER; -static void _pammodutil_lock(void) -{ - pthread_mutex_lock(&_pammodutil_mutex); -} -static void _pammodutil_unlock(void) -{ - pthread_mutex_unlock(&_pammodutil_mutex); -} - -static int intlen(int number) -{ - int len = 2; - while (number != 0) { - number /= 10; - len++; - } - return len; -} - -struct spwd *_pammodutil_getspnam(pam_handle_t *pamh, const char *user) -{ -#ifdef HAVE_GETSPNAM_R - - void *buffer=NULL; - size_t length = PWD_INITIAL_LENGTH; - - do { - int status; - void *new_buffer; - struct spwd *result = NULL; - - new_buffer = realloc(buffer, sizeof(struct spwd) + length); - if (new_buffer == NULL) { - - D(("out of memory")); - - /* no memory for the user - so delete the memory */ - if (buffer) { - free(buffer); - } - return NULL; - } - buffer = new_buffer; - - /* make the re-entrant call to get the spwd structure */ - errno = 0; - status = getspnam_r(user, buffer, - sizeof(struct spwd) + (char *) buffer, - length, &result); - if (!status && (result == buffer)) { - char *data_name; - const void *ignore; - int i; - - data_name = malloc(strlen("_pammodutil_getspnam") + 1 + - strlen(user) + 1 + intlen(INT_MAX) + 1); - if ((pamh != NULL) && (data_name == NULL)) { - D(("was unable to register the data item [%s]", - pam_strerror(pamh, status))); - free(buffer); - return NULL; - } - - if (pamh != NULL) { - for (i = 0; i < INT_MAX; i++) { - sprintf(data_name, "_pammodutil_getspnam_%s_%d", user, i); - _pammodutil_lock(); - status = PAM_NO_MODULE_DATA; - if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) { - status = pam_set_data(pamh, data_name, - result, _pammodutil_cleanup); - } - _pammodutil_unlock(); - if (status == PAM_SUCCESS) { - break; - } - } - } else { - status = PAM_SUCCESS; - } - - free(data_name); - - if (status == PAM_SUCCESS) { - D(("success")); - return result; - } - - D(("was unable to register the data item [%s]", - pam_strerror(pamh, status))); - - free(buffer); - return NULL; - - } else if (errno != ERANGE && errno != EINTR) { - /* no sense in repeating the call */ - break; - } - - length <<= 2; - - } while (length < PWD_ABSURD_PWD_LENGTH); - - D(("spwd structure took %u bytes or so of memory", - length+sizeof(struct spwd))); - - free(buffer); - return NULL; - -#else /* ie. ifndef HAVE_GETSPNAM_R */ - - /* - * Sorry, there does not appear to be a reentrant version of - * getspnam(). So, we use the standard libc function. - */ - - return getspnam(user); - -#endif /* def HAVE_GETSPNAM_R */ -} diff --git a/modules/pammodutil/modutil_ingroup.c b/modules/pammodutil/modutil_ingroup.c deleted file mode 100644 index 5a3b5d8d..00000000 --- a/modules/pammodutil/modutil_ingroup.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * $Id$ - * - * This function provides common methods for checking if a user is in a - * specified group. - */ - -#include "pammodutil.h" -#include "include/security/_pam_modutil.h" -#include <pwd.h> -#include <grp.h> - -#ifdef HAVE_GETGROUPLIST -static int checkgrouplist(const char *user, gid_t primary, gid_t target) -{ - gid_t *grouplist = NULL; - int agroups, ngroups, i; - ngroups = agroups = 3; - do { - grouplist = malloc(sizeof(gid_t) * agroups); - if (grouplist == NULL) { - return 0; - } - ngroups = agroups; - i = getgrouplist(user, primary, grouplist, &ngroups); - if ((i < 0) || (ngroups < 1)) { - agroups *= 2; - free(grouplist); - } else { - for (i = 0; i < ngroups; i++) { - if (grouplist[i] == target) { - free(grouplist); - return 1; - } - } - free(grouplist); - } - } while (((i < 0) || (ngroups < 1)) && (agroups < 10000)); - return 0; -} -#endif - -static int _pammodutil_user_in_group_common(pam_handle_t *pamh, - struct passwd *pwd, - struct group *grp) -{ - int i; - - if (pwd == NULL) { - return 0; - } - if (grp == NULL) { - return 0; - } - - if (pwd->pw_gid == grp->gr_gid) { - return 1; - } - - for (i = 0; (grp->gr_mem != NULL) && (grp->gr_mem[i] != NULL); i++) { - if (strcmp(pwd->pw_name, grp->gr_mem[i]) == 0) { - return 1; - } - } - -#ifdef HAVE_GETGROUPLIST - if (checkgrouplist(pwd->pw_name, pwd->pw_gid, grp->gr_gid)) { - return 1; - } -#endif - - return 0; -} - -int _pammodutil_user_in_group_nam_nam(pam_handle_t *pamh, - const char *user, const char *group) -{ - struct passwd *pwd; - struct group *grp; - - pwd = _pammodutil_getpwnam(pamh, user); - grp = _pammodutil_getgrnam(pamh, group); - - return _pammodutil_user_in_group_common(pamh, pwd, grp); -} - -int _pammodutil_user_in_group_nam_gid(pam_handle_t *pamh, - const char *user, gid_t group) -{ - struct passwd *pwd; - struct group *grp; - - pwd = _pammodutil_getpwnam(pamh, user); - grp = _pammodutil_getgrgid(pamh, group); - - return _pammodutil_user_in_group_common(pamh, pwd, grp); -} - -int _pammodutil_user_in_group_uid_nam(pam_handle_t *pamh, - uid_t user, const char *group) -{ - struct passwd *pwd; - struct group *grp; - - pwd = _pammodutil_getpwuid(pamh, user); - grp = _pammodutil_getgrnam(pamh, group); - - return _pammodutil_user_in_group_common(pamh, pwd, grp); -} - -int _pammodutil_user_in_group_uid_gid(pam_handle_t *pamh, - uid_t user, gid_t group) -{ - struct passwd *pwd; - struct group *grp; - - pwd = _pammodutil_getpwuid(pamh, user); - grp = _pammodutil_getgrgid(pamh, group); - - return _pammodutil_user_in_group_common(pamh, pwd, grp); -} diff --git a/modules/pammodutil/modutil_ioloop.c b/modules/pammodutil/modutil_ioloop.c deleted file mode 100644 index a852a7b8..00000000 --- a/modules/pammodutil/modutil_ioloop.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * $Id$ - * - * These functions provides common methods for ensure a complete read or - * write occurs. It handles EINTR and partial read/write returns. - */ - -#include <unistd.h> -#include <errno.h> - -#include <security/pam_modules.h> -#include "include/security/_pam_modutil.h" - -int _pammodutil_read(int fd, char *buffer, int count) -{ - int block, offset = 0; - - while (count > 0) { - block = read(fd, &buffer[offset], count); - - if (block < 0) { - if (errno == EINTR) continue; - return block; - } - if (block == 0) return offset; - - offset += block; - count -= block; - } - - return offset; -} - -int _pammodutil_write(int fd, const char *buffer, int count) -{ - int block, offset = 0; - - while (count > 0) { - block = write(fd, &buffer[offset], count); - - if (block < 0) { - if (errno == EINTR) continue; - return block; - } - if (block == 0) return offset; - - offset += block; - count -= block; - } - - return offset; -} diff --git a/modules/pammodutil/pammodutil.h b/modules/pammodutil/pammodutil.h deleted file mode 100644 index fbe81023..00000000 --- a/modules/pammodutil/pammodutil.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef PAMMODUTIL_H -#define PAMMODUTIL_H - -/* - * $Id$ - * - * Copyright (c) 2001 Andrew Morgan <morgan@kernel.org> - */ - -#include <security/_pam_aconf.h> -#include <security/_pam_macros.h> -#include <security/pam_modules.h> -#include <security/_pam_modutil.h> - -#define PWD_INITIAL_LENGTH 0x100 -#define PWD_ABSURD_PWD_LENGTH 0x8000 - -/* This is a simple cleanup, it just free()s the 'data' memory */ -extern void _pammodutil_cleanup(pam_handle_t *pamh, void *data, - int error_status); - -#endif /* PAMMODUTIL_H */ diff --git a/modules/register_static b/modules/register_static deleted file mode 100755 index f3aebb60..00000000 --- a/modules/register_static +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -if [ `basename $PWD` != "modules" ]; then - echo "$0 must be run from the .../modules directory" - exit 1 -fi - -merge_line () -{ - if [ $# != 3 ]; then - echo "usage: merge_line token filename 'new line'" - fi - if [ -f $2 ]; then -# remove any existing entry... - grep -v "$1" $2 > tmp.$2 - rm -f $2 - mv {tmp.,}$2 - fi - cat << EOT >> $2 -$3 -EOT - -} - - -if [ $# -ne 2 ]; then - - cat << EOT 2>&1 -$0: this script takes TWO arguments: - the 'alphanumeric label' of the module and the location of - its object file from the .../modules/ directory -EOT - exit 1 - -else - echo " - *> registering static module: $1 ($2) <* -" - merge_line "$1" _static_module_list "\ -extern struct pam_module _$1_modstruct;" - - merge_line "$1" _static_module_entry " &_$1_modstruct," - if [ -n "$2" ]; then - merge_line "$2" _static_module_objects "../modules/$2" - fi - -fi - -exit 0 |