mark samAccountName, objectGUID and objectSID as unique indexed
[ira/wip.git] / source4 / dsdb / schema / schema_init.c
index b6a7cf7cc8aa893501cb04b6c48e7d2d0ecc4ae1..76e7891fbd5d16f15dc988e5df29581d7180125b 100644 (file)
@@ -28,6 +28,7 @@
 #include "librpc/gen_ndr/ndr_drsuapi.h"
 #include "librpc/gen_ndr/ndr_drsblobs.h"
 #include "param/param.h"
+#include "lib/ldb/include/ldb_module.h"
 
 struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience)
 {
@@ -582,6 +583,68 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
        return WERR_OK;
 }
 
+/*
+  this will be replaced with something that looks at the right part of
+  the schema once we know where unique indexing information is hidden
+ */
+static bool dsdb_schema_unique_attribute(const char *attr)
+{
+       const char *attrs[] = { "samAccountName", "objectGUID", "objectSID" , NULL };
+       int i;
+       for (i=0;attrs[i];i++) {
+               if (strcasecmp(attr, attrs[i]) == 0) {
+                       return true;
+               }
+       }
+       return false;
+}
+
+
+/*
+  setup the ldb_schema_attribute field for a dsdb_attribute
+ */
+static int dsdb_schema_setup_ldb_schema_attribute(struct ldb_context *ldb, 
+                                                 struct dsdb_attribute *attr)
+{
+       const char *syntax = attr->syntax->ldb_syntax;
+       const struct ldb_schema_syntax *s;
+       struct ldb_schema_attribute *a;
+
+       if (!syntax) {
+               syntax = attr->syntax->ldap_oid;
+       }
+
+       s = ldb_samba_syntax_by_lDAPDisplayName(ldb, attr->lDAPDisplayName);
+       if (s == NULL) {
+               s = ldb_samba_syntax_by_name(ldb, syntax);
+       }
+       if (s == NULL) {
+               s = ldb_standard_syntax_by_name(ldb, syntax);
+       }
+
+       if (s == NULL) {
+               return LDB_ERR_OPERATIONS_ERROR;                
+       }
+
+       attr->ldb_schema_attribute = a = talloc(attr, struct ldb_schema_attribute);
+       if (attr->ldb_schema_attribute == NULL) {
+               ldb_oom(ldb);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       a->name = attr->lDAPDisplayName;
+       a->flags = 0;
+       a->syntax = s;
+
+       if (dsdb_schema_unique_attribute(a->name)) {
+               a->flags |= LDB_ATTR_FLAG_UNIQUE_INDEX;
+       }
+       
+       return LDB_SUCCESS;
+}
+
+
+
 #define GET_STRING_LDB(msg, attr, mem_ctx, p, elem, strict) do { \
        (p)->elem = samdb_result_string(msg, attr, NULL);\
        if (strict && (p)->elem == NULL) { \
@@ -676,7 +739,8 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
        }\
 } while (0)
 
-WERROR dsdb_attribute_from_ldb(const struct dsdb_schema *schema,
+WERROR dsdb_attribute_from_ldb(struct ldb_context *ldb,
+                              const struct dsdb_schema *schema,
                               struct ldb_message *msg,
                               TALLOC_CTX *mem_ctx,
                               struct dsdb_attribute *attr)
@@ -745,6 +809,10 @@ WERROR dsdb_attribute_from_ldb(const struct dsdb_schema *schema,
                return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
        }
 
+       if (dsdb_schema_setup_ldb_schema_attribute(ldb, attr) != LDB_SUCCESS) {
+               return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
+       }
+
        return WERR_OK;
 }
 
@@ -788,7 +856,6 @@ WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema,
 
        GET_STRING_LIST_LDB(msg, "systemPossSuperiors", mem_ctx, obj, systemPossSuperiors, false);
        GET_STRING_LIST_LDB(msg, "possSuperiors", mem_ctx, obj, possSuperiors, false);
-       GET_STRING_LIST_LDB(msg, "possibleInferiors", mem_ctx, obj, possibleInferiors, false);
 
        GET_STRING_LDB(msg, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, false);
 
@@ -867,7 +934,7 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
                        return LDB_ERR_OPERATIONS_ERROR;
                }
 
-               status = dsdb_attribute_from_ldb(schema, attrs_res->msgs[i], sa, sa);
+               status = dsdb_attribute_from_ldb(ldb, schema, attrs_res->msgs[i], sa, sa);
                if (!W_ERROR_IS_OK(status)) {
                        *error_string = talloc_asprintf(mem_ctx, 
                                      "schema_fsmo_init: failed to load attribute definition: %s:%s",
@@ -1275,7 +1342,8 @@ static struct drsuapi_DsReplicaAttribute *dsdb_find_object_attr_name(struct dsdb
        }\
 } while (0)
 
-WERROR dsdb_attribute_from_drsuapi(struct dsdb_schema *schema,
+WERROR dsdb_attribute_from_drsuapi(struct ldb_context *ldb,
+                                  struct dsdb_schema *schema,
                                   struct drsuapi_DsReplicaObject *r,
                                   TALLOC_CTX *mem_ctx,
                                   struct dsdb_attribute *attr)
@@ -1334,6 +1402,10 @@ WERROR dsdb_attribute_from_drsuapi(struct dsdb_schema *schema,
                return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
        }
 
+       if (dsdb_schema_setup_ldb_schema_attribute(ldb, attr) != LDB_SUCCESS) {
+               return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
+       }
+
        return WERR_OK;
 }
 
@@ -1373,7 +1445,6 @@ WERROR dsdb_class_from_drsuapi(struct dsdb_schema *schema,
 
        GET_STRING_LIST_DS(schema, r, "systemPossSuperiors", mem_ctx, obj, systemPossSuperiors, false);
        GET_STRING_LIST_DS(schema, r, "possSuperiors", mem_ctx, obj, possSuperiors, false);
-       GET_STRING_LIST_DS(schema, r, "possibleInferiors", mem_ctx, obj, possibleInferiors, false);
 
        GET_STRING_DS(schema, r, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, false);