about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2009-02-18 10:38:51 +0000
committerEelco Dolstra <eelco.dolstra@logicblox.com>2009-02-18 10:38:51 +0000
commit1fadce397e5f14cb5197d4ebe12d64054b275b80 (patch)
treeb39955893cd34660ed9f266064cf1cc07e35af47
parent722c3546af2927e0da89082fc7d49f5dd47aa70b (diff)
* slim updated to 1.3.1. This version has PAM support built-in, but it has
  a bug that prevents logins when using pam_unix2.  So I've fixed it.

svn path=/nixpkgs/trunk/; revision=14108
-rw-r--r--pkgs/applications/display-managers/slim/default.nix26
-rw-r--r--pkgs/applications/display-managers/slim/pam.patch446
2 files changed, 100 insertions, 372 deletions
diff --git a/pkgs/applications/display-managers/slim/default.nix b/pkgs/applications/display-managers/slim/default.nix
index 5b711111c9173..7ce261fec294c 100644
--- a/pkgs/applications/display-managers/slim/default.nix
+++ b/pkgs/applications/display-managers/slim/default.nix
@@ -1,25 +1,33 @@
 {stdenv, fetchurl, x11, libjpeg, libpng, libXmu, freetype, pam}:
 
-stdenv.mkDerivation {
-  name = "slim-1.2.6";
+stdenv.mkDerivation rec {
+  name = "slim-1.3.1";
+
   src = fetchurl {
-    url = http://download.berlios.de/slim/slim-1.2.6.tar.gz;
-    sha256 = "0plcmm955rnv67sx67ka6dccanr4rfzwzvsj6lnr8kqdip4522jg";
+    url = "http://download.berlios.de/slim/${name}.tar.gz";
+    sha256 = "0xqgzvg6h1bd29140mcgg9r16vcmskz7zmym7i7jlz7x9c1a9mxc";
   };
+
   patches = [
     # Allow the paths of the configuration file and theme directory to
     # be set at runtime.
     ./runtime-paths.patch
-    # PAM support from
-    # http://developer.berlios.de/patch/?func=detailpatch&patch_id=1979&group_id=2663
+
+    # Fix a bug in slim's PAM support: the "resp" argument to the
+    # conversation function is a pointer to a pointer to an array of
+    # pam_response structures, not a pointer to an array of pointers to
+    # pam_response structures.  Of course C can't tell the difference...
     ./pam.patch
   ];
+
   buildInputs = [x11 libjpeg libpng libXmu freetype pam];
+
   NIX_CFLAGS_COMPILE = "-I${freetype}/include/freetype2";
-  preBuild = "
+
+  preBuild = ''
     substituteInPlace Makefile --replace /usr /no-such-path
-    makeFlagsArray=(CC=gcc CXX=g++ PREFIX=$out MANDIR=$out/share/man CFGDIR=$out/etc)
-  ";
+    makeFlagsArray=(CC=gcc CXX=g++ PREFIX=$out MANDIR=$out/share/man CFGDIR=$out/etc USE_PAM=1)
+  '';
 
   meta = {
     homepage = http://slim.berlios.de;
diff --git a/pkgs/applications/display-managers/slim/pam.patch b/pkgs/applications/display-managers/slim/pam.patch
index 68b86f51ba566..2163d20a5e324 100644
--- a/pkgs/applications/display-managers/slim/pam.patch
+++ b/pkgs/applications/display-managers/slim/pam.patch
@@ -1,369 +1,89 @@
-diff -rc slim-1.2.6-orig/app.cpp slim-1.2.6/app.cpp
-*** slim-1.2.6-orig/app.cpp	2006-09-15 23:00:37.000000000 +0200
---- slim-1.2.6/app.cpp	2007-06-05 12:45:58.000000000 +0200
+diff -rc slim-1.3.1-orig/app.cpp slim-1.3.1/app.cpp
+*** slim-1.3.1-orig/app.cpp	2008-09-26 02:54:15.000000000 +0200
+--- slim-1.3.1/app.cpp	2009-02-17 19:50:06.000000000 +0100
 ***************
-*** 25,30 ****
---- 25,68 ----
-  #include "app.h"
-  #include "numlock.h"
-  
-+ #ifdef USE_PAM
-+ #include <security/pam_appl.h>
-+ #include <security/pam_misc.h>
-+ #include <string>
-+ 
-+ pam_handle_t* pamh;
-+ char const* PAM_service = "slim"; // <----- Change this, if the patch gets accepted upstream
-+ string password;
-+ 
-+ int conv(int num_msg, const struct pam_message **msg,
-+          struct pam_response **resp, void *appdata_ptr){
-+     *resp = (struct pam_response *) calloc(num_msg, sizeof(struct pam_response));
-+     for (int i=0; i<num_msg; i++){
-+         resp[i]->resp_retcode=0;
-+         switch(msg[i]->msg_style){
-+             case PAM_PROMPT_ECHO_ON:
-+                 // We assume PAM is asking for the username
-+ 				// As we should have given that already, this should never happen
-+ 				cerr << APPNAME << ": PAM send an unexpected PAM_PROMPT_ECHO_ON" << endl;
-+ 				cerr << APPNAME << ": " << msg[i]->msg << endl;
-+                 break;
-+ 
-+             case PAM_PROMPT_ECHO_OFF:
-+                 // We assume PAM is asking for the password
-+                 resp[i]->resp=x_strdup(password.c_str());
-+                 break;
-+ 
-+             case PAM_ERROR_MSG:
-+             case PAM_TEXT_INFO:
-+                 // We simply right these to the log
-+                 // TODO: Maybe we should simply ignore them
-+                 cerr << APPNAME << ": " << msg[i]->msg << endl;
-+                 break;
-+         }
-+     }
-+     return PAM_SUCCESS;
-+ }
-+ #endif
-  
-  extern App* LoginApp;
-  
+*** 41,48 ****
+      Panel* panel = *static_cast<Panel**>(appdata_ptr);
+      int result = PAM_SUCCESS;
+      for (int i=0; i<num_msg; i++){
+!         resp[i]->resp=0;
+!         resp[i]->resp_retcode=0;
+          switch(msg[i]->msg_style){
+              case PAM_PROMPT_ECHO_ON:
+                  // We assume PAM is asking for the username
+--- 41,48 ----
+      Panel* panel = *static_cast<Panel**>(appdata_ptr);
+      int result = PAM_SUCCESS;
+      for (int i=0; i<num_msg; i++){
+!         (*resp)[i].resp=0;
+!         (*resp)[i].resp_retcode=0;
+          switch(msg[i]->msg_style){
+              case PAM_PROMPT_ECHO_ON:
+                  // We assume PAM is asking for the username
 ***************
-*** 133,138 ****
---- 171,209 ----
-          }
-      }
-  
-+ #ifdef USE_PAM
-+     int last_result;
-+     struct pam_conv pam_conversation = {
-+         conv,
-+         NULL
-+     };
-+ 
-+     // Start the PAM session
-+     if ((last_result=pam_start(PAM_service, NULL, &pam_conversation, &pamh))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+         exit(ERR_EXIT);
-+     }
-+ 
-+     // Setup some PAM items
-+     if ((last_result=pam_set_item(pamh, PAM_TTY, DisplayName))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+ 	pam_end(pamh, last_result);
-+         exit(ERR_EXIT);
-+     }
-+     char* pam_ruser = "root\0"; // <---- We already checked for this in the constructor
-+     if ((last_result=pam_set_item(pamh, PAM_RUSER, pam_ruser))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+ 	pam_end(pamh, last_result);
-+         exit(ERR_EXIT);
-+     }
-+     char* pam_rhost = "localhost\0"; // <---- This might not entirely correct
-+     if ((last_result=pam_set_item(pamh, PAM_RHOST, pam_rhost))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+ 	pam_end(pamh, last_result);
-+         exit(ERR_EXIT);
-+     }
-+ #endif
-+ 
-      bool loaded = false;
-      while (!loaded) {
-          themedir =  themebase + themeName;
+*** 51,63 ****
+                      case Panel::Suspend:
+                      case Panel::Halt:
+                      case Panel::Reboot:
+!                         resp[i]->resp=strdup("root");
+                          break;
+  
+                      case Panel::Console:
+                      case Panel::Exit:
+                      case Panel::Login:
+!                         resp[i]->resp=strdup(panel->GetName().c_str());
+                          break;
+                  }
+                  break;
+--- 51,63 ----
+                      case Panel::Suspend:
+                      case Panel::Halt:
+                      case Panel::Reboot:
+!                         (*resp)[i].resp=strdup("root");
+                          break;
+  
+                      case Panel::Console:
+                      case Panel::Exit:
+                      case Panel::Login:
+!                         (*resp)[i].resp=strdup(panel->GetName().c_str());
+                          break;
+                  }
+                  break;
 ***************
-*** 313,318 ****
---- 384,421 ----
-      struct passwd *pw;
-      pid_t pid;
-  
-+ #ifdef USE_PAM
-+      int last_result;
-+      switch ((last_result=pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT))){
-+         case PAM_SUCCESS:
-+             // Credentials was established successfully
-+             break;
-+ 
-+         case PAM_CRED_ERR:
-+         case PAM_CRED_EXPIRED:
-+         case PAM_CRED_UNAVAIL:
-+         case PAM_USER_UNKNOWN:
-+             // Credentials couldn't be established
-+             cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+             return;
-+ 
-+         case PAM_BUF_ERR:
-+         case PAM_SYSTEM_ERR:
-+         default:
-+             // System error -> bail out!
-+             last_result=pam_setcred(pamh, PAM_DELETE_CRED);
-+             pam_end(pamh, last_result);
-+             exit(ERR_EXIT);
-+     }
-+ 
-+     if ((last_result=pam_open_session(pamh, PAM_SILENT))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+     	pam_setcred(pamh, PAM_DELETE_CRED);
-+ 	// TODO: Do we need more serious actions?
-+         return;
-+     }
-+ #endif
-+ 
-      pw = LoginPanel->GetInput()->GetPasswdStruct();
-      if(pw == 0)
-          return;
-***************
-*** 320,325 ****
---- 423,433 ----
-      // Create new process
-      pid = fork();
-      if(pid == 0) {
-+ #ifdef USE_PAM
-+         // Close the child's copy of the PAM-handle
-+         pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT);
-+ #endif
-+ 
-          // Login process starts here
-          SwitchUser Su(pw, cfg, DisplayName);
-          string session = LoginPanel->getSession();
+*** 73,79 ****
+  
+                      default:
+                          panel->EventHandler(Panel::Get_Passwd);
+!                         resp[i]->resp=strdup(panel->GetPasswd().c_str());
+                          break;
+                  }
+                  break;
+--- 73,79 ----
+  
+                      default:
+                          panel->EventHandler(Panel::Get_Passwd);
+!                         (*resp)[i].resp=strdup(panel->GetPasswd().c_str());
+                          break;
+                  }
+                  break;
 ***************
-*** 355,361 ****
-          }
+*** 89,97 ****
       }
