* 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:
parent
722c3546af
commit
1fadce397e
@ -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;
|
||||
|
@ -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 ----
|
||||
}
|
||||
*** 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;
|
||||
***************
|
||||
*** 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 ****
|
||||
}
|
||||
|
||||
+ #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;
|
||||
***************
|
||||
*** 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){
|
||||
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 ----
|
||||
}
|
||||
|
||||
! // Close all clients
|
||||
KillAllClients(False);
|
||||
KillAllClients(True);
|
||||
|
||||
--- 463,477 ----
|
||||
}
|
||||
}
|
||||
|
||||
! #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;
|
||||
|
Loading…
Reference in New Issue
Block a user