OSDN Git Service

gpet 0.2 pre
[gpet/origin.git] / src / usr_sbin / editpolicy_offline.c
1 /*
2  * editpolicy_offline.c
3  *
4  * TOMOYO Linux's utilities.
5  *
6  * Copyright (C) 2005-2011  NTT DATA CORPORATION
7  *
8  * Version: 1.8.1   2011/04/01
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License v2 as published by the
12  * Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17  * more details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
22  */
23 #include "ccstools.h"
24 #include "editpolicy.h"
25
26 /**
27  * ccs_handle_misc_policy - Handle policy data other than domain policy.
28  *
29  * @mp:       Pointer to "struct ccs_misc_policy".
30  * @fp:       Pointer to "FILE".
31  * @is_write: True if write request, false otherwise.
32  *
33  * Returns nothing.
34  */
35 static void ccs_handle_misc_policy(struct ccs_misc_policy *mp, FILE *fp,
36                                    _Bool is_write)
37 {
38         int i;
39         if (!is_write)
40                 goto read_policy;
41         while (true) {
42                 char *line = ccs_freadline_unpack(fp);
43                 const struct ccs_path_info *cp;
44                 _Bool is_delete;
45                 if (!line)
46                         break;
47                 if (!line[0])
48                         continue;
49                 is_delete = ccs_str_starts(line, "delete ");
50                 cp = ccs_savename(line);
51                 if (!cp)
52                         ccs_out_of_memory();
53                 if (!is_delete)
54                         goto append_policy;
55                 for (i = 0; i < mp->list_len; i++)
56                         /* Faster comparison, for they are ccs_savename'd. */
57                         if (mp->list[i] == cp)
58                                 break;
59                 if (i < mp->list_len)
60                         for (mp->list_len--; i < mp->list_len; i++)
61                                 mp->list[i] = mp->list[i + 1];
62                 continue;
63 append_policy:
64                 for (i = 0; i < mp->list_len; i++)
65                         /* Faster comparison, for they are ccs_savename'd. */
66                         if (mp->list[i] == cp)
67                                 break;
68                 if (i < mp->list_len)
69                         continue;
70                 mp->list = realloc(mp->list, (mp->list_len + 1)
71                                    * sizeof(const struct ccs_path_info *));
72                 if (!mp->list)
73                         ccs_out_of_memory();
74                 mp->list[mp->list_len++] = cp;
75         }
76         return;
77 read_policy:
78         for (i = 0; i < mp->list_len; i++)
79                 fprintf(fp, "%s\n", mp->list[i]->name);
80 }
81
82 /**
83  * ccs_editpolicy_offline_daemon - Emulate /proc/ccs/ interface.
84  *
85  * This function does not return.
86  */
87 void ccs_editpolicy_offline_daemon(void)
88 {
89         struct ccs_misc_policy mp[3];
90         static const int buffer_len = 8192;
91         char *buffer = malloc(buffer_len);
92         if (!buffer)
93                 ccs_out_of_memory();
94         memset(&ccs_dp, 0, sizeof(ccs_dp));
95         memset(&mp, 0, sizeof(mp));
96         ccs_get();
97         ccs_assign_domain(&ccs_dp, CCS_ROOT_NAME, false, false);
98         while (true) {
99                 FILE *fp;
100                 struct msghdr msg;
101                 struct iovec iov = { buffer, buffer_len - 1 };
102                 char cmsg_buf[CMSG_SPACE(sizeof(int))];
103                 struct cmsghdr *cmsg = (struct cmsghdr *) cmsg_buf;
104                 memset(&msg, 0, sizeof(msg));
105                 msg.msg_iov = &iov;
106                 msg.msg_iovlen = 1;
107                 msg.msg_control = cmsg_buf;
108                 msg.msg_controllen = sizeof(cmsg_buf);
109                 memset(buffer, 0, buffer_len);
110                 errno = 0;
111                 if (recvmsg(ccs_persistent_fd, &msg, 0) <= 0)
112                         break;
113                 cmsg = CMSG_FIRSTHDR(&msg);
114                 if (!cmsg)
115                         break;
116                 if (cmsg->cmsg_level == SOL_SOCKET &&
117                     cmsg->cmsg_type == SCM_RIGHTS &&
118                     cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
119                         const int *fdp = (int *) CMSG_DATA(cmsg);
120                         const int fd = *fdp;
121                         fp = fdopen(fd, "w+");
122                         if (!fp) {
123                                 close(fd);
124                                 continue;
125                         }
126                 } else {
127                         break;
128                 }
129                 if (ccs_str_starts(buffer, "POST ")) {
130                         if (!strcmp(buffer, CCS_PROC_POLICY_DOMAIN_POLICY))
131                                 ccs_handle_domain_policy(&ccs_dp, fp, true);
132                         else if (!strcmp(buffer,
133                                          CCS_PROC_POLICY_EXCEPTION_POLICY))
134                                 ccs_handle_misc_policy(&mp[0], fp, true);
135                         else if (!strcmp(buffer, CCS_PROC_POLICY_PROFILE))
136                                 ccs_handle_misc_policy(&mp[1], fp, true);
137                         else if (!strcmp(buffer, CCS_PROC_POLICY_MANAGER))
138                                 ccs_handle_misc_policy(&mp[2], fp, true);
139                 } else if (ccs_str_starts(buffer, "GET ")) {
140                         if (!strcmp(buffer, CCS_PROC_POLICY_DOMAIN_POLICY))
141                                 ccs_handle_domain_policy(&ccs_dp, fp, false);
142                         else if (!strcmp(buffer,
143                                          CCS_PROC_POLICY_EXCEPTION_POLICY))
144                                 ccs_handle_misc_policy(&mp[0], fp, false);
145                         else if (!strcmp(buffer, CCS_PROC_POLICY_PROFILE))
146                                 ccs_handle_misc_policy(&mp[1], fp, false);
147                         else if (!strcmp(buffer, CCS_PROC_POLICY_MANAGER))
148                                 ccs_handle_misc_policy(&mp[2], fp, false);
149                 }
150                 fclose(fp);
151         }
152         ccs_put();
153         ccs_clear_domain_policy(&ccs_dp);
154         {
155                 int i;
156                 for (i = 0; i < 3; i++) {
157                         free(mp[i].list);
158                         mp[i].list = NULL;
159                         mp[i].list_len = 0;
160                 }
161         }
162         free(buffer);
163         _exit(0);
164 }