Line data Source code
1 : /*
2 : Authors:
3 : Pavel Březina <pbrezina@redhat.com>
4 : Jakub Hrozek <jhrozek@redhat.com>
5 :
6 : Copyright (C) 2011 Red Hat
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include <talloc.h>
23 : #include <tevent.h>
24 : #include <dbus/dbus.h>
25 : #include "sbus/sssd_dbus.h"
26 :
27 : #include "util/util.h"
28 : #include "sbus/sbus_client.h"
29 : #include "providers/data_provider.h"
30 : #include "responder/common/responder.h"
31 : #include "responder/sudo/sudosrv_private.h"
32 : #include "db/sysdb.h"
33 :
34 : struct sss_dp_get_sudoers_info {
35 : struct sss_domain_info *dom;
36 :
37 : bool fast_reply;
38 : enum sss_dp_sudo_type type;
39 : const char *name;
40 : uint32_t num_rules;
41 : struct sysdb_attrs **rules;
42 : };
43 :
44 : static DBusMessage *
45 : sss_dp_get_sudoers_msg(void *pvt);
46 :
47 : struct tevent_req *
48 0 : sss_dp_get_sudoers_send(TALLOC_CTX *mem_ctx,
49 : struct resp_ctx *rctx,
50 : struct sss_domain_info *dom,
51 : bool fast_reply,
52 : enum sss_dp_sudo_type type,
53 : const char *name,
54 : uint32_t num_rules,
55 : struct sysdb_attrs **rules)
56 : {
57 : struct tevent_req *req;
58 : struct sss_dp_req_state *state;
59 : struct sss_dp_get_sudoers_info *info;
60 : errno_t ret;
61 0 : char *key = NULL;
62 :
63 0 : req = tevent_req_create(mem_ctx, &state, struct sss_dp_req_state);
64 0 : if (!req) {
65 0 : ret = ENOMEM;
66 0 : goto error;
67 : }
68 :
69 0 : if (!dom) {
70 0 : ret = EINVAL;
71 0 : goto error;
72 : }
73 :
74 0 : info = talloc_zero(state, struct sss_dp_get_sudoers_info);
75 0 : info->fast_reply = fast_reply;
76 0 : info->type = type;
77 0 : info->name = name;
78 0 : info->dom = dom;
79 0 : info->num_rules = num_rules;
80 0 : info->rules = rules;
81 :
82 0 : switch (info->type) {
83 : case SSS_DP_SUDO_REFRESH_RULES:
84 0 : key = talloc_asprintf(state, "%d:%u:%s@%s", type,
85 : num_rules, name, dom->name);
86 0 : break;
87 : case SSS_DP_SUDO_FULL_REFRESH:
88 0 : key = talloc_asprintf(state, "%d:%s", type, dom->name);
89 0 : break;
90 : }
91 :
92 0 : if (!key) {
93 0 : ret = ENOMEM;
94 0 : goto error;
95 : }
96 :
97 0 : ret = sss_dp_issue_request(state, rctx, key, dom, sss_dp_get_sudoers_msg,
98 : info, req);
99 0 : talloc_free(key);
100 0 : if (ret != EOK) {
101 0 : DEBUG(SSSDBG_OP_FAILURE,
102 : "Could not issue DP request [%d]: %s\n",
103 : ret, strerror(ret));
104 0 : goto error;
105 : }
106 :
107 0 : return req;
108 :
109 : error:
110 0 : tevent_req_error(req, ret);
111 0 : tevent_req_post(req, rctx->ev);
112 0 : return req;
113 : }
114 :
115 : static DBusMessage *
116 0 : sss_dp_get_sudoers_msg(void *pvt)
117 : {
118 : DBusMessage *msg;
119 : DBusMessageIter iter;
120 : DBusMessageIter array_iter;
121 : dbus_bool_t dbret;
122 : errno_t ret;
123 : struct sss_dp_get_sudoers_info *info;
124 0 : uint32_t be_type = 0;
125 0 : const char *rule_name = NULL;
126 : uint32_t i;
127 :
128 0 : info = talloc_get_type(pvt, struct sss_dp_get_sudoers_info);
129 :
130 0 : switch (info->type) {
131 : case SSS_DP_SUDO_REFRESH_RULES:
132 0 : be_type = BE_REQ_SUDO_RULES;
133 0 : break;
134 : case SSS_DP_SUDO_FULL_REFRESH:
135 0 : be_type = BE_REQ_SUDO_FULL;
136 0 : break;
137 : }
138 :
139 0 : if (info->fast_reply) {
140 0 : be_type |= BE_REQ_FAST;
141 : }
142 :
143 0 : msg = dbus_message_new_method_call(NULL,
144 : DP_PATH,
145 : DATA_PROVIDER_IFACE,
146 : DATA_PROVIDER_IFACE_SUDOHANDLER);
147 0 : if (msg == NULL) {
148 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
149 0 : return NULL;
150 : }
151 :
152 : /* create the message */
153 0 : DEBUG(SSSDBG_TRACE_FUNC,
154 : "Creating SUDOers request for [%s][%u][%s][%u]\n",
155 : info->dom->name, be_type, info->name, info->num_rules);
156 :
157 0 : dbus_message_iter_init_append(msg, &iter);
158 :
159 : /* BE TYPE */
160 0 : dbret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &be_type);
161 0 : if (dbret == FALSE) {
162 0 : goto fail;
163 : }
164 :
165 : /* BE TYPE SPECIFIC */
166 0 : if (be_type & BE_REQ_SUDO_RULES) {
167 0 : dbret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32,
168 0 : &info->num_rules);
169 0 : if (dbret == FALSE) {
170 0 : goto fail;
171 : }
172 :
173 0 : dbret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
174 : DBUS_TYPE_STRING_AS_STRING,
175 : &array_iter);
176 0 : if (dbret == FALSE) {
177 0 : goto fail;
178 : }
179 :
180 0 : for (i = 0; i < info->num_rules; i++) {
181 0 : ret = sysdb_attrs_get_string(info->rules[i], SYSDB_NAME, &rule_name);
182 0 : if (ret != EOK) {
183 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not get rule name [%d]: %s\n",
184 : ret, strerror(ret));
185 0 : goto fail;
186 : }
187 :
188 0 : dbret = dbus_message_iter_append_basic(&array_iter,
189 : DBUS_TYPE_STRING,
190 : &rule_name);
191 0 : if (dbret == FALSE) {
192 0 : goto fail;
193 : }
194 : }
195 :
196 0 : dbret = dbus_message_iter_close_container(&iter, &array_iter);
197 0 : if (dbret == FALSE) {
198 0 : goto fail;
199 : }
200 : }
201 :
202 0 : return msg;
203 :
204 : fail:
205 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n");
206 0 : dbus_message_unref(msg);
207 0 : return NULL;
208 : }
209 :
210 : errno_t
211 0 : sss_dp_get_sudoers_recv(TALLOC_CTX *mem_ctx,
212 : struct tevent_req *req,
213 : dbus_uint16_t *dp_err,
214 : dbus_uint32_t *dp_ret,
215 : char **err_msg)
216 : {
217 0 : return sss_dp_req_recv(mem_ctx, req, dp_err, dp_ret, err_msg);
218 : }
|