1
0
Fork 1
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-03-06 23:31:34 +00:00

* 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
This commit is contained in:
Eelco Dolstra 2009-02-18 10:38:51 +00:00
parent 722c3546af
commit 1fadce397e
2 changed files with 102 additions and 374 deletions
pkgs/applications/display-managers/slim

View file

@ -1,25 +1,33 @@
{stdenv, fetchurl, x11, libjpeg, libpng, libXmu, freetype, pam}: {stdenv, fetchurl, x11, libjpeg, libpng, libXmu, freetype, pam}:
stdenv.mkDerivation { stdenv.mkDerivation rec {
name = "slim-1.2.6"; name = "slim-1.3.1";
src = fetchurl { src = fetchurl {
url = http://download.berlios.de/slim/slim-1.2.6.tar.gz; url = "http://download.berlios.de/slim/${name}.tar.gz";
sha256 = "0plcmm955rnv67sx67ka6dccanr4rfzwzvsj6lnr8kqdip4522jg"; sha256 = "0xqgzvg6h1bd29140mcgg9r16vcmskz7zmym7i7jlz7x9c1a9mxc";
}; };
patches = [ patches = [
# Allow the paths of the configuration file and theme directory to # Allow the paths of the configuration file and theme directory to
# be set at runtime. # be set at runtime.
./runtime-paths.patch ./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 ./pam.patch
]; ];
buildInputs = [x11 libjpeg libpng libXmu freetype pam]; buildInputs = [x11 libjpeg libpng libXmu freetype pam];
NIX_CFLAGS_COMPILE = "-I${freetype}/include/freetype2"; NIX_CFLAGS_COMPILE = "-I${freetype}/include/freetype2";
preBuild = "
preBuild = ''
substituteInPlace Makefile --replace /usr /no-such-path 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 = { meta = {
homepage = http://slim.berlios.de; homepage = http://slim.berlios.de;

View file

@ -1,369 +1,89 @@
diff -rc slim-1.2.6-orig/app.cpp slim-1.2.6/app.cpp diff -rc slim-1.3.1-orig/app.cpp slim-1.3.1/app.cpp
*** slim-1.2.6-orig/app.cpp 2006-09-15 23:00:37.000000000 +0200 *** slim-1.3.1-orig/app.cpp 2008-09-26 02:54:15.000000000 +0200
--- slim-1.2.6/app.cpp 2007-06-05 12:45:58.000000000 +0200 --- slim-1.3.1/app.cpp 2009-02-17 19:50:06.000000000 +0100
*************** ***************
*** 25,30 **** *** 41,48 ****
--- 25,68 ---- Panel* panel = *static_cast<Panel**>(appdata_ptr);
#include "app.h" int result = PAM_SUCCESS;
#include "numlock.h" for (int i=0; i<num_msg; i++){
! resp[i]->resp=0;
+ #ifdef USE_PAM ! resp[i]->resp_retcode=0;
+ #include <security/pam_appl.h> switch(msg[i]->msg_style){
+ #include <security/pam_misc.h> case PAM_PROMPT_ECHO_ON:
+ #include <string> // We assume PAM is asking for the username
+ --- 41,48 ----
+ pam_handle_t* pamh; Panel* panel = *static_cast<Panel**>(appdata_ptr);
+ char const* PAM_service = "slim"; // <----- Change this, if the patch gets accepted upstream int result = PAM_SUCCESS;
+ string password; for (int i=0; i<num_msg; i++){
+ ! (*resp)[i].resp=0;
+ int conv(int num_msg, const struct pam_message **msg, ! (*resp)[i].resp_retcode=0;
+ struct pam_response **resp, void *appdata_ptr){ switch(msg[i]->msg_style){
+ *resp = (struct pam_response *) calloc(num_msg, sizeof(struct pam_response)); case PAM_PROMPT_ECHO_ON:
+ for (int i=0; i<num_msg; i++){ // We assume PAM is asking for the username
+ 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;
*************** ***************
*** 133,138 **** *** 51,63 ****
--- 171,209 ---- 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;
***************
*** 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;
***************
*** 89,97 ****
} }
if (result!=PAM_SUCCESS){
+ #ifdef USE_PAM for (int i=0; i<num_msg; i++){
+ int last_result; ! if (resp[i]->resp==0) continue;
+ struct pam_conv pam_conversation = { ! free(resp[i]->resp);
+ conv, ! resp[i]->resp=0;
+ NULL };
+ }; free(*resp);
+ *resp=0;
+ // Start the PAM session --- 89,97 ----
+ 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;
***************
*** 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();
***************
*** 355,361 ****
}
} }
if (result!=PAM_SUCCESS){
! // Close all clients for (int i=0; i<num_msg; i++){
KillAllClients(False); ! if ((*resp)[i].resp==0) continue;
KillAllClients(True); ! free((*resp)[i].resp);
! (*resp)[i].resp=0;
--- 463,477 ---- };
} free(*resp);
} *resp=0;
! #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