mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 10:52:51 +00:00
kcheckpass: actually allow method selection during runtime
requires:
e1fe980be1
log some errors to auth log and use the actual service as PAM service while
at it
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
0acc0d3d5a
commit
459e73c8d3
6 changed files with 109 additions and 53 deletions
|
@ -23,11 +23,10 @@ target_link_libraries(kcheckpass
|
|||
${SOCKET_LIBRARIES}
|
||||
)
|
||||
|
||||
if (PAM_FOUND)
|
||||
set(kcheckpass_suid "")
|
||||
else()
|
||||
if (HAVE_GETSPNAM)
|
||||
set(kcheckpass_suid "SETUID")
|
||||
message(WARNING "PAM not found, will install kcheckpass SUID")
|
||||
message(WARNING "Will install kcheckpass SUID")
|
||||
endif()
|
||||
|
||||
install(
|
||||
|
|
|
@ -21,28 +21,32 @@
|
|||
|
||||
#include "kcheckpass.h"
|
||||
|
||||
#ifdef HAVE_ETCPASSWD
|
||||
|
||||
/*******************************************************************
|
||||
* This is the authentication code for /etc/passwd passwords
|
||||
*******************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
|
||||
AuthReturn Authenticate(const char *method,
|
||||
AuthReturn Authenticate_etcpasswd(const char *method,
|
||||
const char *login, char *(*conv) (ConvRequest, const char *))
|
||||
{
|
||||
if (strcmp(method, "etcpasswd") != 0)
|
||||
return AuthError;
|
||||
|
||||
struct passwd *pw;
|
||||
char *passwd;
|
||||
char *crpt_passwd;
|
||||
|
||||
if (strcmp(method, "classic"))
|
||||
return AuthError;
|
||||
openlog("kcheckpass", LOG_PID, LOG_AUTH);
|
||||
|
||||
/* Get the password entry for the user we want */
|
||||
if (!(pw = getpwnam(login)))
|
||||
if (!(pw = getpwnam(login))) {
|
||||
syslog(LOG_ERR, "getpwnam: %s", strerror(errno));
|
||||
return AuthBad;
|
||||
}
|
||||
|
||||
if (!*pw->pw_passwd)
|
||||
return AuthOk;
|
||||
|
@ -57,5 +61,3 @@ AuthReturn Authenticate(const char *method,
|
|||
dispose(passwd);
|
||||
return AuthBad; /* Password wrong or account locked */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
struct pam_data {
|
||||
char *(*conv) (ConvRequest, const char *);
|
||||
int abort:1;
|
||||
int classic:1;
|
||||
};
|
||||
|
||||
#ifdef PAM_MESSAGE_CONST
|
||||
|
@ -68,7 +67,7 @@ PAM_conv (int num_msg, pam_message_type **msg,
|
|||
break;
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
repl[count].resp =
|
||||
pd->conv(ConvGetHidden, pd->classic ? 0 : msg[count]->msg);
|
||||
pd->conv(ConvGetHidden, msg[count]->msg);
|
||||
break;
|
||||
#ifdef PAM_BINARY_PROMPT
|
||||
case PAM_BINARY_PROMPT:
|
||||
|
@ -122,9 +121,12 @@ fail_delay(int retval ATTR_UNUSED, unsigned usec_delay ATTR_UNUSED,
|
|||
#endif
|
||||
|
||||
|
||||
AuthReturn Authenticate(const char *caller, const char *method,
|
||||
AuthReturn Authenticate_pam(const char *caller, const char *method,
|
||||
const char *user, char *(*conv) (ConvRequest, const char *))
|
||||
{
|
||||
if (strcmp(method, "pam") != 0)
|
||||
return AuthError;
|
||||
|
||||
const char *tty;
|
||||
pam_handle_t *pamh;
|
||||
pam_gi_type pam_item;
|
||||
|
@ -135,14 +137,7 @@ AuthReturn Authenticate(const char *caller, const char *method,
|
|||
openlog("kcheckpass", LOG_PID, LOG_AUTH);
|
||||
|
||||
PAM_data.conv = conv;
|
||||
if (strcmp(method, "classic")) {
|
||||
sprintf(pservb, "%.31s-%.31s", caller, method);
|
||||
pam_service = pservb;
|
||||
} else {
|
||||
/* PAM_data.classic = 1; */
|
||||
pam_service = caller;
|
||||
}
|
||||
pam_error = pam_start(pam_service, user, &PAM_conversation, &pamh);
|
||||
pam_error = pam_start(caller, user, &PAM_conversation, &pamh);
|
||||
if (pam_error != PAM_SUCCESS)
|
||||
return AuthError;
|
||||
|
||||
|
@ -196,4 +191,4 @@ AuthReturn Authenticate(const char *caller, const char *method,
|
|||
return AuthOk;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // HAVE_PAM
|
||||
|
|
|
@ -31,31 +31,40 @@
|
|||
*******************************************************************/
|
||||
|
||||
#ifdef HAVE_SHADOW
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
#include <pwd.h>
|
||||
#include <shadow.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
AuthReturn Authenticate(const char *method,
|
||||
AuthReturn Authenticate_shadow(const char *method,
|
||||
const char *login, char *(*conv) (ConvRequest, const char *))
|
||||
{
|
||||
if (strcmp(method, "shadow") != 0)
|
||||
return AuthError;
|
||||
|
||||
char *typed_in_password;
|
||||
char *crpt_passwd;
|
||||
char *password;
|
||||
struct passwd *pw;
|
||||
struct spwd *spw;
|
||||
|
||||
if (strcmp(method, "classic"))
|
||||
return AuthError;
|
||||
openlog("kcheckpass", LOG_PID, LOG_AUTH);
|
||||
|
||||
if (!(pw = getpwnam(login)))
|
||||
if (!(pw = getpwnam(login))) {
|
||||
syslog(LOG_ERR, "getpwnam: %s", strerror(errno));
|
||||
return AuthAbort;
|
||||
}
|
||||
|
||||
uid_t eid = geteuid();
|
||||
if (eid != 0 && seteuid(0) != 0)
|
||||
if (eid != 0 && seteuid(0) != 0) {
|
||||
syslog(LOG_ERR, "seteuid: %s", strerror(errno));
|
||||
return AuthAbort;
|
||||
}
|
||||
|
||||
spw = getspnam(login);
|
||||
password = spw ? spw->sp_pwdp : pw->pw_passwd;
|
||||
|
@ -92,4 +101,4 @@ AuthReturn Authenticate(const char *method,
|
|||
everything else you need to support shadow passwords is in
|
||||
the standard (ELF) libc.
|
||||
*/
|
||||
#endif
|
||||
#endif // HAVE_SHADOW
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
* It's hopefully simple enough to allow it to be setuid
|
||||
* root.
|
||||
*
|
||||
* Compile with -DHAVE_VSYSLOG if you have vsyslog().
|
||||
* Compile with -DHAVE_PAM if you have a PAM system,
|
||||
* and link with -lpam -ldl.
|
||||
* Compile with -DHAVE_SHADOW if you have a shadow
|
||||
|
@ -65,6 +64,15 @@
|
|||
static int havetty, nullpass = 0;
|
||||
static int sfd = -1;
|
||||
|
||||
static const char* methods[3] = { "", "", "" };
|
||||
#if defined(HAVE_PAM)
|
||||
const char *method = "pam";
|
||||
#elif defined(HAVE_SHADOW)
|
||||
const char *method = "shadow";
|
||||
#else
|
||||
const char *method = "etcpasswd";
|
||||
#endif
|
||||
|
||||
static char *
|
||||
conv_legacy (ConvRequest what, const char *prompt)
|
||||
{
|
||||
|
@ -292,23 +300,22 @@ usage(int exitval)
|
|||
" -U username authenticate the specified user instead of current user\n"
|
||||
" -S handle operate in binary server mode on file descriptor handle\n"
|
||||
" -c caller the calling application, effectively the PAM service basename\n"
|
||||
" -m method use the specified authentication method (default: \"classic\")\n"
|
||||
" -m method use the specified authentication method (default: \"%s\")\n"
|
||||
" exit codes:\n"
|
||||
" 0 success\n"
|
||||
" 1 invalid password\n"
|
||||
" 2 cannot read password database\n"
|
||||
" Anything else tells you something's badly hosed.\n"
|
||||
);
|
||||
" Anything else tells you something's badly hosed.\n",
|
||||
method);
|
||||
exit(exitval);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
#ifdef HAVE_PAM
|
||||
#if defined(HAVE_PAM)
|
||||
const char *caller = KSCREENSAVER_PAM_SERVICE;
|
||||
#endif
|
||||
const char *method = "classic";
|
||||
const char *username = 0;
|
||||
#ifdef ACCEPT_ENV
|
||||
char *p;
|
||||
|
@ -362,6 +369,28 @@ main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
int validmethod = 0;
|
||||
#ifdef HAVE_PAM
|
||||
methods[0] = "pam";
|
||||
if (strcmp(method, "pam") == 0) {
|
||||
validmethod = 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_SHADOW
|
||||
methods[1] = ", shadow";
|
||||
if (strcmp(method, "shadow") == 0) {
|
||||
validmethod = 1;
|
||||
}
|
||||
#endif
|
||||
methods[2] = ", etcpasswd";
|
||||
if (strcmp(method, "etcpasswd") == 0) {
|
||||
validmethod = 1;
|
||||
}
|
||||
if (!validmethod) {
|
||||
message("Method must be one of: %s%s%s\n", methods[0], methods[1], methods[2]);
|
||||
usage(11);
|
||||
}
|
||||
|
||||
uid = getuid();
|
||||
|
||||
#ifdef ACCEPT_ENV
|
||||
|
@ -417,13 +446,32 @@ main(int argc, char **argv)
|
|||
}
|
||||
|
||||
/* Now do the fandango */
|
||||
ret = Authenticate(
|
||||
#ifdef HAVE_PAM
|
||||
if (strcmp(method, "pam") == 0) {
|
||||
ret = Authenticate_pam(
|
||||
caller,
|
||||
#endif
|
||||
method,
|
||||
username,
|
||||
sfd < 0 ? conv_legacy : conv_server);
|
||||
sfd < 0 ? conv_legacy : conv_server
|
||||
);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_SHADOW
|
||||
if (strcmp(method, "shadow") == 0) {
|
||||
ret = Authenticate_shadow(
|
||||
method,
|
||||
username,
|
||||
sfd < 0 ? conv_legacy : conv_server
|
||||
);
|
||||
}
|
||||
#endif
|
||||
if (strcmp(method, "etcpasswd") == 0) {
|
||||
ret = Authenticate_etcpasswd(
|
||||
method,
|
||||
username,
|
||||
sfd < 0 ? conv_legacy : conv_server
|
||||
);
|
||||
}
|
||||
|
||||
if (ret == AuthBad) {
|
||||
message("Authentication failure\n");
|
||||
|
|
|
@ -51,19 +51,10 @@
|
|||
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef _PATH_TMP
|
||||
#define _PATH_TMP "/tmp/"
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
/* Make sure there is only one! */
|
||||
#if defined(HAVE_PAM)
|
||||
#elif defined(HAVE_GETSPNAM)
|
||||
#ifdef HAVE_GETSPNAM
|
||||
# define HAVE_SHADOW
|
||||
#else
|
||||
# define HAVE_ETCPASSWD
|
||||
#endif
|
||||
|
||||
#if !defined(__INSURE__)
|
||||
|
@ -85,10 +76,22 @@ extern "C" {
|
|||
/*****************************************************************
|
||||
* Authenticates user
|
||||
*****************************************************************/
|
||||
AuthReturn Authenticate(
|
||||
#ifdef HAVE_PAM
|
||||
AuthReturn Authenticate_pam(
|
||||
const char *caller,
|
||||
const char *method,
|
||||
const char *user,
|
||||
char *(*conv) (ConvRequest, const char *));
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SHADOW
|
||||
AuthReturn Authenticate_shadow(
|
||||
const char *method,
|
||||
const char *user,
|
||||
char *(*conv) (ConvRequest, const char *));
|
||||
#endif
|
||||
|
||||
AuthReturn Authenticate_etcpasswd(
|
||||
const char *method,
|
||||
const char *user,
|
||||
char *(*conv) (ConvRequest, const char *));
|
||||
|
|
Loading…
Add table
Reference in a new issue