[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    PATCH: PAM service mess cleanup
From:       Oswald Buddenhagen <ob6 () inf ! tu-dresden ! de>
Date:       2001-07-13 23:22:57
[Download RAW message or body]

hi,

this patch does this:
- unify pam service selection -> all "kde" by default. the services
  for kdm, kcheckpass and kscreensaver can be changed with configure 
  args
- attempt to install missing pam service definitions automatically by
  duplicating the "login" service. this is skipped, if a DESTDIR is
  specified
- updated readme.pam
- pam handling fixes in kcheckpass
- kcheckpass now expects directly a service name instead of a "caller".
  this makes it independent from kscreensaver. i don't consider this a
  security hole, as it does not grant any additional priviledges to the
  calling user - and this should not change.

if nobody objects, i'll commit saturday around 16:00 gmt.

greetings

-- 
Hi! I'm a .signature virus! Copy me into your ~/.signature, please!
--
Nothing is fool-proof to a sufficiently talented fool.


Index: Makefile.am
===================================================================
RCS file: /home/kde/kdebase/Makefile.am,v
retrieving revision 1.99
diff -u -r1.99 Makefile.am
--- Makefile.am	2001/01/17 04:04:19	1.99
+++ Makefile.am	2001/07/13 22:59:44
@@ -28,7 +28,7 @@
 $(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in \
$(top_srcdir)/admin/libtool.m4.in  @cd $(top_srcdir) && cat admin/acinclude.m4.in \
admin/libtool.m4.in > acinclude.m4  
-EXTRA_DIST = admin bsd-port debian kdebase.spec.in README.pam kde.pamd \
kscreensaver.pamd +EXTRA_DIST = admin bsd-port debian kdebase.spec.in README.pam \
kde.pamd kscreensaver.pamd mkpamserv  
 dist-hook:
 	cd $(top_distdir) && perl $(top_srcdir)/admin/am_edit -padmin
Index: README.pam
===================================================================
RCS file: /home/kde/kdebase/README.pam,v
retrieving revision 2.3
diff -u -r2.3 README.pam
--- README.pam	2001/01/30 23:09:27	2.3
+++ README.pam	2001/07/13 22:59:44
@@ -1,83 +1,47 @@
 KDE can be configured to support the PAM ("Pluggable Authentication 
-Module") system for password checking by the display manager kdm and 
+Modules") system for password checking by the display manager kdm and 
 by the screen saver kscreensaver (for unlocking the display).
 
 PAM is a flexible application-transparent configurable user-authentication 
-system found on FreeBSD, Solaris, and Linux, where it is most commonly
-found on RedHat Linux systems.  (There may be ports to other unices too).
+system found on FreeBSD, Solaris, and Linux (and maybe other unixes).
 
 Information about PAM may be found on its homepage
       http://www.kernel.org/pub/linux/libs/pam/
 (Despite the location, this information is NOT Linux-specific.)
 
+
 Known Solaris Issues:
 --------------------
 
 For compiling PAM support on Solaris,  PAM_MESSAGE_NONCONST must
 be defined.   This should now be handled automatically by the 
-autoconf script:  just use ./configure --with-pam  . 
-
---------------------
+configure script.
 
-If both PAM and shadow passwords are used on your system, do *NOT*
-configure KDE for shadow password support: configure it for PAM, and PAM
-will take care of everything.
 
 Using PAM
 ---------
 
-By default, use of PAM is DISABLED in KDE.  To enable it, use
-./configure --with-pam
+By default, PAM is automatically used, if it is found. Use
+./configure --without-pam  to disable it.
 
-This form configures KDE to use the default PAM services "xdm",
-(which is likely to be present and properly configured on most
-PAM-aware systems) and "kscreensaver" (for password checking,
-when unlocking  a locked screen).
-
- SINCE A PAM SERVICE "kscreensaver" IS NOT PRESENT BY DEFAULT, 
-IT IS IMPORTANT THAT YOU CONFIGURE THIS PAM SERVICE.  
-(An example configuration file "kscreensaver.pamd" is provided  in 
-the top directory of the kdebase sources, but be aware that it may 
-not be appropriate for your particular PAM version.) 
-If the "kscreensaver" service is not provided, you will 
-NOT be able to unlock a locked screen ...
-
-If the PAM service "xdm" is not present, or if you wish to customize the
-PAM configuration for kdm, use:
-
-./configure --with-pam=<pam_service_name> 
-
-where <pam_service_name> is the name of the PAM service you wish to use.  
-(Note that the required pam service name "kscreensaver" will NOT be changed by
-this configuration option, only the service name used by kdm is changed).
-
-(Exception: --with-pam=yes is equivalent to --with-pam, and --with-pam=no
-is equivalent to  --without-pam,  which is the default). 
-
-You must then (as root) configure this new PAM service, if it has not
-already been configured.  PAM services are generally configured by lines
-beginning with the entry <pam_service_name> in a file /etc/pam.conf or, on
-some systems, in individual files /etc/pam.d/<pam_service_name>.
-
-If your system uses /etc/pam.d for configuration you may wish to use
-
-./configure -with-pam=kde
-
-so KDE uses a PAM service called "kde", and make a symlink
-ln -s ./xdm /etc/pam.d/kde,  (assuming xdm is PAM-configured).
-
-You can later customize your system by creating your own /etc/pam.d/kde.  
-A sample (for RedHat Linux 5.x) is provided in kdebase/kde.pamd
-
-PAM writes entries to the system log identified by the PAM service name;
-this method has the advantage that such entries will identify the PAM
-service involved as "kde" rather than "xdm", which is presumably not
-running.
-
-If there is ever any doubt about which PAM service name kdebase was
-compiled with, it can be determined by examining the PAM-generated entries
-in the system log associated with kdm logins or kscreensaver
-authentication failures....
+If PAM is found, KDE usually uses the PAM service "kde". You may
+override it for all KDE programs by using --with-pam=<service> and/or
+individually by using --with-<prog>-pam=<service>, where <prog> is
+one of kdm, kcp and kss (for kdm, kcheckpass and kscreensaver).
+
+"make install" will attempt to create suitable service definitions; either
+by putting files into /etc/pam.d/ or by adding text to /etc/pam.conf. The
+services are just copies of the "login" service. 
+You may want to edit these definitions to meet your needs.
+There are also two example service definitions in this directory -
+kde.pamd and kscreensaver.pamd - but don't just copy them!
+If the services are misconfigured, you will NOT be able to login via KDM
+and/or unlock a locked screen!
+
+If there is ever any doubt about which PAM service a program was
+compiled with, it can be determined by examining the PAM-generated 
+entries in the system log associated with kdm logins or kscreensaver
+authentication failures.
 
 
 PAM configuration files have four types of entries for each service:
@@ -104,5 +68,6 @@
 continue working. They may also renew tokens etc., where supported.
 See the Linux PAM Administrators guide, which is part of the PAM
 distribution, for more details. 
+
 
 $Id: README.pam,v 2.3 2001/01/30 23:09:27 esken Exp $
Index: configure.in.in
===================================================================
RCS file: /home/kde/kdebase/configure.in.in,v
retrieving revision 1.35
diff -u -r1.35 configure.in.in
--- configure.in.in	2001/06/21 08:46:44	1.35
+++ configure.in.in	2001/07/13 22:59:44
@@ -3,6 +3,10 @@
 dnl PAM, shadow passwords, libcrypt
 KDE_PASSWDLIBS
 
+DEF_PAM_SERVICE(kdm, kdm, KDM)
+DEF_PAM_SERVICE(kcp, kcheckpass, KCHECKPASS)
+DEF_PAM_SERVICE(kss, kscreensaver, KSCREENSAVER)
+
 dnl Image readers/writers
 KDE_CHECK_KIMGIO
 
Index: admin/acinclude.m4.in
===================================================================
RCS file: /home/kde/kde-common/admin/acinclude.m4.in,v
retrieving revision 2.124
diff -u -r2.124 acinclude.m4.in
--- admin/acinclude.m4.in	2001/06/23 21:56:04	2.124
+++ admin/acinclude.m4.in	2001/07/13 22:59:49
@@ -2788,19 +2788,22 @@
     [  --with-pam[=ARG]        enable support for PAM: ARG=[yes|no|service name]],
     [ if test "x$withval" = "xyes"; then
         use_pam=yes
+        pam_service=kde
       elif test "x$withval" = "xno"; then
         use_pam=no
       else
         use_pam=yes
-        pam_service="$withval"
+        pam_service=$withval
       fi
       ac_cv_path_pam="use_pam=$use_pam pam_service=$pam_service"
     ], [
       AC_CACHE_VAL(ac_cv_path_pam,
         [ use_pam=no
           AC_CHECK_LIB(pam, pam_start,
-            [ AC_CHECK_HEADER(security/pam_appl.h, use_pam=yes) ], , $LIBDL)
-	  ac_cv_path_pam="use_pam=$use_pam pam_service="
+            [ AC_CHECK_HEADER(security/pam_appl.h, 
+               	[ use_pam=yes
+                  pam_service=kde ]) ], , $LIBDL)
+	  ac_cv_path_pam="use_pam=$use_pam pam_service=$pam_service"
 	])
     ])
   eval "$ac_cv_path_pam"
@@ -2811,7 +2814,7 @@
     PAMLIBS=""
   else
     AC_MSG_RESULT(yes)
-    AC_DEFINE(HAVE_PAM, 1, [Defines if you have PAM (Pluggable Authentication \
Modules); Redhat-Users!]) +    AC_DEFINE(HAVE_PAM, 1, [Defines if you have PAM \
(Pluggable Authentication Modules)])  PAMLIBS="$PAM_MISC_LIB -lpam $LIBDL"
 
     dnl test whether struct pam_message is const (Linux) or not (Sun)
@@ -2823,16 +2826,31 @@
                         AC_DEFINE(PAM_MESSAGE_NONCONST, 1, [Define if your PAM \
support takes non-const arguments (Solaris)])]  )],
       [AC_MSG_RESULT([not found - assume const, Linux-type PAM])])
