Changeset 988 for vendor/current/source4/dsdb/schema
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/dsdb/schema
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/dsdb/schema/schema.h
r740 r988 24 24 25 25 #include "prefixmap.h" 26 27 enum dsdb_dn_format { 28 DSDB_NORMAL_DN, 29 DSDB_BINARY_DN, 30 DSDB_STRING_DN, 31 DSDB_INVALID_DN 32 }; 33 26 34 27 35 struct dsdb_attribute; … … 66 74 const struct dsdb_attribute *attr, 67 75 const struct ldb_message_element *in); 76 bool auto_normalise; 77 bool userParameters; /* Indicates the syntax userParameters should be forced to */ 68 78 }; 69 79 … … 108 118 bool systemOnly; 109 119 120 bool one_way_link; 121 enum dsdb_dn_format dn_format; 122 110 123 /* internal stuff */ 111 124 const struct dsdb_syntax *syntax; … … 144 157 145 158 uint32_t schemaFlagsEx; 159 uint32_t systemFlags; 146 160 struct ldb_val msDs_Schema_Extensions; 147 161 … … 154 168 bool systemOnly; 155 169 156 const char **supclasses;157 const char **subclasses;158 const char **subclasses_direct;159 const char **posssuperiors;160 170 uint32_t subClassOf_id; 161 171 uint32_t *systemAuxiliaryClass_ids; … … 174 184 * 3 */ 175 185 uint32_t subClass_order; 186 187 struct { 188 const char **supclasses; 189 const char **subclasses; 190 const char **subclasses_direct; 191 const char **posssuperiors; 192 } tmp; 176 193 }; 177 194 … … 186 203 187 204 struct dsdb_schema { 188 struct ldb_dn *base_dn;189 190 205 struct dsdb_schema_prefixmap *prefixmap; 191 206 … … 206 221 struct dsdb_class *classes; 207 222 223 struct dsdb_attribute **attributes_to_remove; 224 uint32_t attributes_to_remove_size; 225 struct dsdb_class **classes_to_remove; 226 uint32_t classes_to_remove_size; 227 208 228 /* lists of classes sorted by various attributes, for faster 209 229 access */ … … 225 245 struct { 226 246 bool we_are_master; 247 bool update_allowed; 227 248 struct ldb_dn *master_dn; 228 249 } fsmo; 229 250 230 251 /* Was this schema loaded from ldb (if so, then we will reload it when we detect a change in ldb) */ 231 struct ldb_module *loaded_from_module;232 struct dsdb_schema *(*refresh_fn)(struct ldb_module *module, struct dsdb_schema *schema, bool is_global_schema);233 252 bool refresh_in_progress; 234 /* an 'opaque' sequence number that the reload function may also wish to use */ 235 uint64_t reload_seq_number; 253 time_t ts_last_change; 254 time_t last_refresh; 255 time_t refresh_interval; 256 /* This 'opaque' is stored in the metadata and is used to check if the currently 257 * loaded schema needs a reload because another process has signaled that it has been 258 * requested to reload the schema (either due through DRS or via the schemaUpdateNow). 259 */ 260 uint64_t metadata_usn; 236 261 237 262 /* Should the syntax handlers in this case handle all incoming OIDs automatically, assigning them as an OID if no text name is known? */ … … 255 280 }; 256 281 282 struct ldb_module; 283 284 typedef struct dsdb_schema *(*dsdb_schema_refresh_fn)(struct ldb_module *module, 285 struct tevent_context *ev, 286 struct dsdb_schema *schema, bool is_global_schema); 257 287 #include "dsdb/schema/proto.h" 258 288 -
vendor/current/source4/dsdb/schema/schema_convert_to_ol.c
r740 r988 135 135 NULL); 136 136 if (schema_entry == NULL) { 137 talloc_free(mem_ctx); 137 138 DEBUG(0, ("failed to generate schema description for %s\n", name)); 138 139 return NULL; … … 146 147 out = talloc_asprintf_append(out, "objectClasses: %s\n", schema_entry); 147 148 break; 149 default: 150 talloc_free(mem_ctx); 151 DEBUG(0,(__location__ " Wrong type of target %u!", (unsigned)target)); 152 return NULL; 148 153 } 149 154 talloc_free(mem_ctx); … … 200 205 target = TARGET_FEDORA_DS; 201 206 } else { 207 talloc_free(mem_ctx); 202 208 DEBUG(0, ("Invalid target type for schema conversion %s\n", target_str)); 203 209 return NULL; 204 210 } 205 211 206 /* The mappings are line-sep erated, and specify details such as OIDs to skip etc */212 /* The mappings are line-separated, and specify details such as OIDs to skip etc */ 207 213 while (1) { 208 214 line = next_line; … … 264 270 schema = dsdb_get_schema(ldb, mem_ctx); 265 271 if (!schema) { 272 talloc_free(mem_ctx); 266 273 DEBUG(0, ("No schema on ldb to convert!\n")); 267 274 return NULL; … … 275 282 out = talloc_strdup(mem_ctx, "dn: cn=schema\n"); 276 283 break; 284 default: 285 talloc_free(mem_ctx); 286 DEBUG(0,(__location__ " Wrong type of target %u!", (unsigned)target)); 287 return NULL; 277 288 } 278 289 … … 340 351 341 352 if (schema_entry == NULL) { 353 talloc_free(mem_ctx); 342 354 DEBUG(0, ("failed to generate attribute description for %s\n", name)); 343 355 return NULL; … … 351 363 out = talloc_asprintf_append(out, "attributeTypes: %s\n", schema_entry); 352 364 break; 365 default: 366 talloc_free(mem_ctx); 367 DEBUG(0,(__location__ " Wrong type of target %u!", (unsigned)target)); 368 return NULL; 353 369 } 354 370 } 355 371 356 372 out = print_schema_recursive(out, schema, "top", target, attrs_skip, attr_map, oid_map); 373 374 talloc_steal(ldb, out); 375 talloc_free(mem_ctx); 357 376 358 377 return out; -
vendor/current/source4/dsdb/schema/schema_inferiors.c
r740 r988 40 40 const char **list; 41 41 42 if (schema_class-> supclasses) {43 return schema_class-> supclasses;42 if (schema_class->tmp.supclasses) { 43 return schema_class->tmp.supclasses; 44 44 } 45 45 … … 53 53 if (schema_class->subClassOf && 54 54 strcmp(schema_class->lDAPDisplayName, schema_class->subClassOf) == 0) { 55 schema_class-> supclasses = list;55 schema_class->tmp.supclasses = list; 56 56 return list; 57 57 } … … 66 66 } 67 67 68 schema_class-> supclasses = str_list_unique(list);69 70 return schema_class-> supclasses;68 schema_class->tmp.supclasses = str_list_unique(list); 69 70 return schema_class->tmp.supclasses; 71 71 } 72 72 … … 88 88 continue; 89 89 } 90 list = str_list_append_const(list, schema_class-> subclasses);90 list = str_list_append_const(list, schema_class->tmp.subclasses); 91 91 } 92 92 return list; … … 100 100 struct dsdb_class *schema_class) 101 101 { 102 if (schema_class-> posssuperiors == NULL) {102 if (schema_class->tmp.posssuperiors == NULL) { 103 103 const char **list2 = const_str_list(str_list_make_empty(schema_class)); 104 104 const char **list3; … … 119 119 list2 = str_list_append_const(list2, schema_subclasses(schema, list2, list2)); 120 120 121 schema_class-> posssuperiors = str_list_unique(list2);122 } 123 124 return schema_class-> posssuperiors;121 schema_class->tmp.posssuperiors = str_list_unique(list2); 122 } 123 124 return schema_class->tmp.posssuperiors; 125 125 } 126 126 … … 128 128 struct dsdb_class *schema_class) 129 129 { 130 const char **list = str_list_copy_const(schema_class, schema_class-> subclasses_direct);130 const char **list = str_list_copy_const(schema_class, schema_class->tmp.subclasses_direct); 131 131 unsigned int i; 132 132 for (i=0;list && list[i]; i++) { … … 142 142 /* Walk down the subClass tree, setting a higher index as we go down 143 143 * each level. top is 1, subclasses of top are 2, etc */ 144 void schema_subclasses_order_recurse(const struct dsdb_schema *schema,145 146 147 { 148 const char **list = schema_class-> subclasses_direct;144 static void schema_subclasses_order_recurse(const struct dsdb_schema *schema, 145 struct dsdb_class *schema_class, 146 const int order) 147 { 148 const char **list = schema_class->tmp.subclasses_direct; 149 149 unsigned int i; 150 150 schema_class->subClass_order = order; … … 170 170 } 171 171 if (schema_class2 && schema_class != schema_class2) { 172 if (schema_class2-> subclasses_direct == NULL) {173 schema_class2-> subclasses_direct = const_str_list(str_list_make_empty(schema_class2));174 if (!schema_class2-> subclasses_direct) {172 if (schema_class2->tmp.subclasses_direct == NULL) { 173 schema_class2->tmp.subclasses_direct = const_str_list(str_list_make_empty(schema_class2)); 174 if (!schema_class2->tmp.subclasses_direct) { 175 175 return LDB_ERR_OPERATIONS_ERROR; 176 176 } 177 177 } 178 schema_class2-> subclasses_direct = str_list_add_const(schema_class2->subclasses_direct,178 schema_class2->tmp.subclasses_direct = str_list_add_const(schema_class2->tmp.subclasses_direct, 179 179 schema_class->lDAPDisplayName); 180 180 } … … 182 182 183 183 for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) { 184 schema_class-> subclasses = str_list_unique(schema_subclasses_recurse(schema, schema_class));184 schema_class->tmp.subclasses = str_list_unique(schema_subclasses_recurse(schema, schema_class)); 185 185 186 186 /* Initialize the subClass order, to ensure we can't have uninitialized sort on the subClass hierarchy */ … … 202 202 { 203 203 struct dsdb_class *c2; 204 205 for (c2=schema->classes; c2; c2=c2->next) { 204 const char **poss_inf = NULL; 205 const char **sys_poss_inf = NULL; 206 207 for (c2 = schema->classes; c2; c2 = c2->next) { 206 208 const char **superiors = schema_posssuperiors(schema, c2); 207 if (c2->systemOnly == false 208 && c2->objectClassCategory != 2 209 && c2->objectClassCategory != 3 210 && str_list_check(superiors, schema_class->lDAPDisplayName)) { 211 if (schema_class->possibleInferiors == NULL) { 212 schema_class->possibleInferiors = const_str_list(str_list_make_empty(schema_class)); 213 } 214 schema_class->possibleInferiors = str_list_add_const(schema_class->possibleInferiors, 215 c2->lDAPDisplayName); 216 } 217 } 218 schema_class->possibleInferiors = str_list_unique(schema_class->possibleInferiors); 219 } 220 221 static void schema_fill_system_possible_inferiors(const struct dsdb_schema *schema, 222 struct dsdb_class *schema_class) 223 { 224 struct dsdb_class *c2; 225 226 for (c2=schema->classes; c2; c2=c2->next) { 227 const char **superiors = schema_posssuperiors(schema, c2); 228 if (c2->objectClassCategory != 2 229 && c2->objectClassCategory != 3 230 && str_list_check(superiors, schema_class->lDAPDisplayName)) { 231 if (schema_class->systemPossibleInferiors == NULL) { 232 schema_class->systemPossibleInferiors = const_str_list(str_list_make_empty(schema_class)); 233 } 234 schema_class->systemPossibleInferiors = str_list_add_const(schema_class->systemPossibleInferiors, 235 c2->lDAPDisplayName); 236 } 237 } 238 schema_class->systemPossibleInferiors = str_list_unique(schema_class->systemPossibleInferiors); 209 if (c2->objectClassCategory != 2 && 210 c2->objectClassCategory != 3 && 211 str_list_check(superiors, schema_class->lDAPDisplayName)) 212 { 213 if (c2->systemOnly == false) { 214 if (poss_inf == NULL) { 215 poss_inf = const_str_list(str_list_make_empty(schema_class)); 216 } 217 poss_inf = str_list_add_const(poss_inf, 218 c2->lDAPDisplayName); 219 } 220 if (sys_poss_inf == NULL) { 221 sys_poss_inf = const_str_list(str_list_make_empty(schema_class)); 222 } 223 sys_poss_inf = str_list_add_const(sys_poss_inf, 224 c2->lDAPDisplayName); 225 } 226 } 227 schema_class->systemPossibleInferiors = str_list_unique(sys_poss_inf); 228 schema_class->possibleInferiors = str_list_unique(poss_inf); 239 229 } 240 230 … … 330 320 struct dsdb_class *schema_class; 331 321 322 /* make sure we start with a clean cache */ 323 for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) { 324 ZERO_STRUCT(schema_class->tmp); 325 } 326 332 327 schema_fill_from_ids(schema); 333 328 … … 339 334 for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) { 340 335 schema_fill_possible_inferiors(schema, schema_class); 341 schema_fill_system_possible_inferiors(schema, schema_class);342 336 } 343 337 344 338 /* free up our internal cache elements */ 345 339 for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) { 346 talloc_free(schema_class->supclasses); 347 talloc_free(schema_class->subclasses_direct); 348 talloc_free(schema_class->subclasses); 349 talloc_free(schema_class->posssuperiors); 350 schema_class->supclasses = NULL; 351 schema_class->subclasses_direct = NULL; 352 schema_class->subclasses = NULL; 353 schema_class->posssuperiors = NULL; 340 TALLOC_FREE(schema_class->tmp.supclasses); 341 TALLOC_FREE(schema_class->tmp.subclasses_direct); 342 TALLOC_FREE(schema_class->tmp.subclasses); 343 TALLOC_FREE(schema_class->tmp.posssuperiors); 354 344 } 355 345 -
vendor/current/source4/dsdb/schema/schema_init.c
r740 r988 40 40 return NULL; 41 41 } 42 schema->refresh_interval = 120; 42 43 43 44 return schema; … … 56 57 if (!schema_copy) { 57 58 return NULL; 58 }59 60 /* schema base_dn */61 schema_copy->base_dn = ldb_dn_copy(schema_copy, schema->base_dn);62 if (!schema_copy->base_dn) {63 goto failed;64 59 } 65 60 … … 94 89 schema_copy->num_attributes = schema->num_attributes; 95 90 91 schema_copy->refresh_interval = schema->refresh_interval; 92 96 93 /* rebuild indexes */ 97 94 ret = dsdb_setup_sorted_accessors(ldb, schema_copy); … … 101 98 102 99 /* leave reload_seq_number = 0 so it will be refresh ASAP */ 103 schema_copy->refresh_fn = schema->refresh_fn;104 schema_copy->loaded_from_module = schema->loaded_from_module;105 100 106 101 return schema_copy; … … 459 454 unsigned int i; 460 455 for (i=0;attrs[i];i++) { 461 if ( strcasecmp(attr, attrs[i]) == 0) {456 if (ldb_attr_cmp(attr, attrs[i]) == 0) { 462 457 return true; 463 458 } … … 615 610 } while (0) 616 611 617 WERROR dsdb_attribute_from_ldb(struct ldb_context *ldb, 618 struct dsdb_schema *schema, 619 struct ldb_message *msg) 612 /** Create an dsdb_attribute out of ldb message, attr must be already talloced 613 */ 614 615 WERROR dsdb_attribute_from_ldb(const struct dsdb_schema *schema, 616 struct ldb_message *msg, 617 struct dsdb_attribute *attr) 620 618 { 621 619 WERROR status; 622 struct dsdb_attribute *attr = talloc_zero(schema, struct dsdb_attribute);623 if (!attr) {624 return WERR_ NOMEM;620 if (attr == NULL) { 621 DEBUG(0, ("%s: attr is null, it's expected not to be so\n", __location__)); 622 return WERR_INVALID_PARAM; 625 623 } 626 624 … … 691 689 GET_BOOL_LDB(msg, "systemOnly", attr, systemOnly, false); 692 690 691 return WERR_OK; 692 } 693 694 WERROR dsdb_set_attribute_from_ldb_dups(struct ldb_context *ldb, 695 struct dsdb_schema *schema, 696 struct ldb_message *msg, 697 bool checkdups) 698 { 699 WERROR status; 700 struct dsdb_attribute *attr = talloc_zero(schema, struct dsdb_attribute); 701 if (!attr) { 702 return WERR_NOMEM; 703 } 704 705 status = dsdb_attribute_from_ldb(schema, msg, attr); 706 if (!W_ERROR_IS_OK(status)) { 707 return status; 708 } 709 693 710 attr->syntax = dsdb_syntax_for_attribute(attr); 694 711 if (!attr->syntax) { … … 706 723 } 707 724 725 if (checkdups) { 726 const struct dsdb_attribute *a2; 727 struct dsdb_attribute **a; 728 uint32_t i; 729 730 a2 = dsdb_attribute_by_attributeID_id(schema, 731 attr->attributeID_id); 732 if (a2 == NULL) { 733 goto done; 734 } 735 736 i = schema->attributes_to_remove_size; 737 a = talloc_realloc(schema, schema->attributes_to_remove, 738 struct dsdb_attribute *, i + 1); 739 if (a == NULL) { 740 return WERR_NOMEM; 741 } 742 /* Mark the old attribute as to be removed */ 743 a[i] = discard_const_p(struct dsdb_attribute, a2); 744 schema->attributes_to_remove = a; 745 schema->attributes_to_remove_size++; 746 } 747 748 done: 708 749 DLIST_ADD(schema->attributes, attr); 709 750 return WERR_OK; 710 751 } 711 752 712 WERROR dsdb_class_from_ldb(struct dsdb_schema *schema, 713 struct ldb_message *msg) 753 WERROR dsdb_set_attribute_from_ldb(struct ldb_context *ldb, 754 struct dsdb_schema *schema, 755 struct ldb_message *msg) 756 { 757 return dsdb_set_attribute_from_ldb_dups(ldb, schema, msg, false); 758 } 759 760 WERROR dsdb_set_class_from_ldb_dups(struct dsdb_schema *schema, 761 struct ldb_message *msg, 762 bool checkdups) 714 763 { 715 764 WERROR status; … … 758 807 759 808 GET_UINT32_LDB(msg, "schemaFlagsEx", obj, schemaFlagsEx); 809 GET_UINT32_LDB(msg, "systemFlags", obj, systemFlags); 760 810 GET_BLOB_LDB(msg, "msDs-Schema-Extensions", obj, obj, msDs_Schema_Extensions); 761 811 … … 768 818 GET_BOOL_LDB(msg, "systemOnly", obj, systemOnly, false); 769 819 820 if (checkdups) { 821 const struct dsdb_class *c2; 822 struct dsdb_class **c; 823 uint32_t i; 824 825 c2 = dsdb_class_by_governsID_id(schema, obj->governsID_id); 826 if (c2 == NULL) { 827 goto done; 828 } 829 830 i = schema->classes_to_remove_size; 831 c = talloc_realloc(schema, schema->classes_to_remove, 832 struct dsdb_class *, i + 1); 833 if (c == NULL) { 834 return WERR_NOMEM; 835 } 836 /* Mark the old class to be removed */ 837 c[i] = discard_const_p(struct dsdb_class, c2); 838 schema->classes_to_remove = c; 839 schema->classes_to_remove_size++; 840 } 841 842 done: 770 843 DLIST_ADD(schema->classes, obj); 771 844 return WERR_OK; 772 845 } 773 846 847 WERROR dsdb_set_class_from_ldb(struct dsdb_schema *schema, 848 struct ldb_message *msg) 849 { 850 return dsdb_set_class_from_ldb_dups(schema, msg, false); 851 } 852 774 853 #define dsdb_oom(error_string, mem_ctx) *error_string = talloc_asprintf(mem_ctx, "dsdb out of memory at %s:%d\n", __FILE__, __LINE__) 775 854 776 855 /* 856 Fill a DSDB schema from the ldb results provided. This is called 857 directly when a schema must be created with a pre-initialised prefixMap 858 */ 859 860 int dsdb_load_ldb_results_into_schema(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 861 struct dsdb_schema *schema, 862 struct ldb_result *attrs_class_res, 863 char **error_string) 864 { 865 unsigned int i; 866 867 schema->ts_last_change = 0; 868 for (i=0; i < attrs_class_res->count; i++) { 869 WERROR status = dsdb_schema_set_el_from_ldb_msg(ldb, schema, attrs_class_res->msgs[i]); 870 if (!W_ERROR_IS_OK(status)) { 871 *error_string = talloc_asprintf(mem_ctx, 872 "dsdb_load_ldb_results_into_schema: failed to load attribute or class definition: %s:%s", 873 ldb_dn_get_linearized(attrs_class_res->msgs[i]->dn), 874 win_errstr(status)); 875 DEBUG(0,(__location__ ": %s\n", *error_string)); 876 return LDB_ERR_CONSTRAINT_VIOLATION; 877 } 878 } 879 880 return LDB_SUCCESS; 881 } 882 883 /* 777 884 Create a DSDB schema from the ldb results provided. This is called 778 885 directly when the schema is provisioned from an on-disk LDIF file, or … … 782 889 int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 783 890 struct ldb_result *schema_res, 784 struct ldb_result *attrs_ res, struct ldb_result *objectclass_res,891 struct ldb_result *attrs_class_res, 785 892 struct dsdb_schema **schema_out, 786 893 char **error_string) 787 894 { 788 895 WERROR status; 789 unsigned int i;790 896 const struct ldb_val *prefix_val; 791 897 const struct ldb_val *info_val; 792 898 struct ldb_val info_val_default; 793 899 struct dsdb_schema *schema; 794 795 schema = dsdb_new_schema(mem_ctx); 900 void *lp_opaque = ldb_get_opaque(ldb, "loadparm"); 901 int ret; 902 903 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 904 if (!tmp_ctx) { 905 dsdb_oom(error_string, mem_ctx); 906 return ldb_operr(ldb); 907 } 908 909 schema = dsdb_new_schema(tmp_ctx); 796 910 if (!schema) { 797 911 dsdb_oom(error_string, mem_ctx); 912 talloc_free(tmp_ctx); 798 913 return ldb_operr(ldb); 799 914 } 800 915 801 schema->base_dn = talloc_steal(schema, schema_res->msgs[0]->dn); 916 if (lp_opaque) { 917 struct loadparm_context *lp_ctx = talloc_get_type_abort(lp_opaque, struct loadparm_context); 918 schema->refresh_interval = lpcfg_parm_int(lp_ctx, NULL, "dsdb", "schema_reload_interval", schema->refresh_interval); 919 lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), 920 struct loadparm_context); 921 schema->fsmo.update_allowed = lpcfg_parm_bool(lp_ctx, NULL, 922 "dsdb", "schema update allowed", 923 false); 924 } 802 925 803 926 prefix_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "prefixMap"); … … 806 929 "schema_fsmo_init: no prefixMap attribute found"); 807 930 DEBUG(0,(__location__ ": %s\n", *error_string)); 931 talloc_free(tmp_ctx); 808 932 return LDB_ERR_CONSTRAINT_VIOLATION; 809 933 } … … 816 940 win_errstr(status)); 817 941 DEBUG(0,(__location__ ": %s\n", *error_string)); 942 talloc_free(tmp_ctx); 818 943 return ldb_operr(ldb); 819 944 } … … 827 952 win_errstr(status)); 828 953 DEBUG(0,(__location__ ": %s\n", *error_string)); 954 talloc_free(tmp_ctx); 829 955 return LDB_ERR_CONSTRAINT_VIOLATION; 830 956 } 831 957 832 for (i=0; i < attrs_res->count; i++) { 833 status = dsdb_attribute_from_ldb(ldb, schema, attrs_res->msgs[i]); 834 if (!W_ERROR_IS_OK(status)) { 835 *error_string = talloc_asprintf(mem_ctx, 836 "schema_fsmo_init: failed to load attribute definition: %s:%s", 837 ldb_dn_get_linearized(attrs_res->msgs[i]->dn), 838 win_errstr(status)); 839 DEBUG(0,(__location__ ": %s\n", *error_string)); 840 return LDB_ERR_CONSTRAINT_VIOLATION; 841 } 842 } 843 844 for (i=0; i < objectclass_res->count; i++) { 845 status = dsdb_class_from_ldb(schema, objectclass_res->msgs[i]); 846 if (!W_ERROR_IS_OK(status)) { 847 *error_string = talloc_asprintf(mem_ctx, 848 "schema_fsmo_init: failed to load class definition: %s:%s", 849 ldb_dn_get_linearized(objectclass_res->msgs[i]->dn), 850 win_errstr(status)); 851 DEBUG(0,(__location__ ": %s\n", *error_string)); 852 return LDB_ERR_CONSTRAINT_VIOLATION; 853 } 958 ret = dsdb_load_ldb_results_into_schema(mem_ctx, ldb, schema, attrs_class_res, error_string); 959 if (ret != LDB_SUCCESS) { 960 talloc_free(tmp_ctx); 961 return ret; 854 962 } 855 963 856 964 schema->fsmo.master_dn = ldb_msg_find_attr_as_dn(ldb, schema, schema_res->msgs[0], "fSMORoleOwner"); 857 if (ldb_dn_compare(samdb_ntds_settings_dn(ldb ), schema->fsmo.master_dn) == 0) {965 if (ldb_dn_compare(samdb_ntds_settings_dn(ldb, tmp_ctx), schema->fsmo.master_dn) == 0) { 858 966 schema->fsmo.we_are_master = true; 859 967 } else { … … 861 969 } 862 970 863 DEBUG(5, ("schema_fsmo_init: we are master: %s\n", 864 (schema->fsmo.we_are_master?"yes":"no"))); 865 866 *schema_out = schema; 971 DEBUG(5, ("schema_fsmo_init: we are master[%s] updates allowed[%s]\n", 972 (schema->fsmo.we_are_master?"yes":"no"), 973 (schema->fsmo.update_allowed?"yes":"no"))); 974 975 *schema_out = talloc_steal(mem_ctx, schema); 976 talloc_free(tmp_ctx); 867 977 return LDB_SUCCESS; 868 978 } -
vendor/current/source4/dsdb/schema/schema_prefixmap.c
r740 r988 156 156 157 157 /* dup memory for bin-oid prefix to be added */ 158 bin_oid = data_blob_dup_talloc(pfm, &bin_oid);158 bin_oid = data_blob_dup_talloc(pfm, bin_oid); 159 159 W_ERROR_HAVE_NO_MEMORY(bin_oid.data); 160 160 … … 312 312 /* return error in read-only mode */ 313 313 if (!can_change_pfm) { 314 DEBUG(0, ("Unable to convert %s to an attid, and can_change_pfm=false!\n", oid)); 314 315 return werr; 315 316 } … … 616 617 /* copy entries from schema_prefixMap */ 617 618 for (i = 0; i < pfm->length; i++) { 618 blob = data_blob_dup_talloc(ctr, &pfm->prefixes[i].bin_oid);619 blob = data_blob_dup_talloc(ctr, pfm->prefixes[i].bin_oid); 619 620 if (!blob.data) { 620 621 talloc_free(ctr); -
vendor/current/source4/dsdb/schema/schema_query.c
r740 r988 23 23 #include "includes.h" 24 24 #include "dsdb/samdb/samdb.h" 25 #include <ldb_module.h> 25 26 #include "lib/util/binsearch.h" 26 27 #include "lib/util/tsort.h" 28 #include "util/dlinklist.h" 27 29 28 30 static const char **dsdb_full_attribute_list_internal(TALLOC_CTX *mem_ctx, … … 329 331 } 330 332 331 /* Return a full attribute list for a given class list (as a ldb_message_element)333 /* Return a full attribute list for a given class list 332 334 333 335 Via attribute_list_from_class() this calls itself when recursing on auxiliary classes … … 444 446 return &attr->schemaIDGUID; 445 447 } 448 449 /* 450 * Sort a "objectClass" attribute (LDB message element "objectclass_element") 451 * into correct order and validate that all object classes specified actually 452 * exist in the schema. 453 * The output is written in an existing LDB message element 454 * "out_objectclass_element" where the values will be allocated on "mem_ctx". 455 */ 456 int dsdb_sort_objectClass_attr(struct ldb_context *ldb, 457 const struct dsdb_schema *schema, 458 const struct ldb_message_element *objectclass_element, 459 TALLOC_CTX *mem_ctx, 460 struct ldb_message_element *out_objectclass_element) 461 { 462 unsigned int i, lowest; 463 struct class_list { 464 struct class_list *prev, *next; 465 const struct dsdb_class *objectclass; 466 } *unsorted = NULL, *sorted = NULL, *current = NULL, 467 *poss_parent = NULL, *new_parent = NULL, 468 *current_lowest = NULL, *current_lowest_struct = NULL; 469 struct ldb_message_element *el; 470 TALLOC_CTX *tmp_mem_ctx; 471 472 tmp_mem_ctx = talloc_new(mem_ctx); 473 if (tmp_mem_ctx == NULL) { 474 return ldb_oom(ldb); 475 } 476 477 /* 478 * DESIGN: 479 * 480 * We work on 4 different 'bins' (implemented here as linked lists): 481 * 482 * * sorted: the eventual list, in the order we wish to push 483 * into the database. This is the only ordered list. 484 * 485 * * parent_class: The current parent class 'bin' we are 486 * trying to find subclasses for 487 * 488 * * subclass: The subclasses we have found so far 489 * 490 * * unsorted: The remaining objectClasses 491 * 492 * The process is a matter of filtering objectClasses up from 493 * unsorted into sorted. Order is irrelevent in the later 3 'bins'. 494 * 495 * We start with 'top' (found and promoted to parent_class 496 * initially). Then we find (in unsorted) all the direct 497 * subclasses of 'top'. parent_classes is concatenated onto 498 * the end of 'sorted', and subclass becomes the list in 499 * parent_class. 500 * 501 * We then repeat, until we find no more subclasses. Any left 502 * over classes are added to the end. 503 * 504 */ 505 506 /* 507 * Firstly, dump all the "objectClass" values into the unsorted bin, 508 * except for 'top', which is special 509 */ 510 for (i=0; i < objectclass_element->num_values; i++) { 511 current = talloc(tmp_mem_ctx, struct class_list); 512 if (!current) { 513 talloc_free(tmp_mem_ctx); 514 return ldb_oom(ldb); 515 } 516 current->objectclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &objectclass_element->values[i]); 517 if (!current->objectclass) { 518 ldb_asprintf_errstring(ldb, "objectclass %.*s is not a valid objectClass in schema", 519 (int)objectclass_element->values[i].length, (const char *)objectclass_element->values[i].data); 520 /* This looks weird, but windows apparently returns this for invalid objectClass values */ 521 talloc_free(tmp_mem_ctx); 522 return LDB_ERR_NO_SUCH_ATTRIBUTE; 523 } else if (current->objectclass->isDefunct) { 524 ldb_asprintf_errstring(ldb, "objectclass %.*s marked as isDefunct objectClass in schema - not valid for new objects", 525 (int)objectclass_element->values[i].length, (const char *)objectclass_element->values[i].data); 526 /* This looks weird, but windows apparently returns this for invalid objectClass values */ 527 talloc_free(tmp_mem_ctx); 528 return LDB_ERR_NO_SUCH_ATTRIBUTE; 529 } 530 531 /* Don't add top to list, we will do that later */ 532 if (ldb_attr_cmp("top", current->objectclass->lDAPDisplayName) != 0) { 533 DLIST_ADD_END(unsorted, current); 534 } 535 } 536 537 538 /* Add top here, to prevent duplicates */ 539 current = talloc(tmp_mem_ctx, struct class_list); 540 current->objectclass = dsdb_class_by_lDAPDisplayName(schema, "top"); 541 DLIST_ADD_END(sorted, current); 542 543 /* For each object: find parent chain */ 544 for (current = unsorted; current != NULL; current = current->next) { 545 for (poss_parent = unsorted; poss_parent; poss_parent = poss_parent->next) { 546 if (ldb_attr_cmp(poss_parent->objectclass->lDAPDisplayName, current->objectclass->subClassOf) == 0) { 547 break; 548 } 549 } 550 /* If we didn't get to the end of the list, we need to add this parent */ 551 if (poss_parent || (ldb_attr_cmp("top", current->objectclass->subClassOf) == 0)) { 552 continue; 553 } 554 555 new_parent = talloc(tmp_mem_ctx, struct class_list); 556 new_parent->objectclass = dsdb_class_by_lDAPDisplayName(schema, current->objectclass->subClassOf); 557 DLIST_ADD_END(unsorted, new_parent); 558 } 559 560 /* For each object: order by hierarchy */ 561 while (unsorted != NULL) { 562 lowest = UINT_MAX; 563 current_lowest = current_lowest_struct = NULL; 564 for (current = unsorted; current != NULL; current = current->next) { 565 if (current->objectclass->subClass_order <= lowest) { 566 /* 567 * According to MS-ADTS 3.1.1.1.4 structural 568 * and 88 object classes are always listed after 569 * the other class types in a subclass hierarchy 570 */ 571 if (current->objectclass->objectClassCategory > 1) { 572 current_lowest = current; 573 } else { 574 current_lowest_struct = current; 575 } 576 lowest = current->objectclass->subClass_order; 577 } 578 } 579 if (current_lowest == NULL) { 580 current_lowest = current_lowest_struct; 581 } 582 583 if (current_lowest != NULL) { 584 DLIST_REMOVE(unsorted,current_lowest); 585 DLIST_ADD_END(sorted,current_lowest); 586 } 587 } 588 589 /* Now rebuild the sorted "objectClass" message element */ 590 el = out_objectclass_element; 591 592 el->flags = objectclass_element->flags; 593 el->name = talloc_strdup(mem_ctx, objectclass_element->name); 594 if (el->name == NULL) { 595 talloc_free(tmp_mem_ctx); 596 return ldb_oom(ldb); 597 } 598 el->num_values = 0; 599 el->values = NULL; 600 for (current = sorted; current != NULL; current = current->next) { 601 el->values = talloc_realloc(mem_ctx, el->values, 602 struct ldb_val, el->num_values + 1); 603 if (el->values == NULL) { 604 talloc_free(tmp_mem_ctx); 605 return ldb_oom(ldb); 606 } 607 el->values[el->num_values] = data_blob_string_const(current->objectclass->lDAPDisplayName); 608 609 ++(el->num_values); 610 } 611 612 talloc_free(tmp_mem_ctx); 613 return LDB_SUCCESS; 614 } -
vendor/current/source4/dsdb/schema/schema_set.c
r740 r988 5 5 Copyright (C) Stefan Metzmacher <metze@samba.org> 2006-2007 6 6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2008 7 Copyright (C) Matthieu Patou <mat@matws.net> 2011 7 8 8 9 This program is free software; you can redistribute it and/or modify … … 30 31 #include "lib/util/tsort.h" 31 32 33 /* change this when we change something in our schema code that 34 * requires a re-index of the database 35 */ 36 #define SAMDB_INDEXING_VERSION "2" 37 32 38 /* 33 39 override the name to attribute handler function … … 45 51 return a->ldb_schema_attribute; 46 52 } 47 48 static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schema *schema, bool write_attributes) 53 /* 54 * Set the attribute handlers onto the LDB, and potentially write the 55 * @INDEXLIST, @IDXONE and @ATTRIBUTES records. The @ATTRIBUTES records 56 * are required so we can operate on a schema-less database (say the 57 * backend during emergency fixes) and during the schema load. 58 */ 59 static int dsdb_schema_set_indices_and_attributes(struct ldb_context *ldb, struct dsdb_schema *schema, bool write_indices_and_attributes) 49 60 { 50 61 int ret = LDB_SUCCESS; … … 60 71 ldb_schema_attribute_set_override_handler(ldb, dsdb_attribute_handler_override, schema); 61 72 62 if (!write_ attributes) {73 if (!write_indices_and_attributes) { 63 74 return ret; 64 75 } … … 91 102 92 103 ret = ldb_msg_add_string(msg_idx, "@IDXONE", "1"); 104 if (ret != LDB_SUCCESS) { 105 goto op_error; 106 } 107 108 109 ret = ldb_msg_add_string(msg_idx, "@IDXVERSION", SAMDB_INDEXING_VERSION); 93 110 if (ret != LDB_SUCCESS) { 94 111 goto op_error; … … 200 217 } 201 218 219 220 /* 221 create extra attribute shortcuts 222 */ 223 static void dsdb_setup_attribute_shortcuts(struct ldb_context *ldb, struct dsdb_schema *schema) 224 { 225 struct dsdb_attribute *attribute; 226 227 /* setup fast access to one_way_link and DN format */ 228 for (attribute=schema->attributes; attribute; attribute=attribute->next) { 229 attribute->dn_format = dsdb_dn_oid_to_format(attribute->syntax->ldap_oid); 230 231 if (attribute->dn_format == DSDB_INVALID_DN) { 232 attribute->one_way_link = false; 233 continue; 234 } 235 236 /* these are not considered to be one way links for 237 the purpose of DN link fixups */ 238 if (ldb_attr_cmp("distinguishedName", attribute->lDAPDisplayName) == 0 || 239 ldb_attr_cmp("objectCategory", attribute->lDAPDisplayName) == 0) { 240 attribute->one_way_link = false; 241 continue; 242 } 243 244 if (attribute->linkID == 0) { 245 attribute->one_way_link = true; 246 continue; 247 } 248 /* handle attributes with a linkID but no backlink */ 249 if ((attribute->linkID & 1) == 0 && 250 dsdb_attribute_by_linkID(schema, attribute->linkID + 1) == NULL) { 251 attribute->one_way_link = true; 252 continue; 253 } 254 attribute->one_way_link = false; 255 } 256 } 257 202 258 static int uint32_cmp(uint32_t c1, uint32_t c2) 203 259 { … … 272 328 unsigned int i; 273 329 unsigned int num_int_id; 330 int ret; 331 332 for (i=0; i < schema->classes_to_remove_size; i++) { 333 DLIST_REMOVE(schema->classes, schema->classes_to_remove[i]); 334 TALLOC_FREE(schema->classes_to_remove[i]); 335 } 336 for (i=0; i < schema->attributes_to_remove_size; i++) { 337 DLIST_REMOVE(schema->attributes, schema->attributes_to_remove[i]); 338 TALLOC_FREE(schema->attributes_to_remove[i]); 339 } 340 341 TALLOC_FREE(schema->classes_to_remove); 342 schema->classes_to_remove_size = 0; 343 TALLOC_FREE(schema->attributes_to_remove); 344 schema->attributes_to_remove_size = 0; 274 345 275 346 /* free all caches */ … … 354 425 TYPESAFE_QSORT(schema->attributes_by_linkID, schema->num_attributes, dsdb_compare_attribute_by_linkID); 355 426 427 dsdb_setup_attribute_shortcuts(ldb, schema); 428 429 ret = schema_fill_constructed(schema); 430 if (ret != LDB_SUCCESS) { 431 dsdb_sorted_accessors_free(schema); 432 return ret; 433 } 434 356 435 return LDB_SUCCESS; 357 436 … … 361 440 } 362 441 363 int dsdb_setup_schema_inversion(struct ldb_context *ldb, struct dsdb_schema *schema)364 {365 /* Walk the list of schema classes */366 367 /* For each subClassOf, add us to subclasses of the parent */368 369 /* collect these subclasses into a recursive list of total subclasses, preserving order */370 371 /* For each subclass under 'top', write the index from it's372 * order as an integer in the dsdb_class (for sorting373 * objectClass lists efficiently) */374 375 /* Walk the list of schema classes */376 377 /* Create a 'total possible superiors' on each class */378 return LDB_SUCCESS;379 }380 381 442 /** 382 443 * Attach the schema to an opaque pointer on the ldb, 383 444 * so ldb modules can find it 384 445 */ 446 int dsdb_set_schema_refresh_function(struct ldb_context *ldb, 447 dsdb_schema_refresh_fn refresh_fn, 448 struct ldb_module *module) 449 { 450 int ret = ldb_set_opaque(ldb, "dsdb_schema_refresh_fn", refresh_fn); 451 if (ret != LDB_SUCCESS) { 452 return ret; 453 } 454 455 ret = ldb_set_opaque(ldb, "dsdb_schema_refresh_fn_private_data", module); 456 if (ret != LDB_SUCCESS) { 457 return ret; 458 } 459 return LDB_SUCCESS; 460 } 461 462 /** 463 * Attach the schema to an opaque pointer on the ldb, 464 * so ldb modules can find it 465 */ 385 466 int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema) 386 467 { … … 389 470 390 471 ret = dsdb_setup_sorted_accessors(ldb, schema); 391 if (ret != LDB_SUCCESS) {392 return ret;393 }394 395 ret = schema_fill_constructed(schema);396 472 if (ret != LDB_SUCCESS) { 397 473 return ret; … … 412 488 } 413 489 490 talloc_steal(ldb, schema); 491 414 492 ret = ldb_set_opaque(ldb, "dsdb_use_global_schema", NULL); 415 493 if (ret != LDB_SUCCESS) { … … 418 496 419 497 /* Set the new attributes based on the new schema */ 420 ret = dsdb_schema_set_ attributes(ldb, schema, true);498 ret = dsdb_schema_set_indices_and_attributes(ldb, schema, true); 421 499 if (ret != LDB_SUCCESS) { 422 500 return ret; … … 433 511 /** 434 512 * Make this ldb use a specified schema, already fully calculated and belonging to another ldb 513 * 514 * The write_indices_and_attributes controls writing of the @ records 515 * because we cannot write to a database that does not yet exist on 516 * disk. 435 517 */ 436 518 int dsdb_reference_schema(struct ldb_context *ldb, struct dsdb_schema *schema, 437 bool write_ attributes)519 bool write_indices_and_attributes) 438 520 { 439 521 int ret; … … 459 541 } 460 542 461 ret = dsdb_schema_set_attributes(ldb, schema, write_attributes); 543 ret = ldb_set_opaque(ldb, "dsdb_refresh_fn", NULL); 544 if (ret != LDB_SUCCESS) { 545 return ret; 546 } 547 548 ret = ldb_set_opaque(ldb, "dsdb_refresh_fn_private_data", NULL); 549 if (ret != LDB_SUCCESS) { 550 return ret; 551 } 552 553 ret = dsdb_schema_set_indices_and_attributes(ldb, schema, write_indices_and_attributes); 462 554 if (ret != LDB_SUCCESS) { 463 555 return ret; … … 474 566 int ret; 475 567 void *use_global_schema = (void *)1; 476 if (!global_schema) { 568 ret = ldb_set_opaque(ldb, "dsdb_use_global_schema", use_global_schema); 569 if (ret != LDB_SUCCESS) { 570 return ret; 571 } 572 573 if (global_schema == NULL) { 477 574 return LDB_SUCCESS; 478 575 } 479 ret = ldb_set_opaque(ldb, "dsdb_use_global_schema", use_global_schema);480 if (ret != LDB_SUCCESS) {481 return ret;482 }483 576 484 577 /* Set the new attributes based on the new schema */ 485 ret = dsdb_schema_set_ attributes(ldb, global_schema, false /* Don't writeattributes, it's expensive */);578 ret = dsdb_schema_set_indices_and_attributes(ldb, global_schema, false /* Don't write indices and attributes, it's expensive */); 486 579 if (ret == LDB_SUCCESS) { 487 580 /* Keep a reference to this schema, just in case the original copy is replaced */ … … 508 601 { 509 602 const void *p; 510 struct dsdb_schema *schema_out; 511 struct dsdb_schema *schema_in; 603 struct dsdb_schema *schema_out = NULL; 604 struct dsdb_schema *schema_in = NULL; 605 dsdb_schema_refresh_fn refresh_fn; 606 struct ldb_module *loaded_from_module; 512 607 bool use_global_schema; 513 608 TALLOC_CTX *tmp_ctx = talloc_new(reference_ctx); 514 if ( !tmp_ctx) {609 if (tmp_ctx == NULL) { 515 610 return NULL; 516 611 } … … 522 617 } else { 523 618 p = ldb_get_opaque(ldb, "dsdb_schema"); 524 525 schema_in = talloc_get_type(p, struct dsdb_schema); 526 if (!schema_in) { 527 talloc_free(tmp_ctx); 528 return NULL; 529 } 530 } 531 532 if (schema_in->refresh_fn && !schema_in->refresh_in_progress) { 533 if (!talloc_reference(tmp_ctx, schema_in)) { 534 /* 535 * ensure that the schema_in->refresh_in_progress 536 * remains valid for the right amount of time 537 */ 538 talloc_free(tmp_ctx); 539 return NULL; 540 } 541 schema_in->refresh_in_progress = true; 542 /* This may change schema, if it needs to reload it from disk */ 543 schema_out = schema_in->refresh_fn(schema_in->loaded_from_module, 544 schema_in, 545 use_global_schema); 546 schema_in->refresh_in_progress = false; 619 if (p != NULL) { 620 schema_in = talloc_get_type_abort(p, struct dsdb_schema); 621 } 622 } 623 624 refresh_fn = ldb_get_opaque(ldb, "dsdb_schema_refresh_fn"); 625 if (refresh_fn) { 626 loaded_from_module = ldb_get_opaque(ldb, "dsdb_schema_refresh_fn_private_data"); 627 628 SMB_ASSERT(loaded_from_module && (ldb_module_get_ctx(loaded_from_module) == ldb)); 629 } 630 631 if (refresh_fn) { 632 /* We need to guard against recurisve calls here */ 633 if (ldb_set_opaque(ldb, "dsdb_schema_refresh_fn", NULL) != LDB_SUCCESS) { 634 ldb_debug_set(ldb, LDB_DEBUG_FATAL, 635 "dsdb_get_schema: clearing dsdb_schema_refresh_fn failed"); 636 } else { 637 schema_out = refresh_fn(loaded_from_module, 638 ldb_get_event_context(ldb), 639 schema_in, 640 use_global_schema); 641 } 642 if (ldb_set_opaque(ldb, "dsdb_schema_refresh_fn", refresh_fn) != LDB_SUCCESS) { 643 ldb_debug_set(ldb, LDB_DEBUG_FATAL, 644 "dsdb_get_schema: re-setting dsdb_schema_refresh_fn failed"); 645 } 646 if (!schema_out) { 647 schema_out = schema_in; 648 ldb_debug_set(ldb, LDB_DEBUG_FATAL, 649 "dsdb_get_schema: refresh_fn() failed"); 650 } 547 651 } else { 548 652 schema_out = schema_in; … … 624 728 625 729 /** 626 * Add an element to the schema (attribute or class) from an LDB message 627 */ 628 WERROR dsdb_schema_set_el_from_ldb_msg(struct ldb_context *ldb, struct dsdb_schema *schema, 629 struct ldb_message *msg) 630 { 730 * @brief Add a new element to the schema and checks if it's a duplicate 731 * 732 * This function will add a new element to the schema and checks for existing 733 * duplicates. 734 * 735 * @param[in] ldb A pointer to an LDB context 736 * 737 * @param[in] schema A pointer to the dsdb_schema where the element 738 * will be added. 739 * 740 * @param[in] msg The ldb_message object representing the element 741 * to add. 742 * 743 * @param[in] checkdups A boolean to indicate if checks for duplicates 744 * should be done. 745 * 746 * @return A WERROR code 747 */ 748 WERROR dsdb_schema_set_el_from_ldb_msg_dups(struct ldb_context *ldb, struct dsdb_schema *schema, 749 struct ldb_message *msg, bool checkdups) 750 { 751 const char* tstring; 752 time_t ts; 753 tstring = ldb_msg_find_attr_as_string(msg, "whenChanged", NULL); 754 /* keep a trace of the ts of the most recently changed object */ 755 if (tstring) { 756 ts = ldb_string_to_time(tstring); 757 if (ts > schema->ts_last_change) { 758 schema->ts_last_change = ts; 759 } 760 } 631 761 if (samdb_find_attribute(ldb, msg, 632 762 "objectclass", "attributeSchema") != NULL) { 633 return dsdb_attribute_from_ldb(ldb, schema, msg); 763 764 return dsdb_set_attribute_from_ldb_dups(ldb, schema, msg, checkdups); 634 765 } else if (samdb_find_attribute(ldb, msg, 635 766 "objectclass", "classSchema") != NULL) { 636 return dsdb_class_from_ldb(schema, msg); 637 } 638 767 return dsdb_set_class_from_ldb_dups(schema, msg, checkdups); 768 } 639 769 /* Don't fail on things not classes or attributes */ 640 770 return WERR_OK; 771 } 772 773 WERROR dsdb_schema_set_el_from_ldb_msg(struct ldb_context *ldb, 774 struct dsdb_schema *schema, 775 struct ldb_message *msg) 776 { 777 return dsdb_schema_set_el_from_ldb_msg_dups(ldb, schema, msg, false); 641 778 } 642 779 … … 647 784 */ 648 785 649 WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const char *df) 786 WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, 787 const char *pf, const char *df, 788 const char *dn) 650 789 { 651 790 struct ldb_ldif *ldif; … … 666 805 667 806 schema = dsdb_new_schema(mem_ctx); 668 807 if (!schema) { 808 goto nomem; 809 } 669 810 schema->fsmo.we_are_master = true; 670 schema->fsmo.master_dn = ldb_dn_new_fmt(schema, ldb, "@PROVISION_SCHEMA_MASTER"); 811 schema->fsmo.update_allowed = true; 812 schema->fsmo.master_dn = ldb_dn_new(schema, ldb, "@PROVISION_SCHEMA_MASTER"); 671 813 if (!schema->fsmo.master_dn) { 672 814 goto nomem; … … 708 850 } 709 851 852 schema->ts_last_change = 0; 710 853 /* load the attribute and class definitions out of df */ 711 854 while ((ldif = ldb_ldif_read_string(ldb, &df))) { -
vendor/current/source4/dsdb/schema/schema_syntax.c
r740 r988 210 210 211 211 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 212 return WERR_ FOOBAR;212 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 213 213 } 214 214 … … 230 230 W_ERROR_HAVE_NO_MEMORY(blobs[i].data); 231 231 232 if (strcmp("TRUE", (const char *)in->values[i].data) == 0) { 232 if (in->values[i].length >= 4 && 233 strncmp("TRUE", (const char *)in->values[i].data, in->values[i].length) == 0) { 233 234 SIVAL(blobs[i].data, 0, 0x00000001); 234 } else if (strcmp("FALSE", (const char *)in->values[i].data) == 0) { 235 } else if (in->values[i].length >= 5 && 236 strncmp("FALSE", (const char *)in->values[i].data, in->values[i].length) == 0) { 235 237 SIVAL(blobs[i].data, 0, 0x00000000); 236 238 } else { … … 249 251 250 252 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 251 return WERR_ FOOBAR;253 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 252 254 } 253 255 254 256 for (i=0; i < in->num_values; i++) { 255 int t, f; 256 257 t = strncmp("TRUE", 257 if (in->values[i].length == 0) { 258 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 259 } 260 261 if (in->values[i].length >= 4 && 262 strncmp("TRUE", 258 263 (const char *)in->values[i].data, 259 in->values[i].length); 260 f = strncmp("FALSE", 264 in->values[i].length) == 0) { 265 continue; 266 } 267 if (in->values[i].length >= 5 && 268 strncmp("FALSE", 261 269 (const char *)in->values[i].data, 262 in->values[i].length); 263 264 if (t != 0 && f != 0) { 265 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 266 } 270 in->values[i].length) == 0) { 271 continue; 272 } 273 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 267 274 } 268 275 … … 319 326 320 327 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 321 return WERR_ FOOBAR;328 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 322 329 } 323 330 … … 358 365 359 366 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 360 return WERR_ FOOBAR;367 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 361 368 } 362 369 … … 446 453 447 454 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 448 return WERR_ FOOBAR;455 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 449 456 } 450 457 … … 483 490 484 491 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 485 return WERR_ FOOBAR;492 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 486 493 } 487 494 … … 551 558 552 559 v = BVAL(in->value_ctr.values[i].blob->data, 0); 560 if (v == 0) { 561 /* special case for 1601 zero timestamp */ 562 out->values[i] = data_blob_string_const("16010101000000.0Z"); 563 continue; 564 } 553 565 v *= 10000000; 554 566 t = nt_time_to_unix(v); … … 581 593 582 594 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 583 return WERR_ FOOBAR;595 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 584 596 } 585 597 … … 604 616 W_ERROR_HAVE_NO_MEMORY(blobs[i].data); 605 617 618 if (ldb_val_string_cmp(&in->values[i], "16010101000000.0Z") == 0) { 619 SBVALS(blobs[i].data, 0, 0); 620 continue; 621 } 622 606 623 t = ldb_string_utc_to_time((const char *)in->values[i].data); 607 624 unix_to_nt_time(&v, t); … … 621 638 622 639 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 623 return WERR_ FOOBAR;640 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 624 641 } 625 642 … … 634 651 memcpy(buf, in->values[i].data, in->values[i].length); 635 652 636 errno = 0;637 653 t = ldb_string_utc_to_time(buf); 638 if ( errno != 0) {654 if (t == 0) { 639 655 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 640 656 } … … 691 707 692 708 v = BVAL(in->value_ctr.values[i].blob->data, 0); 709 if (v == 0) { 710 /* special case for 1601 zero timestamp */ 711 out->values[i] = data_blob_string_const("16010101000000.0Z"); 712 continue; 713 } 693 714 v *= 10000000; 694 715 t = nt_time_to_unix(v); … … 713 734 714 735 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 715 return WERR_ FOOBAR;736 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 716 737 } 717 738 … … 737 758 W_ERROR_HAVE_NO_MEMORY(blobs[i].data); 738 759 760 if (ldb_val_string_cmp(&in->values[i], "16010101000000.0Z") == 0) { 761 SBVALS(blobs[i].data, 0, 0); 762 continue; 763 } 764 739 765 ret = ldb_val_to_time(&in->values[i], &t); 740 766 if (ret != LDB_SUCCESS) { … … 757 783 758 784 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 759 return WERR_ FOOBAR;785 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 760 786 } 761 787 … … 776 802 777 803 if (attr->rangeUpper) { 778 if ((int32_t)t > (int32_t)*attr->range Lower) {804 if ((int32_t)t > (int32_t)*attr->rangeUpper) { 779 805 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 780 806 } … … 811 837 812 838 out->values[i] = data_blob_dup_talloc(out->values, 813 in->value_ctr.values[i].blob);839 *in->value_ctr.values[i].blob); 814 840 W_ERROR_HAVE_NO_MEMORY(out->values[i].data); 815 841 } … … 828 854 829 855 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 830 return WERR_ FOOBAR;856 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 831 857 } 832 858 … … 845 871 out->value_ctr.values[i].blob = &blobs[i]; 846 872 847 blobs[i] = data_blob_dup_talloc(blobs, &in->values[i]);873 blobs[i] = data_blob_dup_talloc(blobs, in->values[i]); 848 874 W_ERROR_HAVE_NO_MEMORY(blobs[i].data); 849 875 } … … 857 883 { 858 884 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 859 return WERR_ FOOBAR;885 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 860 886 } 861 887 … … 883 909 884 910 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 885 return WERR_ FOOBAR;911 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 886 912 } 887 913 … … 1029 1055 1030 1056 if (in->value_ctr.values[i].blob == NULL) { 1057 DEBUG(0, ("Attribute has no value\n")); 1031 1058 return WERR_FOOBAR; 1032 1059 } 1033 1060 1034 1061 if (in->value_ctr.values[i].blob->length != 4) { 1062 DEBUG(0, ("Attribute has a value with 0 length\n")); 1035 1063 return WERR_FOOBAR; 1036 1064 } … … 1067 1095 { 1068 1096 unsigned int i; 1069 1070 SMB_ASSERT(ctx->pfm_remote); 1097 const struct dsdb_schema_prefixmap *prefixmap; 1098 1099 if (ctx->pfm_remote != NULL) { 1100 prefixmap = ctx->pfm_remote; 1101 } else { 1102 prefixmap = ctx->schema->prefixmap; 1103 } 1104 SMB_ASSERT(prefixmap); 1071 1105 1072 1106 out->flags = 0; … … 1093 1127 attid = IVAL(in->value_ctr.values[i].blob->data, 0); 1094 1128 1095 status = dsdb_schema_pfm_oid_from_attid( ctx->pfm_remote, attid,1129 status = dsdb_schema_pfm_oid_from_attid(prefixmap, attid, 1096 1130 out->values, &oid); 1097 1131 if (!W_ERROR_IS_OK(status)) { … … 1233 1267 obj_attr = dsdb_attribute_by_lDAPDisplayName(ctx->schema, (const char *)in->values[i].data); 1234 1268 if (!obj_attr) { 1269 DEBUG(0, ("Unable to find attribute %s in the schema\n", (const char *)in->values[i].data)); 1235 1270 return WERR_FOOBAR; 1236 1271 } … … 1335 1370 { 1336 1371 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1337 return WERR_ FOOBAR;1372 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 1338 1373 } 1339 1374 … … 1380 1415 const char *oid = (const char*)in->values[i].data; 1381 1416 1417 if (in->values[i].length == 0) { 1418 talloc_free(tmp_ctx); 1419 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1420 } 1421 1382 1422 if (!ber_write_OID_String(tmp_ctx, &blob, oid)) { 1383 1423 DEBUG(0,("ber_write_OID_String() failed for %s\n", oid)); … … 1413 1453 1414 1454 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1415 return WERR_ FOOBAR;1455 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 1416 1456 } 1417 1457 … … 1471 1511 1472 1512 for (i=0; i < out->num_values; i++) { 1513 size_t converted_size = 0; 1473 1514 char *str; 1474 1515 … … 1485 1526 in->value_ctr.values[i].blob->data, 1486 1527 in->value_ctr.values[i].blob->length, 1487 (void **)&str, NULL, false)) {1488 return WERR_FOOBAR; 1489 } 1490 1491 out->values[i] = data_blob_ string_const(str);1528 (void **)&str, &converted_size)) { 1529 return WERR_FOOBAR; 1530 } 1531 1532 out->values[i] = data_blob_const(str, converted_size); 1492 1533 } 1493 1534 … … 1505 1546 1506 1547 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1507 return WERR_ FOOBAR;1548 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 1508 1549 } 1509 1550 … … 1525 1566 CH_UNIX, CH_UTF16, 1526 1567 in->values[i].data, in->values[i].length, 1527 (void **)&blobs[i].data, &blobs[i].length , false)) {1568 (void **)&blobs[i].data, &blobs[i].length)) { 1528 1569 return WERR_FOOBAR; 1529 1570 } … … 1542 1583 1543 1584 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1544 return WERR_ FOOBAR;1585 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 1545 1586 } 1546 1587 … … 1550 1591 val->length, 1551 1592 (void **)&dst, 1552 &size , false);1593 &size); 1553 1594 TALLOC_FREE(dst); 1554 1595 if (!ok) { … … 1579 1620 1580 1621 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1581 return WERR_ FOOBAR;1622 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 1582 1623 } 1583 1624 … … 1718 1759 1719 1760 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1720 return WERR_ FOOBAR;1761 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 1721 1762 } 1722 1763 … … 1800 1841 1801 1842 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1802 return WERR_ FOOBAR;1843 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 1803 1844 } 1804 1845 … … 1883 1924 1884 1925 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1885 return WERR_ FOOBAR;1926 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 1886 1927 } 1887 1928 … … 1969 2010 } 1970 2011 1971 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob); 1972 if (!NT_STATUS_IS_OK(status)) { 1973 talloc_free(tmp_ctx); 1974 return ntstatus_to_werror(status); 1975 } 1976 1977 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob); 1978 if (ret != LDB_SUCCESS) { 1979 talloc_free(tmp_ctx); 1980 return WERR_FOOBAR; 1981 } 1982 1983 talloc_free(guid_blob.data); 2012 if (!GUID_all_zero(&id3.guid)) { 2013 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob); 2014 if (!NT_STATUS_IS_OK(status)) { 2015 talloc_free(tmp_ctx); 2016 return ntstatus_to_werror(status); 2017 } 2018 2019 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob); 2020 if (ret != LDB_SUCCESS) { 2021 talloc_free(tmp_ctx); 2022 return WERR_FOOBAR; 2023 } 2024 talloc_free(guid_blob.data); 2025 } 1984 2026 1985 2027 if (id3.__ndr_size_sid) { … … 2024 2066 2025 2067 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 2026 return WERR_ FOOBAR;2068 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 2027 2069 } 2028 2070 … … 2103 2145 2104 2146 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 2105 return WERR_ FOOBAR;2147 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 2106 2148 } 2107 2149 … … 2173 2215 2174 2216 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 2175 return WERR_ FOOBAR;2217 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 2176 2218 } 2177 2219 … … 2228 2270 for (i=0; i < out->num_values; i++) { 2229 2271 size_t len; 2272 size_t converted_size = 0; 2230 2273 char *str; 2231 2274 … … 2247 2290 in->value_ctr.values[i].blob->data+4, 2248 2291 in->value_ctr.values[i].blob->length-4, 2249 (void **)&str, NULL, false)) {2292 (void **)&str, &converted_size)) { 2250 2293 return WERR_FOOBAR; 2251 2294 } … … 2267 2310 2268 2311 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 2269 return WERR_ FOOBAR;2312 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 2270 2313 } 2271 2314 … … 2290 2333 in->values[i].data, 2291 2334 in->values[i].length, 2292 (void **)&data, &ret , false)) {2335 (void **)&data, &ret)) { 2293 2336 return WERR_FOOBAR; 2294 2337 } … … 2329 2372 .validate_ldb = dsdb_syntax_BOOL_validate_ldb, 2330 2373 .equality = "booleanMatch", 2331 .comment = "Boolean" 2374 .comment = "Boolean", 2375 .auto_normalise = true 2332 2376 },{ 2333 2377 .name = "Integer", … … 2340 2384 .equality = "integerMatch", 2341 2385 .comment = "Integer", 2342 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32 2386 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32, 2387 .auto_normalise = true 2343 2388 },{ 2344 2389 .name = "String(Octet)", … … 2351 2396 .equality = "octetStringMatch", 2352 2397 .comment = "Octet String", 2398 .userParameters = true 2353 2399 },{ 2354 2400 .name = "String(Sid)", … … 2381 2427 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi, 2382 2428 .validate_ldb = dsdb_syntax_INT32_validate_ldb, 2383 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32 2429 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32, 2430 .auto_normalise = true 2384 2431 },{ 2385 2432 /* not used in w2k3 forest */ … … 2437 2484 .equality = "generalizedTimeMatch", 2438 2485 .comment = "UTC Time", 2486 .auto_normalise = true 2439 2487 },{ 2440 2488 .name = "String(Generalized-Time)", … … 2447 2495 .equality = "generalizedTimeMatch", 2448 2496 .comment = "Generalized Time", 2449 . ldb_syntax = LDB_SYNTAX_UTC_TIME,2497 .auto_normalise = true 2450 2498 },{ 2451 2499 /* not used in w2k3 schema */ … … 2486 2534 .comment = "Large Integer", 2487 2535 .ldb_syntax = LDB_SYNTAX_INTEGER, 2536 .auto_normalise = true 2488 2537 },{ 2489 2538 .name = "String(NT-Sec-Desc)", … … 2557 2606 /* not used in w2k3 schema */ 2558 2607 .name = "Object(Access-Point)", 2559 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",2608 .ldap_oid = DSDB_SYNTAX_ACCESS_POINT, 2560 2609 .oMSyntax = 127, 2561 2610 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"), … … 2618 2667 2619 2668 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) { 2669 /* 2670 * We must pretend that userParamters was declared 2671 * binary string, so we can store the 'UTF16' (not 2672 * really string) structure as given over SAMR to samba 2673 */ 2674 if (dsdb_syntaxes[i].userParameters && 2675 (strcasecmp(attr->lDAPDisplayName, "userParameters") == 0)) 2676 { 2677 return &dsdb_syntaxes[i]; 2678 } 2620 2679 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue; 2621 2680 … … 2643 2702 const struct drsuapi_DsReplicaAttribute *in, 2644 2703 TALLOC_CTX *mem_ctx, 2645 struct ldb_message_element *out) 2704 struct ldb_message_element *out, 2705 enum drsuapi_DsAttributeId *local_attid_as_enum) 2646 2706 { 2647 2707 const struct dsdb_attribute *sa; … … 2659 2719 DEBUG(0,(__location__ ": Can't find local ATTID for 0x%08X\n", 2660 2720 in->attid)); 2661 return WERR_ FOOBAR;2721 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 2662 2722 } 2663 2723 break; … … 2676 2736 if (!sa) { 2677 2737 DEBUG(1,(__location__ ": Unknown attributeID_id 0x%08X\n", in->attid)); 2678 return WERR_FOOBAR; 2738 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 2739 } 2740 2741 /* 2742 * We return the same class of attid as we were given. That 2743 * is, we trust the remote server not to use an 2744 * msDS-IntId value in the schema partition 2745 */ 2746 if (local_attid_as_enum != NULL) { 2747 *local_attid_as_enum = (enum drsuapi_DsAttributeId)attid_local; 2679 2748 } 2680 2749 … … 2693 2762 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name); 2694 2763 if (!sa) { 2695 return WERR_ FOOBAR;2764 return WERR_DS_ATT_NOT_DEF_IN_SCHEMA; 2696 2765 } 2697 2766 -
vendor/current/source4/dsdb/schema/tests/schema_syntax.c
r740 r988 75 75 torture_assert(tctx, ldif, "Failed to parse LDIF for authOrig"); 76 76 77 werr = dsdb_ attribute_from_ldb(ldb, schema, ldif->msg);77 werr = dsdb_set_attribute_from_ldb(ldb, schema, ldif->msg); 78 78 ldb_ldif_read_free(ldb, ldif); 79 torture_assert_werr_ok(tctx, werr, "dsdb_ attribute_from_ldb() failed!");79 torture_assert_werr_ok(tctx, werr, "dsdb_set_attribute_from_ldb() failed!"); 80 80 81 81 ldb_res = dsdb_set_schema(ldb, schema); … … 206 206 torture_assert(tctx, priv, "No memory"); 207 207 208 priv->ldb = provision_get_schema(priv, tctx->lp_ctx, NULL );208 priv->ldb = provision_get_schema(priv, tctx->lp_ctx, NULL, NULL); 209 209 torture_assert(tctx, priv->ldb, "Failed to load schema from disk"); 210 210
Note:
See TracChangeset
for help on using the changeset viewer.