summaryrefslogtreecommitdiff
path: root/Linux-PAM/doc/specs
diff options
context:
space:
mode:
Diffstat (limited to 'Linux-PAM/doc/specs')
-rw-r--r--Linux-PAM/doc/specs/Makefile.am22
-rw-r--r--Linux-PAM/doc/specs/Makefile.in561
-rw-r--r--Linux-PAM/doc/specs/draft-morgan-pam.raw764
-rw-r--r--Linux-PAM/doc/specs/parse_l.c1719
-rw-r--r--Linux-PAM/doc/specs/parse_l.l21
-rw-r--r--Linux-PAM/doc/specs/parse_y.c1870
-rw-r--r--Linux-PAM/doc/specs/parse_y.h79
-rw-r--r--Linux-PAM/doc/specs/parse_y.y297
-rw-r--r--Linux-PAM/doc/specs/rfc86.0.txt1851
-rw-r--r--Linux-PAM/doc/specs/std-agent-id.raw95
10 files changed, 0 insertions, 7279 deletions
diff --git a/Linux-PAM/doc/specs/Makefile.am b/Linux-PAM/doc/specs/Makefile.am
deleted file mode 100644
index 595c09bf..00000000
--- a/Linux-PAM/doc/specs/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de>
-#
-
-CLEANFILES = draft-morgan-pam-current.txt *~
-
-EXTRA_DIST = draft-morgan-pam.raw std-agent-id.raw rfc86.0.txt
-
-draft-morgan-pam-current.txt: padout draft-morgan-pam.raw
- ./padout < $(srcdir)/draft-morgan-pam.raw > draft-morgan-pam-current.txt
-
-AM_YFLAGS = -d
-
-BUILT_SOURCES = parse_y.h
-
-noinst_PROGRAMS = padout
-
-padout_SOURCES = parse_l.l parse_y.y
-
-padout_LDADD = @LEXLIB@
-
-doc_DATA = draft-morgan-pam-current.txt rfc86.0.txt
diff --git a/Linux-PAM/doc/specs/Makefile.in b/Linux-PAM/doc/specs/Makefile.in
deleted file mode 100644
index 532a1164..00000000
--- a/Linux-PAM/doc/specs/Makefile.in
+++ /dev/null
@@ -1,561 +0,0 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-#
-# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de>
-#
-
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-noinst_PROGRAMS = padout$(EXEEXT)
-subdir = doc/specs
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in parse_l.c \
- parse_y.c parse_y.h
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
- $(top_srcdir)/m4/iconv.m4 \
- $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
- $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
- $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
- $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libprelude.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
- $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.in
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-PROGRAMS = $(noinst_PROGRAMS)
-am_padout_OBJECTS = parse_l.$(OBJEXT) parse_y.$(OBJEXT)
-padout_OBJECTS = $(am_padout_OBJECTS)
-padout_DEPENDENCIES =
-DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
-LTLEXCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(LEX) $(LFLAGS) $(AM_LFLAGS)
-YLWRAP = $(top_srcdir)/ylwrap
-YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
-LTYACCCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(YACC) $(YFLAGS) $(AM_YFLAGS)
-SOURCES = $(padout_SOURCES)
-DIST_SOURCES = $(padout_SOURCES)
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(docdir)"
-docDATA_INSTALL = $(INSTALL_DATA)
-DATA = $(doc_DATA)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-BROWSER = @BROWSER@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-ECHO = @ECHO@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-F77 = @F77@
-FFLAGS = @FFLAGS@
-FO2PDF = @FO2PDF@
-GMSGFMT = @GMSGFMT@
-GMSGFMT_015 = @GMSGFMT_015@
-GREP = @GREP@
-HAVE_KEY_MANAGEMENT = @HAVE_KEY_MANAGEMENT@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INTLLIBS = @INTLLIBS@
-INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-LDFLAGS = @LDFLAGS@
-LEX = @LEX@
-LEXLIB = @LEXLIB@
-LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
-LIBAUDIT = @LIBAUDIT@
-LIBCRACK = @LIBCRACK@
-LIBCRYPT = @LIBCRYPT@
-LIBDB = @LIBDB@
-LIBDL = @LIBDL@
-LIBICONV = @LIBICONV@
-LIBINTL = @LIBINTL@
-LIBNSL = @LIBNSL@
-LIBOBJS = @LIBOBJS@
-LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
-LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
-LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
-LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
-LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
-LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
-LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
-LIBS = @LIBS@
-LIBSELINUX = @LIBSELINUX@
-LIBTOOL = @LIBTOOL@
-LN_S = @LN_S@
-LTLIBICONV = @LTLIBICONV@
-LTLIBINTL = @LTLIBINTL@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-MSGFMT = @MSGFMT@
-MSGFMT_015 = @MSGFMT_015@
-MSGMERGE = @MSGMERGE@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PAM_READ_BOTH_CONFS = @PAM_READ_BOTH_CONFS@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PIE_CFLAGS = @PIE_CFLAGS@
-PIE_LDFLAGS = @PIE_LDFLAGS@
-POSUB = @POSUB@
-RANLIB = @RANLIB@
-SCONFIGDIR = @SCONFIGDIR@
-SECUREDIR = @SECUREDIR@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-USE_NLS = @USE_NLS@
-VERSION = @VERSION@
-WITH_DEBUG = @WITH_DEBUG@
-WITH_PAMLOCKING = @WITH_PAMLOCKING@
-XGETTEXT = @XGETTEXT@
-XGETTEXT_015 = @XGETTEXT_015@
-XMLCATALOG = @XMLCATALOG@
-XMLLINT = @XMLLINT@
-XML_CATALOG_FILE = @XML_CATALOG_FILE@
-XSLTPROC = @XSLTPROC@
-YACC = @YACC@
-YFLAGS = @YFLAGS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_F77 = @ac_ct_F77@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libc_cv_fpie = @libc_cv_fpie@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pam_cv_ld_as_needed = @pam_cv_ld_as_needed@
-pam_xauth_path = @pam_xauth_path@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-CLEANFILES = draft-morgan-pam-current.txt *~
-EXTRA_DIST = draft-morgan-pam.raw std-agent-id.raw rfc86.0.txt
-AM_YFLAGS = -d
-BUILT_SOURCES = parse_y.h
-padout_SOURCES = parse_l.l parse_y.y
-padout_LDADD = @LEXLIB@
-doc_DATA = draft-morgan-pam-current.txt rfc86.0.txt
-all: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .l .lo .o .obj .y
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/specs/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --gnu doc/specs/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-clean-noinstPROGRAMS:
- @list='$(noinst_PROGRAMS)'; for p in $$list; do \
- f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f $$p $$f"; \
- rm -f $$p $$f ; \
- done
-parse_y.h: parse_y.c
- @if test ! -f $@; then \
- rm -f parse_y.c; \
- $(MAKE) $(AM_MAKEFLAGS) parse_y.c; \
- else :; fi
-padout$(EXEEXT): $(padout_OBJECTS) $(padout_DEPENDENCIES)
- @rm -f padout$(EXEEXT)
- $(LINK) $(padout_OBJECTS) $(padout_LDADD) $(LIBS)
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse_l.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse_y.Po@am__quote@
-
-.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
-
-.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-
-.l.c:
- $(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE)
-
-.y.c:
- $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE)
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-install-docDATA: $(doc_DATA)
- @$(NORMAL_INSTALL)
- test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)"
- @list='$(doc_DATA)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \
- $(docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \
- done
-
-uninstall-docDATA:
- @$(NORMAL_UNINSTALL)
- @list='$(doc_DATA)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \
- rm -f "$(DESTDIR)$(docdir)/$$f"; \
- done
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- here=`pwd`; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique; \
- fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- here=`pwd`; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- test -z "$(CTAGS_ARGS)$$tags$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$tags $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) check-am
-all-am: Makefile $(PROGRAMS) $(DATA)
-installdirs:
- for dir in "$(DESTDIR)$(docdir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
- -rm -f parse_l.c
- -rm -f parse_y.c
- -rm -f parse_y.h
- -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
- mostlyclean-am
-
-distclean: distclean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am: install-docDATA
-
-install-dvi: install-dvi-am
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-info: install-info-am
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-ps: install-ps-am
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-docDATA
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-libtool clean-noinstPROGRAMS ctags distclean \
- distclean-compile distclean-generic distclean-libtool \
- distclean-tags distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am \
- install-docDATA install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-man install-pdf install-pdf-am \
- install-ps install-ps-am install-strip installcheck \
- installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-compile \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags uninstall uninstall-am uninstall-docDATA
-
-
-draft-morgan-pam-current.txt: padout draft-morgan-pam.raw
- ./padout < $(srcdir)/draft-morgan-pam.raw > draft-morgan-pam-current.txt
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/Linux-PAM/doc/specs/draft-morgan-pam.raw b/Linux-PAM/doc/specs/draft-morgan-pam.raw
deleted file mode 100644
index 2d55048e..00000000
--- a/Linux-PAM/doc/specs/draft-morgan-pam.raw
+++ /dev/null
@@ -1,764 +0,0 @@
-Open-PAM working group ## A.G. Morgan
-Internet Draft: ## Dec 8, 2001
-Document: draft-morgan-pam-08.txt ##
-Expires: June 8, 2002 ##
-Obsoletes: draft-morgan-pam-07.txt##
-
-## Pluggable Authentication Modules (PAM) ##
-
-#$ Status of this memo
-
-This document is a draft specification. Its contents are subject to
-change with revision. The latest version of this draft may be obtained
-from here:
-
- http://www.kernel.org/pub/linux/libs/pam/pre/doc/
-
-As
-
- Linux-PAM-'version'-docs.tar.gz
-
-It is also contained in the Linux-PAM tar ball.
-
-#$ Abstract
-
-This document is concerned with the definition of a general
-infrastructure for module based authentication. The infrastructure is
-named Pluggable Authentication Modules (PAM for short).
-
-#$ Introduction
-
-Computers are tools. They provide services to people and other
-computers (collectively we shall call these _users_ entities). In
-order to provide convenient, reliable and individual service to
-different entities, it is common for entities to be labelled. Having
-defined a label as referring to a some specific entity, the label is
-used for the purpose of protecting and allocating data resources.
-
-All modern operating systems have a notion of labelled entities and
-all modern operating systems face a common problem: how to
-authenticate the association of a predefined label with applicant
-entities.
-
-There are as many authentication methods as one might care to count.
-None of them are perfect and none of them are invulnerable. In
-general, any given authentication method becomes weaker over time. It
-is common then for new authentication methods to be developed in
-response to newly discovered weaknesses in the old authentication
-methods.
-
-The problem with inventing new authentication methods is the fact that
-old applications do not support them. This contributes to an inertia
-that discourages the overhaul of weakly protected systems. Another
-problem is that individuals (people) are frequently powerless to layer
-the protective authentication around their systems. They are forced
-to rely on single (lowest common denominator) authentication schemes
-even in situations where this is far from appropriate.
-
-PAM, as discussed in this document, is a generalization of the
-approach first introduced in [#$R#{OSF_RFC_PAM}]. In short, it is a
-general framework of interfaces that abstract the process of
-authentication. With PAM, a service provider can custom protect
-individual services to the level that they deem is appropriate.
-
-PAM has nothing explicit to say about transport layer encryption.
-Within the context of this document encryption and/or compression of
-data exchanges are application specific (strictly between client and
-server) and orthogonal to the process of authentication.
-
-#$ Definitions
-
-Here we pose the authentication problem as one of configuring defined
-interfaces between two entities.
-
-#$$#{players} Players in the authentication process
-
-PAM reserves the following words to specify unique entities in the
-authentication process:
-
- applicant
- the entity (user) initiating an application for service
- [PAM associates the PAM_RUSER _item_ with this requesting user].
-
- arbitrator
- the entity (user) under whose identity the service application
- is negotiated and with whose authority service is granted.
-
- user
- the entity (user) whose identity is being authenticated
- [PAM associates the PAM_USER _item_ with this identity].
-
- server
- the application that provides service, or acts as an
- authenticated gateway to the requested service. This
- application is completely responsible for the server end of
- the transport layer connecting the server to the client.
- PAM makes no assumptions about how data is encapsulated for
- exchanges between the server and the client, only that full
- octet sequences can be freely exchanged without corruption.
-
- client
- application providing the direct/primary interface to
- applicant. This application is completely responsible
- for the client end of the transport layer connecting the
- server to the client. PAM makes no assumptions about how data
- is encapsulated for exchanges between the server and the
- client, only that full octet sequences can be freely
- exchanged without corruption.
-
- module
- authentication binary that provides server-side support for
- some (arbitrary) authentication method.
-
- agent
- authentication binary that provides client-side support for
- some (arbitrary) authentication method.
-
-Here is a diagram to help orient the reader:
-
-## +-------+ +--------+ ##
-## . . . . .| agent | .| module | ##
-## . +-------+ .+--------+ ##
-## V | . | ##
-## . | V | ##
-## +---------+ +-------+ . +------+ ##
-## | | |libpamc| . |libpam| ##
-## | | +-------+ . +------+ ##
-## |applicant| | . | ##
-## | | +--------+ +----------+ ##
-## | |---| client |-----------| server | ##
-## +---------+ +--------+ +----------+ ##
-
-Solid lines connecting the boxes represent two-way interaction. The
-dotted-directed lines indicate an optional connection beteween the
-plugin module (agent) and the server (applicant). In the case of the
-module, this represents the module invoking the 'conversation'
-callback function provided to libpam by the server application when it
-inititializes the libpam library. In the case of the agent, this may
-be some out-of-PAM API interaction (for example directly displaying a
-dialog box under X).
-
-#$$ Defined Data Types
-
-In this draft, we define two composite data types, the text string and
-the binary prompt. They are the data types used to communicate
-authentication requests and responses.
-
-#$$$#{text_string} text string
-
-The text string is a simple sequence of non-NUL (NUL = 0x00)
-octets. Terminated with a single NUL (0x00) octet. The character set
-employed in the octet sequence may be negotiated out of band, but
-defaults to utf-8.
-
-## --------------------------- ##
-## [ character data | NUL ] ##
-## [ octet sequence | 0x00 ] ##
-## --------------------------- ##
-
-Within the rest of this text, PAM text strings are delimited with a
-pair of double quotes. Example, "this" = {'t';'h';'i';'s';0x00}.
-
-#$$$#{binary_prompt} binary prompt
-
-A binary prompt consists of a stream of octets arranged as follows:
-
-## ---------------------------------------- ##
-## [ u32 | u8 | (length-5 octets) ] ##
-## [ length | control | data ] ##
-## ---------------------------------------- ##
-
-That is, a 32-bit unsigned integer in network byte order, a single
-unsigned byte of control information and a sequence of octets of
-length (length-5). The composition of the _data_ is context dependent
-but is generally not a concern for either the server or the client. It
-is very much the concern of modules and agents.
-
-For purposes of interoperability, we define the following control
-characters as legal.
-
-## value symbol description ##
-## ------------------------------------------------- ##
-## 0x01 PAM_BPC_OK - continuation packet ##
-## 0x02 PAM_BPC_SELECT - initialization packet ##
-## 0x03 PAM_BPC_DONE - termination packet ##
-## 0x04 PAM_BPC_FAIL - unable to execute ##
-
-The following control characters are only legal for exchanges between
-an agent and a client (it is the responsibility of the client to
-enforce this rule in the face of a rogue server):
-
-## 0x41 PAM_BPC_GETENV - obtain client env.var ##
-## 0x42 PAM_BPC_PUTENV - set client env.var ##
-## 0x43 PAM_BPC_TEXT - display message ##
-## 0x44 PAM_BPC_ERROR - display error message ##
-## 0x45 PAM_BPC_PROMPT - echo'd text prompt ##
-## 0x46 PAM_BPC_PASS - non-echo'd text prompt ##
-## 0x46 PAM_BPC_STATUS - ping all active clients##
-## 0x47 PAM_BPC_ABORT - please abort session ##
-
-Note, length is always equal to the total length of the binary
-prompt and represented by a network ordered unsigned 32 bit integer.
-
-#$$$$#{agent_ids} PAM_BPC_SELECT binary prompts
-
-Binary prompts of control type PAM_BPC_SELECT have a defined
-data part. It is composed of three elements:
-
- {agent_id;'/';data}
-
-The agent_id is a sequence of characters satisfying the following
-regexp:
-
- /^[a-z0-9\_]+(@[a-z0-9\_.]+)?$/
-
-and has a specific form for each independent agent.
-
-o Agent_ids that do not contain an at-sign (@) are to be considered as
- representing some authentication mode that is a "public
- standard" see reference [#$R#{PAM_STD_AGENTIDS}]. Registered names
- MUST NOT contain an at-sign (@).
-
-o Anyone can define additional agents by using names in the format
- name@domainname, e.g. "ouragent@example.com". The part following
- the at-sign MUST be a valid fully qualified internet domain name
- [RFC-1034] controlled by the person or organization defining the
- name. (Said another way, if you control the email address that
- your agent has as an identifier, they you are entitled to use
- this identifier.) It is up to each domain how it manages its local
- namespace.
-
-The '/' character is a mandatory delimiter, indicating the end of the
-agent_id. The trailing data is of a format specific to the agent with
-the given agent_id.
-
-
-#$$ Special cases
-
-In a previous section (#{players}) we identified the most general
-selection of authentication participants. In the case of network
-authentication, it is straightforward to ascribe identities to the
-defined participants. However, there are also special (less general)
-cases that we recognize here.
-
-The primary authentication step, when a user is directly introduced
-into a computer system (log's on to a workstation) is a special case.
-In this situation, the client and the server are generally one
-application. Before authenticating such a user, the applicant is
-formally unknown: PAM_RUSER is NULL.
-
-Some client-server implementations (telnet for example) provide
-effective full tty connections. In these cases, the four simple text
-string prompting cases (see below) can be handled as in the primary
-login step. In other words, the server absorbs most of the overhead of
-propagating authentication messages. In these cases, there needs to be
-special client/server support for handling binary prompts.
-
-In some circumstances, a legacy network transfer protocol can carry
-authentication information. In such cases, a desire to support legacy
-clients (with no client-side support for PAM) will neccessitate the
-'hardcoding' of an agent protocol into the server application. Whilst
-against the spirit of PAM, this special casing can be managed by the
-server's 'conversation function' (see below). The guiding principle
-when implementing such support is for the application developer to
-relegate the authentication process to the PAM module -- simply
-performing a transcription of data from binary-prompt to legacy
-network 'packet' and visa-versa for propagating replies back to the
-driving PAM module. A common case of this is with network protocols
-that define an initialization packet of "user+password". In such cases
-one should attempt to support the "userpass" agent-id and its defined
-protocol.
-
-#$ Defined interfaces for information flow
-
-Here, we discuss the information exchange interfaces between the
-players in the authentication process. It should be understood that
-the server side is responsible for driving the authentication of the
-applicant. Notably, every request received by the client from the
-server must be matched with a single response from the client to the
-server.
-
-#$$#{applicant_client} Applicant <-> client
-
-Once the client is invoked, requests to the applicant entity are
-initiated by the client application. General clients are able to make
-the following requests directly to an applicant:
-
- echo text string
- echo error text string
- prompt with text string for echo'd text string input
- prompt with text string for concealed text string input
-
-the nature of the interface provided by the client for the benefit of
-the applicant entity is client specific and not defined by PAM.
-
-#$$#{client_agent} Client <-> agent
-
-In general, authentication schemes require more modes of exchange than
-the four defined in the previous section (#{applicant_client}). This
-provides a role for client-loadable agents. The client and agent
-exchange binary-messages that can have one of the following forms:
-
- client -> agent
- binary prompt agent expecting binary prompt reply to client
-
- agent -> client
- binary prompt reply from agent to clients binary prompt
-
-Following the acceptance of a binary prompt by the agent, the agent
-may attempt to exchange information with the client before returning
-its binary prompt reply. Permitted exchanges are binary prompts of the
-following types:
-
- agent -> client
- set environment variable (A)
- get environment variable (B)
- echo text string (C)
- echo error text string (D)
- prompt for echo'd text string input (E)
- prompt for concealed text string input (F)
-
-In response to these prompts, the client must legitimately respond
-with a corresponding binary prompt reply. We list a complete set of
-example exchanges, including each type of legitimate response (passes
-and a single fail):
-
-## Type | Agent request | Client response ##
-## --------------------------------------------------------------- ##
-## (A) | {13;PAM_BPC_PUTENV;"FOO=BAR"} | {5;PAM_BPC_OK;} ##
-## | {10;PAM_BPC_PUTENV;"FOO="} | {5;PAM_BPC_OK;} ##
-## | {9;PAM_BPC_PUTENV;"FOO"} (*) | {5;PAM_BPC_OK;} ##
-## | {9;PAM_BPC_PUTENV;"BAR"} (*) | {5;PAM_BPC_FAIL;} ##
-## --------------------------------------------------------------- ##
-## (B) | {10;PAM_BPC_GETENV;"TERM"} | {11;PAM_BPC_OK;"vt100"} ##
-## | {9;PAM_BPC_GETENV;"FOO"} | {5;PAM_BPC_FAIL;} ##
-## --------------------------------------------------------------- ##
-## (C) | {12;PAM_BPC_TEXT;"hello!"} | {5;PAM_BPC_OK;} ##
-## | {12;PAM_BPC_TEXT;"hello!"} | {5;PAM_BPC_FAIL;} ##
-## --------------------------------------------------------------- ##
-## (D) | {11;PAM_BPC_ERROR;"ouch!"} | {5;PAM_BPC_OK;} ##
-## | {11;PAM_BPC_ERROR;"ouch!"} | {5;PAM_BPC_FAIL;} ##
-## --------------------------------------------------------------- ##
-## (E) | {13;PAM_BPC_PROMPT;"login: "} | {9;PAM_BPC_OK;"joe"} ##
-## | {13;PAM_BPC_PROMPT;"login: "} | {6;PAM_BPC_OK;""} ##
-## | {13;PAM_BPC_PROMPT;"login: "} | {5;PAM_BPC_FAIL;} ##
-## --------------------------------------------------------------- ##
-## (F) | {16;PAM_BPC_PASS;"password: "} | {9;PAM_BPC_OK;"XYZ"} ##
-## | {16;PAM_BPC_PASS;"password: "} | {6;PAM_BPC_OK;""} ##
-## | {16;PAM_BPC_PASS;"password: "} | {5;PAM_BPC_FAIL;} ##
-
-(*) Used to attempt the removal of a pre-existing environment
-variable.
-
-#$$ Client <-> server
-
-Once the client has established a connection with the server (the
-nature of the transport protocol is not specified by PAM), the server
-is responsible for driving the authentication process.
-
-General servers can request the following from the client:
-
- (to be forwarded by the client to the applicant)
- echo text string
- echo error text string
- prompt for echo'd text string response
- prompt for concealed text string response
-
- (to be forwarded by the client to the appropriate agent)
- binary prompt for a binary prompt response
-
-Client side agents are required to process binary prompts. The
-agents' binary prompt responses are returned to the server.
-
-#$$ Server <-> module
-
-Modules drive the authentication process. The server provides a
-conversation function with which it encapsulates module-generated
-requests and exchanges them with the client. Every message sent by a
-module should be acknowledged.
-
-General conversation functions can support the following five
-conversation requests:
-
- echo text string
- echo error string
- prompt for echo'd text string response
- prompt for concealed text string response
- binary prompt for binary prompt response
-
-The server is responsible for redirecting these requests to the
-client.
-
-#$ C API for application interfaces (client and server)
-
-#$$ Applicant <-> client
-
-No API is defined for this interface. The interface is considered to
-be specific to the client application. Example applications include
-terminal login, (X)windows login, machine file transfer applications.
-
-All that is important is that the client application is able to
-present the applicant with textual output and to receive textual
-input from the applicant. The forms of textual exchange are listed
-in an earlier section (#{applicant_client}). Other methods of
-data input/output are better suited to being handled via an
-authentication agent.
-
-#$$ Client <-> agent
-
-The client makes use of a general API for communicating with
-agents. The client is not required to communicate directly with
-available agents, instead a layer of abstraction (in the form of a
-library: libpamc) takes care of loading and maintaining communication
-with all requested agents. This layer of abstraction will choose which
-agents to interact with based on the content of binary prompts it
-receives that have the control type PAM_BPC_SELECT.
-
-#$$$ Client <-> libpamc
-
-#$$$$ Compilation information
-
-The C-header file provided for client-agent abstraction is included
-with the following source line:
-
- \#include <security/pam_client.h>
-
-The library providing the corresponding client-agent abstraction
-functions is, libpamc.
-
- cc .... -lpamc
-
-#$$$$ Initializing libpamc
-
-The libpamc library is initialized with a call to the following
-function:
-
- pamc_handle_t pamc_start(void);
-
-This function is responsible for configuring the library and
-registering the location of available agents. The location of the
-available agents on the system is implementation specific.
-
-pamc_start() function returns NULL on failure. Otherwise, the return
-value is a pointer to an opaque data type which provides a handle to
-the libpamc library. On systems where threading is available, the
-libpamc libraray is thread safe provided a single (pamc_handler_t *)
-is used by each thread.
-
-#$$$$ Client (Applicant) selection of agents
-
-For the purpose of applicant and client review of available agents,
-the following function is provided.
-
- char **pamc_list_agents(pamc_handle_t pch);
-
-This returns a list of pointers to the agent_id's of the agents which
-are available on the system. The list is terminated by a NULL pointer.
-It is the clients responsibility to free this memory area by calling
-free() on each agent id and the block of agent_id pointers in the
-result.
-
-PAM represents a server-driven authentication model, so by default
-any available agent may be invoked in the authentication process.
-
-#$$$$$ Client demands agent
-
-If the client requires that a specific authentication agent is
-satisfied during the authentication process, then the client should
-call the following function, immediately after obtaining a
-pamc_handle_t from pamc_start().
-
- int pamc_load(pamc_handle_t pch, const char *agent_id);
-
-agent_id is a PAM text string (see section #{agent_ids}) and is not
-suffixed with a '/' delimiter. The return value for this function is:
-
- PAM_BPC_TRUE - agent located and loaded.
- PAM_BPC_FALSE - agent is not available.
-
-Note, although the agent is loaded, no data is fed to it. The agent's
-opportunity to inform the client that it does not trust the server is
-when the agent is shutdown.
-
-#$$$$$ Client marks agent as unusable
-
-The applicant might prefer that a named agent is marked as not
-available. To do this, the client would invoke the following function
-immediately after obtaining a pamc_handle_t from pam_start().
-
- int pamc_disable(pamc_handle_t pch, const char *agent_id);
-
-here agent_id is a PAM text string containing an agent_id (section
-#{agent_ids}).
-
-The return value for this function is:
-
- PAM_BPC_TRUE - agent is disabled. This is the response
- independent of whether the agent is locally
- available.
-
- PAM_BPC_FALSE - agent cannot be disabled (this may be because
- it has already been invoked).
-
-#$$$$ Allocating and manipulating binary prompts
-
-All conversation between an client and an agent takes place with
-respect to binary prompts. A binary prompt (see section #{binary_prompt}), is
-obtained, resized and deleted via the following C-macro:
-
- CREATION of a binary prompt with control X1 and data length Y1:
-
- pamc_bp_t prompt = NULL;
- PAM_BP_RENEW(&prompt, X1, Y1);
-
- REPLACEMENT of a binary prompt with a control X2 and data length Y2:
-
- PAM_BP_RENEW(&prompt, X2, Y2);
-
- DELETION of a binary prompt (the referenced prompt is scrubbed):
-
- PAM_BP_RENEW(&prompt, 0, 0);
-
-Note, the PAM_BP_RENEW macro always overwrites any prompt that you
-call it with, deleting and liberating the old contents in a secure
-fashion. Also note that PAM_BP_RENEW, when returning a prompt of data
-size Y1>0, will always append a '\0' byte to the end of the prompt (at
-data offset Y1). It is thus, by definition, acceptable to treat the
-data contents of a binary packet as a text string (see #{text_string}).
-
- FILLING a binary prompt from a memory pointer U1 from offset O1 of
- length L1:
-
- PAM_BP_FILL(prompt, O1, L1, U1);
-
- the CONTROL type for the packet can be obtained as follows:
-
- control = PAM_PB_CONTROL(prompt);
-
- the LENGTH of a data within the prompt (_excluding_ its header
- information) can be obtained as follows:
-
- length = PAM_BP_LENGTH(prompt);
-
- the total SIZE of the prompt (_including_ its header information)
- can be obtained as follows:
-
- size = PAM_BP_SIZE(prompt);
-
- EXTRACTING data from a binary prompt from offset O2 of length L2 to
- a memory pointer U2:
-
- PAM_BP_EXTRACT(prompt, O2, L2, U2);
-
- If you require direct access to the raw prompt DATA, you should use
- the following macro:
-
- __u8 *raw_data = PAM_BP_DATA(prompt);
-
-#$$$$ Client<->agent conversations
-
-All exchanges of binary prompts with agents are handled with the
-single function:
-
- int pamc_converse(pamc_handle_t *pch, pamc_bp_t *prompt_p);
-
-The return value for pamc_converse(...) is PAM_BPC_TRUE when there is
-a response packet and PAM_BPC_FALSE when the client is unable to
-handle the request represented by the original prompt. In this latter
-case, *prompt_p is set to NULL.
-
-This function takes a binary prompt and returns a replacement binary
-prompt that is either a request from an agent to be acted upon by the
-client or the 'result' which should be forwarded to the server. In the
-former case, the following macro will return 1 (PAM_BPC_TRUE) and in
-all other cases, 0 (PAM_BPC_FALSE):
-
- PAM_BPC_FOR_CLIENT(/* pamc_bp_t */ prompt)
-
-Note, all non-NULL binary prompts returned by pamc_converse(...), are
-terminated with a '\0', even when the full length of the prompt (as
-returned by the agent) does not contain this delimiter. This is a
-defined property of the PAM_BP_RENEW macro, and can be relied upon.
-
-Important security note: in certain implementations, agents are
-implemented by executable binaries, which are transparently loaded and
-managed by the PAM client library. To ensure there is never a leakage
-of elevated privilege to an unprivileged agent, the client application
-should go to some effort to lower its level of privilege. It remains
-the responsibility of the applicant and the client to ensure that it
-is not compromised by a rogue agent.
-
-#$$$$ Status of agents
-
- int pamc_status(pamc_handle_t *pch, pamc_bp_t *prompt_p);
-
-At any time, the client may ping all active agents for their status
-(with a PAM_BPC_STATUS binary prompt). If any agent replies with
-PAM_BPC_ABORT, the client is responsible for terminating the
-connection to the server and then terminating all agents with a call
-to pamc_end(). In such cases, the return value of pamc_status() is
-PAM_BPC_FALSE.
-
-If the return status of pamc_status() is PAM_BPC_TRUE and *prompt_p is
-non-NULL, then an agent is requesting access to a server module.
-
-XXX - how this information gets propagated to the server, and
- ultimately to the server's module is yet to be determined.
-
-#$$$$ Termination of agents
-
-When closing the authentication session and severing the connection
-between a client and a selection of agents, the following function is
-used:
-
- int pamc_end(pamc_handle_t *pch);
-
-Following a call to pamc_end, the pamc_handle_t will be invalid.
-
-The return value for this function is one of the following:
-
- PAM_BPC_TRUE - all invoked agents are content with
- authentication (the server is _not_ judged
- _un_trustworthy by any agent)
-
- PAM_BPC_FALSE - one or more agents were unsatisfied at
- being terminated. In general, the client
- should terminate its connection to the
- server and indicate to the applicant that
- the server is untrusted.
-
-#$$$ libpamc <-> agents
-
-The agents are manipulated from within libpamc. Each agent is an
-executable in its own right. This permits the agent to have access to
-sensitive data not accessible directly from the client. The mode of
-communication between libpamc and an agent is through a pair of
-pipes. The agent reads binary prompts (section #{binary_prompt})
-through its standard input file descriptor and writes response (to the
-server) binary prompts and instruction binary prompts (instructions
-for the client) through its standard output file descriptor.
-
-#$$ Client <-> server
-
-This interface is concerned with the exchange of text and binary
-prompts between the client application and the server application. No
-API is provided for this as it is considered specific to the transport
-protocol shared by the client and the server.
-
-#$$ Server <-> modules
-
-The server makes use of a general API for communicating with
-modules. The client is not required to communicate directly with
-available modules. By abstracting the authentication interface, it
-becomes possible for the local administrator to make a run time
-decision about the authentication method adopted by the server.
-
-#$$$ Functions and definitions available to servers and modules
-
-[This section will document the following functions
-
- pam_set_item()
- pam_get_item()
- pam_fail_delay(pam_handle_t *pamh, unsigned int micro_sec)
- pam_get_env(pam_handle_t *pamh, const char *varname)
- pam_strerror(pam_handle_t *pamh, int pam_errno)
-
-Event driven support (XXX work in progress)
-
- pam_register_event() - app or module associates an event poller/handler
- pam_select_event() - query for any outstanding event and act on any
-]
-
-#$$$ Server <-> libpam
-
-[This section will document the following pam_ calls:
-
- pam_start
- pam_end
- pam_authenticate (*)
- pam_setcred
- pam_acct_mgmt
- pam_open_session
- pam_close_session
- pam_chauthtok (*)
-
-The asterisked functions may return PAM_INCOMPLETE. In such cases, the
-application should be aware that the conversation function was called
-and that it returned PAM_CONV_AGAIN to a module. The correct action
-for the application to take in response to receiving PAM_INCOMPLETE,
-is to acquire the replies so that the next time the conversation
-function is called it will be able to provide the desired
-responses. And then recall pam_authenticate (pam_chauthtok) with the
-same arguments. Libpam will arrange that the module stack is resumed
-from the module that returned before. This functionality is required
-for programs whose user interface is maintained by an event loop. ]
-
-#$$$ libpam <-> modules
-
-[This section will document the following pam_ and pam_sm_ calls:
-
-functions provided by libpam
-
- pam_set_data
- pam_get_data
-
-functions provided to libpam by each module
-
- groups:
- AUTHENTICATION
- pam_sm_authenticate
- pam_sm_setcred
- ACCOUNT
- pam_sm_acct_mgmt
- SESSION
- pam_sm_open_session
- pam_sm_close_session
- AUTHENTICATION TOKEN MANAGEMENT
- pam_sm_chauthtok
-]
-
-#$$$ The conversation function
-
-The server application, as part of its initialization of libpam,
-provides a conversation function for use by modules and libpam. The
-purpose of the conversation function is to enable direct communication
-to the applicant ultimately via the client and selected agents.
-
-[ this section will contain a definition for the conversation
- function, the conversation structure (appdata etc), and legitimate
- return codes for the application supplied function.
-
- PAM_SUCCESS - ok conversation completed
- PAM_CONV_ERR - conversation failed
- PAM_CONV_AGAIN - application needs control to complete conv
- PAM_CONV_RECONSIDER - application believes module should check if
- it still needs to converse for this info
- ]
-
-#$ Security considerations
-
-This document is devoted to standardizing authentication
-infrastructure: everything in this document has implications for
-security.
-
-#$ Contact
-
-The email list for discussing issues related to this document is
-<pam-list@redhat.com>.
-
-#$ References
-
-[#{OSF_RFC_PAM}] OSF RFC 86.0, "Unified Login with Pluggable Authentication
- Modules (PAM)", October 1995
-
-[#{PAM_STD_AGENTIDS}] Definitions for standard agents, "REGISTERED
- AGENTS AND THEIR AGENT-ID'S", to be found here:
-
-## http://www.kernel.org/pub/linux/libs/pam/pre/doc/std-agent-ids.txt ##
-
-#$ Author's Address
-
-Andrew G. Morgan
-Email: morgan@kernel.org
-
-## $Id: draft-morgan-pam.raw,v 1.2 2001/12/08 18:56:47 agmorgan Exp $ ##
diff --git a/Linux-PAM/doc/specs/parse_l.c b/Linux-PAM/doc/specs/parse_l.c
deleted file mode 100644
index 7fc9cb1d..00000000
--- a/Linux-PAM/doc/specs/parse_l.c
+++ /dev/null
@@ -1,1719 +0,0 @@
-
-#line 3 "parse_l.c"
-
-#define YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 33
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX (4294967295U)
-#endif
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-#if __STDC__
-
-#define YY_USE_CONST
-
-#endif /* __STDC__ */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* Enter a start condition. This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN (yy_start) = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state. The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START (((yy_start) - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#define YY_BUF_SIZE 16384
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-extern int yyleng;
-
-extern FILE *yyin, *yyout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
- #define YY_LESS_LINENO(n)
-
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- *yy_cp = (yy_hold_char); \
- YY_RESTORE_YY_MORE_OFFSET \
- (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
- YY_DO_BEFORE_ACTION; /* set up yytext again */ \
- } \
- while ( 0 )
-
-#define unput(c) yyunput( c, (yytext_ptr) )
-
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- int yy_bs_lineno; /**< The line count. */
- int yy_bs_column; /**< The column count. */
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
- /* When an EOF's been seen but there's still some text to process
- * then we mark the buffer as YY_EOF_PENDING, to indicate that we
- * shouldn't try reading from the input source any more. We might
- * still have a bunch of tokens to match, though, because of
- * possible backing-up.
- *
- * When we actually see the EOF, we change the status to "new"
- * (via yyrestart()), so that the user can continue scanning by
- * just pointing yyin at a new input file.
- */
-#define YY_BUFFER_EOF_PENDING 2
-
- };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
- ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
- : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
-
-/* yy_hold_char holds the character lost when yytext is formed. */
-static char yy_hold_char;
-static int yy_n_chars; /* number of characters read into yy_ch_buf */
-int yyleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 0; /* whether we need to initialize */
-static int yy_start = 0; /* start state number */
-
-/* Flag which is used to allow yywrap()'s to do buffer switches
- * instead of setting up a fresh yyin. A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void yyrestart (FILE *input_file );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
-void yy_delete_buffer (YY_BUFFER_STATE b );
-void yy_flush_buffer (YY_BUFFER_STATE b );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
-void yypop_buffer_state (void );
-
-static void yyensure_buffer_stack (void );
-static void yy_load_buffer_state (void );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
-
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
-
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
-
-void *yyalloc (yy_size_t );
-void *yyrealloc (void *,yy_size_t );
-void yyfree (void * );
-
-#define yy_new_buffer yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
- { \
- if ( ! YY_CURRENT_BUFFER ){ \
- yyensure_buffer_stack (); \
- YY_CURRENT_BUFFER_LVALUE = \
- yy_create_buffer(yyin,YY_BUF_SIZE ); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
- }
-
-#define yy_set_bol(at_bol) \
- { \
- if ( ! YY_CURRENT_BUFFER ){\
- yyensure_buffer_stack (); \
- YY_CURRENT_BUFFER_LVALUE = \
- yy_create_buffer(yyin,YY_BUF_SIZE ); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
- }
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-typedef unsigned char YY_CHAR;
-
-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
-
-typedef int yy_state_type;
-
-extern int yylineno;
-extern char *yytext;
-#define yytext_ptr yytext
-
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
-static int yy_get_next_buffer (void );
-static void yy_fatal_error (yyconst char msg[] );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
- (yytext_ptr) = yy_bp; \
- yyleng = (size_t) (yy_cp - yy_bp); \
- (yy_hold_char) = *yy_cp; \
- *yy_cp = '\0'; \
- (yy_c_buf_p) = yy_cp;
-
-#define YY_NUM_RULES 8
-#define YY_END_OF_BUFFER 9
-/* This struct is not used in this scanner,
- but its presence is necessary. */
-struct yy_trans_info
- {
- flex_int32_t yy_verify;
- flex_int32_t yy_nxt;
- };
-static yyconst flex_int16_t yy_accept[19] =
- { 0,
- 0, 0, 9, 6, 7, 3, 6, 4, 1, 0,
- 5, 0, 1, 0, 1, 0, 2, 0
- } ;
-
-static yyconst flex_int32_t yy_ec[256] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 3, 4, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 1, 1, 1,
- 6, 1, 1, 1, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 1, 8, 1, 1, 9, 1, 7, 7, 7, 7,
-
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 10, 1, 11, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1
- } ;
-
-static yyconst flex_int32_t yy_meta[12] =
- { 0,
- 1, 1, 1, 1, 2, 1, 2, 1, 2, 1,
- 2
- } ;
-
-static yyconst flex_int16_t yy_base[21] =
- { 0,
- 0, 7, 21, 30, 30, 13, 17, 30, 20, 12,
- 30, 13, 10, 2, 7, 0, 30, 30, 27, 2
- } ;
-
-static yyconst flex_int16_t yy_def[21] =
- { 0,
- 19, 19, 18, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 9, 20, 18, 20, 18, 0, 18, 18
- } ;
-
-static yyconst flex_int16_t yy_nxt[42] =
- { 0,
- 18, 5, 6, 16, 18, 18, 18, 7, 5, 6,
- 17, 15, 17, 18, 7, 8, 9, 15, 14, 11,
- 18, 18, 10, 9, 18, 12, 13, 4, 4, 3,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
- 18
- } ;
-
-static yyconst flex_int16_t yy_chk[42] =
- { 0,
- 0, 1, 1, 20, 0, 0, 0, 1, 2, 2,
- 16, 15, 14, 13, 2, 6, 6, 12, 10, 7,
- 3, 0, 6, 9, 0, 9, 9, 19, 19, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
- 18
- } ;
-
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
-
-extern int yy_flex_debug;
-int yy_flex_debug = 0;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *yytext;
-#line 1 "parse_l.l"
-#line 2 "parse_l.l"
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-
-#include "parse_y.h"
-#line 470 "parse_l.c"
-
-#define INITIAL 0
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-static int yy_init_globals (void );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap (void );
-#else
-extern int yywrap (void );
-#endif
-#endif
-
- static void yyunput (int c,char *buf_ptr );
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (void );
-#else
-static int input (void );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
-#endif
-
-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
- { \
- int c = '*'; \
- size_t n; \
- for ( n = 0; n < max_size && \
- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
- buf[n] = (char) c; \
- if ( c == '\n' ) \
- buf[n++] = (char) c; \
- if ( c == EOF && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- result = n; \
- } \
- else \
- { \
- errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
- { \
- if( errno != EINTR) \
- { \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- break; \
- } \
- errno=0; \
- clearerr(yyin); \
- } \
- }\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex (void);
-
-#define YY_DECL int yylex (void)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
- YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
- register yy_state_type yy_current_state;
- register char *yy_cp, *yy_bp;
- register int yy_act;
-
-#line 11 "parse_l.l"
-
-
-#line 626 "parse_l.c"
-
- if ( !(yy_init) )
- {
- (yy_init) = 1;
-
-#ifdef YY_USER_INIT
- YY_USER_INIT;
-#endif
-
- if ( ! (yy_start) )
- (yy_start) = 1; /* first start state */
-
- if ( ! yyin )
- yyin = stdin;
-
- if ( ! yyout )
- yyout = stdout;
-
- if ( ! YY_CURRENT_BUFFER ) {
- yyensure_buffer_stack ();
- YY_CURRENT_BUFFER_LVALUE =
- yy_create_buffer(yyin,YY_BUF_SIZE );
- }
-
- yy_load_buffer_state( );
- }
-
- while ( 1 ) /* loops until end-of-file is reached */
- {
- yy_cp = (yy_c_buf_p);
-
- /* Support of yytext. */
- *yy_cp = (yy_hold_char);
-
- /* yy_bp points to the position in yy_ch_buf of the start of
- * the current run.
- */
- yy_bp = yy_cp;
-
- yy_current_state = (yy_start);
-yy_match:
- do
- {
- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
- if ( yy_accept[yy_current_state] )
- {
- (yy_last_accepting_state) = yy_current_state;
- (yy_last_accepting_cpos) = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 19 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- ++yy_cp;
- }
- while ( yy_base[yy_current_state] != 30 );
-
-yy_find_action:
- yy_act = yy_accept[yy_current_state];
- if ( yy_act == 0 )
- { /* have to back up */
- yy_cp = (yy_last_accepting_cpos);
- yy_current_state = (yy_last_accepting_state);
- yy_act = yy_accept[yy_current_state];
- }
-
- YY_DO_BEFORE_ACTION;
-
-do_action: /* This label is used only to access EOF actions. */
-
- switch ( yy_act )
- { /* beginning of action switch */
- case 0: /* must back up */
- /* undo the effects of YY_DO_BEFORE_ACTION */
- *yy_cp = (yy_hold_char);
- yy_cp = (yy_last_accepting_cpos);
- yy_current_state = (yy_last_accepting_state);
- goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 13 "parse_l.l"
-return NEW_COUNTER;
- YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 14 "parse_l.l"
-return LABEL;
- YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 15 "parse_l.l"
-return NO_INDENT;
- YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 16 "parse_l.l"
-return RIGHT;
- YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 17 "parse_l.l"
-return HASH;
- YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 18 "parse_l.l"
-return CHAR;
- YY_BREAK
-case 7:
-/* rule 7 can match eol */
-YY_RULE_SETUP
-#line 19 "parse_l.l"
-return NEWLINE;
- YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 21 "parse_l.l"
-ECHO;
- YY_BREAK
-#line 750 "parse_l.c"
-case YY_STATE_EOF(INITIAL):
- yyterminate();
-
- case YY_END_OF_BUFFER:
- {
- /* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
-
- /* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = (yy_hold_char);
- YY_RESTORE_YY_MORE_OFFSET
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
- {
- /* We're scanning a new file or input source. It's
- * possible that this happened because the user
- * just pointed yyin at a new source and called
- * yylex(). If so, then we have to assure
- * consistency between YY_CURRENT_BUFFER and our
- * globals. Here is the right place to do so, because
- * this is the first action (other than possibly a
- * back-up) that will match for the new input source.
- */
- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
- }
-
- /* Note that here we test for yy_c_buf_p "<=" to the position
- * of the first EOB in the buffer, since yy_c_buf_p will
- * already have been incremented past the NUL character
- * (since all states make transitions on EOB to the
- * end-of-buffer state). Contrast this with the test
- * in input().
- */
- if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
- { /* This was really a NUL. */
- yy_state_type yy_next_state;
-
- (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( );
-
- /* Okay, we're now positioned to make the NUL
- * transition. We couldn't have
- * yy_get_previous_state() go ahead and do it
- * for us because it doesn't know how to deal
- * with the possibility of jamming (and we don't
- * want to build jamming into it because then it
- * will run more slowly).
- */
-
- yy_next_state = yy_try_NUL_trans( yy_current_state );
-
- yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-
- if ( yy_next_state )
- {
- /* Consume the NUL. */
- yy_cp = ++(yy_c_buf_p);
- yy_current_state = yy_next_state;
- goto yy_match;
- }
-
- else
- {
- yy_cp = (yy_c_buf_p);
- goto yy_find_action;
- }
- }
-
- else switch ( yy_get_next_buffer( ) )
- {
- case EOB_ACT_END_OF_FILE:
- {
- (yy_did_buffer_switch_on_eof) = 0;
-
- if ( yywrap( ) )
- {
- /* Note: because we've taken care in
- * yy_get_next_buffer() to have set up
- * yytext, we can now set up
- * yy_c_buf_p so that if some total
- * hoser (like flex itself) wants to
- * call the scanner after we return the
- * YY_NULL, it'll still work - another
- * YY_NULL will get returned.
- */
- (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
-
- yy_act = YY_STATE_EOF(YY_START);
- goto do_action;
- }
-
- else
- {
- if ( ! (yy_did_buffer_switch_on_eof) )
- YY_NEW_FILE;
- }
- break;
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- (yy_c_buf_p) =
- (yytext_ptr) + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( );
-
- yy_cp = (yy_c_buf_p);
- yy_bp = (yytext_ptr) + YY_MORE_ADJ;
- goto yy_match;
-
- case EOB_ACT_LAST_MATCH:
- (yy_c_buf_p) =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
-
- yy_current_state = yy_get_previous_state( );
-
- yy_cp = (yy_c_buf_p);
- yy_bp = (yytext_ptr) + YY_MORE_ADJ;
- goto yy_find_action;
- }
- break;
- }
-
- default:
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--no action found" );
- } /* end of action switch */
- } /* end of scanning one token */
-} /* end of yylex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- * EOB_ACT_LAST_MATCH -
- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- * EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (void)
-{
- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
- register char *source = (yytext_ptr);
- register int number_to_move, i;
- int ret_val;
-
- if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--end of buffer missed" );
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
- { /* Don't try to fill the buffer, so this is an EOF. */
- if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
- {
- /* We matched a single character, the EOB, so
- * treat this as a final EOF.
- */
- return EOB_ACT_END_OF_FILE;
- }
-
- else
- {
- /* We matched some text prior to the EOB, first
- * process it.
- */
- return EOB_ACT_LAST_MATCH;
- }
- }
-
- /* Try to read more data. */
-
- /* First move last chars to start of buffer. */
- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
-
- for ( i = 0; i < number_to_move; ++i )
- *(dest++) = *(source++);
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
- /* don't do the read, it's not guaranteed to return an EOF,
- * just force an EOF
- */
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
-
- else
- {
- int num_to_read =
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-
- /* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
- int yy_c_buf_p_offset =
- (int) ((yy_c_buf_p) - b->yy_ch_buf);
-
- if ( b->yy_is_our_buffer )
- {
- int new_size = b->yy_buf_size * 2;
-
- if ( new_size <= 0 )
- b->yy_buf_size += b->yy_buf_size / 8;
- else
- b->yy_buf_size *= 2;
-
- b->yy_ch_buf = (char *)
- /* Include room in for 2 EOB chars. */
- yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
- }
- else
- /* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
-
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR(
- "fatal error - scanner input buffer overflow" );
-
- (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
- number_to_move - 1;
-
- }
-
- if ( num_to_read > YY_READ_BUF_SIZE )
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- (yy_n_chars), num_to_read );
-
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
- }
-
- if ( (yy_n_chars) == 0 )
- {
- if ( number_to_move == YY_MORE_ADJ )
- {
- ret_val = EOB_ACT_END_OF_FILE;
- yyrestart(yyin );
- }
-
- else
- {
- ret_val = EOB_ACT_LAST_MATCH;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
- YY_BUFFER_EOF_PENDING;
- }
- }
-
- else
- ret_val = EOB_ACT_CONTINUE_SCAN;
-
- (yy_n_chars) += number_to_move;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
-
- (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
- return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
- static yy_state_type yy_get_previous_state (void)
-{
- register yy_state_type yy_current_state;
- register char *yy_cp;
-
- yy_current_state = (yy_start);
-
- for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
- {
- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
- if ( yy_accept[yy_current_state] )
- {
- (yy_last_accepting_state) = yy_current_state;
- (yy_last_accepting_cpos) = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 19 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- }
-
- return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- * next_state = yy_try_NUL_trans( current_state );
- */
- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
-{
- register int yy_is_jam;
- register char *yy_cp = (yy_c_buf_p);
-
- register YY_CHAR yy_c = 1;
- if ( yy_accept[yy_current_state] )
- {
- (yy_last_accepting_state) = yy_current_state;
- (yy_last_accepting_cpos) = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 19 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 18);
-
- return yy_is_jam ? 0 : yy_current_state;
-}
-
- static void yyunput (int c, register char * yy_bp )
-{
- register char *yy_cp;
-
- yy_cp = (yy_c_buf_p);
-
- /* undo effects of setting up yytext */
- *yy_cp = (yy_hold_char);
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- { /* need to shift things up to make room */
- /* +2 for EOB chars. */
- register int number_to_move = (yy_n_chars) + 2;
- register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
- register char *source =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
- while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- *--dest = *--source;
-
- yy_cp += (int) (dest - source);
- yy_bp += (int) (dest - source);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- YY_FATAL_ERROR( "flex scanner push-back overflow" );
- }
-
- *--yy_cp = (char) c;
-
- (yytext_ptr) = yy_bp;
- (yy_hold_char) = *yy_cp;
- (yy_c_buf_p) = yy_cp;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
- static int yyinput (void)
-#else
- static int input (void)
-#endif
-
-{
- int c;
-
- *(yy_c_buf_p) = (yy_hold_char);
-
- if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
- {
- /* yy_c_buf_p now points to the character we want to return.
- * If this occurs *before* the EOB characters, then it's a
- * valid NUL; if not, then we've hit the end of the buffer.
- */
- if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
- /* This was really a NUL. */
- *(yy_c_buf_p) = '\0';
-
- else
- { /* need more input */
- int offset = (yy_c_buf_p) - (yytext_ptr);
- ++(yy_c_buf_p);
-
- switch ( yy_get_next_buffer( ) )
- {
- case EOB_ACT_LAST_MATCH:
- /* This happens because yy_g_n_b()
- * sees that we've accumulated a
- * token and flags that we need to
- * try matching the token before
- * proceeding. But for input(),
- * there's no matching to consider.
- * So convert the EOB_ACT_LAST_MATCH
- * to EOB_ACT_END_OF_FILE.
- */
-
- /* Reset buffer status. */
- yyrestart(yyin );
-
- /*FALLTHROUGH*/
-
- case EOB_ACT_END_OF_FILE:
- {
- if ( yywrap( ) )
- return EOF;
-
- if ( ! (yy_did_buffer_switch_on_eof) )
- YY_NEW_FILE;
-#ifdef __cplusplus
- return yyinput();
-#else
- return input();
-#endif
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- (yy_c_buf_p) = (yytext_ptr) + offset;
- break;
- }
- }
- }
-
- c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
- *(yy_c_buf_p) = '\0'; /* preserve yytext */
- (yy_hold_char) = *++(yy_c_buf_p);
-
- return c;
-}
-#endif /* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- *
- * @note This function does not reset the start condition to @c INITIAL .
- */
- void yyrestart (FILE * input_file )
-{
-
- if ( ! YY_CURRENT_BUFFER ){
- yyensure_buffer_stack ();
- YY_CURRENT_BUFFER_LVALUE =
- yy_create_buffer(yyin,YY_BUF_SIZE );
- }
-
- yy_init_buffer(YY_CURRENT_BUFFER,input_file );
- yy_load_buffer_state( );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- *
- */
- void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
-{
-
- /* TODO. We should be able to replace this entire function body
- * with
- * yypop_buffer_state();
- * yypush_buffer_state(new_buffer);
- */
- yyensure_buffer_stack ();
- if ( YY_CURRENT_BUFFER == new_buffer )
- return;
-
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *(yy_c_buf_p) = (yy_hold_char);
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
- }
-
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
- yy_load_buffer_state( );
-
- /* We don't actually know whether we did this switch during
- * EOF (yywrap()) processing, but the only time this flag
- * is looked at is after yywrap() is called, so it's safe
- * to go ahead and always set it.
- */
- (yy_did_buffer_switch_on_eof) = 1;
-}
-
-static void yy_load_buffer_state (void)
-{
- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
- (yy_hold_char) = *(yy_c_buf_p);
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- *
- * @return the allocated buffer state.
- */
- YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
-{
- YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
- b->yy_buf_size = size;
-
- /* yy_ch_buf has to be 2 characters longer than the size given because
- * we need to put in 2 end-of-buffer characters.
- */
- b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
- b->yy_is_our_buffer = 1;
-
- yy_init_buffer(b,file );
-
- return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with yy_create_buffer()
- *
- */
- void yy_delete_buffer (YY_BUFFER_STATE b )
-{
-
- if ( ! b )
- return;
-
- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
- if ( b->yy_is_our_buffer )
- yyfree((void *) b->yy_ch_buf );
-
- yyfree((void *) b );
-}
-
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a yyrestart() or at EOF.
- */
- static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
-
-{
- int oerrno = errno;
-
- yy_flush_buffer(b );
-
- b->yy_input_file = file;
- b->yy_fill_buffer = 1;
-
- /* If b is the current buffer, then yy_init_buffer was _probably_
- * called from yyrestart() or through yy_get_next_buffer.
- * In that case, we don't want to reset the lineno or column.
- */
- if (b != YY_CURRENT_BUFFER){
- b->yy_bs_lineno = 1;
- b->yy_bs_column = 0;
- }
-
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-
- errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- *
- */
- void yy_flush_buffer (YY_BUFFER_STATE b )
-{
- if ( ! b )
- return;
-
- b->yy_n_chars = 0;
-
- /* We always need two end-of-buffer characters. The first causes
- * a transition to the end-of-buffer state. The second causes
- * a jam in that state.
- */
- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
- b->yy_buf_pos = &b->yy_ch_buf[0];
-
- b->yy_at_bol = 1;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- if ( b == YY_CURRENT_BUFFER )
- yy_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- * the current state. This function will allocate the stack
- * if necessary.
- * @param new_buffer The new state.
- *
- */
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
- if (new_buffer == NULL)
- return;
-
- yyensure_buffer_stack();
-
- /* This block is copied from yy_switch_to_buffer. */
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *(yy_c_buf_p) = (yy_hold_char);
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
- }
-
- /* Only push if top exists. Otherwise, replace top. */
- if (YY_CURRENT_BUFFER)
- (yy_buffer_stack_top)++;
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
- /* copied from yy_switch_to_buffer. */
- yy_load_buffer_state( );
- (yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- * The next element becomes the new top.
- *
- */
-void yypop_buffer_state (void)
-{
- if (!YY_CURRENT_BUFFER)
- return;
-
- yy_delete_buffer(YY_CURRENT_BUFFER );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- if ((yy_buffer_stack_top) > 0)
- --(yy_buffer_stack_top);
-
- if (YY_CURRENT_BUFFER) {
- yy_load_buffer_state( );
- (yy_did_buffer_switch_on_eof) = 1;
- }
-}
-
-/* Allocates the stack if it does not exist.
- * Guarantees space for at least one push.
- */
-static void yyensure_buffer_stack (void)
-{
- int num_to_alloc;
-
- if (!(yy_buffer_stack)) {
-
- /* First allocation is just for 2 elements, since we don't know if this
- * scanner will even need a stack. We use 2 instead of 1 to avoid an
- * immediate realloc on the next call.
- */
- num_to_alloc = 1;
- (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
- (num_to_alloc * sizeof(struct yy_buffer_state*)
- );
-
- memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
- (yy_buffer_stack_max) = num_to_alloc;
- (yy_buffer_stack_top) = 0;
- return;
- }
-
- if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
-
- /* Increase the buffer to prepare for a possible push. */
- int grow_size = 8 /* arbitrary grow size */;
-
- num_to_alloc = (yy_buffer_stack_max) + grow_size;
- (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
- ((yy_buffer_stack),
- num_to_alloc * sizeof(struct yy_buffer_state*)
- );
-
- /* zero only the new slots.*/
- memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
- (yy_buffer_stack_max) = num_to_alloc;
- }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- *
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
-{
- YY_BUFFER_STATE b;
-
- if ( size < 2 ||
- base[size-2] != YY_END_OF_BUFFER_CHAR ||
- base[size-1] != YY_END_OF_BUFFER_CHAR )
- /* They forgot to leave room for the EOB's. */
- return 0;
-
- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
- b->yy_n_chars = b->yy_buf_size;
- b->yy_is_interactive = 0;
- b->yy_at_bol = 1;
- b->yy_fill_buffer = 0;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- yy_switch_to_buffer(b );
-
- return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to yylex() will
- * scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
- *
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- * yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
-{
-
- return yy_scan_bytes(yystr,strlen(yystr) );
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- *
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
-{
- YY_BUFFER_STATE b;
- char *buf;
- yy_size_t n;
- int i;
-
- /* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) yyalloc(n );
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
- for ( i = 0; i < _yybytes_len; ++i )
- buf[i] = yybytes[i];
-
- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
- b = yy_scan_buffer(buf,n );
- if ( ! b )
- YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
-
- /* It's okay to grow etc. this buffer, and we should throw it
- * away when we're done.
- */
- b->yy_is_our_buffer = 1;
-
- return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg )
-{
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- yytext[yyleng] = (yy_hold_char); \
- (yy_c_buf_p) = yytext + yyless_macro_arg; \
- (yy_hold_char) = *(yy_c_buf_p); \
- *(yy_c_buf_p) = '\0'; \
- yyleng = yyless_macro_arg; \
- } \
- while ( 0 )
-
-/* Accessor methods (get/set functions) to struct members. */
-
-/** Get the input stream.
- *
- */
-FILE *yyget_in (void)
-{
- return yyin;
-}
-
-/** Get the output stream.
- *
- */
-FILE *yyget_out (void)
-{
- return yyout;
-}
-
-/** Get the length of the current token.
- *
- */
-int yyget_leng (void)
-{
- return yyleng;
-}
-
-/** Get the current token.
- *
- */
-
-char *yyget_text (void)
-{
- return yytext;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- *
- * @see yy_switch_to_buffer
- */
-void yyset_in (FILE * in_str )
-{
- yyin = in_str ;
-}
-
-void yyset_out (FILE * out_str )
-{
- yyout = out_str ;
-}
-
-int yyget_debug (void)
-{
- return yy_flex_debug;
-}
-
-void yyset_debug (int bdebug )
-{
- yy_flex_debug = bdebug ;
-}
-
-static int yy_init_globals (void)
-{
- /* Initialization is the same as for the non-reentrant scanner.
- * This function is called from yylex_destroy(), so don't allocate here.
- */
-
- (yy_buffer_stack) = 0;
- (yy_buffer_stack_top) = 0;
- (yy_buffer_stack_max) = 0;
- (yy_c_buf_p) = (char *) 0;
- (yy_init) = 0;
- (yy_start) = 0;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
- yyin = stdin;
- yyout = stdout;
-#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
-#endif
-
- /* For future reference: Set errno on error, since we are called by
- * yylex_init()
- */
- return 0;
-}
-
-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
-int yylex_destroy (void)
-{
-
- /* Pop the buffer stack, destroying each element. */
- while(YY_CURRENT_BUFFER){
- yy_delete_buffer(YY_CURRENT_BUFFER );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- yypop_buffer_state();
- }
-
- /* Destroy the stack itself. */
- yyfree((yy_buffer_stack) );
- (yy_buffer_stack) = NULL;
-
- /* Reset the globals. This is important in a non-reentrant scanner so the next time
- * yylex() is called, initialization will occur. */
- yy_init_globals( );
-
- return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
-{
- register int i;
- for ( i = 0; i < n; ++i )
- s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
-{
- register int n;
- for ( n = 0; s[n]; ++n )
- ;
-
- return n;
-}
-#endif
-
-void *yyalloc (yy_size_t size )
-{
- return (void *) malloc( size );
-}
-
-void *yyrealloc (void * ptr, yy_size_t size )
-{
- /* The cast to (char *) in the following accommodates both
- * implementations that use char* generic pointers, and those
- * that use void* generic pointers. It works with the latter
- * because both ANSI C and C++ allow castless assignment from
- * any pointer type to void*, and deal with argument conversions
- * as though doing an assignment.
- */
- return (void *) realloc( (char *) ptr, size );
-}
-
-void yyfree (void * ptr )
-{
- free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 21 "parse_l.l"
-
-
-
diff --git a/Linux-PAM/doc/specs/parse_l.l b/Linux-PAM/doc/specs/parse_l.l
deleted file mode 100644
index 7cab424c..00000000
--- a/Linux-PAM/doc/specs/parse_l.l
+++ /dev/null
@@ -1,21 +0,0 @@
-%{
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-
-#include "parse_y.h"
-%}
-
-%%
-
-\#[\$]+[a-zA-Z]*(\=[0-9]+)? return NEW_COUNTER;
-\#\{[a-zA-Z][a-zA-Z0-9\_]*\} return LABEL;
-\# return NO_INDENT;
-\#\# return RIGHT;
-\\\# return HASH;
-[^\n] return CHAR;
-[\n] return NEWLINE;
-
-%%
diff --git a/Linux-PAM/doc/specs/parse_y.c b/Linux-PAM/doc/specs/parse_y.c
deleted file mode 100644
index 63c28701..00000000
--- a/Linux-PAM/doc/specs/parse_y.c
+++ /dev/null
@@ -1,1870 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.3. */
-
-/* Skeleton implementation for Bison's Yacc-like parsers in C
-
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* As a special exception, you may create a larger work that contains
- part or all of the Bison parser skeleton and distribute that work
- under terms of your choice, so long as that work isn't itself a
- parser generator using the skeleton or a modified version thereof
- as a parser skeleton. Alternatively, if you modify or redistribute
- the parser skeleton itself, you may (at your option) remove this
- special exception, which will cause the skeleton and the resulting
- Bison output files to be licensed under the GNU General Public
- License without this special exception.
-
- This special exception was added by the Free Software Foundation in
- version 2.2 of Bison. */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
- simplifying the original so-called "semantic" parser. */
-
-/* All symbols defined below should begin with yy or YY, to avoid
- infringing on user name space. This should be done even for local
- variables, as they might otherwise be expanded by user macros.
- There are some unavoidable exceptions within include files to
- define necessary library symbols; they are noted "INFRINGES ON
- USER NAME SPACE" below. */
-
-/* Identify Bison output. */
-#define YYBISON 1
-
-/* Bison version. */
-#define YYBISON_VERSION "2.3"
-
-/* Skeleton name. */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers. */
-#define YYPURE 0
-
-/* Using locations. */
-#define YYLSP_NEEDED 0
-
-
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- NEW_COUNTER = 258,
- LABEL = 259,
- HASH = 260,
- CHAR = 261,
- NEWLINE = 262,
- NO_INDENT = 263,
- RIGHT = 264
- };
-#endif
-/* Tokens. */
-#define NEW_COUNTER 258
-#define LABEL 259
-#define HASH 260
-#define CHAR 261
-#define NEWLINE 262
-#define NO_INDENT 263
-#define RIGHT 264
-
-
-
-
-/* Copy the first part of user declarations. */
-#line 2 "parse_y.y"
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define MAXLINE 1000
-#define INDENT_STRING " "
-#define PAPER_WIDTH 74
-
- int indent=0;
- int line=1;
- char *last_label=NULL;
-
- extern int yylex(void);
- extern char *yytext;
- extern void yyerror(const char *x);
- extern char *get_label(const char *label);
- extern void set_label(const char *label, const char *target);
- char *new_counter(const char *key);
-
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 27 "parse_y.y"
-{
- int def;
- char *string;
-}
-/* Line 187 of yacc.c. */
-#line 144 "parse_y.c"
- YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-
-
-/* Copy the second part of user declarations. */
-
-
-/* Line 216 of yacc.c. */
-#line 157 "parse_y.c"
-
-#ifdef short
-# undef short
-#endif
-
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
-#endif
-
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
-#else
-typedef short int yytype_int8;
-#endif
-
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
-#else
-typedef unsigned short int yytype_uint16;
-#endif
-
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-# define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-# define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# else
-# define YYSIZE_T unsigned int
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-
-#ifndef YY_
-# if YYENABLE_NLS
-# if ENABLE_NLS
-# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_(msgid) dgettext ("bison-runtime", msgid)
-# endif
-# endif
-# ifndef YY_
-# define YY_(msgid) msgid
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E. */
-#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
-#else
-# define YYUSE(e) /* empty */
-#endif
-
-/* Identity function, used to suppress warnings about constant conditions. */
-#ifndef lint
-# define YYID(n) (n)
-#else
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int i)
-#else
-static int
-YYID (i)
- int i;
-#endif
-{
- return i;
-}
-#endif
-
-#if ! defined yyoverflow || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols. */
-
-# ifdef YYSTACK_USE_ALLOCA
-# if YYSTACK_USE_ALLOCA
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# elif defined __BUILTIN_VA_ARG_INCR
-# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-# elif defined _AIX
-# define YYSTACK_ALLOC __alloca
-# elif defined _MSC_VER
-# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-# define alloca _alloca
-# else
-# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
-# endif
-# endif
-# endif
-# endif
-# endif
-
-# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
-# ifndef YYSTACK_ALLOC_MAXIMUM
- /* The OS might guarantee only one guard page at the bottom of the stack,
- and a page size can be as small as 4096 bytes. So we cannot safely
- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
- to allow for a few compiler-allocated temporary stack slots. */
-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-# endif
-# else
-# define YYSTACK_ALLOC YYMALLOC
-# define YYSTACK_FREE YYFREE
-# ifndef YYSTACK_ALLOC_MAXIMUM
-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-# endif
-# if (defined __cplusplus && ! defined _STDLIB_H \
- && ! ((defined YYMALLOC || defined malloc) \
- && (defined YYFREE || defined free)))
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
-# endif
-# endif
-# ifndef YYMALLOC
-# define YYMALLOC malloc
-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# ifndef YYFREE
-# define YYFREE free
-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
-
-#if (! defined yyoverflow \
- && (! defined __cplusplus \
- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member. */
-union yyalloc
-{
- yytype_int16 yyss;
- YYSTYPE yyvs;
- };
-
-/* The size of the maximum gap between one aligned stack and the next. */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
- N elements. */
-# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
- + YYSTACK_GAP_MAXIMUM)
-
-/* Copy COUNT objects from FROM to TO. The source and destination do
- not overlap. */
-# ifndef YYCOPY
-# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (YYID (0))
-# endif
-# endif
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack, Stack, yysize); \
- Stack = &yyptr->Stack; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (YYID (0))
-
-#endif
-
-/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 2
-/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 27
-
-/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 10
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 4
-/* YYNRULES -- Number of rules. */
-#define YYNRULES 15
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 19
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
-#define YYUNDEFTOK 2
-#define YYMAXUTOK 264
-
-#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const yytype_uint8 yytranslate[] =
-{
- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
- 5, 6, 7, 8, 9
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
- YYRHS. */
-static const yytype_uint8 yyprhs[] =
-{
- 0, 0, 3, 4, 7, 11, 17, 25, 33, 34,
- 37, 39, 42, 44, 46, 48
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yytype_int8 yyrhs[] =
-{
- 11, 0, -1, -1, 11, 7, -1, 11, 12, 7,
- -1, 11, 12, 9, 12, 7, -1, 11, 12, 9,
- 12, 9, 12, 7, -1, 11, 12, 9, 12, 9,
- 12, 7, -1, -1, 12, 13, -1, 6, -1, 13,
- 6, -1, 8, -1, 5, -1, 4, -1, 3, -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const yytype_uint8 yyrline[] =
-{
- 0, 39, 39, 40, 44, 53, 72, 99, 128, 131,
- 139, 142, 147, 151, 154, 160
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
-static const char *const yytname[] =
-{
- "$end", "error", "$undefined", "NEW_COUNTER", "LABEL", "HASH", "CHAR",
- "NEWLINE", "NO_INDENT", "RIGHT", "$accept", "doc", "stuff", "text", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
- token YYLEX-NUM. */
-static const yytype_uint16 yytoknum[] =
-{
- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const yytype_uint8 yyr1[] =
-{
- 0, 10, 11, 11, 11, 11, 11, 11, 12, 12,
- 13, 13, 13, 13, 13, 13
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const yytype_uint8 yyr2[] =
-{
- 0, 2, 0, 2, 3, 5, 7, 7, 0, 2,
- 1, 2, 1, 1, 1, 1
-};
-
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
- STATE-NUM when YYTABLE doesn't specify something else to do. Zero
- means the default is an error. */
-static const yytype_uint8 yydefact[] =
-{
- 2, 8, 1, 3, 0, 15, 14, 13, 10, 4,
- 12, 8, 9, 0, 11, 5, 8, 0, 6
-};
-
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yytype_int8 yydefgoto[] =
-{
- -1, 1, 4, 12
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
-#define YYPACT_NINF -3
-static const yytype_int8 yypact[] =
-{
- -3, 0, -3, -3, 5, -3, -3, -3, -3, -3,
- -3, -3, 17, 12, -3, -3, -3, -2, -3
-};
-
-/* YYPGOTO[NTERM-NUM]. */
-static const yytype_int8 yypgoto[] =
-{
- -3, -3, 11, -3
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule which
- number is the opposite. If zero, do what YYDEFACT says.
- If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -1
-static const yytype_uint8 yytable[] =
-{
- 2, 5, 6, 7, 8, 18, 10, 3, 5, 6,
- 7, 8, 9, 10, 11, 5, 6, 7, 8, 15,
- 10, 16, 13, 14, 0, 0, 0, 17
-};
-
-static const yytype_int8 yycheck[] =
-{
- 0, 3, 4, 5, 6, 7, 8, 7, 3, 4,
- 5, 6, 7, 8, 9, 3, 4, 5, 6, 7,
- 8, 9, 11, 6, -1, -1, -1, 16
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
-static const yytype_uint8 yystos[] =
-{
- 0, 11, 0, 7, 12, 3, 4, 5, 6, 7,
- 8, 9, 13, 12, 6, 7, 9, 12, 7
-};
-
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY (-2)
-#define YYEOF 0
-
-#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrorlab
-
-
-/* Like YYERROR except do call yyerror. This remains here temporarily
- to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. */
-
-#define YYFAIL goto yyerrlab
-
-#define YYRECOVERING() (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- yytoken = YYTRANSLATE (yychar); \
- YYPOPSTACK (1); \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (YYID (0))
-
-
-#define YYTERROR 1
-#define YYERRCODE 256
-
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
- If N is 0, then set CURRENT to the empty location which ends
- the previous symbol: RHS[0] (always defined). */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (YYID (N)) \
- { \
- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
- } \
- else \
- { \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC (Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC (Rhs, 0).last_column; \
- } \
- while (YYID (0))
-#endif
-
-
-/* YY_LOCATION_PRINT -- Print the location on the stream.
- This macro was not mandated originally: define only if we know
- we won't break user code: when these are the locations we know. */
-
-#ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-# define YY_LOCATION_PRINT(File, Loc) \
- fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
-# else
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
-#endif
-
-
-/* YYLEX -- calling `yylex' with the right arguments. */
-
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (YYLEX_PARAM)
-#else
-# define YYLEX yylex ()
-#endif
-
-/* Enable debugging if requested. */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-# define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args) \
-do { \
- if (yydebug) \
- YYFPRINTF Args; \
-} while (YYID (0))
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yy_symbol_print (stderr, \
- Type, Value); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (YYID (0))
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE const * const yyvaluep;
-#endif
-{
- if (!yyvaluep)
- return;
-# ifdef YYPRINT
- if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
- YYUSE (yyoutput);
-# endif
- switch (yytype)
- {
- default:
- break;
- }
-}
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE const * const yyvaluep;
-#endif
-{
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
- else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
- yy_symbol_value_print (yyoutput, yytype, yyvaluep);
- YYFPRINTF (yyoutput, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included). |
-`------------------------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
-#else
-static void
-yy_stack_print (bottom, top)
- yytype_int16 *bottom;
- yytype_int16 *top;
-#endif
-{
- YYFPRINTF (stderr, "Stack now");
- for (; bottom <= top; ++bottom)
- YYFPRINTF (stderr, " %d", *bottom);
- YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top) \
-do { \
- if (yydebug) \
- yy_stack_print ((Bottom), (Top)); \
-} while (YYID (0))
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced. |
-`------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
-#else
-static void
-yy_reduce_print (yyvsp, yyrule)
- YYSTYPE *yyvsp;
- int yyrule;
-#endif
-{
- int yynrhs = yyr2[yyrule];
- int yyi;
- unsigned long int yylno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
- yyrule - 1, yylno);
- /* The symbols being reduced. */
- for (yyi = 0; yyi < yynrhs; yyi++)
- {
- fprintf (stderr, " $%d = ", yyi + 1);
- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
- &(yyvsp[(yyi + 1) - (yynrhs)])
- );
- fprintf (stderr, "\n");
- }
-}
-
-# define YY_REDUCE_PRINT(Rule) \
-do { \
- if (yydebug) \
- yy_reduce_print (yyvsp, Rule); \
-} while (YYID (0))
-
-/* Nonzero means print parse trace. It is left uninitialized so that
- multiple parsers can coexist. */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks. */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
- if the built-in stack extension method is used).
-
- Do not make this value too large; the results are undefined if
- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
- evaluated with infinite-precision integer arithmetic. */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-# if defined __GLIBC__ && defined _STRING_H
-# define yystrlen strlen
-# else
-/* Return the length of YYSTR. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static YYSIZE_T
-yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
- const char *yystr;
-#endif
-{
- YYSIZE_T yylen;
- for (yylen = 0; yystr[yylen]; yylen++)
- continue;
- return yylen;
-}
-# endif
-# endif
-
-# ifndef yystpcpy
-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-# define yystpcpy stpcpy
-# else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
- YYDEST. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-#endif
-{
- char *yyd = yydest;
- const char *yys = yysrc;
-
- while ((*yyd++ = *yys++) != '\0')
- continue;
-
- return yyd - 1;
-}
-# endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
- quotes and backslashes, so that it's suitable for yyerror. The
- heuristic is that double-quoting is unnecessary unless the string
- contains an apostrophe, a comma, or backslash (other than
- backslash-backslash). YYSTR is taken from yytname. If YYRES is
- null, do not copy; instead, return the length of what the result
- would have been. */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
- if (*yystr == '"')
- {
- YYSIZE_T yyn = 0;
- char const *yyp = yystr;
-
- for (;;)
- switch (*++yyp)
- {
- case '\'':
- case ',':
- goto do_not_strip_quotes;
-
- case '\\':
- if (*++yyp != '\\')
- goto do_not_strip_quotes;
- /* Fall through. */
- default:
- if (yyres)
- yyres[yyn] = *yyp;
- yyn++;
- break;
-
- case '"':
- if (yyres)
- yyres[yyn] = '\0';
- return yyn;
- }
- do_not_strip_quotes: ;
- }
-
- if (! yyres)
- return yystrlen (yystr);
-
- return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-
-/* Copy into YYRESULT an error message about the unexpected token
- YYCHAR while in state YYSTATE. Return the number of bytes copied,
- including the terminating null byte. If YYRESULT is null, do not
- copy anything; just return the number of bytes that would be
- copied. As a special case, return 0 if an ordinary "syntax error"
- message will do. Return YYSIZE_MAXIMUM if overflow occurs during
- size calculation. */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
- int yyn = yypact[yystate];
-
- if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
- return 0;
- else
- {
- int yytype = YYTRANSLATE (yychar);
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- int yysize_overflow = 0;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- int yyx;
-
-# if 0
- /* This is so xgettext sees the translatable formats that are
- constructed on the fly. */
- YY_("syntax error, unexpected %s");
- YY_("syntax error, unexpected %s, expecting %s");
- YY_("syntax error, unexpected %s, expecting %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
- char *yyfmt;
- char const *yyf;
- static char const yyunexpected[] = "syntax error, unexpected %s";
- static char const yyexpecting[] = ", expecting %s";
- static char const yyor[] = " or %s";
- char yyformat[sizeof yyunexpected
- + sizeof yyexpecting - 1
- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
- * (sizeof yyor - 1))];
- char const *yyprefix = yyexpecting;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 1;
-
- yyarg[0] = yytname[yytype];
- yyfmt = yystpcpy (yyformat, yyunexpected);
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- yyformat[sizeof yyunexpected - 1] = '\0';
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
- yyfmt = yystpcpy (yyfmt, yyprefix);
- yyprefix = yyor;
- }
-
- yyf = YY_(yyformat);
- yysize1 = yysize + yystrlen (yyf);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
-
- if (yysize_overflow)
- return YYSIZE_MAXIMUM;
-
- if (yyresult)
- {
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- char *yyp = yyresult;
- int yyi = 0;
- while ((*yyp = *yyf) != '\0')
- {
- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyf += 2;
- }
- else
- {
- yyp++;
- yyf++;
- }
- }
- }
- return yysize;
- }
-}
-#endif /* YYERROR_VERBOSE */
-
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol. |
-`-----------------------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep)
- const char *yymsg;
- int yytype;
- YYSTYPE *yyvaluep;
-#endif
-{
- YYUSE (yyvaluep);
-
- if (!yymsg)
- yymsg = "Deleting";
- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
- switch (yytype)
- {
-
- default:
- break;
- }
-}
-
-
-/* Prevent warnings from -Wmissing-prototypes. */
-
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
-
-/* The look-ahead symbol. */
-int yychar;
-
-/* The semantic value of the look-ahead symbol. */
-YYSTYPE yylval;
-
-/* Number of syntax errors so far. */
-int yynerrs;
-
-
-
-/*----------.
-| yyparse. |
-`----------*/
-
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void)
-#else
-int
-yyparse ()
-
-#endif
-#endif
-{
-
- int yystate;
- int yyn;
- int yyresult;
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
- /* Look-ahead token as an internal (translated) token number. */
- int yytoken = 0;
-#if YYERROR_VERBOSE
- /* Buffer for error messages, and its allocated size. */
- char yymsgbuf[128];
- char *yymsg = yymsgbuf;
- YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
- /* Three stacks and their tools:
- `yyss': related to states,
- `yyvs': related to semantic values,
- `yyls': related to locations.
-
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* The state stack. */
- yytype_int16 yyssa[YYINITDEPTH];
- yytype_int16 *yyss = yyssa;
- yytype_int16 *yyssp;
-
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs = yyvsa;
- YYSTYPE *yyvsp;
-
-
-
-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
-
- YYSIZE_T yystacksize = YYINITDEPTH;
-
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
-
-
- /* The number of symbols on the RHS of the reduced rule.
- Keep to zero when no symbol should be popped. */
- int yylen = 0;
-
- YYDPRINTF ((stderr, "Starting parse\n"));
-
- yystate = 0;
- yyerrstatus = 0;
- yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
-
- yyssp = yyss;
- yyvsp = yyvs;
-
- goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
-`------------------------------------------------------------*/
- yynewstate:
- /* In all cases, when you get here, the value and location stacks
- have just been pushed. So pushing a state here evens the stacks. */
- yyssp++;
-
- yysetstate:
- *yyssp = yystate;
-
- if (yyss + yystacksize - 1 <= yyssp)
- {
- /* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
- {
- /* Give user a chance to reallocate the stack. Use copies of
- these so that the &'s don't force the real ones into
- memory. */
- YYSTYPE *yyvs1 = yyvs;
- yytype_int16 *yyss1 = yyss;
-
-
- /* Each stack pointer address is followed by the size of the
- data in use in that stack, in bytes. This used to be a
- conditional around just the two extra args, but that might
- be undefined if yyoverflow is a macro. */
- yyoverflow (YY_("memory exhausted"),
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
-
- &yystacksize);
-
- yyss = yyss1;
- yyvs = yyvs1;
- }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyexhaustedlab;
-# else
- /* Extend the stack our own way. */
- if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
- yystacksize *= 2;
- if (YYMAXDEPTH < yystacksize)
- yystacksize = YYMAXDEPTH;
-
- {
- yytype_int16 *yyss1 = yyss;
- union yyalloc *yyptr =
- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
- if (! yyptr)
- goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss);
- YYSTACK_RELOCATE (yyvs);
-
-# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
- YYSTACK_FREE (yyss1);
- }
-# endif
-#endif /* no yyoverflow */
-
- yyssp = yyss + yysize - 1;
- yyvsp = yyvs + yysize - 1;
-
-
- YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
-
- if (yyss + yystacksize - 1 <= yyssp)
- YYABORT;
- }
-
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
- goto yybackup;
-
-/*-----------.
-| yybackup. |
-`-----------*/
-yybackup:
-
- /* Do appropriate processing given the current state. Read a
- look-ahead token if we need one and don't already have one. */
-
- /* First try to decide what to do without reference to look-ahead token. */
- yyn = yypact[yystate];
- if (yyn == YYPACT_NINF)
- goto yydefault;
-
- /* Not known => get a look-ahead token if don't already have one. */
-
- /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
- if (yychar == YYEMPTY)
- {
- YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
- }
-
- if (yychar <= YYEOF)
- {
- yychar = yytoken = YYEOF;
- YYDPRINTF ((stderr, "Now at end of input.\n"));
- }
- else
- {
- yytoken = YYTRANSLATE (yychar);
- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
- }
-
- /* If the proper action on seeing token YYTOKEN is to reduce or to
- detect an error, take that action. */
- yyn += yytoken;
- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
- goto yydefault;
- yyn = yytable[yyn];
- if (yyn <= 0)
- {
- if (yyn == 0 || yyn == YYTABLE_NINF)
- goto yyerrlab;
- yyn = -yyn;
- goto yyreduce;
- }
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- /* Shift the look-ahead token. */
- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
- /* Discard the shifted token unless it is eof. */
- if (yychar != YYEOF)
- yychar = YYEMPTY;
-
- yystate = yyn;
- *++yyvsp = yylval;
-
- goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state. |
-`-----------------------------------------------------------*/
-yydefault:
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyerrlab;
- goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction. |
-`-----------------------------*/
-yyreduce:
- /* yyn is the number of a rule to reduce with. */
- yylen = yyr2[yyn];
-
- /* If YYLEN is nonzero, implement the default value of the action:
- `$$ = $1'.
-
- Otherwise, the following line sets YYVAL to garbage.
- This behavior is undocumented and Bison
- users should not rely upon it. Assigning to YYVAL
- unconditionally makes the parser a bit smaller, and it avoids a
- GCC warning that YYVAL may be used uninitialized. */
- yyval = yyvsp[1-yylen];
-
-
- YY_REDUCE_PRINT (yyn);
- switch (yyn)
- {
- case 3:
-#line 40 "parse_y.y"
- {
- printf("\n");
- ++line;
-}
- break;
-
- case 4:
-#line 44 "parse_y.y"
- {
- if (strlen((yyvsp[(2) - (3)].string)) > (PAPER_WIDTH-(indent ? strlen(INDENT_STRING):0))) {
- yyerror("line too long");
- }
- printf("%s%s\n", indent ? INDENT_STRING:"", (yyvsp[(2) - (3)].string));
- free((yyvsp[(2) - (3)].string));
- indent = 1;
- ++line;
-}
- break;
-
- case 5:
-#line 53 "parse_y.y"
- {
- char fixed[PAPER_WIDTH+1];
- int len;
-
- len = PAPER_WIDTH-(strlen((yyvsp[(2) - (5)].string))+strlen((yyvsp[(4) - (5)].string)));
-
- if (len >= 0) {
- memset(fixed, ' ', len);
- fixed[len] = '\0';
- } else {
- yyerror("line too wide");
- fixed[0] = '\0';
- }
- printf("%s%s%s\n", (yyvsp[(2) - (5)].string), fixed, (yyvsp[(4) - (5)].string));
- free((yyvsp[(2) - (5)].string));
- free((yyvsp[(4) - (5)].string));
- indent = 1;
- ++line;
-}
- break;
-
- case 6:
-#line 72 "parse_y.y"
- {
- char fixed[PAPER_WIDTH+1];
- int len, l;
-
- len = PAPER_WIDTH-(strlen((yyvsp[(2) - (7)].string))+strlen((yyvsp[(4) - (7)].string)));
-
- if (len < 0) {
- len = 0;
- yyerror("line too wide");
- }
-
- l = len/2;
- memset(fixed, ' ', l);
- fixed[l] = '\0';
- printf("%s%s%s", (yyvsp[(2) - (7)].string), fixed, (yyvsp[(4) - (7)].string));
- free((yyvsp[(2) - (7)].string));
- free((yyvsp[(4) - (7)].string));
-
- l = (len+1)/2;
- memset(fixed, ' ', l);
- fixed[l] = '\0';
- printf("%s%s\n", fixed, (yyvsp[(6) - (7)].string));
- free((yyvsp[(6) - (7)].string));
-
- indent = 1;
- ++line;
-}
- break;
-
- case 7:
-#line 99 "parse_y.y"
- {
- char fixed[PAPER_WIDTH+1];
- int len, l;
-
- len = PAPER_WIDTH-(strlen((yyvsp[(2) - (7)].string))+strlen((yyvsp[(4) - (7)].string)));
-
- if (len < 0) {
- len = 0;
- yyerror("line too wide");
- }
-
- l = len/2;
- memset(fixed, ' ', l);
- fixed[l] = '\0';
- printf("%s%s%s", (yyvsp[(2) - (7)].string), fixed, (yyvsp[(4) - (7)].string));
- free((yyvsp[(2) - (7)].string));
- free((yyvsp[(4) - (7)].string));
-
- l = (len+1)/2;
- memset(fixed, ' ', l);
- fixed[l] = '\0';
- printf("%s%s\n", fixed, (yyvsp[(6) - (7)].string));
- free((yyvsp[(6) - (7)].string));
-
- indent = 1;
- ++line;
-}
- break;
-
- case 8:
-#line 128 "parse_y.y"
- {
- (yyval.string) = strdup("");
-}
- break;
-
- case 9:
-#line 131 "parse_y.y"
- {
- (yyval.string) = malloc(strlen((yyvsp[(1) - (2)].string))+strlen((yyvsp[(2) - (2)].string))+1);
- sprintf((yyval.string),"%s%s", (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].string));
- free((yyvsp[(1) - (2)].string));
- free((yyvsp[(2) - (2)].string));
-}
- break;
-
- case 10:
-#line 139 "parse_y.y"
- {
- (yyval.string) = strdup(yytext);
-}
- break;
-
- case 11:
-#line 142 "parse_y.y"
- {
- (yyval.string) = malloc(strlen((yyvsp[(1) - (2)].string))+2);
- sprintf((yyval.string),"%s%s", (yyvsp[(1) - (2)].string), yytext);
- free((yyvsp[(1) - (2)].string));
-}
- break;
-
- case 12:
-#line 147 "parse_y.y"
- {
- (yyval.string) = strdup("");
- indent = 0;
-}
- break;
-
- case 13:
-#line 151 "parse_y.y"
- {
- (yyval.string) = strdup("#");
-}
- break;
-
- case 14:
-#line 154 "parse_y.y"
- {
- if (((yyval.string) = get_label(yytext)) == NULL) {
- set_label(yytext, last_label);
- (yyval.string) = strdup("");
- }
-}
- break;
-
- case 15:
-#line 160 "parse_y.y"
- {
- (yyval.string) = new_counter(yytext);
-}
- break;
-
-
-/* Line 1267 of yacc.c. */
-#line 1523 "parse_y.c"
- default: break;
- }
- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
-
- *++yyvsp = yyval;
-
-
- /* Now `shift' the result of the reduction. Determine what state
- that goes to, based on the state we popped back to and the rule
- number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
-
- goto yynewstate;
-
-
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
- /* If not already recovering from an error, report this error. */
- if (!yyerrstatus)
- {
- ++yynerrs;
-#if ! YYERROR_VERBOSE
- yyerror (YY_("syntax error"));
-#else
- {
- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
- {
- YYSIZE_T yyalloc = 2 * yysize;
- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
- yyalloc = YYSTACK_ALLOC_MAXIMUM;
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yyalloc);
- if (yymsg)
- yymsg_alloc = yyalloc;
- else
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- }
- }
-
- if (0 < yysize && yysize <= yymsg_alloc)
- {
- (void) yysyntax_error (yymsg, yystate, yychar);
- yyerror (yymsg);
- }
- else
- {
- yyerror (YY_("syntax error"));
- if (yysize != 0)
- goto yyexhaustedlab;
- }
- }
-#endif
- }
-
-
-
- if (yyerrstatus == 3)
- {
- /* If just tried and failed to reuse look-ahead token after an
- error, discard it. */
-
- if (yychar <= YYEOF)
- {
- /* Return failure if at end of input. */
- if (yychar == YYEOF)
- YYABORT;
- }
- else
- {
- yydestruct ("Error: discarding",
- yytoken, &yylval);
- yychar = YYEMPTY;
- }
- }
-
- /* Else will try to reuse look-ahead token after shifting the error
- token. */
- goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR. |
-`---------------------------------------------------*/
-yyerrorlab:
-
- /* Pacify compilers like GCC when the user code never invokes
- YYERROR and the label yyerrorlab therefore never appears in user
- code. */
- if (/*CONSTCOND*/ 0)
- goto yyerrorlab;
-
- /* Do not reclaim the symbols of the rule which action triggered
- this YYERROR. */
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
- yystate = *yyssp;
- goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR. |
-`-------------------------------------------------------------*/
-yyerrlab1:
- yyerrstatus = 3; /* Each real token shifted decrements this. */
-
- for (;;)
- {
- yyn = yypact[yystate];
- if (yyn != YYPACT_NINF)
- {
- yyn += YYTERROR;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
- {
- yyn = yytable[yyn];
- if (0 < yyn)
- break;
- }
- }
-
- /* Pop the current state because it cannot handle the error token. */
- if (yyssp == yyss)
- YYABORT;
-
-
- yydestruct ("Error: popping",
- yystos[yystate], yyvsp);
- YYPOPSTACK (1);
- yystate = *yyssp;
- YY_STACK_PRINT (yyss, yyssp);
- }
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- *++yyvsp = yylval;
-
-
- /* Shift the error token. */
- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-
- yystate = yyn;
- goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here. |
-`-------------------------------------*/
-yyacceptlab:
- yyresult = 0;
- goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here. |
-`-----------------------------------*/
-yyabortlab:
- yyresult = 1;
- goto yyreturn;
-
-#ifndef yyoverflow
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here. |
-`-------------------------------------------------*/
-yyexhaustedlab:
- yyerror (YY_("memory exhausted"));
- yyresult = 2;
- /* Fall through. */
-#endif
-
-yyreturn:
- if (yychar != YYEOF && yychar != YYEMPTY)
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval);
- /* Do not reclaim the symbols of the rule which action triggered
- this YYABORT or YYACCEPT. */
- YYPOPSTACK (yylen);
- YY_STACK_PRINT (yyss, yyssp);
- while (yyssp != yyss)
- {
- yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp);
- YYPOPSTACK (1);
- }
-#ifndef yyoverflow
- if (yyss != yyssa)
- YYSTACK_FREE (yyss);
-#endif
-#if YYERROR_VERBOSE
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
-#endif
- /* Make sure YYID is used. */
- return YYID (yyresult);
-}
-
-
-#line 165 "parse_y.y"
-
-
-typedef struct node_s {
- struct node_s *left, *right;
- const char *key;
- char *value;
-} *node_t;
-
-node_t label_root = NULL;
-node_t counter_root = NULL;
-
-static const char *find_key(node_t root, const char *key)
-{
- while (root) {
- int cmp = strcmp(key, root->key);
-
- if (cmp > 0) {
- root = root->right;
- } else if (cmp) {
- root = root->left;
- } else {
- return root->value;
- }
- }
- return NULL;
-}
-
-static node_t set_key(node_t root, const char *key, const char *value)
-{
- if (root) {
- int cmp = strcmp(key, root->key);
- if (cmp > 0) {
- root->right = set_key(root->right, key, value);
- } else if (cmp) {
- root->left = set_key(root->left, key, value);
- } else {
- free(root->value);
- root->value = strdup(value);
- }
- } else {
- root = malloc(sizeof(struct node_s));
- root->right = root->left = NULL;
- root->key = strdup(key);
- root->value = strdup(value);
- }
- return root;
-}
-
-void yyerror(const char *x)
-{
- fprintf(stderr, "line %d: %s\n", line, x);
-}
-
-char *get_label(const char *label)
-{
- const char *found = find_key(label_root, label);
-
- if (found) {
- return strdup(found);
- }
- return NULL;
-}
-
-void set_label(const char *label, const char *target)
-{
- if (target == NULL) {
- yyerror("no hanging value for label");
- target = "<??>";
- }
- label_root = set_key(label_root, label, target);
-}
-
-char *new_counter(const char *key)
-{
- int i=0, j, ndollars = 0;
- const char *old;
- char *new;
-
- if (key[i++] != '#') {
- yyerror("bad index");
- return strdup("<???>");
- }
-
- while (key[i] == '$') {
- ++ndollars;
- ++i;
- }
-
- key += i;
- old = find_key(counter_root, key);
- new = malloc(20*ndollars);
-
- if (old) {
- for (j=0; ndollars > 1 && old[j]; ) {
- if (old[j++] == '.' && --ndollars <= 0) {
- break;
- }
- }
- if (j) {
- strncpy(new, old, j);
- }
- if (old[j]) {
- i = atoi(old+j);
- } else {
- new[j++] = '.';
- i = 0;
- }
- } else {
- j=0;
- while (--ndollars > 0) {
- new[j++] = '0';
- new[j++] = '.';
- }
- i = 0;
- }
- new[j] = '\0';
- sprintf(new+j, "%d", ++i);
-
- counter_root = set_key(counter_root, key, new);
-
- if (last_label) {
- free(last_label);
- }
- last_label = strdup(new);
-
- return new;
-}
-
-int
-main(void)
-{
- return yyparse();
-}
-
diff --git a/Linux-PAM/doc/specs/parse_y.h b/Linux-PAM/doc/specs/parse_y.h
deleted file mode 100644
index 570758d2..00000000
--- a/Linux-PAM/doc/specs/parse_y.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.3. */
-
-/* Skeleton interface for Bison's Yacc-like parsers in C
-
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* As a special exception, you may create a larger work that contains
- part or all of the Bison parser skeleton and distribute that work
- under terms of your choice, so long as that work isn't itself a
- parser generator using the skeleton or a modified version thereof
- as a parser skeleton. Alternatively, if you modify or redistribute
- the parser skeleton itself, you may (at your option) remove this
- special exception, which will cause the skeleton and the resulting
- Bison output files to be licensed under the GNU General Public
- License without this special exception.
-
- This special exception was added by the Free Software Foundation in
- version 2.2 of Bison. */
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- NEW_COUNTER = 258,
- LABEL = 259,
- HASH = 260,
- CHAR = 261,
- NEWLINE = 262,
- NO_INDENT = 263,
- RIGHT = 264
- };
-#endif
-/* Tokens. */
-#define NEW_COUNTER 258
-#define LABEL 259
-#define HASH 260
-#define CHAR 261
-#define NEWLINE 262
-#define NO_INDENT 263
-#define RIGHT 264
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 27 "parse_y.y"
-{
- int def;
- char *string;
-}
-/* Line 1489 of yacc.c. */
-#line 72 "parse_y.h"
- YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-extern YYSTYPE yylval;
-
diff --git a/Linux-PAM/doc/specs/parse_y.y b/Linux-PAM/doc/specs/parse_y.y
deleted file mode 100644
index 87fc54ea..00000000
--- a/Linux-PAM/doc/specs/parse_y.y
+++ /dev/null
@@ -1,297 +0,0 @@
-
-%{
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define MAXLINE 1000
-#define INDENT_STRING " "
-#define PAPER_WIDTH 74
-
- int indent=0;
- int line=1;
- char *last_label=NULL;
-
- extern int yylex(void);
- extern char *yytext;
- extern void yyerror(const char *x);
- extern char *get_label(const char *label);
- extern void set_label(const char *label, const char *target);
- char *new_counter(const char *key);
-%}
-
-%union {
- int def;
- char *string;
-}
-
-%token NEW_COUNTER LABEL HASH CHAR NEWLINE NO_INDENT RIGHT
-%type <string> stuff text
-
-%start doc
-
-%%
-
-doc:
-| doc NEWLINE {
- printf("\n");
- ++line;
-}
-| doc stuff NEWLINE {
- if (strlen($2) > (PAPER_WIDTH-(indent ? strlen(INDENT_STRING):0))) {
- yyerror("line too long");
- }
- printf("%s%s\n", indent ? INDENT_STRING:"", $2);
- free($2);
- indent = 1;
- ++line;
-}
-| doc stuff RIGHT stuff NEWLINE {
- char fixed[PAPER_WIDTH+1];
- int len;
-
- len = PAPER_WIDTH-(strlen($2)+strlen($4));
-
- if (len >= 0) {
- memset(fixed, ' ', len);
- fixed[len] = '\0';
- } else {
- yyerror("line too wide");
- fixed[0] = '\0';
- }
- printf("%s%s%s\n", $2, fixed, $4);
- free($2);
- free($4);
- indent = 1;
- ++line;
-}
-| doc stuff RIGHT stuff RIGHT stuff NEWLINE {
- char fixed[PAPER_WIDTH+1];
- int len, l;
-
- len = PAPER_WIDTH-(strlen($2)+strlen($4));
-
- if (len < 0) {
- len = 0;
- yyerror("line too wide");
- }
-
- l = len/2;
- memset(fixed, ' ', l);
- fixed[l] = '\0';
- printf("%s%s%s", $2, fixed, $4);
- free($2);
- free($4);
-
- l = (len+1)/2;
- memset(fixed, ' ', l);
- fixed[l] = '\0';
- printf("%s%s\n", fixed, $6);
- free($6);
-
- indent = 1;
- ++line;
-}
-| doc stuff RIGHT stuff RIGHT stuff NEWLINE {
- char fixed[PAPER_WIDTH+1];
- int len, l;
-
- len = PAPER_WIDTH-(strlen($2)+strlen($4));
-
- if (len < 0) {
- len = 0;
- yyerror("line too wide");
- }
-
- l = len/2;
- memset(fixed, ' ', l);
- fixed[l] = '\0';
- printf("%s%s%s", $2, fixed, $4);
- free($2);
- free($4);
-
- l = (len+1)/2;
- memset(fixed, ' ', l);
- fixed[l] = '\0';
- printf("%s%s\n", fixed, $6);
- free($6);
-
- indent = 1;
- ++line;
-}
-;
-
-stuff: {
- $$ = strdup("");
-}
-| stuff text {
- $$ = malloc(strlen($1)+strlen($2)+1);
- sprintf($$,"%s%s", $1, $2);
- free($1);
- free($2);
-}
-;
-
-text: CHAR {
- $$ = strdup(yytext);
-}
-| text CHAR {
- $$ = malloc(strlen($1)+2);
- sprintf($$,"%s%s", $1, yytext);
- free($1);
-}
-| NO_INDENT {
- $$ = strdup("");
- indent = 0;
-}
-| HASH {
- $$ = strdup("#");
-}
-| LABEL {
- if (($$ = get_label(yytext)) == NULL) {
- set_label(yytext, last_label);
- $$ = strdup("");
- }
-}
-| NEW_COUNTER {
- $$ = new_counter(yytext);
-}
-;
-
-%%
-
-typedef struct node_s {
- struct node_s *left, *right;
- const char *key;
- char *value;
-} *node_t;
-
-node_t label_root = NULL;
-node_t counter_root = NULL;
-
-static const char *find_key(node_t root, const char *key)
-{
- while (root) {
- int cmp = strcmp(key, root->key);
-
- if (cmp > 0) {
- root = root->right;
- } else if (cmp) {
- root = root->left;
- } else {
- return root->value;
- }
- }
- return NULL;
-}
-
-static node_t set_key(node_t root, const char *key, const char *value)
-{
- if (root) {
- int cmp = strcmp(key, root->key);
- if (cmp > 0) {
- root->right = set_key(root->right, key, value);
- } else if (cmp) {
- root->left = set_key(root->left, key, value);
- } else {
- free(root->value);
- root->value = strdup(value);
- }
- } else {
- root = malloc(sizeof(struct node_s));
- root->right = root->left = NULL;
- root->key = strdup(key);
- root->value = strdup(value);
- }
- return root;
-}
-
-void yyerror(const char *x)
-{
- fprintf(stderr, "line %d: %s\n", line, x);
-}
-
-char *get_label(const char *label)
-{
- const char *found = find_key(label_root, label);
-
- if (found) {
- return strdup(found);
- }
- return NULL;
-}
-
-void set_label(const char *label, const char *target)
-{
- if (target == NULL) {
- yyerror("no hanging value for label");
- target = "<??" ">"; /* avoid trigraph warning */
- }
- label_root = set_key(label_root, label, target);
-}
-
-char *new_counter(const char *key)
-{
- int i=0, j, ndollars = 0;
- const char *old;
- char *new;
-
- if (key[i++] != '#') {
- yyerror("bad index");
- return strdup("<???" ">"); /* avoid trigraph warning */
- }
-
- while (key[i] == '$') {
- ++ndollars;
- ++i;
- }
-
- key += i;
- old = find_key(counter_root, key);
- new = malloc(20*ndollars);
-
- if (old) {
- for (j=0; ndollars > 1 && old[j]; ) {
- if (old[j++] == '.' && --ndollars <= 0) {
- break;
- }
- }
- if (j) {
- strncpy(new, old, j);
- }
- if (old[j]) {
- i = atoi(old+j);
- } else {
- new[j++] = '.';
- i = 0;
- }
- } else {
- j=0;
- while (--ndollars > 0) {
- new[j++] = '0';
- new[j++] = '.';
- }
- i = 0;
- }
- new[j] = '\0';
- sprintf(new+j, "%d", ++i);
-
- counter_root = set_key(counter_root, key, new);
-
- if (last_label) {
- free(last_label);
- }
- last_label = strdup(new);
-
- return new;
-}
-
-int
-main(void)
-{
- return yyparse();
-}
diff --git a/Linux-PAM/doc/specs/rfc86.0.txt b/Linux-PAM/doc/specs/rfc86.0.txt
deleted file mode 100644
index 6dd5e6ea..00000000
--- a/Linux-PAM/doc/specs/rfc86.0.txt
+++ /dev/null
@@ -1,1851 +0,0 @@
-
-
-
-
-
-
-
-
- Open Software Foundation V. Samar (SunSoft)
- Request For Comments: 86.0 R. Schemers (SunSoft)
- October 1995
-
-
-
- UNIFIED LOGIN WITH
- PLUGGABLE AUTHENTICATION MODULES (PAM)
-
-
- 1. INTRODUCTION
-
- Since low-level authentication mechanisms constantly evolve, it is
- important to shield the high-level consumers of these mechanisms
- (system-entry services and users) from such low-level changes. With
- the Pluggable Authentication Module (PAM) framework, we can provide
- pluggability for a variety of system-entry services -- not just
- system authentication _per se_, but also for account, session and
- password management. PAM's ability to _stack_ authentication modules
- can be used to integrate `login' with different authentication
- mechanisms such as RSA, DCE, and Kerberos, and thus unify login
- mechanisms. The PAM framework can also provide easy integration of
- smart cards into the system.
-
- Modular design and pluggability have become important for users who
- want ease of use. In the PC hardware arena, no one wants to set the
- interrupt vector numbers or resolve the addressing conflict between
- various devices. In the software arena, people also want to be able
- to replace components easily for easy customization, maintenance, and
- upgrades.
-
- Authentication software deserves special attention because
- authentication forms a very critical component of any secure computer
- system. The authentication infrastructure and its components may
- have to be modified or replaced either because some deficiencies have
- been found in the current algorithms, or because sites want to
- enforce a different security policy than what was provided by the
- system vendor. The replacement and modification should be done in
- such a way that the user is not affected by these changes.
-
- The solution has to address not just how the applications use the new
- authentication mechanisms in a generic fashion, but also how the user
- will be authenticated to these mechanisms in a generic way. The
- former is addressed by GSS-API [Linn 93], while this RFC addresses
- the later; these two efforts are complementary to each other.
-
- Since most system-entry services (for example, `login', `dtlogin',
- `rlogin', `ftp', `rsh') may want to be independent of the specific
- authentication mechanisms used by the machine, it is important that
- there be a framework for _plugging_ in various mechanisms. This
- requires that the system applications use a standard API to interact
-
-
-
- Samar, Schemers Page 1
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- with the authentication services. If these system-entry services
- remain independent of the actual mechanism used on that machine, the
- system administrator can install suitable authentication modules
- without requiring changes to these applications.
-
- For any security system to be successful, it has to be easy to use.
- In the case of authentication, the single most important ease-of-use
- characteristic is that the user should not be required to learn about
- various ways of authentication and remember multiple passwords.
- Ideally, there should be one all-encompassing authentication system
- where there is only one password, but for heterogeneous sites,
- multiple authentication mechanisms have to co-exist. The problem of
- integrating multiple authentication mechanisms such as Kerberos
- [Steiner 88], RSA [Rivest 78], and Diffie-Hellman [Diffie 76, Taylor
- 88], is also referred to as _integrated login_, or _unified login_
- problem. Even if the user has to use multiple authentication
- mechanisms, the user should not be forced to type multiple passwords.
- Furthermore, the user should be able to use the new network identity
- without taking any further actions. The key here is in modular
- integration of the network authentication technologies with `login'
- and other system-entry services.
-
- In this RFC we discuss the architecture and design of pluggable
- authentication modules. This design gives the capability to use
- field-replaceable authentication modules along with unified login
- capability. It thus provides for both _pluggability_ and _ease-of-
- use_.
-
- The RFC is organized as follows. We first motivate the need for a
- generic way to authenticate the user by various system-entry services
- within the operating system. We describe the goals and constraints
- of the design. This leads to the architecture, description of the
- interfaces, and _stacking_ of modules to get unified login
- functionality. We then describe our experience with the design, and
- end with a description of future work.
-
-
- 2. OVERVIEW OF IDENTIFICATION AND AUTHENTICATION MECHANISMS
-
- An identification and authentication ("I&A") mechanism is used to
- establish a user's identity the system (i.e., to a local machine's
- operating system) and to other principals on the network. On a
- typical UNIX system, there are various ports of entry into the
- system, such as `login', `dtlogin', `rlogin', `ftp', `rsh', `su', and
- `telnet'. In all cases, the user has to be identified and
- authenticated before granting appropriate access rights to the user.
- The user identification and authentication for all these entry points
- needs to be coordinated to ensure a secure system.
-
- In most of the current UNIX systems, the login mechanism is based
- upon verification of the password using the modified DES algorithm.
-
-
-
- Samar, Schemers Page 2
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- The security of the implementation assumes that the password cannot
- be guessed, and that the password does not go over the wire in the
- clear. These assumptions, however, are not universally valid.
- Various programs are now available freely on the Internet that can
- run dictionary attack against the encrypted password. Further, some
- of the network services (for example, `rlogin', `ftp', `telnet') send
- the password over in clear, and there are "sniffer" programs freely
- available to steal these passwords. The classical assumptions may be
- acceptable on a trusted network, but in an open environment there is
- a need to use more restrictive and stronger authentication
- mechanisms. Examples of such mechanisms include Kerberos, RSA,
- Diffie-Hellman, one-time password [Skey 94], and challenge-response
- based smart card authentication systems. Since this list will
- continue to evolve, it is important that the system-entry services do
- not have hard-coded dependencies on any of these authentication
- mechanisms.
-
-
- 3. DESIGN GOALS
-
- The goals of the PAM framework are as follows:
-
- (a) The system administrator should be able to choose the default
- authentication mechanism for the machine. This can range from
- a simple password-based mechanism to a biometric or a smart
- card based system.
-
- (b) It should be possible to configure the user authentication
- mechanism on a per application basis. For example, a site may
- require S/Key password authentication for `telnet' access,
- while allowing machine `login' sessions with just UNIX password
- authentication.
-
- (c) The framework should support the display requirements of the
- applications. For example, for a graphical login session such
- as `dtlogin', the user name and the password may have to be
- entered in a new window. For networking system-entry
- applications such as `ftp' and `telnet', the user name and
- password has to be transmitted over the network to the client
- machine.
-
- (d) It should be possible to configure multiple authentication
- protocols for each of those applications. For example, one may
- want the users to get authenticated by both Kerberos and RSA
- authentication systems.
-
- (e) The system administrator should be able to _stack_ multiple
- user authentication mechanisms such that the user is
- authenticated with all authentication protocols without
- retyping the password.
-
-
-
-
- Samar, Schemers Page 3
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- (f) The architecture should allow for multiple passwords if
- necessary to achieve higher security for users with specific
- security requirements.
-
- (g) The system-entry services should not be required to change when
- the underlying mechanism changes. This can be very useful for
- third-party developers because they often do not have the
- source code for these services.
-
- (h) The architecture should provide for a _pluggable_ model for
- system authentication, as well as for other related tasks such
- as password, account, and session management.
-
- (i) For backward-compatibility reasons, the PAM API should support
- the authentication requirements of the current system-entry
- services.
-
- There are certain issues that the PAM framework does not specifically
- address:
-
- (a) We focus only on providing a generic scheme through which users
- use passwords to establish their identities to the machine.
- Once the identity is established, how the identity is
- communicated to other interested parties is outside the scope
- of this design. There are efforts underway at IETF [Linn 93]
- to develop a Generic Security Services Application Interface
- (GSSAPI) that can be used by applications for secure and
- authenticated communication without knowing the underlying
- mechanism.
-
- (b) The _single-signon_ problem of securely transferring the
- identity of the caller to a remote site is not addressed. For
- example, the problem of delegating credentials from the
- `rlogin' client to the other machine without typing the
- password is not addressed by our work. We also do not address
- the problem of sending the passwords over the network in the
- clear.
-
- (c) We do not address the source of information obtained from the
- "`getXbyY()'" family of calls (e.g., `getpwnam()'). Different
- operating systems address this problem differently. For
- example, Solaris uses the name service switch (NSS) to
- determine the source of information for the "`getXbyY()'"
- calls. It is expected that data which is stored in multiple
- sources (such as passwd entries in NIS+ and the DCE registry)
- is kept in sync using the appropriate commands (such as
- `passwd_export').
-
-
-
-
-
-
-
- Samar, Schemers Page 4
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- 4. OVERVIEW OF THE PAM FRAMEWORK
-
- We propose that the goals listed above can be met through a framework
- in which authentication modules can be _plugged_ independently of the
- application. We call this the _Pluggable Authentication Modules_
- (PAM) framework.
-
- The core components of the PAM framework are the authentication
- library API (the front end) and the authentication mechanism-specific
- modules (the back end), connected through the Service Provider
- Interface (SPI). Applications write to the PAM API, while the
- authentication-system providers write to the PAM SPI and supply the
- back end modules that are independent of the application.
-
- ftp telnet login (Applications)
- | | |
- | | |
- +--------+--------+
- |
- +-----+-----+
- | PAM API | <-- pam.conf file
- +-----+-----+
- |
- +--------+--------+
- UNIX Kerberos Smart Cards (Mechanisms)
-
- Figure 1: The Basic PAM Architecture
-
- Figure 1 illustrates the relationship between the application, the
- PAM library, and the authentication modules. Three applications
- (`login', `telnet' and `ftp') are shown which use the PAM
- authentication interfaces. When an application makes a call to the
- PAM API, it loads the appropriate authentication module as determined
- by the configuration file, `pam.conf'. The request is forwarded to
- the underlying authentication module (for example, UNIX password,
- Kerberos, smart cards) to perform the specified operation. The PAM
- layer then returns the response from the authentication module to the
- application.
-
- PAM unifies system authentication and access control for the system,
- and allows plugging of associated authentication modules through well
- defined interfaces. The plugging can be defined through various
- means, one of which uses a configuration file, such as the one in
- Table 1. For each of the system applications, the file specifies the
- authentication module that should be loaded. In the example below,
- `login' uses the UNIX password module, while `ftp' and `telnet' use
- the S/Key module.
-
-
-
-
-
-
-
- Samar, Schemers Page 5
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- Table 1: A Simplified View of a Sample PAM Configuration File.
-
- service module_path
- ------- -----------
- login pam_unix.so
- ftp pam_skey.so
- telnet pam_skey.so
-
- Authentication configuration is only one aspect of this interface.
- Other critical components include account management, session
- management, and password management. For example, the `login'
- program may want to verify not only the password but also whether the
- account has aged or expired. Generic interfaces also need to be
- provided so that the password can be changed according to the
- requirements of the module. Furthermore, the application may want to
- log information about the current session as determined by the
- module.
-
- Not all applications or services may need all of the above
- components, and not each authentication module may need to provide
- support for all of the interfaces. For example, while `login' may
- need access to all four components, `su' may need access to just the
- authentication component. Some applications may use some specific
- authentication and password management modules but share the account
- and session management modules with others.
-
- This reasoning leads to a partitioning of the entire set of
- interfaces into four areas of functionality: (1) authentication, (2)
- account, (3) session, and (4) password. The concept of PAM was
- extended to these functional areas by implementing each of them as a
- separate pluggable module.
-
- Breaking the functionality into four modules helps the module
- providers because they can use the system-provided libraries for the
- modules that they are not changing. For example, if a supplier wants
- to provide a better version of Kerberos, they can just provide that
- new authentication and password module, and reuse the existing ones
- for account and session.
-
- 4.1. Module Description
-
- More details on specific API's are described in Appendix A. A brief
- description of four modules follows:
-
- (a) Authentication management: This set includes the
- `pam_authenticate()' function to authenticate the user, and the
- `pam_setcred()' interface to set, refresh or destroy the user
- credentials.
-
- (b) Account management: This set includes the `pam_acct_mgmt()'
- function to check whether the authenticated user should be
-
-
-
- Samar, Schemers Page 6
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- given access to his/her account. This function can implement
- account expiration and access hour restrictions.
-
- (c) Session management: This set includes the `pam_open_session()'
- and `pam_close_session()' functions for session management and
- accounting. For example, the system may want to store the
- total time for the session.
-
- (d) Password management: This set includes a function,
- `pam_chauthtok()', to change the password.
-
-
- 5. FRAMEWORK INTERFACES
-
- The PAM framework further provides a set of administrative interfaces
- to support the above modules and to provide for application-module
- communication. There is no corresponding service provider interface
- (SPI) for such functions.
-
- 5.1. Administrative Interfaces
-
- Each set of PAM transactions starts with `pam_start()' and ends with
- the `pam_end()' function. The interfaces `pam_get_item()' and
- `pam_set_item()' are used to read and write the state information
- associated with the PAM transaction.
-
- If there is any error with any of the PAM interfaces, the error
- message can be printed with `pam_strerror()'.
-
- 5.2. Application-Module Communication
-
- During application initialization, certain data such as the user name
- is saved in the PAM framework layer through `pam_start()' so that it
- can be used by the underlying modules. The application can also pass
- opaque data to the module which the modules will pass back while
- communicating with the user.
-
- 5.3. User-Module Communication
-
- The `pam_start()' function also passes conversation function that has
- to be used by the underlying modules to read and write module
- specific authentication information. For example, these functions
- can be used to prompt the user for the password in a way determined
- by the application. PAM can thus be used by graphical, non-
- graphical, or networked applications.
-
-
-
-
-
-
-
-
-
- Samar, Schemers Page 7
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- 5.4. Inter-Module Communication
-
- Though the modules are independent, they can share certain common
- information about the authentication session such as user name,
- service name, password, and conversation function through the
- `pam_get_item()' and `pam_set_item()' interfaces. These API's can
- also be used by the application to change the state information after
- having called `pam_start()' once.
-
- 5.5. Module State Information
-
- The PAM service modules may want to keep certain module-specific
- state information about the session. The interfaces `pam_get_data()'
- and `pam_set_data()' can be used by the service modules to access and
- update module-specific information as needed from the PAM handle.
- The modules can also attach a cleanup function with the data. The
- cleanup function is executed when `pam_end()' is called to indicate
- the end of the current authentication activity.
-
- Since the PAM modules are loaded upon demand, there is no direct
- module initialization support in the PAM framework. If there are
- certain initialization tasks that the PAM service modules have to do,
- they should be done upon the first invocation. However, if there are
- certain clean-up tasks to be done when the authentication session
- ends, the modules should use `pam_set_data()' to specify the clean-up
- functions, which would be called when `pam_end()' is called by the
- application.
-
-
- 6. MODULE CONFIGURATION MANAGEMENT
-
- Table 2 shows an example of a configuration file `pam.conf' with
- support for authentication, session, account, and password management
- modules. `login' has three entries: one each for authentication
- processing, session management and account management. Each entry
- specifies the module name that should be loaded for the given module
- type. In this example, the `ftp' service uses the authentication and
- session modules. Note that all services here share the same session
- management module, while having different authentication modules.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Samar, Schemers Page 8
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- Table 2: Configuration File (pam.conf) with Different Modules
- and Control Flow
-
- service module_type control_flag module_path options
- ------- ----------- ------------ ----------- -------
- login auth required pam_unix_auth.so nowarn
- login session required pam_unix_session.so
- login account required pam_unix_account.so
- ftp auth required pam_skey_auth.so debug
- ftp session required pam_unix_session.so
- telnet session required pam_unix_session.so
- login password required pam_unix_passwd.so
- passwd password required pam_unix_passwd.so
- OTHER auth required pam_unix_auth.so
- OTHER session required pam_unix_session.so
- OTHER account required pam_unix_account.so
-
- The first field, _service_, denotes the service (for example,
- `login', `passwd', `rlogin'). The name `OTHER' indicates the module
- used by all other applications that have not been specified in this
- file. This name can also be used if all services have the same
- requirements. In the example, since all the services use the same
- session module, we could have replaced those lines with a single
- `OTHER' line.
-
- The second field, _module_type_, indicates the type of the PAM
- functional module. It can be one of `auth', `account', `session', or
- `password' modules.
-
- The third field, _control_flag_ determines the behavior of stacking
- multiple modules by specifying whether any particular module is
- _required_, _sufficient_, or _optional_. The next section describes
- stacking in more detail.
-
- The fourth field, _module_path_, specifies the location of the
- module. The PAM framework loads this module upon demand to invoke
- the required function.
-
- The fifth field, _options_, is used by the PAM framework layer to
- pass module specific options to the modules. It is up to the module
- to parse and interpret the options. This field can be used by the
- modules to turn on debugging or to pass any module specific
- parameters such as a timeout value. It is also used to support
- unified login as described below. The options field can be used by
- the system administrator to fine-tune the PAM modules.
-
- If any of the fields are invalid, or if a module is not found, that
- line is ignored and the error is logged as a critical error via
- `syslog(3)'. If no entries are found for the given module type, then
- the PAM framework returns an error to the application.
-
-
-
-
- Samar, Schemers Page 9
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- 7. INTEGRATING MULTIPLE AUTHENTICATION SERVICES WITH STACKING
-
- In the world of heterogeneous systems, the system administrator often
- has to deal with the problem of integrating multiple authentication
- mechanisms. The user is often required to know about the
- authentication command of the new authentication module (for example,
- `kinit', `dce_login') after logging into the system. This is not
- user-friendly because it forces people to remember to type the new
- command and enter the new password. This functionality should be
- invisible instead of burdening the user with it.
-
- There are two problems to be addressed here:
-
- (a) Supporting multiple authentication mechanisms.
-
- (b) Providing unified login in the presence of multiple mechanisms.
-
- In the previous section, we described how one could replace the
- default authentication module with any other module of choice. Now
- we demonstrate how the same model can be extended to provide support
- for multiple modules.
-
- 7.1. Design for Stacked Modules
-
- One possibility was to provide hard-coded rules in `login' or other
- applications requiring authentication services [Adamson 95]. But
- this becomes very specific to the particular combination of
- authentication protocols, and also requires the source code of the
- application. Digital's Security Integration Architecture [SIA 95]
- addresses this problem by specifying the same list of authentication
- modules for all applications. Since requirements for various
- applications can vary, it is essential that the configuration be on a
- per-application basis.
-
- To support multiple authentication mechanisms, the PAM framework was
- extended to support _stacking_. When any API is called, the back
- ends for the stacked modules are invoked in the order listed, and the
- result returned to the caller. In Figure 2, the authentication
- service of `login' is stacked and the user is authenticated by UNIX,
- Kerberos, and RSA authentication mechanisms. Note that in this
- example, there is no stacking for session or account management
- modules.
-
-
-
-
-
-
-
-
-
-
-
-
- Samar, Schemers Page 10
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- login
- |
- +--------+--------+
- | | |
- session auth account
- | | |
- +--+--+ +--+--+ +--+--+
- | PAM | | PAM | | PAM |
- +--+--+ +--+--+ +--+--+
- | | |
- UNIX UNIX UNIX
- session auth account
- |
- Kerberos
- auth
- |
- RSA
- auth
-
- Figure 2: Stacking With the PAM Architecture
-
- Stacking is specified through additional entries in the configuration
- file shown earlier. As shown in Table 2, for each application (such
- as `login') the configuration file can specify multiple mechanisms
- that have to be invoked in the specified order. When mechanisms
- fail, the _control_flag_ decides which error should be returned to
- the application. Since the user should not know which authentication
- module failed when a bad password was typed, the PAM framework
- continues to call other authentication modules on the stack even on
- failure. The semantics of the control flag are as follows:
-
- (a) `required': With this flag, the module failure results in the
- PAM framework returning the error to the caller _after_
- executing all other modules on the stack. For the function to
- be able to return success to the application all `required'
- modules have to report success. This flag is normally set when
- authentication by this module is a _must_.
-
- (b) `optional': With this flag, the PAM framework ignores the
- module failure and continues with the processing of the next
- module in sequence. This flag is used when the user is allowed
- to login even if that particular module has failed.
-
- (c) `sufficient': With this flag, if the module succeeds the PAM
- framework returns success to the application immediately
- without trying any other modules. For failure cases, the
- _sufficient_ modules are treated as `optional'.
-
- Table 3 shows a sample configuration file that stacks the `login'
- command. Here the user is authenticated by UNIX, Kerberos, and RSA
- authentication services. The `required' key word for _control_flag_
-
-
-
- Samar, Schemers Page 11
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- enforces that the user is allowed to login only if he/she is
- authenticated by _both_ UNIX and Kerberos services. RSA
- authentication is optional by virtue of the `optional' key word in
- the _control_flag_ field. The user can still log in even if RSA
- authentication fails.
-
- Table 3: PAM Configuration File with Support for Stacking
-
- service module_type control_flag module_path options
- ------- ----------- ------------ ----------- -------
- login auth required pam_unix.so debug
- login auth required pam_kerb.so use_mapped_pass
- login auth optional pam_rsa.so use_first_pass
-
- Table 4 illustrates the use of the sufficient flag for the `rlogin'
- service. The Berkeley `rlogin' protocol specifies that if the remote
- host is trusted (as specified in the `/etc/hosts.equiv' file or in
- the `.rhosts' file in the home directory of the user), then the
- `rlogin' daemon should not require the user to type the password. If
- this is not the case, then the user is required to type the password.
- Instead of hard coding this policy in the `rlogin' daemon, this can
- be expressed with the `pam.conf' file in Table 4. The PAM module
- `pam_rhosts_auth.so.1' implements the `.rhosts' policy described
- above. If a site administrator wants to enable remote login with
- only passwords, then the first line should be deleted.
-
- Table 4: PAM Configuration File for the rlogin service
-
- service module_type control_flag module_path options
- ------- ----------- ------------ ----------- -------
- rlogin auth sufficient pam_rhosts_auth.so
- rlogin auth required pam_unix.so
-
- 7.2. Password-Mapping
-
- Multiple authentication mechanisms on a machine can lead to multiple
- passwords that users have to remember. One attractive solution from
- the ease-of-use viewpoint is to use the same password for all
- mechanisms. This, however, can also weaken the security because if
- that password were to be compromised in any of the multiple
- mechanisms, all mechanisms would be compromised at the same time.
- Furthermore, different authentication mechanisms may have their own
- distinctive password requirements in regards to its length, allowed
- characters, time interval between updates, aging, locking, and so
- forth. These requirements make it problematic to use the same
- password for multiple authentication mechanisms.
-
- The solution we propose, while not precluding use of the same
- password for every mechanism, allows for a different password for
- each mechanism through what we call _password-mapping_. This
- basically means using the user's _primary_ password to encrypt the
-
-
-
- Samar, Schemers Page 12
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- user's other (_secondary_) passwords, and storing these encrypted
- passwords in a place where they are available to the user. Once the
- primary password is verified, the authentication modules would obtain
- the other passwords for their own mechanisms by decrypting the
- mechanism-specific encrypted password with the primary password, and
- passing it to the authentication service. The security of this
- design for password-mapping assumes that the primary password is the
- user's strongest password, in terms of its unguessability (length,
- type and mix of characters used, etc.).
-
- If there is any error in password-mapping, or if the mapping does not
- exist, the user will be prompted for the password by each
- authentication module.
-
- To support password-mapping, the PAM framework saves the primary
- password and provides it to stacked authentication modules. The
- password is cleared out before the `pam_authenticate' function
- returns.
-
- How the password is encrypted depends completely on the module
- implementation. The encrypted secondary password (also called a
- "mapped password") can be stored in a trusted or untrusted place,
- such as a smart card, a local file, or a directory service. If the
- encrypted passwords are stored in an untrusted publicly accessible
- place, this does provide an intruder with opportunities for potential
- dictionary attack.
-
- Though password-mapping is voluntary, it is recommended that all
- module providers add support for the following four mapping options:
-
- (a) `use_first_pass': Use the same password used by the first
- mechanism that asked for a password. The module should not ask
- for the password if the user cannot be authenticated by the
- first password. This option is normally used when the system
- administrator wants to enforce the same password across
- multiple modules.
-
- (b) `try_first_pass': This is the same as `use_first_pass', except
- that if the primary password is not valid, it should prompt the
- user for the password.
-
- (c) `use_mapped_pass': Use the password-mapping scheme to get the
- actual password for this module. One possible implementation
- is to get the mapped-password using the XFN API [XFN 94], and
- decrypt it with the primary password to get the module-specific
- password. The module should not ask for the password if the
- user cannot be authenticated by the first password. The XFN
- API allows user-defined attributes (such as _mapped-password_)
- to be stored in the _user-context_. Using the XFN API is
- particularly attractive because support for the XFN may be
- found on many systems in the future.
-
-
-
- Samar, Schemers Page 13
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- (d) `try_mapped_pass': This is the same as `use_mapped_pass',
- except that if the primary password is not valid, it should
- prompt the user for the password.
-
- When passwords get updated, the PAM framework stores both the old as
- well as the new password to be able to inform other dependent
- authentication modules about the change. Other modules can use this
- information to update the encrypted password without forcing the user
- to type the sequence of passwords again. The PAM framework clears
- out the passwords before returning to the application.
-
- Table 3 illustrates how the same password can be used by `login' for
- authenticating to the standard UNIX login, Kerberos and RSA services.
- Once the user has been authenticated to the primary authentication
- service (UNIX `login' in this example) with the primary password, the
- option `use_mapped_pass' indicates to the Kerberos module that it
- should use the primary password to decrypt the stored Kerberos
- password and then use the Kerberos password to get the ticket for the
- ticket-granting-service. After that succeeds, the option
- `use_first_pass' indicates to the RSA module that instead of
- prompting the user for a password, it should use the primary password
- typed earlier for authenticating the user. Note that in this
- scenario, the user has to enter the password just once.
-
- Note that if a one-time password scheme (e.g., S/Key) is used,
- password mapping cannot apply.
-
- 7.3. Implications of Stacking on the PAM Design
-
- Because of the stacking capability of PAM, we have designed the PAM
- API's to not return any data to the application, except status. If
- this were not the case, it would be difficult for the PAM framework
- to decide which module should return data to the application. When
- there is any error, the application does not know which of the
- modules failed. This behavior enables (even requires) the
- application to be completely independent from the modules.
-
- Another design decision we have made is that PAM gives only the user
- name to all the underlying PAM modules, hence it is the
- responsibility of the PAM modules to convert the name to their own
- internal format. For example, the Kerberos module may have to
- convert the UNIX user name to a Kerberos principal name.
-
- Stacking also forces the modules to be designed such that they can
- occur anywhere in the stack without any side-effects.
-
- Since modules such as the authentication and the password module are
- very closely related, it is important they be configured in the same
- order and with compatible options.
-
-
-
-
-
- Samar, Schemers Page 14
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- 8. INTEGRATION WITH SMART CARDS
-
- Many networking authentication protocols require possession of a long
- key to establish the user identity. For ease-of-use reasons, that
- long key is normally encrypted with the user's password so that the
- user is not required to memorize it. However, weak passwords can be
- compromised through a dictionary attack and thus undermine the
- stronger network authentication mechanism. Furthermore, the
- encrypted data is normally stored in a centrally accessible service
- whose availability depends upon the reliability of the associated
- service. Solutions have been proposed to use a pass-phrase or one-
- time-password, but those are much longer than the regular eight
- character passwords traditionally used with UNIX `login'. This makes
- the solution user-unfriendly because it requires longer strings to be
- remembered and typed.
-
- For most authentication protocol implementations, the trust boundary
- is the local machine. This assumption may not be valid in cases
- where the user is mobile and has to use publicly available networked
- computers. In such cases, it is required that the clear text of the
- key or the password never be made available to the machine.
-
- Smart cards solve the above problems by reducing password exposure by
- supporting a _two factor_ authentication mechanism: the first with
- the possession of the card, and the second with the knowledge of the
- PIN associated with the card. Not only can the smart cards be a
- secure repository of multiple passwords, they can also provide the
- encryption and authentication functions such that the long (private)
- key is never exposed outside the card.
-
- The PAM framework allows for integrating smart cards to the system by
- providing a smart card specific module for authentication.
- Furthermore, the unified login problem is simplified because the
- multiple passwords for various authentication mechanisms can be
- stored on the smart card itself. This can be enabled by adding a
- suitable key-word such as `use_smart_card' in the _options_ field.
-
-
- 9. SECURITY ISSUES
-
- It is important to understand the impact of PAM on the security of
- any system so that the site-administrator can make an informed
- decision.
-
- (a) Sharing of passwords with multiple authentication mechanisms.
-
- If there are multiple authentication modules, one possibility
- is to use the same password for all of them. If the password
- for any of the multiple authentication system is compromised,
- the user's password in all systems would be compromised. If
- this is a concern, then multiple passwords might be considered
-
-
-
- Samar, Schemers Page 15
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- at the cost of ease-of-use.
-
- (b) Password-mapping.
-
- This technique of encrypting all other passwords with the
- primary password assumes that it is lot more difficult to crack
- the primary password and that reasonable steps have been taken
- to ensure limited availability of the encrypted primary
- password. If this is not done, an intruder could target the
- primary password as the first point of dictionary attack. If
- one of the other modules provide stronger security than the
- password based security, the site would be negating the strong
- security by using password-mapping. If this is a concern, then
- multiple passwords might be considered at the cost of ease-of-
- use. If smart cards are used, they obviate the need for
- password-mapping completely.
-
- (c) Security of the configuration file.
-
- Since the policy file dictates how the user is authenticated,
- this file should be protected from unauthorized modifications.
-
- (d) Stacking various PAM modules.
-
- The system administrator should fully understand the
- implications of stacking various modules that will be installed
- on the system and their respective orders and interactions.
- The composition of various authentication modules should be
- carefully examined. The trusted computing base of the machine
- now includes the PAM modules.
-
-
- 10. EXPERIENCE WITH PAM
-
- The PAM framework was first added in Solaris 2.3 release as a private
- internal interface. PAM is currently being used by several system
- entry applications such as `login', `passwd', `su', `dtlogin',
- `rlogind', `rshd', `telnetd', `ftpd', `in.rexecd', `uucpd', `init',
- `sac', and `ttymon'. We have found that PAM provides an excellent
- framework to encapsulate the authentication-related tasks for the
- entire system. The Solaris 2.3 PAM API's were hence enhanced and
- simplified to support stacking.
-
- PAM modules have been developed for UNIX, DCE, Kerberos, S/Key,
- remote user authentication, and dialpass authentication. Other PAM
- modules are under development, and integration with smart cards is
- being planned.
-
- Some third parties have used the PAM interface to extend the security
- mechanisms offered by the Solaris environment.
-
-
-
-
- Samar, Schemers Page 16
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- The PAM API has been accepted by Common Desktop Environment (CDE)
- vendors as the API to be used for integrating the graphical interface
- for login, `dtlogin' with multiple authentication mechanisms.
-
-
- 11. FUTURE WORK
-
- Amongst the various components of PAM, the password component needs
- to be carefully examined to see whether the stacking semantics are
- particularly applicable, and how PAM should deal with partial
- failures when changing passwords.
-
- The _control_flag_ of the configuration file can be extended to
- include other semantics. For example, if the error is "name service
- not available", one may want to retry. It is also possible to offer
- semantics of "return success if any of the modules return success".
-
- In an earlier section, we had mentioned integration of smart cards
- with PAM. Though we feel that integration should be straight forward
- from the PAM architecture point of view, there may be some issues
- with implementation because the interfaces to the smart cards have
- not yet been standardized.
-
- One possible extension to PAM is to allow the passing of module-
- specific data between applications and PAM modules. For example, the
- `login' program likes to build its new environment from a select list
- of variables, yet the DCE module needs the `KRB5CCNAME' variable to
- be exported to the child process. For now we have modified the
- `login' program to explicitly export the `KRB5CCNAME' variable.
-
- Administrative tools are needed to help system administrators modify
- `pam.conf', and perform sanity checks on it (i.e., a `pam_check'
- utility).
-
-
- 12. CONCLUSION
-
- The PAM framework and the module interfaces provide pluggability for
- user authentication, as well as for account, session and password
- management. The PAM architecture can be used by `login' and by all
- other system-entry services, and thus ensure that all entry points
- for the system have been secured. This architecture enables
- replacement and modification of authentication modules in the field
- to secure the system against the newly found weaknesses without
- changing any of the system services.
-
- The PAM framework can be used to integrate `login' and `dtlogin' with
- different authentication mechanisms such as RSA and Kerberos.
- Multiple authentication systems can be accessed with the same
- password. The PAM framework also provides easy integration of smart
- cards into the system.
-
-
-
- Samar, Schemers Page 17
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- PAM provides complementary functionality to GSS-API, in that it
- provides mechanisms through which the user gets authenticated to any
- new system-level authentication service on the machine. GSS-API then
- uses the credentials for authenticated and secure communications with
- other application-level service entities on the network.
-
-
- 13. ACKNOWLEDGEMENTS
-
- PAM development has spanned several release cycles at SunSoft.
- Shau-Ping Lo, Chuck Hickey, and Alex Choy did the first design and
- implementation. Bill Shannon and Don Stephenson helped with the PAM
- architecture. Rocky Wu prototyped stacking of multiple modules.
- Paul Fronberg, Charlie Lai, and Roland Schemers made very significant
- enhancements to the PAM interfaces and took the project to completion
- within a very short time. Kathy Slattery wrote the PAM
- documentation. John Perry integrated PAM within the CDE framework.
-
-
- APPENDIX A. PAM API'S
-
- This appendix gives an informal description of the various interfaces
- of PAM. Since the goal here is just for the reader to get a working
- knowledge about the PAM interfaces, not all flags and options have
- been fully defined and explained. The API's described here are
- subject to change.
-
- The PAM Service Provider Interface is very similar to the PAM API,
- except for one extra parameter to pass module-specific options to the
- underlying modules.
-
- A.1. Framework Layer API's
-
- int
- pam_start(
- char *service_name,
- char *user,
- struct pam_conv *pam_conversation,
- pam_handle_t **pamh
- );
-
- `pam_start()' is called to initiate an authentication transaction.
- `pam_start()' takes as arguments the name of the service, the name of
- the user to be authenticated, the address of the conversation
- structure. `pamh' is later used as a handle for subsequent calls to
- the PAM library.
-
- The PAM modules do not communicate directly with the user; instead
- they rely on the application to perform all such interaction. The
- application needs to provide the conversation functions, `conv()',
- and associated application data pointers through a `pam_conv'
-
-
-
- Samar, Schemers Page 18
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- structure when it initiates an authentication transaction. The
- module uses the `conv()' function to prompt the user for data,
- display error messages, or text information.
-
- int
- pam_end(
- pam_handle_t *pamh,
- int pam_status
- );
-
- `pam_end()' is called to terminate the PAM transaction as specified
- by `pamh', and to free any storage area allocated by the PAM modules
- with `pam_set_item()'.
-
- int
- pam_set_item(
- pam_handle_t *pamh,
- int item_type,
- void *item
- );
-
- int
- pam_get_item(
- pam_handle_t *pamh,
- int item_type,
- void **item);
-
- `pam_get_item()' and `pam_set_item()' allow the parameters specified
- in the initial call to `pam_start()' to be read and updated. This is
- useful when a particular parameter is not available when
- `pam_start()' is called or must be modified after the initial call to
- `pam_start()'. `pam_set_item()' is passed a pointer to the object,
- `item', and its type, `item_type'. `pam_get_item()' is passed the
- address of the pointer, `item', which is assigned the address of the
- requested object.
-
- The `item_type' is one of the following:
-
- Table 5: Possible Values for Item_type
-
- Item Name Description
- --------- -----------
- PAM_SERVICE The service name
- PAM_USER The user name
- PAM_TTY The tty name
- PAM_RHOST The remote host name
- PAM_CONV The pam_conv structure
- PAM_AUTHTOK The authentication token (password)
- PAM_OLDAUTHTOK The old authentication token
- PAM_RUSER The remote user name
-
-
-
-
- Samar, Schemers Page 19
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- Note that the values of `PAM_AUTHTOK' and `PAM_OLDAUTHTOK' are only
- available to PAM modules and not to the applications. They are
- explicitly cleared out by the framework before returning to the
- application.
-
- char *
- pam_strerror(
- int errnum
- );
-
- `pam_strerror()' maps the error number to a PAM error message string,
- and returns a pointer to that string.
-
- int
- pam_set_data(
- pam_handle_t *pamh,
- char *module_data_name,
- char *data,
- (*cleanup)(pam_handle_t *pamh, char *data,
- int error_status)
- );
-
- The `pam_set_data()' function stores module specific data within the
- PAM handle. The `module_data_name' uniquely specifies the name to
- which some data and cleanup callback function can be attached. The
- cleanup function is called when `pam_end()' is invoked.
-
- int
- pam_get_data(
- pam_handle_t *pamh,
- char *module_data_name,
- void **datap
- );
-
- The `pam_get_data()' function obtains module-specific data from the
- PAM handle stored previously by the `pam_get_data()' function. The
- `module_data_name' uniquely specifies the name for which data has to
- be obtained. This function is normally used to retrieve module
- specific state information.
-
- A.2. Authentication API's
-
- int
- pam_authenticate(
- pam_handle_t *pamh,
- int flags
- );
-
- The `pam_authenticate()' function is called to verify the identity of
- the current user. The user is usually required to enter a password
- or similar authentication token, depending upon the authentication
-
-
-
- Samar, Schemers Page 20
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- module configured with the system. The user in question is specified
- by a prior call to `pam_start()', and is referenced by the
- authentication handle, `pamh'.
-
- int
- pam_setcred(
- pam_handle_t *pamh,
- int flags
- );
-
- The `pam_setcred()' function is called to set the credentials of the
- current process associated with the authentication handle, `pamh'.
- The actions that can be denoted through `flags' include credential
- initialization, refresh, reinitialization and deletion.
-
- A.3. Account Management API
-
- int
- pam_acct_mgmt(
- pam_handle_t *pamh,
- int flags
- );
-
- The function `pam_acct_mgmt()' is called to determine whether the
- current user's account and password are valid. This typically
- includes checking for password and account expiration, valid login
- times, etc. The user in question is specified by a prior call to
- `pam_start()', and is referenced by the authentication handle,
- `pamh'.
-
- A.4. Session Management API's
-
- int
- pam_open_session(
- pam_handle_t *pamh,
- int flags
- );
-
- `pam_open_session()' is called to inform the session modules that a
- new session has been initialized. All programs which use PAM should
- invoke `pam_open_session()' when beginning a new session.
-
- int
- pam_close_session(
- pam_handle_t *pamh,
- int flags
- );
-
- Upon termination of this session, the `pam_close_session()' function
- should be invoked to inform the underlying modules that the session
- has terminated.
-
-
-
- Samar, Schemers Page 21
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- A.5. Password Management API's
-
- int
- pam_chauthtok(
- pam_handle_t *pamh,
- int flags
- );
-
- `pam_chauthtok()' is called to change the authentication token
- associated with the user referenced by the authentication handle
- `pamh'. After the call, the authentication token of the user will be
- changed in accordance with the authentication module configured on
- the system.
-
-
- APPENDIX B. SAMPLE PAM APPLICATION
-
- This appendix shows a sample `login' application which uses the PAM
- API's. It is not meant to be a fully functional login program, as
- some functionality has been left out in order to emphasize the use of
- PAM API's.
-
- #include <security/pam_appl.h>
-
- static int login_conv(int num_msg, struct pam_message **msg,
- struct pam_response **response, void *appdata_ptr);
-
- static struct pam_conv pam_conv = {login_conv, NULL};
-
- static pam_handle_t *pamh; /* Authentication handle */
-
- void
- main(int argc, char *argv[], char **renvp)
- {
-
- /*
- * Call pam_start to initiate a PAM authentication operation
- */
-
- if ((pam_start("login", user_name, &pam_conv, &pamh))
- != PAM_SUCCESS)
- login_exit(1);
-
- pam_set_item(pamh, PAM_TTY, ttyn);
- pam_set_item(pamh, PAM_RHOST, remote_host);
-
- while (!authenticated && retry < MAX_RETRIES) {
- status = pam_authenticate(pamh, 0);
- authenticated = (status == PAM_SUCCESS);
- }
-
-
-
-
- Samar, Schemers Page 22
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- if (status != PAM_SUCCESS) {
- fprintf(stderr,"error: %s\n", pam_strerror(status));
- login_exit(1);
- }
-
- /* now check if the authenticated user is allowed to login. */
-
- if ((status = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS) {
- if (status == PAM_AUTHTOK_EXPIRED) {
- status = pam_chauthtok(pamh, 0);
- if (status != PAM_SUCCESS)
- login_exit(1);
- } else {
- login_exit(1);
- }
- }
-
- /*
- * call pam_open_session to open the authenticated session
- * pam_close_session gets called by the process that
- * cleans up the utmp entry (i.e., init)
- */
- if (status = pam_open_session(pamh, 0) != PAM_SUCCESS) {
- login_exit(status);
- }
-
- /* set up the process credentials */
- setgid(pwd->pw_gid);
-
- /*
- * Initialize the supplementary group access list.
- * This should be done before pam_setcred because
- * the PAM modules might add groups during the pam_setcred call
- */
- initgroups(user_name, pwd->pw_gid);
-
- status = pam_setcred(pamh, PAM_ESTABLISH_CRED);
- if (status != PAM_SUCCESS) {
- login_exit(status);
- }
-
- /* set the real (and effective) UID */
- setuid(pwd->pw_uid);
-
- pam_end(pamh, PAM_SUCCESS); /* Done using PAM */
-
- /*
- * Add DCE/Kerberos cred name, if any.
- * XXX - The module specific stuff should be removed from login
- * program eventually. This is better placed in DCE module and
- * will be once PAM has routines for "exporting" environment
-
-
-
- Samar, Schemers Page 23
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- * variables.
- */
- krb5p = getenv("KRB5CCNAME");
- if (krb5p != NULL) {
- ENVSTRNCAT(krb5ccname, krb5p);
- envinit[basicenv++] = krb5ccname;
- }
- environ = envinit; /* Switch to the new environment. */
- exec_the_shell();
-
- /* All done */
- }
-
- /*
- * login_exit - Call exit() and terminate.
- * This function is here for PAM so cleanup can
- * be done before the process exits.
- */
- static void
- login_exit(int exit_code)
- {
- if (pamh)
- pam_end(pamh, PAM_ABORT);
- exit(exit_code);
- /*NOTREACHED*/
- }
-
- /*
- * login_conv():
- * This is the conv (conversation) function called from
- * a PAM authentication module to print error messages
- * or garner information from the user.
- */
-
- static int
- login_conv(int num_msg, struct pam_message **msg,
- struct pam_response **response, void *appdata_ptr)
- {
-
- while (num_msg--) {
- switch (m->msg_style) {
-
- case PAM_PROMPT_ECHO_OFF:
- r->resp = strdup(getpass(m->msg));
- break;
-
- case PAM_PROMPT_ECHO_ON:
- (void) fputs(m->msg, stdout);
- r->resp = malloc(PAM_MAX_RESP_SIZE);
- fgets(r->resp, PAM_MAX_RESP_SIZE, stdin);
- /* add code here to remove \n from fputs */
-
-
-
- Samar, Schemers Page 24
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- break;
-
- case PAM_ERROR_MSG:
- (void) fputs(m->msg, stderr);
- break;
-
- case PAM_TEXT_INFO:
- (void) fputs(m->msg, stdout);
- break;
-
- default:
- /* add code here to log error message, etc */
- break;
- }
- }
- return (PAM_SUCCESS);
- }
-
-
- APPENDIX C. DCE MODULE
-
- This appendix describes a sample implementation of a DCE PAM module.
- In order to simplify the description, we do not address the issues
- raised by password-mapping or stacking. The intent is to show which
- DCE calls are being made by the DCE module.
-
- The `pam_sm_*()' functions implement the PAM SPI functions which are
- called from the PAM API functions.
-
- C.1. DCE Authentication Management
-
- The algorithm for authenticating with DCE (not including error
- checking, prompting for passwords, etc.) is as follows:
-
- pam_sm_authenticate()
- {
- sec_login_setup_identity(...);
- pam_set_data(...);
- sec_login_valid_and_cert_ident(...);
- }
-
- pam_sm_setcred()
- {
- pam_get_data(...);
- sec_login_set_context(...);
- }
-
- The `pam_sm_authenticate()' function for DCE uses the
- `pam_set_data()' and `pam_get_data()' functions to keep state (like
- the `sec_login_handle_t' context) between calls. The following
- cleanup function is also registered and gets called when `pam_end()'
-
-
-
- Samar, Schemers Page 25
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- is called:
-
- dce_cleanup()
- {
- if (/* PAM_SUCCESS and
- sec_login_valid_and_cert_ident success */) {
- sec_login_release_context(...);
- } else {
- sec_login_purge_context(...);
- }
- }
-
- If everything was successful we release the login context, but leave
- the credentials file intact. If the status passed to `pam_end()' was
- not `PAM_SUCCESS' (i.e., a required module failed) we purge the login
- context which also removes the credentials file.
-
- C.2. DCE Account Management
-
- The algorithm for DCE account management is as follows:
-
- pam_sm_acct_mgmt()
- {
- pam_get_data(...);
- sec_login_inquire_net_info(...);
- /* check for expired password and account */
- sec_login_free_net_info(...);
- }
-
- The `sec_login_inquire_net_info()' function is called to obtain
- information about when the user's account and/or password are going
- to expire. A warning message is displayed (using the conversation
- function) if the user's account or password is going to expire in the
- near future, or has expired. These warning messages can be disabled
- using the `nowarn' option in the `pam.conf' file.
-
- C.3. DCE Session Management
-
- The DCE session management functions are currently empty. They could
- be modified to optionally remove the DCE credentials file upon
- logout, etc.
-
- C.4. DCE Password Management
-
- The algorithm for DCE password management is as follows:
-
-
-
-
-
-
-
-
-
- Samar, Schemers Page 26
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- pam_sm_chauthtok
- {
- sec_rgy_site_open(...);
- sec_rgy_acct_lookup(...);
- sec_rgy_acct_passwd(...);
- sec_rgy_site_close(...);
- }
-
- The `sec_rgy_acct_passwd()' function is called to change the user's
- password in the DCE registry.
-
-
- REFERENCES
-
- [Adamson 95] W. A. Adamson, J. Rees, and P. Honeyman, "Joining
- Security Realms: A Single Login for Netware and
- Kerberos", CITI Technical Report 95-1, Center for
- Information Technology Integration, University of
- Michigan, Ann Arbor, MI, February 1995.
-
- [Diffie 76] W. Diffie and M. E. Hellman, "New Directions in
- Cryptography", IEEE Transactions on Information
- Theory, November 1976.
-
- [Linn 93] J. Linn, "Generic Security Service Application
- Programming Interface", Internet RFC 1508, 1509, 1993.
-
- [Rivest 78] R. L. Rivest, A. Shamir, and L. Adleman., "A Method
- for Obtaining Digital Signatures and Pubic-key
- Cryptosystems", Communications of the ACM, 21(2),
- 1978.
-
- [SIA 95] "Digital UNIX Security", Digital Equipment
- Corporation, Order Number AA-Q0R2C-TE, July 1995.
-
- [Skey 94] N. M. Haller, "The S/Key One-Time Password System",
- ISOC Symposium on Network and Distributed Security,
- 1994.
-
- [Steiner 88] J.G. Steiner, B. C. Neuman, and J. I. Schiller,
- "Kerberos, An Authentication Service for Open Network
- Systems", in Proceedings of the Winter USENIX
- Conference, Dallas, Jan 1988.
-
- [Taylor 88] B. Taylor and D. Goldberg, "Secure Networking in the
- Sun Environment", Sun Microsystems Technical Paper,
- 1988.
-
- [XFN 94] "Federated Naming: the XFN Specifications", X/Open
- Preliminary Specification, X/Open Document #P403,
- ISBN:1-85912-045-8, X/Open Co. Ltd., July 1994.
-
-
-
- Samar, Schemers Page 27
-
-
-
-
-
-
-
- OSF-RFC 86.0 PAM October 1995
-
-
-
- AUTHOR'S ADDRESS
-
- Vipin Samar Internet email: vipin@eng.sun.com
- SunSoft, Inc. Telephone: +1-415-336-1002
- 2550 Garcia Avenue
- Mountain View, CA 94043
- USA
-
- Roland J. Schemers III Internet email: schemers@eng.sun.com
- SunSoft, Inc. Telephone: +1-415-336-1035
- 2550 Garcia Avenue
- Mountain View, CA 94043
- USA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Samar, Schemers Page 28
-
-
-
-
-
-
diff --git a/Linux-PAM/doc/specs/std-agent-id.raw b/Linux-PAM/doc/specs/std-agent-id.raw
deleted file mode 100644
index c97ce975..00000000
--- a/Linux-PAM/doc/specs/std-agent-id.raw
+++ /dev/null
@@ -1,95 +0,0 @@
-PAM working group ## A.G. Morgan
-
-## $Id: std-agent-id.raw,v 1.1 2001/12/08 18:56:47 agmorgan Exp $ ##
-
-## Pluggable Authentication Modules ##
-
-## REGISTERED AGENTS AND THEIR AGENT-ID'S ##
-
-#$ Purpose of this document
-
-#$$#{definition} Definition of an agent-id
-
-The most complete version of a "PAM agent-id" is contained in this
-reference [#$R#{PAM_RFC2}]. A copy of a recent definition is
-reproduced here for convenience. The reader is recommended to consult
-reference [#{PAM_RFC2}] for definitions of other terms that are
-used in this document.
-
-## -------------- ##
-
-The agent_id is a sequence of characters satisfying the following
-regexp:
-
- /^[a-z0-9\_]+(@[a-z0-9\_.]+)?$/
-
-and has a specific form for each independent agent.
-
-o Agent_ids that do not contain an at-sign (@) are to be considered as
- representing some authentication mode that is a "public
- standard". Registered names MUST NOT contain an at-sign (@).
-
-o Anyone can define additional agents by using names in the format
- name@domainname, e.g. "ouragent@example.com". The part following
- the at-sign MUST be a valid fully qualified internet domain name
- [RFC-1034] controlled by the person or organization defining the
- name. (Said another way, if you control the email address that
- your agent has as an identifier, they you are entitled to use
- this identifier.) It is up to each domain how it manages its local
- namespace.
-
-## -------------- ##
-
-#$ Registered agent-id's
-
-The structure of this section is a single subsection for each
-registered agent-id. This section includes a full definition of binary
-prompts accepted by the agent and example responses of said
-agent. Using the defining section alone, it should be possible for a
-third party to create a conforming agent and modules that can
-interoperate with other implementations of these objects.
-
-*$ "userpass" - the user+password agent
-
-Many legacy authentication systems are hardcoded to support one and
-only one authentication method. Namely,
-
- username: joe
- password: <secret>
-
-Indeed, this authentication method is often embedded into parts of the
-transport protocol. The "user+password" agent with PAM agent-id:
-
- "userpass"
-
-Is intended to support this legacy authentication scheme. The protocol
-for binary prompt exchange with this 'standard agent' is as follows:
-
-Case 1: module does not know the username, but expects the agent to
- obtain this information and also the user's password:
-
- module: {LENGTH;PAM_BP_SELECT;userpass;'/'}
- agent: {}
-
-Case 2: module has suggested username, but would like agent to confirm
- it and gather password:
-
- module: {}
- agent: {}
-
-Case 3: module knows username and will not permit the agent to change it:
-
- module: {}
- agent: {}
-
-#$ References
-
-[#{PAM_RFC2}] Internet draft, "Pluggable Authentication Modules
- (PAM)", available here:
-
-# http://linux.kernel.org/pub/linux/libs/pam/pre/doc/current-draft.txt #
-
-#$ Author's Address
-
-Andrew G. Morgan
-Email: morgan@kernel.org