-
-    if test "x$pam_service" = x; then
-      AC_MSG_RESULT(["Default PAM service name will be used."])
-    else
-      AC_DEFINE_UNQUOTED(KDE_PAM_SERVICE, "$pam_service", [Define to change the \
                default name of the PAM service used by KDE])
-      AC_MSG_RESULT([PAM service name will be: $pam_service])
-    fi
   fi
 
   AC_SUBST(PAMLIBS)
+])
+
+dnl DEF_PAM_SERVICE(arg name, full name, define name)
+AC_DEFUN(DEF_PAM_SERVICE, [
+  AC_ARG_WITH($1-pam,
+    [  --with-$1-pam=[val]    override PAM service from --with-pam for $2],
+    [ if test "x$use_pam" = xyes; then
+	$3_PAM_SERVICE="$withval"
+      else
+	AC_MSG_ERROR([Cannot use use --with-$1-pam, as no PAM was detected.
+You may want to enforce it by using --with-pam.])
+      fi
+    ], 
+    [ if test "x$use_pam" = xyes; then
+	$3_PAM_SERVICE="$pam_service"
+      fi
+    ])
+    if test -n "$$3_PAM_SERVICE"; then
+      AC_MSG_RESULT([The PAM service used by $2 will be $$3_PAM_SERVICE])
+      AC_DEFINE_UNQUOTED($3_PAM_SERVICE, "$$3_PAM_SERVICE", [The PAM service to be \
used by $2]) +    fi
+    AC_SUBST($3_PAM_SERVICE)
 ])
 
 AC_DEFUN(KDE_SHADOWPASSWD, [
Index: kcheckpass/Makefile.am
===================================================================
RCS file: /home/kde/kdebase/kcheckpass/Makefile.am,v
retrieving revision 1.18
diff -u -r1.18 Makefile.am
--- kcheckpass/Makefile.am	2001/06/14 07:44:15	1.18
+++ kcheckpass/Makefile.am	2001/07/13 22:59:50
@@ -16,6 +16,8 @@
 
 noinst_HEADERS = kcheckpass.h
 
-EXTRA_DIST = README
+install-data-local:
+	@test -n "$(DESTDIR)" || $(top_srcdir)/mkpamserv @KCHECKPASS_PAM_SERVICE@
 
+EXTRA_DIST = README
 
Index: kcheckpass/checkpass_pam.c
===================================================================
RCS file: /home/kde/kdebase/kcheckpass/checkpass_pam.c,v
retrieving revision 1.9
diff -u -r1.9 checkpass_pam.c
--- kcheckpass/checkpass_pam.c	2001/01/12 22:12:08	1.9
+++ kcheckpass/checkpass_pam.c	2001/07/13 22:59:50
@@ -28,16 +28,6 @@
 #include <string.h>
 #include <security/pam_appl.h>
 
-#ifdef KDE_PAM_SERVICE
-#define KDE_PAM KDE_PAM_SERVICE
-#else
-#ifdef __FreeBSD__
-#define KDE_PAM "login"  /* default PAM service used by kcheckpass */
-#else
-#define KDE_PAM "xdm"  /* default PAM service used by kcheckpass */
-#endif
-#endif
-
 static const char *PAM_username;
 static const char *PAM_password;
 
@@ -52,46 +42,58 @@
 	  struct pam_response **resp,
 	  void *appdata_ptr)
 {
-  int             count = 0, replies = 0;
-  struct pam_response *repl = NULL;
-  int             size = sizeof(struct pam_response);
-
-#define GET_MEM \
-	if (!(repl = (realloc(repl, size)))) \
-  		return PAM_CONV_ERR; \
-	size += sizeof(struct pam_response)
-#define COPY_STRING(s) (s) ? strdup(s) : NULL
+  int             count;
+  struct pam_response *repl;
+
+  if (!(repl = calloc(num_msg, sizeof(struct pam_response))))
+    return PAM_CONV_ERR;
 
-  for (count = 0; count < num_msg; count++) {
+  for (count = 0; count < num_msg; count++)
     switch (msg[count]->msg_style) {
     case PAM_PROMPT_ECHO_ON:
-      GET_MEM;
-      repl[replies].resp_retcode = PAM_SUCCESS;
-      repl[replies++].resp = COPY_STRING(PAM_username);
+      if (PAM_username)
+	if (!(repl[count].resp = strdup(PAM_username)))
+	  goto conv_err;
+      repl[count].resp_retcode = PAM_SUCCESS;
       /* PAM frees resp */
       break;
     case PAM_PROMPT_ECHO_OFF:
-      GET_MEM;
-      repl[replies].resp_retcode = PAM_SUCCESS;
-      repl[replies++].resp = COPY_STRING(PAM_password);
+      if (PAM_password)
+        if (!(repl[count].resp = strdup(PAM_password)))
+	  goto conv_err;
+      repl[count].resp_retcode = PAM_SUCCESS;
       /* PAM frees resp */
       break;
     case PAM_TEXT_INFO:
-      message("unexpected message from PAM: %s\n",
-	      msg[count]->msg);
+      message("unexpected message from PAM: %s\n", msg[count]->msg);
       break;
     case PAM_ERROR_MSG:
+      message("unexpected error from PAM: %s\n", msg[count]->msg);
+      break;
     default:
       /* Must be an error of some sort... */
-      message("unexpected error from PAM: %s\n",
-	     msg[count]->msg);
-      free(repl);
-      return PAM_CONV_ERR;
+      goto conv_err;
     }
-  }
-  if (repl)
-    *resp = repl;
+  *resp = repl;
   return PAM_SUCCESS;
+
+ conv_err:
+  for (; count >= 0; count--)
+    if (repl[count].resp) {
+      switch (msg[count]->msg_style) {
+      case PAM_PROMPT_ECHO_OFF:
+	memset (repl[count].resp, 0, strlen(repl[count].resp));
+	/* fall through */
+      case PAM_ERROR_MSG:
+      case PAM_TEXT_INFO:
+      case PAM_PROMPT_ECHO_ON:
+	free(repl[count].resp);
+	break;
+      }
+      repl[count].resp = 0;
+    }
+  free(repl);
+  return PAM_CONV_ERR;
 }
 
 static struct pam_conv PAM_conversation = {
@@ -104,31 +106,39 @@
 {
   pam_handle_t	*pamh;
   int		pam_error;
+
+  const char *tty;
+  const char *kde_pam = KCHECKPASS_PAM_SERVICE;
 
-  const char *tty = ":0.0";
-  char kde_pam[20] = KDE_PAM;
   PAM_username = login;
   PAM_password = passwd;
 
-  /* If the caller is kscreensaver then use the corresponding pam module */
-  if ( ! strncmp(caller,"kscreensaver",19)  ) {
-      strncpy(kde_pam,"kscreensaver",19);
-  }
-
+  if (caller[0])
+    kde_pam = caller;
   pam_error = pam_start(kde_pam, login, &PAM_conversation, &pamh);
+  if (pam_error != PAM_SUCCESS)
+    return 0;
+
+  tty = getenv ("DISPLAY");
+  if (!tty)
+    tty = ":0";
+  pam_error = pam_set_item (pamh, PAM_TTY, tty);
+  if (pam_error != PAM_SUCCESS) {
+    pam_end(pamh, pam_error);
+    return 0;
+  }
 
-  pam_error = pam_set_item (pamh, PAM_TTY, strdup(tty));
   pam_error = pam_authenticate(pamh, 0);
-  if (pam_error != PAM_SUCCESS
-      || (pam_error = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
+  if (pam_error != PAM_SUCCESS) {
     pam_end(pamh, pam_error);
     return 0;
   }
-  /* Set credentials (You need this e.g. for AFS */
+
+  /* Refresh credentials (Needed e.g. for AFS (timing out Kerberos tokens)) */
   pam_error = pam_setcred(pamh, PAM_REFRESH_CRED);
   if (pam_error != PAM_SUCCESS)  {
-      pam_end(pamh, pam_error);
-      return 0;
+    pam_end(pamh, pam_error);
+    return 0;
   }
 
   pam_end(pamh, PAM_SUCCESS);
Index: kdesktop/Makefile.am
===================================================================
RCS file: /home/kde/kdebase/kdesktop/Makefile.am,v
retrieving revision 1.66
diff -u -r1.66 Makefile.am
--- kdesktop/Makefile.am	2001/06/11 19:16:03	1.66
+++ kdesktop/Makefile.am	2001/07/13 22:59:50
@@ -47,3 +47,6 @@
 
 autostart_DATA = kdesktop.desktop
 autostartdir = $(prefix)/share/autostart
+
+install-data-local:
+	@test -n "$(DESTDIR)" || $(top_srcdir)/mkpamserv @KSCREENSAVER_PAM_SERVICE@
Index: kdesktop/lockeng.cc
===================================================================
RCS file: /home/kde/kdebase/kdesktop/lockeng.cc,v
retrieving revision 1.39
diff -u -r1.39 lockeng.cc
--- kdesktop/lockeng.cc	2001/06/25 01:47:54	1.39
+++ kdesktop/lockeng.cc	2001/07/13 22:59:51
@@ -6,6 +6,8 @@
 //
 
 
+#include <config.h>
+
 #include <stdlib.h>
 #include <qbitmap.h>
 #include <qtextstream.h>
@@ -23,8 +25,6 @@
 #include "lockeng.h"
 #include "lockeng.moc"
 
-#include <config.h>
-
 #ifdef HAVE_SETPRIORITY
 #include <sys/time.h>
 #include <sys/resource.h>
@@ -816,10 +816,10 @@
         mPassProc << kcp_binName;
 
 #ifdef ACCEPT_ENV
-        setenv("KDE_PAM_ACTION","kscreensaver",1);
+        setenv("KDE_PAM_ACTION", KSCREENSAVER_PAM_SERVICE, 1);
 #elif
 #ifdef ACCEPT_ARGS
-        mPassProc << "-c" << "kscreensaver";
+        mPassProc << "-c" << KSCREENSAVER_PAM_SERVICE;
 #endif
 #endif
 	bool ret = mPassProc.start(KProcess::NotifyOnExit, KProcess::Stdin);
Index: kdm/Makefile.am
===================================================================
RCS file: /home/kde/kdebase/kdm/Makefile.am,v
retrieving revision 1.71
diff -u -r1.71 Makefile.am
--- kdm/Makefile.am	2001/06/19 10:20:35	1.71
+++ kdm/Makefile.am	2001/07/13 22:59:51
@@ -3,3 +3,5 @@
 
 EXTRA_DIST = misc
 
+install-data-local:
+	@test -n "$(DESTDIR)" || $(top_srcdir)/mkpamserv @KDM_PAM_SERVICE@
Index: kdm/README
===================================================================
RCS file: /home/kde/kdebase/kdm/README,v
retrieving revision 2.8
diff -u -r2.8 README
--- kdm/README	2001/06/19 14:22:54	2.8
+++ kdm/README	2001/07/13 22:59:51
@@ -14,7 +14,10 @@
 You can change the configuration from the KDE Control Center. 
 You will find the Login Manager module in "System" -> "Login Manager".
 
+Have a look at README.pam in the kdebase top level directory if your
+system uses PAM.
 
+
 Running KDM from init
 ---------------------
 
Index: kdm/kfrontend/kdm_config.c
===================================================================
RCS file: /home/kde/kdebase/kdm/kfrontend/kdm_config.c,v
retrieving revision 1.10
diff -u -r1.10 kdm_config.c
--- kdm/kfrontend/kdm_config.c	2001/07/12 01:31:40	1.10
+++ kdm/kfrontend/kdm_config.c	2001/07/13 22:59:54
@@ -1026,13 +1026,7 @@
 static int cfgMapT[] = { GC_gGlobal, GC_gDisplay };
 static int cfgMap[] = { 0, 0 };
 
-Value pamservice = {
-#ifdef KDE_PAM_SERVICE
-    KDE_PAM_SERVICE, sizeof(KDE_PAM_SERVICE)
-#else
-    "kde", 4	/* XXX i don't like this ... should be "kdm" */
-#endif
-};
+Value pamservice = { KDM_PAM_SERVICE, sizeof(KDM_PAM_SERVICE) };
 
 int main(int argc, char **argv)
 {


>> Visit http://master.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic