Changeset 740 for vendor/current/source4/dsdb/schema
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- Location:
- vendor/current/source4/dsdb/schema
- Files:
-
- 7 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/dsdb/schema/schema.h
r414 r740 23 23 #define _DSDB_SCHEMA_H 24 24 25 #include "prefixmap.h" 26 25 27 struct dsdb_attribute; 26 28 struct dsdb_class; 27 29 struct dsdb_schema; 30 struct dsdb_dn; 31 32 struct dsdb_syntax_ctx { 33 struct ldb_context *ldb; 34 const struct dsdb_schema *schema; 35 36 /* set when converting objects under Schema NC */ 37 bool is_schema_nc; 38 39 /* remote prefixMap to be used for drsuapi_to_ldb conversions */ 40 const struct dsdb_schema_prefixmap *pfm_remote; 41 }; 42 28 43 29 44 struct dsdb_syntax { … … 38 53 const char *ldb_syntax; 39 54 40 WERROR (*drsuapi_to_ldb)(struct ldb_context *ldb, 41 const struct dsdb_schema *schema, 55 WERROR (*drsuapi_to_ldb)(const struct dsdb_syntax_ctx *ctx, 42 56 const struct dsdb_attribute *attr, 43 57 const struct drsuapi_DsReplicaAttribute *in, 44 58 TALLOC_CTX *mem_ctx, 45 59 struct ldb_message_element *out); 46 WERROR (*ldb_to_drsuapi)(struct ldb_context *ldb, 47 const struct dsdb_schema *schema, 60 WERROR (*ldb_to_drsuapi)(const struct dsdb_syntax_ctx *ctx, 48 61 const struct dsdb_attribute *attr, 49 62 const struct ldb_message_element *in, 50 63 TALLOC_CTX *mem_ctx, 51 64 struct drsuapi_DsReplicaAttribute *out); 65 WERROR (*validate_ldb)(const struct dsdb_syntax_ctx *ctx, 66 const struct dsdb_attribute *attr, 67 const struct ldb_message_element *in); 52 68 }; 53 69 … … 61 77 struct GUID schemaIDGUID; 62 78 uint32_t mAPIID; 79 uint32_t msDS_IntId; 63 80 64 81 struct GUID attributeSecurityGUID; 82 struct GUID objectGUID; 65 83 66 84 uint32_t searchFlags; … … 103 121 uint32_t governsID_id; 104 122 struct GUID schemaIDGUID; 123 struct GUID objectGUID; 105 124 106 125 uint32_t objectClassCategory; … … 120 139 const char **mayContain; 121 140 const char **possibleInferiors; 141 const char **systemPossibleInferiors; 122 142 123 143 const char *defaultSecurityDescriptor; … … 134 154 bool systemOnly; 135 155 136 c har **supclasses;137 c har **subclasses;138 c har **subclasses_direct;139 c har **posssuperiors;156 const char **supclasses; 157 const char **subclasses; 158 const char **subclasses_direct; 159 const char **posssuperiors; 140 160 uint32_t subClassOf_id; 141 161 uint32_t *systemAuxiliaryClass_ids; … … 156 176 }; 157 177 158 struct dsdb_schema_oid_prefix { 159 uint32_t id; 160 const char *oid; 161 size_t oid_len; 162 }; 178 /** 179 * data stored in schemaInfo attribute 180 */ 181 struct dsdb_schema_info { 182 uint32_t revision; 183 struct GUID invocation_id; 184 }; 185 163 186 164 187 struct dsdb_schema { 165 uint32_t num_prefixes; 166 struct dsdb_schema_oid_prefix *prefixes; 188 struct ldb_dn *base_dn; 189 190 struct dsdb_schema_prefixmap *prefixmap; 167 191 168 192 /* … … 176 200 const char *schema_info; 177 201 202 /* We can also tell the schema version from the USN on the partition */ 203 uint64_t loaded_usn; 204 178 205 struct dsdb_attribute *attributes; 179 206 struct dsdb_class *classes; … … 193 220 struct dsdb_attribute **attributes_by_attributeID_oid; 194 221 struct dsdb_attribute **attributes_by_linkID; 222 uint32_t num_int_id_attr; 223 struct dsdb_attribute **attributes_by_msDS_IntId; 195 224 196 225 struct { … … 199 228 } fsmo; 200 229 201 struct smb_iconv_convenience *iconv_convenience; 230 /* 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 bool refresh_in_progress; 234 /* an 'opaque' sequence number that the reload function may also wish to use */ 235 uint64_t reload_seq_number; 236 237 /* Should the syntax handlers in this case handle all incoming OIDs automatically, assigning them as an OID if no text name is known? */ 238 bool relax_OID_conversions; 202 239 }; 203 240 -
vendor/current/source4/dsdb/schema/schema_convert_to_ol.c
r414 r740 63 63 .values = &objectclass_name_as_ldb_val 64 64 }; 65 int j;66 int attr_idx;65 unsigned int j; 66 unsigned int attr_idx; 67 67 68 68 if (!mem_ctx) { … … 88 88 if (strcasecmp(name, attr_map[j].old_attr) == 0) { 89 89 name = attr_map[j].new_attr; 90 break; 91 } 92 } 93 94 /* We might have been asked to remap this subClassOf, due to a conflict */ 95 for (j=0; subClassOf && attr_map && attr_map[j].old_attr; j++) { 96 if (strcasecmp(subClassOf, attr_map[j].old_attr) == 0) { 97 subClassOf = attr_map[j].new_attr; 90 98 break; 91 99 } … … 176 184 char *out; 177 185 const char **attrs_skip = NULL; 178 int num_skip = 0;186 unsigned int num_skip = 0; 179 187 struct oid_map *oid_map = NULL; 180 int num_oid_maps = 0;188 unsigned int num_oid_maps = 0; 181 189 struct attr_map *attr_map = NULL; 182 int num_attr_maps = 0;190 unsigned int num_attr_maps = 0; 183 191 struct dsdb_attribute *attribute; 184 192 struct dsdb_schema *schema; … … 254 262 } 255 263 256 schema = dsdb_get_schema(ldb );264 schema = dsdb_get_schema(ldb, mem_ctx); 257 265 if (!schema) { 258 266 DEBUG(0, ("No schema on ldb to convert!\n")); … … 277 285 278 286 char *schema_entry = NULL; 279 int j;287 unsigned int j; 280 288 281 289 /* We have been asked to skip some attributes/objectClasses */ -
vendor/current/source4/dsdb/schema/schema_description.c
r414 r740 178 178 #define APPEND_ATTRS(attributes) \ 179 179 do { \ 180 int k;\180 unsigned int k; \ 181 181 for (k=0; attributes && attributes[k]; k++) { \ 182 182 const char *attr_name = attributes[k]; \ … … 343 343 const struct dsdb_schema *schema) 344 344 { 345 int i;345 unsigned int i; 346 346 char *schema_description; 347 347 const char **aux_class_list = NULL; -
vendor/current/source4/dsdb/schema/schema_inferiors.c
r414 r740 1 1 /* 2 Unix SMB/CIFS mplementation.2 Unix SMB/CIFS implementation. 3 3 4 4 implement possibleInferiors calculation … … 35 35 create the SUPCLASSES() list 36 36 */ 37 static char **schema_supclasses(struct dsdb_schema *schema, struct dsdb_class *schema_class) 38 { 39 char **list; 37 static const char **schema_supclasses(const struct dsdb_schema *schema, 38 struct dsdb_class *schema_class) 39 { 40 const char **list; 40 41 41 42 if (schema_class->supclasses) { … … 43 44 } 44 45 45 list = str_list_make_empty(schema_class);46 list = const_str_list(str_list_make_empty(schema_class)); 46 47 if (list == NULL) { 47 48 DEBUG(0,(__location__ " out of memory\n")); … … 49 50 } 50 51 51 /* Cope with 'top SUP top', i e top is subClassOf top */52 /* Cope with 'top SUP top', i.e. top is subClassOf top */ 52 53 if (schema_class->subClassOf && 53 54 strcmp(schema_class->lDAPDisplayName, schema_class->subClassOf) == 0) { … … 57 58 58 59 if (schema_class->subClassOf) { 60 const struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf); 59 61 const char **list2; 60 list = str_list_add_const(list, schema_class->subClassOf); 61 62 list2 = schema_supclasses(schema, 63 discard_const_p(struct dsdb_class, 64 dsdb_class_by_lDAPDisplayName(schema, 65 schema_class->subClassOf))); 62 list = str_list_add_const(list, schema_class->subClassOf); 63 64 list2 = schema_supclasses(schema, discard_const_p(struct dsdb_class, schema_class2)); 66 65 list = str_list_append_const(list, list2); 67 66 } 68 67 69 68 schema_class->supclasses = str_list_unique(list); 70 71 return list;69 70 return schema_class->supclasses; 72 71 } 73 72 … … 76 75 matches SUBCLASSES() python function 77 76 */ 78 static char **schema_subclasses(struct dsdb_schema *schema, TALLOC_CTX *mem_ctx, char **oclist) 79 { 80 char **list = str_list_make_empty(mem_ctx); 81 int i; 77 static const char **schema_subclasses(const struct dsdb_schema *schema, 78 TALLOC_CTX *mem_ctx, 79 const char **oclist) 80 { 81 const char **list = const_str_list(str_list_make_empty(mem_ctx)); 82 unsigned int i; 82 83 83 84 for (i=0; oclist && oclist[i]; i++) { 84 struct dsdb_class *schema_class =dsdb_class_by_lDAPDisplayName(schema, oclist[i]);85 const struct dsdb_class *schema_class = dsdb_class_by_lDAPDisplayName(schema, oclist[i]); 85 86 if (!schema_class) { 86 87 DEBUG(0, ("ERROR: Unable to locate subClass: '%s'\n", oclist[i])); … … 96 97 equivalent of the POSSSUPERIORS() python function 97 98 */ 98 static c har **schema_posssuperiors(struct dsdb_schema *schema,99 99 static const char **schema_posssuperiors(const struct dsdb_schema *schema, 100 struct dsdb_class *schema_class) 100 101 { 101 102 if (schema_class->posssuperiors == NULL) { 102 c har **list2 = str_list_make_empty(schema_class);103 c har **list3;104 int i;103 const char **list2 = const_str_list(str_list_make_empty(schema_class)); 104 const char **list3; 105 unsigned int i; 105 106 106 107 list2 = str_list_append_const(list2, schema_class->systemPossSuperiors); … … 108 109 list3 = schema_supclasses(schema, schema_class); 109 110 for (i=0; list3 && list3[i]; i++) { 110 struct dsdb_class *class2 = dsdb_class_by_lDAPDisplayName(schema, list3[i]);111 const struct dsdb_class *class2 = dsdb_class_by_lDAPDisplayName(schema, list3[i]); 111 112 if (!class2) { 112 113 DEBUG(0, ("ERROR: Unable to locate supClass: '%s'\n", list3[i])); 113 114 continue; 114 115 } 115 list2 = str_list_append_const(list2, schema_posssuperiors(schema, class2)); 116 list2 = str_list_append_const(list2, schema_posssuperiors(schema, 117 discard_const_p(struct dsdb_class, class2))); 116 118 } 117 119 list2 = str_list_append_const(list2, schema_subclasses(schema, list2, list2)); … … 123 125 } 124 126 125 static char **schema_subclasses_recurse(struct dsdb_schema *schema, struct dsdb_class *schema_class) 126 { 127 char **list = str_list_copy_const(schema_class, schema_class->subclasses_direct); 128 int i; 127 static const char **schema_subclasses_recurse(const struct dsdb_schema *schema, 128 struct dsdb_class *schema_class) 129 { 130 const char **list = str_list_copy_const(schema_class, schema_class->subclasses_direct); 131 unsigned int i; 129 132 for (i=0;list && list[i]; i++) { 130 struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, list[i]);133 const struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, list[i]); 131 134 if (schema_class != schema_class2) { 132 list = str_list_append_const(list, schema_subclasses_recurse(schema, schema_class2)); 135 list = str_list_append_const(list, schema_subclasses_recurse(schema, 136 discard_const_p(struct dsdb_class, schema_class2))); 133 137 } 134 138 } … … 138 142 /* Walk down the subClass tree, setting a higher index as we go down 139 143 * each level. top is 1, subclasses of top are 2, etc */ 140 void schema_subclasses_order_recurse(struct dsdb_schema *schema, struct dsdb_class *schema_class, int order) 144 void schema_subclasses_order_recurse(const struct dsdb_schema *schema, 145 struct dsdb_class *schema_class, 146 const int order) 141 147 { 142 148 const char **list = schema_class->subclasses_direct; 143 int i;149 unsigned int i; 144 150 schema_class->subClass_order = order; 145 151 for (i=0;list && list[i]; i++) { 146 struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, list[i]);147 schema_subclasses_order_recurse(schema, schema_class2, order+1);152 const struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, list[i]); 153 schema_subclasses_order_recurse(schema, discard_const_p(struct dsdb_class, schema_class2), order+1); 148 154 } 149 155 return; 150 156 } 151 157 152 static void schema_create_subclasses(struct dsdb_schema *schema)153 { 154 struct dsdb_class *schema_class ;158 static int schema_create_subclasses(const struct dsdb_schema *schema) 159 { 160 struct dsdb_class *schema_class, *top; 155 161 156 162 for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) { 157 struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf); 163 struct dsdb_class *schema_class2 = discard_const_p(struct dsdb_class, 164 dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf)); 158 165 if (schema_class2 == NULL) { 159 DEBUG(0,("ERROR: no subClassOf for '%s'\n", schema_class->lDAPDisplayName)); 160 continue; 166 DEBUG(0,("ERROR: no subClassOf '%s' for '%s'\n", 167 schema_class->subClassOf, 168 schema_class->lDAPDisplayName)); 169 return LDB_ERR_OPERATIONS_ERROR; 161 170 } 162 171 if (schema_class2 && schema_class != schema_class2) { 163 172 if (schema_class2->subclasses_direct == NULL) { 164 schema_class2->subclasses_direct = str_list_make_empty(schema_class2); 165 } 166 schema_class2->subclasses_direct = str_list_add_const(schema_class2->subclasses_direct, 167 schema_class->lDAPDisplayName); 173 schema_class2->subclasses_direct = const_str_list(str_list_make_empty(schema_class2)); 174 if (!schema_class2->subclasses_direct) { 175 return LDB_ERR_OPERATIONS_ERROR; 176 } 177 } 178 schema_class2->subclasses_direct = str_list_add_const(schema_class2->subclasses_direct, 179 schema_class->lDAPDisplayName); 168 180 } 169 181 } … … 172 184 schema_class->subclasses = str_list_unique(schema_subclasses_recurse(schema, schema_class)); 173 185 174 /* Initi lise the subClass order, to ensure we can't have uninitilised sort on the subClass hirarchy */186 /* Initialize the subClass order, to ensure we can't have uninitialized sort on the subClass hierarchy */ 175 187 schema_class->subClass_order = 0; 176 188 } 177 189 178 schema_subclasses_order_recurse(schema, dsdb_class_by_lDAPDisplayName(schema, "top"), 1); 179 } 180 181 static void schema_fill_possible_inferiors(struct dsdb_schema *schema, struct dsdb_class *schema_class) 190 top = discard_const_p(struct dsdb_class, dsdb_class_by_lDAPDisplayName(schema, "top")); 191 if (!top) { 192 DEBUG(0,("ERROR: no 'top' class in loaded schema\n")); 193 return LDB_ERR_OPERATIONS_ERROR; 194 } 195 196 schema_subclasses_order_recurse(schema, top, 1); 197 return LDB_SUCCESS; 198 } 199 200 static void schema_fill_possible_inferiors(const struct dsdb_schema *schema, 201 struct dsdb_class *schema_class) 182 202 { 183 203 struct dsdb_class *c2; 184 204 185 205 for (c2=schema->classes; c2; c2=c2->next) { 186 c har **superiors = schema_posssuperiors(schema, c2);206 const char **superiors = schema_posssuperiors(schema, c2); 187 207 if (c2->systemOnly == false 188 208 && c2->objectClassCategory != 2 … … 190 210 && str_list_check(superiors, schema_class->lDAPDisplayName)) { 191 211 if (schema_class->possibleInferiors == NULL) { 192 schema_class->possibleInferiors = str_list_make_empty(schema_class);212 schema_class->possibleInferiors = const_str_list(str_list_make_empty(schema_class)); 193 213 } 194 214 schema_class->possibleInferiors = str_list_add_const(schema_class->possibleInferiors, 195 215 c2->lDAPDisplayName); 196 216 } 197 217 } … … 199 219 } 200 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); 239 } 240 201 241 /* 202 242 fill in a string class name from a governs_ID 203 243 */ 204 static void schema_fill_from_class_one(struct dsdb_schema *schema, struct dsdb_class *c, 205 const char **s, uint32_t id) 244 static void schema_fill_from_class_one(const struct dsdb_schema *schema, 245 const struct dsdb_class *c, 246 const char **s, 247 const uint32_t id) 206 248 { 207 249 if (*s == NULL && id != 0) { 208 struct dsdb_class *c2 = dsdb_class_by_governsID_id(schema, id); 250 const struct dsdb_class *c2 = 251 dsdb_class_by_governsID_id(schema, id); 209 252 if (c2) { 210 253 *s = c2->lDAPDisplayName; … … 216 259 fill in a list of string class names from a governs_ID list 217 260 */ 218 static void schema_fill_from_class_list(struct dsdb_schema *schema, struct dsdb_class *c, 219 const char ***s, uint32_t *ids) 261 static void schema_fill_from_class_list(const struct dsdb_schema *schema, 262 const struct dsdb_class *c, 263 const char ***s, 264 const uint32_t *ids) 220 265 { 221 266 if (*s == NULL && ids != NULL) { 222 int i;267 unsigned int i; 223 268 for (i=0;ids[i];i++) ; 224 269 *s = talloc_array(c, const char *, i+1); 225 270 for (i=0;ids[i];i++) { 226 struct dsdb_class *c2 = dsdb_class_by_governsID_id(schema, ids[i]); 271 const struct dsdb_class *c2 = 272 dsdb_class_by_governsID_id(schema, ids[i]); 227 273 if (c2) { 228 274 (*s)[i] = c2->lDAPDisplayName; … … 238 284 fill in a list of string attribute names from a attributeID list 239 285 */ 240 static void schema_fill_from_attribute_list(struct dsdb_schema *schema, struct dsdb_class *c, 241 const char ***s, uint32_t *ids) 286 static void schema_fill_from_attribute_list(const struct dsdb_schema *schema, 287 const struct dsdb_class *c, 288 const char ***s, 289 const uint32_t *ids) 242 290 { 243 291 if (*s == NULL && ids != NULL) { 244 int i;292 unsigned int i; 245 293 for (i=0;ids[i];i++) ; 246 294 *s = talloc_array(c, const char *, i+1); 247 295 for (i=0;ids[i];i++) { 248 struct dsdb_attribute *a = dsdb_attribute_by_attributeID_id(schema, ids[i]); 296 const struct dsdb_attribute *a = 297 dsdb_attribute_by_attributeID_id(schema, ids[i]); 249 298 if (a) { 250 299 (*s)[i] = a->lDAPDisplayName; … … 260 309 if the schema came from DRS then some attributes will be setup as IDs 261 310 */ 262 static void schema_fill_from_ids( struct dsdb_schema *schema)311 static void schema_fill_from_ids(const struct dsdb_schema *schema) 263 312 { 264 313 struct dsdb_class *c; … … 276 325 } 277 326 278 void schema_fill_constructed(struct dsdb_schema *schema) 279 { 327 int schema_fill_constructed(const struct dsdb_schema *schema) 328 { 329 int ret; 280 330 struct dsdb_class *schema_class; 281 331 282 332 schema_fill_from_ids(schema); 283 333 284 schema_create_subclasses(schema); 334 ret = schema_create_subclasses(schema); 335 if (ret != LDB_SUCCESS) { 336 return ret; 337 } 285 338 286 339 for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) { 287 340 schema_fill_possible_inferiors(schema, schema_class); 341 schema_fill_system_possible_inferiors(schema, schema_class); 288 342 } 289 343 … … 299 353 schema_class->posssuperiors = NULL; 300 354 } 301 } 355 356 return LDB_SUCCESS; 357 } -
vendor/current/source4/dsdb/schema/schema_init.c
r414 r740 23 23 #include "includes.h" 24 24 #include "dsdb/samdb/samdb.h" 25 #include "lib/ldb/include/ldb_errors.h" 25 #include "dsdb/common/util.h" 26 #include <ldb_errors.h> 26 27 #include "../lib/util/dlinklist.h" 27 28 #include "librpc/gen_ndr/ndr_misc.h" … … 29 30 #include "librpc/gen_ndr/ndr_drsblobs.h" 30 31 #include "param/param.h" 31 #include "lib/ldb/include/ldb_module.h" 32 33 struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience) 32 #include <ldb_module.h> 33 #include "../lib/util/asn1.h" 34 35 36 struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx) 34 37 { 35 38 struct dsdb_schema *schema = talloc_zero(mem_ctx, struct dsdb_schema); … … 38 41 } 39 42 40 schema->iconv_convenience = iconv_convenience;41 43 return schema; 42 44 } 43 45 44 45 WERROR dsdb_load_oid_mappings_drsuapi(struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr) 46 { 47 uint32_t i,j; 48 49 schema->prefixes = talloc_array(schema, struct dsdb_schema_oid_prefix, ctr->num_mappings); 50 W_ERROR_HAVE_NO_MEMORY(schema->prefixes); 51 52 for (i=0, j=0; i < ctr->num_mappings; i++) { 53 if (ctr->mappings[i].oid.oid == NULL) { 54 return WERR_INVALID_PARAM; 46 struct dsdb_schema *dsdb_schema_copy_shallow(TALLOC_CTX *mem_ctx, 47 struct ldb_context *ldb, 48 const struct dsdb_schema *schema) 49 { 50 int ret; 51 struct dsdb_class *cls; 52 struct dsdb_attribute *attr; 53 struct dsdb_schema *schema_copy; 54 55 schema_copy = dsdb_new_schema(mem_ctx); 56 if (!schema_copy) { 57 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 } 65 66 /* copy prexiMap & schemaInfo */ 67 schema_copy->prefixmap = dsdb_schema_pfm_copy_shallow(schema_copy, 68 schema->prefixmap); 69 if (!schema_copy->prefixmap) { 70 goto failed; 71 } 72 73 schema_copy->schema_info = talloc_strdup(schema_copy, schema->schema_info); 74 75 /* copy classes and attributes*/ 76 for (cls = schema->classes; cls; cls = cls->next) { 77 struct dsdb_class *class_copy = talloc_memdup(schema_copy, 78 cls, sizeof(*cls)); 79 if (!class_copy) { 80 goto failed; 55 81 } 56 57 if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) { 58 if (ctr->mappings[i].id_prefix != 0) { 59 return WERR_INVALID_PARAM; 60 } 61 62 /* the magic value should be in the last array member */ 63 if (i != (ctr->num_mappings - 1)) { 64 return WERR_INVALID_PARAM; 65 } 66 67 if (ctr->mappings[i].oid.__ndr_size != 21) { 68 return WERR_INVALID_PARAM; 69 } 70 71 schema->schema_info = talloc_strdup(schema, ctr->mappings[i].oid.oid); 72 W_ERROR_HAVE_NO_MEMORY(schema->schema_info); 73 } else { 74 /* the last array member should contain the magic value not a oid */ 75 if (i == (ctr->num_mappings - 1)) { 76 return WERR_INVALID_PARAM; 77 } 78 79 schema->prefixes[j].id = ctr->mappings[i].id_prefix<<16; 80 schema->prefixes[j].oid = talloc_asprintf(schema->prefixes, "%s.", 81 ctr->mappings[i].oid.oid); 82 W_ERROR_HAVE_NO_MEMORY(schema->prefixes[j].oid); 83 schema->prefixes[j].oid_len = strlen(schema->prefixes[j].oid); 84 j++; 82 DLIST_ADD(schema_copy->classes, class_copy); 83 } 84 schema_copy->num_classes = schema->num_classes; 85 86 for (attr = schema->attributes; attr; attr = attr->next) { 87 struct dsdb_attribute *a_copy = talloc_memdup(schema_copy, 88 attr, sizeof(*attr)); 89 if (!a_copy) { 90 goto failed; 85 91 } 86 } 87 88 schema->num_prefixes = j; 92 DLIST_ADD(schema_copy->attributes, a_copy); 93 } 94 schema_copy->num_attributes = schema->num_attributes; 95 96 /* rebuild indexes */ 97 ret = dsdb_setup_sorted_accessors(ldb, schema_copy); 98 if (ret != LDB_SUCCESS) { 99 goto failed; 100 } 101 102 /* 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 106 return schema_copy; 107 108 failed: 109 talloc_free(schema_copy); 110 return NULL; 111 } 112 113 114 WERROR dsdb_load_prefixmap_from_drsuapi(struct dsdb_schema *schema, 115 const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr) 116 { 117 WERROR werr; 118 const char *schema_info; 119 struct dsdb_schema_prefixmap *pfm; 120 121 werr = dsdb_schema_pfm_from_drsuapi_pfm(ctr, true, schema, &pfm, &schema_info); 122 W_ERROR_NOT_OK_RETURN(werr); 123 124 /* set loaded prefixMap */ 125 talloc_free(schema->prefixmap); 126 schema->prefixmap = pfm; 127 128 talloc_free(discard_const(schema->schema_info)); 129 schema->schema_info = schema_info; 130 89 131 return WERR_OK; 132 } 133 134 static WERROR _dsdb_prefixmap_from_ldb_val(const struct ldb_val *pfm_ldb_val, 135 TALLOC_CTX *mem_ctx, 136 struct dsdb_schema_prefixmap **_pfm) 137 { 138 WERROR werr; 139 enum ndr_err_code ndr_err; 140 struct prefixMapBlob pfm_blob; 141 142 TALLOC_CTX *temp_ctx = talloc_new(mem_ctx); 143 W_ERROR_HAVE_NO_MEMORY(temp_ctx); 144 145 ndr_err = ndr_pull_struct_blob(pfm_ldb_val, temp_ctx, 146 &pfm_blob, 147 (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); 148 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 149 NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err); 150 DEBUG(0,("_dsdb_prefixmap_from_ldb_val: Failed to parse prefixmap of length %u: %s\n", 151 (unsigned int)pfm_ldb_val->length, ndr_map_error2string(ndr_err))); 152 talloc_free(temp_ctx); 153 return ntstatus_to_werror(nt_status); 154 } 155 156 if (pfm_blob.version != PREFIX_MAP_VERSION_DSDB) { 157 DEBUG(0,("_dsdb_prefixmap_from_ldb_val: pfm_blob->version %u incorrect\n", (unsigned int)pfm_blob.version)); 158 talloc_free(temp_ctx); 159 return WERR_VERSION_PARSE_ERROR; 160 } 161 162 /* call the drsuapi version */ 163 werr = dsdb_schema_pfm_from_drsuapi_pfm(&pfm_blob.ctr.dsdb, false, mem_ctx, _pfm, NULL); 164 if (!W_ERROR_IS_OK(werr)) { 165 DEBUG(0, (__location__ " dsdb_schema_pfm_from_drsuapi_pfm failed: %s\n", win_errstr(werr))); 166 talloc_free(temp_ctx); 167 return werr; 168 } 169 170 talloc_free(temp_ctx); 171 172 return werr; 90 173 } 91 174 … … 94 177 const struct ldb_val *schemaInfo) 95 178 { 96 WERROR status; 97 enum ndr_err_code ndr_err; 98 struct prefixMapBlob pfm; 99 char *schema_info; 100 101 TALLOC_CTX *mem_ctx = talloc_new(schema); 179 WERROR werr; 180 const char *schema_info; 181 struct dsdb_schema_prefixmap *pfm; 182 TALLOC_CTX *mem_ctx; 183 184 /* verify schemaInfo blob is valid one */ 185 if (!dsdb_schema_info_blob_is_valid(schemaInfo)) { 186 DEBUG(0,(__location__": dsdb_schema_info_blob_is_valid() failed.\n")); 187 return WERR_INVALID_PARAMETER; 188 } 189 190 mem_ctx = talloc_new(schema); 102 191 W_ERROR_HAVE_NO_MEMORY(mem_ctx); 103 104 ndr_err = ndr_pull_struct_blob(prefixMap, mem_ctx, schema->iconv_convenience, &pfm, (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); 105 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 106 NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err); 192 193 /* fetch prefixMap */ 194 werr = _dsdb_prefixmap_from_ldb_val(prefixMap, 195 mem_ctx, &pfm); 196 if (!W_ERROR_IS_OK(werr)) { 197 DEBUG(0, (__location__ " _dsdb_prefixmap_from_ldb_val failed: %s\n", win_errstr(werr))); 107 198 talloc_free(mem_ctx); 108 return ntstatus_to_werror(nt_status); 109 } 110 111 if (pfm.version != PREFIX_MAP_VERSION_DSDB) { 199 return werr; 200 } 201 202 /* decode schema_info */ 203 schema_info = hex_encode_talloc(mem_ctx, 204 schemaInfo->data, 205 schemaInfo->length); 206 if (!schema_info) { 112 207 talloc_free(mem_ctx); 113 return WERR_FOOBAR; 114 } 115 116 if (schemaInfo->length != 21 && schemaInfo->data[0] == 0xFF) { 117 talloc_free(mem_ctx); 118 return WERR_FOOBAR; 119 } 120 121 /* append the schema info as last element */ 122 pfm.ctr.dsdb.num_mappings++; 123 pfm.ctr.dsdb.mappings = talloc_realloc(mem_ctx, pfm.ctr.dsdb.mappings, 124 struct drsuapi_DsReplicaOIDMapping, 125 pfm.ctr.dsdb.num_mappings); 126 W_ERROR_HAVE_NO_MEMORY(pfm.ctr.dsdb.mappings); 127 128 schema_info = data_blob_hex_string(pfm.ctr.dsdb.mappings, schemaInfo); 129 W_ERROR_HAVE_NO_MEMORY(schema_info); 130 131 pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].id_prefix = 0; 132 pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.__ndr_size = schemaInfo->length; 133 pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.oid = schema_info; 134 135 /* call the drsuapi version */ 136 status = dsdb_load_oid_mappings_drsuapi(schema, &pfm.ctr.dsdb); 208 return WERR_NOMEM; 209 } 210 211 /* store prefixMap and schema_info into cached Schema */ 212 talloc_free(schema->prefixmap); 213 schema->prefixmap = talloc_steal(schema, pfm); 214 215 talloc_free(discard_const(schema->schema_info)); 216 schema->schema_info = talloc_steal(schema, schema_info); 217 218 /* clean up locally allocated mem */ 137 219 talloc_free(mem_ctx); 138 139 W_ERROR_NOT_OK_RETURN(status);140 220 141 221 return WERR_OK; … … 147 227 struct drsuapi_DsReplicaOIDMapping_Ctr **_ctr) 148 228 { 149 struct drsuapi_DsReplicaOIDMapping_Ctr *ctr; 150 uint32_t i; 151 152 ctr = talloc(mem_ctx, struct drsuapi_DsReplicaOIDMapping_Ctr); 153 W_ERROR_HAVE_NO_MEMORY(ctr); 154 155 ctr->num_mappings = schema->num_prefixes; 156 if (include_schema_info) ctr->num_mappings++; 157 ctr->mappings = talloc_array(schema, struct drsuapi_DsReplicaOIDMapping, ctr->num_mappings); 158 W_ERROR_HAVE_NO_MEMORY(ctr->mappings); 159 160 for (i=0; i < schema->num_prefixes; i++) { 161 ctr->mappings[i].id_prefix = schema->prefixes[i].id>>16; 162 ctr->mappings[i].oid.oid = talloc_strndup(ctr->mappings, 163 schema->prefixes[i].oid, 164 schema->prefixes[i].oid_len - 1); 165 W_ERROR_HAVE_NO_MEMORY(ctr->mappings[i].oid.oid); 166 } 167 168 if (include_schema_info) { 169 ctr->mappings[i].id_prefix = 0; 170 ctr->mappings[i].oid.oid = talloc_strdup(ctr->mappings, 171 schema->schema_info); 172 W_ERROR_HAVE_NO_MEMORY(ctr->mappings[i].oid.oid); 173 } 174 175 *_ctr = ctr; 229 return dsdb_drsuapi_pfm_from_schema_pfm(schema->prefixmap, 230 include_schema_info ? schema->schema_info : NULL, 231 mem_ctx, _ctr); 232 } 233 234 WERROR dsdb_get_drsuapi_prefixmap_as_blob(const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr, 235 TALLOC_CTX *mem_ctx, 236 struct ldb_val *prefixMap) 237 { 238 struct prefixMapBlob pfm; 239 enum ndr_err_code ndr_err; 240 pfm.version = PREFIX_MAP_VERSION_DSDB; 241 pfm.reserved = 0; 242 pfm.ctr.dsdb = *ctr; 243 244 ndr_err = ndr_push_struct_blob(prefixMap, mem_ctx, &pfm, 245 (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); 246 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 247 NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err); 248 return ntstatus_to_werror(nt_status); 249 } 176 250 return WERR_OK; 177 251 } … … 183 257 { 184 258 WERROR status; 185 enum ndr_err_code ndr_err;186 259 struct drsuapi_DsReplicaOIDMapping_Ctr *ctr; 187 struct prefixMapBlob pfm;188 260 189 261 status = dsdb_get_oid_mappings_drsuapi(schema, false, mem_ctx, &ctr); 190 262 W_ERROR_NOT_OK_RETURN(status); 191 263 192 pfm.version = PREFIX_MAP_VERSION_DSDB; 193 pfm.reserved = 0; 194 pfm.ctr.dsdb = *ctr; 195 196 ndr_err = ndr_push_struct_blob(prefixMap, mem_ctx, schema->iconv_convenience, &pfm, (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); 264 status = dsdb_get_drsuapi_prefixmap_as_blob(ctr, mem_ctx, prefixMap); 197 265 talloc_free(ctr); 198 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 199 NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err); 200 return ntstatus_to_werror(nt_status); 201 } 266 W_ERROR_NOT_OK_RETURN(status); 202 267 203 268 *schemaInfo = strhex_to_data_blob(mem_ctx, schema->schema_info); … … 207 272 } 208 273 209 WERROR dsdb_verify_oid_mappings_drsuapi(const struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)210 {211 uint32_t i,j;212 213 for (i=0; i < ctr->num_mappings; i++) {214 if (ctr->mappings[i].oid.oid == NULL) {215 return WERR_INVALID_PARAM;216 }217 218 if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) {219 if (ctr->mappings[i].id_prefix != 0) {220 return WERR_INVALID_PARAM;221 }222 223 /* the magic value should be in the last array member */224 if (i != (ctr->num_mappings - 1)) {225 return WERR_INVALID_PARAM;226 }227 228 if (ctr->mappings[i].oid.__ndr_size != 21) {229 return WERR_INVALID_PARAM;230 }231 232 if (strcasecmp(schema->schema_info, ctr->mappings[i].oid.oid) != 0) {233 return WERR_DS_DRA_SCHEMA_MISMATCH;234 }235 } else {236 /* the last array member should contain the magic value not a oid */237 if (i == (ctr->num_mappings - 1)) {238 return WERR_INVALID_PARAM;239 }240 241 for (j=0; j < schema->num_prefixes; j++) {242 size_t oid_len;243 if (schema->prefixes[j].id != (ctr->mappings[i].id_prefix<<16)) {244 continue;245 }246 247 oid_len = strlen(ctr->mappings[i].oid.oid);248 249 if (oid_len != (schema->prefixes[j].oid_len - 1)) {250 return WERR_DS_DRA_SCHEMA_MISMATCH;251 }252 253 if (strncmp(ctr->mappings[i].oid.oid, schema->prefixes[j].oid, oid_len) != 0) {254 return WERR_DS_DRA_SCHEMA_MISMATCH;255 }256 257 break;258 }259 260 if (j == schema->num_prefixes) {261 return WERR_DS_DRA_SCHEMA_MISMATCH;262 }263 }264 }265 266 return WERR_OK;267 }268 269 WERROR dsdb_map_oid2int(const struct dsdb_schema *schema, const char *in, uint32_t *out)270 {271 return dsdb_find_prefix_for_oid(schema->num_prefixes, schema->prefixes, in, out);272 }273 274 275 WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CTX *mem_ctx, const char **out)276 {277 uint32_t i;278 279 for (i=0; i < schema->num_prefixes; i++) {280 const char *val;281 if (schema->prefixes[i].id != (in & 0xFFFF0000)) {282 continue;283 }284 285 val = talloc_asprintf(mem_ctx, "%s%u",286 schema->prefixes[i].oid,287 in & 0xFFFF);288 W_ERROR_HAVE_NO_MEMORY(val);289 290 *out = val;291 return WERR_OK;292 }293 294 return WERR_DS_NO_MSDS_INTID;295 }296 274 297 275 /* … … 301 279 { 302 280 WERROR status; 303 uint32_t num_prefixes; 304 struct dsdb_schema_oid_prefix *prefixes; 281 uint32_t attid; 305 282 TALLOC_CTX *mem_ctx; 306 uint32_t out;283 struct dsdb_schema_prefixmap *pfm; 307 284 308 285 mem_ctx = talloc_new(ldb); … … 310 287 311 288 /* Read prefixes from disk*/ 312 status = dsdb_read_prefixes_from_ldb( mem_ctx, ldb, &num_prefixes, &prefixes );289 status = dsdb_read_prefixes_from_ldb(ldb, mem_ctx, &pfm); 313 290 if (!W_ERROR_IS_OK(status)) { 314 291 DEBUG(0,("dsdb_create_prefix_mapping: dsdb_read_prefixes_from_ldb: %s\n", … … 319 296 320 297 /* Check if there is a prefix for the oid in the prefixes array*/ 321 status = dsdb_ find_prefix_for_oid( num_prefixes, prefixes, full_oid, &out );298 status = dsdb_schema_pfm_find_oid(pfm, full_oid, NULL); 322 299 if (W_ERROR_IS_OK(status)) { 323 300 /* prefix found*/ 324 301 talloc_free(mem_ctx); 325 302 return status; 326 } else if (!W_ERROR_EQUAL( WERR_DS_NO_MSDS_INTID, status)) {303 } else if (!W_ERROR_EQUAL(status, WERR_NOT_FOUND)) { 327 304 /* error */ 328 305 DEBUG(0,("dsdb_create_prefix_mapping: dsdb_find_prefix_for_oid: %s\n", … … 333 310 334 311 /* Create the new mapping for the prefix of full_oid */ 335 status = dsdb_ prefix_map_update(mem_ctx, &num_prefixes, &prefixes, full_oid);312 status = dsdb_schema_pfm_make_attid(pfm, full_oid, &attid); 336 313 if (!W_ERROR_IS_OK(status)) { 337 DEBUG(0,("dsdb_create_prefix_mapping: dsdb_ prefix_map_update: %s\n",314 DEBUG(0,("dsdb_create_prefix_mapping: dsdb_schema_pfm_make_attid: %s\n", 338 315 win_errstr(status))); 339 316 talloc_free(mem_ctx); … … 341 318 } 342 319 343 talloc_free(schema->prefixes); 344 schema->prefixes = talloc_steal(schema, prefixes); 345 schema->num_prefixes = num_prefixes; 320 talloc_unlink(schema, schema->prefixmap); 321 schema->prefixmap = talloc_steal(schema, pfm); 346 322 347 323 /* Update prefixMap in ldb*/ … … 355 331 356 332 DEBUG(2,(__location__ " Added prefixMap %s - now have %u prefixes\n", 357 full_oid, num_prefixes));333 full_oid, schema->prefixmap->length)); 358 334 359 335 talloc_free(mem_ctx); … … 361 337 } 362 338 363 WERROR dsdb_prefix_map_update(TALLOC_CTX *mem_ctx, uint32_t *num_prefixes, struct dsdb_schema_oid_prefix **prefixes, const char *oid)364 {365 uint32_t new_num_prefixes, index_new_prefix, new_entry_id;366 const char* lastDotOffset;367 size_t size;368 369 new_num_prefixes = *num_prefixes + 1;370 index_new_prefix = *num_prefixes;371 372 /*373 * this is the algorithm we use to create new mappings for now374 *375 * TODO: find what algorithm windows use376 */377 new_entry_id = (*num_prefixes)<<16;378 379 /* Extract the prefix from the oid*/380 lastDotOffset = strrchr(oid, '.');381 if (lastDotOffset == NULL) {382 DEBUG(0,("dsdb_prefix_map_update: failed to find the last dot\n"));383 return WERR_NOT_FOUND;384 }385 386 /* Calculate the size of the remainig string that should be the prefix of it */387 size = strlen(oid) - strlen(lastDotOffset);388 if (size <= 0) {389 DEBUG(0,("dsdb_prefix_map_update: size of the remaining string invalid\n"));390 return WERR_FOOBAR;391 }392 /* Add one because we need to copy the dot */393 size += 1;394 395 /* Create a spot in the prefixMap for one more prefix*/396 (*prefixes) = talloc_realloc(mem_ctx, *prefixes, struct dsdb_schema_oid_prefix, new_num_prefixes);397 W_ERROR_HAVE_NO_MEMORY(*prefixes);398 399 /* Add the new prefix entry*/400 (*prefixes)[index_new_prefix].id = new_entry_id;401 (*prefixes)[index_new_prefix].oid = talloc_strndup(mem_ctx, oid, size);402 (*prefixes)[index_new_prefix].oid_len = strlen((*prefixes)[index_new_prefix].oid);403 404 /* Increase num_prefixes because new prefix has been added */405 ++(*num_prefixes);406 407 return WERR_OK;408 }409 410 WERROR dsdb_find_prefix_for_oid(uint32_t num_prefixes, const struct dsdb_schema_oid_prefix *prefixes, const char *in, uint32_t *out)411 {412 uint32_t i;413 414 for (i=0; i < num_prefixes; i++) {415 const char *val_str;416 char *end_str;417 unsigned val;418 419 if (strncmp(prefixes[i].oid, in, prefixes[i].oid_len) != 0) {420 continue;421 }422 423 val_str = in + prefixes[i].oid_len;424 end_str = NULL;425 errno = 0;426 427 if (val_str[0] == '\0') {428 return WERR_INVALID_PARAM;429 }430 431 /* two '.' chars are invalid */432 if (val_str[0] == '.') {433 return WERR_INVALID_PARAM;434 }435 436 val = strtoul(val_str, &end_str, 10);437 if (end_str[0] == '.' && end_str[1] != '\0') {438 /*439 * if it's a '.' and not the last char440 * then maybe an other mapping apply441 */442 continue;443 } else if (end_str[0] != '\0') {444 return WERR_INVALID_PARAM;445 } else if (val > 0xFFFF) {446 return WERR_INVALID_PARAM;447 }448 449 *out = prefixes[i].id | val;450 return WERR_OK;451 }452 453 DEBUG(5,(__location__ " Failed to find oid %s - have %u prefixes\n", in, num_prefixes));454 455 return WERR_DS_NO_MSDS_INTID;456 }457 339 458 340 WERROR dsdb_write_prefixes_from_schema_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 459 const struct dsdb_schema *schema) 460 { 461 struct ldb_message *msg = ldb_msg_new(mem_ctx); 341 const struct dsdb_schema *schema) 342 { 343 WERROR status; 344 int ldb_ret; 345 struct ldb_message *msg; 462 346 struct ldb_dn *schema_dn; 463 struct prefixMapBlob p m;347 struct prefixMapBlob pfm_blob; 464 348 struct ldb_val ndr_blob; 465 349 enum ndr_err_code ndr_err; 466 uint32_t i; 467 int ret; 468 469 if (!msg) { 470 return WERR_NOMEM; 471 } 472 473 schema_dn = samdb_schema_dn(ldb); 350 TALLOC_CTX *temp_ctx; 351 struct drsuapi_DsReplicaOIDMapping_Ctr *ctr; 352 353 schema_dn = ldb_get_schema_basedn(ldb); 474 354 if (!schema_dn) { 475 DEBUG(0,("dsdb_write_prefixes_from_schema_to_ldb: no schema dn present\n")); 355 DEBUG(0,("dsdb_write_prefixes_from_schema_to_ldb: no schema dn present\n")); 476 356 return WERR_FOOBAR; 477 357 } 478 358 479 pm.version = PREFIX_MAP_VERSION_DSDB; 480 pm.ctr.dsdb.num_mappings = schema->num_prefixes; 481 pm.ctr.dsdb.mappings = talloc_array(msg, 482 struct drsuapi_DsReplicaOIDMapping, 483 pm.ctr.dsdb.num_mappings); 484 if (!pm.ctr.dsdb.mappings) { 485 talloc_free(msg); 486 return WERR_NOMEM; 487 } 488 489 for (i=0; i < schema->num_prefixes; i++) { 490 pm.ctr.dsdb.mappings[i].id_prefix = schema->prefixes[i].id>>16; 491 pm.ctr.dsdb.mappings[i].oid.oid = talloc_strdup(pm.ctr.dsdb.mappings, schema->prefixes[i].oid); 492 } 493 494 ndr_err = ndr_push_struct_blob(&ndr_blob, msg, 495 lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), 496 &pm, 359 temp_ctx = talloc_new(mem_ctx); 360 W_ERROR_HAVE_NO_MEMORY(temp_ctx); 361 362 /* convert schema_prefixMap to prefixMap blob */ 363 status = dsdb_get_oid_mappings_drsuapi(schema, false, temp_ctx, &ctr); 364 if (!W_ERROR_IS_OK(status)) { 365 talloc_free(temp_ctx); 366 return status; 367 } 368 369 pfm_blob.version = PREFIX_MAP_VERSION_DSDB; 370 pfm_blob.ctr.dsdb = *ctr; 371 372 ndr_err = ndr_push_struct_blob(&ndr_blob, temp_ctx, 373 &pfm_blob, 497 374 (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); 498 375 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 499 talloc_free( msg);376 talloc_free(temp_ctx); 500 377 return WERR_FOOBAR; 501 378 } 502 379 380 /* write serialized prefixMap into LDB */ 381 msg = ldb_msg_new(temp_ctx); 382 if (!msg) { 383 talloc_free(temp_ctx); 384 return WERR_NOMEM; 385 } 386 503 387 msg->dn = schema_dn; 504 ret = ldb_msg_add_value(msg, "prefixMap", &ndr_blob, NULL);505 if ( ret != 0) {506 talloc_free( msg);388 ldb_ret = ldb_msg_add_value(msg, "prefixMap", &ndr_blob, NULL); 389 if (ldb_ret != 0) { 390 talloc_free(temp_ctx); 507 391 DEBUG(0,("dsdb_write_prefixes_from_schema_to_ldb: ldb_msg_add_value failed\n")); 508 392 return WERR_NOMEM; 509 393 } 510 394 511 ret = samdb_replace( ldb, msg, msg ); 512 talloc_free(msg); 513 514 if (ret != 0) { 515 DEBUG(0,("dsdb_write_prefixes_from_schema_to_ldb: samdb_replace failed\n")); 395 ldb_ret = dsdb_replace(ldb, msg, DSDB_FLAG_AS_SYSTEM); 396 397 talloc_free(temp_ctx); 398 399 if (ldb_ret != 0) { 400 DEBUG(0,("dsdb_write_prefixes_from_schema_to_ldb: dsdb_replace failed\n")); 516 401 return WERR_FOOBAR; 517 402 } … … 520 405 } 521 406 522 WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes) 523 { 524 struct prefixMapBlob *blob; 525 enum ndr_err_code ndr_err; 526 uint32_t i; 407 WERROR dsdb_read_prefixes_from_ldb(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct dsdb_schema_prefixmap **_pfm) 408 { 409 WERROR werr; 410 int ldb_ret; 527 411 const struct ldb_val *prefix_val; 528 412 struct ldb_dn *schema_dn; 529 struct ldb_result *schema_res; 530 int ret; 413 struct ldb_result *schema_res = NULL; 531 414 static const char *schema_attrs[] = { 532 415 "prefixMap", … … 534 417 }; 535 418 536 schema_dn = samdb_schema_dn(ldb);419 schema_dn = ldb_get_schema_basedn(ldb); 537 420 if (!schema_dn) { 538 421 DEBUG(0,("dsdb_read_prefixes_from_ldb: no schema dn present\n")); … … 540 423 } 541 424 542 ret = ldb_search(ldb, mem_ctx, &schema_res, schema_dn, LDB_SCOPE_BASE, schema_attrs, NULL);543 if ( ret == LDB_ERR_NO_SUCH_OBJECT) {425 ldb_ret = ldb_search(ldb, mem_ctx, &schema_res, schema_dn, LDB_SCOPE_BASE, schema_attrs, NULL); 426 if (ldb_ret == LDB_ERR_NO_SUCH_OBJECT) { 544 427 DEBUG(0,("dsdb_read_prefixes_from_ldb: no prefix map present\n")); 545 428 talloc_free(schema_res); 546 429 return WERR_FOOBAR; 547 } else if ( ret != LDB_SUCCESS) {430 } else if (ldb_ret != LDB_SUCCESS) { 548 431 DEBUG(0,("dsdb_read_prefixes_from_ldb: failed to search the schema head\n")); 549 432 talloc_free(schema_res); … … 558 441 } 559 442 560 blob = talloc(mem_ctx, struct prefixMapBlob); 561 W_ERROR_HAVE_NO_MEMORY(blob); 562 563 ndr_err = ndr_pull_struct_blob(prefix_val, blob, 564 lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), 565 blob, 566 (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); 567 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 568 DEBUG(0,("dsdb_read_prefixes_from_ldb: ndr_pull_struct_blob failed\n")); 569 talloc_free(blob); 570 talloc_free(schema_res); 571 return WERR_FOOBAR; 572 } 573 443 werr = _dsdb_prefixmap_from_ldb_val(prefix_val, 444 mem_ctx, 445 _pfm); 574 446 talloc_free(schema_res); 575 576 if (blob->version != PREFIX_MAP_VERSION_DSDB) { 577 DEBUG(0,("dsdb_read_prefixes_from_ldb: blob->version incorect\n")); 578 talloc_free(blob); 579 return WERR_FOOBAR; 580 } 581 582 *num_prefixes = blob->ctr.dsdb.num_mappings; 583 *prefixes = talloc_array(mem_ctx, struct dsdb_schema_oid_prefix, *num_prefixes); 584 if(!(*prefixes)) { 585 talloc_free(blob); 586 return WERR_NOMEM; 587 } 588 for (i=0; i < blob->ctr.dsdb.num_mappings; i++) { 589 char *oid; 590 (*prefixes)[i].id = blob->ctr.dsdb.mappings[i].id_prefix<<16; 591 oid = talloc_strdup(mem_ctx, blob->ctr.dsdb.mappings[i].oid.oid); 592 (*prefixes)[i].oid = talloc_asprintf_append(oid, "."); 593 (*prefixes)[i].oid_len = strlen((*prefixes)[i].oid); 594 } 595 596 talloc_free(blob); 447 W_ERROR_NOT_OK_RETURN(werr); 448 597 449 return WERR_OK; 598 450 } … … 604 456 static bool dsdb_schema_unique_attribute(const char *attr) 605 457 { 606 const char *attrs[] = { "objectGUID", "objectS ID" , NULL };607 int i;458 const char *attrs[] = { "objectGUID", "objectSid" , NULL }; 459 unsigned int i; 608 460 for (i=0;attrs[i];i++) { 609 461 if (strcasecmp(attr, attrs[i]) == 0) { … … 638 490 639 491 if (s == NULL) { 640 return LDB_ERR_OPERATIONS_ERROR;492 return ldb_operr(ldb); 641 493 } 642 494 643 495 attr->ldb_schema_attribute = a = talloc(attr, struct ldb_schema_attribute); 644 496 if (attr->ldb_schema_attribute == NULL) { 645 ldb_oom(ldb); 646 return LDB_ERR_OPERATIONS_ERROR; 497 return ldb_oom(ldb); 647 498 } 648 499 … … 667 518 if (get_string_val == NULL) { \ 668 519 if (strict) { \ 669 d_printf("%s: %s == NULL \n", __location__, attr); \520 d_printf("%s: %s == NULL in %s\n", __location__, attr, ldb_dn_get_linearized(msg->dn)); \ 670 521 return WERR_INVALID_PARAM; \ 671 522 } else { \ … … 683 534 } while (0) 684 535 685 #define GET_STRING_LIST_LDB(msg, attr, mem_ctx, p, elem , strict) do { \536 #define GET_STRING_LIST_LDB(msg, attr, mem_ctx, p, elem) do { \ 686 537 int get_string_list_counter; \ 687 538 struct ldb_message_element *get_string_list_el = ldb_msg_find_element(msg, attr); \ 688 if (get_string_list_el == NULL) { \ 689 if (strict) { \ 690 d_printf("%s: %s == NULL\n", __location__, attr); \ 691 return WERR_INVALID_PARAM; \ 692 } else { \ 693 (p)->elem = NULL; \ 694 break; \ 695 } \ 539 /* We may get empty attributes over the replication channel */ \ 540 if (get_string_list_el == NULL || get_string_list_el->num_values == 0) { \ 541 (p)->elem = NULL; \ 542 break; \ 696 543 } \ 697 544 (p)->elem = talloc_array(mem_ctx, const char *, get_string_list_el->num_values + 1); \ … … 713 560 #define GET_BOOL_LDB(msg, attr, p, elem, strict) do { \ 714 561 const char *str; \ 715 str = samdb_result_string(msg, attr, NULL);\562 str = ldb_msg_find_attr_as_string(msg, attr, NULL);\ 716 563 if (str == NULL) { \ 717 564 if (strict) { \ … … 732 579 733 580 #define GET_UINT32_LDB(msg, attr, p, elem) do { \ 734 (p)->elem = samdb_result_uint(msg, attr, 0);\581 (p)->elem = ldb_msg_find_attr_as_uint(msg, attr, 0);\ 735 582 } while (0) 736 583 737 #define GET_UINT32_PTR_LDB(msg, attr, p, elem) do {\738 uint64_t _v = samdb_result_uint64(msg, attr, UINT64_MAX);\584 #define GET_UINT32_PTR_LDB(msg, attr, mem_ctx, p, elem) do { \ 585 uint64_t _v = ldb_msg_find_attr_as_uint64(msg, attr, UINT64_MAX);\ 739 586 if (_v == UINT64_MAX) { \ 740 587 (p)->elem = NULL; \ … … 769 616 770 617 WERROR dsdb_attribute_from_ldb(struct ldb_context *ldb, 771 const struct dsdb_schema *schema, 772 struct ldb_message *msg, 773 TALLOC_CTX *mem_ctx, 774 struct dsdb_attribute *attr) 618 struct dsdb_schema *schema, 619 struct ldb_message *msg) 775 620 { 776 621 WERROR status; 777 778 GET_STRING_LDB(msg, "cn", mem_ctx, attr, cn, false); 779 GET_STRING_LDB(msg, "lDAPDisplayName", mem_ctx, attr, lDAPDisplayName, true); 780 GET_STRING_LDB(msg, "attributeID", mem_ctx, attr, attributeID_oid, true); 781 if (schema->num_prefixes == 0) { 622 struct dsdb_attribute *attr = talloc_zero(schema, struct dsdb_attribute); 623 if (!attr) { 624 return WERR_NOMEM; 625 } 626 627 GET_STRING_LDB(msg, "cn", attr, attr, cn, false); 628 GET_STRING_LDB(msg, "lDAPDisplayName", attr, attr, lDAPDisplayName, true); 629 GET_STRING_LDB(msg, "attributeID", attr, attr, attributeID_oid, true); 630 if (!schema->prefixmap || schema->prefixmap->length == 0) { 782 631 /* set an invalid value */ 783 attr->attributeID_id = 0xFFFFFFFF;632 attr->attributeID_id = DRSUAPI_ATTID_INVALID; 784 633 } else { 785 status = dsdb_map_oid2int(schema, attr->attributeID_oid, &attr->attributeID_id); 634 status = dsdb_schema_pfm_make_attid(schema->prefixmap, 635 attr->attributeID_oid, 636 &attr->attributeID_id); 786 637 if (!W_ERROR_IS_OK(status)) { 787 638 DEBUG(0,("%s: '%s': unable to map attributeID %s: %s\n", … … 791 642 } 792 643 } 644 /* fetch msDS-IntId to be used in resolving ATTRTYP values */ 645 GET_UINT32_LDB(msg, "msDS-IntId", attr, msDS_IntId); 646 793 647 GET_GUID_LDB(msg, "schemaIDGUID", attr, schemaIDGUID); 794 648 GET_UINT32_LDB(msg, "mAPIID", attr, mAPIID); 795 649 796 650 GET_GUID_LDB(msg, "attributeSecurityGUID", attr, attributeSecurityGUID); 651 652 GET_GUID_LDB(msg, "objectGUID", attr, objectGUID); 797 653 798 654 GET_UINT32_LDB(msg, "searchFlags", attr, searchFlags); … … 801 657 GET_UINT32_LDB(msg, "linkID", attr, linkID); 802 658 803 GET_STRING_LDB(msg, "attributeSyntax", mem_ctx, attr, attributeSyntax_oid, true);804 if ( schema->num_prefixes== 0) {659 GET_STRING_LDB(msg, "attributeSyntax", attr, attr, attributeSyntax_oid, true); 660 if (!schema->prefixmap || schema->prefixmap->length == 0) { 805 661 /* set an invalid value */ 806 attr->attributeSyntax_id = 0xFFFFFFFF;662 attr->attributeSyntax_id = DRSUAPI_ATTID_INVALID; 807 663 } else { 808 status = dsdb_map_oid2int(schema, attr->attributeSyntax_oid, &attr->attributeSyntax_id); 664 status = dsdb_schema_pfm_attid_from_oid(schema->prefixmap, 665 attr->attributeSyntax_oid, 666 &attr->attributeSyntax_id); 809 667 if (!W_ERROR_IS_OK(status)) { 810 668 DEBUG(0,("%s: '%s': unable to map attributeSyntax_ %s: %s\n", … … 815 673 } 816 674 GET_UINT32_LDB(msg, "oMSyntax", attr, oMSyntax); 817 GET_BLOB_LDB(msg, "oMObjectClass", mem_ctx, attr, oMObjectClass);675 GET_BLOB_LDB(msg, "oMObjectClass", attr, attr, oMObjectClass); 818 676 819 677 GET_BOOL_LDB(msg, "isSingleValued", attr, isSingleValued, true); 820 GET_UINT32_PTR_LDB(msg, "rangeLower", attr, rangeLower);821 GET_UINT32_PTR_LDB(msg, "rangeUpper", attr, rangeUpper);678 GET_UINT32_PTR_LDB(msg, "rangeLower", attr, attr, rangeLower); 679 GET_UINT32_PTR_LDB(msg, "rangeUpper", attr, attr, rangeUpper); 822 680 GET_BOOL_LDB(msg, "extendedCharsAllowed", attr, extendedCharsAllowed, false); 823 681 824 682 GET_UINT32_LDB(msg, "schemaFlagsEx", attr, schemaFlagsEx); 825 GET_BLOB_LDB(msg, "msDs-Schema-Extensions", mem_ctx, attr, msDs_Schema_Extensions);683 GET_BLOB_LDB(msg, "msDs-Schema-Extensions", attr, attr, msDs_Schema_Extensions); 826 684 827 685 GET_BOOL_LDB(msg, "showInAdvancedViewOnly", attr, showInAdvancedViewOnly, false); 828 GET_STRING_LDB(msg, "adminDisplayName", mem_ctx, attr, adminDisplayName, false);829 GET_STRING_LDB(msg, "adminDescription", mem_ctx, attr, adminDescription, false);830 GET_STRING_LDB(msg, "classDisplayName", mem_ctx, attr, classDisplayName, false);686 GET_STRING_LDB(msg, "adminDisplayName", attr, attr, adminDisplayName, false); 687 GET_STRING_LDB(msg, "adminDescription", attr, attr, adminDescription, false); 688 GET_STRING_LDB(msg, "classDisplayName", attr, attr, classDisplayName, false); 831 689 GET_BOOL_LDB(msg, "isEphemeral", attr, isEphemeral, false); 832 690 GET_BOOL_LDB(msg, "isDefunct", attr, isDefunct, false); … … 835 693 attr->syntax = dsdb_syntax_for_attribute(attr); 836 694 if (!attr->syntax) { 695 DEBUG(0,(__location__ ": Unknown schema syntax for %s\n", 696 attr->lDAPDisplayName)); 837 697 return WERR_DS_ATT_SCHEMA_REQ_SYNTAX; 838 698 } 839 699 840 700 if (dsdb_schema_setup_ldb_schema_attribute(ldb, attr) != LDB_SUCCESS) { 701 DEBUG(0,(__location__ ": Unknown schema syntax for %s - ldb_syntax: %s, ldap_oid: %s\n", 702 attr->lDAPDisplayName, 703 attr->syntax->ldb_syntax, 704 attr->syntax->ldap_oid)); 841 705 return WERR_DS_ATT_SCHEMA_REQ_SYNTAX; 842 706 } 843 707 708 DLIST_ADD(schema->attributes, attr); 844 709 return WERR_OK; 845 710 } 846 711 847 WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema, 848 struct ldb_message *msg, 849 TALLOC_CTX *mem_ctx, 850 struct dsdb_class *obj) 712 WERROR dsdb_class_from_ldb(struct dsdb_schema *schema, 713 struct ldb_message *msg) 851 714 { 852 715 WERROR status; 853 854 GET_STRING_LDB(msg, "cn", mem_ctx, obj, cn, false); 855 GET_STRING_LDB(msg, "lDAPDisplayName", mem_ctx, obj, lDAPDisplayName, true); 856 GET_STRING_LDB(msg, "governsID", mem_ctx, obj, governsID_oid, true); 857 if (schema->num_prefixes == 0) { 716 struct dsdb_class *obj = talloc_zero(schema, struct dsdb_class); 717 if (!obj) { 718 return WERR_NOMEM; 719 } 720 GET_STRING_LDB(msg, "cn", obj, obj, cn, false); 721 GET_STRING_LDB(msg, "lDAPDisplayName", obj, obj, lDAPDisplayName, true); 722 GET_STRING_LDB(msg, "governsID", obj, obj, governsID_oid, true); 723 if (!schema->prefixmap || schema->prefixmap->length == 0) { 858 724 /* set an invalid value */ 859 obj->governsID_id = 0xFFFFFFFF;725 obj->governsID_id = DRSUAPI_ATTID_INVALID; 860 726 } else { 861 status = dsdb_map_oid2int(schema, obj->governsID_oid, &obj->governsID_id); 727 status = dsdb_schema_pfm_make_attid(schema->prefixmap, 728 obj->governsID_oid, 729 &obj->governsID_id); 862 730 if (!W_ERROR_IS_OK(status)) { 863 731 DEBUG(0,("%s: '%s': unable to map governsID %s: %s\n", … … 868 736 } 869 737 GET_GUID_LDB(msg, "schemaIDGUID", obj, schemaIDGUID); 738 GET_GUID_LDB(msg, "objectGUID", obj, objectGUID); 870 739 871 740 GET_UINT32_LDB(msg, "objectClassCategory", obj, objectClassCategory); 872 GET_STRING_LDB(msg, "rDNAttID", mem_ctx, obj, rDNAttID, false);873 GET_STRING_LDB(msg, "defaultObjectCategory", mem_ctx, obj, defaultObjectCategory, true);741 GET_STRING_LDB(msg, "rDNAttID", obj, obj, rDNAttID, false); 742 GET_STRING_LDB(msg, "defaultObjectCategory", obj, obj, defaultObjectCategory, true); 874 743 875 GET_STRING_LDB(msg, "subClassOf", mem_ctx, obj, subClassOf, true);876 877 GET_STRING_LIST_LDB(msg, "systemAuxiliaryClass", mem_ctx, obj, systemAuxiliaryClass, false);878 GET_STRING_LIST_LDB(msg, "auxiliaryClass", mem_ctx, obj, auxiliaryClass, false);879 880 GET_STRING_LIST_LDB(msg, "systemMustContain", mem_ctx, obj, systemMustContain, false);881 GET_STRING_LIST_LDB(msg, "systemMayContain", mem_ctx, obj, systemMayContain, false);882 GET_STRING_LIST_LDB(msg, "mustContain", mem_ctx, obj, mustContain, false);883 GET_STRING_LIST_LDB(msg, "mayContain", mem_ctx, obj, mayContain, false);884 885 GET_STRING_LIST_LDB(msg, "systemPossSuperiors", mem_ctx, obj, systemPossSuperiors, false);886 GET_STRING_LIST_LDB(msg, "possSuperiors", mem_ctx, obj, possSuperiors, false);887 888 GET_STRING_LDB(msg, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, false);744 GET_STRING_LDB(msg, "subClassOf", obj, obj, subClassOf, true); 745 746 GET_STRING_LIST_LDB(msg, "systemAuxiliaryClass", obj, obj, systemAuxiliaryClass); 747 GET_STRING_LIST_LDB(msg, "auxiliaryClass", obj, obj, auxiliaryClass); 748 749 GET_STRING_LIST_LDB(msg, "systemMustContain", obj, obj, systemMustContain); 750 GET_STRING_LIST_LDB(msg, "systemMayContain", obj, obj, systemMayContain); 751 GET_STRING_LIST_LDB(msg, "mustContain", obj, obj, mustContain); 752 GET_STRING_LIST_LDB(msg, "mayContain", obj, obj, mayContain); 753 754 GET_STRING_LIST_LDB(msg, "systemPossSuperiors", obj, obj, systemPossSuperiors); 755 GET_STRING_LIST_LDB(msg, "possSuperiors", obj, obj, possSuperiors); 756 757 GET_STRING_LDB(msg, "defaultSecurityDescriptor", obj, obj, defaultSecurityDescriptor, false); 889 758 890 759 GET_UINT32_LDB(msg, "schemaFlagsEx", obj, schemaFlagsEx); 891 GET_BLOB_LDB(msg, "msDs-Schema-Extensions", mem_ctx, obj, msDs_Schema_Extensions);760 GET_BLOB_LDB(msg, "msDs-Schema-Extensions", obj, obj, msDs_Schema_Extensions); 892 761 893 762 GET_BOOL_LDB(msg, "showInAdvancedViewOnly", obj, showInAdvancedViewOnly, false); 894 GET_STRING_LDB(msg, "adminDisplayName", mem_ctx, obj, adminDisplayName, false);895 GET_STRING_LDB(msg, "adminDescription", mem_ctx, obj, adminDescription, false);896 GET_STRING_LDB(msg, "classDisplayName", mem_ctx, obj, classDisplayName, false);763 GET_STRING_LDB(msg, "adminDisplayName", obj, obj, adminDisplayName, false); 764 GET_STRING_LDB(msg, "adminDescription", obj, obj, adminDescription, false); 765 GET_STRING_LDB(msg, "classDisplayName", obj, obj, classDisplayName, false); 897 766 GET_BOOL_LDB(msg, "defaultHidingValue", obj, defaultHidingValue, false); 898 767 GET_BOOL_LDB(msg, "isDefunct", obj, isDefunct, false); 899 768 GET_BOOL_LDB(msg, "systemOnly", obj, systemOnly, false); 900 769 770 DLIST_ADD(schema->classes, obj); 901 771 return WERR_OK; 902 772 } … … 907 777 Create a DSDB schema from the ldb results provided. This is called 908 778 directly when the schema is provisioned from an on-disk LDIF file, or 909 from dsdb_schema_from_schema_dn below779 from dsdb_schema_from_schema_dn in schema_fsmo 910 780 */ 911 781 912 782 int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 913 struct smb_iconv_convenience *iconv_convenience,914 783 struct ldb_result *schema_res, 915 784 struct ldb_result *attrs_res, struct ldb_result *objectclass_res, … … 918 787 { 919 788 WERROR status; 920 u int32_t i;789 unsigned int i; 921 790 const struct ldb_val *prefix_val; 922 791 const struct ldb_val *info_val; … … 924 793 struct dsdb_schema *schema; 925 794 926 schema = dsdb_new_schema(mem_ctx , iconv_convenience);795 schema = dsdb_new_schema(mem_ctx); 927 796 if (!schema) { 928 797 dsdb_oom(error_string, mem_ctx); 929 return LDB_ERR_OPERATIONS_ERROR; 930 } 798 return ldb_operr(ldb); 799 } 800 801 schema->base_dn = talloc_steal(schema, schema_res->msgs[0]->dn); 931 802 932 803 prefix_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "prefixMap"); … … 939 810 info_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "schemaInfo"); 940 811 if (!info_val) { 941 info_val_default = strhex_to_data_blob(mem_ctx, "FF0000000000000000000000000000000000000000"); 942 if (!info_val_default.data) { 943 dsdb_oom(error_string, mem_ctx); 944 return LDB_ERR_OPERATIONS_ERROR; 812 status = dsdb_schema_info_blob_new(mem_ctx, &info_val_default); 813 if (!W_ERROR_IS_OK(status)) { 814 *error_string = talloc_asprintf(mem_ctx, 815 "schema_fsmo_init: dsdb_schema_info_blob_new() failed - %s", 816 win_errstr(status)); 817 DEBUG(0,(__location__ ": %s\n", *error_string)); 818 return ldb_operr(ldb); 945 819 } 946 820 info_val = &info_val_default; … … 957 831 958 832 for (i=0; i < attrs_res->count; i++) { 959 struct dsdb_attribute *sa; 960 961 sa = talloc_zero(schema, struct dsdb_attribute); 962 if (!sa) { 963 dsdb_oom(error_string, mem_ctx); 964 return LDB_ERR_OPERATIONS_ERROR; 965 } 966 967 status = dsdb_attribute_from_ldb(ldb, schema, attrs_res->msgs[i], sa, sa); 833 status = dsdb_attribute_from_ldb(ldb, schema, attrs_res->msgs[i]); 968 834 if (!W_ERROR_IS_OK(status)) { 969 835 *error_string = talloc_asprintf(mem_ctx, … … 974 840 return LDB_ERR_CONSTRAINT_VIOLATION; 975 841 } 976 977 DLIST_ADD(schema->attributes, sa);978 842 } 979 843 980 844 for (i=0; i < objectclass_res->count; i++) { 981 struct dsdb_class *sc; 982 983 sc = talloc_zero(schema, struct dsdb_class); 984 if (!sc) { 985 dsdb_oom(error_string, mem_ctx); 986 return LDB_ERR_OPERATIONS_ERROR; 987 } 988 989 status = dsdb_class_from_ldb(schema, objectclass_res->msgs[i], sc, sc); 845 status = dsdb_class_from_ldb(schema, objectclass_res->msgs[i]); 990 846 if (!W_ERROR_IS_OK(status)) { 991 847 *error_string = talloc_asprintf(mem_ctx, … … 996 852 return LDB_ERR_CONSTRAINT_VIOLATION; 997 853 } 998 999 DLIST_ADD(schema->classes, sc);1000 854 } 1001 855 … … 1013 867 return LDB_SUCCESS; 1014 868 } 1015 1016 /*1017 Given an LDB, and the DN, return a populated schema1018 */1019 1020 int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,1021 struct smb_iconv_convenience *iconv_convenience,1022 struct ldb_dn *schema_dn,1023 struct dsdb_schema **schema,1024 char **error_string_out)1025 {1026 TALLOC_CTX *tmp_ctx;1027 char *error_string;1028 int ret;1029 1030 struct ldb_result *schema_res;1031 struct ldb_result *a_res;1032 struct ldb_result *c_res;1033 static const char *schema_attrs[] = {1034 "prefixMap",1035 "schemaInfo",1036 "fSMORoleOwner",1037 NULL1038 };1039 unsigned flags;1040 1041 tmp_ctx = talloc_new(mem_ctx);1042 if (!tmp_ctx) {1043 dsdb_oom(error_string_out, mem_ctx);1044 return LDB_ERR_OPERATIONS_ERROR;1045 }1046 1047 /* we don't want to trace the schema load */1048 flags = ldb_get_flags(ldb);1049 ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING);1050 1051 /*1052 * setup the prefix mappings and schema info1053 */1054 ret = ldb_search(ldb, tmp_ctx, &schema_res,1055 schema_dn, LDB_SCOPE_BASE, schema_attrs, NULL);1056 if (ret == LDB_ERR_NO_SUCH_OBJECT) {1057 goto failed;1058 } else if (ret != LDB_SUCCESS) {1059 *error_string_out = talloc_asprintf(mem_ctx,1060 "dsdb_schema: failed to search the schema head: %s",1061 ldb_errstring(ldb));1062 goto failed;1063 }1064 if (schema_res->count != 1) {1065 *error_string_out = talloc_asprintf(mem_ctx,1066 "dsdb_schema: [%u] schema heads found on a base search",1067 schema_res->count);1068 goto failed;1069 }1070 1071 /*1072 * load the attribute definitions1073 */1074 ret = ldb_search(ldb, tmp_ctx, &a_res,1075 schema_dn, LDB_SCOPE_ONELEVEL, NULL,1076 "(objectClass=attributeSchema)");1077 if (ret != LDB_SUCCESS) {1078 *error_string_out = talloc_asprintf(mem_ctx,1079 "dsdb_schema: failed to search attributeSchema objects: %s",1080 ldb_errstring(ldb));1081 goto failed;1082 }1083 1084 /*1085 * load the objectClass definitions1086 */1087 ret = ldb_search(ldb, tmp_ctx, &c_res,1088 schema_dn, LDB_SCOPE_ONELEVEL, NULL,1089 "(objectClass=classSchema)");1090 if (ret != LDB_SUCCESS) {1091 *error_string_out = talloc_asprintf(mem_ctx,1092 "dsdb_schema: failed to search attributeSchema objects: %s",1093 ldb_errstring(ldb));1094 goto failed;1095 }1096 1097 ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,1098 lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),1099 schema_res, a_res, c_res, schema, &error_string);1100 if (ret != LDB_SUCCESS) {1101 *error_string_out = talloc_asprintf(mem_ctx,1102 "dsdb_schema load failed: %s",1103 error_string);1104 goto failed;1105 }1106 talloc_steal(mem_ctx, *schema);1107 talloc_free(tmp_ctx);1108 1109 if (flags & LDB_FLG_ENABLE_TRACING) {1110 flags = ldb_get_flags(ldb);1111 ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);1112 }1113 1114 return LDB_SUCCESS;1115 1116 failed:1117 if (flags & LDB_FLG_ENABLE_TRACING) {1118 flags = ldb_get_flags(ldb);1119 ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);1120 }1121 talloc_free(tmp_ctx);1122 return ret;1123 }1124 1125 1126 static const struct {1127 const char *name;1128 const char *oid;1129 } name_mappings[] = {1130 { "cn", "2.5.4.3" },1131 { "name", "1.2.840.113556.1.4.1" },1132 { "lDAPDisplayName", "1.2.840.113556.1.2.460" },1133 { "attributeID", "1.2.840.113556.1.2.30" },1134 { "schemaIDGUID", "1.2.840.113556.1.4.148" },1135 { "mAPIID", "1.2.840.113556.1.2.49" },1136 { "attributeSecurityGUID", "1.2.840.113556.1.4.149" },1137 { "searchFlags", "1.2.840.113556.1.2.334" },1138 { "systemFlags", "1.2.840.113556.1.4.375" },1139 { "isMemberOfPartialAttributeSet", "1.2.840.113556.1.4.639" },1140 { "linkID", "1.2.840.113556.1.2.50" },1141 { "attributeSyntax", "1.2.840.113556.1.2.32" },1142 { "oMSyntax", "1.2.840.113556.1.2.231" },1143 { "oMObjectClass", "1.2.840.113556.1.2.218" },1144 { "isSingleValued", "1.2.840.113556.1.2.33" },1145 { "rangeLower", "1.2.840.113556.1.2.34" },1146 { "rangeUpper", "1.2.840.113556.1.2.35" },1147 { "extendedCharsAllowed", "1.2.840.113556.1.2.380" },1148 { "schemaFlagsEx", "1.2.840.113556.1.4.120" },1149 { "msDs-Schema-Extensions", "1.2.840.113556.1.4.1440" },1150 { "showInAdvancedViewOnly", "1.2.840.113556.1.2.169" },1151 { "adminDisplayName", "1.2.840.113556.1.2.194" },1152 { "adminDescription", "1.2.840.113556.1.2.226" },1153 { "classDisplayName", "1.2.840.113556.1.4.610" },1154 { "isEphemeral", "1.2.840.113556.1.4.1212" },1155 { "isDefunct", "1.2.840.113556.1.4.661" },1156 { "systemOnly", "1.2.840.113556.1.4.170" },1157 { "governsID", "1.2.840.113556.1.2.22" },1158 { "objectClassCategory", "1.2.840.113556.1.2.370" },1159 { "rDNAttID", "1.2.840.113556.1.2.26" },1160 { "defaultObjectCategory", "1.2.840.113556.1.4.783" },1161 { "subClassOf", "1.2.840.113556.1.2.21" },1162 { "systemAuxiliaryClass", "1.2.840.113556.1.4.198" },1163 { "systemPossSuperiors", "1.2.840.113556.1.4.195" },1164 { "systemMustContain", "1.2.840.113556.1.4.197" },1165 { "systemMayContain", "1.2.840.113556.1.4.196" },1166 { "auxiliaryClass", "1.2.840.113556.1.2.351" },1167 { "possSuperiors", "1.2.840.113556.1.2.8" },1168 { "mustContain", "1.2.840.113556.1.2.24" },1169 { "mayContain", "1.2.840.113556.1.2.25" },1170 { "defaultSecurityDescriptor", "1.2.840.113556.1.4.224" },1171 { "defaultHidingValue", "1.2.840.113556.1.4.518" },1172 };1173 1174 static struct drsuapi_DsReplicaAttribute *dsdb_find_object_attr_name(struct dsdb_schema *schema,1175 struct drsuapi_DsReplicaObject *obj,1176 const char *name,1177 uint32_t *idx)1178 {1179 WERROR status;1180 uint32_t i, id;1181 const char *oid = NULL;1182 1183 for(i=0; i < ARRAY_SIZE(name_mappings); i++) {1184 if (strcmp(name_mappings[i].name, name) != 0) continue;1185 1186 oid = name_mappings[i].oid;1187 break;1188 }1189 1190 if (!oid) {1191 return NULL;1192 }1193 1194 status = dsdb_map_oid2int(schema, oid, &id);1195 if (!W_ERROR_IS_OK(status)) {1196 return NULL;1197 }1198 1199 for (i=0; i < obj->attribute_ctr.num_attributes; i++) {1200 if (obj->attribute_ctr.attributes[i].attid != id) continue;1201 1202 if (idx) *idx = i;1203 return &obj->attribute_ctr.attributes[i];1204 }1205 1206 return NULL;1207 }1208 1209 #define GET_STRING_DS(s, r, attr, mem_ctx, p, elem, strict) do { \1210 struct drsuapi_DsReplicaAttribute *_a; \1211 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \1212 if (strict && !_a) { \1213 d_printf("%s: %s == NULL\n", __location__, attr); \1214 return WERR_INVALID_PARAM; \1215 } \1216 if (strict && _a->value_ctr.num_values != 1) { \1217 d_printf("%s: %s num_values == %u\n", __location__, attr, \1218 _a->value_ctr.num_values); \1219 return WERR_INVALID_PARAM; \1220 } \1221 if (_a && _a->value_ctr.num_values >= 1) { \1222 size_t _ret; \1223 if (!convert_string_talloc_convenience(mem_ctx, s->iconv_convenience, CH_UTF16, CH_UNIX, \1224 _a->value_ctr.values[0].blob->data, \1225 _a->value_ctr.values[0].blob->length, \1226 (void **)discard_const(&(p)->elem), &_ret, false)) { \1227 DEBUG(0,("%s: invalid data!\n", attr)); \1228 dump_data(0, \1229 _a->value_ctr.values[0].blob->data, \1230 _a->value_ctr.values[0].blob->length); \1231 return WERR_FOOBAR; \1232 } \1233 } else { \1234 (p)->elem = NULL; \1235 } \1236 } while (0)1237 1238 #define GET_UINT32_LIST_DS(s, r, attr, mem_ctx, p, elem) do { \1239 int list_counter; \1240 struct drsuapi_DsReplicaAttribute *_a; \1241 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \1242 (p)->elem = _a ? talloc_array(mem_ctx, uint32_t, _a->value_ctr.num_values + 1) : NULL; \1243 for (list_counter=0; \1244 _a && list_counter < _a->value_ctr.num_values; \1245 list_counter++) { \1246 if (_a->value_ctr.values[list_counter].blob->length != 4) { \1247 return WERR_INVALID_PARAM; \1248 } \1249 (p)->elem[list_counter] = IVAL(_a->value_ctr.values[list_counter].blob->data, 0); \1250 } \1251 if (_a) (p)->elem[list_counter] = 0; \1252 } while (0)1253 1254 #define GET_DN_DS(s, r, attr, mem_ctx, p, elem, strict) do { \1255 struct drsuapi_DsReplicaAttribute *_a; \1256 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \1257 if (strict && !_a) { \1258 d_printf("%s: %s == NULL\n", __location__, attr); \1259 return WERR_INVALID_PARAM; \1260 } \1261 if (strict && _a->value_ctr.num_values != 1) { \1262 d_printf("%s: %s num_values == %u\n", __location__, attr, \1263 _a->value_ctr.num_values); \1264 return WERR_INVALID_PARAM; \1265 } \1266 if (strict && !_a->value_ctr.values[0].blob) { \1267 d_printf("%s: %s data == NULL\n", __location__, attr); \1268 return WERR_INVALID_PARAM; \1269 } \1270 if (_a && _a->value_ctr.num_values >= 1 \1271 && _a->value_ctr.values[0].blob) { \1272 struct drsuapi_DsReplicaObjectIdentifier3 _id3; \1273 enum ndr_err_code _ndr_err; \1274 _ndr_err = ndr_pull_struct_blob_all(_a->value_ctr.values[0].blob, \1275 mem_ctx, s->iconv_convenience, &_id3,\1276 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);\1277 if (!NDR_ERR_CODE_IS_SUCCESS(_ndr_err)) { \1278 NTSTATUS _nt_status = ndr_map_error2ntstatus(_ndr_err); \1279 return ntstatus_to_werror(_nt_status); \1280 } \1281 (p)->elem = _id3.dn; \1282 } else { \1283 (p)->elem = NULL; \1284 } \1285 } while (0)1286 1287 #define GET_BOOL_DS(s, r, attr, p, elem, strict) do { \1288 struct drsuapi_DsReplicaAttribute *_a; \1289 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \1290 if (strict && !_a) { \1291 d_printf("%s: %s == NULL\n", __location__, attr); \1292 return WERR_INVALID_PARAM; \1293 } \1294 if (strict && _a->value_ctr.num_values != 1) { \1295 d_printf("%s: %s num_values == %u\n", __location__, attr, \1296 (unsigned int)_a->value_ctr.num_values); \1297 return WERR_INVALID_PARAM; \1298 } \1299 if (strict && !_a->value_ctr.values[0].blob) { \1300 d_printf("%s: %s data == NULL\n", __location__, attr); \1301 return WERR_INVALID_PARAM; \1302 } \1303 if (strict && _a->value_ctr.values[0].blob->length != 4) { \1304 d_printf("%s: %s length == %u\n", __location__, attr, \1305 (unsigned int)_a->value_ctr.values[0].blob->length); \1306 return WERR_INVALID_PARAM; \1307 } \1308 if (_a && _a->value_ctr.num_values >= 1 \1309 && _a->value_ctr.values[0].blob \1310 && _a->value_ctr.values[0].blob->length == 4) { \1311 (p)->elem = (IVAL(_a->value_ctr.values[0].blob->data,0)?true:false);\1312 } else { \1313 (p)->elem = false; \1314 } \1315 } while (0)1316 1317 #define GET_UINT32_DS(s, r, attr, p, elem) do { \1318 struct drsuapi_DsReplicaAttribute *_a; \1319 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \1320 if (_a && _a->value_ctr.num_values >= 1 \1321 && _a->value_ctr.values[0].blob \1322 && _a->value_ctr.values[0].blob->length == 4) { \1323 (p)->elem = IVAL(_a->value_ctr.values[0].blob->data,0);\1324 } else { \1325 (p)->elem = 0; \1326 } \1327 } while (0)1328 1329 #define GET_UINT32_PTR_DS(s, r, attr, p, elem) do { \1330 struct drsuapi_DsReplicaAttribute *_a; \1331 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \1332 if (_a && _a->value_ctr.num_values >= 1 \1333 && _a->value_ctr.values[0].blob \1334 && _a->value_ctr.values[0].blob->length == 4) { \1335 (p)->elem = talloc(mem_ctx, uint32_t); \1336 if (!(p)->elem) { \1337 d_printf("%s: talloc failed for %s\n", __location__, attr); \1338 return WERR_NOMEM; \1339 } \1340 *(p)->elem = IVAL(_a->value_ctr.values[0].blob->data,0);\1341 } else { \1342 (p)->elem = NULL; \1343 } \1344 } while (0)1345 1346 #define GET_GUID_DS(s, r, attr, mem_ctx, p, elem) do { \1347 struct drsuapi_DsReplicaAttribute *_a; \1348 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \1349 if (_a && _a->value_ctr.num_values >= 1 \1350 && _a->value_ctr.values[0].blob \1351 && _a->value_ctr.values[0].blob->length == 16) { \1352 enum ndr_err_code _ndr_err; \1353 _ndr_err = ndr_pull_struct_blob_all(_a->value_ctr.values[0].blob, \1354 mem_ctx, s->iconv_convenience, &(p)->elem, \1355 (ndr_pull_flags_fn_t)ndr_pull_GUID); \1356 if (!NDR_ERR_CODE_IS_SUCCESS(_ndr_err)) { \1357 NTSTATUS _nt_status = ndr_map_error2ntstatus(_ndr_err); \1358 return ntstatus_to_werror(_nt_status); \1359 } \1360 } else { \1361 ZERO_STRUCT((p)->elem);\1362 } \1363 } while (0)1364 1365 #define GET_BLOB_DS(s, r, attr, mem_ctx, p, elem) do { \1366 struct drsuapi_DsReplicaAttribute *_a; \1367 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \1368 if (_a && _a->value_ctr.num_values >= 1 \1369 && _a->value_ctr.values[0].blob) { \1370 (p)->elem = *_a->value_ctr.values[0].blob;\1371 talloc_steal(mem_ctx, (p)->elem.data); \1372 } else { \1373 ZERO_STRUCT((p)->elem);\1374 }\1375 } while (0)1376 1377 WERROR dsdb_attribute_from_drsuapi(struct ldb_context *ldb,1378 struct dsdb_schema *schema,1379 struct drsuapi_DsReplicaObject *r,1380 TALLOC_CTX *mem_ctx,1381 struct dsdb_attribute *attr)1382 {1383 WERROR status;1384 1385 GET_STRING_DS(schema, r, "name", mem_ctx, attr, cn, true);1386 GET_STRING_DS(schema, r, "lDAPDisplayName", mem_ctx, attr, lDAPDisplayName, true);1387 GET_UINT32_DS(schema, r, "attributeID", attr, attributeID_id);1388 status = dsdb_map_int2oid(schema, attr->attributeID_id, mem_ctx, &attr->attributeID_oid);1389 if (!W_ERROR_IS_OK(status)) {1390 DEBUG(0,("%s: '%s': unable to map attributeID 0x%08X: %s\n",1391 __location__, attr->lDAPDisplayName, attr->attributeID_id,1392 win_errstr(status)));1393 return status;1394 }1395 GET_GUID_DS(schema, r, "schemaIDGUID", mem_ctx, attr, schemaIDGUID);1396 GET_UINT32_DS(schema, r, "mAPIID", attr, mAPIID);1397 1398 GET_GUID_DS(schema, r, "attributeSecurityGUID", mem_ctx, attr, attributeSecurityGUID);1399 1400 GET_UINT32_DS(schema, r, "searchFlags", attr, searchFlags);1401 GET_UINT32_DS(schema, r, "systemFlags", attr, systemFlags);1402 GET_BOOL_DS(schema, r, "isMemberOfPartialAttributeSet", attr, isMemberOfPartialAttributeSet, false);1403 GET_UINT32_DS(schema, r, "linkID", attr, linkID);1404 1405 GET_UINT32_DS(schema, r, "attributeSyntax", attr, attributeSyntax_id);1406 status = dsdb_map_int2oid(schema, attr->attributeSyntax_id, mem_ctx, &attr->attributeSyntax_oid);1407 if (!W_ERROR_IS_OK(status)) {1408 DEBUG(0,("%s: '%s': unable to map attributeSyntax 0x%08X: %s\n",1409 __location__, attr->lDAPDisplayName, attr->attributeSyntax_id,1410 win_errstr(status)));1411 return status;1412 }1413 GET_UINT32_DS(schema, r, "oMSyntax", attr, oMSyntax);1414 GET_BLOB_DS(schema, r, "oMObjectClass", mem_ctx, attr, oMObjectClass);1415 1416 GET_BOOL_DS(schema, r, "isSingleValued", attr, isSingleValued, true);1417 GET_UINT32_PTR_DS(schema, r, "rangeLower", attr, rangeLower);1418 GET_UINT32_PTR_DS(schema, r, "rangeUpper", attr, rangeUpper);1419 GET_BOOL_DS(schema, r, "extendedCharsAllowed", attr, extendedCharsAllowed, false);1420 1421 GET_UINT32_DS(schema, r, "schemaFlagsEx", attr, schemaFlagsEx);1422 GET_BLOB_DS(schema, r, "msDs-Schema-Extensions", mem_ctx, attr, msDs_Schema_Extensions);1423 1424 GET_BOOL_DS(schema, r, "showInAdvancedViewOnly", attr, showInAdvancedViewOnly, false);1425 GET_STRING_DS(schema, r, "adminDisplayName", mem_ctx, attr, adminDisplayName, false);1426 GET_STRING_DS(schema, r, "adminDescription", mem_ctx, attr, adminDescription, false);1427 GET_STRING_DS(schema, r, "classDisplayName", mem_ctx, attr, classDisplayName, false);1428 GET_BOOL_DS(schema, r, "isEphemeral", attr, isEphemeral, false);1429 GET_BOOL_DS(schema, r, "isDefunct", attr, isDefunct, false);1430 GET_BOOL_DS(schema, r, "systemOnly", attr, systemOnly, false);1431 1432 attr->syntax = dsdb_syntax_for_attribute(attr);1433 if (!attr->syntax) {1434 return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;1435 }1436 1437 if (dsdb_schema_setup_ldb_schema_attribute(ldb, attr) != LDB_SUCCESS) {1438 return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;1439 }1440 1441 return WERR_OK;1442 }1443 1444 WERROR dsdb_class_from_drsuapi(struct dsdb_schema *schema,1445 struct drsuapi_DsReplicaObject *r,1446 TALLOC_CTX *mem_ctx,1447 struct dsdb_class *obj)1448 {1449 WERROR status;1450 1451 GET_STRING_DS(schema, r, "name", mem_ctx, obj, cn, true);1452 GET_STRING_DS(schema, r, "lDAPDisplayName", mem_ctx, obj, lDAPDisplayName, true);1453 GET_UINT32_DS(schema, r, "governsID", obj, governsID_id);1454 status = dsdb_map_int2oid(schema, obj->governsID_id, mem_ctx, &obj->governsID_oid);1455 if (!W_ERROR_IS_OK(status)) {1456 DEBUG(0,("%s: '%s': unable to map governsID 0x%08X: %s\n",1457 __location__, obj->lDAPDisplayName, obj->governsID_id,1458 win_errstr(status)));1459 return status;1460 }1461 GET_GUID_DS(schema, r, "schemaIDGUID", mem_ctx, obj, schemaIDGUID);1462 1463 GET_UINT32_DS(schema, r, "objectClassCategory", obj, objectClassCategory);1464 GET_STRING_DS(schema, r, "rDNAttID", mem_ctx, obj, rDNAttID, false);1465 GET_DN_DS(schema, r, "defaultObjectCategory", mem_ctx, obj, defaultObjectCategory, true);1466 1467 GET_UINT32_DS(schema, r, "subClassOf", obj, subClassOf_id);1468 1469 GET_UINT32_LIST_DS(schema, r, "systemAuxiliaryClass", mem_ctx, obj, systemAuxiliaryClass_ids);1470 GET_UINT32_LIST_DS(schema, r, "auxiliaryClass", mem_ctx, obj, auxiliaryClass_ids);1471 1472 GET_UINT32_LIST_DS(schema, r, "systemMustContain", mem_ctx, obj, systemMustContain_ids);1473 GET_UINT32_LIST_DS(schema, r, "systemMayContain", mem_ctx, obj, systemMayContain_ids);1474 GET_UINT32_LIST_DS(schema, r, "mustContain", mem_ctx, obj, mustContain_ids);1475 GET_UINT32_LIST_DS(schema, r, "mayContain", mem_ctx, obj, mayContain_ids);1476 1477 GET_UINT32_LIST_DS(schema, r, "systemPossSuperiors", mem_ctx, obj, systemPossSuperiors_ids);1478 GET_UINT32_LIST_DS(schema, r, "possSuperiors", mem_ctx, obj, possSuperiors_ids);1479 1480 GET_STRING_DS(schema, r, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, false);1481 1482 GET_UINT32_DS(schema, r, "schemaFlagsEx", obj, schemaFlagsEx);1483 GET_BLOB_DS(schema, r, "msDs-Schema-Extensions", mem_ctx, obj, msDs_Schema_Extensions);1484 1485 GET_BOOL_DS(schema, r, "showInAdvancedViewOnly", obj, showInAdvancedViewOnly, false);1486 GET_STRING_DS(schema, r, "adminDisplayName", mem_ctx, obj, adminDisplayName, false);1487 GET_STRING_DS(schema, r, "adminDescription", mem_ctx, obj, adminDescription, false);1488 GET_STRING_DS(schema, r, "classDisplayName", mem_ctx, obj, classDisplayName, false);1489 GET_BOOL_DS(schema, r, "defaultHidingValue", obj, defaultHidingValue, false);1490 GET_BOOL_DS(schema, r, "isDefunct", obj, isDefunct, false);1491 GET_BOOL_DS(schema, r, "systemOnly", obj, systemOnly, false);1492 1493 return WERR_OK;1494 }1495 -
vendor/current/source4/dsdb/schema/schema_query.c
r414 r740 23 23 #include "includes.h" 24 24 #include "dsdb/samdb/samdb.h" 25 26 /* a binary array search, where the array is an array of pointers to structures, 27 and we want to find a match for 'target' on 'field' in those structures. 28 29 Inputs: 30 array: base pointer to an array of structures 31 arrray_size: number of elements in the array 32 field: the name of the field in the structure we are keying off 33 target: the field value we are looking for 34 comparison_fn: the comparison function 35 result: where the result of the search is put 36 37 if the element is found, then 'result' is set to point to the found array element. If not, 38 then 'result' is set to NULL. 39 40 The array is assumed to be sorted by the same comparison_fn as the 41 search (with, for example, qsort) 42 */ 43 #define BINARY_ARRAY_SEARCH(array, array_size, field, target, comparison_fn, result) do { \ 44 int32_t _b, _e; \ 45 (result) = NULL; \ 46 for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ 47 int32_t _i = (_b+_e)/2; \ 48 int _r = comparison_fn(target, array[_i]->field); \ 49 if (_r == 0) { (result) = array[_i]; break; } \ 50 if (_r < 0) _e = _i - 1; else _b = _i + 1; \ 51 } } while (0) 52 25 #include "lib/util/binsearch.h" 26 #include "lib/util/tsort.h" 53 27 54 28 static const char **dsdb_full_attribute_list_internal(TALLOC_CTX *mem_ctx, … … 59 33 static int uint32_cmp(uint32_t c1, uint32_t c2) 60 34 { 61 return c1 - c2; 35 if (c1 == c2) return 0; 36 return c1 > c2 ? 1 : -1; 62 37 } 63 38 … … 66 41 int ret = strncasecmp((const char *)target->data, str, target->length); 67 42 if (ret == 0) { 68 return (target->length - strlen(str)); 43 size_t len = strlen(str); 44 if (target->length > len) { 45 if (target->data[len] == 0) { 46 return 0; 47 } 48 return 1; 49 } 50 return (target->length - len); 69 51 } 70 52 return ret; … … 82 64 if (id == 0xFFFFFFFF) return NULL; 83 65 84 BINARY_ARRAY_SEARCH(schema->attributes_by_attributeID_id, 85 schema->num_attributes, attributeID_id, id, uint32_cmp, c); 66 /* check for msDS-IntId type attribute */ 67 if (dsdb_pfm_get_attid_type(id) == DSDB_ATTID_TYPE_INTID) { 68 BINARY_ARRAY_SEARCH_P(schema->attributes_by_msDS_IntId, 69 schema->num_int_id_attr, msDS_IntId, id, uint32_cmp, c); 70 return c; 71 } 72 73 BINARY_ARRAY_SEARCH_P(schema->attributes_by_attributeID_id, 74 schema->num_attributes, attributeID_id, id, uint32_cmp, c); 86 75 return c; 87 76 } … … 94 83 if (!oid) return NULL; 95 84 96 BINARY_ARRAY_SEARCH (schema->attributes_by_attributeID_oid,97 schema->num_attributes, attributeID_oid, oid, strcasecmp, c);85 BINARY_ARRAY_SEARCH_P(schema->attributes_by_attributeID_oid, 86 schema->num_attributes, attributeID_oid, oid, strcasecmp, c); 98 87 return c; 99 88 } … … 106 95 if (!name) return NULL; 107 96 108 BINARY_ARRAY_SEARCH(schema->attributes_by_lDAPDisplayName, 109 schema->num_attributes, lDAPDisplayName, name, strcasecmp, c); 110 return c; 97 BINARY_ARRAY_SEARCH_P(schema->attributes_by_lDAPDisplayName, 98 schema->num_attributes, lDAPDisplayName, name, strcasecmp, c); 99 return c; 100 } 101 102 const struct dsdb_attribute *dsdb_attribute_by_lDAPDisplayName_ldb_val(const struct dsdb_schema *schema, 103 const struct ldb_val *name) 104 { 105 struct dsdb_attribute *a; 106 107 if (!name) return NULL; 108 109 BINARY_ARRAY_SEARCH_P(schema->attributes_by_lDAPDisplayName, 110 schema->num_attributes, lDAPDisplayName, name, strcasecmp_with_ldb_val, a); 111 return a; 111 112 } 112 113 … … 116 117 struct dsdb_attribute *c; 117 118 118 BINARY_ARRAY_SEARCH (schema->attributes_by_linkID,119 schema->num_attributes, linkID, linkID, uint32_cmp, c);119 BINARY_ARRAY_SEARCH_P(schema->attributes_by_linkID, 120 schema->num_attributes, linkID, linkID, uint32_cmp, c); 120 121 return c; 121 122 } … … 132 133 if (id == 0xFFFFFFFF) return NULL; 133 134 134 BINARY_ARRAY_SEARCH (schema->classes_by_governsID_id,135 schema->num_classes, governsID_id, id, uint32_cmp, c);135 BINARY_ARRAY_SEARCH_P(schema->classes_by_governsID_id, 136 schema->num_classes, governsID_id, id, uint32_cmp, c); 136 137 return c; 137 138 } … … 142 143 struct dsdb_class *c; 143 144 if (!oid) return NULL; 144 BINARY_ARRAY_SEARCH (schema->classes_by_governsID_oid,145 schema->num_classes, governsID_oid, oid, strcasecmp, c);145 BINARY_ARRAY_SEARCH_P(schema->classes_by_governsID_oid, 146 schema->num_classes, governsID_oid, oid, strcasecmp, c); 146 147 return c; 147 148 } … … 152 153 struct dsdb_class *c; 153 154 if (!name) return NULL; 154 BINARY_ARRAY_SEARCH (schema->classes_by_lDAPDisplayName,155 schema->num_classes, lDAPDisplayName, name, strcasecmp, c);155 BINARY_ARRAY_SEARCH_P(schema->classes_by_lDAPDisplayName, 156 schema->num_classes, lDAPDisplayName, name, strcasecmp, c); 156 157 return c; 157 158 } … … 162 163 struct dsdb_class *c; 163 164 if (!name) return NULL; 164 BINARY_ARRAY_SEARCH (schema->classes_by_lDAPDisplayName,165 schema->num_classes, lDAPDisplayName, name, strcasecmp_with_ldb_val, c);165 BINARY_ARRAY_SEARCH_P(schema->classes_by_lDAPDisplayName, 166 schema->num_classes, lDAPDisplayName, name, strcasecmp_with_ldb_val, c); 166 167 return c; 167 168 } … … 172 173 struct dsdb_class *c; 173 174 if (!cn) return NULL; 174 BINARY_ARRAY_SEARCH (schema->classes_by_cn,175 schema->num_classes, cn, cn, strcasecmp, c);175 BINARY_ARRAY_SEARCH_P(schema->classes_by_cn, 176 schema->num_classes, cn, cn, strcasecmp, c); 176 177 return c; 177 178 } … … 182 183 struct dsdb_class *c; 183 184 if (!cn) return NULL; 184 BINARY_ARRAY_SEARCH (schema->classes_by_cn,185 schema->num_classes, cn, cn, strcasecmp_with_ldb_val, c);185 BINARY_ARRAY_SEARCH_P(schema->classes_by_cn, 186 schema->num_classes, cn, cn, strcasecmp_with_ldb_val, c); 186 187 return c; 187 188 } … … 217 218 const char **attr_list = NULL; 218 219 struct dsdb_attribute *cur; 219 int i = 0;220 unsigned int i = 0; 220 221 for (cur = schema->attributes; cur; cur = cur->next) { 221 222 if (cur->linkID == 0) continue; … … 237 238 { 238 239 const char **ret_attrs; 239 int i;240 unsigned int i; 240 241 size_t new_len, orig_len = str_list_length(attrs); 241 242 if (!new_attrs) { … … 337 338 enum dsdb_attr_list_query query) 338 339 { 339 int i;340 unsigned int i; 340 341 const char **attr_list = NULL; 341 342 … … 364 365 enum dsdb_attr_list_query query) 365 366 { 366 int i;367 unsigned int i; 367 368 const char **attr_list = NULL; 368 369 … … 378 379 } 379 380 381 static int qsort_string(const char **s1, const char **s2) 382 { 383 return strcasecmp(*s1, *s2); 384 } 385 380 386 /* Helper function to remove duplicates from the attribute list to be returned */ 381 387 static const char **dedup_attr_list(const char **attr_list) … … 384 390 /* Remove duplicates */ 385 391 if (new_len > 1) { 386 int i; 387 qsort(attr_list, new_len, 388 sizeof(*attr_list), 389 (comparison_fn_t)strcasecmp); 390 391 for (i=1 ; i < new_len; i++) { 392 size_t i; 393 TYPESAFE_QSORT(attr_list, new_len, qsort_string); 394 395 for (i=1; i < new_len; i++) { 392 396 const char **val1 = &attr_list[i-1]; 393 397 const char **val2 = &attr_list[i]; 394 398 if (ldb_attr_cmp(*val1, *val2) == 0) { 395 399 memmove(val1, val2, (new_len - i) * sizeof( *attr_list)); 400 attr_list[new_len-1] = NULL; 396 401 new_len--; 397 402 i--; … … 420 425 /* Return the schemaIDGUID of a class */ 421 426 422 const struct GUID * 423 427 const struct GUID *class_schemaid_guid_by_lDAPDisplayName(const struct dsdb_schema *schema, 428 const char *name) 424 429 { 425 430 const struct dsdb_class *object_class = dsdb_class_by_lDAPDisplayName(schema, name); … … 429 434 return &object_class->schemaIDGUID; 430 435 } 436 437 const struct GUID *attribute_schemaid_guid_by_lDAPDisplayName(const struct dsdb_schema *schema, 438 const char *name) 439 { 440 const struct dsdb_attribute *attr = dsdb_attribute_by_lDAPDisplayName(schema, name); 441 if (!attr) 442 return NULL; 443 444 return &attr->schemaIDGUID; 445 } -
vendor/current/source4/dsdb/schema/schema_set.c
r414 r740 1 /* 2 Unix SMB/CIFS mplementation.1 /* 2 Unix SMB/CIFS implementation. 3 3 DSDB schema header 4 4 5 5 Copyright (C) Stefan Metzmacher <metze@samba.org> 2006-2007 6 6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2008 … … 10 10 the Free Software Foundation; either version 3 of the License, or 11 11 (at your option) any later version. 12 12 13 13 This program is distributed in the hope that it will be useful, 14 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 16 GNU General Public License for more details. 17 17 18 18 You should have received a copy of the GNU General Public License 19 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20 20 21 21 */ 22 22 … … 24 24 #include "lib/util/dlinklist.h" 25 25 #include "dsdb/samdb/samdb.h" 26 #include "lib/ldb/include/ldb_module.h"26 #include <ldb_module.h> 27 27 #include "param/param.h" 28 #include "librpc/ndr/libndr.h" 29 #include "librpc/gen_ndr/ndr_misc.h" 30 #include "lib/util/tsort.h" 28 31 29 32 /* 30 33 override the name to attribute handler function 31 34 */ 32 const struct ldb_schema_attribute *dsdb_attribute_handler_override(struct ldb_context *ldb, 35 const struct ldb_schema_attribute *dsdb_attribute_handler_override(struct ldb_context *ldb, 33 36 void *private_data, 34 37 const char *name) … … 63 66 mem_ctx = talloc_new(ldb); 64 67 if (!mem_ctx) { 65 return LDB_ERR_OPERATIONS_ERROR;68 return ldb_oom(ldb); 66 69 } 67 70 … … 81 84 goto op_error; 82 85 } 83 msg_idx->dn = ldb_dn_new(msg , ldb, "@INDEXLIST");86 msg_idx->dn = ldb_dn_new(msg_idx, ldb, "@INDEXLIST"); 84 87 if (!msg_idx->dn) { 85 88 ldb_oom(ldb); … … 94 97 for (attr = schema->attributes; attr; attr = attr->next) { 95 98 const char *syntax = attr->syntax->ldb_syntax; 96 99 97 100 if (!syntax) { 98 101 syntax = attr->syntax->ldap_oid; 99 102 } 100 103 101 /* Write out a rough approximation of the schema as an @ATTRIBUTES value, for bootstrapping */ 104 /* 105 * Write out a rough approximation of the schema 106 * as an @ATTRIBUTES value, for bootstrapping 107 */ 102 108 if (strcmp(syntax, LDB_SYNTAX_INTEGER) == 0) { 103 109 ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "INTEGER"); 104 110 } else if (strcmp(syntax, LDB_SYNTAX_DIRECTORY_STRING) == 0) { 105 111 ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "CASE_INSENSITIVE"); 106 } 112 } 107 113 if (ret != LDB_SUCCESS) { 108 114 break; … … 122 128 } 123 129 124 /* Try to avoid churning the attributes too much - we only want to do this if they have changed */ 125 ret = ldb_search(ldb, mem_ctx, &res, msg->dn, LDB_SCOPE_BASE, NULL, "dn=%s", ldb_dn_get_linearized(msg->dn)); 130 /* 131 * Try to avoid churning the attributes too much, 132 * we only want to do this if they have changed 133 */ 134 ret = ldb_search(ldb, mem_ctx, &res, msg->dn, LDB_SCOPE_BASE, NULL, 135 NULL); 126 136 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 127 137 ret = ldb_add(ldb, msg); … … 133 143 /* Annoyingly added to our search results */ 134 144 ldb_msg_remove_attr(res->msgs[0], "distinguishedName"); 135 136 mod_msg = ldb_msg_diff(ldb, res->msgs[0], msg); 145 146 ret = ldb_msg_difference(ldb, mem_ctx, 147 res->msgs[0], msg, &mod_msg); 148 if (ret != LDB_SUCCESS) { 149 goto op_error; 150 } 137 151 if (mod_msg->num_elements > 0) { 138 ret = samdb_replace(ldb, mem_ctx, mod_msg); 139 } 140 } 141 142 if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { 143 /* We might be on a read-only DB */ 152 ret = dsdb_replace(ldb, mod_msg, 0); 153 } 154 talloc_free(mod_msg); 155 } 156 157 if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS || ret == LDB_ERR_INVALID_DN_SYNTAX) { 158 /* We might be on a read-only DB or LDAP */ 144 159 ret = LDB_SUCCESS; 145 160 } … … 149 164 } 150 165 151 /* Now write out the indexs, as found in the schema (if they have changed) */ 152 153 ret = ldb_search(ldb, mem_ctx, &res_idx, msg_idx->dn, LDB_SCOPE_BASE, NULL, "dn=%s", ldb_dn_get_linearized(msg_idx->dn)); 166 /* Now write out the indexes, as found in the schema (if they have changed) */ 167 168 ret = ldb_search(ldb, mem_ctx, &res_idx, msg_idx->dn, LDB_SCOPE_BASE, 169 NULL, NULL); 154 170 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 155 171 ret = ldb_add(ldb, msg_idx); … … 162 178 ldb_msg_remove_attr(res_idx->msgs[0], "distinguishedName"); 163 179 164 mod_msg = ldb_msg_diff(ldb, res_idx->msgs[0], msg_idx); 180 ret = ldb_msg_difference(ldb, mem_ctx, 181 res_idx->msgs[0], msg_idx, &mod_msg); 182 if (ret != LDB_SUCCESS) { 183 goto op_error; 184 } 165 185 if (mod_msg->num_elements > 0) { 166 ret = samdb_replace(ldb, mem_ctx, mod_msg); 167 } 168 } 169 if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { 186 ret = dsdb_replace(ldb, mod_msg, 0); 187 } 188 talloc_free(mod_msg); 189 } 190 if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS || ret == LDB_ERR_INVALID_DN_SYNTAX) { 170 191 /* We might be on a read-only DB */ 171 192 ret = LDB_SUCCESS; … … 176 197 op_error: 177 198 talloc_free(mem_ctx); 178 return LDB_ERR_OPERATIONS_ERROR; 199 return ldb_operr(ldb); 200 } 201 202 static int uint32_cmp(uint32_t c1, uint32_t c2) 203 { 204 if (c1 == c2) return 0; 205 return c1 > c2 ? 1 : -1; 179 206 } 180 207 … … 185 212 static int dsdb_compare_class_by_governsID_id(struct dsdb_class **c1, struct dsdb_class **c2) 186 213 { 187 return (*c1)->governsID_id - (*c2)->governsID_id;214 return uint32_cmp((*c1)->governsID_id, (*c2)->governsID_id); 188 215 } 189 216 static int dsdb_compare_class_by_governsID_oid(struct dsdb_class **c1, struct dsdb_class **c2) … … 202 229 static int dsdb_compare_attribute_by_attributeID_id(struct dsdb_attribute **a1, struct dsdb_attribute **a2) 203 230 { 204 return (*a1)->attributeID_id - (*a2)->attributeID_id; 231 return uint32_cmp((*a1)->attributeID_id, (*a2)->attributeID_id); 232 } 233 static int dsdb_compare_attribute_by_msDS_IntId(struct dsdb_attribute **a1, struct dsdb_attribute **a2) 234 { 235 return uint32_cmp((*a1)->msDS_IntId, (*a2)->msDS_IntId); 205 236 } 206 237 static int dsdb_compare_attribute_by_attributeID_oid(struct dsdb_attribute **a1, struct dsdb_attribute **a2) … … 210 241 static int dsdb_compare_attribute_by_linkID(struct dsdb_attribute **a1, struct dsdb_attribute **a2) 211 242 { 212 return (*a1)->linkID - (*a2)->linkID; 243 return uint32_cmp((*a1)->linkID, (*a2)->linkID); 244 } 245 246 /** 247 * Clean up Classes and Attributes accessor arrays 248 */ 249 static void dsdb_sorted_accessors_free(struct dsdb_schema *schema) 250 { 251 /* free classes accessors */ 252 TALLOC_FREE(schema->classes_by_lDAPDisplayName); 253 TALLOC_FREE(schema->classes_by_governsID_id); 254 TALLOC_FREE(schema->classes_by_governsID_oid); 255 TALLOC_FREE(schema->classes_by_cn); 256 /* free attribute accessors */ 257 TALLOC_FREE(schema->attributes_by_lDAPDisplayName); 258 TALLOC_FREE(schema->attributes_by_attributeID_id); 259 TALLOC_FREE(schema->attributes_by_msDS_IntId); 260 TALLOC_FREE(schema->attributes_by_attributeID_oid); 261 TALLOC_FREE(schema->attributes_by_linkID); 213 262 } 214 263 … … 216 265 create the sorted accessor arrays for the schema 217 266 */ 218 staticint dsdb_setup_sorted_accessors(struct ldb_context *ldb,219 267 int dsdb_setup_sorted_accessors(struct ldb_context *ldb, 268 struct dsdb_schema *schema) 220 269 { 221 270 struct dsdb_class *cur; 222 271 struct dsdb_attribute *a; 223 uint32_t i; 224 225 talloc_free(schema->classes_by_lDAPDisplayName); 226 talloc_free(schema->classes_by_governsID_id); 227 talloc_free(schema->classes_by_governsID_oid); 228 talloc_free(schema->classes_by_cn); 272 unsigned int i; 273 unsigned int num_int_id; 274 275 /* free all caches */ 276 dsdb_sorted_accessors_free(schema); 229 277 230 278 /* count the classes */ … … 252 300 253 301 /* sort the arrays */ 254 qsort(schema->classes_by_lDAPDisplayName, schema->num_classes, 255 sizeof(struct dsdb_class *), QSORT_CAST dsdb_compare_class_by_lDAPDisplayName); 256 qsort(schema->classes_by_governsID_id, schema->num_classes, 257 sizeof(struct dsdb_class *), QSORT_CAST dsdb_compare_class_by_governsID_id); 258 qsort(schema->classes_by_governsID_oid, schema->num_classes, 259 sizeof(struct dsdb_class *), QSORT_CAST dsdb_compare_class_by_governsID_oid); 260 qsort(schema->classes_by_cn, schema->num_classes, 261 sizeof(struct dsdb_class *), QSORT_CAST dsdb_compare_class_by_cn); 302 TYPESAFE_QSORT(schema->classes_by_lDAPDisplayName, schema->num_classes, dsdb_compare_class_by_lDAPDisplayName); 303 TYPESAFE_QSORT(schema->classes_by_governsID_id, schema->num_classes, dsdb_compare_class_by_governsID_id); 304 TYPESAFE_QSORT(schema->classes_by_governsID_oid, schema->num_classes, dsdb_compare_class_by_governsID_oid); 305 TYPESAFE_QSORT(schema->classes_by_cn, schema->num_classes, dsdb_compare_class_by_cn); 262 306 263 307 /* now build the attribute accessor arrays */ 264 talloc_free(schema->attributes_by_lDAPDisplayName); 265 talloc_free(schema->attributes_by_attributeID_id); 266 talloc_free(schema->attributes_by_attributeID_oid); 267 talloc_free(schema->attributes_by_linkID); 268 269 /* count the attributes */ 270 for (i=0, a=schema->attributes; a; i++, a=a->next) /* noop */ ; 308 309 /* count the attributes 310 * and attributes with msDS-IntId set */ 311 num_int_id = 0; 312 for (i=0, a=schema->attributes; a; i++, a=a->next) { 313 if (a->msDS_IntId != 0) { 314 num_int_id++; 315 } 316 } 271 317 schema->num_attributes = i; 318 schema->num_int_id_attr = num_int_id; 272 319 273 320 /* setup attributes_by_* */ 274 321 schema->attributes_by_lDAPDisplayName = talloc_array(schema, struct dsdb_attribute *, i); 275 322 schema->attributes_by_attributeID_id = talloc_array(schema, struct dsdb_attribute *, i); 323 schema->attributes_by_msDS_IntId = talloc_array(schema, 324 struct dsdb_attribute *, num_int_id); 276 325 schema->attributes_by_attributeID_oid = talloc_array(schema, struct dsdb_attribute *, i); 277 326 schema->attributes_by_linkID = talloc_array(schema, struct dsdb_attribute *, i); 278 327 if (schema->attributes_by_lDAPDisplayName == NULL || 279 328 schema->attributes_by_attributeID_id == NULL || 329 schema->attributes_by_msDS_IntId == NULL || 280 330 schema->attributes_by_attributeID_oid == NULL || 281 331 schema->attributes_by_linkID == NULL) { … … 283 333 } 284 334 335 num_int_id = 0; 285 336 for (i=0, a=schema->attributes; a; i++, a=a->next) { 286 337 schema->attributes_by_lDAPDisplayName[i] = a; … … 288 339 schema->attributes_by_attributeID_oid[i] = a; 289 340 schema->attributes_by_linkID[i] = a; 290 } 341 /* append attr-by-msDS-IntId values */ 342 if (a->msDS_IntId != 0) { 343 schema->attributes_by_msDS_IntId[num_int_id] = a; 344 num_int_id++; 345 } 346 } 347 SMB_ASSERT(num_int_id == schema->num_int_id_attr); 291 348 292 349 /* sort the arrays */ 293 qsort(schema->attributes_by_lDAPDisplayName, schema->num_attributes, 294 sizeof(struct dsdb_attribute *), QSORT_CAST dsdb_compare_attribute_by_lDAPDisplayName); 295 qsort(schema->attributes_by_attributeID_id, schema->num_attributes, 296 sizeof(struct dsdb_attribute *), QSORT_CAST dsdb_compare_attribute_by_attributeID_id); 297 qsort(schema->attributes_by_attributeID_oid, schema->num_attributes, 298 sizeof(struct dsdb_attribute *), QSORT_CAST dsdb_compare_attribute_by_attributeID_oid); 299 qsort(schema->attributes_by_linkID, schema->num_attributes, 300 sizeof(struct dsdb_attribute *), QSORT_CAST dsdb_compare_attribute_by_linkID); 350 TYPESAFE_QSORT(schema->attributes_by_lDAPDisplayName, schema->num_attributes, dsdb_compare_attribute_by_lDAPDisplayName); 351 TYPESAFE_QSORT(schema->attributes_by_attributeID_id, schema->num_attributes, dsdb_compare_attribute_by_attributeID_id); 352 TYPESAFE_QSORT(schema->attributes_by_msDS_IntId, schema->num_int_id_attr, dsdb_compare_attribute_by_msDS_IntId); 353 TYPESAFE_QSORT(schema->attributes_by_attributeID_oid, schema->num_attributes, dsdb_compare_attribute_by_attributeID_oid); 354 TYPESAFE_QSORT(schema->attributes_by_linkID, schema->num_attributes, dsdb_compare_attribute_by_linkID); 301 355 302 356 return LDB_SUCCESS; 303 357 304 358 failed: 305 schema->classes_by_lDAPDisplayName = NULL; 306 schema->classes_by_governsID_id = NULL; 307 schema->classes_by_governsID_oid = NULL; 308 schema->classes_by_cn = NULL; 309 schema->attributes_by_lDAPDisplayName = NULL; 310 schema->attributes_by_attributeID_id = NULL; 311 schema->attributes_by_attributeID_oid = NULL; 312 schema->attributes_by_linkID = NULL; 313 ldb_oom(ldb); 314 return LDB_ERR_OPERATIONS_ERROR; 359 dsdb_sorted_accessors_free(schema); 360 return ldb_oom(ldb); 315 361 } 316 362 … … 327 373 * objectClass lists efficiently) */ 328 374 329 /* Walk the list of sche amclasses */330 375 /* Walk the list of schema classes */ 376 331 377 /* Create a 'total possible superiors' on each class */ 332 378 return LDB_SUCCESS; … … 334 380 335 381 /** 336 * Attach the schema to an opaque pointer on the ldb, so ldb modules 337 * can find it 338 */ 339 382 * Attach the schema to an opaque pointer on the ldb, 383 * so ldb modules can find it 384 */ 340 385 int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema) 341 386 { 387 struct dsdb_schema *old_schema; 342 388 int ret; 343 389 … … 347 393 } 348 394 349 schema_fill_constructed(schema); 395 ret = schema_fill_constructed(schema); 396 if (ret != LDB_SUCCESS) { 397 return ret; 398 } 399 400 old_schema = ldb_get_opaque(ldb, "dsdb_schema"); 350 401 351 402 ret = ldb_set_opaque(ldb, "dsdb_schema", schema); 403 if (ret != LDB_SUCCESS) { 404 return ret; 405 } 406 407 /* Remove the reference to the schema we just overwrote - if there was 408 * none, NULL is harmless here */ 409 if (old_schema != schema) { 410 talloc_unlink(ldb, old_schema); 411 talloc_steal(ldb, schema); 412 } 413 414 ret = ldb_set_opaque(ldb, "dsdb_use_global_schema", NULL); 352 415 if (ret != LDB_SUCCESS) { 353 416 return ret; … … 360 423 } 361 424 362 talloc_steal(ldb, schema);363 364 425 return LDB_SUCCESS; 365 426 } … … 377 438 { 378 439 int ret; 440 struct dsdb_schema *old_schema; 441 old_schema = ldb_get_opaque(ldb, "dsdb_schema"); 379 442 ret = ldb_set_opaque(ldb, "dsdb_schema", schema); 380 443 if (ret != LDB_SUCCESS) { … … 382 445 } 383 446 384 /* Set the new attributes based on the new schema */ 447 /* Remove the reference to the schema we just overwrote - if there was 448 * none, NULL is harmless here */ 449 talloc_unlink(ldb, old_schema); 450 451 if (talloc_reference(ldb, schema) == NULL) { 452 return ldb_oom(ldb); 453 } 454 455 /* Make this ldb use local schema preferably */ 456 ret = ldb_set_opaque(ldb, "dsdb_use_global_schema", NULL); 457 if (ret != LDB_SUCCESS) { 458 return ret; 459 } 460 385 461 ret = dsdb_schema_set_attributes(ldb, schema, write_attributes); 386 462 if (ret != LDB_SUCCESS) { … … 388 464 } 389 465 390 /* Keep a reference to this schema, just incase the original copy is replaced */391 if (talloc_reference(ldb, schema) == NULL) {392 return LDB_ERR_OPERATIONS_ERROR;393 }394 395 466 return LDB_SUCCESS; 396 467 } … … 401 472 int dsdb_set_global_schema(struct ldb_context *ldb) 402 473 { 474 int ret; 475 void *use_global_schema = (void *)1; 403 476 if (!global_schema) { 404 477 return LDB_SUCCESS; 405 478 } 406 407 return dsdb_reference_schema(ldb, global_schema, false /* Don't write attributes, it's expensive */); 479 ret = ldb_set_opaque(ldb, "dsdb_use_global_schema", use_global_schema); 480 if (ret != LDB_SUCCESS) { 481 return ret; 482 } 483 484 /* Set the new attributes based on the new schema */ 485 ret = dsdb_schema_set_attributes(ldb, global_schema, false /* Don't write attributes, it's expensive */); 486 if (ret == LDB_SUCCESS) { 487 /* Keep a reference to this schema, just in case the original copy is replaced */ 488 if (talloc_reference(ldb, global_schema) == NULL) { 489 return ldb_oom(ldb); 490 } 491 } 492 493 return ret; 494 } 495 496 bool dsdb_uses_global_schema(struct ldb_context *ldb) 497 { 498 return (ldb_get_opaque(ldb, "dsdb_use_global_schema") != NULL); 408 499 } 409 500 410 501 /** 411 502 * Find the schema object for this ldb 412 */ 413 414 struct dsdb_schema *dsdb_get_schema(struct ldb_context *ldb) 503 * 504 * If reference_ctx is not NULL, then talloc_reference onto that context 505 */ 506 507 struct dsdb_schema *dsdb_get_schema(struct ldb_context *ldb, TALLOC_CTX *reference_ctx) 415 508 { 416 509 const void *p; 417 struct dsdb_schema *schema; 510 struct dsdb_schema *schema_out; 511 struct dsdb_schema *schema_in; 512 bool use_global_schema; 513 TALLOC_CTX *tmp_ctx = talloc_new(reference_ctx); 514 if (!tmp_ctx) { 515 return NULL; 516 } 418 517 419 518 /* see if we have a cached copy */ 420 p = ldb_get_opaque(ldb, "dsdb_schema"); 421 if (!p) { 422 return NULL; 423 } 424 425 schema = talloc_get_type(p, struct dsdb_schema); 426 if (!schema) { 427 return NULL; 428 } 429 430 return schema; 519 use_global_schema = dsdb_uses_global_schema(ldb); 520 if (use_global_schema) { 521 schema_in = global_schema; 522 } else { 523 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; 547 } else { 548 schema_out = schema_in; 549 } 550 551 /* This removes the extra reference above */ 552 talloc_free(tmp_ctx); 553 if (!reference_ctx) { 554 return schema_out; 555 } else { 556 return talloc_reference(reference_ctx, schema_out); 557 } 431 558 } 432 559 … … 435 562 */ 436 563 437 void dsdb_make_schema_global(struct ldb_context *ldb) 438 { 439 struct dsdb_schema *schema = dsdb_get_schema(ldb); 564 void dsdb_make_schema_global(struct ldb_context *ldb, struct dsdb_schema *schema) 565 { 440 566 if (!schema) { 441 567 return; … … 447 573 448 574 /* we want the schema to be around permanently */ 449 talloc_reparent(talloc_parent(schema), talloc_autofree_context(), schema); 450 575 talloc_reparent(ldb, talloc_autofree_context(), schema); 451 576 global_schema = schema; 452 577 578 /* This calls the talloc_reference() of the global schema back onto the ldb */ 453 579 dsdb_set_global_schema(ldb); 454 580 } 455 581 582 /** 583 * When loading the schema from LDIF files, we don't get the extended DNs. 584 * 585 * We need to set these up, so that from the moment we start the provision, 586 * the defaultObjectCategory links are set up correctly. 587 */ 588 int dsdb_schema_fill_extended_dn(struct ldb_context *ldb, struct dsdb_schema *schema) 589 { 590 struct dsdb_class *cur; 591 const struct dsdb_class *target_class; 592 for (cur = schema->classes; cur; cur = cur->next) { 593 const struct ldb_val *rdn; 594 struct ldb_val guid; 595 NTSTATUS status; 596 struct ldb_dn *dn = ldb_dn_new(NULL, ldb, cur->defaultObjectCategory); 597 598 if (!dn) { 599 return LDB_ERR_INVALID_DN_SYNTAX; 600 } 601 rdn = ldb_dn_get_component_val(dn, 0); 602 if (!rdn) { 603 talloc_free(dn); 604 return LDB_ERR_INVALID_DN_SYNTAX; 605 } 606 target_class = dsdb_class_by_cn_ldb_val(schema, rdn); 607 if (!target_class) { 608 talloc_free(dn); 609 return LDB_ERR_CONSTRAINT_VIOLATION; 610 } 611 612 status = GUID_to_ndr_blob(&target_class->objectGUID, dn, &guid); 613 if (!NT_STATUS_IS_OK(status)) { 614 talloc_free(dn); 615 return ldb_operr(ldb); 616 } 617 ldb_dn_set_extended_component(dn, "GUID", &guid); 618 619 cur->defaultObjectCategory = ldb_dn_get_extended_linearized(cur, dn, 1); 620 talloc_free(dn); 621 } 622 return LDB_SUCCESS; 623 } 624 625 /** 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 { 631 if (samdb_find_attribute(ldb, msg, 632 "objectclass", "attributeSchema") != NULL) { 633 return dsdb_attribute_from_ldb(ldb, schema, msg); 634 } else if (samdb_find_attribute(ldb, msg, 635 "objectclass", "classSchema") != NULL) { 636 return dsdb_class_from_ldb(schema, msg); 637 } 638 639 /* Don't fail on things not classes or attributes */ 640 return WERR_OK; 641 } 456 642 457 643 /** … … 473 659 struct ldb_val info_val_default; 474 660 661 475 662 mem_ctx = talloc_new(ldb); 476 663 if (!mem_ctx) { … … 478 665 } 479 666 480 schema = dsdb_new_schema(mem_ctx , lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")));667 schema = dsdb_new_schema(mem_ctx); 481 668 482 669 schema->fsmo.we_are_master = true; … … 496 683 talloc_steal(mem_ctx, ldif); 497 684 498 msg = ldb_msg_canonicalize(ldb, ldif->msg);499 if ( !msg) {685 ret = ldb_msg_normalize(ldb, mem_ctx, ldif->msg, &msg); 686 if (ret != LDB_SUCCESS) { 500 687 goto nomem; 501 688 } 502 talloc_steal(mem_ctx, msg);503 689 talloc_free(ldif); 504 690 … … 511 697 info_val = ldb_msg_find_ldb_val(msg, "schemaInfo"); 512 698 if (!info_val) { 513 info_val_default = strhex_to_data_blob(mem_ctx, "FF0000000000000000000000000000000000000000"); 514 if (!info_val_default.data) { 515 goto nomem; 516 } 699 status = dsdb_schema_info_blob_new(mem_ctx, &info_val_default); 700 W_ERROR_NOT_OK_GOTO(status, failed); 517 701 info_val = &info_val_default; 518 702 } … … 520 704 status = dsdb_load_oid_mappings_ldb(schema, prefix_val, info_val); 521 705 if (!W_ERROR_IS_OK(status)) { 706 DEBUG(0,("ERROR: dsdb_load_oid_mappings_ldb() failed with %s\n", win_errstr(status))); 522 707 goto failed; 523 708 } 524 709 525 /* 526 * load the attribute and class definitions outof df 527 */ 710 /* load the attribute and class definitions out of df */ 528 711 while ((ldif = ldb_ldif_read_string(ldb, &df))) { 529 bool is_sa;530 bool is_sc;531 532 712 talloc_steal(mem_ctx, ldif); 533 713 534 msg = ldb_msg_canonicalize(ldb, ldif->msg);535 if ( !msg) {714 ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &msg); 715 if (ret != LDB_SUCCESS) { 536 716 goto nomem; 537 717 } 538 718 539 talloc_steal(mem_ctx, msg);719 status = dsdb_schema_set_el_from_ldb_msg(ldb, schema, msg); 540 720 talloc_free(ldif); 541 542 is_sa = ldb_msg_check_string_attribute(msg, "objectClass", "attributeSchema"); 543 is_sc = ldb_msg_check_string_attribute(msg, "objectClass", "classSchema"); 544 545 if (is_sa) { 546 struct dsdb_attribute *sa; 547 548 sa = talloc_zero(schema, struct dsdb_attribute); 549 if (!sa) { 550 goto nomem; 551 } 552 553 status = dsdb_attribute_from_ldb(ldb, schema, msg, sa, sa); 554 if (!W_ERROR_IS_OK(status)) { 555 goto failed; 556 } 557 558 DLIST_ADD(schema->attributes, sa); 559 } else if (is_sc) { 560 struct dsdb_class *sc; 561 562 sc = talloc_zero(schema, struct dsdb_class); 563 if (!sc) { 564 goto nomem; 565 } 566 567 status = dsdb_class_from_ldb(schema, msg, sc, sc); 568 if (!W_ERROR_IS_OK(status)) { 569 goto failed; 570 } 571 572 DLIST_ADD(schema->classes, sc); 721 if (!W_ERROR_IS_OK(status)) { 722 goto failed; 573 723 } 574 724 } 575 725 576 726 ret = dsdb_set_schema(ldb, schema); 727 if (ret != LDB_SUCCESS) { 728 status = WERR_FOOBAR; 729 goto failed; 730 } 731 732 ret = dsdb_schema_fill_extended_dn(ldb, schema); 577 733 if (ret != LDB_SUCCESS) { 578 734 status = WERR_FOOBAR; -
vendor/current/source4/dsdb/schema/schema_syntax.c
r414 r740 1 /* 1 /* 2 2 Unix SMB/CIFS mplementation. 3 3 DSDB schema syntaxes 4 4 5 5 Copyright (C) Stefan Metzmacher <metze@samba.org> 2006 6 6 Copyright (C) Simo Sorce 2005 … … 11 11 the Free Software Foundation; either version 3 of the License, or 12 12 (at your option) any later version. 13 13 14 14 This program is distributed in the hope that it will be useful, 15 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 17 GNU General Public License for more details. 18 18 19 19 You should have received a copy of the GNU General Public License 20 20 along with this program. If not, see <http://www.gnu.org/licenses/>. 21 21 22 22 */ 23 23 #include "includes.h" … … 26 26 #include "librpc/gen_ndr/ndr_security.h" 27 27 #include "librpc/gen_ndr/ndr_misc.h" 28 #include "lib/ldb/include/ldb.h"29 #include "lib/ldb/include/ldb_errors.h"28 #include <ldb.h> 29 #include <ldb_errors.h> 30 30 #include "system/time.h" 31 31 #include "../lib/util/charset/charset.h" 32 32 #include "librpc/ndr/libndr.h" 33 34 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(struct ldb_context *ldb, 35 const struct dsdb_schema *schema, 33 #include "../lib/util/asn1.h" 34 35 /** 36 * Initialize dsdb_syntax_ctx with default values 37 * for common cases. 38 */ 39 void dsdb_syntax_ctx_init(struct dsdb_syntax_ctx *ctx, 40 struct ldb_context *ldb, 41 const struct dsdb_schema *schema) 42 { 43 ctx->ldb = ldb; 44 ctx->schema = schema; 45 46 /* 47 * 'true' will keep current behavior, 48 * i.e. attributeID_id will be returned by default 49 */ 50 ctx->is_schema_nc = true; 51 52 ctx->pfm_remote = NULL; 53 } 54 55 56 /** 57 * Returns ATTID for DRS attribute. 58 * 59 * ATTID depends on whether we are replicating 60 * Schema NC or msDs-IntId is set for schemaAttribute 61 * for the attribute. 62 */ 63 uint32_t dsdb_attribute_get_attid(const struct dsdb_attribute *attr, 64 bool for_schema_nc) 65 { 66 if (!for_schema_nc && attr->msDS_IntId) { 67 return attr->msDS_IntId; 68 } 69 70 return attr->attributeID_id; 71 } 72 73 /** 74 * Map an ATTID from remote DC to a local ATTID 75 * using remote prefixMap 76 */ 77 static bool dsdb_syntax_attid_from_remote_attid(const struct dsdb_syntax_ctx *ctx, 78 TALLOC_CTX *mem_ctx, 79 uint32_t id_remote, 80 uint32_t *id_local) 81 { 82 WERROR werr; 83 const char *oid; 84 85 /* 86 * map remote ATTID to local directly in case 87 * of no remote prefixMap (during provision for instance) 88 */ 89 if (!ctx->pfm_remote) { 90 *id_local = id_remote; 91 return true; 92 } 93 94 werr = dsdb_schema_pfm_oid_from_attid(ctx->pfm_remote, id_remote, mem_ctx, &oid); 95 if (!W_ERROR_IS_OK(werr)) { 96 DEBUG(0,("ATTID->OID failed (%s) for: 0x%08X\n", win_errstr(werr), id_remote)); 97 return false; 98 } 99 100 werr = dsdb_schema_pfm_make_attid(ctx->schema->prefixmap, oid, id_local); 101 if (!W_ERROR_IS_OK(werr)) { 102 DEBUG(0,("OID->ATTID failed (%s) for: %s\n", win_errstr(werr), oid)); 103 return false; 104 } 105 106 return true; 107 } 108 109 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 36 110 const struct dsdb_attribute *attr, 37 111 const struct drsuapi_DsReplicaAttribute *in, … … 39 113 struct ldb_message_element *out) 40 114 { 41 u int32_t i;115 unsigned int i; 42 116 43 117 out->flags = 0; … … 66 140 } 67 141 68 static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(struct ldb_context *ldb, 69 const struct dsdb_schema *schema, 142 static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 70 143 const struct dsdb_attribute *attr, 71 144 const struct ldb_message_element *in, … … 76 149 } 77 150 78 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(struct ldb_context *ldb, 79 const struct dsdb_schema *schema, 151 static WERROR dsdb_syntax_FOOBAR_validate_ldb(const struct dsdb_syntax_ctx *ctx, 152 const struct dsdb_attribute *attr, 153 const struct ldb_message_element *in) 154 { 155 return WERR_FOOBAR; 156 } 157 158 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 80 159 const struct dsdb_attribute *attr, 81 160 const struct drsuapi_DsReplicaAttribute *in, … … 83 162 struct ldb_message_element *out) 84 163 { 85 u int32_t i;164 unsigned int i; 86 165 87 166 out->flags = 0; … … 121 200 } 122 201 123 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(struct ldb_context *ldb, 124 const struct dsdb_schema *schema, 202 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 125 203 const struct dsdb_attribute *attr, 126 204 const struct ldb_message_element *in, … … 128 206 struct drsuapi_DsReplicaAttribute *out) 129 207 { 130 u int32_t i;208 unsigned int i; 131 209 DATA_BLOB *blobs; 132 210 133 if (attr->attributeID_id == 0xFFFFFFFF) { 134 return WERR_FOOBAR; 135 } 136 137 out->attid = attr->attributeID_id; 211 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 212 return WERR_FOOBAR; 213 } 214 215 out->attid = dsdb_attribute_get_attid(attr, 216 ctx->is_schema_nc); 138 217 out->value_ctr.num_values = in->num_values; 139 218 out->value_ctr.values = talloc_array(mem_ctx, … … 163 242 } 164 243 165 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(struct ldb_context *ldb, 166 const struct dsdb_schema *schema, 244 static WERROR dsdb_syntax_BOOL_validate_ldb(const struct dsdb_syntax_ctx *ctx, 245 const struct dsdb_attribute *attr, 246 const struct ldb_message_element *in) 247 { 248 unsigned int i; 249 250 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 251 return WERR_FOOBAR; 252 } 253 254 for (i=0; i < in->num_values; i++) { 255 int t, f; 256 257 t = strncmp("TRUE", 258 (const char *)in->values[i].data, 259 in->values[i].length); 260 f = strncmp("FALSE", 261 (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 } 267 } 268 269 return WERR_OK; 270 } 271 272 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 167 273 const struct dsdb_attribute *attr, 168 274 const struct drsuapi_DsReplicaAttribute *in, … … 170 276 struct ldb_message_element *out) 171 277 { 172 u int32_t i;278 unsigned int i; 173 279 174 280 out->flags = 0; … … 203 309 } 204 310 205 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(struct ldb_context *ldb, 206 const struct dsdb_schema *schema, 311 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 207 312 const struct dsdb_attribute *attr, 208 313 const struct ldb_message_element *in, … … 210 315 struct drsuapi_DsReplicaAttribute *out) 211 316 { 212 u int32_t i;317 unsigned int i; 213 318 DATA_BLOB *blobs; 214 319 215 if (attr->attributeID_id == 0xFFFFFFFF) { 216 return WERR_FOOBAR; 217 } 218 219 out->attid = attr->attributeID_id; 320 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 321 return WERR_FOOBAR; 322 } 323 324 out->attid = dsdb_attribute_get_attid(attr, 325 ctx->is_schema_nc); 220 326 out->value_ctr.num_values = in->num_values; 221 327 out->value_ctr.values = talloc_array(mem_ctx, … … 245 351 } 246 352 247 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(struct ldb_context *ldb, 248 const struct dsdb_schema *schema, 353 static WERROR dsdb_syntax_INT32_validate_ldb(const struct dsdb_syntax_ctx *ctx, 354 const struct dsdb_attribute *attr, 355 const struct ldb_message_element *in) 356 { 357 unsigned int i; 358 359 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 360 return WERR_FOOBAR; 361 } 362 363 for (i=0; i < in->num_values; i++) { 364 long v; 365 char buf[sizeof("-2147483648")]; 366 char *end = NULL; 367 368 ZERO_STRUCT(buf); 369 if (in->values[i].length >= sizeof(buf)) { 370 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 371 } 372 373 memcpy(buf, in->values[i].data, in->values[i].length); 374 errno = 0; 375 v = strtol(buf, &end, 10); 376 if (errno != 0) { 377 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 378 } 379 if (end && end[0] != '\0') { 380 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 381 } 382 383 if (attr->rangeLower) { 384 if ((int32_t)v < (int32_t)*attr->rangeLower) { 385 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 386 } 387 } 388 389 if (attr->rangeUpper) { 390 if ((int32_t)v > (int32_t)*attr->rangeUpper) { 391 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 392 } 393 } 394 } 395 396 return WERR_OK; 397 } 398 399 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 249 400 const struct dsdb_attribute *attr, 250 401 const struct drsuapi_DsReplicaAttribute *in, … … 252 403 struct ldb_message_element *out) 253 404 { 254 u int32_t i;405 unsigned int i; 255 406 256 407 out->flags = 0; … … 285 436 } 286 437 287 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(struct ldb_context *ldb, 288 const struct dsdb_schema *schema, 438 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 289 439 const struct dsdb_attribute *attr, 290 440 const struct ldb_message_element *in, … … 292 442 struct drsuapi_DsReplicaAttribute *out) 293 443 { 294 u int32_t i;444 unsigned int i; 295 445 DATA_BLOB *blobs; 296 446 297 if (attr->attributeID_id == 0xFFFFFFFF) { 298 return WERR_FOOBAR; 299 } 300 301 out->attid = attr->attributeID_id; 447 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 448 return WERR_FOOBAR; 449 } 450 451 out->attid = dsdb_attribute_get_attid(attr, 452 ctx->is_schema_nc); 302 453 out->value_ctr.num_values = in->num_values; 303 454 out->value_ctr.values = talloc_array(mem_ctx, … … 325 476 } 326 477 327 static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(struct ldb_context *ldb, 328 const struct dsdb_schema *schema, 478 static WERROR dsdb_syntax_INT64_validate_ldb(const struct dsdb_syntax_ctx *ctx, 479 const struct dsdb_attribute *attr, 480 const struct ldb_message_element *in) 481 { 482 unsigned int i; 483 484 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 485 return WERR_FOOBAR; 486 } 487 488 for (i=0; i < in->num_values; i++) { 489 long long v; 490 char buf[sizeof("-9223372036854775808")]; 491 char *end = NULL; 492 493 ZERO_STRUCT(buf); 494 if (in->values[i].length >= sizeof(buf)) { 495 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 496 } 497 memcpy(buf, in->values[i].data, in->values[i].length); 498 499 errno = 0; 500 v = strtoll(buf, &end, 10); 501 if (errno != 0) { 502 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 503 } 504 if (end && end[0] != '\0') { 505 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 506 } 507 508 if (attr->rangeLower) { 509 if ((int64_t)v < (int64_t)*attr->rangeLower) { 510 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 511 } 512 } 513 514 if (attr->rangeUpper) { 515 if ((int64_t)v > (int64_t)*attr->rangeUpper) { 516 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 517 } 518 } 519 } 520 521 return WERR_OK; 522 } 523 static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 329 524 const struct dsdb_attribute *attr, 330 525 const struct drsuapi_DsReplicaAttribute *in, … … 332 527 struct ldb_message_element *out) 333 528 { 334 u int32_t i;529 unsigned int i; 335 530 336 531 out->flags = 0; … … 359 554 t = nt_time_to_unix(v); 360 555 361 /* 556 /* 362 557 * NOTE: On a w2k3 server you can set a GeneralizedTime string 363 558 * via LDAP, but you get back an UTCTime string, … … 368 563 * we'll loose information! 369 564 */ 370 str = ldb_timestring_utc(out->values, t); 565 str = ldb_timestring_utc(out->values, t); 371 566 W_ERROR_HAVE_NO_MEMORY(str); 372 567 out->values[i] = data_blob_string_const(str); … … 376 571 } 377 572 378 static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(struct ldb_context *ldb, 379 const struct dsdb_schema *schema, 573 static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 380 574 const struct dsdb_attribute *attr, 381 575 const struct ldb_message_element *in, … … 383 577 struct drsuapi_DsReplicaAttribute *out) 384 578 { 385 u int32_t i;579 unsigned int i; 386 580 DATA_BLOB *blobs; 387 581 388 if (attr->attributeID_id == 0xFFFFFFFF) { 389 return WERR_FOOBAR; 390 } 391 392 out->attid = attr->attributeID_id; 582 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 583 return WERR_FOOBAR; 584 } 585 586 out->attid = dsdb_attribute_get_attid(attr, 587 ctx->is_schema_nc); 393 588 out->value_ctr.num_values = in->num_values; 394 589 out->value_ctr.values = talloc_array(mem_ctx, … … 419 614 } 420 615 421 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(struct ldb_context *ldb, 422 const struct dsdb_schema *schema, 616 static WERROR dsdb_syntax_NTTIME_UTC_validate_ldb(const struct dsdb_syntax_ctx *ctx, 617 const struct dsdb_attribute *attr, 618 const struct ldb_message_element *in) 619 { 620 unsigned int i; 621 622 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 623 return WERR_FOOBAR; 624 } 625 626 for (i=0; i < in->num_values; i++) { 627 time_t t; 628 char buf[sizeof("090826075717Z")]; 629 630 ZERO_STRUCT(buf); 631 if (in->values[i].length >= sizeof(buf)) { 632 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 633 } 634 memcpy(buf, in->values[i].data, in->values[i].length); 635 636 errno = 0; 637 t = ldb_string_utc_to_time(buf); 638 if (errno != 0) { 639 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 640 } 641 642 if (attr->rangeLower) { 643 if ((int32_t)t < (int32_t)*attr->rangeLower) { 644 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 645 } 646 } 647 648 if (attr->rangeUpper) { 649 if ((int32_t)t > (int32_t)*attr->rangeLower) { 650 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 651 } 652 } 653 654 /* 655 * TODO: verify the comment in the 656 * dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb() function! 657 */ 658 } 659 660 return WERR_OK; 661 } 662 663 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 423 664 const struct dsdb_attribute *attr, 424 665 const struct drsuapi_DsReplicaAttribute *in, … … 426 667 struct ldb_message_element *out) 427 668 { 428 u int32_t i;669 unsigned int i; 429 670 430 671 out->flags = 0; … … 453 694 t = nt_time_to_unix(v); 454 695 455 str = ldb_timestring(out->values, t); 696 str = ldb_timestring(out->values, t); 456 697 W_ERROR_HAVE_NO_MEMORY(str); 457 698 … … 462 703 } 463 704 464 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(struct ldb_context *ldb, 465 const struct dsdb_schema *schema, 705 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 466 706 const struct dsdb_attribute *attr, 467 707 const struct ldb_message_element *in, … … 469 709 struct drsuapi_DsReplicaAttribute *out) 470 710 { 471 u int32_t i;711 unsigned int i; 472 712 DATA_BLOB *blobs; 473 713 474 if (attr->attributeID_id == 0xFFFFFFFF) { 475 return WERR_FOOBAR; 476 } 477 478 out->attid = attr->attributeID_id; 714 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 715 return WERR_FOOBAR; 716 } 717 718 out->attid = dsdb_attribute_get_attid(attr, 719 ctx->is_schema_nc); 479 720 out->value_ctr.num_values = in->num_values; 480 721 out->value_ctr.values = talloc_array(mem_ctx, … … 489 730 NTTIME v; 490 731 time_t t; 732 int ret; 491 733 492 734 out->value_ctr.values[i].blob = &blobs[i]; … … 495 737 W_ERROR_HAVE_NO_MEMORY(blobs[i].data); 496 738 497 t = ldb_string_to_time((const char *)in->values[i].data); 739 ret = ldb_val_to_time(&in->values[i], &t); 740 if (ret != LDB_SUCCESS) { 741 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 742 } 498 743 unix_to_nt_time(&v, t); 499 744 v /= 10000000; … … 505 750 } 506 751 507 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(struct ldb_context *ldb, 508 const struct dsdb_schema *schema, 752 static WERROR dsdb_syntax_NTTIME_validate_ldb(const struct dsdb_syntax_ctx *ctx, 753 const struct dsdb_attribute *attr, 754 const struct ldb_message_element *in) 755 { 756 unsigned int i; 757 758 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 759 return WERR_FOOBAR; 760 } 761 762 for (i=0; i < in->num_values; i++) { 763 time_t t; 764 int ret; 765 766 ret = ldb_val_to_time(&in->values[i], &t); 767 if (ret != LDB_SUCCESS) { 768 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 769 } 770 771 if (attr->rangeLower) { 772 if ((int32_t)t < (int32_t)*attr->rangeLower) { 773 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 774 } 775 } 776 777 if (attr->rangeUpper) { 778 if ((int32_t)t > (int32_t)*attr->rangeLower) { 779 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 780 } 781 } 782 } 783 784 return WERR_OK; 785 } 786 787 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 509 788 const struct dsdb_attribute *attr, 510 789 const struct drsuapi_DsReplicaAttribute *in, … … 512 791 struct ldb_message_element *out) 513 792 { 514 u int32_t i;793 unsigned int i; 515 794 516 795 out->flags = 0; … … 539 818 } 540 819 541 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(struct ldb_context *ldb, 542 const struct dsdb_schema *schema, 820 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 543 821 const struct dsdb_attribute *attr, 544 822 const struct ldb_message_element *in, … … 546 824 struct drsuapi_DsReplicaAttribute *out) 547 825 { 548 u int32_t i;826 unsigned int i; 549 827 DATA_BLOB *blobs; 550 828 551 if (attr->attributeID_id == 0xFFFFFFFF) { 552 return WERR_FOOBAR; 553 } 554 555 out->attid = attr->attributeID_id; 829 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 830 return WERR_FOOBAR; 831 } 832 833 out->attid = dsdb_attribute_get_attid(attr, 834 ctx->is_schema_nc); 556 835 out->value_ctr.num_values = in->num_values; 557 836 out->value_ctr.values = talloc_array(mem_ctx, … … 573 852 } 574 853 575 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(struct ldb_context *ldb, 576 const struct dsdb_schema *schema, 854 static WERROR dsdb_syntax_DATA_BLOB_validate_one_val(const struct dsdb_syntax_ctx *ctx, 855 const struct dsdb_attribute *attr, 856 const struct ldb_val *val) 857 { 858 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 859 return WERR_FOOBAR; 860 } 861 862 if (attr->rangeLower) { 863 if ((uint32_t)val->length < (uint32_t)*attr->rangeLower) { 864 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 865 } 866 } 867 868 if (attr->rangeUpper) { 869 if ((uint32_t)val->length > (uint32_t)*attr->rangeUpper) { 870 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 871 } 872 } 873 874 return WERR_OK; 875 } 876 877 static WERROR dsdb_syntax_DATA_BLOB_validate_ldb(const struct dsdb_syntax_ctx *ctx, 878 const struct dsdb_attribute *attr, 879 const struct ldb_message_element *in) 880 { 881 unsigned int i; 882 WERROR status; 883 884 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 885 return WERR_FOOBAR; 886 } 887 888 for (i=0; i < in->num_values; i++) { 889 if (in->values[i].length == 0) { 890 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 891 } 892 893 status = dsdb_syntax_DATA_BLOB_validate_one_val(ctx, 894 attr, 895 &in->values[i]); 896 if (!W_ERROR_IS_OK(status)) { 897 return status; 898 } 899 } 900 901 return WERR_OK; 902 } 903 904 static WERROR _dsdb_syntax_auto_OID_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 905 const struct dsdb_attribute *attr, 906 const struct drsuapi_DsReplicaAttribute *in, 907 TALLOC_CTX *mem_ctx, 908 struct ldb_message_element *out) 909 { 910 unsigned int i; 911 912 out->flags = 0; 913 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName); 914 W_ERROR_HAVE_NO_MEMORY(out->name); 915 916 out->num_values = in->value_ctr.num_values; 917 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values); 918 W_ERROR_HAVE_NO_MEMORY(out->values); 919 920 for (i=0; i < out->num_values; i++) { 921 uint32_t v; 922 const struct dsdb_class *c; 923 const struct dsdb_attribute *a; 924 const char *str = NULL; 925 926 if (in->value_ctr.values[i].blob == NULL) { 927 return WERR_FOOBAR; 928 } 929 930 if (in->value_ctr.values[i].blob->length != 4) { 931 return WERR_FOOBAR; 932 } 933 934 v = IVAL(in->value_ctr.values[i].blob->data, 0); 935 936 if ((c = dsdb_class_by_governsID_id(ctx->schema, v))) { 937 str = talloc_strdup(out->values, c->lDAPDisplayName); 938 } else if ((a = dsdb_attribute_by_attributeID_id(ctx->schema, v))) { 939 str = talloc_strdup(out->values, a->lDAPDisplayName); 940 } else { 941 WERROR werr; 942 SMB_ASSERT(ctx->pfm_remote); 943 werr = dsdb_schema_pfm_oid_from_attid(ctx->pfm_remote, v, 944 out->values, &str); 945 W_ERROR_NOT_OK_RETURN(werr); 946 } 947 W_ERROR_HAVE_NO_MEMORY(str); 948 949 /* the values need to be reversed */ 950 out->values[out->num_values - (i + 1)] = data_blob_string_const(str); 951 } 952 953 return WERR_OK; 954 } 955 956 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 577 957 const struct dsdb_attribute *attr, 578 958 const struct drsuapi_DsReplicaAttribute *in, … … 580 960 struct ldb_message_element *out) 581 961 { 582 u int32_t i;962 unsigned int i; 583 963 584 964 out->flags = 0; … … 605 985 v = IVAL(in->value_ctr.values[i].blob->data, 0); 606 986 607 c = dsdb_class_by_governsID_id(schema, v); 987 /* convert remote ATTID to local ATTID */ 988 if (!dsdb_syntax_attid_from_remote_attid(ctx, mem_ctx, v, &v)) { 989 DEBUG(1,(__location__ ": Failed to map remote ATTID to local ATTID!\n")); 990 return WERR_FOOBAR; 991 } 992 993 c = dsdb_class_by_governsID_id(ctx->schema, v); 608 994 if (!c) { 995 DEBUG(1,(__location__ ": Unknown governsID 0x%08X\n", v)); 609 996 return WERR_FOOBAR; 610 997 } … … 620 1007 } 621 1008 622 static WERROR _dsdb_syntax_OID_attr_drsuapi_to_ldb(struct ldb_context *ldb, 623 const struct dsdb_schema *schema, 1009 static WERROR _dsdb_syntax_OID_attr_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 624 1010 const struct dsdb_attribute *attr, 625 1011 const struct drsuapi_DsReplicaAttribute *in, … … 627 1013 struct ldb_message_element *out) 628 1014 { 629 u int32_t i;1015 unsigned int i; 630 1016 631 1017 out->flags = 0; … … 652 1038 v = IVAL(in->value_ctr.values[i].blob->data, 0); 653 1039 654 a = dsdb_attribute_by_attributeID_id(schema, v); 1040 /* convert remote ATTID to local ATTID */ 1041 if (!dsdb_syntax_attid_from_remote_attid(ctx, mem_ctx, v, &v)) { 1042 DEBUG(1,(__location__ ": Failed to map remote ATTID to local ATTID!\n")); 1043 return WERR_FOOBAR; 1044 } 1045 1046 a = dsdb_attribute_by_attributeID_id(ctx->schema, v); 655 1047 if (!a) { 1048 DEBUG(1,(__location__ ": Unknown attributeID_id 0x%08X\n", v)); 656 1049 return WERR_FOOBAR; 657 1050 } … … 667 1060 } 668 1061 669 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(struct ldb_context *ldb, 670 const struct dsdb_schema *schema, 1062 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 671 1063 const struct dsdb_attribute *attr, 672 1064 const struct drsuapi_DsReplicaAttribute *in, … … 674 1066 struct ldb_message_element *out) 675 1067 { 676 uint32_t i; 1068 unsigned int i; 1069 1070 SMB_ASSERT(ctx->pfm_remote); 677 1071 678 1072 out->flags = 0; … … 685 1079 686 1080 for (i=0; i < out->num_values; i++) { 687 uint32_t v;1081 uint32_t attid; 688 1082 WERROR status; 689 const char * str;1083 const char *oid; 690 1084 691 1085 if (in->value_ctr.values[i].blob == NULL) { … … 697 1091 } 698 1092 699 v = IVAL(in->value_ctr.values[i].blob->data, 0); 700 701 status = dsdb_map_int2oid(schema, v, out->values, &str); 702 W_ERROR_NOT_OK_RETURN(status); 703 704 out->values[i] = data_blob_string_const(str); 705 } 706 707 return WERR_OK; 708 } 709 710 static WERROR _dsdb_syntax_OID_obj_ldb_to_drsuapi(struct ldb_context *ldb, 711 const struct dsdb_schema *schema, 712 const struct dsdb_attribute *attr, 713 const struct ldb_message_element *in, 714 TALLOC_CTX *mem_ctx, 715 struct drsuapi_DsReplicaAttribute *out) 716 { 717 uint32_t i; 1093 attid = IVAL(in->value_ctr.values[i].blob->data, 0); 1094 1095 status = dsdb_schema_pfm_oid_from_attid(ctx->pfm_remote, attid, 1096 out->values, &oid); 1097 if (!W_ERROR_IS_OK(status)) { 1098 DEBUG(0,(__location__ ": Error: Unknown ATTID 0x%08X\n", 1099 attid)); 1100 return status; 1101 } 1102 1103 out->values[i] = data_blob_string_const(oid); 1104 } 1105 1106 return WERR_OK; 1107 } 1108 1109 static WERROR _dsdb_syntax_auto_OID_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 1110 const struct dsdb_attribute *attr, 1111 const struct ldb_message_element *in, 1112 TALLOC_CTX *mem_ctx, 1113 struct drsuapi_DsReplicaAttribute *out) 1114 { 1115 unsigned int i; 718 1116 DATA_BLOB *blobs; 719 1117 720 out->attid= attr->attributeID_id; 1118 out->attid= dsdb_attribute_get_attid(attr, 1119 ctx->is_schema_nc); 721 1120 out->value_ctr.num_values= in->num_values; 722 1121 out->value_ctr.values= talloc_array(mem_ctx, … … 730 1129 for (i=0; i < in->num_values; i++) { 731 1130 const struct dsdb_class *obj_class; 1131 const struct dsdb_attribute *obj_attr; 1132 struct ldb_val *v; 732 1133 733 1134 out->value_ctr.values[i].blob= &blobs[i]; … … 736 1137 W_ERROR_HAVE_NO_MEMORY(blobs[i].data); 737 1138 738 obj_class = dsdb_class_by_lDAPDisplayName(schema, (const char *)in->values[i].data); 739 if (!obj_class) { 740 return WERR_FOOBAR; 741 } 742 SIVAL(blobs[i].data, 0, obj_class->governsID_id); 1139 /* in DRS windows puts the classes in the opposite 1140 order to the order used in ldap */ 1141 v = &in->values[(in->num_values-1)-i]; 1142 1143 if ((obj_class = dsdb_class_by_lDAPDisplayName_ldb_val(ctx->schema, v))) { 1144 SIVAL(blobs[i].data, 0, obj_class->governsID_id); 1145 } else if ((obj_attr = dsdb_attribute_by_lDAPDisplayName_ldb_val(ctx->schema, v))) { 1146 SIVAL(blobs[i].data, 0, obj_attr->attributeID_id); 1147 } else { 1148 uint32_t attid; 1149 WERROR werr; 1150 werr = dsdb_schema_pfm_attid_from_oid(ctx->schema->prefixmap, 1151 (const char *)v->data, 1152 &attid); 1153 W_ERROR_NOT_OK_RETURN(werr); 1154 SIVAL(blobs[i].data, 0, attid); 1155 } 1156 743 1157 } 744 1158 … … 747 1161 } 748 1162 749 static WERROR _dsdb_syntax_OID_attr_ldb_to_drsuapi(struct ldb_context *ldb, 750 const struct dsdb_schema *schema, 751 const struct dsdb_attribute *attr, 752 const struct ldb_message_element *in, 753 TALLOC_CTX *mem_ctx, 754 struct drsuapi_DsReplicaAttribute *out) 755 { 756 uint32_t i; 1163 static WERROR _dsdb_syntax_OID_obj_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 1164 const struct dsdb_attribute *attr, 1165 const struct ldb_message_element *in, 1166 TALLOC_CTX *mem_ctx, 1167 struct drsuapi_DsReplicaAttribute *out) 1168 { 1169 unsigned int i; 757 1170 DATA_BLOB *blobs; 758 1171 759 out->attid= attr->attributeID_id; 1172 out->attid= dsdb_attribute_get_attid(attr, 1173 ctx->is_schema_nc); 760 1174 out->value_ctr.num_values= in->num_values; 761 1175 out->value_ctr.values= talloc_array(mem_ctx, … … 768 1182 769 1183 for (i=0; i < in->num_values; i++) { 770 const struct dsdb_ attribute *obj_attr;1184 const struct dsdb_class *obj_class; 771 1185 772 1186 out->value_ctr.values[i].blob= &blobs[i]; … … 775 1189 W_ERROR_HAVE_NO_MEMORY(blobs[i].data); 776 1190 777 obj_attr = dsdb_attribute_by_lDAPDisplayName(schema, (const char *)in->values[i].data); 1191 /* in DRS windows puts the classes in the opposite 1192 order to the order used in ldap */ 1193 obj_class = dsdb_class_by_lDAPDisplayName(ctx->schema, 1194 (const char *)in->values[(in->num_values-1)-i].data); 1195 if (!obj_class) { 1196 return WERR_FOOBAR; 1197 } 1198 SIVAL(blobs[i].data, 0, obj_class->governsID_id); 1199 } 1200 1201 1202 return WERR_OK; 1203 } 1204 1205 static WERROR _dsdb_syntax_OID_attr_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 1206 const struct dsdb_attribute *attr, 1207 const struct ldb_message_element *in, 1208 TALLOC_CTX *mem_ctx, 1209 struct drsuapi_DsReplicaAttribute *out) 1210 { 1211 unsigned int i; 1212 DATA_BLOB *blobs; 1213 1214 out->attid= dsdb_attribute_get_attid(attr, 1215 ctx->is_schema_nc); 1216 out->value_ctr.num_values= in->num_values; 1217 out->value_ctr.values= talloc_array(mem_ctx, 1218 struct drsuapi_DsAttributeValue, 1219 in->num_values); 1220 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values); 1221 1222 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values); 1223 W_ERROR_HAVE_NO_MEMORY(blobs); 1224 1225 for (i=0; i < in->num_values; i++) { 1226 const struct dsdb_attribute *obj_attr; 1227 1228 out->value_ctr.values[i].blob= &blobs[i]; 1229 1230 blobs[i] = data_blob_talloc(blobs, NULL, 4); 1231 W_ERROR_HAVE_NO_MEMORY(blobs[i].data); 1232 1233 obj_attr = dsdb_attribute_by_lDAPDisplayName(ctx->schema, (const char *)in->values[i].data); 778 1234 if (!obj_attr) { 779 1235 return WERR_FOOBAR; … … 786 1242 } 787 1243 788 static WERROR _dsdb_syntax_OID_oid_ldb_to_drsuapi(struct ldb_context *ldb, 789 const struct dsdb_schema *schema, 1244 static WERROR _dsdb_syntax_OID_oid_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 790 1245 const struct dsdb_attribute *attr, 791 1246 const struct ldb_message_element *in, … … 793 1248 struct drsuapi_DsReplicaAttribute *out) 794 1249 { 795 u int32_t i;1250 unsigned int i; 796 1251 DATA_BLOB *blobs; 797 1252 798 out->attid= attr->attributeID_id; 1253 out->attid= dsdb_attribute_get_attid(attr, 1254 ctx->is_schema_nc); 799 1255 out->value_ctr.num_values= in->num_values; 800 1256 out->value_ctr.values= talloc_array(mem_ctx, … … 807 1263 808 1264 for (i=0; i < in->num_values; i++) { 809 uint32_t v;1265 uint32_t attid; 810 1266 WERROR status; 811 1267 … … 815 1271 W_ERROR_HAVE_NO_MEMORY(blobs[i].data); 816 1272 817 status = dsdb_ map_oid2int(schema,818 (const char *)in->values[i].data,819 &v);1273 status = dsdb_schema_pfm_attid_from_oid(ctx->schema->prefixmap, 1274 (const char *)in->values[i].data, 1275 &attid); 820 1276 W_ERROR_NOT_OK_RETURN(status); 821 1277 822 SIVAL(blobs[i].data, 0, v); 823 } 824 825 return WERR_OK; 826 } 827 828 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(struct ldb_context *ldb, 829 const struct dsdb_schema *schema, 1278 SIVAL(blobs[i].data, 0, attid); 1279 } 1280 1281 return WERR_OK; 1282 } 1283 1284 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 830 1285 const struct dsdb_attribute *attr, 831 1286 const struct drsuapi_DsReplicaAttribute *in, … … 833 1288 struct ldb_message_element *out) 834 1289 { 835 uint32_t i;1290 WERROR werr; 836 1291 837 1292 switch (attr->attributeID_id) { 838 case DRSUAPI_ATTRIBUTE_objectClass: 839 case DRSUAPI_ATTRIBUTE_subClassOf: 840 case DRSUAPI_ATTRIBUTE_auxiliaryClass: 841 case DRSUAPI_ATTRIBUTE_systemPossSuperiors: 842 case DRSUAPI_ATTRIBUTE_possSuperiors: 843 return _dsdb_syntax_OID_obj_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out); 844 case DRSUAPI_ATTRIBUTE_systemMustContain: 845 case DRSUAPI_ATTRIBUTE_systemMayContain: 846 case DRSUAPI_ATTRIBUTE_mustContain: 847 case DRSUAPI_ATTRIBUTE_mayContain: 848 return _dsdb_syntax_OID_attr_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out); 849 case DRSUAPI_ATTRIBUTE_governsID: 850 case DRSUAPI_ATTRIBUTE_attributeID: 851 case DRSUAPI_ATTRIBUTE_attributeSyntax: 852 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out); 853 } 854 855 out->flags = 0; 856 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName); 857 W_ERROR_HAVE_NO_MEMORY(out->name); 858 859 out->num_values = in->value_ctr.num_values; 860 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values); 861 W_ERROR_HAVE_NO_MEMORY(out->values); 862 863 for (i=0; i < out->num_values; i++) { 864 uint32_t v; 865 const char *name; 866 char *str; 867 868 if (in->value_ctr.values[i].blob == NULL) { 869 return WERR_FOOBAR; 870 } 871 872 if (in->value_ctr.values[i].blob->length != 4) { 873 return WERR_FOOBAR; 874 } 875 876 v = IVAL(in->value_ctr.values[i].blob->data, 0); 877 878 name = dsdb_lDAPDisplayName_by_id(schema, v); 879 if (!name) { 880 return WERR_FOOBAR; 881 } 882 883 str = talloc_strdup(out->values, name); 884 W_ERROR_HAVE_NO_MEMORY(str); 885 886 out->values[i] = data_blob_string_const(str); 887 } 888 889 return WERR_OK; 890 } 891 892 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(struct ldb_context *ldb, 893 const struct dsdb_schema *schema, 1293 case DRSUAPI_ATTID_objectClass: 1294 case DRSUAPI_ATTID_subClassOf: 1295 case DRSUAPI_ATTID_auxiliaryClass: 1296 case DRSUAPI_ATTID_systemAuxiliaryClass: 1297 case DRSUAPI_ATTID_systemPossSuperiors: 1298 case DRSUAPI_ATTID_possSuperiors: 1299 werr = _dsdb_syntax_OID_obj_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out); 1300 break; 1301 case DRSUAPI_ATTID_systemMustContain: 1302 case DRSUAPI_ATTID_systemMayContain: 1303 case DRSUAPI_ATTID_mustContain: 1304 case DRSUAPI_ATTID_rDNAttId: 1305 case DRSUAPI_ATTID_transportAddressAttribute: 1306 case DRSUAPI_ATTID_mayContain: 1307 werr = _dsdb_syntax_OID_attr_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out); 1308 break; 1309 case DRSUAPI_ATTID_governsID: 1310 case DRSUAPI_ATTID_attributeID: 1311 case DRSUAPI_ATTID_attributeSyntax: 1312 werr = _dsdb_syntax_OID_oid_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out); 1313 break; 1314 default: 1315 DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n", 1316 attr->lDAPDisplayName)); 1317 return _dsdb_syntax_auto_OID_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out); 1318 } 1319 1320 /* When we are doing the vampire of a schema, we don't want 1321 * the inability to reference an OID to get in the way. 1322 * Otherwise, we won't get the new schema with which to 1323 * understand this */ 1324 if (!W_ERROR_IS_OK(werr) && ctx->schema->relax_OID_conversions) { 1325 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ctx, attr, in, mem_ctx, out); 1326 } 1327 return werr; 1328 } 1329 1330 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 894 1331 const struct dsdb_attribute *attr, 895 1332 const struct ldb_message_element *in, … … 897 1334 struct drsuapi_DsReplicaAttribute *out) 898 1335 { 899 uint32_t i; 1336 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1337 return WERR_FOOBAR; 1338 } 1339 1340 switch (attr->attributeID_id) { 1341 case DRSUAPI_ATTID_objectClass: 1342 case DRSUAPI_ATTID_subClassOf: 1343 case DRSUAPI_ATTID_auxiliaryClass: 1344 case DRSUAPI_ATTID_systemAuxiliaryClass: 1345 case DRSUAPI_ATTID_systemPossSuperiors: 1346 case DRSUAPI_ATTID_possSuperiors: 1347 return _dsdb_syntax_OID_obj_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out); 1348 case DRSUAPI_ATTID_systemMustContain: 1349 case DRSUAPI_ATTID_systemMayContain: 1350 case DRSUAPI_ATTID_mustContain: 1351 case DRSUAPI_ATTID_rDNAttId: 1352 case DRSUAPI_ATTID_transportAddressAttribute: 1353 case DRSUAPI_ATTID_mayContain: 1354 return _dsdb_syntax_OID_attr_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out); 1355 case DRSUAPI_ATTID_governsID: 1356 case DRSUAPI_ATTID_attributeID: 1357 case DRSUAPI_ATTID_attributeSyntax: 1358 return _dsdb_syntax_OID_oid_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out); 1359 } 1360 1361 DEBUG(0,(__location__ ": Unknown handling for attributeID_id for %s\n", 1362 attr->lDAPDisplayName)); 1363 1364 return _dsdb_syntax_auto_OID_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out); 1365 } 1366 1367 static WERROR _dsdb_syntax_OID_validate_numericoid(const struct dsdb_syntax_ctx *ctx, 1368 const struct dsdb_attribute *attr, 1369 const struct ldb_message_element *in) 1370 { 1371 unsigned int i; 1372 TALLOC_CTX *tmp_ctx; 1373 1374 tmp_ctx = talloc_new(ctx->ldb); 1375 W_ERROR_HAVE_NO_MEMORY(tmp_ctx); 1376 1377 for (i=0; i < in->num_values; i++) { 1378 DATA_BLOB blob; 1379 char *oid_out; 1380 const char *oid = (const char*)in->values[i].data; 1381 1382 if (!ber_write_OID_String(tmp_ctx, &blob, oid)) { 1383 DEBUG(0,("ber_write_OID_String() failed for %s\n", oid)); 1384 talloc_free(tmp_ctx); 1385 return WERR_INVALID_PARAMETER; 1386 } 1387 1388 if (!ber_read_OID_String(tmp_ctx, blob, &oid_out)) { 1389 DEBUG(0,("ber_read_OID_String() failed for %s\n", 1390 hex_encode_talloc(tmp_ctx, blob.data, blob.length))); 1391 talloc_free(tmp_ctx); 1392 return WERR_INVALID_PARAMETER; 1393 } 1394 1395 if (strcmp(oid, oid_out) != 0) { 1396 talloc_free(tmp_ctx); 1397 return WERR_INVALID_PARAMETER; 1398 } 1399 } 1400 1401 talloc_free(tmp_ctx); 1402 return WERR_OK; 1403 } 1404 1405 static WERROR dsdb_syntax_OID_validate_ldb(const struct dsdb_syntax_ctx *ctx, 1406 const struct dsdb_attribute *attr, 1407 const struct ldb_message_element *in) 1408 { 1409 WERROR status; 1410 struct drsuapi_DsReplicaAttribute drs_tmp; 1411 struct ldb_message_element ldb_tmp; 1412 TALLOC_CTX *tmp_ctx; 1413 1414 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1415 return WERR_FOOBAR; 1416 } 1417 1418 switch (attr->attributeID_id) { 1419 case DRSUAPI_ATTID_governsID: 1420 case DRSUAPI_ATTID_attributeID: 1421 case DRSUAPI_ATTID_attributeSyntax: 1422 return _dsdb_syntax_OID_validate_numericoid(ctx, attr, in); 1423 } 1424 1425 /* 1426 * TODO: optimize and verify this code 1427 */ 1428 1429 tmp_ctx = talloc_new(ctx->ldb); 1430 W_ERROR_HAVE_NO_MEMORY(tmp_ctx); 1431 1432 status = dsdb_syntax_OID_ldb_to_drsuapi(ctx, 1433 attr, 1434 in, 1435 tmp_ctx, 1436 &drs_tmp); 1437 if (!W_ERROR_IS_OK(status)) { 1438 talloc_free(tmp_ctx); 1439 return status; 1440 } 1441 1442 status = dsdb_syntax_OID_drsuapi_to_ldb(ctx, 1443 attr, 1444 &drs_tmp, 1445 tmp_ctx, 1446 &ldb_tmp); 1447 if (!W_ERROR_IS_OK(status)) { 1448 talloc_free(tmp_ctx); 1449 return status; 1450 } 1451 1452 talloc_free(tmp_ctx); 1453 return WERR_OK; 1454 } 1455 1456 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 1457 const struct dsdb_attribute *attr, 1458 const struct drsuapi_DsReplicaAttribute *in, 1459 TALLOC_CTX *mem_ctx, 1460 struct ldb_message_element *out) 1461 { 1462 unsigned int i; 1463 1464 out->flags = 0; 1465 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName); 1466 W_ERROR_HAVE_NO_MEMORY(out->name); 1467 1468 out->num_values = in->value_ctr.num_values; 1469 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values); 1470 W_ERROR_HAVE_NO_MEMORY(out->values); 1471 1472 for (i=0; i < out->num_values; i++) { 1473 char *str; 1474 1475 if (in->value_ctr.values[i].blob == NULL) { 1476 return WERR_FOOBAR; 1477 } 1478 1479 if (in->value_ctr.values[i].blob->length == 0) { 1480 return WERR_FOOBAR; 1481 } 1482 1483 if (!convert_string_talloc(out->values, 1484 CH_UTF16, CH_UNIX, 1485 in->value_ctr.values[i].blob->data, 1486 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); 1492 } 1493 1494 return WERR_OK; 1495 } 1496 1497 static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 1498 const struct dsdb_attribute *attr, 1499 const struct ldb_message_element *in, 1500 TALLOC_CTX *mem_ctx, 1501 struct drsuapi_DsReplicaAttribute *out) 1502 { 1503 unsigned int i; 900 1504 DATA_BLOB *blobs; 901 1505 902 if (attr->attributeID_id == 0xFFFFFFFF) { 903 return WERR_FOOBAR; 904 } 905 906 switch (attr->attributeID_id) { 907 case DRSUAPI_ATTRIBUTE_objectClass: 908 case DRSUAPI_ATTRIBUTE_subClassOf: 909 case DRSUAPI_ATTRIBUTE_auxiliaryClass: 910 case DRSUAPI_ATTRIBUTE_systemPossSuperiors: 911 case DRSUAPI_ATTRIBUTE_possSuperiors: 912 return _dsdb_syntax_OID_obj_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out); 913 case DRSUAPI_ATTRIBUTE_systemMustContain: 914 case DRSUAPI_ATTRIBUTE_systemMayContain: 915 case DRSUAPI_ATTRIBUTE_mustContain: 916 case DRSUAPI_ATTRIBUTE_mayContain: 917 return _dsdb_syntax_OID_attr_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out); 918 case DRSUAPI_ATTRIBUTE_governsID: 919 case DRSUAPI_ATTRIBUTE_attributeID: 920 case DRSUAPI_ATTRIBUTE_attributeSyntax: 921 return _dsdb_syntax_OID_oid_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out); 922 } 923 924 out->attid = attr->attributeID_id; 1506 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1507 return WERR_FOOBAR; 1508 } 1509 1510 out->attid = dsdb_attribute_get_attid(attr, 1511 ctx->is_schema_nc); 925 1512 out->value_ctr.num_values = in->num_values; 926 1513 out->value_ctr.values = talloc_array(mem_ctx, … … 933 1520 934 1521 for (i=0; i < in->num_values; i++) { 935 uint32_t v;936 937 1522 out->value_ctr.values[i].blob = &blobs[i]; 938 1523 939 blobs[i] = data_blob_talloc(blobs, NULL, 4); 940 W_ERROR_HAVE_NO_MEMORY(blobs[i].data); 941 942 v = strtol((const char *)in->values[i].data, NULL, 10); 943 944 SIVAL(blobs[i].data, 0, v); 945 } 946 947 return WERR_OK; 948 } 949 950 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(struct ldb_context *ldb, 951 const struct dsdb_schema *schema, 952 const struct dsdb_attribute *attr, 953 const struct drsuapi_DsReplicaAttribute *in, 954 TALLOC_CTX *mem_ctx, 955 struct ldb_message_element *out) 956 { 957 uint32_t i; 1524 if (!convert_string_talloc(blobs, 1525 CH_UNIX, CH_UTF16, 1526 in->values[i].data, in->values[i].length, 1527 (void **)&blobs[i].data, &blobs[i].length, false)) { 1528 return WERR_FOOBAR; 1529 } 1530 } 1531 1532 return WERR_OK; 1533 } 1534 1535 static WERROR dsdb_syntax_UNICODE_validate_one_val(const struct dsdb_syntax_ctx *ctx, 1536 const struct dsdb_attribute *attr, 1537 const struct ldb_val *val) 1538 { 1539 void *dst = NULL; 1540 size_t size; 1541 bool ok; 1542 1543 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1544 return WERR_FOOBAR; 1545 } 1546 1547 ok = convert_string_talloc(ctx->ldb, 1548 CH_UNIX, CH_UTF16, 1549 val->data, 1550 val->length, 1551 (void **)&dst, 1552 &size, false); 1553 TALLOC_FREE(dst); 1554 if (!ok) { 1555 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1556 } 1557 1558 if (attr->rangeLower) { 1559 if ((size/2) < *attr->rangeLower) { 1560 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1561 } 1562 } 1563 1564 if (attr->rangeUpper) { 1565 if ((size/2) > *attr->rangeUpper) { 1566 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1567 } 1568 } 1569 1570 return WERR_OK; 1571 } 1572 1573 static WERROR dsdb_syntax_UNICODE_validate_ldb(const struct dsdb_syntax_ctx *ctx, 1574 const struct dsdb_attribute *attr, 1575 const struct ldb_message_element *in) 1576 { 1577 WERROR status; 1578 unsigned int i; 1579 1580 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1581 return WERR_FOOBAR; 1582 } 1583 1584 for (i=0; i < in->num_values; i++) { 1585 if (in->values[i].length == 0) { 1586 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1587 } 1588 1589 status = dsdb_syntax_UNICODE_validate_one_val(ctx, 1590 attr, 1591 &in->values[i]); 1592 if (!W_ERROR_IS_OK(status)) { 1593 return status; 1594 } 1595 } 1596 1597 return WERR_OK; 1598 } 1599 1600 static WERROR dsdb_syntax_one_DN_drsuapi_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 1601 const struct dsdb_syntax *syntax, 1602 const DATA_BLOB *in, DATA_BLOB *out) 1603 { 1604 struct drsuapi_DsReplicaObjectIdentifier3 id3; 1605 enum ndr_err_code ndr_err; 1606 DATA_BLOB guid_blob; 1607 struct ldb_dn *dn; 1608 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 1609 int ret; 1610 NTSTATUS status; 1611 1612 if (!tmp_ctx) { 1613 W_ERROR_HAVE_NO_MEMORY(tmp_ctx); 1614 } 1615 1616 if (in == NULL) { 1617 talloc_free(tmp_ctx); 1618 return WERR_FOOBAR; 1619 } 1620 1621 if (in->length == 0) { 1622 talloc_free(tmp_ctx); 1623 return WERR_FOOBAR; 1624 } 1625 1626 1627 /* windows sometimes sends an extra two pad bytes here */ 1628 ndr_err = ndr_pull_struct_blob(in, 1629 tmp_ctx, &id3, 1630 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3); 1631 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1632 status = ndr_map_error2ntstatus(ndr_err); 1633 talloc_free(tmp_ctx); 1634 return ntstatus_to_werror(status); 1635 } 1636 1637 dn = ldb_dn_new(tmp_ctx, ldb, id3.dn); 1638 if (!dn) { 1639 talloc_free(tmp_ctx); 1640 /* If this fails, it must be out of memory, as it does not do much parsing */ 1641 W_ERROR_HAVE_NO_MEMORY(dn); 1642 } 1643 1644 if (!GUID_all_zero(&id3.guid)) { 1645 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob); 1646 if (!NT_STATUS_IS_OK(status)) { 1647 talloc_free(tmp_ctx); 1648 return ntstatus_to_werror(status); 1649 } 1650 1651 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob); 1652 if (ret != LDB_SUCCESS) { 1653 talloc_free(tmp_ctx); 1654 return WERR_FOOBAR; 1655 } 1656 talloc_free(guid_blob.data); 1657 } 1658 1659 if (id3.__ndr_size_sid) { 1660 DATA_BLOB sid_blob; 1661 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid, 1662 (ndr_push_flags_fn_t)ndr_push_dom_sid); 1663 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1664 status = ndr_map_error2ntstatus(ndr_err); 1665 talloc_free(tmp_ctx); 1666 return ntstatus_to_werror(status); 1667 } 1668 1669 ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob); 1670 if (ret != LDB_SUCCESS) { 1671 talloc_free(tmp_ctx); 1672 return WERR_FOOBAR; 1673 } 1674 } 1675 1676 *out = data_blob_string_const(ldb_dn_get_extended_linearized(mem_ctx, dn, 1)); 1677 talloc_free(tmp_ctx); 1678 return WERR_OK; 1679 } 1680 1681 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 1682 const struct dsdb_attribute *attr, 1683 const struct drsuapi_DsReplicaAttribute *in, 1684 TALLOC_CTX *mem_ctx, 1685 struct ldb_message_element *out) 1686 { 1687 unsigned int i; 958 1688 959 1689 out->flags = 0; … … 966 1696 967 1697 for (i=0; i < out->num_values; i++) { 968 char *str; 969 970 if (in->value_ctr.values[i].blob == NULL) { 971 return WERR_FOOBAR; 972 } 973 974 if (in->value_ctr.values[i].blob->length == 0) { 975 return WERR_FOOBAR; 976 } 977 978 if (!convert_string_talloc_convenience(out->values, 979 schema->iconv_convenience, 980 CH_UTF16, CH_UNIX, 981 in->value_ctr.values[i].blob->data, 982 in->value_ctr.values[i].blob->length, 983 (void **)&str, NULL, false)) { 984 return WERR_FOOBAR; 985 } 986 987 out->values[i] = data_blob_string_const(str); 988 } 989 990 return WERR_OK; 991 } 992 993 static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(struct ldb_context *ldb, 994 const struct dsdb_schema *schema, 995 const struct dsdb_attribute *attr, 996 const struct ldb_message_element *in, 997 TALLOC_CTX *mem_ctx, 998 struct drsuapi_DsReplicaAttribute *out) 999 { 1000 uint32_t i; 1698 WERROR status = dsdb_syntax_one_DN_drsuapi_to_ldb(out->values, ctx->ldb, attr->syntax, 1699 in->value_ctr.values[i].blob, 1700 &out->values[i]); 1701 if (!W_ERROR_IS_OK(status)) { 1702 return status; 1703 } 1704 1705 } 1706 1707 return WERR_OK; 1708 } 1709 1710 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 1711 const struct dsdb_attribute *attr, 1712 const struct ldb_message_element *in, 1713 TALLOC_CTX *mem_ctx, 1714 struct drsuapi_DsReplicaAttribute *out) 1715 { 1716 unsigned int i; 1001 1717 DATA_BLOB *blobs; 1002 1718 1003 if (attr->attributeID_id == 0xFFFFFFFF) { 1004 return WERR_FOOBAR; 1005 } 1006 1007 out->attid = attr->attributeID_id; 1719 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1720 return WERR_FOOBAR; 1721 } 1722 1723 out->attid = dsdb_attribute_get_attid(attr, 1724 ctx->is_schema_nc); 1008 1725 out->value_ctr.num_values = in->num_values; 1009 1726 out->value_ctr.values = talloc_array(mem_ctx, … … 1016 1733 1017 1734 for (i=0; i < in->num_values; i++) { 1735 struct drsuapi_DsReplicaObjectIdentifier3 id3; 1736 enum ndr_err_code ndr_err; 1737 struct ldb_dn *dn; 1738 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 1739 NTSTATUS status; 1740 1741 W_ERROR_HAVE_NO_MEMORY(tmp_ctx); 1742 1018 1743 out->value_ctr.values[i].blob = &blobs[i]; 1019 1744 1020 if (!convert_string_talloc_convenience(blobs, 1021 schema->iconv_convenience, CH_UNIX, CH_UTF16, 1022 in->values[i].data, in->values[i].length, 1023 (void **)&blobs[i].data, &blobs[i].length, false)) { 1024 return WERR_FOOBAR; 1025 } 1026 } 1027 1028 return WERR_OK; 1029 } 1030 1031 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb, 1032 const struct dsdb_schema *schema, 1033 const struct dsdb_attribute *attr, 1034 const struct drsuapi_DsReplicaAttribute *in, 1035 TALLOC_CTX *mem_ctx, 1036 struct ldb_message_element *out) 1037 { 1038 uint32_t i; 1745 dn = ldb_dn_from_ldb_val(tmp_ctx, ctx->ldb, &in->values[i]); 1746 1747 W_ERROR_HAVE_NO_MEMORY(dn); 1748 1749 ZERO_STRUCT(id3); 1750 1751 status = dsdb_get_extended_dn_guid(dn, &id3.guid, "GUID"); 1752 if (!NT_STATUS_IS_OK(status) && 1753 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 1754 talloc_free(tmp_ctx); 1755 return ntstatus_to_werror(status); 1756 } 1757 1758 status = dsdb_get_extended_dn_sid(dn, &id3.sid, "SID"); 1759 if (!NT_STATUS_IS_OK(status) && 1760 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 1761 talloc_free(tmp_ctx); 1762 return ntstatus_to_werror(status); 1763 } 1764 1765 id3.dn = ldb_dn_get_linearized(dn); 1766 1767 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3); 1768 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1769 status = ndr_map_error2ntstatus(ndr_err); 1770 talloc_free(tmp_ctx); 1771 return ntstatus_to_werror(status); 1772 } 1773 talloc_free(tmp_ctx); 1774 } 1775 1776 return WERR_OK; 1777 } 1778 1779 static WERROR dsdb_syntax_DN_validate_one_val(const struct dsdb_syntax_ctx *ctx, 1780 const struct dsdb_attribute *attr, 1781 const struct ldb_val *val, 1782 TALLOC_CTX *mem_ctx, 1783 struct dsdb_dn **_dsdb_dn) 1784 { 1785 static const char * const extended_list[] = { "GUID", "SID", NULL }; 1786 enum ndr_err_code ndr_err; 1787 struct GUID guid; 1788 struct dom_sid sid; 1789 const DATA_BLOB *sid_blob; 1790 struct dsdb_dn *dsdb_dn; 1791 struct ldb_dn *dn; 1792 char *dn_str; 1793 struct ldb_dn *dn2; 1794 char *dn2_str; 1795 int num_components; 1796 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 1797 NTSTATUS status; 1798 1799 W_ERROR_HAVE_NO_MEMORY(tmp_ctx); 1800 1801 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1802 return WERR_FOOBAR; 1803 } 1804 1805 dsdb_dn = dsdb_dn_parse(tmp_ctx, ctx->ldb, val, 1806 attr->syntax->ldap_oid); 1807 if (!dsdb_dn) { 1808 talloc_free(tmp_ctx); 1809 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1810 } 1811 dn = dsdb_dn->dn; 1812 1813 dn2 = ldb_dn_copy(tmp_ctx, dn); 1814 if (dn == NULL) { 1815 talloc_free(tmp_ctx); 1816 return WERR_NOMEM; 1817 } 1818 1819 num_components = ldb_dn_get_comp_num(dn); 1820 1821 status = dsdb_get_extended_dn_guid(dn, &guid, "GUID"); 1822 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 1823 num_components++; 1824 } else if (!NT_STATUS_IS_OK(status)) { 1825 talloc_free(tmp_ctx); 1826 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1827 } 1828 1829 sid_blob = ldb_dn_get_extended_component(dn, "SID"); 1830 if (sid_blob) { 1831 num_components++; 1832 ndr_err = ndr_pull_struct_blob_all(sid_blob, 1833 tmp_ctx, 1834 &sid, 1835 (ndr_pull_flags_fn_t)ndr_pull_dom_sid); 1836 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1837 talloc_free(tmp_ctx); 1838 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1839 } 1840 } 1841 1842 /* Do not allow links to the RootDSE */ 1843 if (num_components == 0) { 1844 talloc_free(tmp_ctx); 1845 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1846 } 1847 1848 /* 1849 * We need to check that only "GUID" and "SID" are 1850 * specified as extended components, we do that 1851 * by comparing the dn's after removing all components 1852 * from one dn and only the allowed subset from the other 1853 * one. 1854 */ 1855 ldb_dn_extended_filter(dn, extended_list); 1856 1857 dn_str = ldb_dn_get_extended_linearized(tmp_ctx, dn, 0); 1858 if (dn_str == NULL) { 1859 talloc_free(tmp_ctx); 1860 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1861 } 1862 dn2_str = ldb_dn_get_extended_linearized(tmp_ctx, dn2, 0); 1863 if (dn2_str == NULL) { 1864 talloc_free(tmp_ctx); 1865 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1866 } 1867 1868 if (strcmp(dn_str, dn2_str) != 0) { 1869 talloc_free(tmp_ctx); 1870 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1871 } 1872 1873 *_dsdb_dn = talloc_move(mem_ctx, &dsdb_dn); 1874 talloc_free(tmp_ctx); 1875 return WERR_OK; 1876 } 1877 1878 static WERROR dsdb_syntax_DN_validate_ldb(const struct dsdb_syntax_ctx *ctx, 1879 const struct dsdb_attribute *attr, 1880 const struct ldb_message_element *in) 1881 { 1882 unsigned int i; 1883 1884 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 1885 return WERR_FOOBAR; 1886 } 1887 1888 for (i=0; i < in->num_values; i++) { 1889 WERROR status; 1890 struct dsdb_dn *dsdb_dn; 1891 TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb); 1892 W_ERROR_HAVE_NO_MEMORY(tmp_ctx); 1893 1894 status = dsdb_syntax_DN_validate_one_val(ctx, 1895 attr, 1896 &in->values[i], 1897 tmp_ctx, &dsdb_dn); 1898 if (!W_ERROR_IS_OK(status)) { 1899 talloc_free(tmp_ctx); 1900 return status; 1901 } 1902 1903 if (dsdb_dn->dn_format != DSDB_NORMAL_DN) { 1904 talloc_free(tmp_ctx); 1905 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 1906 } 1907 1908 talloc_free(tmp_ctx); 1909 } 1910 1911 return WERR_OK; 1912 } 1913 1914 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 1915 const struct dsdb_attribute *attr, 1916 const struct drsuapi_DsReplicaAttribute *in, 1917 TALLOC_CTX *mem_ctx, 1918 struct ldb_message_element *out) 1919 { 1920 unsigned int i; 1039 1921 int ret; 1040 1922 … … 1048 1930 1049 1931 for (i=0; i < out->num_values; i++) { 1050 struct drsuapi_DsReplicaObjectIdentifier3 id3;1932 struct drsuapi_DsReplicaObjectIdentifier3Binary id3; 1051 1933 enum ndr_err_code ndr_err; 1052 1934 DATA_BLOB guid_blob; 1053 1935 struct ldb_dn *dn; 1936 struct dsdb_dn *dsdb_dn; 1937 NTSTATUS status; 1054 1938 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 1055 1939 if (!tmp_ctx) { … … 1067 1951 } 1068 1952 1069 1953 1070 1954 /* windows sometimes sends an extra two pad bytes here */ 1071 1955 ndr_err = ndr_pull_struct_blob(in->value_ctr.values[i].blob, 1072 tmp_ctx, schema->iconv_convenience,&id3,1073 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3 );1956 tmp_ctx, &id3, 1957 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary); 1074 1958 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1075 NTSTATUSstatus = ndr_map_error2ntstatus(ndr_err);1959 status = ndr_map_error2ntstatus(ndr_err); 1076 1960 talloc_free(tmp_ctx); 1077 1961 return ntstatus_to_werror(status); 1078 1962 } 1079 1963 1080 dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);1964 dn = ldb_dn_new(tmp_ctx, ctx->ldb, id3.dn); 1081 1965 if (!dn) { 1082 1966 talloc_free(tmp_ctx); … … 1085 1969 } 1086 1970 1087 ndr_err = ndr_push_struct_blob(&guid_blob, tmp_ctx, schema->iconv_convenience, &id3.guid, 1088 (ndr_push_flags_fn_t)ndr_push_GUID); 1089 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1090 NTSTATUS status = ndr_map_error2ntstatus(ndr_err); 1971 status = GUID_to_ndr_blob(&id3.guid, tmp_ctx, &guid_blob); 1972 if (!NT_STATUS_IS_OK(status)) { 1091 1973 talloc_free(tmp_ctx); 1092 1974 return ntstatus_to_werror(status); … … 1103 1985 if (id3.__ndr_size_sid) { 1104 1986 DATA_BLOB sid_blob; 1105 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, schema->iconv_convenience,&id3.sid,1987 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, &id3.sid, 1106 1988 (ndr_push_flags_fn_t)ndr_push_dom_sid); 1107 1989 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1108 NTSTATUSstatus = ndr_map_error2ntstatus(ndr_err);1990 status = ndr_map_error2ntstatus(ndr_err); 1109 1991 talloc_free(tmp_ctx); 1110 1992 return ntstatus_to_werror(status); … … 1118 2000 } 1119 2001 1120 out->values[i] = data_blob_string_const(ldb_dn_get_extended_linearized(out->values, dn, 1)); 2002 /* set binary stuff */ 2003 dsdb_dn = dsdb_dn_construct(tmp_ctx, dn, id3.binary, attr->syntax->ldap_oid); 2004 if (!dsdb_dn) { 2005 /* If this fails, it must be out of memory, we know the ldap_oid is valid */ 2006 talloc_free(tmp_ctx); 2007 W_ERROR_HAVE_NO_MEMORY(dsdb_dn); 2008 } 2009 out->values[i] = data_blob_string_const(dsdb_dn_get_extended_linearized(out->values, dsdb_dn, 1)); 1121 2010 talloc_free(tmp_ctx); 1122 2011 } … … 1125 2014 } 1126 2015 1127 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(struct ldb_context *ldb, 1128 const struct dsdb_schema *schema, 1129 const struct dsdb_attribute *attr, 1130 const struct ldb_message_element *in, 1131 TALLOC_CTX *mem_ctx, 1132 struct drsuapi_DsReplicaAttribute *out) 1133 { 1134 uint32_t i; 2016 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 2017 const struct dsdb_attribute *attr, 2018 const struct ldb_message_element *in, 2019 TALLOC_CTX *mem_ctx, 2020 struct drsuapi_DsReplicaAttribute *out) 2021 { 2022 unsigned int i; 1135 2023 DATA_BLOB *blobs; 1136 2024 1137 if (attr->attributeID_id == 0xFFFFFFFF) { 1138 return WERR_FOOBAR; 1139 } 1140 1141 out->attid = attr->attributeID_id; 2025 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 2026 return WERR_FOOBAR; 2027 } 2028 2029 out->attid = dsdb_attribute_get_attid(attr, 2030 ctx->is_schema_nc); 1142 2031 out->value_ctr.num_values = in->num_values; 1143 2032 out->value_ctr.values = talloc_array(mem_ctx, … … 1150 2039 1151 2040 for (i=0; i < in->num_values; i++) { 1152 struct drsuapi_DsReplicaObjectIdentifier3 id3;2041 struct drsuapi_DsReplicaObjectIdentifier3Binary id3; 1153 2042 enum ndr_err_code ndr_err; 1154 const DATA_BLOB * guid_blob, *sid_blob;1155 struct ldb_dn *dn;2043 const DATA_BLOB *sid_blob; 2044 struct dsdb_dn *dsdb_dn; 1156 2045 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 2046 NTSTATUS status; 2047 1157 2048 W_ERROR_HAVE_NO_MEMORY(tmp_ctx); 1158 2049 1159 2050 out->value_ctr.values[i].blob = &blobs[i]; 1160 2051 1161 dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]); 1162 1163 W_ERROR_HAVE_NO_MEMORY(dn); 1164 1165 guid_blob = ldb_dn_get_extended_component(dn, "GUID"); 2052 dsdb_dn = dsdb_dn_parse(tmp_ctx, ctx->ldb, &in->values[i], attr->syntax->ldap_oid); 2053 2054 if (!dsdb_dn) { 2055 talloc_free(tmp_ctx); 2056 return ntstatus_to_werror(NT_STATUS_INVALID_PARAMETER); 2057 } 1166 2058 1167 2059 ZERO_STRUCT(id3); 1168 2060 1169 if (guid_blob) { 1170 ndr_err = ndr_pull_struct_blob_all(guid_blob, 1171 tmp_ctx, schema->iconv_convenience, &id3.guid, 1172 (ndr_pull_flags_fn_t)ndr_pull_GUID); 2061 status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &id3.guid, "GUID"); 2062 if (!NT_STATUS_IS_OK(status) && 2063 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 2064 talloc_free(tmp_ctx); 2065 return ntstatus_to_werror(status); 2066 } 2067 2068 sid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "SID"); 2069 if (sid_blob) { 2070 2071 ndr_err = ndr_pull_struct_blob_all(sid_blob, 2072 tmp_ctx, &id3.sid, 2073 (ndr_pull_flags_fn_t)ndr_pull_dom_sid); 1173 2074 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1174 NTSTATUSstatus = ndr_map_error2ntstatus(ndr_err);2075 status = ndr_map_error2ntstatus(ndr_err); 1175 2076 talloc_free(tmp_ctx); 1176 2077 return ntstatus_to_werror(status); … … 1178 2079 } 1179 2080 1180 sid_blob = ldb_dn_get_extended_component(dn, "SID"); 1181 if (sid_blob) { 1182 1183 ndr_err = ndr_pull_struct_blob_all(sid_blob, 1184 tmp_ctx, schema->iconv_convenience, &id3.sid, 1185 (ndr_pull_flags_fn_t)ndr_pull_dom_sid); 1186 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1187 NTSTATUS status = ndr_map_error2ntstatus(ndr_err); 1188 talloc_free(tmp_ctx); 1189 return ntstatus_to_werror(status); 1190 } 1191 } 1192 1193 id3.dn = ldb_dn_get_linearized(dn); 1194 1195 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3); 2081 id3.dn = ldb_dn_get_linearized(dsdb_dn->dn); 2082 2083 /* get binary stuff */ 2084 id3.binary = dsdb_dn->extra_part; 2085 2086 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary); 1196 2087 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1197 NTSTATUSstatus = ndr_map_error2ntstatus(ndr_err);2088 status = ndr_map_error2ntstatus(ndr_err); 1198 2089 talloc_free(tmp_ctx); 1199 2090 return ntstatus_to_werror(status); … … 1205 2096 } 1206 2097 1207 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb, 1208 const struct dsdb_schema *schema, 2098 static WERROR dsdb_syntax_DN_BINARY_validate_ldb(const struct dsdb_syntax_ctx *ctx, 2099 const struct dsdb_attribute *attr, 2100 const struct ldb_message_element *in) 2101 { 2102 unsigned int i; 2103 2104 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 2105 return WERR_FOOBAR; 2106 } 2107 2108 for (i=0; i < in->num_values; i++) { 2109 WERROR status; 2110 struct dsdb_dn *dsdb_dn; 2111 TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb); 2112 W_ERROR_HAVE_NO_MEMORY(tmp_ctx); 2113 2114 status = dsdb_syntax_DN_validate_one_val(ctx, 2115 attr, 2116 &in->values[i], 2117 tmp_ctx, &dsdb_dn); 2118 if (!W_ERROR_IS_OK(status)) { 2119 talloc_free(tmp_ctx); 2120 return status; 2121 } 2122 2123 if (dsdb_dn->dn_format != DSDB_BINARY_DN) { 2124 talloc_free(tmp_ctx); 2125 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 2126 } 2127 2128 status = dsdb_syntax_DATA_BLOB_validate_one_val(ctx, 2129 attr, 2130 &dsdb_dn->extra_part); 2131 if (!W_ERROR_IS_OK(status)) { 2132 talloc_free(tmp_ctx); 2133 return status; 2134 } 2135 2136 talloc_free(tmp_ctx); 2137 } 2138 2139 return WERR_OK; 2140 } 2141 2142 static WERROR dsdb_syntax_DN_STRING_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 1209 2143 const struct dsdb_attribute *attr, 1210 2144 const struct drsuapi_DsReplicaAttribute *in, … … 1212 2146 struct ldb_message_element *out) 1213 2147 { 1214 uint32_t i; 1215 1216 out->flags = 0; 1217 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName); 1218 W_ERROR_HAVE_NO_MEMORY(out->name); 1219 1220 out->num_values = in->value_ctr.num_values; 1221 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values); 1222 W_ERROR_HAVE_NO_MEMORY(out->values); 1223 1224 for (i=0; i < out->num_values; i++) { 1225 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b; 1226 char *binary; 1227 char *str; 1228 enum ndr_err_code ndr_err; 1229 1230 if (in->value_ctr.values[i].blob == NULL) { 1231 return WERR_FOOBAR; 1232 } 1233 1234 if (in->value_ctr.values[i].blob->length == 0) { 1235 return WERR_FOOBAR; 1236 } 1237 1238 ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob, 1239 out->values, schema->iconv_convenience, &id3b, 1240 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary); 1241 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1242 NTSTATUS status = ndr_map_error2ntstatus(ndr_err); 1243 return ntstatus_to_werror(status); 1244 } 1245 1246 /* TODO: handle id3.guid and id3.sid */ 1247 binary = data_blob_hex_string(out->values, &id3b.binary); 1248 W_ERROR_HAVE_NO_MEMORY(binary); 1249 1250 str = talloc_asprintf(out->values, "B:%u:%s:%s", 1251 (unsigned int)(id3b.binary.length * 2), /* because of 2 hex chars per byte */ 1252 binary, 1253 id3b.dn); 1254 W_ERROR_HAVE_NO_MEMORY(str); 1255 1256 /* TODO: handle id3.guid and id3.sid */ 1257 out->values[i] = data_blob_string_const(str); 1258 } 1259 1260 return WERR_OK; 1261 } 1262 1263 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb, 1264 const struct dsdb_schema *schema, 2148 return dsdb_syntax_DN_BINARY_drsuapi_to_ldb(ctx, 2149 attr, 2150 in, 2151 mem_ctx, 2152 out); 2153 } 2154 2155 static WERROR dsdb_syntax_DN_STRING_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 1265 2156 const struct dsdb_attribute *attr, 1266 2157 const struct ldb_message_element *in, … … 1268 2159 struct drsuapi_DsReplicaAttribute *out) 1269 2160 { 1270 uint32_t i; 2161 return dsdb_syntax_DN_BINARY_ldb_to_drsuapi(ctx, 2162 attr, 2163 in, 2164 mem_ctx, 2165 out); 2166 } 2167 2168 static WERROR dsdb_syntax_DN_STRING_validate_ldb(const struct dsdb_syntax_ctx *ctx, 2169 const struct dsdb_attribute *attr, 2170 const struct ldb_message_element *in) 2171 { 2172 unsigned int i; 2173 2174 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 2175 return WERR_FOOBAR; 2176 } 2177 2178 for (i=0; i < in->num_values; i++) { 2179 WERROR status; 2180 struct dsdb_dn *dsdb_dn; 2181 TALLOC_CTX *tmp_ctx = talloc_new(ctx->ldb); 2182 W_ERROR_HAVE_NO_MEMORY(tmp_ctx); 2183 2184 status = dsdb_syntax_DN_validate_one_val(ctx, 2185 attr, 2186 &in->values[i], 2187 tmp_ctx, &dsdb_dn); 2188 if (!W_ERROR_IS_OK(status)) { 2189 talloc_free(tmp_ctx); 2190 return status; 2191 } 2192 2193 if (dsdb_dn->dn_format != DSDB_STRING_DN) { 2194 talloc_free(tmp_ctx); 2195 return WERR_DS_INVALID_ATTRIBUTE_SYNTAX; 2196 } 2197 2198 status = dsdb_syntax_UNICODE_validate_one_val(ctx, 2199 attr, 2200 &dsdb_dn->extra_part); 2201 if (!W_ERROR_IS_OK(status)) { 2202 talloc_free(tmp_ctx); 2203 return status; 2204 } 2205 2206 talloc_free(tmp_ctx); 2207 } 2208 2209 return WERR_OK; 2210 } 2211 2212 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_syntax_ctx *ctx, 2213 const struct dsdb_attribute *attr, 2214 const struct drsuapi_DsReplicaAttribute *in, 2215 TALLOC_CTX *mem_ctx, 2216 struct ldb_message_element *out) 2217 { 2218 unsigned int i; 2219 2220 out->flags = 0; 2221 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName); 2222 W_ERROR_HAVE_NO_MEMORY(out->name); 2223 2224 out->num_values = in->value_ctr.num_values; 2225 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values); 2226 W_ERROR_HAVE_NO_MEMORY(out->values); 2227 2228 for (i=0; i < out->num_values; i++) { 2229 size_t len; 2230 char *str; 2231 2232 if (in->value_ctr.values[i].blob == NULL) { 2233 return WERR_FOOBAR; 2234 } 2235 2236 if (in->value_ctr.values[i].blob->length < 4) { 2237 return WERR_FOOBAR; 2238 } 2239 2240 len = IVAL(in->value_ctr.values[i].blob->data, 0); 2241 2242 if (len != in->value_ctr.values[i].blob->length) { 2243 return WERR_FOOBAR; 2244 } 2245 2246 if (!convert_string_talloc(out->values, CH_UTF16, CH_UNIX, 2247 in->value_ctr.values[i].blob->data+4, 2248 in->value_ctr.values[i].blob->length-4, 2249 (void **)&str, NULL, false)) { 2250 return WERR_FOOBAR; 2251 } 2252 2253 out->values[i] = data_blob_string_const(str); 2254 } 2255 2256 return WERR_OK; 2257 } 2258 2259 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx, 2260 const struct dsdb_attribute *attr, 2261 const struct ldb_message_element *in, 2262 TALLOC_CTX *mem_ctx, 2263 struct drsuapi_DsReplicaAttribute *out) 2264 { 2265 unsigned int i; 1271 2266 DATA_BLOB *blobs; 1272 2267 1273 if (attr->attributeID_id == 0xFFFFFFFF) { 1274 return WERR_FOOBAR; 1275 } 1276 1277 out->attid = attr->attributeID_id; 2268 if (attr->attributeID_id == DRSUAPI_ATTID_INVALID) { 2269 return WERR_FOOBAR; 2270 } 2271 2272 out->attid = dsdb_attribute_get_attid(attr, 2273 ctx->is_schema_nc); 1278 2274 out->value_ctr.num_values = in->num_values; 1279 2275 out->value_ctr.values = talloc_array(mem_ctx, … … 1286 2282 1287 2283 for (i=0; i < in->num_values; i++) { 1288 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;1289 enum ndr_err_code ndr_err;1290 1291 out->value_ctr.values[i].blob = &blobs[i];1292 1293 /* TODO: handle id3b.guid and id3b.sid, id3.binary */1294 ZERO_STRUCT(id3b);1295 id3b.dn = (const char *)in->values[i].data;1296 id3b.binary = data_blob(NULL, 0);1297 1298 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3b,1299 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);1300 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {1301 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);1302 return ntstatus_to_werror(status);1303 }1304 }1305 1306 return WERR_OK;1307 }1308 1309 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(struct ldb_context *ldb,1310 const struct dsdb_schema *schema,1311 const struct dsdb_attribute *attr,1312 const struct drsuapi_DsReplicaAttribute *in,1313 TALLOC_CTX *mem_ctx,1314 struct ldb_message_element *out)1315 {1316 uint32_t i;1317 1318 out->flags = 0;1319 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);1320 W_ERROR_HAVE_NO_MEMORY(out->name);1321 1322 out->num_values = in->value_ctr.num_values;1323 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);1324 W_ERROR_HAVE_NO_MEMORY(out->values);1325 1326 for (i=0; i < out->num_values; i++) {1327 uint32_t len;1328 char *str;1329 1330 if (in->value_ctr.values[i].blob == NULL) {1331 return WERR_FOOBAR;1332 }1333 1334 if (in->value_ctr.values[i].blob->length < 4) {1335 return WERR_FOOBAR;1336 }1337 1338 len = IVAL(in->value_ctr.values[i].blob->data, 0);1339 1340 if (len != in->value_ctr.values[i].blob->length) {1341 return WERR_FOOBAR;1342 }1343 1344 if (!convert_string_talloc_convenience(out->values, schema->iconv_convenience, CH_UTF16, CH_UNIX,1345 in->value_ctr.values[i].blob->data+4,1346 in->value_ctr.values[i].blob->length-4,1347 (void **)&str, NULL, false)) {1348 return WERR_FOOBAR;1349 }1350 1351 out->values[i] = data_blob_string_const(str);1352 }1353 1354 return WERR_OK;1355 }1356 1357 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(struct ldb_context *ldb,1358 const struct dsdb_schema *schema,1359 const struct dsdb_attribute *attr,1360 const struct ldb_message_element *in,1361 TALLOC_CTX *mem_ctx,1362 struct drsuapi_DsReplicaAttribute *out)1363 {1364 uint32_t i;1365 DATA_BLOB *blobs;1366 1367 if (attr->attributeID_id == 0xFFFFFFFF) {1368 return WERR_FOOBAR;1369 }1370 1371 out->attid = attr->attributeID_id;1372 out->value_ctr.num_values = in->num_values;1373 out->value_ctr.values = talloc_array(mem_ctx,1374 struct drsuapi_DsAttributeValue,1375 in->num_values);1376 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);1377 1378 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);1379 W_ERROR_HAVE_NO_MEMORY(blobs);1380 1381 for (i=0; i < in->num_values; i++) {1382 2284 uint8_t *data; 1383 2285 size_t ret; … … 1385 2287 out->value_ctr.values[i].blob = &blobs[i]; 1386 2288 1387 if (!convert_string_talloc _convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,1388 1389 1390 2289 if (!convert_string_talloc(blobs, CH_UNIX, CH_UTF16, 2290 in->values[i].data, 2291 in->values[i].length, 2292 (void **)&data, &ret, false)) { 1391 2293 return WERR_FOOBAR; 1392 2294 } … … 1404 2306 1405 2307 return WERR_OK; 2308 } 2309 2310 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_validate_ldb(const struct dsdb_syntax_ctx *ctx, 2311 const struct dsdb_attribute *attr, 2312 const struct ldb_message_element *in) 2313 { 2314 return dsdb_syntax_UNICODE_validate_ldb(ctx, 2315 attr, 2316 in); 1406 2317 } 1407 2318 … … 1416 2327 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb, 1417 2328 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi, 2329 .validate_ldb = dsdb_syntax_BOOL_validate_ldb, 1418 2330 .equality = "booleanMatch", 1419 .comment = "Boolean" 2331 .comment = "Boolean" 1420 2332 },{ 1421 2333 .name = "Integer", … … 1425 2337 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb, 1426 2338 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi, 2339 .validate_ldb = dsdb_syntax_INT32_validate_ldb, 1427 2340 .equality = "integerMatch", 1428 2341 .comment = "Integer", … … 1435 2348 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb, 1436 2349 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi, 2350 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb, 1437 2351 .equality = "octetStringMatch", 1438 2352 .comment = "Octet String", … … 1444 2358 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb, 1445 2359 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi, 2360 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb, 1446 2361 .equality = "octetStringMatch", 1447 2362 .comment = "Octet String - Security Identifier (SID)", … … 1454 2369 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb, 1455 2370 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi, 2371 .validate_ldb = dsdb_syntax_OID_validate_ldb, 1456 2372 .equality = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */ 1457 2373 .comment = "OID String", … … 1464 2380 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb, 1465 2381 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi, 2382 .validate_ldb = dsdb_syntax_INT32_validate_ldb, 1466 2383 .ldb_syntax = LDB_SYNTAX_SAMBA_INT32 1467 2384 },{ … … 1473 2390 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb, 1474 2391 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi, 2392 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb, 1475 2393 .equality = "numericStringMatch", 1476 2394 .substring = "numericStringSubstringsMatch", … … 1484 2402 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb, 1485 2403 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi, 2404 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb, 1486 2405 .ldb_syntax = LDB_SYNTAX_OCTET_STRING, 1487 2406 },{ … … 1492 2411 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb, 1493 2412 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi, 2413 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb, 1494 2414 .equality = "caseIgnoreMatch", 1495 2415 .substring = "caseIgnoreSubstringsMatch", … … 1503 2423 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb, 1504 2424 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi, 2425 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb, 1505 2426 .equality = "caseExactIA5Match", 1506 2427 .comment = "Printable String", … … 1513 2434 .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb, 1514 2435 .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi, 2436 .validate_ldb = dsdb_syntax_NTTIME_UTC_validate_ldb, 1515 2437 .equality = "generalizedTimeMatch", 1516 2438 .comment = "UTC Time", … … 1522 2444 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb, 1523 2445 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi, 2446 .validate_ldb = dsdb_syntax_NTTIME_validate_ldb, 1524 2447 .equality = "generalizedTimeMatch", 1525 2448 .comment = "Generalized Time", … … 1531 2454 .oMSyntax = 27, 1532 2455 .attributeSyntax_oid = "2.5.5.3", 1533 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb, 1534 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi, 2456 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb, 2457 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi, 2458 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb, 2459 .equality = "caseExactMatch", 2460 .substring = "caseExactSubstringsMatch", 2461 /* TODO (kim): according to LDAP rfc we should be using same comparison 2462 * as Directory String (LDB_SYNTAX_DIRECTORY_STRING), but case sensitive. 2463 * But according to ms docs binary compare should do the job: 2464 * http://msdn.microsoft.com/en-us/library/cc223200(v=PROT.10).aspx */ 2465 .ldb_syntax = LDB_SYNTAX_OCTET_STRING, 1535 2466 },{ 1536 2467 .name = "String(Unicode)", … … 1540 2471 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb, 1541 2472 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi, 2473 .validate_ldb = dsdb_syntax_UNICODE_validate_ldb, 1542 2474 .equality = "caseIgnoreMatch", 1543 2475 .substring = "caseIgnoreSubstringsMatch", … … 1550 2482 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb, 1551 2483 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi, 2484 .validate_ldb = dsdb_syntax_INT64_validate_ldb, 1552 2485 .equality = "integerMatch", 1553 2486 .comment = "Large Integer", … … 1560 2493 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb, 1561 2494 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi, 2495 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb, 1562 2496 },{ 1563 2497 .name = "Object(DS-DN)", … … 1568 2502 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb, 1569 2503 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi, 2504 .validate_ldb = dsdb_syntax_DN_validate_ldb, 1570 2505 .equality = "distinguishedNameMatch", 1571 2506 .comment = "Object(DS-DN) == a DN", 1572 2507 },{ 1573 2508 .name = "Object(DN-Binary)", 1574 .ldap_oid = "1.2.840.113556.1.4.903",2509 .ldap_oid = DSDB_SYNTAX_BINARY_DN, 1575 2510 .oMSyntax = 127, 1576 2511 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"), … … 1578 2513 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb, 1579 2514 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi, 2515 .validate_ldb = dsdb_syntax_DN_BINARY_validate_ldb, 1580 2516 .equality = "octetStringMatch", 1581 2517 .comment = "OctetString: Binary+DN", 1582 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,1583 2518 },{ 1584 /* not used in w2k3 schema 2519 /* not used in w2k3 schema, but used in Exchange schema*/ 1585 2520 .name = "Object(OR-Name)", 1586 .ldap_oid = "1.2.840.113556.1.4.1221",2521 .ldap_oid = DSDB_SYNTAX_OR_NAME, 1587 2522 .oMSyntax = 127, 1588 2523 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"), 1589 2524 .attributeSyntax_oid = "2.5.5.7", 1590 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb, 1591 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi, 2525 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb, 2526 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi, 2527 .validate_ldb = dsdb_syntax_DN_BINARY_validate_ldb, 2528 .equality = "caseIgnoreMatch", 2529 .ldb_syntax = LDB_SYNTAX_DN, 1592 2530 },{ 1593 /* 2531 /* 1594 2532 * TODO: verify if DATA_BLOB is correct here...! 1595 2533 * 1596 2534 * repsFrom and repsTo are the only attributes using 1597 * this attribute syntax, but they're not replicated... 2535 * this attribute syntax, but they're not replicated... 1598 2536 */ 1599 2537 .name = "Object(Replica-Link)", … … 1604 2542 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb, 1605 2543 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi, 2544 .validate_ldb = dsdb_syntax_DATA_BLOB_validate_ldb, 1606 2545 },{ 1607 2546 .name = "Object(Presentation-Address)", … … 1612 2551 .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb, 1613 2552 .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi, 2553 .validate_ldb = dsdb_syntax_PRESENTATION_ADDRESS_validate_ldb, 1614 2554 .comment = "Presentation Address", 1615 2555 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING, … … 1623 2563 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb, 1624 2564 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi, 2565 .validate_ldb = dsdb_syntax_FOOBAR_validate_ldb, 1625 2566 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING, 1626 2567 },{ 1627 2568 /* not used in w2k3 schema */ 1628 2569 .name = "Object(DN-String)", 1629 .ldap_oid = "1.2.840.113556.1.4.904",2570 .ldap_oid = DSDB_SYNTAX_STRING_DN, 1630 2571 .oMSyntax = 127, 1631 2572 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"), 1632 2573 .attributeSyntax_oid = "2.5.5.14", 1633 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb, 1634 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi, 2574 .drsuapi_to_ldb = dsdb_syntax_DN_STRING_drsuapi_to_ldb, 2575 .ldb_to_drsuapi = dsdb_syntax_DN_STRING_ldb_to_drsuapi, 2576 .validate_ldb = dsdb_syntax_DN_STRING_validate_ldb, 1635 2577 .equality = "octetStringMatch", 1636 2578 .comment = "OctetString: String+DN", 1637 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,1638 2579 } 1639 2580 }; 1640 2581 1641 const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid) 1642 { 1643 int i;2582 const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid) 2583 { 2584 unsigned int i; 1644 2585 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) { 1645 2586 if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) { … … 1650 2591 } 1651 2592 1652 const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax) 1653 { 1654 int i;2593 const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax) 2594 { 2595 unsigned int i; 1655 2596 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) { 1656 2597 if (oMSyntax == dsdb_syntaxes[i].oMSyntax) { … … 1661 2602 } 1662 2603 1663 const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid) 1664 { 1665 int i;2604 const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid) 2605 { 2606 unsigned int i; 1666 2607 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) { 1667 2608 if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) { … … 1671 2612 return NULL; 1672 2613 } 2614 1673 2615 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr) 1674 2616 { 1675 u int32_t i;2617 unsigned int i; 1676 2618 1677 2619 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) { … … 1696 2638 } 1697 2639 1698 WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb, 2640 WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb, 1699 2641 const struct dsdb_schema *schema, 2642 const struct dsdb_schema_prefixmap *pfm_remote, 1700 2643 const struct drsuapi_DsReplicaAttribute *in, 1701 2644 TALLOC_CTX *mem_ctx, … … 1703 2646 { 1704 2647 const struct dsdb_attribute *sa; 1705 1706 sa = dsdb_attribute_by_attributeID_id(schema, in->attid); 2648 struct dsdb_syntax_ctx syntax_ctx; 2649 uint32_t attid_local; 2650 2651 /* use default syntax conversion context */ 2652 dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema); 2653 syntax_ctx.pfm_remote = pfm_remote; 2654 2655 switch (dsdb_pfm_get_attid_type(in->attid)) { 2656 case DSDB_ATTID_TYPE_PFM: 2657 /* map remote ATTID to local ATTID */ 2658 if (!dsdb_syntax_attid_from_remote_attid(&syntax_ctx, mem_ctx, in->attid, &attid_local)) { 2659 DEBUG(0,(__location__ ": Can't find local ATTID for 0x%08X\n", 2660 in->attid)); 2661 return WERR_FOOBAR; 2662 } 2663 break; 2664 case DSDB_ATTID_TYPE_INTID: 2665 /* use IntId value directly */ 2666 attid_local = in->attid; 2667 break; 2668 default: 2669 /* we should never get here */ 2670 DEBUG(0,(__location__ ": Invalid ATTID type passed for conversion - 0x%08X\n", 2671 in->attid)); 2672 return WERR_INVALID_PARAMETER; 2673 } 2674 2675 sa = dsdb_attribute_by_attributeID_id(schema, attid_local); 1707 2676 if (!sa) { 1708 return WERR_FOOBAR; 1709 } 1710 1711 return sa->syntax->drsuapi_to_ldb(ldb, schema, sa, in, mem_ctx, out); 1712 } 1713 1714 WERROR dsdb_attribute_ldb_to_drsuapi(struct ldb_context *ldb, 2677 DEBUG(1,(__location__ ": Unknown attributeID_id 0x%08X\n", in->attid)); 2678 return WERR_FOOBAR; 2679 } 2680 2681 return sa->syntax->drsuapi_to_ldb(&syntax_ctx, sa, in, mem_ctx, out); 2682 } 2683 2684 WERROR dsdb_attribute_ldb_to_drsuapi(struct ldb_context *ldb, 1715 2685 const struct dsdb_schema *schema, 1716 2686 const struct ldb_message_element *in, … … 1719 2689 { 1720 2690 const struct dsdb_attribute *sa; 2691 struct dsdb_syntax_ctx syntax_ctx; 1721 2692 1722 2693 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name); … … 1725 2696 } 1726 2697 1727 return sa->syntax->ldb_to_drsuapi(ldb, schema, sa, in, mem_ctx, out); 1728 } 2698 /* use default syntax conversion context */ 2699 dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema); 2700 2701 return sa->syntax->ldb_to_drsuapi(&syntax_ctx, sa, in, mem_ctx, out); 2702 } 2703
Note:
See TracChangeset
for help on using the changeset viewer.