Line data Source code
1 : /*
2 : SSSD
3 :
4 : sss_cache
5 :
6 : Copyright (C) Jan Zeleny <jzeleny@redhat.com> 2011
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 <stdio.h>
23 : #include <stdlib.h>
24 : #include <talloc.h>
25 : #include <popt.h>
26 : #include <sys/types.h>
27 :
28 : #include "util/util.h"
29 : #include "tools/sss_sync_ops.h"
30 : #include "db/sysdb.h"
31 : #include "db/sysdb_services.h"
32 : #include "db/sysdb_autofs.h"
33 : #include "db/sysdb_ssh.h"
34 :
35 : #define INVALIDATE_NONE 0
36 : #define INVALIDATE_USERS 1
37 : #define INVALIDATE_GROUPS 2
38 : #define INVALIDATE_NETGROUPS 4
39 : #define INVALIDATE_SERVICES 8
40 : #define INVALIDATE_AUTOFSMAPS 16
41 : #define INVALIDATE_SSH_HOSTS 32
42 :
43 : #ifdef BUILD_AUTOFS
44 : #ifdef BUILD_SSH
45 : #define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \
46 : INVALIDATE_NETGROUPS | INVALIDATE_SERVICES | \
47 : INVALIDATE_AUTOFSMAPS | INVALIDATE_SSH_HOSTS )
48 : #else /* BUILD_SSH */
49 : #define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \
50 : INVALIDATE_NETGROUPS | INVALIDATE_SERVICES | \
51 : INVALIDATE_AUTOFSMAPS )
52 : #endif /* BUILD_SSH */
53 : #else /* BUILD_AUTOFS */
54 : #ifdef BUILD_SSH
55 : #define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \
56 : INVALIDATE_NETGROUPS | INVALIDATE_SERVICES | \
57 : INVALIDATE_SSH_HOSTS )
58 : #else /* BUILD_SSH */
59 : #define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \
60 : INVALIDATE_NETGROUPS | INVALIDATE_SERVICES )
61 : #endif /* BUILD_SSH */
62 : #endif /* BUILD_AUTOFS */
63 :
64 : enum sss_cache_entry {
65 : TYPE_USER=0,
66 : TYPE_GROUP,
67 : TYPE_NETGROUP,
68 : TYPE_SERVICE,
69 : TYPE_AUTOFSMAP,
70 : TYPE_SSH_HOST
71 : };
72 :
73 : static errno_t search_autofsmaps(TALLOC_CTX *mem_ctx,
74 : struct sss_domain_info *domain,
75 : const char *sub_filter, const char **attrs,
76 : size_t *msgs_count, struct ldb_message ***msgs);
77 :
78 : struct cache_tool_ctx {
79 : struct confdb_ctx *confdb;
80 : struct sss_domain_info *domains;
81 :
82 : char *user_filter;
83 : char *group_filter;
84 : char *netgroup_filter;
85 : char *service_filter;
86 : char *autofs_filter;
87 : char *ssh_host_filter;
88 :
89 : char *user_name;
90 : char *group_name;
91 : char *netgroup_name;
92 : char *service_name;
93 : char *autofs_name;
94 : char *ssh_host_name;
95 :
96 : bool update_user_filter;
97 : bool update_group_filter;
98 : bool update_netgroup_filter;
99 : bool update_service_filter;
100 : bool update_autofs_filter;
101 : bool update_ssh_host_filter;
102 : };
103 :
104 : errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain);
105 : errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx);
106 : static errno_t invalidate_entry(TALLOC_CTX *ctx,
107 : struct sss_domain_info *domain,
108 : const char *name, int entry_type);
109 : static bool invalidate_entries(TALLOC_CTX *ctx,
110 : struct sss_domain_info *dinfo,
111 : enum sss_cache_entry entry_type,
112 : const char *filter, const char *name);
113 : static errno_t update_all_filters(struct cache_tool_ctx *tctx,
114 : struct sss_domain_info *dinfo);
115 :
116 0 : int main(int argc, const char *argv[])
117 : {
118 : errno_t ret;
119 0 : struct cache_tool_ctx *tctx = NULL;
120 : struct sysdb_ctx *sysdb;
121 0 : bool skipped = true;
122 : struct sss_domain_info *dinfo;
123 :
124 0 : ret = init_context(argc, argv, &tctx);
125 0 : if (ret != EOK) {
126 0 : DEBUG(SSSDBG_CRIT_FAILURE,
127 : "Error initializing context for the application\n");
128 0 : goto done;
129 : }
130 :
131 0 : for (dinfo = tctx->domains; dinfo; dinfo = get_next_domain(dinfo, true)) {
132 0 : if (!IS_SUBDOMAIN(dinfo)) {
133 : /* Update list of subdomains for this domain */
134 0 : ret = sysdb_update_subdomains(dinfo);
135 0 : if (ret != EOK) {
136 0 : DEBUG(SSSDBG_MINOR_FAILURE,
137 : "Failed to update subdomains for domain %s.\n", dinfo->name);
138 : }
139 : }
140 :
141 0 : sysdb = dinfo->sysdb;
142 : /* Update filters for each domain */
143 0 : ret = update_all_filters(tctx, dinfo);
144 0 : if (ret != EOK) {
145 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to update filters.\n");
146 0 : goto done;
147 : }
148 :
149 0 : ret = sysdb_transaction_start(sysdb);
150 0 : if (ret != EOK) {
151 0 : DEBUG(SSSDBG_CRIT_FAILURE,
152 : "Could not start the transaction!\n");
153 0 : goto done;
154 : }
155 :
156 0 : skipped &= !invalidate_entries(tctx, dinfo, TYPE_USER,
157 0 : tctx->user_filter,
158 0 : tctx->user_name);
159 0 : skipped &= !invalidate_entries(tctx, dinfo, TYPE_GROUP,
160 0 : tctx->group_filter,
161 0 : tctx->group_name);
162 0 : skipped &= !invalidate_entries(tctx, dinfo, TYPE_NETGROUP,
163 0 : tctx->netgroup_filter,
164 0 : tctx->netgroup_name);
165 0 : skipped &= !invalidate_entries(tctx, dinfo, TYPE_SERVICE,
166 0 : tctx->service_filter,
167 0 : tctx->service_name);
168 0 : skipped &= !invalidate_entries(tctx, dinfo, TYPE_AUTOFSMAP,
169 0 : tctx->autofs_filter,
170 0 : tctx->autofs_name);
171 0 : skipped &= !invalidate_entries(tctx, dinfo, TYPE_SSH_HOST,
172 0 : tctx->ssh_host_filter,
173 0 : tctx->ssh_host_name);
174 :
175 0 : ret = sysdb_transaction_commit(sysdb);
176 0 : if (ret != EOK) {
177 0 : DEBUG(SSSDBG_CRIT_FAILURE,
178 : "Could not commit the transaction!\n");
179 0 : ret = sysdb_transaction_cancel(sysdb);
180 0 : if (ret != EOK) {
181 0 : DEBUG(SSSDBG_CRIT_FAILURE,
182 : "Failed to cancel transaction\n");
183 : }
184 : }
185 : }
186 :
187 0 : if (skipped == true) {
188 0 : ERROR("No cache object matched the specified search\n");
189 0 : ret = ENOENT;
190 0 : goto done;
191 : } else {
192 0 : ret = sss_memcache_clear_all();
193 0 : if (ret != EOK) {
194 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to clear memory cache.\n");
195 0 : goto done;
196 : }
197 : }
198 :
199 0 : ret = EOK;
200 : done:
201 0 : if (tctx) talloc_free(tctx);
202 0 : return ret;
203 : }
204 :
205 0 : static errno_t update_filter(struct cache_tool_ctx *tctx,
206 : struct sss_domain_info *dinfo,
207 : char *name, bool update, const char *fmt,
208 : bool force_case_sensitivity,
209 : char **_filter)
210 : {
211 : errno_t ret;
212 0 : char *parsed_domain = NULL;
213 0 : char *parsed_name = NULL;
214 0 : TALLOC_CTX *tmp_ctx = NULL;
215 0 : char *use_name = NULL;
216 : char *filter;
217 : char *sanitized;
218 : char *lc_sanitized;
219 :
220 0 : if (!name || !update) {
221 : /* Nothing to do */
222 0 : return EOK;
223 : }
224 :
225 0 : tmp_ctx = talloc_new(NULL);
226 0 : if (tmp_ctx == NULL) {
227 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n");
228 0 : return ENOMEM;
229 : }
230 :
231 0 : ret = sss_parse_name(tmp_ctx, dinfo->names, name,
232 : &parsed_domain, &parsed_name);
233 0 : if (ret != EOK) {
234 0 : DEBUG(SSSDBG_CRIT_FAILURE, "sss_parse_name failed\n");
235 0 : goto done;
236 : }
237 :
238 0 : if (parsed_domain != NULL && strcasecmp(dinfo->name, parsed_domain) != 0) {
239 : /* We were able to parse the domain from given fqdn, but it
240 : * does not match with currently processed domain. */
241 0 : filter = NULL;
242 0 : ret = EOK;
243 0 : goto done;
244 : }
245 :
246 0 : if (!dinfo->case_sensitive && !force_case_sensitivity) {
247 0 : use_name = sss_tc_utf8_str_tolower(tmp_ctx, parsed_name);
248 0 : if (!use_name) {
249 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n");
250 0 : ret = ENOMEM;
251 0 : goto done;
252 : }
253 : } else {
254 0 : use_name = parsed_name;
255 : }
256 :
257 0 : if (parsed_domain) {
258 0 : use_name = sss_get_domain_name(tmp_ctx, use_name, dinfo);
259 0 : if (!use_name) {
260 0 : ret = ENOMEM;
261 0 : goto done;
262 : }
263 : }
264 :
265 0 : ret = sss_filter_sanitize_for_dom(tmp_ctx, use_name, dinfo,
266 : &sanitized, &lc_sanitized);
267 0 : if (ret != EOK) {
268 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to sanitize the given name.\n");
269 0 : goto done;
270 : }
271 :
272 0 : if (fmt) {
273 0 : if (!dinfo->case_sensitive && !force_case_sensitivity) {
274 0 : filter = talloc_asprintf(tmp_ctx, "(|(%s=%s)(%s=%s))",
275 : SYSDB_NAME_ALIAS, lc_sanitized,
276 : SYSDB_NAME_ALIAS, sanitized);
277 : } else {
278 0 : filter = talloc_asprintf(tmp_ctx, fmt, SYSDB_NAME, sanitized);
279 : }
280 : } else {
281 0 : filter = talloc_strdup(tmp_ctx, sanitized);
282 : }
283 0 : if (filter == NULL) {
284 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n");
285 0 : ret = ENOMEM;
286 0 : goto done;
287 : }
288 :
289 0 : ret = EOK;
290 :
291 : done:
292 0 : if (ret == EOK) {
293 0 : talloc_free(*_filter);
294 0 : *_filter = talloc_steal(tctx, filter);
295 : }
296 :
297 0 : talloc_free(tmp_ctx);
298 0 : return ret;
299 :
300 : }
301 :
302 : /* This function updates all filters for specified domain using this
303 : * domains regex to parse string into domain and name (if exists). */
304 0 : static errno_t update_all_filters(struct cache_tool_ctx *tctx,
305 : struct sss_domain_info *dinfo)
306 : {
307 : errno_t ret;
308 :
309 : /* Update user filter */
310 0 : ret = update_filter(tctx, dinfo, tctx->user_name,
311 0 : tctx->update_user_filter, "(%s=%s)", false,
312 : &tctx->user_filter);
313 0 : if (ret != EOK) {
314 0 : return ret;
315 : }
316 :
317 : /* Update group filter */
318 0 : ret = update_filter(tctx, dinfo, tctx->group_name,
319 0 : tctx->update_group_filter, "(%s=%s)", false,
320 : &tctx->group_filter);
321 0 : if (ret != EOK) {
322 0 : return ret;
323 : }
324 :
325 : /* Update netgroup filter */
326 0 : ret = update_filter(tctx, dinfo, tctx->netgroup_name,
327 0 : tctx->update_netgroup_filter, "(%s=%s)", false,
328 : &tctx->netgroup_filter);
329 0 : if (ret != EOK) {
330 0 : return ret;
331 : }
332 :
333 : /* Update service filter */
334 0 : ret = update_filter(tctx, dinfo, tctx->service_name,
335 0 : tctx->update_service_filter, "(%s=%s)", false,
336 : &tctx->service_filter);
337 0 : if (ret != EOK) {
338 0 : return ret;
339 : }
340 :
341 : /* Update autofs filter */
342 0 : ret = update_filter(tctx, dinfo, tctx->autofs_name,
343 0 : tctx->update_autofs_filter,
344 : "(&(objectclass="SYSDB_AUTOFS_MAP_OC")(%s=%s))", true,
345 : &tctx->autofs_filter);
346 0 : if (ret != EOK) {
347 0 : return ret;
348 : }
349 :
350 : /* Update ssh host filter */
351 0 : ret = update_filter(tctx, dinfo, tctx->ssh_host_name,
352 0 : tctx->update_ssh_host_filter, "(%s=%s)", false,
353 : &tctx->ssh_host_filter);
354 0 : if (ret != EOK) {
355 0 : return ret;
356 : }
357 :
358 0 : return EOK;
359 : }
360 :
361 0 : static bool invalidate_entries(TALLOC_CTX *ctx,
362 : struct sss_domain_info *dinfo,
363 : enum sss_cache_entry entry_type,
364 : const char *filter, const char *name)
365 : {
366 0 : const char *attrs[] = {SYSDB_NAME, NULL};
367 : size_t msg_count;
368 : struct ldb_message **msgs;
369 0 : const char *type_string = "unknown";
370 0 : errno_t ret = EINVAL;
371 : int i;
372 : const char *c_name;
373 : bool iret;
374 :
375 0 : if (!filter) return false;
376 0 : switch (entry_type) {
377 : case TYPE_USER:
378 0 : type_string = "user";
379 0 : ret = sysdb_search_users(ctx, dinfo,
380 : filter, attrs, &msg_count, &msgs);
381 0 : break;
382 : case TYPE_GROUP:
383 0 : type_string = "group";
384 0 : ret = sysdb_search_groups(ctx, dinfo,
385 : filter, attrs, &msg_count, &msgs);
386 0 : break;
387 : case TYPE_NETGROUP:
388 0 : type_string = "netgroup";
389 0 : ret = sysdb_search_netgroups(ctx, dinfo,
390 : filter, attrs, &msg_count, &msgs);
391 0 : break;
392 : case TYPE_SERVICE:
393 0 : type_string = "service";
394 0 : ret = sysdb_search_services(ctx, dinfo,
395 : filter, attrs, &msg_count, &msgs);
396 0 : break;
397 : case TYPE_AUTOFSMAP:
398 0 : type_string = "autofs map";
399 0 : ret = search_autofsmaps(ctx, dinfo, filter, attrs, &msg_count, &msgs);
400 0 : break;
401 : case TYPE_SSH_HOST:
402 0 : type_string = "ssh_host";
403 : #ifdef BUILD_SSH
404 0 : ret = sysdb_search_ssh_hosts(ctx, dinfo,
405 : filter, attrs, &msg_count, &msgs);
406 : #else /* BUILD_SSH */
407 : ret = ENOSYS;
408 : #endif /* BUILD_SSH */
409 0 : break;
410 : }
411 :
412 0 : if (ret != EOK) {
413 0 : if (ret == ENOENT) {
414 0 : DEBUG(SSSDBG_TRACE_FUNC, "'%s' %s: Not found in domain '%s'\n",
415 : type_string, name ? name : "", dinfo->name);
416 : } else {
417 0 : DEBUG(SSSDBG_CRIT_FAILURE,
418 : "Searching for %s in domain %s with filter %s failed\n",
419 : type_string, dinfo->name, filter);
420 : }
421 0 : return false;
422 : }
423 :
424 0 : iret = true;
425 0 : for (i = 0; i < msg_count; i++) {
426 0 : c_name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL);
427 0 : if (c_name == NULL) {
428 0 : DEBUG(SSSDBG_MINOR_FAILURE,
429 : "Something bad happened, can't find attribute %s\n",
430 : SYSDB_NAME);
431 0 : ERROR("Couldn't invalidate %1$s\n", type_string);
432 0 : iret = false;
433 : } else {
434 0 : ret = invalidate_entry(ctx, dinfo, c_name, entry_type);
435 0 : if (ret != EOK) {
436 0 : DEBUG(SSSDBG_MINOR_FAILURE,
437 : "Couldn't invalidate %s %s\n", type_string, c_name);
438 0 : ERROR("Couldn't invalidate %1$s %2$s\n", type_string, c_name);
439 0 : iret = false;
440 : }
441 : }
442 : }
443 0 : talloc_zfree(msgs);
444 0 : return iret;
445 : }
446 :
447 0 : static errno_t invalidate_entry(TALLOC_CTX *ctx,
448 : struct sss_domain_info *domain,
449 : const char *name, int entry_type)
450 : {
451 0 : struct sysdb_attrs *sys_attrs = NULL;
452 : errno_t ret;
453 :
454 0 : sys_attrs = sysdb_new_attrs(ctx);
455 0 : if (sys_attrs) {
456 0 : ret = sysdb_attrs_add_time_t(sys_attrs,
457 : SYSDB_CACHE_EXPIRE, 1);
458 0 : if (ret == EOK) {
459 0 : switch (entry_type) {
460 : case TYPE_USER:
461 : /* For users, we also need to reset the initgroups
462 : * cache expiry */
463 0 : ret = sysdb_attrs_add_time_t(sys_attrs,
464 : SYSDB_INITGR_EXPIRE, 1);
465 0 : if (ret != EOK) return ret;
466 :
467 0 : ret = sysdb_set_user_attr(domain, name, sys_attrs,
468 : SYSDB_MOD_REP);
469 0 : break;
470 : case TYPE_GROUP:
471 0 : ret = sysdb_set_group_attr(domain, name, sys_attrs,
472 : SYSDB_MOD_REP);
473 0 : break;
474 : case TYPE_NETGROUP:
475 0 : ret = sysdb_set_netgroup_attr(domain, name, sys_attrs,
476 : SYSDB_MOD_REP);
477 0 : break;
478 : case TYPE_SERVICE:
479 0 : ret = sysdb_set_service_attr(domain, name,
480 : sys_attrs, SYSDB_MOD_REP);
481 0 : break;
482 : case TYPE_AUTOFSMAP:
483 0 : ret = sysdb_set_autofsmap_attr(domain, name,
484 : sys_attrs, SYSDB_MOD_REP);
485 0 : break;
486 : case TYPE_SSH_HOST:
487 : #ifdef BUILD_SSH
488 0 : ret = sysdb_set_ssh_host_attr(domain, name,
489 : sys_attrs, SYSDB_MOD_REP);
490 : #else /* BUILD_SSH */
491 : ret = ENOSYS;
492 : #endif /* BUILD_SSH */
493 0 : break;
494 : default:
495 0 : return EINVAL;
496 : }
497 0 : if (ret != EOK) {
498 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Could not set entry attributes\n");
499 : }
500 : } else {
501 0 : DEBUG(SSSDBG_MINOR_FAILURE,
502 : "Could not add expiration time to attributes\n");
503 : }
504 0 : talloc_zfree(sys_attrs);
505 : } else {
506 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Could not create sysdb attributes\n");
507 0 : ret = ENOMEM;
508 : }
509 0 : return ret;
510 : }
511 :
512 0 : errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain)
513 : {
514 : char *confdb_path;
515 : int ret;
516 : struct sss_domain_info *dinfo;
517 :
518 0 : confdb_path = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE);
519 0 : if (confdb_path == NULL) {
520 0 : return ENOMEM;
521 : }
522 :
523 : /* Connect to the conf db */
524 0 : ret = confdb_init(ctx, &ctx->confdb, confdb_path);
525 0 : talloc_free(confdb_path);
526 0 : if (ret != EOK) {
527 0 : DEBUG(SSSDBG_CRIT_FAILURE,
528 : "Could not initialize connection to the confdb\n");
529 0 : return ret;
530 : }
531 :
532 0 : if (domain) {
533 0 : ret = sssd_domain_init(ctx, ctx->confdb,
534 : domain, DB_PATH, &ctx->domains);
535 0 : if (ret != EOK) {
536 0 : SYSDB_VERSION_ERROR(ret);
537 0 : DEBUG(SSSDBG_CRIT_FAILURE,
538 : "Could not initialize connection to the sysdb\n");
539 0 : return ret;
540 : }
541 :
542 : } else {
543 0 : ret = confdb_get_domains(ctx->confdb, &ctx->domains);
544 0 : if (ret != EOK) {
545 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize domains\n");
546 0 : return ret;
547 : }
548 :
549 0 : ret = sysdb_init(ctx, ctx->domains, false);
550 0 : SYSDB_VERSION_ERROR(ret);
551 0 : if (ret != EOK) {
552 0 : DEBUG(SSSDBG_CRIT_FAILURE,
553 : "Could not initialize connection to the sysdb\n");
554 0 : return ret;
555 : }
556 : }
557 :
558 0 : for (dinfo = ctx->domains; dinfo; dinfo = get_next_domain(dinfo, false)) {
559 0 : ret = sss_names_init(ctx, ctx->confdb, dinfo->name, &dinfo->names);
560 0 : if (ret != EOK) {
561 0 : DEBUG(SSSDBG_CRIT_FAILURE, "sss_names_init() failed\n");
562 0 : return ret;
563 : }
564 : }
565 :
566 0 : return EOK;
567 : }
568 :
569 0 : errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx)
570 : {
571 0 : struct cache_tool_ctx *ctx = NULL;
572 0 : int idb = INVALIDATE_NONE;
573 0 : char *user = NULL;
574 0 : char *group = NULL;
575 0 : char *netgroup = NULL;
576 0 : char *service = NULL;
577 0 : char *map = NULL;
578 0 : char *ssh_host = NULL;
579 0 : char *domain = NULL;
580 0 : int debug = SSSDBG_DEFAULT;
581 0 : errno_t ret = EOK;
582 :
583 0 : poptContext pc = NULL;
584 0 : struct poptOption long_options[] = {
585 : POPT_AUTOHELP
586 : { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &debug,
587 0 : 0, _("The debug level to run with"), NULL },
588 : { "everything", 'E', POPT_ARG_NONE, NULL, 'e',
589 0 : _("Invalidate all cached entries except for sudo rules"), NULL },
590 : { "user", 'u', POPT_ARG_STRING, &user, 0,
591 0 : _("Invalidate particular user"), NULL },
592 : { "users", 'U', POPT_ARG_NONE, NULL, 'u',
593 0 : _("Invalidate all users"), NULL },
594 : { "group", 'g', POPT_ARG_STRING, &group, 0,
595 0 : _("Invalidate particular group"), NULL },
596 : { "groups", 'G', POPT_ARG_NONE, NULL, 'g',
597 0 : _("Invalidate all groups"), NULL },
598 : { "netgroup", 'n', POPT_ARG_STRING, &netgroup, 0,
599 0 : _("Invalidate particular netgroup"), NULL },
600 : { "netgroups", 'N', POPT_ARG_NONE, NULL, 'n',
601 0 : _("Invalidate all netgroups"), NULL },
602 : { "service", 's', POPT_ARG_STRING, &service, 0,
603 0 : _("Invalidate particular service"), NULL },
604 : { "services", 'S', POPT_ARG_NONE, NULL, 's',
605 0 : _("Invalidate all services"), NULL },
606 : #ifdef BUILD_AUTOFS
607 : { "autofs-map", 'a', POPT_ARG_STRING, &map, 0,
608 0 : _("Invalidate particular autofs map"), NULL },
609 : { "autofs-maps", 'A', POPT_ARG_NONE, NULL, 'a',
610 0 : _("Invalidate all autofs maps"), NULL },
611 : #endif /* BUILD_AUTOFS */
612 : #ifdef BUILD_SSH
613 : { "ssh-host", 'h', POPT_ARG_STRING, &ssh_host, 0,
614 0 : _("Invalidate particular SSH host"), NULL },
615 : { "ssh-hosts", 'H', POPT_ARG_NONE, NULL, 'h',
616 0 : _("Invalidate all SSH hosts"), NULL },
617 : #endif /* BUILD_SSH */
618 : { "domain", 'd', POPT_ARG_STRING, &domain, 0,
619 0 : _("Only invalidate entries from a particular domain"), NULL },
620 : POPT_TABLEEND
621 : };
622 :
623 0 : ret = set_locale();
624 0 : if (ret != EOK) {
625 0 : DEBUG(SSSDBG_CRIT_FAILURE,
626 : "set_locale failed (%d): %s\n", ret, strerror(ret));
627 0 : ERROR("Error setting the locale\n");
628 0 : goto fini;
629 : }
630 :
631 0 : pc = poptGetContext(NULL, argc, argv, long_options, 0);
632 0 : while ((ret = poptGetNextOpt(pc)) > 0) {
633 0 : switch (ret) {
634 : case 'u':
635 0 : idb |= INVALIDATE_USERS;
636 0 : break;
637 : case 'g':
638 0 : idb |= INVALIDATE_GROUPS;
639 0 : break;
640 : case 'n':
641 0 : idb |= INVALIDATE_NETGROUPS;
642 0 : break;
643 : case 's':
644 0 : idb |= INVALIDATE_SERVICES;
645 0 : break;
646 : case 'a':
647 0 : idb |= INVALIDATE_AUTOFSMAPS;
648 0 : break;
649 : case 'h':
650 0 : idb |= INVALIDATE_SSH_HOSTS;
651 0 : break;
652 : case 'e':
653 0 : idb = INVALIDATE_EVERYTHING;
654 0 : break;
655 : }
656 : }
657 :
658 0 : DEBUG_CLI_INIT(debug);
659 0 : debug_prg_name = argv[0];
660 :
661 0 : if (ret != -1) {
662 0 : BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini);
663 : }
664 :
665 0 : if (idb == INVALIDATE_NONE && !user && !group &&
666 0 : !netgroup && !service && !map && !ssh_host) {
667 0 : BAD_POPT_PARAMS(pc,
668 : _("Please select at least one object to invalidate\n"),
669 : ret, fini);
670 : }
671 :
672 0 : CHECK_ROOT(ret, debug_prg_name);
673 :
674 0 : ctx = talloc_zero(NULL, struct cache_tool_ctx);
675 0 : if (ctx == NULL) {
676 0 : DEBUG(SSSDBG_CRIT_FAILURE,
677 : "Could not allocate memory for tools context\n");
678 0 : ret = ENOMEM;
679 0 : goto fini;
680 : }
681 :
682 0 : if (idb & INVALIDATE_USERS) {
683 0 : ctx->user_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME);
684 0 : ctx->update_user_filter = false;
685 0 : } else if (user) {
686 0 : ctx->user_name = talloc_strdup(ctx, user);
687 0 : ctx->update_user_filter = true;
688 : }
689 :
690 0 : if (idb & INVALIDATE_GROUPS) {
691 0 : ctx->group_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME);
692 0 : ctx->update_group_filter = false;
693 0 : } else if (group) {
694 0 : ctx->group_name = talloc_strdup(ctx, group);
695 0 : ctx->update_group_filter = true;
696 : }
697 :
698 0 : if (idb & INVALIDATE_NETGROUPS) {
699 0 : ctx->netgroup_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME);
700 0 : ctx->update_netgroup_filter = false;
701 0 : } else if (netgroup) {
702 0 : ctx->netgroup_name = talloc_strdup(ctx, netgroup);
703 0 : ctx->update_netgroup_filter = true;
704 : }
705 :
706 0 : if (idb & INVALIDATE_SERVICES) {
707 0 : ctx->service_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME);
708 0 : ctx->update_service_filter = false;
709 0 : } else if (service) {
710 0 : ctx->service_name = talloc_strdup(ctx, service);
711 0 : ctx->update_service_filter = true;
712 : }
713 :
714 0 : if (idb & INVALIDATE_AUTOFSMAPS) {
715 0 : ctx->autofs_filter = talloc_asprintf(ctx, "(&(objectclass=%s)(%s=*))",
716 : SYSDB_AUTOFS_MAP_OC, SYSDB_NAME);
717 0 : ctx->update_autofs_filter = false;
718 0 : } else if (map) {
719 0 : ctx->autofs_name = talloc_strdup(ctx, map);
720 0 : ctx->update_autofs_filter = true;
721 : }
722 :
723 0 : if (idb & INVALIDATE_SSH_HOSTS) {
724 0 : ctx->ssh_host_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME);
725 0 : ctx->update_ssh_host_filter = false;
726 0 : } else if (ssh_host) {
727 0 : ctx->ssh_host_name = talloc_strdup(ctx, ssh_host);
728 0 : ctx->update_ssh_host_filter = true;
729 : }
730 :
731 0 : if (((idb & INVALIDATE_USERS) && !ctx->user_filter) ||
732 0 : ((idb & INVALIDATE_GROUPS) && !ctx->group_filter) ||
733 0 : ((idb & INVALIDATE_NETGROUPS) && !ctx->netgroup_filter) ||
734 0 : ((idb & INVALIDATE_SERVICES) && !ctx->service_filter) ||
735 0 : ((idb & INVALIDATE_AUTOFSMAPS) && !ctx->autofs_filter) ||
736 0 : ((idb & INVALIDATE_SSH_HOSTS) && !ctx->ssh_host_filter) ||
737 0 : (user && !ctx->user_name) ||
738 0 : (group && !ctx->group_name) ||
739 0 : (netgroup && !ctx->netgroup_name) ||
740 0 : (service && !ctx->service_name) ||
741 0 : (map && !ctx->autofs_name) ||
742 0 : (ssh_host && !ctx->ssh_host_name)) {
743 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Construction of filters failed\n");
744 0 : ret = ENOMEM;
745 0 : goto fini;
746 : }
747 :
748 0 : ret = init_domains(ctx, domain);
749 0 : if (ret != EOK) {
750 0 : if (domain) {
751 0 : ERROR("Could not open domain %1$s. If the domain is a subdomain "
752 : "(trusted domain), use fully qualified name instead of "
753 : "--domain/-d parameter.\n", domain);
754 : } else {
755 0 : ERROR("Could not open available domains\n");
756 : }
757 0 : DEBUG(SSSDBG_OP_FAILURE,
758 : "Initialization of sysdb connections failed\n");
759 0 : goto fini;
760 : }
761 :
762 0 : ret = EOK;
763 :
764 : fini:
765 0 : poptFreeContext(pc);
766 0 : free(user);
767 0 : free(group);
768 0 : free(netgroup);
769 0 : free(domain);
770 0 : if (ret != EOK && ctx) {
771 0 : talloc_zfree(ctx);
772 : }
773 0 : if (ret == EOK) {
774 0 : *tctx = ctx;
775 : }
776 0 : return ret;
777 : }
778 :
779 : static errno_t
780 0 : search_autofsmaps(TALLOC_CTX *mem_ctx,
781 : struct sss_domain_info *domain,
782 : const char *sub_filter, const char **attrs,
783 : size_t *msgs_count, struct ldb_message ***msgs)
784 : {
785 : #ifdef BUILD_AUTOFS
786 0 : return sysdb_search_custom(mem_ctx, domain, sub_filter,
787 : AUTOFS_MAP_SUBDIR, attrs,
788 : msgs_count, msgs);
789 : #else
790 : return ENOSYS;
791 : #endif /* BUILD_AUTOFS */
792 : }
|