229 lines
5.5 KiB
C
229 lines
5.5 KiB
C
// Copyright (C) 2006-2009 Hendrik Baecker <andurin@process-zero.de>
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License version 2 as
|
|
// published by the Free Software Foundation;
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
#include "../include/config.h"
|
|
#include "../include/pnp.h"
|
|
|
|
extern int prepare_vars();
|
|
|
|
extern int thread_counter;
|
|
extern int max_threads;
|
|
extern int daemon_mode;
|
|
extern int loglevel;
|
|
extern int use_syslog;
|
|
int sighup_detected = FALSE;
|
|
|
|
extern char** command;
|
|
extern char *command_args;
|
|
extern char *user;
|
|
extern char *group;
|
|
extern char *directory;
|
|
extern char *macro_x;
|
|
extern char *config_file;
|
|
extern char buffer[MAX_LOGMESSAGE_SIZE];
|
|
|
|
extern void process_configfile(char *);
|
|
extern int check_needed_config_options(void);
|
|
|
|
typedef void (*sighandler_t)(int);
|
|
|
|
// This function has special copyright!!!
|
|
/* Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) */
|
|
/* strip newline, carriage return, and tab characters from beginning and end of a string */
|
|
void pnp_strip(char *buffer) {
|
|
register int x;
|
|
register int y;
|
|
register int z;
|
|
|
|
if (buffer == NULL || buffer[0] == '\x0')
|
|
return;
|
|
|
|
/* strip end of string */
|
|
y = (int) strlen(buffer);
|
|
for (x = y - 1; x >= 0; x--) {
|
|
if (buffer[x] == ' ' || buffer[x] == '\n' || buffer[x] == '\r'
|
|
|| buffer[x] == '\t' || buffer[x] == 13)
|
|
buffer[x] = '\x0';
|
|
else
|
|
break;
|
|
}
|
|
|
|
/* strip beginning of string (by shifting) */
|
|
y = (int) strlen(buffer);
|
|
for (x = 0; x < y; x++) {
|
|
if (buffer[x] == ' ' || buffer[x] == '\n' || buffer[x] == '\r'
|
|
|| buffer[x] == '\t' || buffer[x] == 13)
|
|
continue;
|
|
else
|
|
break;
|
|
}
|
|
if (x > 0) {
|
|
for (z = x; z < y; z++)
|
|
buffer[z - x] = buffer[z];
|
|
buffer[y - x] = '\x0';
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/*********************** SECURITY FUNCTIONS ***********************/
|
|
/******************************************************************/
|
|
/* drops privileges */
|
|
int drop_privileges(char *user, char *group) {
|
|
uid_t uid = -1;
|
|
gid_t gid = -1;
|
|
struct group *grp = NULL;
|
|
struct passwd *pw = NULL;
|
|
int result = OK;
|
|
|
|
/* only drop privileges if we're running as root, so we don't interfere with being debugged while running as some random user */
|
|
if (getuid() != 0)
|
|
return OK;
|
|
|
|
/* set effective group ID */
|
|
if (group != NULL) {
|
|
|
|
/* see if this is a group name */
|
|
if (strspn(group, "0123456789") < strlen(group)) {
|
|
grp = (struct group *) getgrnam(group);
|
|
if (grp != NULL) {
|
|
gid = (gid_t) (grp->gr_gid);
|
|
} else {
|
|
printf("Warning: Could not get group entry for '%s'\n", group);
|
|
}
|
|
}
|
|
|
|
/* else we were passed the GID */
|
|
else
|
|
gid = (gid_t) atoi(group);
|
|
|
|
/* set effective group ID if other than current EGID */
|
|
if (gid != getegid()) {
|
|
|
|
if (setgid(gid) == -1) {
|
|
printf("Warning: Could not set effective GID=%d\n", (int) gid);
|
|
result = ERROR;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* set effective user ID */
|
|
if (user != NULL) {
|
|
|
|
/* see if this is a user name */
|
|
if (strspn(user, "0123456789") < strlen(user)) {
|
|
pw = (struct passwd *) getpwnam(user);
|
|
if (pw != NULL)
|
|
uid = (uid_t) (pw->pw_uid);
|
|
else {
|
|
printf("Warning: Could not get passwd entry for '%s'\n", user);
|
|
}
|
|
}
|
|
|
|
/* else we were passed the UID */
|
|
else
|
|
uid = (uid_t) atoi(user);
|
|
|
|
#ifdef HAVE_INITGROUPS
|
|
|
|
if(uid!=geteuid()) {
|
|
|
|
/* initialize supplementary groups */
|
|
if(initgroups(user,gid)==-1) {
|
|
if(errno==EPERM) {
|
|
printf("Warning: Unable to change supplementary groups using initgroups() -- I hope you know what you're doing\n");
|
|
}
|
|
else {
|
|
printf("Warning: Possibly root user failed dropping privileges with initgroups()\n");
|
|
return ERROR;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
if (setuid(uid) == -1) {
|
|
printf("Warning: Could not set effective UID=%d\n", (int) uid);
|
|
result = ERROR;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*******************
|
|
*
|
|
* Signal functions
|
|
*
|
|
*******************/
|
|
|
|
sighandler_t handle_signal(int sig_nr, sighandler_t signalhandler) {
|
|
struct sigaction new_sig, old_sig;
|
|
|
|
new_sig.sa_handler = signalhandler;
|
|
sigemptyset(&new_sig.sa_mask);
|
|
new_sig.sa_flags = SA_RESTART;
|
|
if (sigaction(sig_nr, &new_sig, &old_sig) < 0)
|
|
return SIG_ERR;
|
|
return old_sig.sa_handler;
|
|
}
|
|
|
|
void check_sig(int signr) {
|
|
char buffer[MAX_LOGMESSAGE_SIZE];
|
|
|
|
switch (signr) {
|
|
case SIGINT:
|
|
LOG(0, "Caught SIGINT - Good bye\n");
|
|
exit(EXIT_SUCCESS);
|
|
break;
|
|
|
|
case SIGTERM:
|
|
LOG(0, "Caught Termination Signal - Astalavista... baby\n");
|
|
exit(EXIT_SUCCESS);
|
|
break;
|
|
|
|
case SIGHUP:
|
|
LOG(0, "Caught SIGHUP - reloading configuration\n");
|
|
sighup_detected = TRUE;
|
|
|
|
process_configfile(config_file);
|
|
if (check_needed_config_options() != 0) {
|
|
LOG(0, "There is an error in the config! Exiting...\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
prepare_vars();
|
|
LOG(0, "Configuration reload succesfull.\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
snprintf(buffer, sizeof(buffer - 1),
|
|
"Caught the Signal '%d' but don't care about this.\n", signr);
|
|
LOG(2, buffer);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* This won't compile on Solaris and HP UX */
|
|
|
|
#ifdef HAVE_STRUCT_DIRENT_D_TYPE
|
|
int is_file(const struct dirent *d) {
|
|
if (d->d_type == DT_REG)
|
|
return 1;
|
|
|
|
//free(d);
|
|
return 0;
|
|
}
|
|
#endif
|
|
|