1/* 2 SAM ldb module 3 4 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005 5 Copyright (C) Simo Sorce 2004-2008 6 Copyright (C) Matthias Dieter Wallnöfer 2009 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/* 23 * Name: ldb 24 * 25 * Component: ldb samldb module 26 * 27 * Description: add embedded user/group creation functionality 28 * 29 * Author: Simo Sorce 30 */ 31 32#include "includes.h" 33#include "libcli/ldap/ldap_ndr.h" 34#include "ldb_module.h" 35#include "dsdb/samdb/samdb.h" 36#include "libcli/security/security.h" 37#include "librpc/gen_ndr/ndr_security.h" 38#include "../lib/util/util_ldb.h" 39#include "ldb_wrap.h" 40 41struct samldb_ctx; 42 43typedef int (*samldb_step_fn_t)(struct samldb_ctx *); 44 45struct samldb_step { 46 struct samldb_step *next; 47 samldb_step_fn_t fn; 48}; 49 50struct samldb_ctx { 51 struct ldb_module *module; 52 struct ldb_request *req; 53 54 /* used for add operations */ 55 const char *type; 56 57 /* the resulting message */ 58 struct ldb_message *msg; 59 60 /* used to find parent domain */ 61 struct ldb_dn *check_dn; 62 struct ldb_dn *domain_dn; 63 struct dom_sid *domain_sid; 64 uint32_t next_rid; 65 66 /* holds the entry SID */ 67 struct dom_sid *sid; 68 69 /* holds a generic dn */ 70 struct ldb_dn *dn; 71 72 /* used in conjunction with "sid" in "samldb_dn_from_sid" */ 73 struct ldb_dn *res_dn; 74 75 /* used in conjunction with "dn" in "samldb_sid_from_dn" */ 76 struct dom_sid *res_sid; 77 78 /* used in "samldb_user_dn_to_prim_group_rid" */ 79 uint32_t prim_group_rid; 80 81 /* used in conjunction with "prim_group_rid" in 82 * "samldb_prim_group_rid_to_users_cnt" */ 83 unsigned int users_cnt; 84 85 /* used in "samldb_group_add_member" and "samldb_group_del_member" */ 86 struct ldb_dn *group_dn; 87 struct ldb_dn *member_dn; 88 89 /* used in "samldb_primary_group_change" */ 90 struct ldb_dn *user_dn; 91 struct ldb_dn *old_prim_group_dn, *new_prim_group_dn; 92 93 /* generic counter - used in "samldb_member_check" */ 94 unsigned int cnt; 95 96 /* all the async steps necessary to complete the operation */ 97 struct samldb_step *steps; 98 struct samldb_step *curstep; 99}; 100 101static struct samldb_ctx *samldb_ctx_init(struct ldb_module *module, 102 struct ldb_request *req) 103{ 104 struct ldb_context *ldb; 105 struct samldb_ctx *ac; 106 107 ldb = ldb_module_get_ctx(module); 108 109 ac = talloc_zero(req, struct samldb_ctx); 110 if (ac == NULL) { 111 ldb_oom(ldb); 112 return NULL; 113 } 114 115 ac->module = module; 116 ac->req = req; 117 118 return ac; 119} 120 121static int samldb_add_step(struct samldb_ctx *ac, samldb_step_fn_t fn) 122{ 123 struct samldb_step *step, *stepper; 124 125 step = talloc_zero(ac, struct samldb_step); 126 if (step == NULL) { 127 return LDB_ERR_OPERATIONS_ERROR; 128 } 129 130 step->fn = fn; 131 132 if (ac->steps == NULL) { 133 ac->steps = step; 134 ac->curstep = step; 135 } else { 136 if (ac->curstep == NULL) 137 return LDB_ERR_OPERATIONS_ERROR; 138 for (stepper = ac->curstep; stepper->next != NULL; 139 stepper = stepper->next); 140 stepper->next = step; 141 } 142 143 return LDB_SUCCESS; 144} 145 146static int samldb_first_step(struct samldb_ctx *ac) 147{ 148 if (ac->steps == NULL) { 149 return LDB_ERR_OPERATIONS_ERROR; 150 } 151 152 ac->curstep = ac->steps; 153 return ac->curstep->fn(ac); 154} 155 156static int samldb_next_step(struct samldb_ctx *ac) 157{ 158 if (ac->curstep->next) { 159 ac->curstep = ac->curstep->next; 160 return ac->curstep->fn(ac); 161 } 162 163 /* it is an error if the last step does not properly 164 * return to the upper module by itself */ 165 return LDB_ERR_OPERATIONS_ERROR; 166} 167 168/* 169 * samldb_get_parent_domain (async) 170 */ 171 172static int samldb_get_parent_domain(struct samldb_ctx *ac); 173 174static int samldb_get_parent_domain_callback(struct ldb_request *req, 175 struct ldb_reply *ares) 176{ 177 struct ldb_context *ldb; 178 struct samldb_ctx *ac; 179 const char *nextRid; 180 int ret; 181 182 ac = talloc_get_type(req->context, struct samldb_ctx); 183 ldb = ldb_module_get_ctx(ac->module); 184 185 if (!ares) { 186 ret = LDB_ERR_OPERATIONS_ERROR; 187 goto done; 188 } 189 if (ares->error != LDB_SUCCESS) { 190 return ldb_module_done(ac->req, ares->controls, 191 ares->response, ares->error); 192 } 193 194 switch (ares->type) { 195 case LDB_REPLY_ENTRY: 196 /* save entry */ 197 if ((ac->domain_dn != NULL) || (ac->domain_sid != NULL)) { 198 /* one too many! */ 199 ldb_set_errstring(ldb, 200 "Invalid number of results while searching " 201 "for domain object!"); 202 ret = LDB_ERR_OPERATIONS_ERROR; 203 break; 204 } 205 206 nextRid = ldb_msg_find_attr_as_string(ares->message, 207 "nextRid", NULL); 208 if (nextRid == NULL) { 209 ldb_asprintf_errstring(ldb, 210 "While looking for domain above %s attribute nextRid not found in %s!\n", 211 ldb_dn_get_linearized( 212 ac->req->op.add.message->dn), 213 ldb_dn_get_linearized(ares->message->dn)); 214 ret = LDB_ERR_OPERATIONS_ERROR; 215 break; 216 } 217 218 ac->next_rid = strtol(nextRid, NULL, 0); 219 220 ac->domain_sid = samdb_result_dom_sid(ac, ares->message, 221 "objectSid"); 222 if (ac->domain_sid == NULL) { 223 ldb_set_errstring(ldb, 224 "Unable to get the parent domain SID!\n"); 225 ret = LDB_ERR_CONSTRAINT_VIOLATION; 226 break; 227 } 228 ac->domain_dn = ldb_dn_copy(ac, ares->message->dn); 229 230 talloc_free(ares); 231 ret = LDB_SUCCESS; 232 break; 233 234 case LDB_REPLY_REFERRAL: 235 /* ignore */ 236 talloc_free(ares); 237 ret = LDB_SUCCESS; 238 break; 239 240 case LDB_REPLY_DONE: 241 talloc_free(ares); 242 if ((ac->domain_dn == NULL) || (ac->domain_sid == NULL)) { 243 /* not found -> retry */ 244 ret = samldb_get_parent_domain(ac); 245 } else { 246 /* found, go on */ 247 ret = samldb_next_step(ac); 248 } 249 break; 250 } 251 252done: 253 if (ret != LDB_SUCCESS) { 254 return ldb_module_done(ac->req, NULL, NULL, ret); 255 } 256 257 return LDB_SUCCESS; 258} 259 260/* Find a domain object in the parents of a particular DN. */ 261static int samldb_get_parent_domain(struct samldb_ctx *ac) 262{ 263 struct ldb_context *ldb; 264 static const char * const attrs[] = { "objectSid", "nextRid", NULL }; 265 struct ldb_request *req; 266 struct ldb_dn *dn; 267 int ret; 268 269 ldb = ldb_module_get_ctx(ac->module); 270 271 if (ac->check_dn == NULL) { 272 return LDB_ERR_OPERATIONS_ERROR; 273 } 274 275 dn = ldb_dn_get_parent(ac, ac->check_dn); 276 if (dn == NULL) { 277 ldb_set_errstring(ldb, 278 "Unable to find parent domain object!"); 279 return LDB_ERR_CONSTRAINT_VIOLATION; 280 } 281 282 ac->check_dn = dn; 283 284 ret = ldb_build_search_req(&req, ldb, ac, 285 dn, LDB_SCOPE_BASE, 286 "(|(objectClass=domain)" 287 "(objectClass=builtinDomain)" 288 "(objectClass=samba4LocalDomain))", 289 attrs, 290 NULL, 291 ac, samldb_get_parent_domain_callback, 292 ac->req); 293 294 if (ret != LDB_SUCCESS) { 295 return ret; 296 } 297 298 return ldb_next_request(ac->module, req); 299} 300 301 302static int samldb_generate_samAccountName(struct ldb_message *msg) 303{ 304 char *name; 305 306 /* Format: $000000-000000000000 */ 307 308 name = talloc_asprintf(msg, "$%.6X-%.6X%.6X", 309 (unsigned int)generate_random(), 310 (unsigned int)generate_random(), 311 (unsigned int)generate_random()); 312 if (name == NULL) { 313 return LDB_ERR_OPERATIONS_ERROR; 314 } 315 return ldb_msg_add_steal_string(msg, "samAccountName", name); 316} 317 318/* 319 * samldb_check_samAccountName (async) 320 */ 321 322static int samldb_check_samAccountName_callback(struct ldb_request *req, 323 struct ldb_reply *ares) 324{ 325 struct samldb_ctx *ac; 326 int ret; 327 328 ac = talloc_get_type(req->context, struct samldb_ctx); 329 330 if (ares->error != LDB_SUCCESS) { 331 return ldb_module_done(ac->req, ares->controls, 332 ares->response, ares->error); 333 } 334 335 switch (ares->type) { 336 case LDB_REPLY_ENTRY: 337 /* if we get an entry it means this samAccountName 338 * already exists */ 339 return ldb_module_done(ac->req, NULL, NULL, 340 LDB_ERR_ENTRY_ALREADY_EXISTS); 341 342 case LDB_REPLY_REFERRAL: 343 /* this should not happen */ 344 return ldb_module_done(ac->req, NULL, NULL, 345 LDB_ERR_OPERATIONS_ERROR); 346 347 case LDB_REPLY_DONE: 348 /* not found, go on */ 349 talloc_free(ares); 350 ret = samldb_next_step(ac); 351 break; 352 } 353 354 if (ret != LDB_SUCCESS) { 355 return ldb_module_done(ac->req, NULL, NULL, ret); 356 } 357 358 return LDB_SUCCESS; 359} 360 361static int samldb_check_samAccountName(struct samldb_ctx *ac) 362{ 363 struct ldb_context *ldb; 364 struct ldb_request *req; 365 const char *name; 366 char *filter; 367 int ret; 368 369 ldb = ldb_module_get_ctx(ac->module); 370 371 if (ldb_msg_find_element(ac->msg, "samAccountName") == NULL) { 372 ret = samldb_generate_samAccountName(ac->msg); 373 if (ret != LDB_SUCCESS) { 374 return ret; 375 } 376 } 377 378 name = ldb_msg_find_attr_as_string(ac->msg, "samAccountName", NULL); 379 if (name == NULL) { 380 return LDB_ERR_OPERATIONS_ERROR; 381 } 382 filter = talloc_asprintf(ac, "samAccountName=%s", ldb_binary_encode_string(ac, name)); 383 if (filter == NULL) { 384 return LDB_ERR_OPERATIONS_ERROR; 385 } 386 387 ret = ldb_build_search_req(&req, ldb, ac, 388 ac->domain_dn, LDB_SCOPE_SUBTREE, 389 filter, NULL, 390 NULL, 391 ac, samldb_check_samAccountName_callback, 392 ac->req); 393 talloc_free(filter); 394 if (ret != LDB_SUCCESS) { 395 return ret; 396 } 397 return ldb_next_request(ac->module, req); 398} 399 400 401static int samldb_check_samAccountType(struct samldb_ctx *ac) 402{ 403 struct ldb_context *ldb; 404 unsigned int account_type; 405 unsigned int group_type; 406 unsigned int uac; 407 int ret; 408 409 ldb = ldb_module_get_ctx(ac->module); 410 411 /* make sure sAMAccountType is not specified */ 412 if (ldb_msg_find_element(ac->msg, "sAMAccountType") != NULL) { 413 ldb_asprintf_errstring(ldb, 414 "sAMAccountType must not be specified!"); 415 return LDB_ERR_UNWILLING_TO_PERFORM; 416 } 417 418 if (strcmp("user", ac->type) == 0) { 419 uac = samdb_result_uint(ac->msg, "userAccountControl", 0); 420 if (uac == 0) { 421 ldb_asprintf_errstring(ldb, 422 "userAccountControl invalid!"); 423 return LDB_ERR_UNWILLING_TO_PERFORM; 424 } else { 425 account_type = ds_uf2atype(uac); 426 ret = samdb_msg_add_uint(ldb, 427 ac->msg, ac->msg, 428 "sAMAccountType", 429 account_type); 430 if (ret != LDB_SUCCESS) { 431 return ret; 432 } 433 } 434 } else 435 if (strcmp("group", ac->type) == 0) { 436 437 group_type = samdb_result_uint(ac->msg, "groupType", 0); 438 if (group_type == 0) { 439 ldb_asprintf_errstring(ldb, 440 "groupType invalid!"); 441 return LDB_ERR_UNWILLING_TO_PERFORM; 442 } else { 443 account_type = ds_gtype2atype(group_type); 444 ret = samdb_msg_add_uint(ldb, 445 ac->msg, ac->msg, 446 "sAMAccountType", 447 account_type); 448 if (ret != LDB_SUCCESS) { 449 return ret; 450 } 451 } 452 } 453 454 return samldb_next_step(ac); 455} 456 457 458/* 459 * samldb_get_sid_domain (async) 460 */ 461 462static int samldb_get_sid_domain_callback(struct ldb_request *req, 463 struct ldb_reply *ares) 464{ 465 struct ldb_context *ldb; 466 struct samldb_ctx *ac; 467 const char *nextRid; 468 int ret; 469 470 ac = talloc_get_type(req->context, struct samldb_ctx); 471 ldb = ldb_module_get_ctx(ac->module); 472 473 if (!ares) { 474 ret = LDB_ERR_OPERATIONS_ERROR; 475 goto done; 476 } 477 if (ares->error != LDB_SUCCESS) { 478 return ldb_module_done(ac->req, ares->controls, 479 ares->response, ares->error); 480 } 481 482 switch (ares->type) { 483 case LDB_REPLY_ENTRY: 484 /* save entry */ 485 if (ac->next_rid != 0) { 486 /* one too many! */ 487 ldb_set_errstring(ldb, 488 "Invalid number of results while searching " 489 "for domain object!"); 490 ret = LDB_ERR_OPERATIONS_ERROR; 491 break; 492 } 493 494 nextRid = ldb_msg_find_attr_as_string(ares->message, 495 "nextRid", NULL); 496 if (nextRid == NULL) { 497 ldb_asprintf_errstring(ldb, 498 "Attribute nextRid not found in %s!\n", 499 ldb_dn_get_linearized(ares->message->dn)); 500 ret = LDB_ERR_OPERATIONS_ERROR; 501 break; 502 } 503 504 ac->next_rid = strtol(nextRid, NULL, 0); 505 506 ac->domain_dn = ldb_dn_copy(ac, ares->message->dn); 507 508 talloc_free(ares); 509 ret = LDB_SUCCESS; 510 break; 511 512 case LDB_REPLY_REFERRAL: 513 /* ignore */ 514 talloc_free(ares); 515 ret = LDB_SUCCESS; 516 break; 517 518 case LDB_REPLY_DONE: 519 talloc_free(ares); 520 if (ac->next_rid == 0) { 521 ldb_asprintf_errstring(ldb, 522 "Unable to get nextRid from domain entry!\n"); 523 ret = LDB_ERR_OPERATIONS_ERROR; 524 break; 525 } 526 527 /* found, go on */ 528 ret = samldb_next_step(ac); 529 break; 530 } 531 532done: 533 if (ret != LDB_SUCCESS) { 534 return ldb_module_done(ac->req, NULL, NULL, ret); 535 } 536 537 return LDB_SUCCESS; 538} 539 540/* Find a domain object in the parents of a particular DN. */ 541static int samldb_get_sid_domain(struct samldb_ctx *ac) 542{ 543 struct ldb_context *ldb; 544 static const char * const attrs[2] = { "nextRid", NULL }; 545 struct ldb_request *req; 546 char *filter; 547 int ret; 548 549 ldb = ldb_module_get_ctx(ac->module); 550 551 if (ac->sid == NULL) { 552 return LDB_ERR_OPERATIONS_ERROR; 553 } 554 555 ac->domain_sid = dom_sid_dup(ac, ac->sid); 556 if (!ac->domain_sid) { 557 return LDB_ERR_OPERATIONS_ERROR; 558 } 559 /* get the domain component part of the provided SID */ 560 ac->domain_sid->num_auths--; 561 562 filter = talloc_asprintf(ac, "(&(objectSid=%s)" 563 "(|(objectClass=domain)" 564 "(objectClass=builtinDomain)" 565 "(objectClass=samba4LocalDomain)))", 566 ldap_encode_ndr_dom_sid(ac, ac->domain_sid)); 567 if (filter == NULL) { 568 return LDB_ERR_OPERATIONS_ERROR; 569 } 570 571 ret = ldb_build_search_req(&req, ldb, ac, 572 ldb_get_default_basedn(ldb), 573 LDB_SCOPE_SUBTREE, 574 filter, attrs, 575 NULL, 576 ac, samldb_get_sid_domain_callback, 577 ac->req); 578 579 if (ret != LDB_SUCCESS) { 580 return ret; 581 } 582 583 ac->next_rid = 0; 584 return ldb_next_request(ac->module, req); 585} 586 587/* 588 * samldb_dn_from_sid (async) 589 */ 590 591static int samldb_dn_from_sid(struct samldb_ctx *ac); 592 593static int samldb_dn_from_sid_callback(struct ldb_request *req, 594 struct ldb_reply *ares) 595{ 596 struct ldb_context *ldb; 597 struct samldb_ctx *ac; 598 int ret; 599 600 ac = talloc_get_type(req->context, struct samldb_ctx); 601 ldb = ldb_module_get_ctx(ac->module); 602 603 if (!ares) { 604 ret = LDB_ERR_OPERATIONS_ERROR; 605 goto done; 606 } 607 if (ares->error != LDB_SUCCESS) { 608 return ldb_module_done(ac->req, ares->controls, 609 ares->response, ares->error); 610 } 611 612 switch (ares->type) { 613 case LDB_REPLY_ENTRY: 614 /* save entry */ 615 if (ac->res_dn != NULL) { 616 /* one too many! */ 617 ldb_set_errstring(ldb, 618 "Invalid number of results while searching " 619 "for domain objects!"); 620 ret = LDB_ERR_OPERATIONS_ERROR; 621 break; 622 } 623 ac->res_dn = ldb_dn_copy(ac, ares->message->dn); 624 625 talloc_free(ares); 626 ret = LDB_SUCCESS; 627 break; 628 629 case LDB_REPLY_REFERRAL: 630 /* ignore */ 631 talloc_free(ares); 632 ret = LDB_SUCCESS; 633 break; 634 635 case LDB_REPLY_DONE: 636 talloc_free(ares); 637 638 /* found or not found, go on */ 639 ret = samldb_next_step(ac); 640 break; 641 } 642 643done: 644 if (ret != LDB_SUCCESS) { 645 return ldb_module_done(ac->req, NULL, NULL, ret); 646 } 647 648 return LDB_SUCCESS; 649} 650 651/* Finds the DN "res_dn" of an object with a given SID "sid" */ 652static int samldb_dn_from_sid(struct samldb_ctx *ac) 653{ 654 struct ldb_context *ldb; 655 static const char * const attrs[] = { NULL }; 656 struct ldb_request *req; 657 char *filter; 658 int ret; 659 660 ldb = ldb_module_get_ctx(ac->module); 661 662 if (ac->sid == NULL) 663 return LDB_ERR_OPERATIONS_ERROR; 664 665 filter = talloc_asprintf(ac, "(objectSid=%s)", 666 ldap_encode_ndr_dom_sid(ac, ac->sid)); 667 if (filter == NULL) 668 return LDB_ERR_OPERATIONS_ERROR; 669 670 ret = ldb_build_search_req(&req, ldb, ac, 671 ldb_get_default_basedn(ldb), 672 LDB_SCOPE_SUBTREE, 673 filter, attrs, 674 NULL, 675 ac, samldb_dn_from_sid_callback, 676 ac->req); 677 if (ret != LDB_SUCCESS) 678 return ret; 679 680 return ldb_next_request(ac->module, req); 681} 682 683 684static int samldb_check_primaryGroupID_1(struct samldb_ctx *ac) 685{ 686 struct ldb_context *ldb; 687 uint32_t rid; 688 689 ldb = ldb_module_get_ctx(ac->module); 690 691 rid = samdb_result_uint(ac->msg, "primaryGroupID", ~0); 692 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid); 693 if (ac->sid == NULL) 694 return LDB_ERR_OPERATIONS_ERROR; 695 ac->res_dn = NULL; 696 697 return samldb_next_step(ac); 698} 699 700static int samldb_check_primaryGroupID_2(struct samldb_ctx *ac) 701{ 702 if (ac->res_dn == NULL) 703 return LDB_ERR_UNWILLING_TO_PERFORM; 704 705 return samldb_next_step(ac); 706} 707 708 709static bool samldb_msg_add_sid(struct ldb_message *msg, 710 const char *name, 711 const struct dom_sid *sid) 712{ 713 struct ldb_val v; 714 enum ndr_err_code ndr_err; 715 716 ndr_err = ndr_push_struct_blob(&v, msg, NULL, sid, 717 (ndr_push_flags_fn_t)ndr_push_dom_sid); 718 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 719 return false; 720 } 721 return (ldb_msg_add_value(msg, name, &v, NULL) == 0); 722} 723 724static int samldb_new_sid(struct samldb_ctx *ac) 725{ 726 727 if (ac->domain_sid == NULL || ac->next_rid == 0) { 728 return LDB_ERR_OPERATIONS_ERROR; 729 } 730 731 ac->sid = dom_sid_add_rid(ac, ac->domain_sid, ac->next_rid + 1); 732 if (ac->sid == NULL) { 733 return LDB_ERR_OPERATIONS_ERROR; 734 } 735 736 if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) { 737 return LDB_ERR_OPERATIONS_ERROR; 738 } 739 740 return samldb_next_step(ac); 741} 742 743/* 744 * samldb_notice_sid_callback (async) 745 */ 746 747static int samldb_notice_sid_callback(struct ldb_request *req, 748 struct ldb_reply *ares) 749{ 750 struct ldb_context *ldb; 751 struct samldb_ctx *ac; 752 int ret; 753 754 ac = talloc_get_type(req->context, struct samldb_ctx); 755 ldb = ldb_module_get_ctx(ac->module); 756 757 if (!ares) { 758 ret = LDB_ERR_OPERATIONS_ERROR; 759 goto done; 760 } 761 if (ares->error != LDB_SUCCESS) { 762 return ldb_module_done(ac->req, ares->controls, 763 ares->response, ares->error); 764 } 765 if (ares->type != LDB_REPLY_DONE) { 766 ldb_set_errstring(ldb, 767 "Invalid reply type!\n"); 768 ret = LDB_ERR_OPERATIONS_ERROR; 769 goto done; 770 } 771 772 ret = samldb_next_step(ac); 773 774done: 775 if (ret != LDB_SUCCESS) { 776 return ldb_module_done(ac->req, NULL, NULL, ret); 777 } 778 779 return LDB_SUCCESS; 780} 781 782/* If we are adding new users/groups, we need to update the nextRid 783 * attribute to be 'above' the new/incoming RID. Attempt to do it 784 * atomically. */ 785static int samldb_notice_sid(struct samldb_ctx *ac) 786{ 787 struct ldb_context *ldb; 788 uint32_t old_id, new_id; 789 struct ldb_request *req; 790 struct ldb_message *msg; 791 struct ldb_message_element *els; 792 struct ldb_val *vals; 793 int ret; 794 795 ldb = ldb_module_get_ctx(ac->module); 796 old_id = ac->next_rid; 797 new_id = ac->sid->sub_auths[ac->sid->num_auths - 1]; 798 799 if (old_id >= new_id) { 800 /* no need to update the domain nextRid attribute */ 801 return samldb_next_step(ac); 802 } 803 804 /* we do a delete and add as a single operation. That prevents 805 a race, in case we are not actually on a transaction db */ 806 msg = ldb_msg_new(ac); 807 if (msg == NULL) { 808 ldb_oom(ldb); 809 return LDB_ERR_OPERATIONS_ERROR; 810 } 811 els = talloc_array(msg, struct ldb_message_element, 2); 812 if (els == NULL) { 813 ldb_oom(ldb); 814 return LDB_ERR_OPERATIONS_ERROR; 815 } 816 vals = talloc_array(msg, struct ldb_val, 2); 817 if (vals == NULL) { 818 ldb_oom(ldb); 819 return LDB_ERR_OPERATIONS_ERROR; 820 } 821 msg->dn = ac->domain_dn; 822 msg->num_elements = 2; 823 msg->elements = els; 824 825 els[0].num_values = 1; 826 els[0].values = &vals[0]; 827 els[0].flags = LDB_FLAG_MOD_DELETE; 828 els[0].name = talloc_strdup(msg, "nextRid"); 829 if (!els[0].name) { 830 ldb_oom(ldb); 831 return LDB_ERR_OPERATIONS_ERROR; 832 } 833 834 els[1].num_values = 1; 835 els[1].values = &vals[1]; 836 els[1].flags = LDB_FLAG_MOD_ADD; 837 els[1].name = els[0].name; 838 839 vals[0].data = (uint8_t *)talloc_asprintf(vals, "%u", old_id); 840 if (!vals[0].data) { 841 ldb_oom(ldb); 842 return LDB_ERR_OPERATIONS_ERROR; 843 } 844 vals[0].length = strlen((char *)vals[0].data); 845 846 vals[1].data = (uint8_t *)talloc_asprintf(vals, "%u", new_id); 847 if (!vals[1].data) { 848 ldb_oom(ldb); 849 return LDB_ERR_OPERATIONS_ERROR; 850 } 851 vals[1].length = strlen((char *)vals[1].data); 852 853 ret = ldb_build_mod_req(&req, ldb, ac, 854 msg, NULL, 855 ac, samldb_notice_sid_callback, 856 ac->req); 857 if (ret != LDB_SUCCESS) { 858 return ret; 859 } 860 861 return ldb_next_request(ac->module, req); 862} 863 864/* 865 * samldb_add_entry (async) 866 */ 867 868static int samldb_add_entry_callback(struct ldb_request *req, 869 struct ldb_reply *ares) 870{ 871 struct ldb_context *ldb; 872 struct samldb_ctx *ac; 873 874 ac = talloc_get_type(req->context, struct samldb_ctx); 875 ldb = ldb_module_get_ctx(ac->module); 876 877 if (!ares) { 878 return ldb_module_done(ac->req, NULL, NULL, 879 LDB_ERR_OPERATIONS_ERROR); 880 } 881 if (ares->error != LDB_SUCCESS) { 882 return ldb_module_done(ac->req, ares->controls, 883 ares->response, ares->error); 884 } 885 if (ares->type != LDB_REPLY_DONE) { 886 ldb_set_errstring(ldb, 887 "Invalid reply type!\n"); 888 return ldb_module_done(ac->req, NULL, NULL, 889 LDB_ERR_OPERATIONS_ERROR); 890 } 891 892 /* we exit the samldb module here */ 893 return ldb_module_done(ac->req, ares->controls, 894 ares->response, LDB_SUCCESS); 895} 896 897static int samldb_add_entry(struct samldb_ctx *ac) 898{ 899 struct ldb_context *ldb; 900 struct ldb_request *req; 901 int ret; 902 903 ldb = ldb_module_get_ctx(ac->module); 904 905 ret = ldb_build_add_req(&req, ldb, ac, 906 ac->msg, 907 ac->req->controls, 908 ac, samldb_add_entry_callback, 909 ac->req); 910 if (ret != LDB_SUCCESS) { 911 return ret; 912 } 913 914 return ldb_next_request(ac->module, req); 915} 916 917 918static int samldb_fill_object(struct samldb_ctx *ac, const char *type) 919{ 920 struct ldb_context *ldb; 921 int ret; 922 923 ldb = ldb_module_get_ctx(ac->module); 924 925 /* search for a parent domain objet */ 926 ac->check_dn = ac->req->op.add.message->dn; 927 ret = samldb_add_step(ac, samldb_get_parent_domain); 928 if (ret != LDB_SUCCESS) return ret; 929 930 /* Add informations for the different account types */ 931 ac->type = type; 932 if (strcmp(ac->type, "user") == 0) { 933 ret = samdb_find_or_add_attribute(ldb, ac->msg, 934 "userAccountControl", "546"); 935 if (ret != LDB_SUCCESS) return ret; 936 ret = samdb_find_or_add_attribute(ldb, ac->msg, 937 "badPwdCount", "0"); 938 if (ret != LDB_SUCCESS) return ret; 939 ret = samdb_find_or_add_attribute(ldb, ac->msg, 940 "codePage", "0"); 941 if (ret != LDB_SUCCESS) return ret; 942 ret = samdb_find_or_add_attribute(ldb, ac->msg, 943 "countryCode", "0"); 944 if (ret != LDB_SUCCESS) return ret; 945 ret = samdb_find_or_add_attribute(ldb, ac->msg, 946 "badPasswordTime", "0"); 947 if (ret != LDB_SUCCESS) return ret; 948 ret = samdb_find_or_add_attribute(ldb, ac->msg, 949 "lastLogoff", "0"); 950 if (ret != LDB_SUCCESS) return ret; 951 ret = samdb_find_or_add_attribute(ldb, ac->msg, 952 "lastLogon", "0"); 953 if (ret != LDB_SUCCESS) return ret; 954 ret = samdb_find_or_add_attribute(ldb, ac->msg, 955 "pwdLastSet", "0"); 956 if (ret != LDB_SUCCESS) return ret; 957 ret = samdb_find_or_add_attribute(ldb, ac->msg, 958 "primaryGroupID", "513"); 959 if (ret != LDB_SUCCESS) return ret; 960 ret = samdb_find_or_add_attribute(ldb, ac->msg, 961 "accountExpires", "9223372036854775807"); 962 if (ret != LDB_SUCCESS) return ret; 963 ret = samdb_find_or_add_attribute(ldb, ac->msg, 964 "logonCount", "0"); 965 if (ret != LDB_SUCCESS) return ret; 966 } else if (strcmp(ac->type, "group") == 0) { 967 ret = samdb_find_or_add_attribute(ldb, ac->msg, 968 "groupType", "-2147483646"); 969 if (ret != LDB_SUCCESS) return ret; 970 } else { 971 /* we should only have "user" and "group" */ 972 ldb_asprintf_errstring(ldb, 973 "Invalid entry type!\n"); 974 return LDB_ERR_OPERATIONS_ERROR; 975 } 976 977 /* check if we have a valid samAccountName */ 978 ret = samldb_add_step(ac, samldb_check_samAccountName); 979 if (ret != LDB_SUCCESS) return ret; 980 981 /* check account_type/group_type */ 982 ret = samldb_add_step(ac, samldb_check_samAccountType); 983 if (ret != LDB_SUCCESS) return ret; 984 985 /* check if we have a valid primary group ID */ 986 if (strcmp(ac->type, "user") == 0) { 987 ret = samldb_add_step(ac, samldb_check_primaryGroupID_1); 988 if (ret != LDB_SUCCESS) return ret; 989 ret = samldb_add_step(ac, samldb_dn_from_sid); 990 if (ret != LDB_SUCCESS) return ret; 991 ret = samldb_add_step(ac, samldb_check_primaryGroupID_2); 992 if (ret != LDB_SUCCESS) return ret; 993 } 994 995 /* check if we have a valid SID */ 996 ac->sid = samdb_result_dom_sid(ac, ac->msg, "objectSid"); 997 if ( ! ac->sid) { 998 ret = samldb_add_step(ac, samldb_new_sid); 999 if (ret != LDB_SUCCESS) return ret; 1000 } else { 1001 ret = samldb_add_step(ac, samldb_get_sid_domain); 1002 if (ret != LDB_SUCCESS) return ret; 1003 } 1004 1005 ret = samldb_add_step(ac, samldb_notice_sid); 1006 if (ret != LDB_SUCCESS) return ret; 1007 1008 /* finally proceed with adding the entry */ 1009 ret = samldb_add_step(ac, samldb_add_entry); 1010 if (ret != LDB_SUCCESS) return ret; 1011 1012 return samldb_first_step(ac); 1013} 1014 1015/* 1016 * samldb_foreign_notice_sid (async) 1017 */ 1018 1019static int samldb_foreign_notice_sid_callback(struct ldb_request *req, 1020 struct ldb_reply *ares) 1021{ 1022 struct ldb_context *ldb; 1023 struct samldb_ctx *ac; 1024 const char *nextRid; 1025 const char *name; 1026 int ret; 1027 1028 ac = talloc_get_type(req->context, struct samldb_ctx); 1029 ldb = ldb_module_get_ctx(ac->module); 1030 1031 if (!ares) { 1032 ret = LDB_ERR_OPERATIONS_ERROR; 1033 goto done; 1034 } 1035 if (ares->error != LDB_SUCCESS) { 1036 return ldb_module_done(ac->req, ares->controls, 1037 ares->response, ares->error); 1038 } 1039 1040 switch (ares->type) { 1041 case LDB_REPLY_ENTRY: 1042 /* save entry */ 1043 if (ac->next_rid != 0) { 1044 /* one too many! */ 1045 ldb_set_errstring(ldb, 1046 "Invalid number of results while searching " 1047 "for domain object!"); 1048 ret = LDB_ERR_OPERATIONS_ERROR; 1049 break; 1050 } 1051 1052 nextRid = ldb_msg_find_attr_as_string(ares->message, 1053 "nextRid", NULL); 1054 if (nextRid == NULL) { 1055 ldb_asprintf_errstring(ldb, 1056 "while looking for forign sid %s attribute nextRid not found in %s\n", 1057 dom_sid_string(ares, ac->sid), 1058 ldb_dn_get_linearized(ares->message->dn)); 1059 ret = LDB_ERR_OPERATIONS_ERROR; 1060 break; 1061 } 1062 1063 ac->next_rid = strtol(nextRid, NULL, 0); 1064 1065 ac->domain_dn = ldb_dn_copy(ac, ares->message->dn); 1066 1067 name = samdb_result_string(ares->message, "name", NULL); 1068 ldb_debug(ldb, LDB_DEBUG_TRACE, 1069 "NOTE (strange but valid): Adding foreign SID " 1070 "record with SID %s, but this domain (%s) is " 1071 "not foreign in the database", 1072 dom_sid_string(ares, ac->sid), name); 1073 1074 talloc_free(ares); 1075 ret = LDB_SUCCESS; 1076 break; 1077 1078 case LDB_REPLY_REFERRAL: 1079 /* ignore */ 1080 talloc_free(ares); 1081 ret = LDB_SUCCESS; 1082 break; 1083 1084 case LDB_REPLY_DONE: 1085 talloc_free(ares); 1086 1087 /* if this is a fake foreign SID, notice the SID */ 1088 if (ac->domain_dn) { 1089 ret = samldb_notice_sid(ac); 1090 break; 1091 } 1092 1093 /* found, go on */ 1094 ret = samldb_next_step(ac); 1095 break; 1096 } 1097 1098done: 1099 if (ret != LDB_SUCCESS) { 1100 return ldb_module_done(ac->req, NULL, NULL, ret); 1101 } 1102 1103 return LDB_SUCCESS; 1104} 1105 1106/* Find a domain object in the parents of a particular DN. */ 1107static int samldb_foreign_notice_sid(struct samldb_ctx *ac) 1108{ 1109 struct ldb_context *ldb; 1110 static const char * const attrs[3] = { "nextRid", "name", NULL }; 1111 struct ldb_request *req; 1112 NTSTATUS status; 1113 char *filter; 1114 int ret; 1115 1116 ldb = ldb_module_get_ctx(ac->module); 1117 1118 if (ac->sid == NULL) { 1119 return LDB_ERR_OPERATIONS_ERROR; 1120 } 1121 1122 status = dom_sid_split_rid(ac, ac->sid, &ac->domain_sid, NULL); 1123 if (!NT_STATUS_IS_OK(status)) { 1124 return LDB_ERR_OPERATIONS_ERROR; 1125 } 1126 1127 filter = talloc_asprintf(ac, "(&(objectSid=%s)(objectclass=domain))", 1128 ldap_encode_ndr_dom_sid(ac, ac->domain_sid)); 1129 if (filter == NULL) { 1130 return LDB_ERR_OPERATIONS_ERROR; 1131 } 1132 1133 ret = ldb_build_search_req(&req, ldb, ac, 1134 ldb_get_default_basedn(ldb), 1135 LDB_SCOPE_SUBTREE, 1136 filter, attrs, 1137 NULL, 1138 ac, samldb_foreign_notice_sid_callback, 1139 ac->req); 1140 1141 if (ret != LDB_SUCCESS) { 1142 return ret; 1143 } 1144 1145 return ldb_next_request(ac->module, req); 1146} 1147 1148 1149static int samldb_fill_foreignSecurityPrincipal_object(struct samldb_ctx *ac) 1150{ 1151 struct ldb_context *ldb; 1152 int ret; 1153 1154 ldb = ldb_module_get_ctx(ac->module); 1155 1156 ac->next_rid = 0; 1157 1158 ac->sid = samdb_result_dom_sid(ac->msg, ac->msg, "objectSid"); 1159 if (ac->sid == NULL) { 1160 ac->sid = dom_sid_parse_talloc(ac->msg, 1161 (const char *)ldb_dn_get_rdn_val(ac->msg->dn)->data); 1162 if (!ac->sid) { 1163 ldb_set_errstring(ldb, 1164 "No valid SID found in " 1165 "ForeignSecurityPrincipal CN!"); 1166 talloc_free(ac); 1167 return LDB_ERR_CONSTRAINT_VIOLATION; 1168 } 1169 if ( ! samldb_msg_add_sid(ac->msg, "objectSid", ac->sid)) { 1170 talloc_free(ac); 1171 return LDB_ERR_OPERATIONS_ERROR; 1172 } 1173 } 1174 1175 /* check if we need to notice this SID */ 1176 ret = samldb_add_step(ac, samldb_foreign_notice_sid); 1177 if (ret != LDB_SUCCESS) return ret; 1178 1179 /* finally proceed with adding the entry */ 1180 ret = samldb_add_step(ac, samldb_add_entry); 1181 if (ret != LDB_SUCCESS) return ret; 1182 1183 return samldb_first_step(ac); 1184} 1185 1186static int samldb_check_rdn(struct ldb_module *module, struct ldb_dn *dn) 1187{ 1188 struct ldb_context *ldb; 1189 const char *rdn_name; 1190 1191 ldb = ldb_module_get_ctx(module); 1192 rdn_name = ldb_dn_get_rdn_name(dn); 1193 1194 if (strcasecmp(rdn_name, "cn") != 0) { 1195 ldb_asprintf_errstring(ldb, 1196 "Bad RDN (%s=) for samldb object, " 1197 "should be CN=!\n", rdn_name); 1198 return LDB_ERR_CONSTRAINT_VIOLATION; 1199 } 1200 1201 return LDB_SUCCESS; 1202} 1203 1204/* 1205 * samldb_sid_from_dn (async) 1206 */ 1207 1208static int samldb_sid_from_dn(struct samldb_ctx *ac); 1209 1210static int samldb_sid_from_dn_callback(struct ldb_request *req, 1211 struct ldb_reply *ares) 1212{ 1213 struct ldb_context *ldb; 1214 struct samldb_ctx *ac; 1215 int ret; 1216 1217 ac = talloc_get_type(req->context, struct samldb_ctx); 1218 ldb = ldb_module_get_ctx(ac->module); 1219 1220 if (!ares) { 1221 ret = LDB_ERR_OPERATIONS_ERROR; 1222 goto done; 1223 } 1224 if (ares->error != LDB_SUCCESS) { 1225 return ldb_module_done(ac->req, ares->controls, 1226 ares->response, ares->error); 1227 } 1228 1229 switch (ares->type) { 1230 case LDB_REPLY_ENTRY: 1231 /* save entry */ 1232 if (ac->res_sid != NULL) { 1233 /* one too many! */ 1234 ldb_set_errstring(ldb, 1235 "Invalid number of results while searching " 1236 "for domain objects!"); 1237 ret = LDB_ERR_OPERATIONS_ERROR; 1238 break; 1239 } 1240 ac->res_sid = samdb_result_dom_sid(ac, ares->message, 1241 "objectSid"); 1242 1243 talloc_free(ares); 1244 ret = LDB_SUCCESS; 1245 break; 1246 1247 case LDB_REPLY_REFERRAL: 1248 /* ignore */ 1249 talloc_free(ares); 1250 ret = LDB_SUCCESS; 1251 break; 1252 1253 case LDB_REPLY_DONE: 1254 talloc_free(ares); 1255 1256 /* found or not found, go on */ 1257 ret = samldb_next_step(ac); 1258 break; 1259 } 1260 1261done: 1262 if (ret != LDB_SUCCESS) { 1263 return ldb_module_done(ac->req, NULL, NULL, ret); 1264 } 1265 1266 return LDB_SUCCESS; 1267} 1268 1269/* Finds the SID "res_sid" of an object with a given DN "dn" */ 1270static int samldb_sid_from_dn(struct samldb_ctx *ac) 1271{ 1272 struct ldb_context *ldb; 1273 static const char * const attrs[] = { "objectSid" }; 1274 struct ldb_request *req; 1275 int ret; 1276 1277 ldb = ldb_module_get_ctx(ac->module); 1278 1279 if (ac->dn == NULL) 1280 return LDB_ERR_OPERATIONS_ERROR; 1281 1282 ret = ldb_build_search_req(&req, ldb, ac, 1283 ac->dn, 1284 LDB_SCOPE_BASE, 1285 NULL, attrs, 1286 NULL, 1287 ac, samldb_sid_from_dn_callback, 1288 ac->req); 1289 if (ret != LDB_SUCCESS) 1290 return ret; 1291 1292 return ldb_next_request(ac->module, req); 1293} 1294 1295/* 1296 * samldb_user_dn_to_prim_group_rid (async) 1297 */ 1298 1299static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac); 1300 1301static int samldb_user_dn_to_prim_group_rid_callback(struct ldb_request *req, 1302 struct ldb_reply *ares) 1303{ 1304 struct ldb_context *ldb; 1305 struct samldb_ctx *ac; 1306 int ret; 1307 1308 ac = talloc_get_type(req->context, struct samldb_ctx); 1309 ldb = ldb_module_get_ctx(ac->module); 1310 1311 if (!ares) { 1312 ret = LDB_ERR_OPERATIONS_ERROR; 1313 goto done; 1314 } 1315 if (ares->error != LDB_SUCCESS) { 1316 return ldb_module_done(ac->req, ares->controls, 1317 ares->response, ares->error); 1318 } 1319 1320 switch (ares->type) { 1321 case LDB_REPLY_ENTRY: 1322 /* save entry */ 1323 if (ac->prim_group_rid != 0) { 1324 /* one too many! */ 1325 ldb_set_errstring(ldb, 1326 "Invalid number of results while searching " 1327 "for domain objects!"); 1328 ret = LDB_ERR_OPERATIONS_ERROR; 1329 break; 1330 } 1331 ac->prim_group_rid = samdb_result_uint(ares->message, 1332 "primaryGroupID", ~0); 1333 1334 talloc_free(ares); 1335 ret = LDB_SUCCESS; 1336 break; 1337 1338 case LDB_REPLY_REFERRAL: 1339 /* ignore */ 1340 talloc_free(ares); 1341 ret = LDB_SUCCESS; 1342 break; 1343 1344 case LDB_REPLY_DONE: 1345 talloc_free(ares); 1346 if (ac->prim_group_rid == 0) { 1347 ldb_asprintf_errstring(ldb, 1348 "Unable to get the primary group RID!\n"); 1349 ret = LDB_ERR_OPERATIONS_ERROR; 1350 break; 1351 } 1352 1353 /* found, go on */ 1354 ret = samldb_next_step(ac); 1355 break; 1356 } 1357 1358done: 1359 if (ret != LDB_SUCCESS) { 1360 return ldb_module_done(ac->req, NULL, NULL, ret); 1361 } 1362 1363 return LDB_SUCCESS; 1364} 1365 1366/* Locates the "primaryGroupID" attribute from a certain user specified as 1367 * "user_dn". Saves the result in "prim_group_rid". */ 1368static int samldb_user_dn_to_prim_group_rid(struct samldb_ctx *ac) 1369{ 1370 struct ldb_context *ldb; 1371 static const char * const attrs[] = { "primaryGroupID", NULL }; 1372 struct ldb_request *req; 1373 int ret; 1374 1375 ldb = ldb_module_get_ctx(ac->module); 1376 1377 if (ac->user_dn == NULL) 1378 return LDB_ERR_OPERATIONS_ERROR; 1379 1380 ret = ldb_build_search_req(&req, ldb, ac, 1381 ac->user_dn, 1382 LDB_SCOPE_BASE, 1383 NULL, attrs, 1384 NULL, 1385 ac, samldb_user_dn_to_prim_group_rid_callback, 1386 ac->req); 1387 if (ret != LDB_SUCCESS) 1388 return ret; 1389 1390 return ldb_next_request(ac->module, req); 1391} 1392 1393/* 1394 * samldb_prim_group_rid_to_users_cnt (async) 1395 */ 1396 1397static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx *ac); 1398 1399static int samldb_prim_group_rid_to_users_cnt_callback(struct ldb_request *req, 1400 struct ldb_reply *ares) 1401{ 1402 struct ldb_context *ldb; 1403 struct samldb_ctx *ac; 1404 int ret; 1405 1406 ac = talloc_get_type(req->context, struct samldb_ctx); 1407 ldb = ldb_module_get_ctx(ac->module); 1408 1409 if (!ares) { 1410 ret = LDB_ERR_OPERATIONS_ERROR; 1411 goto done; 1412 } 1413 if (ares->error != LDB_SUCCESS) { 1414 return ldb_module_done(ac->req, ares->controls, 1415 ares->response, ares->error); 1416 } 1417 1418 switch (ares->type) { 1419 case LDB_REPLY_ENTRY: 1420 /* save entry */ 1421 ++(ac->users_cnt); 1422 1423 talloc_free(ares); 1424 ret = LDB_SUCCESS; 1425 break; 1426 1427 case LDB_REPLY_REFERRAL: 1428 /* ignore */ 1429 talloc_free(ares); 1430 ret = LDB_SUCCESS; 1431 break; 1432 1433 case LDB_REPLY_DONE: 1434 talloc_free(ares); 1435 1436 /* found or not found, go on */ 1437 ret = samldb_next_step(ac); 1438 break; 1439 } 1440 1441done: 1442 if (ret != LDB_SUCCESS) { 1443 return ldb_module_done(ac->req, NULL, NULL, ret); 1444 } 1445 1446 return LDB_SUCCESS; 1447} 1448 1449/* Finds the amount of users which have the primary group "prim_group_rid" and 1450 * save the result in "users_cnt" */ 1451static int samldb_prim_group_rid_to_users_cnt(struct samldb_ctx *ac) 1452{ 1453 struct ldb_context *ldb; 1454 static const char * const attrs[] = { NULL }; 1455 struct ldb_request *req; 1456 char *filter; 1457 int ret; 1458 1459 ldb = ldb_module_get_ctx(ac->module); 1460 1461 if ((ac->prim_group_rid == 0) || (ac->users_cnt != 0)) 1462 return LDB_ERR_OPERATIONS_ERROR; 1463 1464 filter = talloc_asprintf(ac, "(&(primaryGroupID=%u)(objectclass=user))", 1465 ac->prim_group_rid); 1466 if (filter == NULL) 1467 return LDB_ERR_OPERATIONS_ERROR; 1468 1469 ret = ldb_build_search_req(&req, ldb, ac, 1470 ldb_get_default_basedn(ldb), 1471 LDB_SCOPE_SUBTREE, 1472 filter, attrs, 1473 NULL, 1474 ac, 1475 samldb_prim_group_rid_to_users_cnt_callback, 1476 ac->req); 1477 if (ret != LDB_SUCCESS) 1478 return ret; 1479 1480 return ldb_next_request(ac->module, req); 1481} 1482 1483/* 1484 * samldb_group_add_member (async) 1485 * samldb_group_del_member (async) 1486 */ 1487 1488static int samldb_group_add_del_member_callback(struct ldb_request *req, 1489 struct ldb_reply *ares) 1490{ 1491 struct ldb_context *ldb; 1492 struct samldb_ctx *ac; 1493 int ret; 1494 1495 ac = talloc_get_type(req->context, struct samldb_ctx); 1496 ldb = ldb_module_get_ctx(ac->module); 1497 1498 if (!ares) { 1499 ret = LDB_ERR_OPERATIONS_ERROR; 1500 goto done; 1501 } 1502 if (ares->error != LDB_SUCCESS) { 1503 if (ares->error == LDB_ERR_NO_SUCH_ATTRIBUTE) { 1504 /* On error "NO_SUCH_ATTRIBUTE" (delete of an invalid 1505 * "member" attribute) return "UNWILLING_TO_PERFORM" */ 1506 ares->error = LDB_ERR_UNWILLING_TO_PERFORM; 1507 } 1508 return ldb_module_done(ac->req, ares->controls, 1509 ares->response, ares->error); 1510 } 1511 if (ares->type != LDB_REPLY_DONE) { 1512 ldb_set_errstring(ldb, 1513 "Invalid reply type!\n"); 1514 ret = LDB_ERR_OPERATIONS_ERROR; 1515 goto done; 1516 } 1517 1518 ret = samldb_next_step(ac); 1519 1520done: 1521 if (ret != LDB_SUCCESS) { 1522 return ldb_module_done(ac->req, NULL, NULL, ret); 1523 } 1524 1525 return LDB_SUCCESS; 1526} 1527 1528/* Adds a member with DN "member_dn" to a group with DN "group_dn" */ 1529static int samldb_group_add_member(struct samldb_ctx *ac) 1530{ 1531 struct ldb_context *ldb; 1532 struct ldb_request *req; 1533 struct ldb_message *msg; 1534 int ret; 1535 1536 ldb = ldb_module_get_ctx(ac->module); 1537 1538 if ((ac->group_dn == NULL) || (ac->member_dn == NULL)) 1539 return LDB_ERR_OPERATIONS_ERROR; 1540 1541 msg = ldb_msg_new(ac); 1542 msg->dn = ac->group_dn; 1543 samdb_msg_add_addval(ldb, ac, msg, "member", 1544 ldb_dn_get_linearized(ac->member_dn)); 1545 1546 ret = ldb_build_mod_req(&req, ldb, ac, 1547 msg, NULL, 1548 ac, samldb_group_add_del_member_callback, 1549 ac->req); 1550 if (ret != LDB_SUCCESS) 1551 return ret; 1552 1553 return ldb_next_request(ac->module, req); 1554} 1555 1556/* Removes a member with DN "member_dn" from a group with DN "group_dn" */ 1557static int samldb_group_del_member(struct samldb_ctx *ac) 1558{ 1559 struct ldb_context *ldb; 1560 struct ldb_request *req; 1561 struct ldb_message *msg; 1562 int ret; 1563 1564 ldb = ldb_module_get_ctx(ac->module); 1565 1566 if ((ac->group_dn == NULL) || (ac->member_dn == NULL)) 1567 return LDB_ERR_OPERATIONS_ERROR; 1568 1569 msg = ldb_msg_new(ac); 1570 msg->dn = ac->group_dn; 1571 samdb_msg_add_delval(ldb, ac, msg, "member", 1572 ldb_dn_get_linearized(ac->member_dn)); 1573 1574 ret = ldb_build_mod_req(&req, ldb, ac, 1575 msg, NULL, 1576 ac, samldb_group_add_del_member_callback, 1577 ac->req); 1578 if (ret != LDB_SUCCESS) 1579 return ret; 1580 1581 return ldb_next_request(ac->module, req); 1582} 1583 1584 1585static int samldb_prim_group_change_1(struct samldb_ctx *ac) 1586{ 1587 struct ldb_context *ldb; 1588 uint32_t rid; 1589 1590 ldb = ldb_module_get_ctx(ac->module); 1591 1592 ac->user_dn = ac->msg->dn; 1593 1594 rid = samdb_result_uint(ac->msg, "primaryGroupID", ~0); 1595 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), rid); 1596 if (ac->sid == NULL) 1597 return LDB_ERR_OPERATIONS_ERROR; 1598 ac->res_dn = NULL; 1599 1600 ac->prim_group_rid = 0; 1601 1602 return samldb_next_step(ac); 1603} 1604 1605static int samldb_prim_group_change_2(struct samldb_ctx *ac) 1606{ 1607 struct ldb_context *ldb; 1608 1609 ldb = ldb_module_get_ctx(ac->module); 1610 1611 if (ac->res_dn != NULL) 1612 ac->new_prim_group_dn = ac->res_dn; 1613 else 1614 return LDB_ERR_UNWILLING_TO_PERFORM; 1615 1616 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), 1617 ac->prim_group_rid); 1618 if (ac->sid == NULL) 1619 return LDB_ERR_OPERATIONS_ERROR; 1620 ac->res_dn = NULL; 1621 1622 return samldb_next_step(ac); 1623} 1624 1625static int samldb_prim_group_change_4(struct samldb_ctx *ac); 1626static int samldb_prim_group_change_5(struct samldb_ctx *ac); 1627static int samldb_prim_group_change_6(struct samldb_ctx *ac); 1628 1629static int samldb_prim_group_change_3(struct samldb_ctx *ac) 1630{ 1631 int ret; 1632 1633 if (ac->res_dn != NULL) 1634 ac->old_prim_group_dn = ac->res_dn; 1635 else 1636 return LDB_ERR_UNWILLING_TO_PERFORM; 1637 1638 /* Only update when the primary group changed */ 1639 if (ldb_dn_compare(ac->old_prim_group_dn, ac->new_prim_group_dn) != 0) { 1640 ac->member_dn = ac->user_dn; 1641 /* Remove the "member" attribute of the actual (new) primary 1642 * group */ 1643 1644 ret = samldb_add_step(ac, samldb_prim_group_change_4); 1645 if (ret != LDB_SUCCESS) return ret; 1646 1647 ret = samldb_add_step(ac, samldb_group_del_member); 1648 if (ret != LDB_SUCCESS) return ret; 1649 1650 /* Add a "member" attribute for the previous primary group */ 1651 1652 ret = samldb_add_step(ac, samldb_prim_group_change_5); 1653 if (ret != LDB_SUCCESS) return ret; 1654 1655 ret = samldb_add_step(ac, samldb_group_add_member); 1656 if (ret != LDB_SUCCESS) return ret; 1657 } 1658 1659 ret = samldb_add_step(ac, samldb_prim_group_change_6); 1660 if (ret != LDB_SUCCESS) return ret; 1661 1662 return samldb_next_step(ac); 1663} 1664 1665static int samldb_prim_group_change_4(struct samldb_ctx *ac) 1666{ 1667 ac->group_dn = ac->new_prim_group_dn; 1668 1669 return samldb_next_step(ac); 1670} 1671 1672static int samldb_prim_group_change_5(struct samldb_ctx *ac) 1673{ 1674 ac->group_dn = ac->old_prim_group_dn; 1675 1676 return samldb_next_step(ac); 1677} 1678 1679static int samldb_prim_group_change_6(struct samldb_ctx *ac) 1680{ 1681 return ldb_next_request(ac->module, ac->req); 1682} 1683 1684static int samldb_prim_group_change(struct samldb_ctx *ac) 1685{ 1686 int ret; 1687 1688 /* Finds out the DN of the new primary group */ 1689 1690 ret = samldb_add_step(ac, samldb_prim_group_change_1); 1691 if (ret != LDB_SUCCESS) return ret; 1692 1693 ret = samldb_add_step(ac, samldb_dn_from_sid); 1694 if (ret != LDB_SUCCESS) return ret; 1695 1696 ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid); 1697 if (ret != LDB_SUCCESS) return ret; 1698 1699 /* Finds out the DN of the old primary group */ 1700 1701 ret = samldb_add_step(ac, samldb_prim_group_change_2); 1702 if (ret != LDB_SUCCESS) return ret; 1703 1704 ret = samldb_add_step(ac, samldb_dn_from_sid); 1705 if (ret != LDB_SUCCESS) return ret; 1706 1707 ret = samldb_add_step(ac, samldb_prim_group_change_3); 1708 if (ret != LDB_SUCCESS) return ret; 1709 1710 return samldb_first_step(ac); 1711} 1712 1713 1714static int samldb_member_check_1(struct samldb_ctx *ac) 1715{ 1716 struct ldb_context *ldb; 1717 struct ldb_message_element *el; 1718 1719 ldb = ldb_module_get_ctx(ac->module); 1720 1721 el = ldb_msg_find_element(ac->msg, "member"); 1722 1723 ac->user_dn = ldb_dn_from_ldb_val(ac, ldb, &el->values[ac->cnt]); 1724 if (!ldb_dn_validate(ac->user_dn)) 1725 return LDB_ERR_OPERATIONS_ERROR; 1726 ac->prim_group_rid = 0; 1727 1728 return samldb_next_step(ac); 1729} 1730 1731static int samldb_member_check_2(struct samldb_ctx *ac) 1732{ 1733 struct ldb_context *ldb; 1734 1735 ldb = ldb_module_get_ctx(ac->module); 1736 1737 ac->sid = dom_sid_add_rid(ac, samdb_domain_sid(ldb), 1738 ac->prim_group_rid); 1739 if (ac->sid == NULL) 1740 return LDB_ERR_OPERATIONS_ERROR; 1741 ac->res_dn = NULL; 1742 1743 return samldb_next_step(ac); 1744} 1745 1746static int samldb_member_check_3(struct samldb_ctx *ac) 1747{ 1748 if (ldb_dn_compare(ac->res_dn, ac->msg->dn) == 0) 1749 return LDB_ERR_ENTRY_ALREADY_EXISTS; 1750 1751 ++(ac->cnt); 1752 1753 return samldb_next_step(ac); 1754} 1755 1756static int samldb_member_check_4(struct samldb_ctx *ac) 1757{ 1758 return ldb_next_request(ac->module, ac->req); 1759} 1760 1761static int samldb_member_check(struct samldb_ctx *ac) 1762{ 1763 struct ldb_message_element *el; 1764 int i, ret; 1765 1766 el = ldb_msg_find_element(ac->msg, "member"); 1767 ac->cnt = 0; 1768 for (i = 0; i < el->num_values; i++) { 1769 /* Denies to add "member"s to groups which are primary ones 1770 * for them */ 1771 ret = samldb_add_step(ac, samldb_member_check_1); 1772 if (ret != LDB_SUCCESS) return ret; 1773 1774 ret = samldb_add_step(ac, samldb_user_dn_to_prim_group_rid); 1775 if (ret != LDB_SUCCESS) return ret; 1776 1777 ret = samldb_add_step(ac, samldb_member_check_2); 1778 if (ret != LDB_SUCCESS) return ret; 1779 1780 ret = samldb_add_step(ac, samldb_dn_from_sid); 1781 if (ret != LDB_SUCCESS) return ret; 1782 1783 ret = samldb_add_step(ac, samldb_member_check_3); 1784 if (ret != LDB_SUCCESS) return ret; 1785 } 1786 1787 ret = samldb_add_step(ac, samldb_member_check_4); 1788 if (ret != LDB_SUCCESS) return ret; 1789 1790 return samldb_first_step(ac); 1791} 1792 1793 1794static int samldb_prim_group_users_check_1(struct samldb_ctx *ac) 1795{ 1796 ac->dn = ac->req->op.del.dn; 1797 ac->res_sid = NULL; 1798 1799 return samldb_next_step(ac); 1800} 1801 1802static int samldb_prim_group_users_check_2(struct samldb_ctx *ac) 1803{ 1804 NTSTATUS status; 1805 uint32_t rid; 1806 1807 if (ac->res_sid == NULL) { 1808 /* No SID - therefore ok here */ 1809 return ldb_next_request(ac->module, ac->req); 1810 } 1811 status = dom_sid_split_rid(ac, ac->res_sid, NULL, &rid); 1812 if (!NT_STATUS_IS_OK(status)) 1813 return LDB_ERR_OPERATIONS_ERROR; 1814 1815 if (rid == 0) { 1816 /* Special object (security principal?) */ 1817 return ldb_next_request(ac->module, ac->req); 1818 } 1819 1820 ac->prim_group_rid = rid; 1821 ac->users_cnt = 0; 1822 1823 return samldb_next_step(ac); 1824} 1825 1826static int samldb_prim_group_users_check_3(struct samldb_ctx *ac) 1827{ 1828 if (ac->users_cnt > 0) 1829 return LDB_ERR_ENTRY_ALREADY_EXISTS; 1830 1831 return ldb_next_request(ac->module, ac->req); 1832} 1833 1834static int samldb_prim_group_users_check(struct samldb_ctx *ac) 1835{ 1836 int ret; 1837 1838 /* Finds out the SID/RID of the domain object */ 1839 1840 ret = samldb_add_step(ac, samldb_prim_group_users_check_1); 1841 if (ret != LDB_SUCCESS) return ret; 1842 1843 ret = samldb_add_step(ac, samldb_sid_from_dn); 1844 if (ret != LDB_SUCCESS) return ret; 1845 1846 /* Deny delete requests from groups which are primary ones */ 1847 1848 ret = samldb_add_step(ac, samldb_prim_group_users_check_2); 1849 if (ret != LDB_SUCCESS) return ret; 1850 1851 ret = samldb_add_step(ac, samldb_prim_group_rid_to_users_cnt); 1852 if (ret != LDB_SUCCESS) return ret; 1853 1854 ret = samldb_add_step(ac, samldb_prim_group_users_check_3); 1855 if (ret != LDB_SUCCESS) return ret; 1856 1857 return samldb_first_step(ac); 1858} 1859 1860 1861/* add */ 1862static int samldb_add(struct ldb_module *module, struct ldb_request *req) 1863{ 1864 struct ldb_context *ldb; 1865 struct samldb_ctx *ac; 1866 int ret; 1867 1868 ldb = ldb_module_get_ctx(module); 1869 ldb_debug(ldb, LDB_DEBUG_TRACE, "samldb_add_record\n"); 1870 1871 /* do not manipulate our control entries */ 1872 if (ldb_dn_is_special(req->op.add.message->dn)) { 1873 return ldb_next_request(module, req); 1874 } 1875 1876 ac = samldb_ctx_init(module, req); 1877 if (ac == NULL) { 1878 return LDB_ERR_OPERATIONS_ERROR; 1879 } 1880 1881 /* build the new msg */ 1882 ac->msg = ldb_msg_copy(ac, ac->req->op.add.message); 1883 if (!ac->msg) { 1884 talloc_free(ac); 1885 ldb_debug(ldb, LDB_DEBUG_FATAL, 1886 "samldb_add: ldb_msg_copy failed!\n"); 1887 return LDB_ERR_OPERATIONS_ERROR; 1888 } 1889 1890 if (samdb_find_attribute(ldb, ac->msg, 1891 "objectclass", "computer") != NULL) { 1892 1893 /* make sure the computer object also has the 'user' 1894 * objectclass so it will be handled by the next call */ 1895 ret = samdb_find_or_add_value(ldb, ac->msg, 1896 "objectclass", "user"); 1897 if (ret != LDB_SUCCESS) { 1898 talloc_free(ac); 1899 return ret; 1900 } 1901 } 1902 1903 if (samdb_find_attribute(ldb, ac->msg, 1904 "objectclass", "user") != NULL) { 1905 1906 ret = samldb_check_rdn(module, ac->req->op.add.message->dn); 1907 if (ret != LDB_SUCCESS) { 1908 talloc_free(ac); 1909 return ret; 1910 } 1911 1912 return samldb_fill_object(ac, "user"); 1913 } 1914 1915 if (samdb_find_attribute(ldb, ac->msg, 1916 "objectclass", "group") != NULL) { 1917 1918 ret = samldb_check_rdn(module, ac->req->op.add.message->dn); 1919 if (ret != LDB_SUCCESS) { 1920 talloc_free(ac); 1921 return ret; 1922 } 1923 1924 return samldb_fill_object(ac, "group"); 1925 } 1926 1927 /* perhaps a foreignSecurityPrincipal? */ 1928 if (samdb_find_attribute(ldb, ac->msg, 1929 "objectclass", 1930 "foreignSecurityPrincipal") != NULL) { 1931 1932 ret = samldb_check_rdn(module, ac->req->op.add.message->dn); 1933 if (ret != LDB_SUCCESS) { 1934 talloc_free(ac); 1935 return ret; 1936 } 1937 1938 return samldb_fill_foreignSecurityPrincipal_object(ac); 1939 } 1940 1941 talloc_free(ac); 1942 1943 /* nothing matched, go on */ 1944 return ldb_next_request(module, req); 1945} 1946 1947/* modify */ 1948static int samldb_modify(struct ldb_module *module, struct ldb_request *req) 1949{ 1950 struct ldb_context *ldb; 1951 struct ldb_message *msg; 1952 struct ldb_message_element *el, *el2; 1953 int ret; 1954 uint32_t account_type; 1955 1956 if (ldb_dn_is_special(req->op.mod.message->dn)) { 1957 /* do not manipulate our control entries */ 1958 return ldb_next_request(module, req); 1959 } 1960 1961 ldb = ldb_module_get_ctx(module); 1962 1963 if (ldb_msg_find_element(req->op.mod.message, "sAMAccountType") != NULL) { 1964 ldb_asprintf_errstring(ldb, 1965 "sAMAccountType must not be specified!"); 1966 return LDB_ERR_UNWILLING_TO_PERFORM; 1967 } 1968 1969 /* TODO: do not modify original request, create a new one */ 1970 1971 el = ldb_msg_find_element(req->op.mod.message, "groupType"); 1972 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) { 1973 uint32_t group_type; 1974 1975 req->op.mod.message = msg = ldb_msg_copy_shallow(req, 1976 req->op.mod.message); 1977 1978 group_type = strtoul((const char *)el->values[0].data, NULL, 0); 1979 account_type = ds_gtype2atype(group_type); 1980 ret = samdb_msg_add_uint(ldb, msg, msg, 1981 "sAMAccountType", 1982 account_type); 1983 if (ret != LDB_SUCCESS) { 1984 return ret; 1985 } 1986 el2 = ldb_msg_find_element(msg, "sAMAccountType"); 1987 el2->flags = LDB_FLAG_MOD_REPLACE; 1988 } 1989 1990 el = ldb_msg_find_element(req->op.mod.message, "userAccountControl"); 1991 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) { 1992 uint32_t user_account_control; 1993 1994 req->op.mod.message = msg = ldb_msg_copy_shallow(req, 1995 req->op.mod.message); 1996 1997 user_account_control = strtoul((const char *)el->values[0].data, 1998 NULL, 0); 1999 account_type = ds_uf2atype(user_account_control); 2000 ret = samdb_msg_add_uint(ldb, msg, msg, 2001 "sAMAccountType", 2002 account_type); 2003 if (ret != LDB_SUCCESS) { 2004 return ret; 2005 } 2006 el2 = ldb_msg_find_element(msg, "sAMAccountType"); 2007 el2->flags = LDB_FLAG_MOD_REPLACE; 2008 2009 if (user_account_control & UF_SERVER_TRUST_ACCOUNT) { 2010 ret = samdb_msg_add_string(ldb, msg, msg, 2011 "isCriticalSystemObject", "TRUE"); 2012 if (ret != LDB_SUCCESS) { 2013 return ret; 2014 } 2015 el2 = ldb_msg_find_element(msg, "isCriticalSystemObject"); 2016 el2->flags = LDB_FLAG_MOD_REPLACE; 2017 } 2018 } 2019 2020 el = ldb_msg_find_element(req->op.mod.message, "primaryGroupID"); 2021 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) { 2022 struct samldb_ctx *ac; 2023 2024 ac = samldb_ctx_init(module, req); 2025 if (ac == NULL) 2026 return LDB_ERR_OPERATIONS_ERROR; 2027 2028 req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req, 2029 req->op.mod.message); 2030 2031 return samldb_prim_group_change(ac); 2032 } 2033 2034 el = ldb_msg_find_element(req->op.mod.message, "member"); 2035 if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && el->num_values == 1) { 2036 struct samldb_ctx *ac; 2037 2038 ac = samldb_ctx_init(module, req); 2039 if (ac == NULL) 2040 return LDB_ERR_OPERATIONS_ERROR; 2041 2042 req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req, 2043 req->op.mod.message); 2044 2045 return samldb_member_check(ac); 2046 } 2047 2048 /* nothing matched, go on */ 2049 return ldb_next_request(module, req); 2050} 2051 2052/* delete */ 2053static int samldb_delete(struct ldb_module *module, struct ldb_request *req) 2054{ 2055 struct samldb_ctx *ac; 2056 2057 if (ldb_dn_is_special(req->op.del.dn)) { 2058 /* do not manipulate our control entries */ 2059 return ldb_next_request(module, req); 2060 } 2061 2062 ac = samldb_ctx_init(module, req); 2063 if (ac == NULL) 2064 return LDB_ERR_OPERATIONS_ERROR; 2065 2066 return samldb_prim_group_users_check(ac); 2067} 2068 2069 2070static int samldb_init(struct ldb_module *module) 2071{ 2072 return ldb_next_init(module); 2073} 2074 2075_PUBLIC_ const struct ldb_module_ops ldb_samldb_module_ops = { 2076 .name = "samldb", 2077 .init_context = samldb_init, 2078 .add = samldb_add, 2079 .modify = samldb_modify, 2080 .del = samldb_delete 2081}; 2082