bin/76169: [PATCH] Add PAM support to cvs pserver

Dan Nelson dnelson at allantgroup.com
Wed Jan 12 10:20:22 PST 2005


>Number:         76169
>Category:       bin
>Synopsis:       [PATCH] Add PAM support to cvs pserver
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jan 12 18:20:21 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Dan Nelson
>Release:        FreeBSD 5.3-STABLE i386
>Organization:
>Environment:
System: FreeBSD dan.emsphone.com 5.3-STABLE FreeBSD 5.3-STABLE #386: Tue Jan 11 12:01:34 CST 2005 zsh at dan.emsphone.com:/usr/src/sys/i386/compile/DANSMP i386


	
>Description:

Most of the base services have been PAM-ified, but cvs is a notable
exception.  CVS 1.12 will have PAM support, but I don't know when 1.12
will be declared stable. The following patch is based on Steve
McIntyre's 1.11 patch at
http://ccvs.cvshome.org/issues/show_bug.cgi?id=44 .

	
>How-To-Repeat:
	
>Fix:

Index: contrib/cvs/src/server.c
===================================================================
RCS file: /home/ncvs/src/contrib/cvs/src/server.c,v
retrieving revision 1.24
diff -u -p -r1.24 server.c
--- contrib/cvs/src/server.c	10 Jun 2004 19:12:50 -0000	1.24
+++ contrib/cvs/src/server.c	5 Jan 2005 18:25:50 -0000
@@ -20,6 +20,13 @@
 #include "getline.h"
 #include "buffer.h"
 
+#define HAVE_PAM
+
+#ifdef HAVE_PAM
+#include <security/pam_appl.h>
+#include <security/openpam.h>
+#endif
+
 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
 # ifdef HAVE_GSSAPI
 /* This stuff isn't included solely with SERVER_SUPPORT since some of these
@@ -5593,7 +5600,66 @@ check_repository_password (username, pas
     return retval;
 }
 
+#ifdef HAVE_PAM
+
+static struct pam_conv conv = {
+    openpam_nullconv,
+    NULL
+};
+
+/* Modelled very closely on the example code in "The Linux-PAM
+   Application Developers' Guide" by Andrew G. Morgan. */
+static int
+check_pam_password (username, password, repository, host_user_ptr)
+     char *username, *password, *repository, **host_user_ptr;
+{
+    pam_handle_t *pamh=NULL;
+    int retval;
+    int rc = 0;
+
+    retval = pam_start("cvs", username, &conv, &pamh);
+
+    if (retval == PAM_SUCCESS)
+	retval = pam_set_item(pamh, PAM_AUTHTOK, password);
+
+    if (retval == PAM_SUCCESS)
+	retval = pam_authenticate(pamh, 0);    /* is user really user? */
+
+    if (retval == PAM_SUCCESS)
+	retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
+
+    /* This is where we have been authorized or not. */
+
+    switch(retval)
+    {
+	case PAM_SUCCESS:
+	    *host_user_ptr = xstrdup(username);
+	    rc = 1;
+	    break;
+	case PAM_AUTH_ERR:
+	    syslog (LOG_DAEMON | LOG_ERR,
+		    "some pam function failed: %s ",
+		    pam_strerror(pamh, retval));
+	    *host_user_ptr = NULL;
+	    rc = 2;
+	    break;
+	default:
+	    syslog (LOG_DAEMON | LOG_ERR,
+		    "some pam function failed: %s ",
+		    pam_strerror(pamh, retval));
+	    *host_user_ptr = NULL;
+	    rc = 0;
+	    break;
+    }
+    
+    if (pam_end(pamh, retval) != PAM_SUCCESS) {     /* close PAM */
+	pamh = NULL;
+	fprintf(stderr, "failed to release authenticator\n");
+    }
 
+    return rc;       /* indicate success */
+}
+#endif /* HAVE_PAM */
 
 /* Return a hosting username if password matches, else NULL. */
 static char *
@@ -5639,6 +5705,26 @@ check_password (username, password, repo
 	error_exit ();
     }
 
+
+#ifdef HAVE_PAM
+	rc = check_pam_password (username, password, repository,
+				 &host_user);
+	if (rc == 2)
+	{
+		syslog (LOG_NOTICE,
+			"pam auth failed for %s", username);
+		return NULL;
+	}
+
+	/* else */
+	
+	if (rc == 1)
+	{
+	    /* host_user already set by reference, so just return. */
+	    goto handle_return;
+	}
+#else /* HAVE_PAM */
+
     /* No cvs password found, so try /etc/passwd. */
 
 #ifdef HAVE_GETSPNAM
@@ -5714,6 +5800,7 @@ error 0 %s: no such user\n", username);
     syslog (LOG_AUTHPRIV | LOG_NOTICE,
 	    "login refused for %s: user has no password", username);
 #endif
+#endif /* HAVE_PAM */
 
 handle_return:
     if (host_user)
Index: gnu/usr.bin/cvs/cvs/Makefile
===================================================================
RCS file: /home/ncvs/src/gnu/usr.bin/cvs/cvs/Makefile,v
retrieving revision 1.48
diff -u -p -r1.48 Makefile
--- gnu/usr.bin/cvs/cvs/Makefile	6 Aug 2004 07:27:03 -0000	1.48
+++ gnu/usr.bin/cvs/cvs/Makefile	5 Jan 2005 18:25:50 -0000
@@ -31,7 +31,7 @@ CFLAGS+= -I${.CURDIR} -I../lib -DHAVE_CO
 	 -I${CVSDIR}/lib -I${CVSDIR}/diff -I.
 
 DPADD=	${LIBCVS} ${LIBDIFF} ${LIBGNUREGEX} ${LIBMD} ${LIBCRYPT} ${LIBZ}
-LDADD=	${LIBCVS} ${LIBDIFF} -lgnuregex -lmd -lcrypt -lz
+LDADD=	${LIBCVS} ${LIBDIFF} -lgnuregex -lmd -lcrypt -lz -lpam
 
 .if !defined(NO_KERBEROS) && !defined(NO_OPENSSL) && !defined(NOCRYPT)
 CFLAGS+= -DHAVE_GSSAPI -DHAVE_GSSAPI_H -DENCRYPTION


	


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list