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.
234 lines
5.1 KiB
234 lines
5.1 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 <unistd.h>
|
|
#include <dirent.h>
|
|
#include <errno.h>
|
|
#include <iniparser.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 INI_ENV "/etc/calculate/ini.env"
|
|
#define PROTECT_DIR "/etc"
|
|
|
|
#define HAVE_NO_UPDATE 0x0
|
|
#define HAVE_NEW_CONFIG 0x1
|
|
#define HAVE_NEW_PACKAGES 0x2
|
|
|
|
static
|
|
int has_cfg_files(char *pdir) {
|
|
DIR *dfd;
|
|
struct dirent *dp;
|
|
char filename[NAME_MAX];
|
|
int ret=0;
|
|
|
|
dfd = opendir(pdir);
|
|
if(!dfd) {
|
|
return 0;
|
|
}
|
|
while( (dp=readdir(dfd)) != NULL) {
|
|
// skip internal name
|
|
if(strcmp(dp->d_name,".") == 0 ||
|
|
strcmp(dp->d_name,"..") == 0)
|
|
continue;
|
|
// found ._cfg files for dispatch-conf
|
|
if(strncmp(dp->d_name,"._cfg", 5) == 0) {
|
|
ret = 1;
|
|
break;
|
|
}
|
|
// recursive search in directories
|
|
if(dp->d_type == DT_DIR) {
|
|
if(strlen(pdir) + strlen(dp->d_name) + 1 < NAME_MAX) {
|
|
strcpy(filename,pdir);
|
|
strcat(filename,"/");
|
|
strcat(filename,dp->d_name);
|
|
if(has_cfg_files(filename)) {
|
|
ret = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
closedir(dfd);
|
|
return ret;
|
|
}
|
|
|
|
static
|
|
int has_new_packages() {
|
|
dictionary *ini;
|
|
char *value;
|
|
int ret = 0;
|
|
|
|
ini = iniparser_load(INI_ENV);
|
|
if(ini==NULL) {
|
|
fprintf(stderr, "wrong file: %s\n", INI_ENV);
|
|
return 0;
|
|
}
|
|
value = iniparser_getstring(ini, "update:updates", NULL);
|
|
if(value && strcmp(value,"on") == 0) {
|
|
ret = 1;
|
|
}
|
|
else if(!value) {
|
|
value = iniparser_getstring(ini, "update:packages", NULL);
|
|
if(value && strcmp(value,"on") == 0) {
|
|
ret = 1;
|
|
}
|
|
}
|
|
iniparser_freedict(ini);
|
|
return ret;
|
|
}
|
|
|
|
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 */
|