Imported Upstream version 2.4.3
[platform/upstream/audit.git] / src / auditd-reconfig.c
1 /* auditd-reconfig.c -- 
2  * Copyright 2005 Red Hat Inc., Durham, North Carolina.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * Authors:
20  *   Steve Grubb <sgrubb@redhat.com>
21  * 
22  */
23
24 #include "config.h"
25 #include <pthread.h>
26 #include <signal.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include "libaudit.h"
32 #include "auditd-event.h"
33 #include "auditd-config.h"
34 #include "private.h"
35
36 /* This is the configuration manager code */
37 static pthread_t config_thread;
38 static pthread_mutex_t config_lock;
39 static void *config_thread_main(void *arg);
40
41 void init_config_manager(void)
42 {
43         pthread_mutex_init(&config_lock, NULL);
44         audit_msg(LOG_DEBUG, "config_manager init complete");
45 }
46
47 int start_config_manager(struct auditd_reply_list *rep)
48 {
49         int retval, rc = 0;
50         
51         retval = pthread_mutex_trylock(&config_lock);
52         if (retval == 0) {
53                 pthread_attr_t detached;
54
55                 pthread_attr_init(&detached);
56                 pthread_attr_setdetachstate(&detached,
57                         PTHREAD_CREATE_DETACHED);
58
59                 if (pthread_create(&config_thread, &detached,
60                                 config_thread_main, rep) < 0) {
61                         audit_msg(LOG_ERR,
62                         "Couldn't create config thread, no config changes");
63                         free(rep);
64                         pthread_mutex_unlock(&config_lock);
65                         rc = 1;
66                 }
67                 pthread_attr_destroy(&detached);
68         } else {
69                 audit_msg(LOG_ERR, 
70                         "Config thread already running, no config changes");
71                 free(rep);
72                 rc = 1;
73         }
74         return rc;
75 }
76
77 void shutdown_config(void)
78 {
79         pthread_cancel(config_thread);
80 }
81
82 static void *config_thread_main(void *arg)
83 {
84         sigset_t sigs;
85         struct auditd_reply_list *rep = (struct auditd_reply_list *)arg;
86         struct daemon_conf new_config;
87         extern int send_audit_event(int type, const char *str);
88
89         /* This is a worker thread. Don't handle signals. */
90         sigemptyset(&sigs);
91         sigaddset(&sigs, SIGALRM);
92         sigaddset(&sigs, SIGTERM);
93         sigaddset(&sigs, SIGHUP);
94         sigaddset(&sigs, SIGUSR1);
95         sigaddset(&sigs, SIGUSR2);
96         pthread_sigmask(SIG_SETMASK, &sigs, NULL);
97
98         if (load_config(&new_config, TEST_AUDITD) == 0) {
99                 /* We will re-use the current reply */
100                 new_config.sender_uid = rep->reply.signal_info->uid;
101                 new_config.sender_pid = rep->reply.signal_info->pid;
102                 if (rep->reply.len > 24)
103                         new_config.sender_ctx = 
104                                 strdup(rep->reply.signal_info->ctx);
105                 else
106                         new_config.sender_ctx = strdup("?"); 
107                 memcpy(rep->reply.msg.data, &new_config, sizeof(new_config));
108                 rep->reply.conf = (struct daemon_conf *)rep->reply.msg.data;
109                 rep->reply.type = AUDIT_DAEMON_RECONFIG;
110                 enqueue_event(rep);
111         } else {
112                 // need to send a failed event message
113                 char txt[MAX_AUDIT_MESSAGE_LENGTH];
114                 snprintf(txt, sizeof(txt),
115             "reconfig aborted, sending auid=%u pid=%d subj=%s res=failed",
116                         rep->reply.signal_info->uid,
117                         rep->reply.signal_info->pid,
118                         (rep->reply.len > 24) ? 
119                                 rep->reply.signal_info->ctx : "?");
120                 send_audit_event(AUDIT_DAEMON_CONFIG, txt);
121                 free_config(&new_config);
122                 free(rep);
123         }
124
125         pthread_mutex_unlock(&config_lock);
126         return NULL;            
127 }
128