Line data Source code
1 : /*
2 : Authors:
3 : Pavel Březina <pbrezina@redhat.com>
4 :
5 : Copyright (C) 2016 Red Hat
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <talloc.h>
22 : #include <tevent.h>
23 :
24 : #include "sbus/sssd_dbus.h"
25 : #include "providers/data_provider/dp_private.h"
26 : #include "providers/data_provider/dp_iface.h"
27 : #include "providers/backend.h"
28 : #include "util/util.h"
29 :
30 0 : static errno_t dp_sudo_parse_message(TALLOC_CTX *mem_ctx,
31 : DBusMessage *msg,
32 : uint32_t *_dp_flags,
33 : uint32_t *_sudo_type,
34 : char ***_rules)
35 : {
36 : DBusError error;
37 : DBusMessageIter iter;
38 : DBusMessageIter array_iter;
39 : uint32_t dp_flags;
40 : uint32_t sudo_type;
41 : uint32_t num_rules;
42 : const char *rule;
43 0 : char **rules = NULL;
44 : uint32_t i;
45 : errno_t ret;
46 :
47 0 : dbus_error_init(&error);
48 0 : dbus_message_iter_init(msg, &iter);
49 :
50 : /* get dp flags */
51 0 : if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) {
52 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed, to parse the message!\n");
53 0 : ret = EIO;
54 0 : goto done;
55 : }
56 :
57 0 : dbus_message_iter_get_basic(&iter, &dp_flags);
58 0 : dbus_message_iter_next(&iter); /* step behind the request type */
59 :
60 : /* get type of the request */
61 0 : if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) {
62 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed, to parse the message!\n");
63 0 : ret = EIO;
64 0 : goto done;
65 : }
66 :
67 0 : dbus_message_iter_get_basic(&iter, &sudo_type);
68 0 : dbus_message_iter_next(&iter); /* step behind the request type */
69 :
70 : /* get additional arguments according to the request type */
71 0 : switch (sudo_type) {
72 : case BE_REQ_SUDO_FULL:
73 : /* no arguments required */
74 0 : break;
75 : case BE_REQ_SUDO_RULES:
76 : /* additional arguments:
77 : * rules_num
78 : * rules[rules_num]
79 : */
80 : /* read rules_num */
81 0 : if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) {
82 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed, to parse the message!\n");
83 0 : ret = EIO;
84 0 : goto done;
85 : }
86 :
87 0 : dbus_message_iter_get_basic(&iter, &num_rules);
88 :
89 0 : rules = talloc_zero_array(mem_ctx, char *, num_rules + 1);
90 0 : if (rules == NULL) {
91 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_array() failed.\n");
92 0 : ret = ENOMEM;
93 0 : goto done;
94 : }
95 :
96 0 : dbus_message_iter_next(&iter);
97 :
98 0 : if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
99 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed, to parse the message!\n");
100 0 : ret = EIO;
101 0 : goto done;
102 : }
103 :
104 0 : dbus_message_iter_recurse(&iter, &array_iter);
105 :
106 : /* read the rules */
107 0 : for (i = 0; i < num_rules; i++) {
108 0 : if (dbus_message_iter_get_arg_type(&array_iter)
109 : != DBUS_TYPE_STRING) {
110 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed, to parse the message!\n");
111 0 : ret = EIO;
112 0 : goto done;
113 : }
114 :
115 0 : dbus_message_iter_get_basic(&array_iter, &rule);
116 0 : rules[i] = talloc_strdup(rules, rule);
117 0 : if (rules[i] == NULL) {
118 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed.\n");
119 0 : ret = ENOMEM;
120 0 : goto done;
121 : }
122 :
123 0 : dbus_message_iter_next(&array_iter);
124 : }
125 :
126 0 : rules[num_rules] = NULL;
127 :
128 0 : break;
129 : default:
130 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type %d\n", sudo_type);
131 0 : return EINVAL;
132 : }
133 :
134 0 : *_dp_flags = dp_flags;
135 0 : *_sudo_type = sudo_type;
136 0 : *_rules = rules;
137 :
138 0 : ret = EOK;
139 :
140 : done:
141 0 : if (ret != EOK) {
142 0 : talloc_free(rules);
143 : }
144 :
145 0 : return ret;
146 : }
147 :
148 0 : static const char *dp_sudo_get_key(uint32_t type)
149 : {
150 0 : switch (type) {
151 : case BE_REQ_SUDO_FULL:
152 0 : return "full-refresh";
153 : case BE_REQ_SUDO_RULES:
154 0 : return NULL;
155 : }
156 :
157 0 : return NULL;
158 : }
159 :
160 0 : static const char *dp_sudo_get_name(uint32_t type)
161 : {
162 0 : switch (type) {
163 : case BE_REQ_SUDO_FULL:
164 0 : return "SUDO Full Refresh";
165 : case BE_REQ_SUDO_RULES:
166 0 : return "SUDO Rules Refresh";
167 : }
168 :
169 0 : return NULL;
170 : }
171 :
172 0 : errno_t dp_sudo_handler(struct sbus_request *sbus_req, void *dp_cli)
173 : {
174 : struct dp_sudo_data *data;
175 : uint32_t dp_flags;
176 : const char *key;
177 : const char *name;
178 : errno_t ret;
179 :
180 0 : data = talloc_zero(sbus_req, struct dp_sudo_data);
181 0 : if (data == NULL) {
182 0 : return ENOMEM;
183 : }
184 :
185 0 : ret = dp_sudo_parse_message(data, sbus_req->message, &dp_flags,
186 : &data->type, &data->rules);
187 0 : if (ret != EOK) {
188 0 : return ret;
189 : }
190 :
191 0 : key = dp_sudo_get_key(data->type);
192 0 : name = dp_sudo_get_name(data->type);
193 :
194 0 : dp_req_with_reply(dp_cli, NULL, name, key, sbus_req, DPT_SUDO,
195 : DPM_SUDO_HANDLER, dp_flags, data,
196 : dp_req_reply_std, struct dp_reply_std);
197 :
198 0 : return EOK;
199 : }
|