Line data Source code
1 : /*
2 : SSSD
3 :
4 : Authors:
5 : Simo Sorce <ssorce@redhat.com>
6 : Stephen Gallagher <sgallagh@redhat.com>
7 :
8 : Copyright (C) 2008-2011 Simo Sorce <ssorce@redhat.com>
9 : Copyright (C) 2008-2011 Stephen Gallagher
10 :
11 : This program is free software; you can redistribute it and/or modify
12 : it under the terms of the GNU General Public License as published by
13 : the Free Software Foundation; either version 3 of the License, or
14 : (at your option) any later version.
15 :
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 :
21 : You should have received a copy of the GNU General Public License
22 : along with this program. If not, see <http://www.gnu.org/licenses/>.
23 : */
24 :
25 : #include "util/util.h"
26 : #include "db/sysdb_private.h"
27 : #include "db/sysdb_autofs.h"
28 :
29 : struct upgrade_ctx {
30 : struct ldb_context *ldb;
31 : const char *new_version;
32 : };
33 :
34 0 : static errno_t commence_upgrade(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
35 : const char *new_ver, struct upgrade_ctx **_ctx)
36 : {
37 : struct upgrade_ctx *ctx;
38 : int ret;
39 :
40 0 : DEBUG(SSSDBG_CRIT_FAILURE, "UPGRADING DB TO VERSION %s\n", new_ver);
41 :
42 0 : ctx = talloc(mem_ctx, struct upgrade_ctx);
43 0 : if (!ctx) {
44 0 : return ENOMEM;
45 : }
46 :
47 0 : ctx->ldb = ldb;
48 0 : ctx->new_version = new_ver;
49 :
50 0 : ret = ldb_transaction_start(ldb);
51 0 : if (ret != LDB_SUCCESS) {
52 0 : ret = EIO;
53 0 : goto done;
54 : }
55 :
56 0 : ret = EOK;
57 :
58 : done:
59 0 : if (ret != EOK) {
60 0 : talloc_free(ctx);
61 : } else {
62 0 : *_ctx = ctx;
63 : }
64 0 : return ret;
65 : }
66 :
67 0 : static errno_t update_version(struct upgrade_ctx *ctx)
68 : {
69 0 : struct ldb_message *msg = NULL;
70 : errno_t ret;
71 :
72 0 : msg = ldb_msg_new(ctx);
73 0 : if (!msg) {
74 0 : ret = ENOMEM;
75 0 : goto done;
76 : }
77 0 : msg->dn = ldb_dn_new(msg, ctx->ldb, SYSDB_BASE);
78 0 : if (!msg->dn) {
79 0 : ret = ENOMEM;
80 0 : goto done;
81 : }
82 :
83 0 : ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL);
84 0 : if (ret != LDB_SUCCESS) {
85 0 : ret = ENOMEM;
86 0 : goto done;
87 : }
88 :
89 0 : ret = ldb_msg_add_string(msg, "version", ctx->new_version);
90 0 : if (ret != LDB_SUCCESS) {
91 0 : ret = ENOMEM;
92 0 : goto done;
93 : }
94 :
95 0 : ret = ldb_modify(ctx->ldb, msg);
96 0 : if (ret != LDB_SUCCESS) {
97 0 : ret = sysdb_error_to_errno(ret);
98 0 : goto done;
99 : }
100 :
101 0 : ret = EOK;
102 :
103 : done:
104 0 : talloc_free(msg);
105 0 : return ret;
106 : }
107 :
108 0 : static int finish_upgrade(int ret, struct upgrade_ctx **ctx, const char **ver)
109 : {
110 : int lret;
111 :
112 0 : if (ret == EOK) {
113 0 : lret = ldb_transaction_commit((*ctx)->ldb);
114 0 : ret = sysdb_error_to_errno(lret);
115 0 : if (ret == EOK) {
116 0 : *ver = (*ctx)->new_version;
117 : }
118 : }
119 :
120 0 : if (ret != EOK) {
121 0 : lret = ldb_transaction_cancel((*ctx)->ldb);
122 0 : if (lret != LDB_SUCCESS) {
123 0 : DEBUG(SSSDBG_CRIT_FAILURE,
124 : "Could not cancel transaction! [%s]\n",
125 : ldb_strerror(lret));
126 : /* Do not overwrite ret here, we want to return
127 : * the original failure, not the failure of the
128 : * transaction cancellation.
129 : */
130 : }
131 : }
132 :
133 0 : talloc_zfree(*ctx);
134 0 : return ret;
135 : }
136 :
137 : /* serach all groups that have a memberUid attribute.
138 : * change it into a member attribute for a user of same domain.
139 : * remove the memberUid attribute
140 : * add the new member attribute
141 : * finally stop indexing memberUid
142 : * upgrade version to 0.2
143 : */
144 0 : int sysdb_upgrade_01(struct ldb_context *ldb, const char **ver)
145 : {
146 : struct ldb_message_element *el;
147 : struct ldb_result *res;
148 : struct ldb_dn *basedn;
149 : struct ldb_dn *mem_dn;
150 : struct ldb_message *msg;
151 : const struct ldb_val *val;
152 0 : const char *filter = "(&(memberUid=*)(objectclass=group))";
153 0 : const char *attrs[] = { "memberUid", NULL };
154 : const char *mdn;
155 : char *domain;
156 : int ret, i, j;
157 : TALLOC_CTX *tmp_ctx;
158 : struct upgrade_ctx *ctx;
159 :
160 0 : tmp_ctx = talloc_new(NULL);
161 0 : if (!tmp_ctx) {
162 0 : return ENOMEM;
163 : }
164 :
165 0 : ret = commence_upgrade(tmp_ctx, ldb, SYSDB_VERSION_0_2, &ctx);
166 0 : if (ret) {
167 0 : talloc_free(tmp_ctx);
168 0 : return ret;
169 : }
170 :
171 0 : basedn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE);
172 0 : if (!basedn) {
173 0 : ret = EIO;
174 0 : goto done;
175 : }
176 :
177 0 : ret = ldb_search(ldb, tmp_ctx, &res,
178 : basedn, LDB_SCOPE_SUBTREE,
179 : attrs, "%s", filter);
180 0 : if (ret != LDB_SUCCESS) {
181 0 : ret = EIO;
182 0 : goto done;
183 : }
184 :
185 0 : for (i = 0; i < res->count; i++) {
186 0 : el = ldb_msg_find_element(res->msgs[i], "memberUid");
187 0 : if (!el) {
188 0 : DEBUG(SSSDBG_CRIT_FAILURE,
189 : "memberUid is missing from message [%s], skipping\n",
190 : ldb_dn_get_linearized(res->msgs[i]->dn));
191 0 : continue;
192 : }
193 :
194 : /* create modification message */
195 0 : msg = ldb_msg_new(tmp_ctx);
196 0 : if (!msg) {
197 0 : ret = ENOMEM;
198 0 : goto done;
199 : }
200 0 : msg->dn = res->msgs[i]->dn;
201 :
202 0 : ret = ldb_msg_add_empty(msg, "memberUid", LDB_FLAG_MOD_DELETE, NULL);
203 0 : if (ret != LDB_SUCCESS) {
204 0 : ret = ENOMEM;
205 0 : goto done;
206 : }
207 :
208 0 : ret = ldb_msg_add_empty(msg, SYSDB_MEMBER, LDB_FLAG_MOD_ADD, NULL);
209 0 : if (ret != LDB_SUCCESS) {
210 0 : ret = ENOMEM;
211 0 : goto done;
212 : }
213 :
214 : /* get domain name component value */
215 0 : val = ldb_dn_get_component_val(res->msgs[i]->dn, 2);
216 0 : domain = talloc_strndup(tmp_ctx, (const char *)val->data, val->length);
217 0 : if (!domain) {
218 0 : ret = ENOMEM;
219 0 : goto done;
220 : }
221 :
222 0 : for (j = 0; j < el->num_values; j++) {
223 0 : mem_dn = ldb_dn_new_fmt(tmp_ctx, ldb, SYSDB_TMPL_USER,
224 0 : (const char *)el->values[j].data, domain);
225 0 : if (!mem_dn) {
226 0 : ret = ENOMEM;
227 0 : goto done;
228 : }
229 :
230 0 : mdn = talloc_strdup(msg, ldb_dn_get_linearized(mem_dn));
231 0 : if (!mdn) {
232 0 : ret = ENOMEM;
233 0 : goto done;
234 : }
235 0 : ret = ldb_msg_add_string(msg, SYSDB_MEMBER, mdn);
236 0 : if (ret != LDB_SUCCESS) {
237 0 : ret = ENOMEM;
238 0 : goto done;
239 : }
240 :
241 0 : talloc_zfree(mem_dn);
242 : }
243 :
244 : /* ok now we are ready to modify the entry */
245 0 : ret = ldb_modify(ldb, msg);
246 0 : if (ret != LDB_SUCCESS) {
247 0 : ret = sysdb_error_to_errno(ret);
248 0 : goto done;
249 : }
250 :
251 0 : talloc_zfree(msg);
252 : }
253 :
254 : /* conversion done, update version number */
255 0 : ret = update_version(ctx);
256 :
257 : done:
258 0 : ret = finish_upgrade(ret, &ctx, ver);
259 0 : talloc_free(tmp_ctx);
260 0 : return ret;
261 : }
262 :
263 0 : int sysdb_check_upgrade_02(struct sss_domain_info *domains,
264 : const char *db_path)
265 : {
266 0 : TALLOC_CTX *tmp_ctx = NULL;
267 : struct ldb_context *ldb;
268 : char *ldb_file;
269 : struct sysdb_ctx *sysdb;
270 : struct sss_domain_info *dom;
271 : struct ldb_message_element *el;
272 : struct ldb_message *msg;
273 : struct ldb_result *res;
274 : struct ldb_dn *verdn;
275 0 : const char *version = NULL;
276 0 : bool do_02_upgrade = false;
277 0 : bool ctx_trans = false;
278 : int ret;
279 :
280 0 : tmp_ctx = talloc_new(NULL);
281 0 : if (!tmp_ctx) {
282 0 : return ENOMEM;
283 : }
284 :
285 0 : ret = sysdb_get_db_file(tmp_ctx,
286 : "local", "UPGRADE",
287 : db_path, &ldb_file);
288 0 : if (ret != EOK) {
289 0 : goto exit;
290 : }
291 :
292 0 : ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb);
293 0 : if (ret != EOK) {
294 0 : DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_ldb_connect failed.\n");
295 0 : return ret;
296 : }
297 :
298 0 : verdn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE);
299 0 : if (!verdn) {
300 0 : ret = EIO;
301 0 : goto exit;
302 : }
303 :
304 0 : ret = ldb_search(ldb, tmp_ctx, &res,
305 : verdn, LDB_SCOPE_BASE,
306 : NULL, NULL);
307 0 : if (ret != LDB_SUCCESS) {
308 0 : ret = EIO;
309 0 : goto exit;
310 : }
311 0 : if (res->count > 1) {
312 0 : ret = EIO;
313 0 : goto exit;
314 : }
315 :
316 0 : if (res->count == 1) {
317 0 : el = ldb_msg_find_element(res->msgs[0], "version");
318 0 : if (el) {
319 0 : if (el->num_values != 1) {
320 0 : ret = EINVAL;
321 0 : goto exit;
322 : }
323 0 : version = talloc_strndup(tmp_ctx,
324 0 : (char *)(el->values[0].data),
325 0 : el->values[0].length);
326 0 : if (!version) {
327 0 : ret = ENOMEM;
328 0 : goto exit;
329 : }
330 :
331 0 : if (strcmp(version, SYSDB_VERSION) == 0) {
332 : /* all fine, return */
333 0 : ret = EOK;
334 0 : goto exit;
335 : }
336 :
337 0 : DEBUG(SSSDBG_CONF_SETTINGS,
338 : "Upgrading DB from version: %s\n", version);
339 :
340 0 : if (strcmp(version, SYSDB_VERSION_0_1) == 0) {
341 : /* convert database */
342 0 : ret = sysdb_upgrade_01(ldb, &version);
343 0 : if (ret != EOK) goto exit;
344 : }
345 :
346 0 : if (strcmp(version, SYSDB_VERSION_0_2) == 0) {
347 : /* need to convert database to split files */
348 0 : do_02_upgrade = true;
349 : }
350 :
351 : }
352 : }
353 :
354 0 : if (!do_02_upgrade) {
355 : /* not a v2 upgrade, return and let the normal code take over any
356 : * further upgrade */
357 0 : ret = EOK;
358 0 : goto exit;
359 : }
360 :
361 : /* == V2->V3 UPGRADE == */
362 :
363 0 : DEBUG(SSSDBG_FATAL_FAILURE,
364 : "UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_3);
365 :
366 : /* ldb uses posix locks,
367 : * posix is stupid and kills all locks when you close *any* file
368 : * descriptor associated to the same file.
369 : * Therefore we must close and reopen the ldb file here */
370 :
371 : /* == Backup and reopen ldb == */
372 :
373 : /* close */
374 0 : talloc_zfree(ldb);
375 :
376 : /* backup*/
377 0 : ret = backup_file(ldb_file, SSSDBG_FATAL_FAILURE);
378 0 : if (ret != EOK) {
379 0 : goto exit;
380 : }
381 :
382 : /* reopen */
383 0 : ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb);
384 0 : if (ret != EOK) {
385 0 : DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_ldb_connect failed.\n");
386 0 : return ret;
387 : }
388 :
389 : /* open a transaction */
390 0 : ret = ldb_transaction_start(ldb);
391 0 : if (ret != LDB_SUCCESS) {
392 0 : DEBUG(SSSDBG_CRIT_FAILURE,
393 : "Failed to start ldb transaction! (%d)\n", ret);
394 0 : ret = EIO;
395 0 : goto exit;
396 : }
397 :
398 : /* == Upgrade contents == */
399 :
400 0 : for (dom = domains; dom; dom = dom->next) {
401 : struct ldb_dn *domain_dn;
402 : struct ldb_dn *users_dn;
403 : struct ldb_dn *groups_dn;
404 : int i;
405 :
406 : /* skip local */
407 0 : if (strcasecmp(dom->provider, "local") == 0) {
408 0 : continue;
409 : }
410 :
411 : /* create new dom db */
412 0 : ret = sysdb_domain_init_internal(tmp_ctx, dom,
413 : db_path, false, &sysdb);
414 0 : if (ret != EOK) {
415 0 : goto done;
416 : }
417 :
418 0 : ret = ldb_transaction_start(sysdb->ldb);
419 0 : if (ret != LDB_SUCCESS) {
420 0 : DEBUG(SSSDBG_CRIT_FAILURE,
421 : "Failed to start ldb transaction! (%d)\n", ret);
422 0 : ret = EIO;
423 0 : goto done;
424 : }
425 0 : ctx_trans = true;
426 :
427 : /* search all entries for this domain in local,
428 : * copy them all in the new database,
429 : * then remove them from local */
430 :
431 0 : domain_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
432 : SYSDB_DOM_BASE, dom->name);
433 0 : if (!domain_dn) {
434 0 : ret = ENOMEM;
435 0 : goto done;
436 : }
437 :
438 0 : ret = ldb_search(ldb, tmp_ctx, &res,
439 : domain_dn, LDB_SCOPE_SUBTREE,
440 : NULL, NULL);
441 0 : if (ret != LDB_SUCCESS) {
442 0 : ret = EIO;
443 0 : goto done;
444 : }
445 :
446 0 : users_dn = sysdb_user_base_dn(tmp_ctx, dom);
447 0 : if (!users_dn) {
448 0 : ret = ENOMEM;
449 0 : goto done;
450 : }
451 0 : groups_dn = sysdb_group_base_dn(tmp_ctx, dom);
452 0 : if (!groups_dn) {
453 0 : ret = ENOMEM;
454 0 : goto done;
455 : }
456 :
457 0 : for (i = 0; i < res->count; i++) {
458 :
459 : struct ldb_dn *orig_dn;
460 :
461 0 : msg = res->msgs[i];
462 :
463 : /* skip pre-created congtainers */
464 0 : if ((ldb_dn_compare(msg->dn, domain_dn) == 0) ||
465 0 : (ldb_dn_compare(msg->dn, users_dn) == 0) ||
466 0 : (ldb_dn_compare(msg->dn, groups_dn) == 0)) {
467 0 : continue;
468 : }
469 :
470 : /* regenerate the DN against the new ldb as it may have different
471 : * casefolding rules (example: name changing from case insensitive
472 : * to case sensitive) */
473 0 : orig_dn = msg->dn;
474 0 : msg->dn = ldb_dn_new(msg, sysdb->ldb,
475 : ldb_dn_get_linearized(orig_dn));
476 0 : if (!msg->dn) {
477 0 : ret = ENOMEM;
478 0 : goto done;
479 : }
480 :
481 0 : ret = ldb_add(sysdb->ldb, msg);
482 0 : if (ret != LDB_SUCCESS) {
483 0 : DEBUG(SSSDBG_FATAL_FAILURE, "WARNING: Could not add entry %s,"
484 : " to new ldb file! (%d [%s])\n",
485 : ldb_dn_get_linearized(msg->dn),
486 : ret, ldb_errstring(sysdb->ldb));
487 : }
488 :
489 0 : ret = ldb_delete(ldb, orig_dn);
490 0 : if (ret != LDB_SUCCESS) {
491 0 : DEBUG(SSSDBG_FATAL_FAILURE,
492 : "WARNING: Could not remove entry %s,"
493 : " from old ldb file! (%d [%s])\n",
494 : ldb_dn_get_linearized(orig_dn),
495 : ret, ldb_errstring(ldb));
496 : }
497 : }
498 :
499 : /* now remove the basic containers from local */
500 : /* these were optional so debug at level 9 in case
501 : * of failure just for tracing */
502 0 : ret = ldb_delete(ldb, groups_dn);
503 0 : if (ret != LDB_SUCCESS) {
504 0 : DEBUG(SSSDBG_TRACE_ALL, "WARNING: Could not remove entry %s,"
505 : " from old ldb file! (%d [%s])\n",
506 : ldb_dn_get_linearized(groups_dn),
507 : ret, ldb_errstring(ldb));
508 : }
509 0 : ret = ldb_delete(ldb, users_dn);
510 0 : if (ret != LDB_SUCCESS) {
511 0 : DEBUG(SSSDBG_TRACE_ALL, "WARNING: Could not remove entry %s,"
512 : " from old ldb file! (%d [%s])\n",
513 : ldb_dn_get_linearized(users_dn),
514 : ret, ldb_errstring(ldb));
515 : }
516 0 : ret = ldb_delete(ldb, domain_dn);
517 0 : if (ret != LDB_SUCCESS) {
518 0 : DEBUG(SSSDBG_TRACE_ALL, "WARNING: Could not remove entry %s,"
519 : " from old ldb file! (%d [%s])\n",
520 : ldb_dn_get_linearized(domain_dn),
521 : ret, ldb_errstring(ldb));
522 : }
523 :
524 0 : ret = ldb_transaction_commit(sysdb->ldb);
525 0 : if (ret != LDB_SUCCESS) {
526 0 : DEBUG(SSSDBG_CRIT_FAILURE,
527 : "Failed to commit ldb transaction! (%d)\n", ret);
528 0 : ret = EIO;
529 0 : goto done;
530 : }
531 0 : ctx_trans = false;
532 :
533 0 : talloc_zfree(domain_dn);
534 0 : talloc_zfree(groups_dn);
535 0 : talloc_zfree(users_dn);
536 0 : talloc_zfree(res);
537 : }
538 :
539 : /* conversion done, upgrade version number */
540 0 : msg = ldb_msg_new(tmp_ctx);
541 0 : if (!msg) {
542 0 : ret = ENOMEM;
543 0 : goto done;
544 : }
545 0 : msg->dn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE);
546 0 : if (!msg->dn) {
547 0 : ret = ENOMEM;
548 0 : goto done;
549 : }
550 :
551 0 : ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL);
552 0 : if (ret != LDB_SUCCESS) {
553 0 : ret = ENOMEM;
554 0 : goto done;
555 : }
556 0 : ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_3);
557 0 : if (ret != LDB_SUCCESS) {
558 0 : ret = ENOMEM;
559 0 : goto done;
560 : }
561 :
562 0 : ret = ldb_modify(ldb, msg);
563 0 : if (ret != LDB_SUCCESS) {
564 0 : ret = sysdb_error_to_errno(ret);
565 0 : goto done;
566 : }
567 :
568 0 : ret = ldb_transaction_commit(ldb);
569 0 : if (ret != LDB_SUCCESS) {
570 0 : DEBUG(SSSDBG_CRIT_FAILURE,
571 : "Failed to commit ldb transaction! (%d)\n", ret);
572 0 : ret = EIO;
573 0 : goto exit;
574 : }
575 :
576 0 : ret = EOK;
577 :
578 : done:
579 0 : if (ret != EOK) {
580 0 : if (ctx_trans) {
581 0 : ret = ldb_transaction_cancel(sysdb->ldb);
582 0 : if (ret != LDB_SUCCESS) {
583 0 : DEBUG(SSSDBG_CRIT_FAILURE,
584 : "Failed to cancel ldb transaction! (%d)\n", ret);
585 : }
586 : }
587 0 : ret = ldb_transaction_cancel(ldb);
588 0 : if (ret != LDB_SUCCESS) {
589 0 : DEBUG(SSSDBG_CRIT_FAILURE,
590 : "Failed to cancel ldb transaction! (%d)\n", ret);
591 : }
592 : }
593 :
594 : exit:
595 0 : talloc_free(tmp_ctx);
596 0 : return ret;
597 : }
598 :
599 0 : int sysdb_upgrade_03(struct sysdb_ctx *sysdb, const char **ver)
600 : {
601 : TALLOC_CTX *tmp_ctx;
602 : int ret;
603 : struct ldb_message *msg;
604 : struct upgrade_ctx *ctx;
605 :
606 0 : tmp_ctx = talloc_new(NULL);
607 0 : if (!tmp_ctx) {
608 0 : return ENOMEM;
609 : }
610 :
611 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_4, &ctx);
612 0 : if (ret) {
613 0 : return ret;
614 : }
615 :
616 : /* Make this database case-sensitive */
617 0 : msg = ldb_msg_new(tmp_ctx);
618 0 : if (!msg) {
619 0 : ret = ENOMEM;
620 0 : goto done;
621 : }
622 0 : msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES");
623 0 : if (!msg->dn) {
624 0 : ret = ENOMEM;
625 0 : goto done;
626 : }
627 :
628 0 : ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_DELETE, NULL);
629 0 : if (ret != LDB_SUCCESS) {
630 0 : ret = ENOMEM;
631 0 : goto done;
632 : }
633 :
634 0 : ret = ldb_modify(sysdb->ldb, msg);
635 0 : if (ret != LDB_SUCCESS) {
636 0 : ret = sysdb_error_to_errno(ret);
637 0 : goto done;
638 : }
639 :
640 : /* conversion done, update version number */
641 0 : ret = update_version(ctx);
642 :
643 : done:
644 0 : ret = finish_upgrade(ret, &ctx, ver);
645 0 : talloc_free(tmp_ctx);
646 0 : return ret;
647 : }
648 :
649 0 : int sysdb_upgrade_04(struct sysdb_ctx *sysdb, const char **ver)
650 : {
651 : TALLOC_CTX *tmp_ctx;
652 : int ret;
653 : struct ldb_message *msg;
654 : struct upgrade_ctx *ctx;
655 :
656 0 : tmp_ctx = talloc_new(NULL);
657 0 : if (!tmp_ctx) {
658 0 : return ENOMEM;
659 : }
660 :
661 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_5, &ctx);
662 0 : if (ret) {
663 0 : return ret;
664 : }
665 :
666 : /* Add new index */
667 0 : msg = ldb_msg_new(tmp_ctx);
668 0 : if (!msg) {
669 0 : ret = ENOMEM;
670 0 : goto done;
671 : }
672 0 : msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
673 0 : if (!msg->dn) {
674 0 : ret = ENOMEM;
675 0 : goto done;
676 : }
677 :
678 0 : ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
679 0 : if (ret != LDB_SUCCESS) {
680 0 : ret = ENOMEM;
681 0 : goto done;
682 : }
683 0 : ret = ldb_msg_add_string(msg, "@IDXATTR", "originalDN");
684 0 : if (ret != LDB_SUCCESS) {
685 0 : ret = ENOMEM;
686 0 : goto done;
687 : }
688 :
689 0 : ret = ldb_modify(sysdb->ldb, msg);
690 0 : if (ret != LDB_SUCCESS) {
691 0 : ret = sysdb_error_to_errno(ret);
692 0 : goto done;
693 : }
694 :
695 : /* Rebuild memberuid and memberoif attributes */
696 0 : msg = ldb_msg_new(tmp_ctx);
697 0 : if (!msg) {
698 0 : ret = ENOMEM;
699 0 : goto done;
700 : }
701 0 : msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@MEMBEROF-REBUILD");
702 0 : if (!msg->dn) {
703 0 : ret = ENOMEM;
704 0 : goto done;
705 : }
706 :
707 0 : ret = ldb_add(sysdb->ldb, msg);
708 0 : if (ret != LDB_SUCCESS) {
709 0 : ret = sysdb_error_to_errno(ret);
710 0 : goto done;
711 : }
712 :
713 : /* conversion done, update version number */
714 0 : ret = update_version(ctx);
715 :
716 : done:
717 0 : ret = finish_upgrade(ret, &ctx, ver);
718 0 : talloc_free(tmp_ctx);
719 0 : return ret;
720 : }
721 :
722 0 : int sysdb_upgrade_05(struct sysdb_ctx *sysdb, const char **ver)
723 : {
724 : TALLOC_CTX *tmp_ctx;
725 : int ret;
726 : struct ldb_message *msg;
727 : struct upgrade_ctx *ctx;
728 :
729 0 : tmp_ctx = talloc_new(NULL);
730 0 : if (!tmp_ctx) {
731 0 : return ENOMEM;
732 : }
733 :
734 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_6, &ctx);
735 0 : if (ret) {
736 0 : return ret;
737 : }
738 :
739 : /* Add new indexes */
740 0 : msg = ldb_msg_new(tmp_ctx);
741 0 : if (!msg) {
742 0 : ret = ENOMEM;
743 0 : goto done;
744 : }
745 0 : msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
746 0 : if (!msg->dn) {
747 0 : ret = ENOMEM;
748 0 : goto done;
749 : }
750 :
751 : /* Add Index for dataExpireTimestamp */
752 0 : ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
753 0 : if (ret != LDB_SUCCESS) {
754 0 : ret = ENOMEM;
755 0 : goto done;
756 : }
757 0 : ret = ldb_msg_add_string(msg, "@IDXATTR", "dataExpireTimestamp");
758 0 : if (ret != LDB_SUCCESS) {
759 0 : ret = ENOMEM;
760 0 : goto done;
761 : }
762 :
763 : /* Add index to speed up ONELEVEL searches */
764 0 : ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_ADD, NULL);
765 0 : if (ret != LDB_SUCCESS) {
766 0 : ret = ENOMEM;
767 0 : goto done;
768 : }
769 0 : ret = ldb_msg_add_string(msg, "@IDXONE", "1");
770 0 : if (ret != LDB_SUCCESS) {
771 0 : ret = ENOMEM;
772 0 : goto done;
773 : }
774 :
775 0 : ret = ldb_modify(sysdb->ldb, msg);
776 0 : if (ret != LDB_SUCCESS) {
777 0 : ret = sysdb_error_to_errno(ret);
778 0 : goto done;
779 : }
780 :
781 : /* conversion done, update version number */
782 0 : ret = update_version(ctx);
783 :
784 : done:
785 0 : ret = finish_upgrade(ret, &ctx, ver);
786 0 : talloc_free(tmp_ctx);
787 0 : return ret;
788 : }
789 :
790 0 : int sysdb_upgrade_06(struct sysdb_ctx *sysdb, const char **ver)
791 : {
792 : TALLOC_CTX *tmp_ctx;
793 : int ret;
794 : struct ldb_message *msg;
795 : struct upgrade_ctx *ctx;
796 :
797 0 : tmp_ctx = talloc_new(NULL);
798 0 : if (!tmp_ctx) {
799 0 : return ENOMEM;
800 : }
801 :
802 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_7, &ctx);
803 0 : if (ret) {
804 0 : return ret;
805 : }
806 :
807 : /* Add new indexes */
808 0 : msg = ldb_msg_new(tmp_ctx);
809 0 : if (!msg) {
810 0 : ret = ENOMEM;
811 0 : goto done;
812 : }
813 0 : msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES");
814 0 : if (!msg->dn) {
815 0 : ret = ENOMEM;
816 0 : goto done;
817 : }
818 :
819 : /* Case insensitive search for originalDN */
820 0 : ret = ldb_msg_add_empty(msg, SYSDB_ORIG_DN, LDB_FLAG_MOD_ADD, NULL);
821 0 : if (ret != LDB_SUCCESS) {
822 0 : ret = ENOMEM;
823 0 : goto done;
824 : }
825 0 : ret = ldb_msg_add_string(msg, SYSDB_ORIG_DN, "CASE_INSENSITIVE");
826 0 : if (ret != LDB_SUCCESS) {
827 0 : ret = ENOMEM;
828 0 : goto done;
829 : }
830 :
831 0 : ret = ldb_modify(sysdb->ldb, msg);
832 0 : if (ret != LDB_SUCCESS) {
833 0 : ret = sysdb_error_to_errno(ret);
834 0 : goto done;
835 : }
836 :
837 : /* conversion done, update version number */
838 0 : ret = update_version(ctx);
839 :
840 : done:
841 0 : ret = finish_upgrade(ret, &ctx, ver);
842 0 : talloc_free(tmp_ctx);
843 0 : return ret;
844 : }
845 :
846 0 : int sysdb_upgrade_07(struct sysdb_ctx *sysdb, const char **ver)
847 : {
848 : TALLOC_CTX *tmp_ctx;
849 : int ret;
850 : struct ldb_message *msg;
851 : struct upgrade_ctx *ctx;
852 :
853 0 : tmp_ctx = talloc_new(NULL);
854 0 : if (!tmp_ctx) {
855 0 : return ENOMEM;
856 : }
857 :
858 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_8, &ctx);
859 0 : if (ret) {
860 0 : return ret;
861 : }
862 :
863 : /* Add new indexes */
864 0 : msg = ldb_msg_new(tmp_ctx);
865 0 : if (!msg) {
866 0 : ret = ENOMEM;
867 0 : goto done;
868 : }
869 0 : msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
870 0 : if (!msg->dn) {
871 0 : ret = ENOMEM;
872 0 : goto done;
873 : }
874 :
875 : /* Add Index for nameAlias */
876 0 : ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
877 0 : if (ret != LDB_SUCCESS) {
878 0 : ret = ENOMEM;
879 0 : goto done;
880 : }
881 0 : ret = ldb_msg_add_string(msg, "@IDXATTR", "nameAlias");
882 0 : if (ret != LDB_SUCCESS) {
883 0 : ret = ENOMEM;
884 0 : goto done;
885 : }
886 :
887 0 : ret = ldb_modify(sysdb->ldb, msg);
888 0 : if (ret != LDB_SUCCESS) {
889 0 : ret = sysdb_error_to_errno(ret);
890 0 : goto done;
891 : }
892 :
893 : /* conversion done, update version number */
894 0 : ret = update_version(ctx);
895 :
896 : done:
897 0 : ret = finish_upgrade(ret, &ctx, ver);
898 0 : talloc_free(tmp_ctx);
899 0 : return ret;
900 : }
901 :
902 0 : int sysdb_upgrade_08(struct sysdb_ctx *sysdb, const char **ver)
903 : {
904 : TALLOC_CTX *tmp_ctx;
905 : int ret;
906 : struct ldb_message *msg;
907 : struct upgrade_ctx *ctx;
908 :
909 0 : tmp_ctx = talloc_new(NULL);
910 0 : if (!tmp_ctx) {
911 0 : return ENOMEM;
912 : }
913 :
914 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_9, &ctx);
915 0 : if (ret) {
916 0 : return ret;
917 : }
918 :
919 : /* Add new indexes */
920 0 : msg = ldb_msg_new(tmp_ctx);
921 0 : if (!msg) {
922 0 : ret = ENOMEM;
923 0 : goto done;
924 : }
925 0 : msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
926 0 : if (!msg->dn) {
927 0 : ret = ENOMEM;
928 0 : goto done;
929 : }
930 :
931 : /* Add Index for servicePort and serviceProtocol */
932 0 : ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
933 0 : if (ret != LDB_SUCCESS) {
934 0 : ret = ENOMEM;
935 0 : goto done;
936 : }
937 0 : ret = ldb_msg_add_string(msg, "@IDXATTR", "servicePort");
938 0 : if (ret != LDB_SUCCESS) {
939 0 : ret = ENOMEM;
940 0 : goto done;
941 : }
942 :
943 0 : ret = ldb_msg_add_string(msg, "@IDXATTR", "serviceProtocol");
944 0 : if (ret != LDB_SUCCESS) {
945 0 : ret = ENOMEM;
946 0 : goto done;
947 : }
948 :
949 0 : ret = ldb_modify(sysdb->ldb, msg);
950 0 : if (ret != LDB_SUCCESS) {
951 0 : ret = sysdb_error_to_errno(ret);
952 0 : goto done;
953 : }
954 :
955 : /* conversion done, update version number */
956 0 : ret = update_version(ctx);
957 :
958 : done:
959 0 : ret = finish_upgrade(ret, &ctx, ver);
960 0 : talloc_free(tmp_ctx);
961 0 : return ret;
962 : }
963 :
964 0 : int sysdb_upgrade_09(struct sysdb_ctx *sysdb, const char **ver)
965 : {
966 : TALLOC_CTX *tmp_ctx;
967 : int ret;
968 : struct ldb_message *msg;
969 : struct upgrade_ctx *ctx;
970 :
971 0 : tmp_ctx = talloc_new(NULL);
972 0 : if (!tmp_ctx) {
973 0 : return ENOMEM;
974 : }
975 :
976 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_10, &ctx);
977 0 : if (ret) {
978 0 : return ret;
979 : }
980 :
981 : /* Add new indexes */
982 0 : msg = ldb_msg_new(tmp_ctx);
983 0 : if (!msg) {
984 0 : ret = ENOMEM;
985 0 : goto done;
986 : }
987 0 : msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
988 0 : if (!msg->dn) {
989 0 : ret = ENOMEM;
990 0 : goto done;
991 : }
992 :
993 : /* Add Index for servicePort and serviceProtocol */
994 0 : ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
995 0 : if (ret != LDB_SUCCESS) {
996 0 : ret = ENOMEM;
997 0 : goto done;
998 : }
999 :
1000 0 : ret = ldb_msg_add_string(msg, "@IDXATTR", "sudoUser");
1001 0 : if (ret != LDB_SUCCESS) {
1002 0 : ret = ENOMEM;
1003 0 : goto done;
1004 : }
1005 :
1006 0 : ret = ldb_modify(sysdb->ldb, msg);
1007 0 : if (ret != LDB_SUCCESS) {
1008 0 : ret = sysdb_error_to_errno(ret);
1009 0 : goto done;
1010 : }
1011 :
1012 : /* conversion done, update version number */
1013 0 : ret = update_version(ctx);
1014 :
1015 : done:
1016 0 : ret = finish_upgrade(ret, &ctx, ver);
1017 0 : talloc_free(tmp_ctx);
1018 0 : return ret;
1019 : }
1020 :
1021 0 : int sysdb_upgrade_10(struct sysdb_ctx *sysdb, struct sss_domain_info *domain,
1022 : const char **ver)
1023 : {
1024 :
1025 : TALLOC_CTX *tmp_ctx;
1026 : int ret;
1027 : struct ldb_result *res;
1028 : struct ldb_message *msg;
1029 : struct ldb_message *user;
1030 : struct ldb_message_element *memberof_el;
1031 : const char *name;
1032 : struct ldb_dn *basedn;
1033 0 : const char *filter = "(&(objectClass=user)(!(uidNumber=*))(memberOf=*))";
1034 0 : const char *attrs[] = { "name", "memberof", NULL };
1035 : struct upgrade_ctx *ctx;
1036 : int i, j;
1037 :
1038 0 : tmp_ctx = talloc_new(NULL);
1039 0 : if (tmp_ctx == NULL) {
1040 0 : return ENOMEM;
1041 : }
1042 :
1043 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_11, &ctx);
1044 0 : if (ret) {
1045 0 : return ret;
1046 : }
1047 :
1048 0 : basedn = sysdb_user_base_dn(tmp_ctx, domain);
1049 0 : if (basedn == NULL) {
1050 0 : ret = EIO;
1051 0 : goto done;
1052 : }
1053 :
1054 0 : ret = ldb_search(sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE,
1055 : attrs, "%s", filter);
1056 0 : if (ret != LDB_SUCCESS) {
1057 0 : ret = EIO;
1058 0 : goto done;
1059 : }
1060 :
1061 0 : for (i = 0; i < res->count; i++) {
1062 0 : user = res->msgs[i];
1063 0 : memberof_el = ldb_msg_find_element(user, "memberof");
1064 0 : name = ldb_msg_find_attr_as_string(user, "name", NULL);
1065 0 : if (name == NULL) {
1066 0 : ret = EIO;
1067 0 : goto done;
1068 : }
1069 :
1070 0 : DEBUG(SSSDBG_TRACE_LIBS, "User [%s] is a member of %d groups\n",
1071 : name, memberof_el->num_values);
1072 :
1073 0 : for (j = 0; j < memberof_el->num_values; j++) {
1074 0 : msg = ldb_msg_new(tmp_ctx);
1075 0 : if (msg == NULL) {
1076 0 : ret = ENOMEM;
1077 0 : goto done;
1078 : }
1079 :
1080 0 : msg->dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb, &memberof_el->values[j]);
1081 0 : if (msg->dn == NULL) {
1082 0 : ret = ENOMEM;
1083 0 : goto done;
1084 : }
1085 :
1086 0 : if (!ldb_dn_validate(msg->dn)) {
1087 0 : DEBUG(SSSDBG_MINOR_FAILURE, "DN validation failed during "
1088 : "upgrade: [%s]\n",
1089 : memberof_el->values[j].data);
1090 0 : talloc_zfree(msg);
1091 0 : continue;
1092 : }
1093 :
1094 0 : ret = ldb_msg_add_empty(msg, "ghost", LDB_FLAG_MOD_ADD, NULL);
1095 0 : if (ret != LDB_SUCCESS) {
1096 0 : ret = ENOMEM;
1097 0 : goto done;
1098 : }
1099 0 : ret = ldb_msg_add_string(msg, "ghost", name);
1100 0 : if (ret != LDB_SUCCESS) {
1101 0 : ret = ENOMEM;
1102 0 : goto done;
1103 : }
1104 :
1105 0 : DEBUG(SSSDBG_TRACE_FUNC, "Adding ghost [%s] to entry [%s]\n",
1106 : name, ldb_dn_get_linearized(msg->dn));
1107 :
1108 0 : ret = sss_ldb_modify_permissive(sysdb->ldb, msg);
1109 0 : talloc_zfree(msg);
1110 0 : if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1111 : /* If we failed adding the ghost user(s) because the values already
1112 : * exist, they were probably propagated from a parent that was
1113 : * upgraded before us. Mark the group as expired so that it is
1114 : * refreshed on next request.
1115 : */
1116 0 : msg = ldb_msg_new(tmp_ctx);
1117 0 : if (msg == NULL) {
1118 0 : ret = ENOMEM;
1119 0 : goto done;
1120 : }
1121 :
1122 0 : msg->dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb, &memberof_el->values[j]);
1123 0 : if (msg->dn == NULL) {
1124 0 : ret = ENOMEM;
1125 0 : goto done;
1126 : }
1127 :
1128 0 : ret = ldb_msg_add_empty(msg, SYSDB_CACHE_EXPIRE,
1129 : LDB_FLAG_MOD_REPLACE, NULL);
1130 0 : if (ret != LDB_SUCCESS) {
1131 0 : goto done;
1132 : }
1133 :
1134 0 : ret = ldb_msg_add_string(msg, SYSDB_CACHE_EXPIRE, "1");
1135 0 : if (ret != LDB_SUCCESS) {
1136 0 : goto done;
1137 : }
1138 :
1139 0 : ret = sss_ldb_modify_permissive(sysdb->ldb, msg);
1140 0 : talloc_zfree(msg);
1141 0 : if (ret != LDB_SUCCESS) {
1142 0 : goto done;
1143 : }
1144 0 : } else if (ret != LDB_SUCCESS) {
1145 0 : ret = sysdb_error_to_errno(ret);
1146 0 : goto done;
1147 : }
1148 : }
1149 :
1150 0 : DEBUG(SSSDBG_TRACE_FUNC, "Removing fake user [%s]\n",
1151 : ldb_dn_get_linearized(user->dn));
1152 :
1153 0 : ret = ldb_delete(sysdb->ldb, user->dn);
1154 0 : if (ret != LDB_SUCCESS) {
1155 0 : ret = sysdb_error_to_errno(ret);
1156 0 : goto done;
1157 : }
1158 : }
1159 :
1160 : /* conversion done, update version number */
1161 0 : ret = update_version(ctx);
1162 :
1163 : done:
1164 0 : ret = finish_upgrade(ret, &ctx, ver);
1165 0 : talloc_free(tmp_ctx);
1166 0 : return ret;
1167 : }
1168 :
1169 0 : int sysdb_upgrade_11(struct sysdb_ctx *sysdb, struct sss_domain_info *domain,
1170 : const char **ver)
1171 : {
1172 : TALLOC_CTX *tmp_ctx;
1173 : errno_t ret;
1174 : struct ldb_result *res;
1175 : struct ldb_message *entry;
1176 : const char *key;
1177 : const char *value;
1178 : struct ldb_message_element *memberof_el;
1179 : struct ldb_dn *memberof_dn;
1180 : struct ldb_dn *basedn;
1181 : const struct ldb_val *val;
1182 0 : const char *attrs[] = { SYSDB_AUTOFS_ENTRY_KEY,
1183 : SYSDB_AUTOFS_ENTRY_VALUE,
1184 : SYSDB_MEMBEROF,
1185 : NULL };
1186 : struct upgrade_ctx *ctx;
1187 : size_t i, j;
1188 :
1189 0 : tmp_ctx = talloc_new(NULL);
1190 0 : if (!tmp_ctx) {
1191 0 : return ENOMEM;
1192 : }
1193 :
1194 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_12, &ctx);
1195 0 : if (ret) {
1196 0 : return ret;
1197 : }
1198 :
1199 0 : basedn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE,
1200 : AUTOFS_ENTRY_SUBDIR, domain->name);
1201 0 : if (basedn == NULL) {
1202 0 : ret = ENOMEM;
1203 0 : goto done;
1204 : }
1205 :
1206 0 : ret = ldb_search(sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE,
1207 : attrs, "(objectClass=%s)", SYSDB_AUTOFS_ENTRY_OC);
1208 0 : if (ret != LDB_SUCCESS) {
1209 0 : ret = EIO;
1210 0 : goto done;
1211 : }
1212 :
1213 0 : DEBUG(SSSDBG_TRACE_LIBS, "Found %d autofs entries\n", res->count);
1214 :
1215 0 : for (i = 0; i < res->count; i++) {
1216 0 : entry = res->msgs[i];
1217 0 : key = ldb_msg_find_attr_as_string(entry,
1218 : SYSDB_AUTOFS_ENTRY_KEY, NULL);
1219 0 : value = ldb_msg_find_attr_as_string(entry,
1220 : SYSDB_AUTOFS_ENTRY_VALUE, NULL);
1221 0 : memberof_el = ldb_msg_find_element(entry, SYSDB_MEMBEROF);
1222 :
1223 0 : if (key && value && memberof_el) {
1224 0 : for (j = 0; j < memberof_el->num_values; j++) {
1225 0 : memberof_dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb,
1226 0 : &(memberof_el->values[j]));
1227 0 : if (!memberof_dn) {
1228 0 : DEBUG(SSSDBG_OP_FAILURE, "Cannot convert memberof into DN, skipping\n");
1229 0 : continue;
1230 : }
1231 :
1232 0 : val = ldb_dn_get_rdn_val(memberof_dn);
1233 0 : if (!val) {
1234 0 : DEBUG(SSSDBG_OP_FAILURE, "Cannot get map name from map DN\n");
1235 0 : continue;
1236 : }
1237 :
1238 0 : ret = sysdb_save_autofsentry(domain,
1239 0 : (const char *) val->data,
1240 : key, value, NULL);
1241 0 : if (ret != EOK) {
1242 0 : DEBUG(SSSDBG_OP_FAILURE,
1243 : "Cannot save autofs entry [%s]-[%s] into map %s\n",
1244 : key, value, val->data);
1245 0 : continue;
1246 : }
1247 : }
1248 :
1249 : }
1250 :
1251 : /* Delete the old entry if it was either processed or incomplete */
1252 0 : DEBUG(SSSDBG_TRACE_LIBS, "Deleting [%s]\n",
1253 : ldb_dn_get_linearized(entry->dn));
1254 :
1255 0 : ret = ldb_delete(sysdb->ldb, entry->dn);
1256 0 : if (ret != EOK) {
1257 0 : DEBUG(SSSDBG_OP_FAILURE, "Cannot delete old autofs entry %s\n",
1258 : ldb_dn_get_linearized(entry->dn));
1259 0 : continue;
1260 : }
1261 : }
1262 :
1263 : /* conversion done, update version number */
1264 0 : ret = update_version(ctx);
1265 :
1266 : done:
1267 0 : ret = finish_upgrade(ret, &ctx, ver);
1268 0 : talloc_free(tmp_ctx);
1269 0 : return ret;
1270 : }
1271 :
1272 0 : int sysdb_upgrade_12(struct sysdb_ctx *sysdb, const char **ver)
1273 : {
1274 : TALLOC_CTX *tmp_ctx;
1275 : int ret;
1276 : struct ldb_message *msg;
1277 : struct upgrade_ctx *ctx;
1278 :
1279 0 : tmp_ctx = talloc_new(NULL);
1280 0 : if (!tmp_ctx) {
1281 0 : return ENOMEM;
1282 : }
1283 :
1284 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_13, &ctx);
1285 0 : if (ret) {
1286 0 : return ret;
1287 : }
1288 :
1289 : /* add new indexes */
1290 0 : msg = ldb_msg_new(tmp_ctx);
1291 0 : if (!msg) {
1292 0 : ret = ENOMEM;
1293 0 : goto done;
1294 : }
1295 0 : msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
1296 0 : if (!msg->dn) {
1297 0 : ret = ENOMEM;
1298 0 : goto done;
1299 : }
1300 :
1301 : /* add index for sshKnownHostsExpire */
1302 0 : ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
1303 0 : if (ret != LDB_SUCCESS) {
1304 0 : ret = ENOMEM;
1305 0 : goto done;
1306 : }
1307 :
1308 0 : ret = ldb_msg_add_string(msg, "@IDXATTR", "sshKnownHostsExpire");
1309 0 : if (ret != LDB_SUCCESS) {
1310 0 : ret = ENOMEM;
1311 0 : goto done;
1312 : }
1313 :
1314 0 : ret = ldb_modify(sysdb->ldb, msg);
1315 0 : if (ret != LDB_SUCCESS) {
1316 0 : ret = sysdb_error_to_errno(ret);
1317 0 : goto done;
1318 : }
1319 :
1320 : /* conversion done, update version number */
1321 0 : ret = update_version(ctx);
1322 :
1323 : done:
1324 0 : ret = finish_upgrade(ret, &ctx, ver);
1325 0 : talloc_free(tmp_ctx);
1326 0 : return ret;
1327 : }
1328 :
1329 0 : int sysdb_upgrade_13(struct sysdb_ctx *sysdb, const char **ver)
1330 : {
1331 : struct upgrade_ctx *ctx;
1332 : struct ldb_result *dom_res;
1333 : struct ldb_result *res;
1334 : struct ldb_dn *basedn;
1335 0 : const char *attrs[] = { "cn", "name", NULL };
1336 : const char *tmp_str;
1337 : errno_t ret;
1338 : int i, j, l, n;
1339 :
1340 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_14, &ctx);
1341 0 : if (ret) {
1342 0 : return ret;
1343 : }
1344 :
1345 0 : basedn = ldb_dn_new(ctx, sysdb->ldb, SYSDB_BASE);
1346 0 : if (!basedn) {
1347 0 : DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n");
1348 0 : ret = EIO;
1349 0 : goto done;
1350 : }
1351 :
1352 0 : ret = ldb_search(sysdb->ldb, ctx, &dom_res,
1353 : basedn, LDB_SCOPE_ONELEVEL,
1354 : attrs, "objectclass=%s", SYSDB_SUBDOMAIN_CLASS);
1355 0 : if (ret != LDB_SUCCESS) {
1356 0 : DEBUG(SSSDBG_OP_FAILURE, "Failed to search subdomains\n");
1357 0 : ret = EIO;
1358 0 : goto done;
1359 : }
1360 :
1361 0 : for (i = 0; i < dom_res->count; i++) {
1362 :
1363 0 : tmp_str = ldb_msg_find_attr_as_string(dom_res->msgs[i], "cn", NULL);
1364 0 : if (tmp_str == NULL) {
1365 0 : DEBUG(SSSDBG_MINOR_FAILURE,
1366 : "The object [%s] doesn't have a name\n",
1367 : ldb_dn_get_linearized(dom_res->msgs[i]->dn));
1368 0 : continue;
1369 : }
1370 :
1371 0 : basedn = ldb_dn_new_fmt(ctx, sysdb->ldb, SYSDB_DOM_BASE, tmp_str);
1372 0 : if (!basedn) {
1373 0 : DEBUG(SSSDBG_OP_FAILURE,
1374 : "Failed to build base dn for subdomain %s\n", tmp_str);
1375 0 : continue;
1376 : }
1377 :
1378 0 : ret = ldb_search(sysdb->ldb, ctx, &res,
1379 : basedn, LDB_SCOPE_SUBTREE, attrs, NULL);
1380 0 : if (ret != LDB_SUCCESS) {
1381 0 : DEBUG(SSSDBG_OP_FAILURE,
1382 : "Failed to search subdomain %s\n", tmp_str);
1383 0 : talloc_free(basedn);
1384 0 : continue;
1385 : }
1386 :
1387 0 : l = ldb_dn_get_comp_num(basedn);
1388 0 : for (j = 0; j < res->count; j++) {
1389 0 : n = ldb_dn_get_comp_num(res->msgs[j]->dn);
1390 0 : if (n <= l + 1) {
1391 : /* Do not remove subdomain containers, only their contents */
1392 0 : continue;
1393 : }
1394 0 : ret = ldb_delete(sysdb->ldb, res->msgs[j]->dn);
1395 0 : if (ret) {
1396 0 : DEBUG(SSSDBG_OP_FAILURE,
1397 : "Failed to delete %s\n",
1398 : ldb_dn_get_linearized(res->msgs[j]->dn));
1399 0 : continue;
1400 : }
1401 : }
1402 :
1403 0 : talloc_free(basedn);
1404 0 : talloc_free(res);
1405 : }
1406 :
1407 0 : talloc_free(dom_res);
1408 :
1409 : /* conversion done, update version number */
1410 0 : ret = update_version(ctx);
1411 :
1412 : done:
1413 0 : ret = finish_upgrade(ret, &ctx, ver);
1414 0 : return ret;
1415 : }
1416 :
1417 0 : int sysdb_upgrade_14(struct sysdb_ctx *sysdb, const char **ver)
1418 : {
1419 : struct upgrade_ctx *ctx;
1420 : struct ldb_message *msg;
1421 : struct ldb_result *res;
1422 : struct ldb_dn *basedn;
1423 : struct ldb_dn *newdn;
1424 0 : const char *attrs[] = { SYSDB_NAME, NULL };
1425 : const char *tmp_str;
1426 : errno_t ret;
1427 : int i;
1428 :
1429 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_15, &ctx);
1430 0 : if (ret) {
1431 0 : return ret;
1432 : }
1433 :
1434 0 : basedn = ldb_dn_new(ctx, sysdb->ldb, SYSDB_BASE);
1435 0 : if (!basedn) {
1436 0 : DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n");
1437 0 : ret = EIO;
1438 0 : goto done;
1439 : }
1440 :
1441 : /* create base ranges container */
1442 0 : msg = ldb_msg_new(ctx);
1443 0 : if (!msg) {
1444 0 : ret = ENOMEM;
1445 0 : goto done;
1446 : }
1447 0 : msg->dn = ldb_dn_new(msg, sysdb->ldb, SYSDB_TMPL_RANGE_BASE);
1448 0 : if (!msg->dn) {
1449 0 : ret = ENOMEM;
1450 0 : goto done;
1451 : }
1452 0 : ret = ldb_msg_add_string(msg, "cn", "ranges");
1453 0 : if (ret != LDB_SUCCESS) {
1454 0 : ret = EIO;
1455 0 : goto done;
1456 : }
1457 : /* do a synchronous add */
1458 0 : ret = ldb_add(sysdb->ldb, msg);
1459 0 : if (ret != LDB_SUCCESS) {
1460 0 : DEBUG(SSSDBG_FATAL_FAILURE,
1461 : "Failed to upgrade DB (%d, [%s])!\n",
1462 : ret, ldb_errstring(sysdb->ldb));
1463 0 : ret = EIO;
1464 0 : goto done;
1465 : }
1466 0 : talloc_zfree(msg);
1467 :
1468 0 : ret = ldb_search(sysdb->ldb, ctx, &res,
1469 : basedn, LDB_SCOPE_SUBTREE, attrs,
1470 : "objectclass=%s", SYSDB_ID_RANGE_CLASS);
1471 0 : if (ret != LDB_SUCCESS) {
1472 0 : DEBUG(SSSDBG_OP_FAILURE, "Failed to search range objects\n");
1473 0 : ret = EIO;
1474 0 : goto done;
1475 : }
1476 :
1477 : /* Failure to convert any range is not fatal. As long as there are no
1478 : * left-over objects we can fail to move them around, as they will be
1479 : * recreated on the next online access */
1480 0 : for (i = 0; i < res->count; i++) {
1481 0 : tmp_str = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_NAME, NULL);
1482 0 : if (tmp_str == NULL) {
1483 0 : DEBUG(SSSDBG_OP_FAILURE,
1484 : "The object [%s] doesn't have a name\n",
1485 : ldb_dn_get_linearized(res->msgs[i]->dn));
1486 0 : ret = ldb_delete(sysdb->ldb, res->msgs[i]->dn);
1487 0 : if (ret) {
1488 0 : DEBUG(SSSDBG_OP_FAILURE,
1489 : "Failed to delete %s\n",
1490 : ldb_dn_get_linearized(res->msgs[i]->dn));
1491 0 : ret = EIO;
1492 0 : goto done;
1493 : }
1494 0 : continue;
1495 : }
1496 :
1497 0 : newdn = ldb_dn_new_fmt(ctx, sysdb->ldb, SYSDB_TMPL_RANGE, tmp_str);
1498 0 : if (!newdn) {
1499 0 : DEBUG(SSSDBG_CRIT_FAILURE,
1500 : "Failed to create new DN to move [%s]\n",
1501 : ldb_dn_get_linearized(res->msgs[i]->dn));
1502 0 : ret = ENOMEM;
1503 0 : goto done;
1504 : }
1505 0 : ret = ldb_rename(sysdb->ldb, res->msgs[i]->dn, newdn);
1506 0 : if (ret != LDB_SUCCESS) {
1507 0 : DEBUG(SSSDBG_CRIT_FAILURE,
1508 : "Failed to move [%s] to [%s]\n",
1509 : ldb_dn_get_linearized(res->msgs[i]->dn),
1510 : ldb_dn_get_linearized(newdn));
1511 0 : ret = ldb_delete(sysdb->ldb, res->msgs[i]->dn);
1512 0 : if (ret) {
1513 0 : DEBUG(SSSDBG_OP_FAILURE,
1514 : "Failed to delete %s\n",
1515 : ldb_dn_get_linearized(res->msgs[i]->dn));
1516 0 : ret = EIO;
1517 0 : goto done;
1518 : }
1519 : }
1520 0 : talloc_zfree(newdn);
1521 : }
1522 :
1523 : /* conversion done, update version number */
1524 0 : ret = update_version(ctx);
1525 :
1526 : done:
1527 0 : ret = finish_upgrade(ret, &ctx, ver);
1528 0 : return ret;
1529 : }
1530 :
1531 0 : int sysdb_upgrade_15(struct sysdb_ctx *sysdb, const char **ver)
1532 : {
1533 : TALLOC_CTX *tmp_ctx;
1534 : int ret;
1535 : struct ldb_message *msg;
1536 : struct upgrade_ctx *ctx;
1537 :
1538 0 : tmp_ctx = talloc_new(NULL);
1539 0 : if (!tmp_ctx) {
1540 0 : return ENOMEM;
1541 : }
1542 :
1543 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_16, &ctx);
1544 0 : if (ret) {
1545 0 : return ret;
1546 : }
1547 :
1548 : /* Add new indexes */
1549 0 : msg = ldb_msg_new(tmp_ctx);
1550 0 : if (!msg) {
1551 0 : ret = ENOMEM;
1552 0 : goto done;
1553 : }
1554 0 : msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES");
1555 0 : if (!msg->dn) {
1556 0 : ret = ENOMEM;
1557 0 : goto done;
1558 : }
1559 :
1560 : /* Case insensitive search for canonicalUserPrincipalName */
1561 0 : ret = ldb_msg_add_empty(msg, SYSDB_CANONICAL_UPN, LDB_FLAG_MOD_ADD, NULL);
1562 0 : if (ret != LDB_SUCCESS) {
1563 0 : ret = ENOMEM;
1564 0 : goto done;
1565 : }
1566 0 : ret = ldb_msg_add_string(msg, SYSDB_CANONICAL_UPN, "CASE_INSENSITIVE");
1567 0 : if (ret != LDB_SUCCESS) {
1568 0 : ret = ENOMEM;
1569 0 : goto done;
1570 : }
1571 :
1572 0 : ret = ldb_modify(sysdb->ldb, msg);
1573 0 : if (ret != LDB_SUCCESS) {
1574 0 : ret = sysdb_error_to_errno(ret);
1575 0 : goto done;
1576 : }
1577 :
1578 : /* conversion done, update version number */
1579 0 : ret = update_version(ctx);
1580 :
1581 : done:
1582 0 : ret = finish_upgrade(ret, &ctx, ver);
1583 0 : talloc_free(tmp_ctx);
1584 0 : return ret;
1585 : }
1586 :
1587 0 : int sysdb_upgrade_16(struct sysdb_ctx *sysdb, const char **ver)
1588 : {
1589 : struct ldb_message *msg;
1590 : struct upgrade_ctx *ctx;
1591 : errno_t ret;
1592 :
1593 0 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_17, &ctx);
1594 0 : if (ret) {
1595 0 : return ret;
1596 : }
1597 :
1598 0 : msg = ldb_msg_new(ctx);
1599 0 : if (msg == NULL) {
1600 0 : ret = ENOMEM;
1601 0 : goto done;
1602 : }
1603 :
1604 0 : msg->dn = ldb_dn_new(msg, sysdb->ldb, "@INDEXLIST");
1605 0 : if (msg->dn == NULL) {
1606 0 : ret = ENOMEM;
1607 0 : goto done;
1608 : }
1609 :
1610 : /* add index for objectSIDString */
1611 0 : ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
1612 0 : if (ret != LDB_SUCCESS) {
1613 0 : ret = ENOMEM;
1614 0 : goto done;
1615 : }
1616 :
1617 0 : ret = ldb_msg_add_string(msg, "@IDXATTR", "objectSIDString");
1618 0 : if (ret != LDB_SUCCESS) {
1619 0 : ret = ENOMEM;
1620 0 : goto done;
1621 : }
1622 :
1623 0 : ret = ldb_modify(sysdb->ldb, msg);
1624 0 : if (ret != LDB_SUCCESS) {
1625 0 : ret = sysdb_error_to_errno(ret);
1626 0 : goto done;
1627 : }
1628 :
1629 : /* conversion done, update version number */
1630 0 : ret = update_version(ctx);
1631 :
1632 : done:
1633 0 : ret = finish_upgrade(ret, &ctx, ver);
1634 0 : return ret;
1635 : }
1636 :
1637 : /*
1638 : * Example template for future upgrades.
1639 : * Copy and change version numbers as appropriate.
1640 : */
1641 : #if 0
1642 :
1643 : int sysdb_upgrade_13(struct sysdb_ctx *sysdb, const char **ver)
1644 : {
1645 : struct upgrade_ctx *ctx;
1646 : errno_t ret;
1647 :
1648 : ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_14, &ctx);
1649 : if (ret) {
1650 : return ret;
1651 : }
1652 :
1653 : /* DO STUFF HERE (use ctx, as the local temporary memory context) */
1654 :
1655 : /* conversion done, update version number */
1656 : ret = update_version(ctx);
1657 :
1658 : done:
1659 : ret = finish_upgrade(ret, &ctx, ver);
1660 : return ret;
1661 : }
1662 : #endif
|