38#include "clientpipe.h"
39#include "cmdhandler.h"
42#include "scheduler/schedule.h"
43#include "scheduler/task.h"
57#include <libxml/parser.h>
63#include <sys/socket.h>
70static const char* engine_str =
"engine";
82 if (!engine)
return NULL;
88 engine->
taskq = schedule_create();
99 schedule_cleanup(engine->
taskq);
112 ods_log_assert(engine);
113 ods_log_debug(
"[%s] start command handler", engine_str);
114 janitor_thread_create(&engine->
cmdhandler->thread_id, workerthreadclass, (janitor_runfn_t)cmdhandler_start, engine->
cmdhandler);
124 ods_status status = ODS_STATUS_OK;
128 ods_log_assert(engine);
129 ods_log_assert(engine->
config);
130 ods_log_debug(
"[%s] drop privileges", engine_str);
133 ods_log_verbose(
"[%s] drop privileges to user %s, group %s",
136 ods_log_verbose(
"[%s] drop privileges to user %s", engine_str,
139 ods_log_verbose(
"[%s] drop privileges to group %s", engine_str,
143 ods_log_verbose(
"[%s] chroot to %s", engine_str,
163 ods_log_assert(engine);
164 ods_log_assert(engine->
config);
165 engine->
workers = (worker_type**) malloc(
168 asprintf(&name,
"worker[%d]", i+1);
169 engine->
workers[i] = worker_create(name, engine->
taskq);
178 ods_log_assert(engine);
179 ods_log_assert(engine->
config);
180 ods_log_debug(
"[%s] start workers", engine_str);
182 engine->
workers[i]->need_to_exit = 0;
184 if (!engine->
workers[i]->context) {
185 ods_log_crit(
"Failed to start worker, could not connect to database");
187 janitor_thread_create(&engine->
workers[i]->thread_id, workerthreadclass, (janitor_runfn_t)worker_start, engine->
workers[i]);
197 ods_log_assert(engine);
198 ods_log_assert(engine->
config);
199 ods_log_debug(
"[%s] stop workers", engine_str);
202 engine->
workers[i]->need_to_exit = 1;
207 ods_log_debug(
"[%s] join worker %i", engine_str, i+1);
208 janitor_thread_join(engine->
workers[i]->thread_id);
220 ods_log_assert(engine);
221 ods_log_debug(
"[%s] wake up workers", engine_str);
222 schedule_release_all(engine->
taskq);
236 ods_log_crit(
"database connection failed");
273 fprintf(stderr,
"db_configuraiton_list_new failed\n");
285 fprintf(stderr,
"setup configuration backend failed\n");
296 fprintf(stderr,
"setup configuration file failed\n");
310 fprintf(stderr,
"setup configuration backend failed\n");
321 fprintf(stderr,
"setup configuration file failed\n");
327 if (snprintf(&str[0],
sizeof(str),
"%d", engine->
config->
db_port) >= (
int)
sizeof(str)) {
330 fprintf(stderr,
"setup configuration file failed\n");
341 fprintf(stderr,
"setup configuration file failed\n");
354 fprintf(stderr,
"setup configuration file failed\n");
366 fprintf(stderr,
"setup configuration file failed\n");
378 fprintf(stderr,
"setup configuration file failed\n");
402signal_handler(sig_atomic_t sig)
438 ods_log_debug(
"[%s] enforcer setup", engine_str);
440 engine->
pid = getpid();
443 ods_log_error(
"[%s] Pidfile exists and process with PID is running", engine_str);
444 return ODS_STATUS_WRITE_PIDFILE_ERR;
447 if (setup_database(engine))
return ODS_STATUS_DB_ERR;
449 if (probe_database(engine)) {
450 ods_log_crit(
"Could not connect to database or database not set up properly.");
451 return ODS_STATUS_DB_ERR;
457 ods_log_error(
"[%s] create command handler to %s failed",
459 return ODS_STATUS_CMDHANDLER_ERR;
463 ods_log_error(
"[%s] unable to pipe: %s", engine_str, strerror(errno));
464 return ODS_STATUS_PIPE_ERR;
481 ods_log_error(
"[%s] chdir to %s failed: %s", engine_str,
483 return ODS_STATUS_CHDIR_ERR;
485 if (engine_privdrop(engine) != ODS_STATUS_OK) {
486 ods_log_error(
"[%s] unable to drop privileges", engine_str);
487 return ODS_STATUS_PRIVDROP_ERR;
494 ods_log_error(
"[%s] unable to fork daemon: %s",
495 engine_str, strerror(errno));
496 return ODS_STATUS_FORK_ERR;
498 if ((fd = open(
"/dev/null", O_RDWR, 0)) != -1) {
499 (void)dup2(fd, STDIN_FILENO);
500 (void)dup2(fd, STDOUT_FILENO);
501 (void)dup2(fd, STDERR_FILENO);
502 if (fd > 2) (void)close(fd);
509 while (read(pipefd[0], &buff, 1) != -1) {
510 if (buff <= 1)
break;
515 ods_log_error(
"[%s] fail to start enforcerd completely", engine_str);
518 ods_log_debug(
"[%s] enforcerd started successfully", engine_str);
521 if (setsid() == -1) {
522 ods_log_error(
"[%s] unable to setsid daemon (%s)",
523 engine_str, strerror(errno));
524 const char *err =
"unable to setsid daemon: ";
525 ods_writen(pipefd[1], err, strlen(err));
526 ods_writeln(pipefd[1], strerror(errno));
527 write(pipefd[1],
"\0", 1);
529 return ODS_STATUS_SETSID_ERR;
535 engine->
pid = getpid();
536 ods_log_info(
"[%s] running as pid %lu", engine_str,
537 (
unsigned long) engine->
pid);
540 engine_create_workers(engine);
545 ods_log_error(
"[%s] unable to write pid file", engine_str);
547 ods_writeln(pipefd[1],
"unable to write pid file");
548 write(pipefd[1],
"\0", 1);
551 return ODS_STATUS_WRITE_PIDFILE_ERR;
553 ods_log_info(
"[%s] enforcer started", engine_str);
555 if (error != HSM_OK) {
556 char* errorstr = hsm_get_error(NULL);
558 (void)asprintf(&errorstr,
"error opening libhsm (errno %i)", error);
560 ods_log_error(
"[%s] %s", engine_str, errorstr);
562 if (errorstr) ods_writeln(pipefd[1], errorstr);
563 write(pipefd[1],
"\0", 1);
567 return ODS_STATUS_HSM_ERR;
570 engine_start_cmdhandler(engine);
572 write(pipefd[1],
"\1", 1);
574 if (!engine->
daemonize) close(pipefd[0]);
576 return ODS_STATUS_OK;
599 worker_cleanup(engine->
workers[i]);
608 desetup_database(engine);
614 struct sigaction action;
620 engine->
pid = getpid();
627 action.sa_handler = (void (*)(int))signal_handler;
628 sigfillset(&action.sa_mask);
630 sigaction(SIGHUP, &action, NULL);
631 sigaction(SIGTERM, &action, NULL);
632 sigaction(SIGINT, &action, NULL);
634 action.sa_handler = SIG_IGN;
635 sigaction(SIGPIPE, &action, NULL);
645 ods_log_assert(engine);
667 ods_log_debug(
"[%s] taking a break", engine_str);
672 ods_log_debug(
"[%s] enforcer halted", engine_str);
675 schedule_purge(engine->
taskq);
@ ENFORCER_DATABASE_TYPE_MYSQL
@ ENFORCER_DATABASE_TYPE_SQLITE
int database_version_get_version(db_connection_t *connection)
db_configuration_t * db_configuration_new(void)
db_configuration_list_t * db_configuration_list_new(void)
void db_configuration_free(db_configuration_t *configuration)
int db_configuration_set_name(db_configuration_t *configuration, const char *name)
int db_configuration_list_add(db_configuration_list_t *configuration_list, db_configuration_t *configuration)
int db_configuration_set_value(db_configuration_t *configuration, const char *value)
void db_configuration_list_free(db_configuration_list_t *configuration_list)
int db_connection_connect(const db_connection_t *connection)
db_connection_t * db_connection_new(void)
int db_connection_setup(db_connection_t *connection)
void db_connection_free(db_connection_t *connection)
int db_connection_set_configuration_list(db_connection_t *connection, const db_configuration_list_t *configuration_list)
struct cmd_func_block ** enforcercommands
void engine_teardown(engine_type *engine)
void engine_init(engine_type *engine, int daemonize)
void engine_dealloc(engine_type *engine)
engine_type * engine_alloc(void)
void engine_wakeup_workers(engine_type *engine)
void engine_start_workers(engine_type *engine)
int engine_run(engine_type *engine, start_cb_t start, int single_run)
void engine_stop_workers(engine_type *engine)
db_connection_t * get_database_connection(engine_type *engine)
ods_status engine_setup()
void(* start_cb_t)(engine_type *engine)
void hsm_key_factory_deinit(void)
pthread_mutex_t signal_lock
cmdhandler_type * cmdhandler
pthread_cond_t signal_cond
db_configuration_list_t * dbcfg_list
engineconfig_type * config
engineconfig_database_type_t db_type
const char * clisock_filename
hsm_repository_t * repositories
const char * pid_filename
const char * log_filename