Line data Source code
1 : /*
2 : Authors:
3 : Jakub Hrozek <jhrozek@redhat.com>
4 :
5 : Copyright (C) 2012 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 :
23 : #include "db/sysdb.h"
24 : #include "db/sysdb_private.h"
25 : #include "db/sysdb_autofs.h"
26 :
27 : #define SYSDB_TMPL_AUTOFS_ENTRY SYSDB_NAME"=%s,"SYSDB_TMPL_CUSTOM
28 :
29 : static struct ldb_dn *
30 10 : sysdb_autofsmap_dn(TALLOC_CTX *mem_ctx,
31 : struct sss_domain_info *domain,
32 : const char *map_name)
33 : {
34 10 : return sysdb_custom_dn(mem_ctx, domain, map_name, AUTOFS_MAP_SUBDIR);
35 : }
36 :
37 : static struct ldb_dn *
38 110 : sysdb_autofsentry_dn(TALLOC_CTX *mem_ctx,
39 : struct sss_domain_info *domain,
40 : const char *map_name,
41 : const char *entry_name,
42 : const char *entry_value)
43 : {
44 : errno_t ret;
45 : TALLOC_CTX *tmp_ctx;
46 : char *clean_name;
47 : char *clean_value;
48 : const char *rdn;
49 110 : struct ldb_dn *dn = NULL;
50 :
51 110 : tmp_ctx = talloc_new(NULL);
52 110 : if (!tmp_ctx) {
53 0 : return NULL;
54 : }
55 :
56 110 : ret = sysdb_dn_sanitize(tmp_ctx, entry_name, &clean_name);
57 110 : if (ret != EOK) {
58 0 : goto done;
59 : }
60 :
61 110 : ret = sysdb_dn_sanitize(tmp_ctx, entry_value, &clean_value);
62 110 : if (ret != EOK) {
63 0 : goto done;
64 : }
65 :
66 110 : rdn = talloc_asprintf(tmp_ctx, "%s%s", clean_name, clean_value);
67 110 : if (!rdn) {
68 0 : goto done;
69 : }
70 :
71 110 : dn = ldb_dn_new_fmt(mem_ctx, domain->sysdb->ldb, SYSDB_TMPL_AUTOFS_ENTRY,
72 : rdn, map_name, AUTOFS_MAP_SUBDIR, domain->name);
73 :
74 : done:
75 110 : talloc_free(tmp_ctx);
76 110 : return dn;
77 : }
78 :
79 : char *
80 0 : sysdb_autofsentry_strdn(TALLOC_CTX *mem_ctx,
81 : struct sss_domain_info *domain,
82 : const char *map_name,
83 : const char *entry_name,
84 : const char *entry_value)
85 : {
86 : struct ldb_dn *dn;
87 : char *strdn;
88 :
89 0 : dn = sysdb_autofsentry_dn(mem_ctx, domain,
90 : map_name, entry_name, entry_value);
91 0 : if (!dn) return NULL;
92 :
93 0 : strdn = talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
94 0 : talloc_free(dn);
95 0 : return strdn;
96 : }
97 :
98 : errno_t
99 10 : sysdb_save_autofsmap(struct sss_domain_info *domain,
100 : const char *name,
101 : const char *autofsmapname,
102 : struct sysdb_attrs *attrs,
103 : int cache_timeout,
104 : time_t now)
105 : {
106 : errno_t ret;
107 : TALLOC_CTX *tmp_ctx;
108 :
109 10 : DEBUG(SSSDBG_TRACE_FUNC, "Adding autofs map %s\n", autofsmapname);
110 :
111 10 : tmp_ctx = talloc_new(NULL);
112 10 : if (!tmp_ctx) {
113 0 : return ENOMEM;
114 : }
115 :
116 10 : if (!attrs) {
117 10 : attrs = sysdb_new_attrs(tmp_ctx);
118 10 : if (!attrs) {
119 0 : ret = ENOMEM;
120 0 : goto done;
121 : }
122 : }
123 :
124 10 : ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS,
125 : SYSDB_AUTOFS_MAP_OC);
126 10 : if (ret != EOK) {
127 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not set map object class [%d]: %s\n",
128 : ret, strerror(ret));
129 0 : goto done;
130 : }
131 :
132 10 : ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_MAP_NAME, autofsmapname);
133 10 : if (ret != EOK) {
134 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not set map name [%d]: %s\n",
135 : ret, strerror(ret));
136 0 : goto done;
137 : }
138 :
139 10 : ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name);
140 10 : if (ret != EOK) {
141 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not set name attribute [%d]: %s\n",
142 : ret, strerror(ret));
143 0 : goto done;
144 : }
145 :
146 10 : ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now);
147 10 : if (ret) {
148 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not set sysdb lastUpdate [%d]: %s\n",
149 : ret, strerror(ret));
150 0 : goto done;
151 : }
152 :
153 10 : ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE,
154 : ((cache_timeout) ?
155 0 : (now + cache_timeout) : 0));
156 10 : if (ret) {
157 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not set sysdb cache expire [%d]: %s\n",
158 : ret, strerror(ret));
159 0 : goto done;
160 : }
161 :
162 10 : ret = sysdb_store_custom(domain, name, AUTOFS_MAP_SUBDIR, attrs);
163 10 : if (ret != EOK) {
164 0 : DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_custom failed [%d]: %s\n",
165 : ret, strerror(ret));
166 0 : goto done;
167 : }
168 :
169 10 : ret = EOK;
170 : done:
171 10 : talloc_free(tmp_ctx);
172 10 : return ret;
173 : }
174 :
175 : errno_t
176 10 : sysdb_delete_autofsmap(struct sss_domain_info *domain,
177 : const char *name)
178 : {
179 10 : DEBUG(SSSDBG_TRACE_FUNC, "Deleting autofs map %s\n", name);
180 10 : return sysdb_delete_custom(domain, name, AUTOFS_MAP_SUBDIR);
181 : }
182 :
183 : errno_t
184 20 : sysdb_get_map_byname(TALLOC_CTX *mem_ctx,
185 : struct sss_domain_info *domain,
186 : const char *map_name,
187 : struct ldb_message **_map)
188 : {
189 : errno_t ret;
190 : TALLOC_CTX *tmp_ctx;
191 : const char *filter;
192 : char *safe_map_name;
193 : size_t count;
194 : struct ldb_message **msgs;
195 20 : const char *attrs[] = { SYSDB_OBJECTCLASS,
196 : SYSDB_CACHE_EXPIRE,
197 : SYSDB_LAST_UPDATE,
198 : SYSDB_AUTOFS_MAP_NAME,
199 : SYSDB_MEMBER,
200 : NULL };
201 :
202 20 : tmp_ctx = talloc_new(NULL);
203 20 : if (!tmp_ctx) return ENOMEM;
204 :
205 20 : ret = sss_filter_sanitize(tmp_ctx, map_name, &safe_map_name);
206 20 : if (ret != EOK) {
207 0 : DEBUG(SSSDBG_CRIT_FAILURE,
208 : "Cannot sanitize map [%s] error [%d]: %s\n",
209 : map_name, ret, strerror(ret));
210 0 : goto done;
211 : }
212 :
213 20 : filter = talloc_asprintf(tmp_ctx, "(&(objectclass=%s)(%s=%s))",
214 : SYSDB_AUTOFS_MAP_OC, SYSDB_NAME, safe_map_name);
215 20 : if (!filter) {
216 0 : ret = ENOMEM;
217 0 : goto done;
218 : }
219 :
220 20 : ret = sysdb_search_custom(tmp_ctx, domain, filter,
221 : AUTOFS_MAP_SUBDIR, attrs,
222 : &count, &msgs);
223 20 : if (ret != EOK && ret != ENOENT) {
224 0 : DEBUG(SSSDBG_CRIT_FAILURE,
225 : "Error looking up autofs map [%s]\n", safe_map_name);
226 0 : goto done;
227 20 : } else if (ret == ENOENT) {
228 10 : DEBUG(SSSDBG_TRACE_FUNC, "No such map\n");
229 10 : *_map = NULL;
230 10 : goto done;
231 : }
232 :
233 10 : if (count != 1) {
234 0 : DEBUG(SSSDBG_CRIT_FAILURE,
235 : "More than one map named %s\n", safe_map_name);
236 0 : goto done;
237 : }
238 :
239 10 : *_map = talloc_steal(mem_ctx, msgs[0]);
240 10 : ret = EOK;
241 : done:
242 20 : talloc_free(tmp_ctx);
243 20 : return ret;
244 : }
245 :
246 : errno_t
247 110 : sysdb_save_autofsentry(struct sss_domain_info *domain,
248 : const char *map,
249 : const char *key,
250 : const char *value,
251 : struct sysdb_attrs *attrs)
252 : {
253 : errno_t ret;
254 : TALLOC_CTX *tmp_ctx;
255 : struct ldb_message *msg;
256 : struct ldb_dn *dn;
257 : const char *name;
258 :
259 110 : DEBUG(SSSDBG_TRACE_FUNC,
260 : "Adding autofs entry [%s] - [%s]\n", key, value);
261 :
262 110 : tmp_ctx = talloc_new(NULL);
263 110 : if (!tmp_ctx) {
264 0 : return ENOMEM;
265 : }
266 :
267 110 : if (!attrs) {
268 110 : attrs = sysdb_new_attrs(tmp_ctx);
269 110 : if (!attrs) {
270 0 : ret = ENOMEM;
271 0 : goto done;
272 : }
273 : }
274 :
275 110 : ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS,
276 : SYSDB_AUTOFS_ENTRY_OC);
277 110 : if (ret != EOK) {
278 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not set entry object class [%d]: %s\n",
279 : ret, strerror(ret));
280 0 : goto done;
281 : }
282 :
283 110 : ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_ENTRY_KEY, key);
284 110 : if (ret != EOK) {
285 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not set entry key [%d]: %s\n",
286 : ret, strerror(ret));
287 0 : goto done;
288 : }
289 :
290 110 : ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_ENTRY_VALUE, value);
291 110 : if (ret != EOK) {
292 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not set entry key [%d]: %s\n",
293 : ret, strerror(ret));
294 0 : goto done;
295 : }
296 :
297 110 : name = talloc_asprintf(tmp_ctx, "%s%s", key, value);
298 110 : if (!name) {
299 0 : ret = ENOMEM;
300 0 : goto done;
301 : }
302 :
303 110 : ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name);
304 110 : if (ret != EOK) {
305 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not set name attribute [%d]: %s\n",
306 : ret, strerror(ret));
307 0 : goto done;
308 : }
309 :
310 110 : dn = sysdb_autofsentry_dn(tmp_ctx, domain, map, key, value);
311 110 : if (!dn) {
312 0 : ret = ENOMEM;
313 0 : goto done;
314 : }
315 :
316 110 : msg = ldb_msg_new(tmp_ctx);
317 110 : if (!msg) {
318 0 : ret = ENOMEM;
319 0 : goto done;
320 : }
321 :
322 110 : msg->dn = dn;
323 110 : msg->elements = attrs->a;
324 110 : msg->num_elements = attrs->num;
325 :
326 110 : ret = ldb_add(domain->sysdb->ldb, msg);
327 110 : ret = sysdb_error_to_errno(ret);
328 : done:
329 110 : talloc_free(tmp_ctx);
330 110 : return ret;
331 : }
332 :
333 : errno_t
334 0 : sysdb_del_autofsentry(struct sss_domain_info *domain,
335 : const char *entry_dn)
336 : {
337 : struct ldb_dn *dn;
338 : errno_t ret;
339 :
340 0 : dn = ldb_dn_new(NULL, sysdb_ctx_get_ldb(domain->sysdb), entry_dn);
341 0 : if (!dn) {
342 0 : return ENOMEM;
343 : }
344 :
345 0 : ret = sysdb_delete_entry(domain->sysdb, dn, true);
346 0 : talloc_free(dn);
347 0 : return ret;
348 : }
349 :
350 : errno_t
351 10 : sysdb_autofs_entries_by_map(TALLOC_CTX *mem_ctx,
352 : struct sss_domain_info *domain,
353 : const char *mapname,
354 : size_t *_count,
355 : struct ldb_message ***_entries)
356 : {
357 : errno_t ret;
358 : TALLOC_CTX *tmp_ctx;
359 : char *filter;
360 10 : const char *attrs[] = { SYSDB_AUTOFS_ENTRY_KEY,
361 : SYSDB_AUTOFS_ENTRY_VALUE,
362 : NULL };
363 : size_t count;
364 : struct ldb_message **msgs;
365 : struct ldb_dn *mapdn;
366 :
367 10 : DEBUG(SSSDBG_TRACE_FUNC, "Getting entries for map %s\n", mapname);
368 :
369 10 : tmp_ctx = talloc_new(NULL);
370 10 : if (!tmp_ctx) {
371 0 : return ENOMEM;
372 : }
373 :
374 10 : mapdn = sysdb_autofsmap_dn(tmp_ctx, domain, mapname);
375 10 : if (!mapdn) {
376 0 : ret = ENOMEM;
377 0 : goto done;
378 : }
379 :
380 10 : filter = talloc_asprintf(tmp_ctx, "(objectclass=%s)",
381 : SYSDB_AUTOFS_ENTRY_OC);
382 10 : if (!filter) {
383 0 : ret = ENOMEM;
384 0 : goto done;
385 : }
386 :
387 10 : ret = sysdb_search_entry(tmp_ctx, domain->sysdb, mapdn, LDB_SCOPE_ONELEVEL,
388 : filter, attrs, &count, &msgs);
389 10 : if (ret != EOK && ret != ENOENT) {
390 0 : DEBUG(SSSDBG_OP_FAILURE, "sysdb search failed: %d\n", ret);
391 0 : goto done;
392 10 : } else if (ret == ENOENT) {
393 0 : DEBUG(SSSDBG_TRACE_FUNC, "No entries for the map\n");
394 0 : *_count = 0;
395 0 : *_entries = NULL;
396 0 : goto done;
397 : }
398 :
399 10 : *_count = count;
400 10 : *_entries = talloc_steal(mem_ctx, msgs);
401 10 : ret = EOK;
402 10 : DEBUG(SSSDBG_TRACE_INTERNAL, "found %zu entries for map %s\n",
403 : count, mapname);
404 : done:
405 10 : talloc_free(tmp_ctx);
406 10 : return ret;
407 : }
408 :
409 : errno_t
410 0 : sysdb_set_autofsmap_attr(struct sss_domain_info *domain,
411 : const char *name,
412 : struct sysdb_attrs *attrs,
413 : int mod_op)
414 : {
415 : errno_t ret;
416 : struct ldb_dn *dn;
417 : TALLOC_CTX *tmp_ctx;
418 :
419 0 : tmp_ctx = talloc_new(NULL);
420 0 : if (!tmp_ctx) {
421 0 : return ENOMEM;
422 : }
423 :
424 0 : dn = sysdb_autofsmap_dn(tmp_ctx, domain, name);
425 0 : if (!dn) {
426 0 : ret = ENOMEM;
427 0 : goto done;
428 : }
429 :
430 0 : ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, mod_op);
431 :
432 : done:
433 0 : talloc_free(tmp_ctx);
434 0 : return ret;
435 : }
436 :
437 : errno_t
438 0 : sysdb_invalidate_autofs_maps(struct sss_domain_info *domain)
439 : {
440 : errno_t ret;
441 : TALLOC_CTX *tmp_ctx;
442 : const char *filter;
443 0 : struct sysdb_attrs *sys_attrs = NULL;
444 0 : const char *attrs[] = { SYSDB_OBJECTCLASS,
445 : SYSDB_NAME,
446 : SYSDB_CACHE_EXPIRE,
447 : NULL };
448 : size_t count;
449 : struct ldb_message **msgs;
450 : const char *name;
451 0 : bool in_transaction = false;
452 : int sret;
453 : int i;
454 :
455 0 : tmp_ctx = talloc_new(NULL);
456 0 : if (!tmp_ctx) return ENOMEM;
457 :
458 0 : filter = talloc_asprintf(tmp_ctx, "(&(objectclass=%s)(%s=*))",
459 : SYSDB_AUTOFS_MAP_OC, SYSDB_NAME);
460 0 : if (!filter) {
461 0 : ret = ENOMEM;
462 0 : goto done;
463 : }
464 :
465 0 : ret = sysdb_search_custom(tmp_ctx, domain, filter,
466 : AUTOFS_MAP_SUBDIR, attrs,
467 : &count, &msgs);
468 0 : if (ret != EOK && ret != ENOENT) {
469 0 : DEBUG(SSSDBG_CRIT_FAILURE,
470 : "Error looking up autofs maps\n");
471 0 : goto done;
472 0 : } else if (ret == ENOENT) {
473 0 : ret = EOK;
474 0 : goto done;
475 : }
476 :
477 0 : sys_attrs = sysdb_new_attrs(tmp_ctx);
478 0 : if (!sys_attrs) {
479 0 : ret = ENOMEM;
480 0 : goto done;
481 : }
482 :
483 0 : ret = sysdb_attrs_add_time_t(sys_attrs, SYSDB_CACHE_EXPIRE, 1);
484 0 : if (ret != EOK) {
485 0 : goto done;
486 : }
487 :
488 0 : ret = sysdb_transaction_start(domain->sysdb);
489 0 : if (ret != EOK) {
490 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
491 0 : goto done;
492 : }
493 0 : in_transaction = true;
494 :
495 0 : for (i = 0; i < count; i++) {
496 0 : name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL);
497 0 : if (!name) {
498 0 : DEBUG(SSSDBG_MINOR_FAILURE, "A map with no name?\n");
499 0 : continue;
500 : }
501 :
502 0 : ret = sysdb_set_autofsmap_attr(domain, name,
503 : sys_attrs, SYSDB_MOD_REP);
504 0 : if (ret != EOK) {
505 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Could not expire map %s\n", name);
506 0 : continue;
507 : }
508 : }
509 :
510 0 : ret = sysdb_transaction_commit(domain->sysdb);
511 0 : if (ret != EOK) {
512 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not commit transaction\n");
513 0 : goto done;
514 : }
515 0 : in_transaction = false;
516 :
517 0 : ret = EOK;
518 : done:
519 0 : if (in_transaction) {
520 0 : sret = sysdb_transaction_cancel(domain->sysdb);
521 0 : if (sret != EOK) {
522 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not cancel transaction\n");
523 : }
524 : }
525 0 : talloc_free(tmp_ctx);
526 0 : return ret;
527 : }
|