Changeset 988 for vendor/current/source4/dsdb/common
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/dsdb/common
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/dsdb/common/dsdb_access.c
r740 r988 65 65 66 66 sd_element = ldb_msg_find_element(acl_res, "nTSecurityDescriptor"); 67 if ( !sd_element) {68 *sd = NULL;69 return LDB_SUCCESS;67 if (sd_element == NULL) { 68 return ldb_error(ldb, LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS, 69 "nTSecurityDescriptor is missing"); 70 70 } 71 71 *sd = talloc(mem_ctx, struct security_descriptor); … … 94 94 struct dom_sid *sid = NULL; 95 95 struct object_tree *root = NULL; 96 struct object_tree *new_node = NULL;97 96 NTSTATUS status; 98 97 uint32_t access_granted; … … 103 102 return ldb_operr(ldb); 104 103 } 105 /* Theoretically we pass the check if the object has no sd */ 106 if (!sd) { 107 return LDB_SUCCESS; 108 } 104 109 105 sid = samdb_result_dom_sid(mem_ctx, acl_res->msgs[0], "objectSid"); 110 106 if (guid) { 111 if (!insert_in_object_tree(mem_ctx, guid, access_mask, &root,112 & new_node)) {107 if (!insert_in_object_tree(mem_ctx, guid, access_mask, NULL, 108 &root)) { 113 109 return ldb_operr(ldb); 114 110 } … … 125 121 true, 126 122 10); 123 ldb_asprintf_errstring(ldb, 124 "dsdb_access: Access check failed on %s", 125 ldb_dn_get_linearized(dn)); 127 126 return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; 128 127 } … … 150 149 NULL 151 150 }; 152 NTSTATUS status = GUID_from_string(ext_right, &guid); 153 if (!NT_STATUS_IS_OK(status)) { 154 return LDB_ERR_OPERATIONS_ERROR; 151 152 if (ext_right != NULL) { 153 NTSTATUS status = GUID_from_string(ext_right, &guid); 154 if (!NT_STATUS_IS_OK(status)) { 155 return LDB_ERR_OPERATIONS_ERROR; 156 } 155 157 } 156 158 157 ret = dsdb_search_dn(ldb, mem_ctx, &acl_res, dn, acl_attrs, DSDB_SEARCH_SHOW_DELETED); 159 /* 160 * We need AS_SYSTEM in order to get the nTSecurityDescriptor attribute. 161 * Also the result of this search not controlled by the client 162 * nor is the result exposed to the client. 163 */ 164 ret = dsdb_search_dn(ldb, mem_ctx, &acl_res, dn, acl_attrs, 165 DSDB_FLAG_AS_SYSTEM | DSDB_SEARCH_SHOW_RECYCLED); 158 166 if (ret != LDB_SUCCESS) { 159 167 DEBUG(10,("access_check: failed to find object %s\n", ldb_dn_get_linearized(dn))); … … 166 174 dn, 167 175 access_mask, 168 &guid);176 ext_right ? &guid : NULL); 169 177 } 170 178 -
vendor/current/source4/dsdb/common/dsdb_dn.c
r740 r988 77 77 struct dsdb_dn *dsdb_dn; 78 78 struct ldb_dn *dn; 79 const char *data;80 79 size_t len; 81 80 TALLOC_CTX *tmp_ctx; … … 88 87 89 88 enum dsdb_dn_format dn_format = dsdb_dn_oid_to_format(dn_oid); 89 90 if (dn_blob == NULL || dn_blob->data == NULL || dn_blob->length == 0) { 91 return NULL; 92 } 93 90 94 switch (dn_format) { 91 95 case DSDB_INVALID_DN: … … 114 118 } 115 119 116 if (dn_blob && dn_blob->data 117 && (strlen((const char*)dn_blob->data) != dn_blob->length)) { 120 if (strlen((const char*)dn_blob->data) != dn_blob->length) { 118 121 /* The RDN must not contain a character with value 0x0 */ 119 122 return NULL; 120 123 } 121 122 if (!dn_blob->data || dn_blob->length == 0) { 123 return NULL; 124 } 125 124 126 125 tmp_ctx = talloc_new(mem_ctx); 127 126 if (tmp_ctx == NULL) { 128 127 return NULL; 129 128 } 130 131 data = (const char *)dn_blob->data;132 129 133 130 len = dn_blob->length - 2; … … 215 212 dsdb_dn = dsdb_dn_construct(mem_ctx, dn, bval, dn_oid); 216 213 214 talloc_free(tmp_ctx); 217 215 return dsdb_dn; 218 216 -
vendor/current/source4/dsdb/common/dsdb_dn.h
r740 r988 1 enum dsdb_dn_format {2 DSDB_NORMAL_DN,3 DSDB_BINARY_DN,4 DSDB_STRING_DN,5 DSDB_INVALID_DN6 };7 8 1 struct dsdb_dn { 9 2 struct ldb_dn *dn; … … 16 9 #define DSDB_SYNTAX_STRING_DN "1.2.840.113556.1.4.904" 17 10 #define DSDB_SYNTAX_OR_NAME "1.2.840.113556.1.4.1221" 11 #define DSDB_SYNTAX_ACCESS_POINT "1.3.6.1.4.1.1466.115.121.1.2" 18 12 19 13 -
vendor/current/source4/dsdb/common/tests/dsdb_dn.c
r740 r988 78 78 "compare of binary+dn an dn should have failed"); 79 79 80 /* Test compare (false) with different binary prefix */ 81 dn1 = data_blob_string_const("B:6:abcdef:dc=samba,dc=org"); 82 dn2 = data_blob_string_const("B:4:abcd:dc=samba,dc=org"); 83 torture_assert(torture, 84 syntax->comparison_fn(ldb, mem_ctx, &dn1, &dn2) != 0, 85 "compare of binary+dn an dn should have failed"); 86 80 87 /* Test DN+String behaviour */ 81 88 torture_assert(torture, syntax = ldb_samba_syntax_by_name(ldb, DSDB_SYNTAX_STRING_DN), … … 108 115 "compare of string+dn an dn should have failed"); 109 116 117 /* Test compare (false) with different string prefix */ 118 dn1 = data_blob_string_const("S:6:abcdef:dc=samba,dc=org"); 119 dn2 = data_blob_string_const("S:6:abcXYZ:dc=samba,dc=org"); 120 torture_assert(torture, 121 syntax->comparison_fn(ldb, mem_ctx, &dn1, &dn2) != 0, 122 "compare of string+dn an dn should have failed"); 123 110 124 talloc_free(mem_ctx); 111 125 return true; -
vendor/current/source4/dsdb/common/util.c
r740 r988 361 361 return NULL; 362 362 } 363 ok = sid_ blob_parse(*v, sid);363 ok = sid_parse(v->data, v->length, sid); 364 364 if (!ok) { 365 365 talloc_free(sid); … … 506 506 maxPwdAge = samdb_search_int64(sam_ldb, mem_ctx, 0, domain_dn, 507 507 "maxPwdAge", NULL); 508 if (maxPwdAge == 0 ) {508 if (maxPwdAge == 0 || maxPwdAge == -0x8000000000000000ULL) { 509 509 return 0x7FFFFFFFFFFFFFFFULL; 510 510 } else { … … 559 559 } 560 560 561 NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct ldb_message *msg, 562 struct samr_Password **lm_pwd, struct samr_Password **nt_pwd) 561 NTSTATUS samdb_result_passwords_from_history(TALLOC_CTX *mem_ctx, 562 struct loadparm_context *lp_ctx, 563 struct ldb_message *msg, 564 unsigned int idx, 565 struct samr_Password **lm_pwd, 566 struct samr_Password **nt_pwd) 563 567 { 564 568 struct samr_Password *lmPwdHash, *ntPwdHash; 569 570 if (nt_pwd) { 571 unsigned int num_nt; 572 num_nt = samdb_result_hashes(mem_ctx, msg, "ntPwdHistory", &ntPwdHash); 573 if (num_nt <= idx) { 574 *nt_pwd = NULL; 575 } else { 576 *nt_pwd = &ntPwdHash[idx]; 577 } 578 } 579 if (lm_pwd) { 580 /* Ensure that if we have turned off LM 581 * authentication, that we never use the LM hash, even 582 * if we store it */ 583 if (lpcfg_lanman_auth(lp_ctx)) { 584 unsigned int num_lm; 585 num_lm = samdb_result_hashes(mem_ctx, msg, "lmPwdHistory", &lmPwdHash); 586 if (num_lm <= idx) { 587 *lm_pwd = NULL; 588 } else { 589 *lm_pwd = &lmPwdHash[idx]; 590 } 591 } else { 592 *lm_pwd = NULL; 593 } 594 } 595 return NT_STATUS_OK; 596 } 597 598 NTSTATUS samdb_result_passwords_no_lockout(TALLOC_CTX *mem_ctx, 599 struct loadparm_context *lp_ctx, 600 struct ldb_message *msg, 601 struct samr_Password **lm_pwd, 602 struct samr_Password **nt_pwd) 603 { 604 struct samr_Password *lmPwdHash, *ntPwdHash; 605 565 606 if (nt_pwd) { 566 607 unsigned int num_nt; … … 595 636 } 596 637 638 NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, 639 struct loadparm_context *lp_ctx, 640 struct ldb_message *msg, 641 struct samr_Password **lm_pwd, 642 struct samr_Password **nt_pwd) 643 { 644 uint16_t acct_flags; 645 646 acct_flags = samdb_result_acct_flags(msg, 647 "msDS-User-Account-Control-Computed"); 648 /* Quit if the account was locked out. */ 649 if (acct_flags & ACB_AUTOLOCK) { 650 DEBUG(3,("samdb_result_passwords: Account for user %s was locked out.\n", 651 ldb_dn_get_linearized(msg->dn))); 652 return NT_STATUS_ACCOUNT_LOCKED_OUT; 653 } 654 655 return samdb_result_passwords_no_lockout(mem_ctx, lp_ctx, msg, 656 lm_pwd, nt_pwd); 657 } 658 597 659 /* 598 660 pull a samr_LogonHours structutre from a result set. … … 626 688 pull a set of account_flags from a result set. 627 689 628 This requires that the attributes: 629 pwdLastSet 630 userAccountControl 631 be included in 'msg' 690 Naturally, this requires that userAccountControl and 691 (if not null) the attributes 'attr' be already 692 included in msg 632 693 */ 633 uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, 634 struct ldb_message *msg, struct ldb_dn *domain_dn) 694 uint32_t samdb_result_acct_flags(struct ldb_message *msg, const char *attr) 635 695 { 636 696 uint32_t userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0); 697 uint32_t attr_flags = 0; 637 698 uint32_t acct_flags = ds_uf2acb(userAccountControl); 638 NTTIME must_change_time; 639 NTTIME now; 640 641 must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx, 642 domain_dn, msg); 643 644 /* Test account expire time */ 645 unix_to_nt_time(&now, time(NULL)); 646 /* check for expired password */ 647 if (must_change_time < now) { 648 acct_flags |= ACB_PW_EXPIRED; 649 } 699 if (attr) { 700 attr_flags = ldb_msg_find_attr_as_uint(msg, attr, UF_ACCOUNTDISABLE); 701 if (attr_flags == UF_ACCOUNTDISABLE) { 702 DEBUG(0, ("Attribute %s not found, disabling account %s!\n", attr, 703 ldb_dn_get_linearized(msg->dn))); 704 } 705 acct_flags |= ds_uf2acb(attr_flags); 706 } 707 650 708 return acct_flags; 651 709 } 652 710 653 struct lsa_BinaryString samdb_result_parameters(TALLOC_CTX *mem_ctx, 654 struct ldb_message *msg, 655 const char *attr) 656 { 657 struct lsa_BinaryString s; 711 NTSTATUS samdb_result_parameters(TALLOC_CTX *mem_ctx, 712 struct ldb_message *msg, 713 const char *attr, 714 struct lsa_BinaryString *s) 715 { 716 int i; 658 717 const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr); 659 718 660 ZERO_STRUCT (s);719 ZERO_STRUCTP(s); 661 720 662 721 if (!val) { 663 return s; 664 } 665 666 s.array = talloc_array(mem_ctx, uint16_t, val->length/2); 667 if (!s.array) { 668 return s; 669 } 670 s.length = s.size = val->length; 671 memcpy(s.array, val->data, val->length); 672 673 return s; 722 return NT_STATUS_OK; 723 } 724 725 if ((val->length % 2) != 0) { 726 /* 727 * If the on-disk data is not even in length, we know 728 * it is corrupt, and can not be safely pushed. We 729 * would either truncate, send either a un-initilaised 730 * byte or send a forced zero byte 731 */ 732 return NT_STATUS_INTERNAL_DB_CORRUPTION; 733 } 734 735 s->array = talloc_array(mem_ctx, uint16_t, val->length/2); 736 if (!s->array) { 737 return NT_STATUS_NO_MEMORY; 738 } 739 s->length = s->size = val->length; 740 741 /* The on-disk format is the 'network' format, being UTF16LE (sort of) */ 742 for (i = 0; i < s->length / 2; i++) { 743 s->array[i] = SVAL(val->data, i * 2); 744 } 745 746 return NT_STATUS_OK; 674 747 } 675 748 … … 702 775 int samdb_find_or_add_attribute(struct ldb_context *ldb, struct ldb_message *msg, const char *name, const char *set_value) 703 776 { 777 int ret; 704 778 struct ldb_message_element *el; 705 779 … … 709 783 } 710 784 711 return ldb_msg_add_string(msg, name, set_value); 785 ret = ldb_msg_add_string(msg, name, set_value); 786 if (ret != LDB_SUCCESS) { 787 return ret; 788 } 789 msg->elements[msg->num_elements - 1].flags = LDB_FLAG_MOD_ADD; 790 return LDB_SUCCESS; 712 791 } 713 792 … … 716 795 */ 717 796 int samdb_msg_add_dom_sid(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, 718 const char *attr_name,struct dom_sid *sid)797 const char *attr_name, const struct dom_sid *sid) 719 798 { 720 799 struct ldb_val v; … … 979 1058 const char *attr_name, struct lsa_BinaryString *parameters) 980 1059 { 1060 int i; 981 1061 struct ldb_val val; 1062 if ((parameters->length % 2) != 0) { 1063 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 1064 } 1065 1066 val.data = talloc_array(mem_ctx, uint8_t, parameters->length); 1067 if (val.data == NULL) { 1068 return LDB_ERR_OPERATIONS_ERROR; 1069 } 982 1070 val.length = parameters->length; 983 val.data = (uint8_t *)parameters->array; 984 return ldb_msg_add_value(msg, attr_name, &val, NULL); 985 } 986 987 /* 988 sets a general value element to a message 989 */ 990 int samdb_msg_set_value(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, 991 const char *attr_name, const struct ldb_val *val) 992 { 993 struct ldb_message_element *el; 994 995 el = ldb_msg_find_element(msg, attr_name); 996 if (el) { 997 el->num_values = 0; 998 } 999 return ldb_msg_add_value(msg, attr_name, val, NULL); 1000 } 1001 1002 /* 1003 set a string element in a message 1004 */ 1005 int samdb_msg_set_string(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, 1006 const char *attr_name, const char *str) 1007 { 1008 struct ldb_message_element *el; 1009 1010 el = ldb_msg_find_element(msg, attr_name); 1011 if (el) { 1012 el->num_values = 0; 1013 } 1014 return ldb_msg_add_string(msg, attr_name, str); 1015 } 1016 1017 /* 1018 * sets a signed integer in a message 1019 */ 1020 int samdb_msg_set_int(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, 1021 struct ldb_message *msg, const char *attr_name, int v) 1022 { 1023 struct ldb_message_element *el; 1024 1025 el = ldb_msg_find_element(msg, attr_name); 1026 if (el) { 1027 el->num_values = 0; 1028 } 1029 return samdb_msg_add_int(sam_ldb, mem_ctx, msg, attr_name, v); 1071 for (i = 0; i < parameters->length / 2; i++) { 1072 /* 1073 * The on-disk format needs to be in the 'network' 1074 * format, parmeters->array is a uint16_t array of 1075 * length parameters->length / 2 1076 */ 1077 SSVAL(val.data, i * 2, parameters->array[i]); 1078 } 1079 return ldb_msg_add_steal_value(msg, attr_name, &val); 1030 1080 } 1031 1081 … … 1058 1108 * Handle ldb_request in transaction 1059 1109 */ 1060 staticint dsdb_autotransaction_request(struct ldb_context *sam_ldb,1061 1110 int dsdb_autotransaction_request(struct ldb_context *sam_ldb, 1111 struct ldb_request *req) 1062 1112 { 1063 1113 int ret; … … 1253 1303 struct ldb_dn *ntds_settings_dn_old; 1254 1304 1255 /* see if we have a cached copy*/1305 /* see if we have a forced copy from provision */ 1256 1306 ntds_settings_dn_old = talloc_get_type(ldb_get_opaque(ldb, 1257 " cache.ntds_settings_dn"), struct ldb_dn);1307 "forced.ntds_settings_dn"), struct ldb_dn); 1258 1308 1259 1309 tmp_ctx = talloc_new(ldb); … … 1267 1317 } 1268 1318 1269 /* cache the domain_sid in the ldb*/1270 if (ldb_set_opaque(ldb, " cache.ntds_settings_dn", ntds_settings_dn_new) != LDB_SUCCESS) {1319 /* set the DN in the ldb to avoid lookups during provision */ 1320 if (ldb_set_opaque(ldb, "forced.ntds_settings_dn", ntds_settings_dn_new) != LDB_SUCCESS) { 1271 1321 goto failed; 1272 1322 } … … 1287 1337 work out the ntds settings dn for the current open ldb 1288 1338 */ 1289 struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb )1339 struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx) 1290 1340 { 1291 1341 TALLOC_CTX *tmp_ctx; … … 1296 1346 1297 1347 /* see if we have a cached copy */ 1298 settings_dn = (struct ldb_dn *)ldb_get_opaque(ldb, " cache.ntds_settings_dn");1348 settings_dn = (struct ldb_dn *)ldb_get_opaque(ldb, "forced.ntds_settings_dn"); 1299 1349 if (settings_dn) { 1300 return settings_dn;1301 } 1302 1303 tmp_ctx = talloc_new( ldb);1350 return ldb_dn_copy(mem_ctx, settings_dn); 1351 } 1352 1353 tmp_ctx = talloc_new(mem_ctx); 1304 1354 if (tmp_ctx == NULL) { 1305 1355 goto failed; … … 1307 1357 1308 1358 ret = ldb_search(ldb, tmp_ctx, &root_res, ldb_dn_new(tmp_ctx, ldb, ""), LDB_SCOPE_BASE, root_attrs, NULL); 1309 if (ret ) {1359 if (ret != LDB_SUCCESS) { 1310 1360 DEBUG(1,("Searching for dsServiceName in rootDSE failed: %s\n", 1311 1361 ldb_errstring(ldb))); … … 1319 1369 settings_dn = ldb_msg_find_attr_as_dn(ldb, tmp_ctx, root_res->msgs[0], "dsServiceName"); 1320 1370 1321 /* cache the domain_sid in the ldb */ 1322 if (ldb_set_opaque(ldb, "cache.ntds_settings_dn", settings_dn) != LDB_SUCCESS) { 1323 goto failed; 1324 } 1325 1326 talloc_steal(ldb, settings_dn); 1371 /* note that we do not cache the DN here, as that would mean 1372 * we could not handle server renames at runtime. Only 1373 * provision sets up forced.ntds_settings_dn */ 1374 1375 talloc_steal(mem_ctx, settings_dn); 1327 1376 talloc_free(tmp_ctx); 1328 1377 … … 1349 1398 invocation_id = (struct GUID *)ldb_get_opaque(ldb, "cache.invocation_id"); 1350 1399 if (invocation_id) { 1400 SMB_ASSERT(!GUID_all_zero(invocation_id)); 1351 1401 return invocation_id; 1352 1402 } … … 1357 1407 } 1358 1408 1359 ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb ), LDB_SCOPE_BASE, attrs, NULL);1409 ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL); 1360 1410 if (ret) { 1361 1411 goto failed; … … 1372 1422 1373 1423 *invocation_id = samdb_result_guid(res->msgs[0], "invocationId"); 1424 if (GUID_all_zero(invocation_id)) { 1425 if (ldb_msg_find_ldb_val(res->msgs[0], "invocationId")) { 1426 DEBUG(0, ("Failed to find our own NTDS Settings invocationId in the ldb!\n")); 1427 } else { 1428 DEBUG(0, ("Failed to find parse own NTDS Settings invocationId from the ldb!\n")); 1429 } 1430 goto failed; 1431 } 1374 1432 1375 1433 /* cache the domain_sid in the ldb */ … … 1409 1467 } 1410 1468 1469 SMB_ASSERT(!GUID_all_zero(invocation_id_in)); 1411 1470 *invocation_id_new = *invocation_id_in; 1412 1471 … … 1450 1509 } 1451 1510 1452 ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb ), LDB_SCOPE_BASE, attrs, NULL);1511 ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL); 1453 1512 if (ret) { 1454 1513 goto failed; … … 1525 1584 struct ldb_dn *samdb_server_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx) 1526 1585 { 1527 return ldb_dn_get_parent(mem_ctx, samdb_ntds_settings_dn(ldb)); 1586 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 1587 struct ldb_dn *dn; 1588 if (!tmp_ctx) { 1589 return NULL; 1590 } 1591 dn = ldb_dn_get_parent(mem_ctx, samdb_ntds_settings_dn(ldb, tmp_ctx)); 1592 talloc_free(tmp_ctx); 1593 return dn; 1594 1528 1595 } 1529 1596 … … 1627 1694 attrs[1] = NULL; 1628 1695 1629 ret = dsdb_search(ldb, mem_ctx, &res, base, LDB_SCOPE_BASE, attrs, DSDB_SEARCH_ONE_ONLY, NULL); 1630 if (ret != LDB_SUCCESS) { 1696 ret = dsdb_search(ldb, mem_ctx, &res, base, LDB_SCOPE_BASE, attrs, DSDB_SEARCH_ONE_ONLY|DSDB_SEARCH_SHOW_EXTENDED_DN, NULL); 1697 if (ret != LDB_SUCCESS) { 1698 ldb_asprintf_errstring(ldb, "Cannot find DN %s to get attribute %s for reference dn: %s", 1699 ldb_dn_get_linearized(base), attribute, ldb_errstring(ldb)); 1631 1700 return ret; 1632 1701 } … … 1647 1716 talloc_free(res); 1648 1717 return LDB_SUCCESS; 1718 } 1719 1720 /* 1721 find if a DN (must have GUID component!) is our ntdsDsa 1722 */ 1723 int samdb_dn_is_our_ntdsa(struct ldb_context *ldb, struct ldb_dn *dn, bool *is_ntdsa) 1724 { 1725 NTSTATUS status; 1726 struct GUID dn_guid; 1727 const struct GUID *our_ntds_guid; 1728 status = dsdb_get_extended_dn_guid(dn, &dn_guid, "GUID"); 1729 if (!NT_STATUS_IS_OK(status)) { 1730 return LDB_ERR_OPERATIONS_ERROR; 1731 } 1732 1733 our_ntds_guid = samdb_ntds_objectGUID(ldb); 1734 if (!our_ntds_guid) { 1735 DEBUG(0, ("Failed to find our NTDS Settings GUID for comparison with %s - %s\n", ldb_dn_get_linearized(dn), ldb_errstring(ldb))); 1736 return LDB_ERR_OPERATIONS_ERROR; 1737 } 1738 1739 *is_ntdsa = GUID_equal(&dn_guid, our_ntds_guid); 1740 return LDB_SUCCESS; 1741 } 1742 1743 /* 1744 find a 'reference' DN that points at another object and indicate if it is our ntdsDsa 1745 */ 1746 int samdb_reference_dn_is_our_ntdsa(struct ldb_context *ldb, struct ldb_dn *base, 1747 const char *attribute, bool *is_ntdsa) 1748 { 1749 int ret; 1750 struct ldb_dn *referenced_dn; 1751 TALLOC_CTX *tmp_ctx = talloc_new(ldb); 1752 if (tmp_ctx == NULL) { 1753 return LDB_ERR_OPERATIONS_ERROR; 1754 } 1755 ret = samdb_reference_dn(ldb, tmp_ctx, base, attribute, &referenced_dn); 1756 if (ret != LDB_SUCCESS) { 1757 DEBUG(0, ("Failed to find object %s for attribute %s - %s\n", ldb_dn_get_linearized(base), attribute, ldb_errstring(ldb))); 1758 return ret; 1759 } 1760 1761 ret = samdb_dn_is_our_ntdsa(ldb, referenced_dn, is_ntdsa); 1762 1763 talloc_free(tmp_ctx); 1764 return ret; 1649 1765 } 1650 1766 … … 1763 1879 allow_list[0] = l_subnet_name; 1764 1880 1765 if ( allow_access(mem_ctx, NULL, allow_list, "", ip_address)) {1881 if (socket_allow_access(mem_ctx, NULL, allow_list, "", ip_address)) { 1766 1882 sites_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, 1767 1883 res->msgs[i], … … 1815 1931 bool samdb_is_pdc(struct ldb_context *ldb) 1816 1932 { 1817 const char *dom_attrs[] = { "fSMORoleOwner", NULL };1818 1933 int ret; 1819 struct ldb_result *dom_res;1820 TALLOC_CTX *tmp_ctx;1821 1934 bool is_pdc; 1822 struct ldb_dn *pdc; 1823 1824 tmp_ctx = talloc_new(ldb); 1825 if (tmp_ctx == NULL) { 1826 DEBUG(1, ("talloc_new failed in samdb_is_pdc")); 1827 return false; 1828 } 1829 1830 ret = ldb_search(ldb, tmp_ctx, &dom_res, ldb_get_default_basedn(ldb), LDB_SCOPE_BASE, dom_attrs, NULL); 1831 if (ret != LDB_SUCCESS) { 1832 DEBUG(1,("Searching for fSMORoleOwner in %s failed: %s\n", 1935 1936 ret = samdb_reference_dn_is_our_ntdsa(ldb, ldb_get_default_basedn(ldb), "fsmoRoleOwner", 1937 &is_pdc); 1938 if (ret != LDB_SUCCESS) { 1939 DEBUG(1,("Failed to find if we are the PDC for this ldb: Searching for fSMORoleOwner in %s failed: %s\n", 1833 1940 ldb_dn_get_linearized(ldb_get_default_basedn(ldb)), 1834 1941 ldb_errstring(ldb))); 1835 goto failed; 1836 } 1837 if (dom_res->count != 1) { 1838 goto failed; 1839 } 1840 1841 pdc = ldb_msg_find_attr_as_dn(ldb, tmp_ctx, dom_res->msgs[0], "fSMORoleOwner"); 1842 1843 if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), pdc) == 0) { 1844 is_pdc = true; 1845 } else { 1846 is_pdc = false; 1847 } 1848 1849 talloc_free(tmp_ctx); 1942 return false; 1943 } 1850 1944 1851 1945 return is_pdc; 1852 1853 failed:1854 DEBUG(1,("Failed to find if we are the PDC for this ldb\n"));1855 talloc_free(tmp_ctx);1856 return false;1857 1946 } 1858 1947 … … 1862 1951 bool samdb_is_gc(struct ldb_context *ldb) 1863 1952 { 1864 const char *attrs[] = { "options", NULL };1865 1953 uint32_t options; 1866 int ret; 1867 struct ldb_result *res; 1868 TALLOC_CTX *tmp_ctx; 1869 1870 tmp_ctx = talloc_new(ldb); 1871 if (tmp_ctx == NULL) { 1872 DEBUG(1, ("talloc_new failed in samdb_is_pdc")); 1954 if (samdb_ntds_options(ldb, &options) != LDB_SUCCESS) { 1873 1955 return false; 1874 1956 } 1875 1876 /* Query cn=ntds settings,.... */ 1877 ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL); 1878 if (ret != LDB_SUCCESS) { 1879 talloc_free(tmp_ctx); 1880 return false; 1881 } 1882 if (res->count != 1) { 1883 talloc_free(tmp_ctx); 1884 return false; 1885 } 1886 1887 options = ldb_msg_find_attr_as_uint(res->msgs[0], "options", 0); 1888 talloc_free(tmp_ctx); 1889 1890 /* if options attribute has the 0x00000001 flag set, then enable the global catlog */ 1891 if (options & DS_NTDSDSA_OPT_IS_GC) { 1892 return true; 1893 } 1894 return false; 1957 return (options & DS_NTDSDSA_OPT_IS_GC) != 0; 1895 1958 } 1896 1959 … … 1949 2012 * Result codes from "enum samr_ValidationStatus" (consider "samr.idl") 1950 2013 */ 1951 enum samr_ValidationStatus samdb_check_password(const DATA_BLOB * password,2014 enum samr_ValidationStatus samdb_check_password(const DATA_BLOB *utf8_blob, 1952 2015 const uint32_t pwdProperties, 1953 2016 const uint32_t minPwdLength) 1954 2017 { 2018 const char *utf8_pw = (const char *)utf8_blob->data; 2019 size_t utf8_len = strlen_m(utf8_pw); 2020 1955 2021 /* checks if the "minPwdLength" property is satisfied */ 1956 if (minPwdLength > password->length)2022 if (minPwdLength > utf8_len) { 1957 2023 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT; 2024 } 1958 2025 1959 2026 /* checks the password complexity */ 1960 if (((pwdProperties & DOMAIN_PASSWORD_COMPLEX) != 0) 1961 && (password->data != NULL) 1962 && (!check_password_quality((const char *) password->data))) 2027 if (!(pwdProperties & DOMAIN_PASSWORD_COMPLEX)) { 2028 return SAMR_VALIDATION_STATUS_SUCCESS; 2029 } 2030 2031 if (utf8_len == 0) { 1963 2032 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH; 2033 } 2034 2035 if (!check_password_quality(utf8_pw)) { 2036 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH; 2037 } 1964 2038 1965 2039 return SAMR_VALIDATION_STATUS_SUCCESS; … … 2006 2080 * NT_STATUS_WRONG_PASSWORD, NT_STATUS_PASSWORD_RESTRICTION 2007 2081 */ 2008 NTSTATUS samdb_set_password(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,2082 static NTSTATUS samdb_set_password_internal(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, 2009 2083 struct ldb_dn *user_dn, struct ldb_dn *domain_dn, 2010 2084 const DATA_BLOB *new_password, … … 2014 2088 const struct samr_Password *ntOldHash, 2015 2089 enum samPwdChangeReason *reject_reason, 2016 struct samr_DomInfo1 **_dominfo) 2090 struct samr_DomInfo1 **_dominfo, 2091 bool permit_interdomain_trust) 2017 2092 { 2018 2093 struct ldb_message *msg; … … 2021 2096 struct dsdb_control_password_change_status *pwd_stat = NULL; 2022 2097 int ret; 2098 bool hash_values = false; 2023 2099 NTSTATUS status = NT_STATUS_OK; 2024 2100 … … 2056 2132 el->flags = LDB_FLAG_MOD_REPLACE; 2057 2133 } 2134 hash_values = true; 2058 2135 } else { 2059 2136 /* the password wasn't specified correctly */ … … 2093 2170 } 2094 2171 } 2172 if (hash_values) { 2173 ret = ldb_request_add_control(req, 2174 DSDB_CONTROL_PASSWORD_HASH_VALUES_OID, 2175 true, NULL); 2176 if (ret != LDB_SUCCESS) { 2177 talloc_free(req); 2178 talloc_free(msg); 2179 return NT_STATUS_NO_MEMORY; 2180 } 2181 } 2182 if (permit_interdomain_trust) { 2183 ret = ldb_request_add_control(req, 2184 DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID, 2185 false, NULL); 2186 if (ret != LDB_SUCCESS) { 2187 talloc_free(req); 2188 talloc_free(msg); 2189 return NT_STATUS_NO_MEMORY; 2190 } 2191 } 2095 2192 ret = ldb_request_add_control(req, 2096 DSDB_CONTROL_PASSWORD_ HASH_VALUES_OID,2193 DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID, 2097 2194 true, NULL); 2098 2195 if (ret != LDB_SUCCESS) { … … 2101 2198 return NT_STATUS_NO_MEMORY; 2102 2199 } 2103 ret = ldb_request_add_control(req,2104 DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID,2105 true, NULL);2106 if (ret != LDB_SUCCESS) {2107 talloc_free(req);2108 talloc_free(msg);2109 return NT_STATUS_NO_MEMORY;2110 }2111 2200 2112 2201 ret = dsdb_autotransaction_request(ldb, req); 2113 2202 2114 2203 if (req->context != NULL) { 2115 pwd_stat = talloc_steal(mem_ctx, 2116 ((struct ldb_control *)req->context)->data); 2204 struct ldb_control *control = talloc_get_type_abort(req->context, 2205 struct ldb_control); 2206 pwd_stat = talloc_get_type_abort(control->data, 2207 struct dsdb_control_password_change_status); 2208 talloc_steal(mem_ctx, pwd_stat); 2117 2209 } 2118 2210 … … 2171 2263 /* don't let the caller know if an account doesn't exist */ 2172 2264 status = NT_STATUS_WRONG_PASSWORD; 2265 } else if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { 2266 status = NT_STATUS_ACCESS_DENIED; 2173 2267 } else if (ret != LDB_SUCCESS) { 2268 DEBUG(1, ("Failed to set password on %s: %s\n", 2269 ldb_dn_get_linearized(msg->dn), 2270 ldb_errstring(ldb))); 2174 2271 status = NT_STATUS_UNSUCCESSFUL; 2175 2272 } 2176 2273 2177 2274 return status; 2275 } 2276 2277 NTSTATUS samdb_set_password(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, 2278 struct ldb_dn *user_dn, struct ldb_dn *domain_dn, 2279 const DATA_BLOB *new_password, 2280 const struct samr_Password *lmNewHash, 2281 const struct samr_Password *ntNewHash, 2282 const struct samr_Password *lmOldHash, 2283 const struct samr_Password *ntOldHash, 2284 enum samPwdChangeReason *reject_reason, 2285 struct samr_DomInfo1 **_dominfo) 2286 { 2287 return samdb_set_password_internal(ldb, mem_ctx, 2288 user_dn, domain_dn, 2289 new_password, 2290 lmNewHash, ntNewHash, 2291 lmOldHash, ntOldHash, 2292 reject_reason, _dominfo, 2293 false); /* reject trusts */ 2178 2294 } 2179 2295 … … 2198 2314 NTSTATUS samdb_set_password_sid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, 2199 2315 const struct dom_sid *user_sid, 2316 const uint32_t *new_version, /* optional for trusts */ 2200 2317 const DATA_BLOB *new_password, 2201 2318 const struct samr_Password *lmNewHash, … … 2206 2323 struct samr_DomInfo1 **_dominfo) 2207 2324 { 2325 TALLOC_CTX *frame = talloc_stackframe(); 2208 2326 NTSTATUS nt_status; 2209 struct ldb_dn *user_dn; 2327 const char * const user_attrs[] = { 2328 "userAccountControl", 2329 "sAMAccountName", 2330 NULL 2331 }; 2332 struct ldb_message *user_msg = NULL; 2210 2333 int ret; 2334 uint32_t uac = 0; 2211 2335 2212 2336 ret = ldb_transaction_start(ldb); 2213 2337 if (ret != LDB_SUCCESS) { 2214 2338 DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(ldb))); 2339 TALLOC_FREE(frame); 2215 2340 return NT_STATUS_TRANSACTION_ABORTED; 2216 2341 } 2217 2342 2218 user_dn = samdb_search_dn(ldb, mem_ctx, NULL, 2219 "(&(objectSid=%s)(objectClass=user))", 2220 ldap_encode_ndr_dom_sid(mem_ctx, user_sid)); 2221 if (!user_dn) { 2343 ret = dsdb_search_one(ldb, frame, &user_msg, ldb_get_default_basedn(ldb), 2344 LDB_SCOPE_SUBTREE, user_attrs, 0, 2345 "(&(objectSid=%s)(objectClass=user))", 2346 ldap_encode_ndr_dom_sid(frame, user_sid)); 2347 if (ret != LDB_SUCCESS) { 2222 2348 ldb_transaction_cancel(ldb); 2223 DEBUG(3, ("samdb_set_password_sid: SID %s not found in samdb, returning NO_SUCH_USER\n", 2224 dom_sid_string(mem_ctx, user_sid))); 2349 DEBUG(3, ("samdb_set_password_sid: SID[%s] not found in samdb %s - %s, " 2350 "returning NO_SUCH_USER\n", 2351 dom_sid_string(frame, user_sid), 2352 ldb_strerror(ret), ldb_errstring(ldb))); 2353 TALLOC_FREE(frame); 2225 2354 return NT_STATUS_NO_SUCH_USER; 2226 2355 } 2227 2356 2228 nt_status = samdb_set_password(ldb, mem_ctx, 2229 user_dn, NULL, 2230 new_password, 2231 lmNewHash, ntNewHash, 2232 lmOldHash, ntOldHash, 2233 reject_reason, _dominfo); 2357 uac = ldb_msg_find_attr_as_uint(user_msg, "userAccountControl", 0); 2358 if (!(uac & UF_ACCOUNT_TYPE_MASK)) { 2359 ldb_transaction_cancel(ldb); 2360 DEBUG(1, ("samdb_set_password_sid: invalid " 2361 "userAccountControl[0x%08X] for SID[%s] DN[%s], " 2362 "returning NO_SUCH_USER\n", 2363 (unsigned)uac, dom_sid_string(frame, user_sid), 2364 ldb_dn_get_linearized(user_msg->dn))); 2365 TALLOC_FREE(frame); 2366 return NT_STATUS_NO_SUCH_USER; 2367 } 2368 2369 if (uac & UF_INTERDOMAIN_TRUST_ACCOUNT) { 2370 const char * const tdo_attrs[] = { 2371 "trustAuthIncoming", 2372 "trustDirection", 2373 NULL 2374 }; 2375 struct ldb_message *tdo_msg = NULL; 2376 const char *account_name = NULL; 2377 uint32_t trust_direction; 2378 uint32_t i; 2379 const struct ldb_val *old_val = NULL; 2380 struct trustAuthInOutBlob old_blob = {}; 2381 uint32_t old_version = 0; 2382 struct AuthenticationInformation *old_version_a = NULL; 2383 uint32_t _new_version = 0; 2384 struct trustAuthInOutBlob new_blob = {}; 2385 struct ldb_val new_val = {}; 2386 struct timeval tv = timeval_current(); 2387 NTTIME now = timeval_to_nttime(&tv); 2388 enum ndr_err_code ndr_err; 2389 2390 if (new_password == NULL && ntNewHash == NULL) { 2391 ldb_transaction_cancel(ldb); 2392 DEBUG(1, ("samdb_set_password_sid: " 2393 "no new password provided " 2394 "sAMAccountName for SID[%s] DN[%s], " 2395 "returning INVALID_PARAMETER\n", 2396 dom_sid_string(frame, user_sid), 2397 ldb_dn_get_linearized(user_msg->dn))); 2398 TALLOC_FREE(frame); 2399 return NT_STATUS_INVALID_PARAMETER; 2400 } 2401 2402 if (new_password != NULL && ntNewHash != NULL) { 2403 ldb_transaction_cancel(ldb); 2404 DEBUG(1, ("samdb_set_password_sid: " 2405 "two new passwords provided " 2406 "sAMAccountName for SID[%s] DN[%s], " 2407 "returning INVALID_PARAMETER\n", 2408 dom_sid_string(frame, user_sid), 2409 ldb_dn_get_linearized(user_msg->dn))); 2410 TALLOC_FREE(frame); 2411 return NT_STATUS_INVALID_PARAMETER; 2412 } 2413 2414 if (new_password != NULL && (new_password->length % 2)) { 2415 ldb_transaction_cancel(ldb); 2416 DEBUG(2, ("samdb_set_password_sid: " 2417 "invalid utf16 length (%zu) " 2418 "sAMAccountName for SID[%s] DN[%s], " 2419 "returning WRONG_PASSWORD\n", 2420 new_password->length, 2421 dom_sid_string(frame, user_sid), 2422 ldb_dn_get_linearized(user_msg->dn))); 2423 TALLOC_FREE(frame); 2424 return NT_STATUS_WRONG_PASSWORD; 2425 } 2426 2427 if (new_password != NULL && new_password->length >= 500) { 2428 ldb_transaction_cancel(ldb); 2429 DEBUG(2, ("samdb_set_password_sid: " 2430 "utf16 password too long (%zu) " 2431 "sAMAccountName for SID[%s] DN[%s], " 2432 "returning WRONG_PASSWORD\n", 2433 new_password->length, 2434 dom_sid_string(frame, user_sid), 2435 ldb_dn_get_linearized(user_msg->dn))); 2436 TALLOC_FREE(frame); 2437 return NT_STATUS_WRONG_PASSWORD; 2438 } 2439 2440 account_name = ldb_msg_find_attr_as_string(user_msg, 2441 "sAMAccountName", NULL); 2442 if (account_name == NULL) { 2443 ldb_transaction_cancel(ldb); 2444 DEBUG(1, ("samdb_set_password_sid: missing " 2445 "sAMAccountName for SID[%s] DN[%s], " 2446 "returning NO_SUCH_USER\n", 2447 dom_sid_string(frame, user_sid), 2448 ldb_dn_get_linearized(user_msg->dn))); 2449 TALLOC_FREE(frame); 2450 return NT_STATUS_NO_SUCH_USER; 2451 } 2452 2453 nt_status = dsdb_trust_search_tdo_by_type(ldb, 2454 SEC_CHAN_DOMAIN, 2455 account_name, 2456 tdo_attrs, 2457 frame, &tdo_msg); 2458 if (!NT_STATUS_IS_OK(nt_status)) { 2459 ldb_transaction_cancel(ldb); 2460 DEBUG(1, ("samdb_set_password_sid: dsdb_trust_search_tdo " 2461 "failed(%s) for sAMAccountName[%s] SID[%s] DN[%s], " 2462 "returning INTERNAL_DB_CORRUPTION\n", 2463 nt_errstr(nt_status), account_name, 2464 dom_sid_string(frame, user_sid), 2465 ldb_dn_get_linearized(user_msg->dn))); 2466 TALLOC_FREE(frame); 2467 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2468 } 2469 2470 trust_direction = ldb_msg_find_attr_as_int(tdo_msg, 2471 "trustDirection", 0); 2472 if (!(trust_direction & LSA_TRUST_DIRECTION_INBOUND)) { 2473 ldb_transaction_cancel(ldb); 2474 DEBUG(1, ("samdb_set_password_sid: direction[0x%08X] is " 2475 "not inbound for sAMAccountName[%s] " 2476 "DN[%s] TDO[%s], " 2477 "returning INTERNAL_DB_CORRUPTION\n", 2478 (unsigned)trust_direction, 2479 account_name, 2480 ldb_dn_get_linearized(user_msg->dn), 2481 ldb_dn_get_linearized(tdo_msg->dn))); 2482 TALLOC_FREE(frame); 2483 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2484 } 2485 2486 old_val = ldb_msg_find_ldb_val(tdo_msg, "trustAuthIncoming"); 2487 if (old_val != NULL) { 2488 ndr_err = ndr_pull_struct_blob(old_val, frame, &old_blob, 2489 (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob); 2490 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 2491 ldb_transaction_cancel(ldb); 2492 DEBUG(1, ("samdb_set_password_sid: " 2493 "failed(%s) to parse " 2494 "trustAuthOutgoing sAMAccountName[%s] " 2495 "DN[%s] TDO[%s], " 2496 "returning INTERNAL_DB_CORRUPTION\n", 2497 ndr_map_error2string(ndr_err), 2498 account_name, 2499 ldb_dn_get_linearized(user_msg->dn), 2500 ldb_dn_get_linearized(tdo_msg->dn))); 2501 2502 TALLOC_FREE(frame); 2503 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2504 } 2505 } 2506 2507 for (i = old_blob.current.count; i > 0; i--) { 2508 struct AuthenticationInformation *a = 2509 &old_blob.current.array[i - 1]; 2510 2511 switch (a->AuthType) { 2512 case TRUST_AUTH_TYPE_NONE: 2513 if (i == old_blob.current.count) { 2514 /* 2515 * remove TRUST_AUTH_TYPE_NONE at the 2516 * end 2517 */ 2518 old_blob.current.count--; 2519 } 2520 break; 2521 2522 case TRUST_AUTH_TYPE_VERSION: 2523 old_version_a = a; 2524 old_version = a->AuthInfo.version.version; 2525 break; 2526 2527 case TRUST_AUTH_TYPE_CLEAR: 2528 break; 2529 2530 case TRUST_AUTH_TYPE_NT4OWF: 2531 break; 2532 } 2533 } 2534 2535 if (new_version == NULL) { 2536 _new_version = 0; 2537 new_version = &_new_version; 2538 } 2539 2540 if (old_version_a != NULL && *new_version != (old_version + 1)) { 2541 old_version_a->LastUpdateTime = now; 2542 old_version_a->AuthType = TRUST_AUTH_TYPE_NONE; 2543 } 2544 2545 new_blob.count = MAX(old_blob.current.count, 2); 2546 new_blob.current.array = talloc_zero_array(frame, 2547 struct AuthenticationInformation, 2548 new_blob.count); 2549 if (new_blob.current.array == NULL) { 2550 ldb_transaction_cancel(ldb); 2551 TALLOC_FREE(frame); 2552 return NT_STATUS_NO_MEMORY; 2553 } 2554 new_blob.previous.array = talloc_zero_array(frame, 2555 struct AuthenticationInformation, 2556 new_blob.count); 2557 if (new_blob.current.array == NULL) { 2558 ldb_transaction_cancel(ldb); 2559 TALLOC_FREE(frame); 2560 return NT_STATUS_NO_MEMORY; 2561 } 2562 2563 for (i = 0; i < old_blob.current.count; i++) { 2564 struct AuthenticationInformation *o = 2565 &old_blob.current.array[i]; 2566 struct AuthenticationInformation *p = 2567 &new_blob.previous.array[i]; 2568 2569 *p = *o; 2570 new_blob.previous.count++; 2571 } 2572 for (; i < new_blob.count; i++) { 2573 struct AuthenticationInformation *pi = 2574 &new_blob.previous.array[i]; 2575 2576 if (i == 0) { 2577 /* 2578 * new_blob.previous is still empty so 2579 * we'll do new_blob.previous = new_blob.current 2580 * below. 2581 */ 2582 break; 2583 } 2584 2585 pi->LastUpdateTime = now; 2586 pi->AuthType = TRUST_AUTH_TYPE_NONE; 2587 new_blob.previous.count++; 2588 } 2589 2590 for (i = 0; i < new_blob.count; i++) { 2591 struct AuthenticationInformation *ci = 2592 &new_blob.current.array[i]; 2593 2594 ci->LastUpdateTime = now; 2595 switch (i) { 2596 case 0: 2597 if (ntNewHash != NULL) { 2598 ci->AuthType = TRUST_AUTH_TYPE_NT4OWF; 2599 ci->AuthInfo.nt4owf.password = *ntNewHash; 2600 break; 2601 } 2602 2603 ci->AuthType = TRUST_AUTH_TYPE_CLEAR; 2604 ci->AuthInfo.clear.size = new_password->length; 2605 ci->AuthInfo.clear.password = new_password->data; 2606 break; 2607 case 1: 2608 ci->AuthType = TRUST_AUTH_TYPE_VERSION; 2609 ci->AuthInfo.version.version = *new_version; 2610 break; 2611 default: 2612 ci->AuthType = TRUST_AUTH_TYPE_NONE; 2613 break; 2614 } 2615 2616 new_blob.current.count++; 2617 } 2618 2619 if (new_blob.previous.count == 0) { 2620 TALLOC_FREE(new_blob.previous.array); 2621 new_blob.previous = new_blob.current; 2622 } 2623 2624 ndr_err = ndr_push_struct_blob(&new_val, frame, &new_blob, 2625 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); 2626 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 2627 ldb_transaction_cancel(ldb); 2628 DEBUG(1, ("samdb_set_password_sid: " 2629 "failed(%s) to generate " 2630 "trustAuthOutgoing sAMAccountName[%s] " 2631 "DN[%s] TDO[%s], " 2632 "returning UNSUCCESSFUL\n", 2633 ndr_map_error2string(ndr_err), 2634 account_name, 2635 ldb_dn_get_linearized(user_msg->dn), 2636 ldb_dn_get_linearized(tdo_msg->dn))); 2637 TALLOC_FREE(frame); 2638 return NT_STATUS_UNSUCCESSFUL; 2639 } 2640 2641 tdo_msg->num_elements = 0; 2642 TALLOC_FREE(tdo_msg->elements); 2643 2644 ret = ldb_msg_add_empty(tdo_msg, "trustAuthIncoming", 2645 LDB_FLAG_MOD_REPLACE, NULL); 2646 if (ret != LDB_SUCCESS) { 2647 ldb_transaction_cancel(ldb); 2648 TALLOC_FREE(frame); 2649 return NT_STATUS_NO_MEMORY; 2650 } 2651 ret = ldb_msg_add_value(tdo_msg, "trustAuthIncoming", 2652 &new_val, NULL); 2653 if (ret != LDB_SUCCESS) { 2654 ldb_transaction_cancel(ldb); 2655 TALLOC_FREE(frame); 2656 return NT_STATUS_NO_MEMORY; 2657 } 2658 2659 ret = ldb_modify(ldb, tdo_msg); 2660 if (ret != LDB_SUCCESS) { 2661 nt_status = dsdb_ldb_err_to_ntstatus(ret); 2662 ldb_transaction_cancel(ldb); 2663 DEBUG(1, ("samdb_set_password_sid: " 2664 "failed to replace " 2665 "trustAuthOutgoing sAMAccountName[%s] " 2666 "DN[%s] TDO[%s], " 2667 "%s - %s\n", 2668 account_name, 2669 ldb_dn_get_linearized(user_msg->dn), 2670 ldb_dn_get_linearized(tdo_msg->dn), 2671 nt_errstr(nt_status), ldb_errstring(ldb))); 2672 TALLOC_FREE(frame); 2673 return nt_status; 2674 } 2675 } 2676 2677 nt_status = samdb_set_password_internal(ldb, mem_ctx, 2678 user_msg->dn, NULL, 2679 new_password, 2680 lmNewHash, ntNewHash, 2681 lmOldHash, ntOldHash, 2682 reject_reason, _dominfo, 2683 true); /* permit trusts */ 2234 2684 if (!NT_STATUS_IS_OK(nt_status)) { 2235 2685 ldb_transaction_cancel(ldb); 2236 talloc_free(user_dn);2686 TALLOC_FREE(frame); 2237 2687 return nt_status; 2238 2688 } … … 2241 2691 if (ret != LDB_SUCCESS) { 2242 2692 DEBUG(0,("Failed to commit transaction to change password on %s: %s\n", 2243 ldb_dn_get_linearized(user_ dn),2693 ldb_dn_get_linearized(user_msg->dn), 2244 2694 ldb_errstring(ldb))); 2245 talloc_free(user_dn);2695 TALLOC_FREE(frame); 2246 2696 return NT_STATUS_TRANSACTION_ABORTED; 2247 2697 } 2248 2698 2249 talloc_free(user_dn);2699 TALLOC_FREE(frame); 2250 2700 return NT_STATUS_OK; 2251 2701 } … … 2324 2774 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 2325 2775 const char *binary_encoded; 2326 const char * *split_realm;2776 const char * const *split_realm; 2327 2777 struct ldb_dn *dn; 2328 2778 … … 2331 2781 } 2332 2782 2333 split_realm = (const char * *)str_list_make(tmp_ctx, dns_domain, ".");2783 split_realm = (const char * const *)str_list_make(tmp_ctx, dns_domain, "."); 2334 2784 if (!split_realm) { 2335 2785 talloc_free(tmp_ctx); … … 2355 2805 return dn; 2356 2806 } 2807 2808 2809 /* 2810 Find the DNS equivalent of a DN, in dotted DNS form 2811 */ 2812 char *samdb_dn_to_dns_domain(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) 2813 { 2814 int i, num_components = ldb_dn_get_comp_num(dn); 2815 char *dns_name = talloc_strdup(mem_ctx, ""); 2816 if (dns_name == NULL) { 2817 return NULL; 2818 } 2819 2820 for (i=0; i<num_components; i++) { 2821 const struct ldb_val *v = ldb_dn_get_component_val(dn, i); 2822 char *s; 2823 if (v == NULL) { 2824 talloc_free(dns_name); 2825 return NULL; 2826 } 2827 s = talloc_asprintf_append_buffer(dns_name, "%*.*s.", 2828 (int)v->length, (int)v->length, (char *)v->data); 2829 if (s == NULL) { 2830 talloc_free(dns_name); 2831 return NULL; 2832 } 2833 dns_name = s; 2834 } 2835 2836 /* remove the last '.' */ 2837 if (dns_name[0] != 0) { 2838 dns_name[strlen(dns_name)-1] = 0; 2839 } 2840 2841 return dns_name; 2842 } 2843 2844 /* 2845 Find the DNS _msdcs name for a given NTDS GUID. The resulting DNS 2846 name is based on the forest DNS name 2847 */ 2848 char *samdb_ntds_msdcs_dns_name(struct ldb_context *samdb, 2849 TALLOC_CTX *mem_ctx, 2850 const struct GUID *ntds_guid) 2851 { 2852 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 2853 const char *guid_str; 2854 struct ldb_dn *forest_dn; 2855 const char *dnsforest; 2856 char *ret; 2857 2858 guid_str = GUID_string(tmp_ctx, ntds_guid); 2859 if (guid_str == NULL) { 2860 talloc_free(tmp_ctx); 2861 return NULL; 2862 } 2863 forest_dn = ldb_get_root_basedn(samdb); 2864 if (forest_dn == NULL) { 2865 talloc_free(tmp_ctx); 2866 return NULL; 2867 } 2868 dnsforest = samdb_dn_to_dns_domain(tmp_ctx, forest_dn); 2869 if (dnsforest == NULL) { 2870 talloc_free(tmp_ctx); 2871 return NULL; 2872 } 2873 ret = talloc_asprintf(mem_ctx, "%s._msdcs.%s", guid_str, dnsforest); 2874 talloc_free(tmp_ctx); 2875 return ret; 2876 } 2877 2357 2878 2358 2879 /* … … 2415 2936 int dsdb_find_dn_by_guid(struct ldb_context *ldb, 2416 2937 TALLOC_CTX *mem_ctx, 2417 const struct GUID *guid, struct ldb_dn **dn) 2938 const struct GUID *guid, 2939 uint32_t dsdb_flags, 2940 struct ldb_dn **dn) 2418 2941 { 2419 2942 int ret; … … 2429 2952 DSDB_SEARCH_SEARCH_ALL_PARTITIONS | 2430 2953 DSDB_SEARCH_SHOW_EXTENDED_DN | 2431 DSDB_SEARCH_ONE_ONLY ,2954 DSDB_SEARCH_ONE_ONLY | dsdb_flags, 2432 2955 "objectGUID=%s", guid_str); 2433 2956 talloc_free(guid_str); … … 2598 3121 unsigned int i; 2599 3122 struct ldb_message_element *el; 3123 int ret; 2600 3124 2601 3125 *r = NULL; 2602 3126 *count = 0; 2603 3127 2604 if (ldb_search(sam_ctx, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, NULL) != LDB_SUCCESS || 2605 res->count < 1) { 2606 DEBUG(0,("dsdb_loadreps: failed to read partition object\n")); 3128 ret = dsdb_search_dn(sam_ctx, tmp_ctx, &res, dn, attrs, 0); 3129 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 3130 /* partition hasn't been replicated yet */ 3131 return WERR_OK; 3132 } 3133 if (ret != LDB_SUCCESS) { 3134 DEBUG(0,("dsdb_loadreps: failed to read partition object: %s\n", ldb_errstring(sam_ctx))); 2607 3135 talloc_free(tmp_ctx); 2608 3136 return WERR_DS_DRA_INTERNAL_ERROR; … … 2678 3206 } 2679 3207 2680 if ( ldb_modify(sam_ctx, msg) != LDB_SUCCESS) {3208 if (dsdb_modify(sam_ctx, msg, 0) != LDB_SUCCESS) { 2681 3209 DEBUG(0,("Failed to store %s - %s\n", attr, ldb_errstring(sam_ctx))); 2682 3210 goto failed; … … 2910 3438 2911 3439 /* 3440 * return NTDSSiteSettings options. See MS-ADTS 7.1.1.2.2.1.1 3441 * flags are DS_NTDSSETTINGS_OPT_* 3442 */ 3443 int samdb_ntds_site_settings_options(struct ldb_context *ldb_ctx, 3444 uint32_t *options) 3445 { 3446 int rc; 3447 TALLOC_CTX *tmp_ctx; 3448 struct ldb_result *res; 3449 struct ldb_dn *site_dn; 3450 const char *attrs[] = { "options", NULL }; 3451 3452 tmp_ctx = talloc_new(ldb_ctx); 3453 if (tmp_ctx == NULL) 3454 goto failed; 3455 3456 /* Retrieve the site dn for the ldb that we 3457 * have open. This is our local site. 3458 */ 3459 site_dn = samdb_server_site_dn(ldb_ctx, tmp_ctx); 3460 if (site_dn == NULL) 3461 goto failed; 3462 3463 /* Perform a one level (child) search from the local 3464 * site distinguided name. We're looking for the 3465 * "options" attribute within the nTDSSiteSettings 3466 * object 3467 */ 3468 rc = ldb_search(ldb_ctx, tmp_ctx, &res, site_dn, 3469 LDB_SCOPE_ONELEVEL, attrs, 3470 "objectClass=nTDSSiteSettings"); 3471 3472 if (rc != LDB_SUCCESS || res->count != 1) 3473 goto failed; 3474 3475 *options = ldb_msg_find_attr_as_uint(res->msgs[0], "options", 0); 3476 3477 talloc_free(tmp_ctx); 3478 3479 return LDB_SUCCESS; 3480 3481 failed: 3482 DEBUG(1,("Failed to find our NTDS Site Settings options in ldb!\n")); 3483 talloc_free(tmp_ctx); 3484 return LDB_ERR_NO_SUCH_OBJECT; 3485 } 3486 3487 /* 2912 3488 return NTDS options flags. See MS-ADTS 7.1.1.2.2.1.2.1.1 2913 3489 … … 2926 3502 } 2927 3503 2928 ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb ), LDB_SCOPE_BASE, attrs, NULL);3504 ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL); 2929 3505 if (ret != LDB_SUCCESS) { 2930 3506 goto failed; … … 2953 3529 struct ldb_result *res; 2954 3530 2955 ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb ), LDB_SCOPE_BASE, attrs, NULL);3531 ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL); 2956 3532 if (ret != LDB_SUCCESS) { 2957 3533 goto failed; … … 2984 3560 /* "tolower()" and "toupper()" should also work properly on 0x00 */ 2985 3561 tokens[0][0] = tolower(tokens[0][0]); 2986 for (i = 1; i < str_list_length((const char * *)tokens); i++)3562 for (i = 1; i < str_list_length((const char * const *)tokens); i++) 2987 3563 tokens[i][0] = toupper(tokens[i][0]); 2988 3564 2989 3565 ret = talloc_strdup(mem_ctx, tokens[0]); 2990 for (i = 1; i < str_list_length((const char * *)tokens); i++)3566 for (i = 1; i < str_list_length((const char * const *)tokens); i++) 2991 3567 ret = talloc_asprintf_append_buffer(ret, "%s", tokens[i]); 2992 3568 … … 3193 3769 bool dsdb_dn_is_upgraded_link_val(struct ldb_val *val) 3194 3770 { 3195 return memmem(val->data, val->length, "<RMD_ ADDTIME=", 13) != NULL;3771 return memmem(val->data, val->length, "<RMD_VERSION=", 13) != NULL; 3196 3772 } 3197 3773 … … 3257 3833 ret = ldb_search(samdb, tmp_ctx, &root_res, 3258 3834 ldb_dn_new(tmp_ctx, samdb, ""), LDB_SCOPE_BASE, root_attrs, NULL); 3259 if (ret != LDB_SUCCESS ) {3835 if (ret != LDB_SUCCESS || root_res->count == 0) { 3260 3836 DEBUG(1,("Searching for namingContexts in rootDSE failed: %s\n", ldb_errstring(samdb))); 3261 3837 talloc_free(tmp_ctx); … … 3402 3978 unsigned int i; 3403 3979 int ret; 3404 uint64_t highest_usn ;3980 uint64_t highest_usn = 0; 3405 3981 const struct GUID *our_invocation_id; 3406 struct timeval now = timeval_current(); 3982 static const struct timeval tv1970; 3983 NTTIME nt1970 = timeval_to_nttime(&tv1970); 3407 3984 3408 3985 ret = ldb_search(samdb, mem_ctx, &r, dn, LDB_SCOPE_BASE, attrs, NULL); … … 3445 4022 } 3446 4023 3447 ret = dsdb_load_partition_usn(samdb, dn, &highest_usn, NULL);4024 ret = ldb_sequence_number(samdb, LDB_SEQ_HIGHEST_SEQ, &highest_usn); 3448 4025 if (ret != LDB_SUCCESS) { 3449 4026 /* nothing to add - this can happen after a vampire */ … … 3455 4032 if (GUID_equal(our_invocation_id, &(*cursors)[i].source_dsa_invocation_id)) { 3456 4033 (*cursors)[i].highest_usn = highest_usn; 3457 (*cursors)[i].last_sync_success = timeval_to_nttime(&now);4034 (*cursors)[i].last_sync_success = nt1970; 3458 4035 TYPESAFE_QSORT(*cursors, *count, drsuapi_DsReplicaCursor2_compare); 3459 4036 return LDB_SUCCESS; … … 3468 4045 (*cursors)[*count].source_dsa_invocation_id = *our_invocation_id; 3469 4046 (*cursors)[*count].highest_usn = highest_usn; 3470 (*cursors)[*count].last_sync_success = timeval_to_nttime(&now);4047 (*cursors)[*count].last_sync_success = nt1970; 3471 4048 (*count)++; 3472 4049 … … 3536 4113 } 3537 4114 4115 if (dsdb_flags & DSDB_SEARCH_NO_GLOBAL_CATALOG) { 4116 ret = ldb_request_add_control(req, 4117 DSDB_CONTROL_NO_GLOBAL_CATALOG, 4118 false, NULL); 4119 if (ret != LDB_SUCCESS) { 4120 return ret; 4121 } 4122 } 4123 3538 4124 if (dsdb_flags & DSDB_SEARCH_SHOW_DELETED) { 3539 4125 ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_DELETED_OID, true, NULL); … … 3551 4137 3552 4138 if (dsdb_flags & DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT) { 3553 ret = ldb_request_add_control(req, DSDB_CONTROL_DN_STORAGE_FORMAT_OID, true, NULL);4139 ret = ldb_request_add_control(req, DSDB_CONTROL_DN_STORAGE_FORMAT_OID, false, NULL); 3554 4140 if (ret != LDB_SUCCESS) { 3555 4141 return ret; … … 3607 4193 if (dsdb_flags & DSDB_PROVISION) { 3608 4194 ret = ldb_request_add_control(req, LDB_CONTROL_PROVISION_OID, false, NULL); 4195 if (ret != LDB_SUCCESS) { 4196 return ret; 4197 } 4198 } 4199 4200 /* This is a special control to bypass the password_hash module for use in pdb_samba4 for Samba3 upgrades */ 4201 if (dsdb_flags & DSDB_BYPASS_PASSWORD_HASH) { 4202 ret = ldb_request_add_control(req, DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID, true, NULL); 4203 if (ret != LDB_SUCCESS) { 4204 return ret; 4205 } 4206 } 4207 4208 if (dsdb_flags & DSDB_PASSWORD_BYPASS_LAST_SET) { 4209 /* 4210 * This must not be critical, as it will only be 4211 * handled (and need to be handled) if the other 4212 * attributes in the request bring password_hash into 4213 * action 4214 */ 4215 ret = ldb_request_add_control(req, DSDB_CONTROL_PASSWORD_BYPASS_LAST_SET_OID, false, NULL); 4216 if (ret != LDB_SUCCESS) { 4217 return ret; 4218 } 4219 } 4220 4221 if (dsdb_flags & DSDB_MODIFY_PARTIAL_REPLICA) { 4222 ret = ldb_request_add_control(req, DSDB_CONTROL_PARTIAL_REPLICA, false, NULL); 3609 4223 if (ret != LDB_SUCCESS) { 3610 4224 return ret; … … 3676 4290 3677 4291 /* 4292 a delete with a set of flags 4293 */ 4294 int dsdb_delete(struct ldb_context *ldb, struct ldb_dn *dn, 4295 uint32_t dsdb_flags) 4296 { 4297 struct ldb_request *req; 4298 int ret; 4299 4300 ret = ldb_build_del_req(&req, ldb, ldb, 4301 dn, 4302 NULL, 4303 NULL, 4304 ldb_op_default_callback, 4305 NULL); 4306 4307 if (ret != LDB_SUCCESS) return ret; 4308 4309 ret = dsdb_request_add_controls(req, dsdb_flags); 4310 if (ret != LDB_SUCCESS) { 4311 talloc_free(req); 4312 return ret; 4313 } 4314 4315 ret = dsdb_autotransaction_request(ldb, req); 4316 4317 talloc_free(req); 4318 return ret; 4319 } 4320 4321 /* 3678 4322 like dsdb_modify() but set all the element flags to 3679 4323 LDB_FLAG_MOD_REPLACE … … 3697 4341 int dsdb_search_dn(struct ldb_context *ldb, 3698 4342 TALLOC_CTX *mem_ctx, 3699 struct ldb_result **_res ,4343 struct ldb_result **_result, 3700 4344 struct ldb_dn *basedn, 3701 4345 const char * const *attrs, … … 3742 4386 } 3743 4387 3744 *_res = res;4388 *_result = res; 3745 4389 return LDB_SUCCESS; 3746 4390 } … … 3752 4396 int dsdb_search_by_dn_guid(struct ldb_context *ldb, 3753 4397 TALLOC_CTX *mem_ctx, 3754 struct ldb_result **_res ,4398 struct ldb_result **_result, 3755 4399 const struct GUID *guid, 3756 4400 const char * const *attrs, … … 3767 4411 } 3768 4412 3769 ret = dsdb_search_dn(ldb, mem_ctx, _res , dn, attrs, dsdb_flags);4413 ret = dsdb_search_dn(ldb, mem_ctx, _result, dn, attrs, dsdb_flags); 3770 4414 talloc_free(tmp_ctx); 3771 4415 return ret; … … 3777 4421 int dsdb_search(struct ldb_context *ldb, 3778 4422 TALLOC_CTX *mem_ctx, 3779 struct ldb_result **_res ,4423 struct ldb_result **_result, 3780 4424 struct ldb_dn *basedn, 3781 4425 enum ldb_scope scope, … … 3790 4434 char *expression = NULL; 3791 4435 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 4436 4437 /* cross-partitions searches with a basedn break multi-domain support */ 4438 SMB_ASSERT(basedn == NULL || (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) == 0); 3792 4439 3793 4440 res = talloc_zero(tmp_ctx, struct ldb_result); … … 3852 4499 } 3853 4500 3854 *_res = talloc_steal(mem_ctx, res);4501 *_result = talloc_steal(mem_ctx, res); 3855 4502 talloc_free(tmp_ctx); 3856 4503 … … 4009 4656 account_dn = ldb_msg_find_attr_as_dn(ldb, tmp_ctx, msg, "serverReference"); 4010 4657 if (account_dn == NULL) { 4011 DEBUG(1,(__location__ ": Failed to find account_dn for DSA with objectGUID %s, sid %s\n", 4012 GUID_string(tmp_ctx, dsa_guid), dom_sid_string(tmp_ctx, sid))); 4658 DEBUG(1,(__location__ ": Failed to find account dn " 4659 "(serverReference) for %s, parent of DSA with " 4660 "objectGUID %s, sid %s\n", 4661 ldb_dn_get_linearized(msg->dn), 4662 GUID_string(tmp_ctx, dsa_guid), 4663 dom_sid_string(tmp_ctx, sid))); 4013 4664 talloc_free(tmp_ctx); 4014 4665 return ldb_operr(ldb); … … 4217 4868 } 4218 4869 4870 4871 /* 4872 map an ldb error code to an approximate NTSTATUS code 4873 */ 4874 NTSTATUS dsdb_ldb_err_to_ntstatus(int err) 4875 { 4876 switch (err) { 4877 case LDB_SUCCESS: 4878 return NT_STATUS_OK; 4879 4880 case LDB_ERR_PROTOCOL_ERROR: 4881 return NT_STATUS_DEVICE_PROTOCOL_ERROR; 4882 4883 case LDB_ERR_TIME_LIMIT_EXCEEDED: 4884 return NT_STATUS_IO_TIMEOUT; 4885 4886 case LDB_ERR_SIZE_LIMIT_EXCEEDED: 4887 return NT_STATUS_BUFFER_TOO_SMALL; 4888 4889 case LDB_ERR_COMPARE_FALSE: 4890 case LDB_ERR_COMPARE_TRUE: 4891 return NT_STATUS_REVISION_MISMATCH; 4892 4893 case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED: 4894 return NT_STATUS_NOT_SUPPORTED; 4895 4896 case LDB_ERR_STRONG_AUTH_REQUIRED: 4897 case LDB_ERR_CONFIDENTIALITY_REQUIRED: 4898 case LDB_ERR_SASL_BIND_IN_PROGRESS: 4899 case LDB_ERR_INAPPROPRIATE_AUTHENTICATION: 4900 case LDB_ERR_INVALID_CREDENTIALS: 4901 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 4902 case LDB_ERR_UNWILLING_TO_PERFORM: 4903 return NT_STATUS_ACCESS_DENIED; 4904 4905 case LDB_ERR_NO_SUCH_OBJECT: 4906 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 4907 4908 case LDB_ERR_REFERRAL: 4909 case LDB_ERR_NO_SUCH_ATTRIBUTE: 4910 return NT_STATUS_NOT_FOUND; 4911 4912 case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION: 4913 return NT_STATUS_NOT_SUPPORTED; 4914 4915 case LDB_ERR_ADMIN_LIMIT_EXCEEDED: 4916 return NT_STATUS_BUFFER_TOO_SMALL; 4917 4918 case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE: 4919 case LDB_ERR_INAPPROPRIATE_MATCHING: 4920 case LDB_ERR_CONSTRAINT_VIOLATION: 4921 case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX: 4922 case LDB_ERR_INVALID_DN_SYNTAX: 4923 case LDB_ERR_NAMING_VIOLATION: 4924 case LDB_ERR_OBJECT_CLASS_VIOLATION: 4925 case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF: 4926 case LDB_ERR_NOT_ALLOWED_ON_RDN: 4927 return NT_STATUS_INVALID_PARAMETER; 4928 4929 case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS: 4930 case LDB_ERR_ENTRY_ALREADY_EXISTS: 4931 return NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS; 4932 4933 case LDB_ERR_BUSY: 4934 return NT_STATUS_NETWORK_BUSY; 4935 4936 case LDB_ERR_ALIAS_PROBLEM: 4937 case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM: 4938 case LDB_ERR_UNAVAILABLE: 4939 case LDB_ERR_LOOP_DETECT: 4940 case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED: 4941 case LDB_ERR_AFFECTS_MULTIPLE_DSAS: 4942 case LDB_ERR_OTHER: 4943 case LDB_ERR_OPERATIONS_ERROR: 4944 break; 4945 } 4946 return NT_STATUS_UNSUCCESSFUL; 4947 } 4948 4949 4950 /* 4951 create a new naming context that will hold a partial replica 4952 */ 4953 int dsdb_create_partial_replica_NC(struct ldb_context *ldb, struct ldb_dn *dn) 4954 { 4955 TALLOC_CTX *tmp_ctx = talloc_new(ldb); 4956 struct ldb_message *msg; 4957 int ret; 4958 4959 msg = ldb_msg_new(tmp_ctx); 4960 if (msg == NULL) { 4961 talloc_free(tmp_ctx); 4962 return ldb_oom(ldb); 4963 } 4964 4965 msg->dn = dn; 4966 ret = ldb_msg_add_string(msg, "objectClass", "top"); 4967 if (ret != LDB_SUCCESS) { 4968 talloc_free(tmp_ctx); 4969 return ldb_oom(ldb); 4970 } 4971 4972 /* [MS-DRSR] implies that we should only add the 'top' 4973 * objectclass, but that would cause lots of problems with our 4974 * objectclass code as top is not structural, so we add 4975 * 'domainDNS' as well to keep things sane. We're expecting 4976 * this new NC to be of objectclass domainDNS after 4977 * replication anyway 4978 */ 4979 ret = ldb_msg_add_string(msg, "objectClass", "domainDNS"); 4980 if (ret != LDB_SUCCESS) { 4981 talloc_free(tmp_ctx); 4982 return ldb_oom(ldb); 4983 } 4984 4985 ret = ldb_msg_add_fmt(msg, "instanceType", "%u", 4986 INSTANCE_TYPE_IS_NC_HEAD| 4987 INSTANCE_TYPE_NC_ABOVE| 4988 INSTANCE_TYPE_UNINSTANT); 4989 if (ret != LDB_SUCCESS) { 4990 talloc_free(tmp_ctx); 4991 return ldb_oom(ldb); 4992 } 4993 4994 ret = dsdb_add(ldb, msg, DSDB_MODIFY_PARTIAL_REPLICA); 4995 if (ret != LDB_SUCCESS && ret != LDB_ERR_ENTRY_ALREADY_EXISTS) { 4996 DEBUG(0,("Failed to create new NC for %s - %s (%s)\n", 4997 ldb_dn_get_linearized(dn), 4998 ldb_errstring(ldb), ldb_strerror(ret))); 4999 talloc_free(tmp_ctx); 5000 return ret; 5001 } 5002 5003 DEBUG(1,("Created new NC for %s\n", ldb_dn_get_linearized(dn))); 5004 5005 talloc_free(tmp_ctx); 5006 return LDB_SUCCESS; 5007 } 5008 5009 /** 5010 build a GUID from a string 5011 */ 5012 _PUBLIC_ NTSTATUS NS_GUID_from_string(const char *s, struct GUID *guid) 5013 { 5014 NTSTATUS status = NT_STATUS_INVALID_PARAMETER; 5015 uint32_t time_low; 5016 uint32_t time_mid, time_hi_and_version; 5017 uint32_t clock_seq[2]; 5018 uint32_t node[6]; 5019 int i; 5020 5021 if (s == NULL) { 5022 return NT_STATUS_INVALID_PARAMETER; 5023 } 5024 5025 if (11 == sscanf(s, "%08x-%04x%04x-%02x%02x%02x%02x-%02x%02x%02x%02x", 5026 &time_low, &time_mid, &time_hi_and_version, 5027 &clock_seq[0], &clock_seq[1], 5028 &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) { 5029 status = NT_STATUS_OK; 5030 } 5031 5032 if (!NT_STATUS_IS_OK(status)) { 5033 return status; 5034 } 5035 5036 guid->time_low = time_low; 5037 guid->time_mid = time_mid; 5038 guid->time_hi_and_version = time_hi_and_version; 5039 guid->clock_seq[0] = clock_seq[0]; 5040 guid->clock_seq[1] = clock_seq[1]; 5041 for (i=0;i<6;i++) { 5042 guid->node[i] = node[i]; 5043 } 5044 5045 return NT_STATUS_OK; 5046 } 5047 5048 _PUBLIC_ char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid) 5049 { 5050 return talloc_asprintf(mem_ctx, 5051 "%08x-%04x%04x-%02x%02x%02x%02x-%02x%02x%02x%02x", 5052 guid->time_low, guid->time_mid, 5053 guid->time_hi_and_version, 5054 guid->clock_seq[0], 5055 guid->clock_seq[1], 5056 guid->node[0], guid->node[1], 5057 guid->node[2], guid->node[3], 5058 guid->node[4], guid->node[5]); 5059 } 5060 5061 /* 5062 * Return the effective badPwdCount 5063 * 5064 * This requires that the user_msg have (if present): 5065 * - badPasswordTime 5066 * - badPwdCount 5067 * 5068 * This also requires that the domain_msg have (if present): 5069 * - lockOutObservationWindow 5070 */ 5071 static int dsdb_effective_badPwdCount(struct ldb_message *user_msg, 5072 int64_t lockOutObservationWindow, 5073 NTTIME now) 5074 { 5075 int64_t badPasswordTime; 5076 badPasswordTime = ldb_msg_find_attr_as_int64(user_msg, "badPasswordTime", 0); 5077 5078 if (badPasswordTime - lockOutObservationWindow >= now) { 5079 return ldb_msg_find_attr_as_int(user_msg, "badPwdCount", 0); 5080 } else { 5081 return 0; 5082 } 5083 } 5084 5085 /* 5086 * Return the effective badPwdCount 5087 * 5088 * This requires that the user_msg have (if present): 5089 * - badPasswordTime 5090 * - badPwdCount 5091 * 5092 */ 5093 int samdb_result_effective_badPwdCount(struct ldb_context *sam_ldb, 5094 TALLOC_CTX *mem_ctx, 5095 struct ldb_dn *domain_dn, 5096 struct ldb_message *user_msg) 5097 { 5098 struct timeval tv_now = timeval_current(); 5099 NTTIME now = timeval_to_nttime(&tv_now); 5100 int64_t lockOutObservationWindow = samdb_search_int64(sam_ldb, mem_ctx, 0, domain_dn, 5101 "lockOutObservationWindow", NULL); 5102 return dsdb_effective_badPwdCount(user_msg, lockOutObservationWindow, now); 5103 } 5104 5105 /* 5106 * Prepare an update to the badPwdCount and associated attributes. 5107 * 5108 * This requires that the user_msg have (if present): 5109 * - objectSid 5110 * - badPasswordTime 5111 * - badPwdCount 5112 * 5113 * This also requires that the domain_msg have (if present): 5114 * - pwdProperties 5115 * - lockoutThreshold 5116 * - lockOutObservationWindow 5117 */ 5118 NTSTATUS dsdb_update_bad_pwd_count(TALLOC_CTX *mem_ctx, 5119 struct ldb_context *sam_ctx, 5120 struct ldb_message *user_msg, 5121 struct ldb_message *domain_msg, 5122 struct ldb_message **_mod_msg) 5123 { 5124 int i, ret, badPwdCount; 5125 int64_t lockoutThreshold, lockOutObservationWindow; 5126 struct dom_sid *sid; 5127 struct timeval tv_now = timeval_current(); 5128 NTTIME now = timeval_to_nttime(&tv_now); 5129 NTSTATUS status; 5130 uint32_t pwdProperties, rid = 0; 5131 struct ldb_message *mod_msg; 5132 5133 sid = samdb_result_dom_sid(mem_ctx, user_msg, "objectSid"); 5134 5135 pwdProperties = ldb_msg_find_attr_as_uint(domain_msg, 5136 "pwdProperties", -1); 5137 if (sid && !(pwdProperties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)) { 5138 status = dom_sid_split_rid(NULL, sid, NULL, &rid); 5139 if (!NT_STATUS_IS_OK(status)) { 5140 /* 5141 * This can't happen anyway, but always try 5142 * and update the badPwdCount on failure 5143 */ 5144 rid = 0; 5145 } 5146 } 5147 TALLOC_FREE(sid); 5148 5149 /* 5150 * Work out if we are doing password lockout on the domain. 5151 * Also, the built in administrator account is exempt: 5152 * http://msdn.microsoft.com/en-us/library/windows/desktop/aa375371%28v=vs.85%29.aspx 5153 */ 5154 lockoutThreshold = ldb_msg_find_attr_as_int(domain_msg, 5155 "lockoutThreshold", 0); 5156 if (lockoutThreshold == 0 || (rid == DOMAIN_RID_ADMINISTRATOR)) { 5157 DEBUG(5, ("Not updating badPwdCount on %s after wrong password\n", 5158 ldb_dn_get_linearized(user_msg->dn))); 5159 return NT_STATUS_OK; 5160 } 5161 5162 mod_msg = ldb_msg_new(mem_ctx); 5163 if (mod_msg == NULL) { 5164 return NT_STATUS_NO_MEMORY; 5165 } 5166 mod_msg->dn = ldb_dn_copy(mod_msg, user_msg->dn); 5167 if (mod_msg->dn == NULL) { 5168 TALLOC_FREE(mod_msg); 5169 return NT_STATUS_NO_MEMORY; 5170 } 5171 5172 lockOutObservationWindow = ldb_msg_find_attr_as_int64(domain_msg, 5173 "lockOutObservationWindow", 0); 5174 5175 badPwdCount = dsdb_effective_badPwdCount(user_msg, lockOutObservationWindow, now); 5176 5177 badPwdCount++; 5178 5179 ret = samdb_msg_add_int(sam_ctx, mod_msg, mod_msg, "badPwdCount", badPwdCount); 5180 if (ret != LDB_SUCCESS) { 5181 TALLOC_FREE(mod_msg); 5182 return NT_STATUS_NO_MEMORY; 5183 } 5184 ret = samdb_msg_add_int64(sam_ctx, mod_msg, mod_msg, "badPasswordTime", now); 5185 if (ret != LDB_SUCCESS) { 5186 TALLOC_FREE(mod_msg); 5187 return NT_STATUS_NO_MEMORY; 5188 } 5189 5190 if (badPwdCount >= lockoutThreshold) { 5191 ret = samdb_msg_add_int64(sam_ctx, mod_msg, mod_msg, "lockoutTime", now); 5192 if (ret != LDB_SUCCESS) { 5193 TALLOC_FREE(mod_msg); 5194 return NT_STATUS_NO_MEMORY; 5195 } 5196 DEBUG(5, ("Locked out user %s after %d wrong passwords\n", 5197 ldb_dn_get_linearized(user_msg->dn), badPwdCount)); 5198 } else { 5199 DEBUG(5, ("Updated badPwdCount on %s after %d wrong passwords\n", 5200 ldb_dn_get_linearized(user_msg->dn), badPwdCount)); 5201 } 5202 5203 /* mark all the message elements as LDB_FLAG_MOD_REPLACE */ 5204 for (i=0; i< mod_msg->num_elements; i++) { 5205 mod_msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; 5206 } 5207 5208 *_mod_msg = mod_msg; 5209 return NT_STATUS_OK; 5210 } 5211 5212 /** 5213 * Sets defaults for a User object 5214 * List of default attributes set: 5215 * accountExpires, badPasswordTime, badPwdCount, 5216 * codePage, countryCode, lastLogoff, lastLogon 5217 * logonCount, pwdLastSet 5218 */ 5219 int dsdb_user_obj_set_defaults(struct ldb_context *ldb, struct ldb_message *usr_obj) 5220 { 5221 int i, ret; 5222 const struct attribute_values { 5223 const char *name; 5224 const char *value; 5225 } map[] = { 5226 { 5227 .name = "accountExpires", 5228 .value = "9223372036854775807" 5229 }, 5230 { 5231 .name = "badPasswordTime", 5232 .value = "0" 5233 }, 5234 { 5235 .name = "badPwdCount", 5236 .value = "0" 5237 }, 5238 { 5239 .name = "codePage", 5240 .value = "0" 5241 }, 5242 { 5243 .name = "countryCode", 5244 .value = "0" 5245 }, 5246 { 5247 .name = "lastLogoff", 5248 .value = "0" 5249 }, 5250 { 5251 .name = "lastLogon", 5252 .value = "0" 5253 }, 5254 { 5255 .name = "logonCount", 5256 .value = "0" 5257 }, 5258 { 5259 .name = "pwdLastSet", 5260 .value = "0" 5261 } 5262 }; 5263 5264 for (i = 0; i < ARRAY_SIZE(map); i++) { 5265 ret = samdb_find_or_add_attribute(ldb, usr_obj, 5266 map[i].name, map[i].value); 5267 if (ret != LDB_SUCCESS) { 5268 return ret; 5269 } 5270 } 5271 5272 return LDB_SUCCESS; 5273 } 5274 5275 /** 5276 * Sets 'sAMAccountType on user object based on userAccountControl 5277 * @param ldb Current ldb_context 5278 * @param usr_obj ldb_message representing User object 5279 * @param user_account_control Value for userAccountControl flags 5280 * @param account_type_p Optional pointer to account_type to return 5281 * @return LDB_SUCCESS or LDB_ERR* code on failure 5282 */ 5283 int dsdb_user_obj_set_account_type(struct ldb_context *ldb, struct ldb_message *usr_obj, 5284 uint32_t user_account_control, uint32_t *account_type_p) 5285 { 5286 int ret; 5287 uint32_t account_type; 5288 struct ldb_message_element *el; 5289 5290 account_type = ds_uf2atype(user_account_control); 5291 if (account_type == 0) { 5292 ldb_set_errstring(ldb, "dsdb: Unrecognized account type!"); 5293 return LDB_ERR_UNWILLING_TO_PERFORM; 5294 } 5295 ret = samdb_msg_add_uint(ldb, usr_obj, usr_obj, 5296 "sAMAccountType", 5297 account_type); 5298 if (ret != LDB_SUCCESS) { 5299 return ret; 5300 } 5301 el = ldb_msg_find_element(usr_obj, "sAMAccountType"); 5302 el->flags = LDB_FLAG_MOD_REPLACE; 5303 5304 if (account_type_p) { 5305 *account_type_p = account_type; 5306 } 5307 5308 return LDB_SUCCESS; 5309 } 5310 5311 /** 5312 * Determine and set primaryGroupID based on userAccountControl value 5313 * @param ldb Current ldb_context 5314 * @param usr_obj ldb_message representing User object 5315 * @param user_account_control Value for userAccountControl flags 5316 * @param group_rid_p Optional pointer to group RID to return 5317 * @return LDB_SUCCESS or LDB_ERR* code on failure 5318 */ 5319 int dsdb_user_obj_set_primary_group_id(struct ldb_context *ldb, struct ldb_message *usr_obj, 5320 uint32_t user_account_control, uint32_t *group_rid_p) 5321 { 5322 int ret; 5323 uint32_t rid; 5324 struct ldb_message_element *el; 5325 5326 rid = ds_uf2prim_group_rid(user_account_control); 5327 5328 ret = samdb_msg_add_uint(ldb, usr_obj, usr_obj, 5329 "primaryGroupID", rid); 5330 if (ret != LDB_SUCCESS) { 5331 return ret; 5332 } 5333 el = ldb_msg_find_element(usr_obj, "primaryGroupID"); 5334 el->flags = LDB_FLAG_MOD_REPLACE; 5335 5336 if (group_rid_p) { 5337 *group_rid_p = rid; 5338 } 5339 5340 return LDB_SUCCESS; 5341 } -
vendor/current/source4/dsdb/common/util.h
r740 r988 20 20 */ 21 21 22 #ifndef __DSDB_COMMON_UTIL_H__ 23 #define __DSDB_COMMON_UTIL_H__ 24 22 25 /* 23 26 flags for dsdb_request_add_controls(). For the module functions, … … 36 39 #define DSDB_SEARCH_SHOW_RECYCLED 0x0400 37 40 #define DSDB_PROVISION 0x0800 41 #define DSDB_BYPASS_PASSWORD_HASH 0x1000 42 #define DSDB_SEARCH_NO_GLOBAL_CATALOG 0x2000 43 #define DSDB_MODIFY_PARTIAL_REPLICA 0x4000 44 #define DSDB_PASSWORD_BYPASS_LAST_SET 0x8000 38 45 39 46 bool is_attr_in_list(const char * const * attrs, const char *attr); 40 47 41 48 #define DSDB_SECRET_ATTRIBUTES_EX(sep) \ 49 "pekList" sep \ 50 "msDS-ExecuteScriptPassword" sep \ 42 51 "currentValue" sep \ 43 52 "dBCSPwd" sep \ … … 50 59 "trustAuthIncoming" sep \ 51 60 "trustAuthOutgoing" sep \ 52 "unicodePwd" 61 "unicodePwd" sep \ 62 "clearTextPassword" 53 63 54 64 #define DSDB_SECRET_ATTRIBUTES_COMMA , 55 65 #define DSDB_SECRET_ATTRIBUTES DSDB_SECRET_ATTRIBUTES_EX(DSDB_SECRET_ATTRIBUTES_COMMA) 66 67 struct GUID; 68 69 char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid); 70 NTSTATUS NS_GUID_from_string(const char *s, struct GUID *guid); 71 72 #endif /* __DSDB_COMMON_UTIL_H__ */ -
vendor/current/source4/dsdb/common/util_groups.c
r740 r988 127 127 } 128 128 129 /* 130 * We have the problem with the caller creating a <SID=S-....> 131 * DN for ForeignSecurityPrincipals as they also have 132 * duplicate objects with the SAME SID under CN=Configuration. 133 * This causes a SID= DN to fail with NO_SUCH_OBJECT on Samba 134 * and on Windows. So, we allow this to fail, and 135 * double-check if we can find it with a search in the main 136 * domain partition. 137 */ 138 if (ret == LDB_ERR_NO_SUCH_OBJECT && only_childs) { 139 char *sid_string = dom_sid_string(tmp_ctx, 140 &sid); 141 if (!sid_string) { 142 talloc_free(tmp_ctx); 143 return NT_STATUS_OK; 144 } 145 146 ret = dsdb_search(sam_ctx, tmp_ctx, &res, 147 ldb_get_default_basedn(sam_ctx), 148 LDB_SCOPE_SUBTREE, 149 attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, 150 "(&(objectClass=foreignSecurityPrincipal)(objectSID=%s))", 151 sid_string); 152 } 153 129 154 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 130 155 talloc_free(tmp_ctx); … … 150 175 *res_sids = talloc_realloc(res_sids_ctx, *res_sids, 151 176 struct dom_sid, *num_res_sids + 1); 152 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*res_sids, tmp_ctx); 177 if (*res_sids == NULL) { 178 TALLOC_FREE(tmp_ctx); 179 return NT_STATUS_NO_MEMORY; 180 } 153 181 (*res_sids)[*num_res_sids] = sid; 154 182 ++(*num_res_sids); -
vendor/current/source4/dsdb/common/util_samr.c
r740 r988 37 37 const char *account_name, 38 38 uint32_t acct_flags, 39 const struct dom_sid *forced_sid, 39 40 struct dom_sid **sid, 40 41 struct ldb_dn **dn) … … 70 71 ldb_errstring(ldb))); 71 72 talloc_free(tmp_ctx); 72 return NT_STATUS_ INTERNAL_DB_CORRUPTION;73 return NT_STATUS_LOCK_NOT_GRANTED; 73 74 } 74 75 … … 109 110 container = "CN=Users"; 110 111 obj_class = "user"; 111 112 user_account_control = UF_NORMAL_ACCOUNT; 112 113 } else if (acct_flags == ACB_WSTRUST) { 113 114 if (cn_name[cn_name_len - 1] != '$') { … … 118 119 container = "CN=Computers"; 119 120 obj_class = "computer"; 121 user_account_control = UF_WORKSTATION_TRUST_ACCOUNT; 120 122 121 123 } else if (acct_flags == ACB_SVRTRUST) { … … 127 129 container = "OU=Domain Controllers"; 128 130 obj_class = "computer"; 131 user_account_control = UF_SERVER_TRUST_ACCOUNT; 132 } else if (acct_flags == ACB_DOMTRUST) { 133 DEBUG(3, ("Invalid account flags specified: cannot create domain trusts via this interface (must use LSA CreateTrustedDomain calls\n")); 134 ldb_transaction_cancel(ldb); 135 talloc_free(tmp_ctx); 136 return NT_STATUS_INVALID_PARAMETER; 129 137 } else { 138 DEBUG(3, ("Invalid account flags specified 0x%08X, must be exactly one of \n" 139 "ACB_NORMAL (0x%08X) ACB_WSTRUST (0x%08X) or ACB_SVRTRUST (0x%08X)\n", 140 acct_flags, 141 ACB_NORMAL, ACB_WSTRUST, ACB_SVRTRUST)); 130 142 ldb_transaction_cancel(ldb); 131 143 talloc_free(tmp_ctx); 132 144 return NT_STATUS_INVALID_PARAMETER; 133 145 } 146 147 user_account_control |= UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD; 134 148 135 149 /* add core elements to the ldb_message for the user */ … … 143 157 ldb_msg_add_string(msg, "sAMAccountName", account_name); 144 158 ldb_msg_add_string(msg, "objectClass", obj_class); 159 samdb_msg_add_uint(ldb, tmp_ctx, msg, 160 "userAccountControl", 161 user_account_control); 162 163 /* This is only here for migrations using pdb_samba4, the 164 * caller and the samldb are responsible for ensuring it makes 165 * sense */ 166 if (forced_sid) { 167 ret = samdb_msg_add_dom_sid(ldb, msg, msg, "objectSID", forced_sid); 168 if (ret != LDB_SUCCESS) { 169 ldb_transaction_cancel(ldb); 170 talloc_free(tmp_ctx); 171 return NT_STATUS_INTERNAL_ERROR; 172 } 173 } 145 174 146 175 /* create the user */ … … 195 224 } 196 225 197 /* Change the account control to be the correct account type.198 * The default is for a workstation account */199 user_account_control = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);200 user_account_control = (user_account_control &201 ~(UF_NORMAL_ACCOUNT |202 UF_INTERDOMAIN_TRUST_ACCOUNT |203 UF_WORKSTATION_TRUST_ACCOUNT |204 UF_SERVER_TRUST_ACCOUNT));205 user_account_control |= ds_acb2uf(acct_flags);206 207 talloc_free(msg);208 msg = ldb_msg_new(tmp_ctx);209 if (msg == NULL) {210 ldb_transaction_cancel(ldb);211 talloc_free(tmp_ctx);212 return NT_STATUS_NO_MEMORY;213 }214 215 msg->dn = account_dn;216 217 if (samdb_msg_add_uint(ldb, tmp_ctx, msg,218 "userAccountControl",219 user_account_control) != LDB_SUCCESS) {220 ldb_transaction_cancel(ldb);221 talloc_free(tmp_ctx);222 return NT_STATUS_NO_MEMORY;223 }224 225 /* modify the samdb record */226 ret = dsdb_replace(ldb, msg, 0);227 if (ret != LDB_SUCCESS) {228 DEBUG(0,("Failed to modify account record %s to set userAccountControl: %s\n",229 ldb_dn_get_linearized(msg->dn),230 ldb_errstring(ldb)));231 ldb_transaction_cancel(ldb);232 talloc_free(tmp_ctx);233 234 /* we really need samdb.c to return NTSTATUS */235 return NT_STATUS_UNSUCCESSFUL;236 }237 238 226 ret = ldb_transaction_commit(ldb); 239 227 if (ret != LDB_SUCCESS) { … … 245 233 } 246 234 *dn = talloc_steal(mem_ctx, account_dn); 247 *sid = talloc_steal(mem_ctx, account_sid); 235 if (sid) { 236 *sid = talloc_steal(mem_ctx, account_sid); 237 } 248 238 talloc_free(tmp_ctx); 249 239 return NT_STATUS_OK; … … 343 333 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); 344 334 335 if (ldb_transaction_start(ldb) != LDB_SUCCESS) { 336 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(ldb))); 337 return NT_STATUS_INTERNAL_ERROR; 338 } 339 345 340 /* Check if alias already exists */ 346 341 name = samdb_search_string(ldb, tmp_ctx, NULL, … … 351 346 if (name != NULL) { 352 347 talloc_free(tmp_ctx); 348 ldb_transaction_cancel(ldb); 353 349 return NT_STATUS_ALIAS_EXISTS; 354 350 } … … 357 353 if (msg == NULL) { 358 354 talloc_free(tmp_ctx); 355 ldb_transaction_cancel(ldb); 359 356 return NT_STATUS_NO_MEMORY; 360 357 } … … 365 362 if (!msg->dn) { 366 363 talloc_free(tmp_ctx); 364 ldb_transaction_cancel(ldb); 367 365 return NT_STATUS_NO_MEMORY; 368 366 } … … 379 377 case LDB_ERR_ENTRY_ALREADY_EXISTS: 380 378 talloc_free(tmp_ctx); 379 ldb_transaction_cancel(ldb); 381 380 return NT_STATUS_ALIAS_EXISTS; 382 381 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 383 382 talloc_free(tmp_ctx); 383 ldb_transaction_cancel(ldb); 384 384 return NT_STATUS_ACCESS_DENIED; 385 385 default: … … 388 388 ldb_errstring(ldb))); 389 389 talloc_free(tmp_ctx); 390 ldb_transaction_cancel(ldb); 390 391 return NT_STATUS_INTERNAL_DB_CORRUPTION; 391 392 } … … 395 396 msg->dn, "objectSid", NULL); 396 397 398 if (ldb_transaction_commit(ldb) != LDB_SUCCESS) { 399 DEBUG(0, ("Failed to commit transaction in dsdb_add_domain_alias(): %s\n", 400 ldb_errstring(ldb))); 401 return NT_STATUS_INTERNAL_ERROR; 402 } 403 397 404 *dn = talloc_steal(mem_ctx, msg->dn); 398 405 *sid = talloc_steal(mem_ctx, alias_sid); 399 406 talloc_free(tmp_ctx); 407 400 408 401 409 return NT_STATUS_OK;
Note:
See TracChangeset
for help on using the changeset viewer.