You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
3.7 KiB

/* pam_update module */
/*
* Module for check Calculate update, pam_mail as base.
*/
#include <ctype.h>
#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#define PAM_SM_SESSION
#define PAM_SM_AUTH
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
#include <security/pam_modutil.h>
#include <security/pam_ext.h>
#define UPDATES_MARK "/var/lib/calculate/calculate-update/updates.available"
#define HAVE_NO_UPDATE 0x0
#define HAVE_NEW_CONFIG 0x1
#define HAVE_NEW_PACKAGES 0x2
static
int has_new_packages() {
return (faccessat(0, UPDATES_MARK, F_OK, AT_SYMLINK_NOFOLLOW) == 0) ? 1 : 0;
}
static int
get_update_status(pam_handle_t *pamh)
{
int ret = HAVE_NO_UPDATE;
if(has_new_packages()) ret |= HAVE_NEW_PACKAGES;
//if(has_cfg_files(PROTECT_DIR)) ret |= HAVE_NEW_CONFIG;
return ret;
}
static int
report_update(pam_handle_t *pamh, int type)
{
int retval;
switch (type)
{
case HAVE_NO_UPDATE:
retval = PAM_SUCCESS;
break;
case HAVE_NEW_CONFIG:
case HAVE_NEW_PACKAGES:
retval = pam_info (pamh, "%s", "The system has updates.");
break;
default:
retval = PAM_SUCCESS;
}
return retval;
}
static int _do_update(pam_handle_t *, int, int, const char **, int);
/* --- authentication functions --- */
PAM_EXTERN int
pam_sm_authenticate (pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
return PAM_IGNORE;
}
/* Checking update as part of authentication */
PAM_EXTERN
int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
const char **argv)
{
if (!(flags & (PAM_ESTABLISH_CRED|PAM_DELETE_CRED)))
return PAM_IGNORE;
return _do_update(pamh,flags,argc,argv,(flags & PAM_ESTABLISH_CRED));
}
/* --- session management functions --- */
PAM_EXTERN
int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc
,const char **argv)
{
return _do_update(pamh,flags,argc,argv,0);
}
/* Checking update as part of the session management */
PAM_EXTERN
int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
const char **argv)
{
return _do_update(pamh,flags,argc,argv,1);
}
/* --- The Beaf (Tm) --- */
static int _do_update(pam_handle_t *pamh, int flags, int argc,
const char **argv, int est)
{
int retval, type;
size_t hashcount;
char *folder = NULL;
const char *user;
const char *path_mail = NULL;
const struct passwd *pwd = NULL;
retval = pam_get_user(pamh, &user, NULL);
if (retval != PAM_SUCCESS || user == NULL) {
pam_syslog(pamh, LOG_ERR, "cannot determine username");
return PAM_USER_UNKNOWN;
}
pwd = pam_modutil_getpwnam (pamh, user);
if (pwd == NULL) {
pam_syslog(pamh, LOG_ERR, "user unknown");
return PAM_USER_UNKNOWN;
}
if(strcmp(user,"root")) {
return PAM_IGNORE;
}
PAM_MODUTIL_DEF_PRIVS(privs);
if (pam_modutil_drop_priv(pamh, &privs, pwd)) {
return PAM_SESSION_ERR;
} else {
type = get_update_status(pamh);
if (pam_modutil_regain_priv(pamh, &privs)) {
return PAM_SESSION_ERR;
}
}
if (type != 0) {
retval = report_update(pamh, type);
type = 0;
}
return retval;
}
#ifdef PAM_STATIC
/* static module data */
struct pam_module _pam_update_modstruct = {
"pam_update",
pam_sm_authenticate,
pam_sm_setcred,
NULL,
pam_sm_open_session,
pam_sm_close_session,
NULL,
};
#endif
/* end of module definition */