public inbox for gnats-devel@sourceware.org
 help / color / mirror / Atom feed
From: Pankaj K Garg <gargp@earthlink.net>
To: help-gnats@gnu.org
Subject: PAM Authentication Patch
Date: Sun, 20 Jun 2004 17:39:00 -0000	[thread overview]
Message-ID: <40D5BE7A.2080503@earthlink.net> (raw)
In-Reply-To: <20040614165706.GG3528@wookimus.net>

[-- Attachment #1: Type: text/plain, Size: 1722 bytes --]

I'm attaching a patch for enabling PAM authentication support.

To keep the patch file small, I've not included the diffs to the files
'configure' and 'gnats/configure'. Use autoconf to generate these two 
files. If you need the generated files, let me know and I'll create 
another patch.

PAM support can now be enabled by using '--enable-pam' switch to configure.

With PAM support enabled, you can put an entry in the gantsd.user_access 
file as:

   <user>:$p$:<access-level>

  and the authentication for the user will be done against the 
configured PAM modules.

  The name of the PAM service is taken from the DEFAULT_GANTS_SERVICE 
define, so by default it should be 'support'. Hence, you can configure 
PAM by creating the file /etc/pam.d/support on RH Linux.

  I've tried to make appropriate changes to the documentation. Let me 
know if any other document requires update.

  I've done some preliminary testing on my RH 9.0 Linux. Please let me 
know if there's any problem with it.

Pankaj

Chad C. Walstrom wrote:
> Pankaj K Garg wrote:
> 
>>Is anyone signed up for adding PAM authentication support yet? If not,
>>I can sign up for it.
> 
> 
> No, no one has signed up for this yet.  I placed your name in the TODO
> list and updated it in CVS.  I don't plan on making ChangeLog entries
> for these files (.todo and TODO), though I will note the changes made in
> the cvs log entry.  Welcome aboard!  I look forward to getting your
> patches!

-- 
Pankaj K Garg                         garg@zeesource.net
1684 Nightingale Avenue               408-373-4027
Suite 201                             408-733-2737(fax)
Sunnyvale, CA 94087

http://www.zeesource.net              http://home.earthlink.net/~gargp


[-- Attachment #2: pam_patch.out --]
[-- Type: text/plain, Size: 17955 bytes --]

? autom4te.cache
? pamdiffs.out
? gnats/autom4te.cache
? libiberty/xhost-mkfrag
Index: doc/gnats.texi
===================================================================
RCS file: /cvsroot/gnats/gnats/doc/gnats.texi,v
retrieving revision 1.44
diff -u -p -r1.44 gnats.texi
--- doc/gnats.texi	30 Aug 2003 07:55:06 -0000	1.44
+++ doc/gnats.texi	20 Jun 2004 16:34:24 -0000
@@ -1670,8 +1670,9 @@ string @samp{$1$}.@footnote{Some systems
 methods.  In FreeBSD, for instance, a prefix of @samp{$2$} implies
 Blowfish encoding.  @sc{gnats} will happily accept any encryption that
 the OS supports.} Passwords encrypted by @code{crypt()} should have no
-prefix. If no password is given then users can login with an empty
-password string.
+prefix. If you want to authenticate users with PAM authentication
+module, then supply a @samp{$p$} for the password entry. If no
+password is given then users can login with an empty password string.
 
 A @code{gnats-passwd} tool to manage @file{gnatsd.user_access} files is
 planned.  In the meantime, @code{crypt()} passwords can be generated by
Index: gnats/acconfig.h
===================================================================
RCS file: /cvsroot/gnats/gnats/gnats/acconfig.h,v
retrieving revision 1.3
diff -u -p -r1.3 acconfig.h
--- gnats/acconfig.h	26 May 2001 20:42:30 -0000	1.3
+++ gnats/acconfig.h	20 Jun 2004 16:34:24 -0000
@@ -26,3 +26,8 @@ Software Foundation, 59 Temple Place - S
 
 /* Define if strftime supports %z. */
 #undef HAVE_STRFTIME_WITH_Z
+
+/* Define to enable system authentication with PAM instead of using the simple
+   getpwnam interface. This allows authentication (in theory) with any PAM
+   module, e.g. on systems with shadow passwords or via LDAP */
+#undef HAVE_PAM
Index: gnats/autoconf.h.in
===================================================================
RCS file: /cvsroot/gnats/gnats/gnats/autoconf.h.in,v
retrieving revision 1.11
diff -u -p -r1.11 autoconf.h.in
--- gnats/autoconf.h.in	6 Jan 2002 16:16:45 -0000	1.11
+++ gnats/autoconf.h.in	20 Jun 2004 16:34:24 -0000
@@ -1,143 +1,212 @@
-/* autoconf.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/* autoconf.h.in.  Generated from configure.in by autoheader.  */
+/* GNATS specific autoconf symbols.
+   Copyright (C) 2001 Milan Zamazal
+   Copyright (C) 1995, 1996 ??? (FIXME, see ChangeLog.v3)
+
+This file is part of GNU GNATS.
+
+GNU GNATS 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.
+
+GNU GNATS 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 GNU GNATS; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA.  */
 
-/* Define if on AIX 3.
-   System headers sometimes define this.
-   We just want to avoid a redefinition error message.  */
-#ifndef _ALL_SOURCE
-#undef _ALL_SOURCE
-#endif
+/* Define if you have MIT Kerberos version 4 available.  */
+#undef HAVE_KERBEROS
 
-/* Define if using alloca.c.  */
-#undef C_ALLOCA
+/* Define if your system has socklen_t (glibc?) */
+#undef HAVE_SOCKLEN_T
 
-/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
-   This function is required for alloca.c support on those systems.  */
+/* Define if strftime supports %z. */
+#undef HAVE_STRFTIME_WITH_Z
+
+/* Define to enable system authentication with PAM instead of using the simple
+   getpwnam interface. This allows authentication (in theory) with any PAM
+   module, e.g. on systems with shadow passwords or via LDAP */
+#undef HAVE_PAM
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
 #undef CRAY_STACKSEG_END
 
-/* Define if you have alloca, as a function or macro.  */
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define to 1 if you have `alloca', as a function or macro. */
 #undef HAVE_ALLOCA
 
-/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
 #undef HAVE_ALLOCA_H
 
-/* Define if on MINIX.  */
-#undef _MINIX
-
-/* Define if the system does not provide POSIX.1 features except
-   with this defined.  */
-#undef _POSIX_1_SOURCE
-
-/* Define if you need to in order for stat and other things to work.  */
-#undef _POSIX_SOURCE
-
-/* Define to `unsigned' if <sys/types.h> doesn't define.  */
-#undef size_t
-
-/* If using the C implementation of alloca, define if you know the
-   direction of stack growth for your system; otherwise it will be
-   automatically deduced at run-time.
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown
- */
-#undef STACK_DIRECTION
+/* Define to 1 if you have the <crypt.h> header file. */
+#undef HAVE_CRYPT_H
 
-/* Define if you have the ANSI C header files.  */
-#undef STDC_HEADERS
+/* Whether unsetenv is present in headers. */
+#undef HAVE_DECL_UNSETENV
 
-/* Define if you have MIT Kerberos version 4 available.  */
-#undef HAVE_KERBEROS
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_DIRENT_H
 
-/* Define if your system has socklen_t (glibc?) */
-#undef HAVE_SOCKLEN_T
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
 
-/* Define if you have the ftime function.  */
+/* Define to 1 if you have the `ftime' function. */
 #undef HAVE_FTIME
 
-/* Define if you have the krb_get_err_text function.  */
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `krb_get_err_text' function. */
 #undef HAVE_KRB_GET_ERR_TEXT
 
-/* Define if you have the mkdir function.  */
-#undef HAVE_MKDIR
+/* Define to 1 if you have the `crypt' library (-lcrypt). */
+#undef HAVE_LIBCRYPT
 
-/* Define if you have the mkstemp function.  */
-#undef HAVE_MKSTEMP
+/* Define to 1 if you have the `gen' library (-lgen). */
+#undef HAVE_LIBGEN
 
-/* Define if you have the mktemp function.  */
-#undef HAVE_MKTEMP
+/* Define to 1 if you have the <libgen.h> header file. */
+#undef HAVE_LIBGEN_H
 
-/* Define if you have the unsetenv function.  */
-#undef HAVE_UNSETENV
+/* Define to 1 if you have the `inet' library (-linet). */
+#undef HAVE_LIBINET
 
-/* Define if you have the <crypt.h> header file.  */
-#undef HAVE_CRYPT_H
+/* Define to 1 if you have the `intl' library (-lintl). */
+#undef HAVE_LIBINTL
 
-/* Define if you have the <dirent.h> header file.  */
-#undef HAVE_DIRENT_H
+/* Define to 1 if you have the `malloc' library (-lmalloc). */
+#undef HAVE_LIBMALLOC
 
-/* Define if you have the <fcntl.h> header file.  */
-#undef HAVE_FCNTL_H
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
 
-/* Define if you have the <libgen.h> header file.  */
-#undef HAVE_LIBGEN_H
+/* Define to 1 if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
 
-/* Define if you have the <limits.h> header file.  */
+/* Define to 1 if you have the <limits.h> header file. */
 #undef HAVE_LIMITS_H
 
-/* Define if you have the <machine/endian.h> header file.  */
+/* Define to 1 if you have the <machine/endian.h> header file. */
 #undef HAVE_MACHINE_ENDIAN_H
 
-/* Define if you have the <memory.h> header file.  */
+/* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
-/* Define if you have the <ndir.h> header file.  */
+/* Define to 1 if you have the `mkdir' function. */
+#undef HAVE_MKDIR
+
+/* Define to 1 if you have the `mkstemp' function. */
+#undef HAVE_MKSTEMP
+
+/* Define to 1 if you have the `mktemp' function. */
+#undef HAVE_MKTEMP
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
 #undef HAVE_NDIR_H
 
-/* Define if you have the <netdb.h> header file.  */
+/* Define to 1 if you have the <netdb.h> header file. */
 #undef HAVE_NETDB_H
 
-/* Define if you have the <string.h> header file.  */
+/* Define to enable system authentication with PAM instead of using the simple
+   getpwnam interface. This allows authentication (in theory) with any PAM
+   module, e.g. on systems with shadow passwords or via LDAP */
+#undef HAVE_PAM
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
 #undef HAVE_STRING_H
 
-/* Define if you have the <sys/dir.h> header file.  */
+/* Define to 1 if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
 #undef HAVE_SYS_DIR_H
 
-/* Define if you have the <sys/ndir.h> header file.  */
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
 #undef HAVE_SYS_NDIR_H
 
-/* Define if you have the <sys/select.h> header file.  */
+/* Define to 1 if you have the <sys/select.h> header file. */
 #undef HAVE_SYS_SELECT_H
 
-/* Define if you have the <syslog.h> header file.  */
-#undef HAVE_SYSLOG_H
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
 
-/* Define if you have the <unistd.h> header file.  */
+/* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
-/* Define if you have the crypt library (-lcrypt).  */
-#undef HAVE_LIBCRYPT
+/* Define to 1 if you have the `unsetenv' function. */
+#undef HAVE_UNSETENV
 
-/* Define if you have the gen library (-lgen).  */
-#undef HAVE_LIBGEN
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
 
-/* Define if you have the inet library (-linet).  */
-#undef HAVE_LIBINET
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
 
-/* Define if you have the intl library (-lintl).  */
-#undef HAVE_LIBINTL
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
 
-/* Define if you have the malloc library (-lmalloc).  */
-#undef HAVE_LIBMALLOC
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
 
-/* Define if you have the nsl library (-lnsl).  */
-#undef HAVE_LIBNSL
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
 
-/* Define if you have the socket library (-lsocket).  */
-#undef HAVE_LIBSOCKET
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
 
-/* Whether unsetenv is present in headers. */
-#undef HAVE_DECL_UNSETENV
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
 
-/* Whether unsetenv is present in headers. */
-#undef HAVE_DECL_UNSETENV
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+   `char[]'. */
+#undef YYTEXT_POINTER
 
+/* Define to 1 if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
Index: gnats/configure.in
===================================================================
RCS file: /cvsroot/gnats/gnats/gnats/configure.in,v
retrieving revision 1.31
diff -u -p -r1.31 configure.in
--- gnats/configure.in	20 Sep 2003 22:36:43 -0000	1.31
+++ gnats/configure.in	20 Jun 2004 16:34:24 -0000
@@ -291,6 +291,42 @@ if test -z "${GNATS_DEFAULT_DB_DIR}"; th
 	GNATS_DEFAULT_DB_DIR=${sharedstatedir}/gnatsdb
 fi
 
+dnl
+dnl begin --enable-pam
+dnl
+
+dnl
+dnl Check if PAM authentication is enabled
+dnl
+AC_ARG_ENABLE(
+  [pam],
+  AC_HELP_STRING(
+    [--enable-pam],
+    [Use to enable system authentication with PAM instead of using the 
+    simple file based passwords.  This allows authentication (in theory) 
+    with any PAM module, e.g. on systems with shadow passwords or via LDAP]), ,
+  [enable_pam=no]
+  )
+
+if test yes = $enable_pam; then
+  AC_CHECK_HEADER(security/pam_appl.h, 
+    AC_DEFINE(HAVE_PAM, 1, 
+    [Define to enable system authentication with PAM instead of using the 
+    simple getpwnam interface.  This allows authentication (in theory) 
+    with any PAM module, e.g. on systems with shadow passwords or via LDAP])
+    AC_CHECK_LIB(pam, pam_start, [LIBS="${LIBS} -lpam"],
+      AC_MSG_ERROR([Could not find PAM libraries but the headers exist.
+      Give the --disable-pam option to compile without PAM support (or fix
+      your broken configuration)])
+    ),
+    AC_MSG_ERROR([Could not find PAM headers])
+  )
+fi
+
+dnl
+dnl end --enable-pam
+dnl
+
 # Set up default values to be overridden
 
 _h=`(hostname || uname -n) 2>/dev/null | sed 1q`
Index: gnats/gnatsd.c
===================================================================
RCS file: /cvsroot/gnats/gnats/gnats/gnatsd.c,v
retrieving revision 1.48
diff -u -p -r1.48 gnatsd.c
--- gnats/gnatsd.c	14 Oct 2002 11:42:25 -0000	1.48
+++ gnats/gnatsd.c	20 Jun 2004 16:34:25 -0000
@@ -248,18 +248,133 @@ match (const char *line, const char *pat
     }
 }
 
-/* Return true iff `password' matches `hash'.
-   `hash' is a possibly encrypted password, according to the $?$ convention. */
+#ifdef HAVE_PAM
+/**
+ *
+ * Support for PAM authentication. Code borrowed from CVS server code
+ * with similar capability (gargp@acm.org)
+ *
+ **/
+#include <security/pam_appl.h>
+
+struct gnats_pam_userinfo {
+  const char *username;
+  const char *password;
+};
+
 static int
-password_match (const char *password, const char *hash)
+gnats_pam_conv(int num_msg, const struct pam_message **msg,
+	       struct pam_response **resp, void *appdata_ptr )
 {
-  if (strlen(password) && strlen(hash))
+  int i;
+  struct pam_response *response;
+  struct gnats_pam_userinfo *ui = (struct gnats_pam_userinfo *)appdata_ptr;
+
+  response = xmalloc(num_msg * sizeof(struct pam_response));
+  memset(response, 0, num_msg * sizeof(struct pam_response));
+
+  for (i = 0; i < num_msg; i++)
+    {
+      switch(msg[i]->msg_style) 
+	{
+	  /* PAM wants a username */
+	case PAM_PROMPT_ECHO_ON:
+	  response[i].resp = xstrdup(ui->username);
+	  break;
+	  /* PAM wants a password */
+	case PAM_PROMPT_ECHO_OFF:
+	  response[i].resp = xstrdup(ui->password);
+	  break;
+	case PAM_ERROR_MSG:
+	case PAM_TEXT_INFO:
+	  printf("%s\n",msg[i]->msg);
+	  break;
+	  /* PAM wants something we don't understand - bail out */
+	default:
+	  goto cleanup;
+	}
+    }
+
+  *resp = response;
+  return PAM_SUCCESS;
+
+ cleanup:
+  for (i = 0; i < num_msg; i++)
+    {
+      if (response[i].resp)
+	{
+	  free(response[i].resp);
+	  response[i].resp = 0;
+	}
+    }
+  free(response);
+  return PAM_CONV_ERR;
+}
+
+static bool
+pam_password_match( const char *username, const char *password )
+{
+  pam_handle_t *pamh = NULL;
+  int retval, err;
+  struct gnats_pam_userinfo ui;
+  struct pam_conv conv;
+  const char *pam_stage = "start";
+
+  ui.username = username;
+  ui.password = password;
+
+  conv.conv        =  gnats_pam_conv;
+  conv.appdata_ptr = (void *)&ui;
+
+  retval = pam_start(DEFAULT_GNATS_SERVICE, username, &conv, &pamh);
+
+  if (retval == PAM_SUCCESS) {
+    pam_stage = "authenticate";
+    retval = pam_authenticate(pamh, 0);
+  }
+
+  if (retval == PAM_SUCCESS) {
+    pam_stage = "account";
+    retval = pam_acct_mgmt(pamh, 0);
+  }
+
+  if (retval != PAM_SUCCESS)
+    syslog(LOG_ERR, "PAM %s error: %s\n", pam_stage, pam_strerror(pamh, retval));
+
+  if ((err = pam_end(pamh, retval)) != PAM_SUCCESS)
+    {
+      syslog(LOG_ERR, "PAM error %s\n", pam_strerror(NULL, err));
+      exit (EXIT_FAILURE);
+    }
+
+  return retval == PAM_SUCCESS ? TRUE : FALSE;       /* indicate success */
+}
+#endif
+
+/**
+ *
+ * Return TRUE iff `password' matches, as specified by `hash'.
+ * `hash' is a possibly encrypted password, according to the $?$ convention.
+ * If hash == '$p$', then use the PAM service for authentication.
+ *
+ **/
+static int
+password_match (const char *user, const char *password, const char *hash)
+{
+  if (strlen(user) && strlen(password) && strlen(hash))
     {
       if (! strncmp (hash, "$0$", 3))
 	{
 	  /* explicit plain-text password */
 	  return match (password, hash+3, TRUE);
 	}
+#ifdef HAVE_PAM
+      else if (! strncmp (hash, "$p$", 3))
+	{
+	  /* check with PAM module */
+	  return pam_password_match (user, password);
+	}
+#endif
       else
 	{
 #ifdef HAVE_LIBCRYPT
@@ -461,7 +576,7 @@ findUserAccessLevel (const char *file, c
 	  if ((ent->fieldcount == 3 || ent->fieldcount == 4)
 	      && match (user, ent->admFields[0], TRUE))
 	    {
-	      if (! password_match (passwd, ent->admFields[1]))
+	      if (! password_match (user, passwd, ent->admFields[1]))
 		{
 		  /* Username matched but password didn't.  */
 		  if (strlen(ent->admFields[1]) && strlen(passwd))

[-- Attachment #3: Type: text/plain, Size: 140 bytes --]

_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://lists.gnu.org/mailman/listinfo/help-gnats

  reply	other threads:[~2004-06-20 16:43 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-06-10 21:20 CVS, Documentation, TODO Lists, New Maintainer, and Stuff Chad C. Walstrom
2004-06-10 21:44 ` Chad C. Walstrom
2004-06-13  8:51   ` Mel Hatzis
2004-06-13 23:01   ` Andrew Gray
2004-06-11 22:28 ` Yngve Svendsen
2004-06-14 17:07 ` Pankaj K Garg
2004-06-14 17:16   ` Chad C. Walstrom
2004-06-20 17:39     ` Pankaj K Garg [this message]
     [not found]       ` <gargp@earthlink.net>
2004-06-20 17:59         ` PAM Authentication Patch Mark D. Baushke
2004-06-21  7:25           ` Chad Walstrom
2004-06-21 15:26             ` Chad Walstrom
     [not found]               ` <chewie@wookimus.net>
2004-06-21 15:34                 ` Mark D. Baushke
2004-11-04  1:27                 ` Preparing 4.1 Mark D. Baushke
2004-11-04  3:15                   ` Chad Walstrom
2004-11-04 19:15                     ` Chad Walstrom
2004-11-17 23:26                       ` Chad Walstrom
2004-06-21 16:13       ` PAM Authentication Patch Chad Walstrom
2004-10-29 21:33 Preparing 4.1 Chad C. Walstrom
2004-10-31 14:03 ` Pankaj Garg
2004-11-01 19:09 ` Pankaj Garg
2004-11-03 22:39   ` Chad C. Walstrom
2004-11-03 22:46 ` Chad C. Walstrom

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=40D5BE7A.2080503@earthlink.net \
    --to=gargp@earthlink.net \
    --cc=gargp@acm.org \
    --cc=help-gnats@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).