-  
-!     // Close all clients
-      KillAllClients(False);
-      KillAllClients(True);
-  
---- 463,477 ----
-          }
+      if (result!=PAM_SUCCESS){
+          for (int i=0; i<num_msg; i++){
+!             if (resp[i]->resp==0) continue;
+!             free(resp[i]->resp);
+!             resp[i]->resp=0;
+          };
+          free(*resp);
+          *resp=0;
+--- 89,97 ----
       }
-  
-! #ifdef USE_PAM
-!     if ((last_result=pam_close_session(pamh, PAM_SILENT))!=PAM_SUCCESS){
-!         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-!     	last_result=pam_setcred(pamh, PAM_DELETE_CRED);	
-! 	// TODO: Do we need more serious actions?
-!     }
-! #endif
-! 
-! // Close all clients
-      KillAllClients(False);
-      KillAllClients(True);
-  
-***************
-*** 382,387 ****
---- 498,510 ----
-      // Stop alarm clock
-      alarm(0);
-  
-+ #ifdef USE_PAM
-+     int last_result;
-+     if ((last_result=pam_end(pamh, PAM_SUCCESS))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+     }
-+ #endif
-+ 
-      // Write message
-      LoginPanel->Message((char*)cfg->getOption("reboot_msg").c_str());
-      sleep(3);
-***************
-*** 398,403 ****
---- 521,533 ----
-      // Stop alarm clock
-      alarm(0);
-  
-+ #ifdef USE_PAM
-+     int last_result;
-+     if ((last_result=pam_end(pamh, PAM_SUCCESS))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+     }
-+ #endif
-+ 
-      // Write message
-      LoginPanel->Message((char*)cfg->getOption("shutdown_msg").c_str());
-      sleep(3);
-***************
-*** 433,438 ****
---- 563,575 ----
-  
-  
-  void App::Exit() {
-+ #ifdef USE_PAM
-+     int last_result;
-+     if ((last_result=pam_end(pamh, PAM_SUCCESS))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+     }
-+ #endif
-+ 
-      if (testing) {
-          char* testmsg = "This is a test message :-)";
-          LoginPanel->Message(testmsg);
-***************
-*** 453,458 ****
---- 590,602 ----
-  }
-  
-  void App::RestartServer() {
-+ #ifdef USE_PAM
-+     int last_result;
-+     if ((last_result=pam_end(pamh, PAM_SUCCESS))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+     }
-+ #endif
-+ 
-          StopServer(); 
-          RemoveLock();
-          Run();
-Only in slim-1.2.6/: app.cpp~
-diff -rc slim-1.2.6-orig/input.cpp slim-1.2.6/input.cpp
-*** slim-1.2.6-orig/input.cpp	2006-09-15 23:00:37.000000000 +0200
---- slim-1.2.6/input.cpp	2007-06-05 12:45:58.000000000 +0200
-***************
-*** 12,17 ****
---- 12,25 ----
-  #include "input.h"
-  #include <cstdlib>
-  
-+ #ifdef USE_PAM
-+ #include <security/pam_appl.h>
-+ #include <string>
-+ 
-+ extern pam_handle_t* pamh;
-+ extern string password;
-+ #endif
-+ 
-  Input::Input(Cfg* c) {
-      NameBuffer[0] = '\0';
-      PasswdBuffer[0] = '\0';
-***************
-*** 100,106 ****
---- 108,126 ----
-  
-  
-  struct passwd* Input::GetPasswdStruct() {
-+ #ifdef USE_PAM
-+     int last_result;
-+     char* username=NULL;
-+ 
-+     if ((last_result=pam_get_item(pamh, PAM_USER, (const void**)&username))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+         pam_end(pamh, last_result);
-+         exit(ERR_EXIT);
-+     }
-+     struct passwd* pw = getpwnam(username);
-+ #else
-      struct passwd* pw = getpwnam(NameBuffer);
-+ #endif
-      endpwent();
-      if (pw->pw_shell[0] == '\0') {
-          setusershell();
-***************
-*** 183,188 ****
---- 203,240 ----
-  }
-  
-  int Input::Correct() {
-+ #ifdef USE_PAM
-+     int last_result;
-+ 
-+     // Store the password in global variables accessible
-+     // by the PAM-conversation function
-+     password=PasswdBuffer;
-+ 
-+ 	// Set the username in PAM
-+     if ((last_result=pam_set_item(pamh, PAM_USER, NameBuffer))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+         pam_end(pamh, last_result);
-+         exit(ERR_EXIT);
-+     }    
-+ 
-+     // Authenticate the user
-+     if ((last_result=pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+         if (last_result==PAM_ABORT){
-+             pam_end(pamh, last_result);
-+             exit(ERR_EXIT);
-+         }
-+ 	return 0;
-+     }
-+ 
-+     // Check the health of the account
-+     if ((last_result=pam_acct_mgmt(pamh, PAM_SILENT))!=PAM_SUCCESS){
-+         cerr << APPNAME << ": " << pam_strerror(pamh, last_result) << endl;
-+ 	return 0;
-+     }
-+ 
-+     return 1;
-+ #else
-      char *unencrypted, *encrypted, *correct;
-      struct passwd *pw;
-  
-***************
-*** 197,203 ****
-      if(sp)
-  	correct = sp->sp_pwdp;
-      else
-! #endif
-  	correct = pw->pw_passwd;
-  
-      if(correct == 0 || correct[0] == '\0')
---- 249,255 ----
-      if(sp)
-  	correct = sp->sp_pwdp;
-      else
-! #endif        /* HAVE_SHADOW */
-  	correct = pw->pw_passwd;
-  
-      if(correct == 0 || correct[0] == '\0')
-***************
-*** 207,212 ****
---- 259,265 ----
-      encrypted = crypt(unencrypted, correct);
-      memset(unencrypted, 0, strlen (unencrypted));
-      return (strcmp(encrypted, correct) == 0);
-+ #endif        /* USE_PAM */
-  }
-  
-  
-diff -rc slim-1.2.6-orig/Makefile slim-1.2.6/Makefile
-*** slim-1.2.6-orig/Makefile	2006-09-15 23:00:37.000000000 +0200
---- slim-1.2.6/Makefile	2007-06-05 12:45:58.000000000 +0200
-***************
-*** 6,13 ****
-  CXX=/usr/bin/g++
-  CC=/usr/bin/gcc
-  CFLAGS=-I. -I/usr/X11R6/include -I/usr/include/freetype2 -I/usr/include/freetype2/config -I/usr/include/libpng12 -I/usr/include
-! LDFLAGS=-L/usr/X11R6/lib -lXft -lX11 -lfreetype -lXrender -lfontconfig -lpng12 -lz -lm -lcrypt -lXmu -lpng -ljpeg
-! CUSTOM=-DHAVE_SHADOW
-  PREFIX=/usr
-  CFGDIR=/etc
-  MANDIR=/usr/man
---- 6,13 ----
-  CXX=/usr/bin/g++
-  CC=/usr/bin/gcc
-  CFLAGS=-I. -I/usr/X11R6/include -I/usr/include/freetype2 -I/usr/include/freetype2/config -I/usr/include/libpng12 -I/usr/include
-! LDFLAGS=-L/usr/X11R6/lib -lXft -lX11 -lfreetype -lXrender -lfontconfig -lpng12 -lz -lm -lcrypt -lXmu -lpng -ljpeg -lpam
-! CUSTOM=-DHAVE_SHADOW -DUSE_PAM
-  PREFIX=/usr
-  CFGDIR=/etc
-  MANDIR=/usr/man
+      if (result!=PAM_SUCCESS){
+          for (int i=0; i<num_msg; i++){
+!             if ((*resp)[i].resp==0) continue;
+!             free((*resp)[i].resp);
+!             (*resp)[i].resp=0;
+          };
+          free(*resp);
+          *resp=0;