Line data Source code
1 : /*
2 : Authors:
3 : Pavel Březina <pbrezina@redhat.com>
4 :
5 : Copyright (C) 2011 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 "config.h"
22 :
23 : #include <stdlib.h>
24 : #include <stdio.h>
25 : #include <string.h>
26 : #include <errno.h>
27 :
28 : #include "util/util.h"
29 : #include "sss_client/sss_cli.h"
30 : #include "sss_client/sudo/sss_sudo.h"
31 : #include "sss_client/sudo/sss_sudo_private.h"
32 :
33 : int sss_sudo_create_query(uid_t uid,
34 : const char *username,
35 : uint8_t **_query,
36 : size_t *_query_len);
37 :
38 : static void sss_sudo_free_rules(unsigned int num_rules,
39 : struct sss_sudo_rule *rules);
40 :
41 : static void sss_sudo_free_attrs(unsigned int num_attrs,
42 : struct sss_sudo_attr *attrs);
43 :
44 0 : static int sss_sudo_send_recv_generic(enum sss_cli_command command,
45 : uid_t uid,
46 : const char *username,
47 : uint32_t *_error,
48 : char **_domainname,
49 : struct sss_sudo_result **_result)
50 : {
51 : struct sss_cli_req_data request;
52 0 : uint8_t *query_buf = NULL;
53 0 : size_t query_len = 0;
54 0 : uint8_t *reply_buf = NULL;
55 0 : size_t reply_len = 0;
56 0 : int errnop = 0;
57 0 : int ret = 0;
58 :
59 : /* create query */
60 :
61 0 : ret = sss_sudo_create_query(uid, username, &query_buf, &query_len);
62 0 : if (ret != EOK) {
63 0 : goto done;
64 : }
65 :
66 0 : request.len = query_len;
67 0 : request.data = (const void*)query_buf;
68 :
69 : /* send query and receive response */
70 :
71 0 : errnop = 0;
72 0 : ret = sss_sudo_make_request(command, &request,
73 : &reply_buf, &reply_len, &errnop);
74 0 : if (ret != SSS_STATUS_SUCCESS) {
75 0 : ret = errnop;
76 0 : goto done;
77 : }
78 :
79 : /* parse structure */
80 :
81 0 : ret = sss_sudo_parse_response((const char*)reply_buf, reply_len,
82 : _domainname, _result, _error);
83 :
84 : done:
85 0 : free(query_buf);
86 0 : free(reply_buf);
87 0 : return ret;
88 : }
89 :
90 0 : int sss_sudo_send_recv(uid_t uid,
91 : const char *username,
92 : const char *domainname,
93 : uint32_t *_error,
94 : struct sss_sudo_result **_result)
95 : {
96 : int ret;
97 :
98 0 : if (username == NULL || strlen(username) == 0) {
99 0 : return EINVAL;
100 : }
101 :
102 : /* send query and receive response */
103 :
104 0 : ret = sss_sudo_send_recv_generic(SSS_SUDO_GET_SUDORULES, uid, username,
105 : _error, NULL, _result);
106 0 : return ret;
107 : }
108 :
109 0 : int sss_sudo_send_recv_defaults(uid_t uid,
110 : const char *username,
111 : uint32_t *_error,
112 : char **_domainname,
113 : struct sss_sudo_result **_result)
114 : {
115 0 : if (username == NULL || strlen(username) == 0) {
116 0 : return EINVAL;
117 : }
118 :
119 0 : return sss_sudo_send_recv_generic(SSS_SUDO_GET_DEFAULTS, uid, username,
120 : _error, _domainname, _result);
121 : }
122 :
123 0 : int sss_sudo_create_query(uid_t uid, const char *username,
124 : uint8_t **_query, size_t *_query_len)
125 : {
126 0 : uint8_t *data = NULL;
127 0 : size_t username_len = strlen(username) * sizeof(char) + 1;
128 0 : size_t data_len = sizeof(uid_t) + username_len;
129 0 : size_t offset = 0;
130 :
131 0 : data = (uint8_t*)malloc(data_len * sizeof(uint8_t));
132 0 : if (data == NULL) {
133 0 : return ENOMEM;
134 : }
135 :
136 0 : SAFEALIGN_SET_VALUE(data, uid, uid_t, &offset);
137 0 : memcpy(data + offset, username, username_len);
138 :
139 0 : *_query = data;
140 0 : *_query_len = data_len;
141 :
142 0 : return EOK;
143 : }
144 :
145 0 : int sss_sudo_get_values(struct sss_sudo_rule *e,
146 : const char *attrname, char ***_values)
147 : {
148 0 : struct sss_sudo_attr *attr = NULL;
149 0 : char **values = NULL;
150 : int i, j;
151 :
152 0 : for (i = 0; i < e->num_attrs; i++) {
153 0 : attr = e->attrs + i;
154 0 : if (strcasecmp(attr->name, attrname) == 0) {
155 0 : values = calloc(attr->num_values + 1, sizeof(char*));
156 0 : if (values == NULL) {
157 0 : return ENOMEM;
158 : }
159 :
160 0 : for (j = 0; j < attr->num_values; j++) {
161 0 : values[j] = strdup(attr->values[j]);
162 0 : if (values[j] == NULL) {
163 0 : sss_sudo_free_values(values);
164 0 : return ENOMEM;
165 : }
166 : }
167 :
168 0 : values[attr->num_values] = NULL;
169 :
170 0 : break;
171 : }
172 : }
173 :
174 0 : if (values == NULL) {
175 0 : return ENOENT;
176 : }
177 :
178 0 : *_values = values;
179 :
180 0 : return EOK;
181 : }
182 :
183 0 : void sss_sudo_free_values(char **values)
184 : {
185 0 : char **value = NULL;
186 :
187 0 : if (values == NULL) {
188 0 : return;
189 : }
190 :
191 0 : for (value = values; *value != NULL; value++) {
192 0 : free(*value);
193 : }
194 :
195 0 : free(values);
196 : }
197 :
198 0 : void sss_sudo_free_result(struct sss_sudo_result *result)
199 : {
200 0 : if (result == NULL) {
201 0 : return;
202 : }
203 :
204 0 : sss_sudo_free_rules(result->num_rules, result->rules);
205 0 : free(result);
206 : }
207 :
208 0 : void sss_sudo_free_rules(unsigned int num_rules, struct sss_sudo_rule *rules)
209 : {
210 0 : struct sss_sudo_rule *rule = NULL;
211 : int i;
212 :
213 0 : if (rules == NULL) {
214 0 : return;
215 : }
216 :
217 0 : for (i = 0; i < num_rules; i++) {
218 0 : rule = rules + i;
219 :
220 0 : sss_sudo_free_attrs(rule->num_attrs, rule->attrs);
221 0 : rule->attrs = NULL;
222 : }
223 :
224 0 : free(rules);
225 : }
226 :
227 0 : void sss_sudo_free_attrs(unsigned int num_attrs, struct sss_sudo_attr *attrs)
228 : {
229 0 : struct sss_sudo_attr *attr = NULL;;
230 : int i, j;
231 :
232 0 : if (attrs == NULL) {
233 0 : return;
234 : }
235 :
236 0 : for (i = 0; i < num_attrs; i++) {
237 0 : attr = attrs + i;
238 :
239 0 : free(attr->name);
240 0 : attr->name = NULL;
241 :
242 0 : for (j = 0; j < attr->num_values; j++) {
243 0 : free(attr->values[j]);
244 0 : attr->values[j] = NULL;
245 : }
246 :
247 0 : free(attr->values);
248 : }
249 :
250 0 : free(attrs);
251 : }
|