diff --git a/pkgs/applications/display-managers/slim/default.nix b/pkgs/applications/display-managers/slim/default.nix index 748e0947a640..c16582fc3880 100644 --- a/pkgs/applications/display-managers/slim/default.nix +++ b/pkgs/applications/display-managers/slim/default.nix @@ -1,4 +1,4 @@ -{stdenv, fetchurl, x11, libjpeg, libpng, libXmu, freetype}: +{stdenv, fetchurl, x11, libjpeg, libpng, libXmu, freetype, pam}: stdenv.mkDerivation { name = "slim-1.2.6"; @@ -6,10 +6,18 @@ stdenv.mkDerivation { url = http://download.berlios.de/slim/slim-1.2.6.tar.gz; sha256 = "0plcmm955rnv67sx67ka6dccanr4rfzwzvsj6lnr8kqdip4522jg"; }; - patches = [./runtime-paths.patch]; - buildInputs = [x11 libjpeg libpng libXmu freetype]; + 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 + ./pam.patch + ]; + buildInputs = [x11 libjpeg libpng libXmu freetype pam]; NIX_CFLAGS_COMPILE = "-I${freetype}/include/freetype2"; preBuild = " + substituteInPlace Makefile --replace /usr /no-such-path makeFlagsArray=(CC=gcc CXX=g++ PREFIX=$out MANDIR=$out/share/man CFGDIR=$out/etc) "; } diff --git a/pkgs/applications/display-managers/slim/pam.patch b/pkgs/applications/display-managers/slim/pam.patch new file mode 100644 index 000000000000..f7cbddf5aaa2 --- /dev/null +++ b/pkgs/applications/display-managers/slim/pam.patch @@ -0,0 +1,369 @@ +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 +*************** +*** 25,30 **** +--- 25,68 ---- + #include "app.h" + #include "numlock.h" + ++ #ifdef USE_PAM ++ #include ++ #include ++ #include ++ ++ pam_handle_t* pamh; ++ char const* PAM_service = "login"; // <----- 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; iresp_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 **** +--- 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; +*************** +*** 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 **** + } + } + +! // 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 + ++ #ifdef USE_PAM ++ #include ++ #include ++ ++ 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 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 8c5b162eba15..299b439c9561 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -2939,7 +2939,7 @@ rec { }; slim = import ../applications/display-managers/slim { - inherit fetchurl stdenv x11 libjpeg libpng freetype; + inherit fetchurl stdenv x11 libjpeg libpng freetype pam; inherit (xlibs) libXmu; };