root/source4/dsdb/schema/schema_query.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dsdb_attribute_by_attributeID_id
  2. dsdb_attribute_by_attributeID_oid
  3. dsdb_attribute_by_lDAPDisplayName
  4. dsdb_attribute_by_linkID
  5. dsdb_class_by_governsID_id
  6. dsdb_class_by_governsID_oid
  7. dsdb_class_by_lDAPDisplayName
  8. dsdb_class_by_cn
  9. dsdb_lDAPDisplayName_by_id
  10. dsdb_linked_attribute_lDAPDisplayName_list
  11. merge_attr_list
  12. dsdb_attribute_list
  13. dsdb_full_attribute_list_internal
  14. dsdb_full_attribute_list

   1 /* 
   2    Unix SMB/CIFS mplementation.
   3    DSDB schema header
   4    
   5    Copyright (C) Stefan Metzmacher <metze@samba.org> 2006-2007
   6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2008
   7 
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20    
  21 */
  22 
  23 #include "includes.h"
  24 #include "dsdb/samdb/samdb.h"
  25 
  26 const struct dsdb_attribute *dsdb_attribute_by_attributeID_id(const struct dsdb_schema *schema,
     /* [<][>][^][v][top][bottom][index][help] */
  27                                                               uint32_t id)
  28 {
  29         struct dsdb_attribute *cur;
  30 
  31         /*
  32          * 0xFFFFFFFF is used as value when no mapping table is available,
  33          * so don't try to match with it
  34          */
  35         if (id == 0xFFFFFFFF) return NULL;
  36 
  37         /* TODO: add binary search */
  38         for (cur = schema->attributes; cur; cur = cur->next) {
  39                 if (cur->attributeID_id != id) continue;
  40 
  41                 return cur;
  42         }
  43 
  44         return NULL;
  45 }
  46 
  47 const struct dsdb_attribute *dsdb_attribute_by_attributeID_oid(const struct dsdb_schema *schema,
     /* [<][>][^][v][top][bottom][index][help] */
  48                                                                const char *oid)
  49 {
  50         struct dsdb_attribute *cur;
  51 
  52         if (!oid) return NULL;
  53 
  54         /* TODO: add binary search */
  55         for (cur = schema->attributes; cur; cur = cur->next) {
  56                 if (strcmp(cur->attributeID_oid, oid) != 0) continue;
  57 
  58                 return cur;
  59         }
  60 
  61         return NULL;
  62 }
  63 
  64 const struct dsdb_attribute *dsdb_attribute_by_lDAPDisplayName(const struct dsdb_schema *schema,
     /* [<][>][^][v][top][bottom][index][help] */
  65                                                                const char *name)
  66 {
  67         struct dsdb_attribute *cur;
  68 
  69         if (!name) return NULL;
  70 
  71         /* TODO: add binary search */
  72         for (cur = schema->attributes; cur; cur = cur->next) {
  73                 if (strcasecmp(cur->lDAPDisplayName, name) != 0) continue;
  74 
  75                 return cur;
  76         }
  77 
  78         return NULL;
  79 }
  80 
  81 const struct dsdb_attribute *dsdb_attribute_by_linkID(const struct dsdb_schema *schema,
     /* [<][>][^][v][top][bottom][index][help] */
  82                                                       int linkID)
  83 {
  84         struct dsdb_attribute *cur;
  85 
  86         /* TODO: add binary search */
  87         for (cur = schema->attributes; cur; cur = cur->next) {
  88                 if (cur->linkID != linkID) continue;
  89 
  90                 return cur;
  91         }
  92 
  93         return NULL;
  94 }
  95 
  96 const struct dsdb_class *dsdb_class_by_governsID_id(const struct dsdb_schema *schema,
     /* [<][>][^][v][top][bottom][index][help] */
  97                                                     uint32_t id)
  98 {
  99         struct dsdb_class *cur;
 100 
 101         /*
 102          * 0xFFFFFFFF is used as value when no mapping table is available,
 103          * so don't try to match with it
 104          */
 105         if (id == 0xFFFFFFFF) return NULL;
 106 
 107         /* TODO: add binary search */
 108         for (cur = schema->classes; cur; cur = cur->next) {
 109                 if (cur->governsID_id != id) continue;
 110 
 111                 return cur;
 112         }
 113 
 114         return NULL;
 115 }
 116 
 117 const struct dsdb_class *dsdb_class_by_governsID_oid(const struct dsdb_schema *schema,
     /* [<][>][^][v][top][bottom][index][help] */
 118                                                      const char *oid)
 119 {
 120         struct dsdb_class *cur;
 121 
 122         if (!oid) return NULL;
 123 
 124         /* TODO: add binary search */
 125         for (cur = schema->classes; cur; cur = cur->next) {
 126                 if (strcmp(cur->governsID_oid, oid) != 0) continue;
 127 
 128                 return cur;
 129         }
 130 
 131         return NULL;
 132 }
 133 
 134 const struct dsdb_class *dsdb_class_by_lDAPDisplayName(const struct dsdb_schema *schema,
     /* [<][>][^][v][top][bottom][index][help] */
 135                                                        const char *name)
 136 {
 137         struct dsdb_class *cur;
 138 
 139         if (!name) return NULL;
 140 
 141         /* TODO: add binary search */
 142         for (cur = schema->classes; cur; cur = cur->next) {
 143                 if (strcasecmp(cur->lDAPDisplayName, name) != 0) continue;
 144 
 145                 return cur;
 146         }
 147 
 148         return NULL;
 149 }
 150 
 151 const struct dsdb_class *dsdb_class_by_cn(const struct dsdb_schema *schema,
     /* [<][>][^][v][top][bottom][index][help] */
 152                                           const char *cn)
 153 {
 154         struct dsdb_class *cur;
 155 
 156         if (!cn) return NULL;
 157 
 158         /* TODO: add binary search */
 159         for (cur = schema->classes; cur; cur = cur->next) {
 160                 if (strcasecmp(cur->cn, cn) != 0) continue;
 161 
 162                 return cur;
 163         }
 164 
 165         return NULL;
 166 }
 167 
 168 const char *dsdb_lDAPDisplayName_by_id(const struct dsdb_schema *schema,
     /* [<][>][^][v][top][bottom][index][help] */
 169                                        uint32_t id)
 170 {
 171         const struct dsdb_attribute *a;
 172         const struct dsdb_class *c;
 173 
 174         /* TODO: add binary search */
 175         a = dsdb_attribute_by_attributeID_id(schema, id);
 176         if (a) {
 177                 return a->lDAPDisplayName;
 178         }
 179 
 180         c = dsdb_class_by_governsID_id(schema, id);
 181         if (c) {
 182                 return c->lDAPDisplayName;
 183         }
 184 
 185         return NULL;
 186 }
 187 
 188 /** 
 189     Return a list of linked attributes, in lDAPDisplayName format.
 190 
 191     This may be used to determine if a modification would require
 192     backlinks to be updated, for example
 193 */
 194 
 195 WERROR dsdb_linked_attribute_lDAPDisplayName_list(const struct dsdb_schema *schema, TALLOC_CTX *mem_ctx, const char ***attr_list_ret)
     /* [<][>][^][v][top][bottom][index][help] */
 196 {
 197         const char **attr_list = NULL;
 198         struct dsdb_attribute *cur;
 199         int i = 0;
 200         for (cur = schema->attributes; cur; cur = cur->next) {
 201                 if (cur->linkID == 0) continue;
 202                 
 203                 attr_list = talloc_realloc(mem_ctx, attr_list, const char *, i+2);
 204                 if (!attr_list) {
 205                         return WERR_NOMEM;
 206                 }
 207                 attr_list[i] = cur->lDAPDisplayName;
 208                 i++;
 209         }
 210         attr_list[i] = NULL;
 211         *attr_list_ret = attr_list;
 212         return WERR_OK;
 213 }
 214 
 215 const char **merge_attr_list(TALLOC_CTX *mem_ctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 216                        const char **attrs, const char * const*new_attrs) 
 217 {
 218         const char **ret_attrs;
 219         int i;
 220         size_t new_len, orig_len = str_list_length(attrs);
 221         if (!new_attrs) {
 222                 return attrs;
 223         }
 224 
 225         ret_attrs = talloc_realloc(mem_ctx, 
 226                                    attrs, const char *, orig_len + str_list_length(new_attrs) + 1);
 227         if (ret_attrs) {
 228                 for (i=0; i < str_list_length(new_attrs); i++) {
 229                         ret_attrs[orig_len + i] = new_attrs[i];
 230                 }
 231                 new_len = orig_len + str_list_length(new_attrs);
 232 
 233                 ret_attrs[new_len] = NULL;
 234         }
 235 
 236         return ret_attrs;
 237 }
 238 
 239 /*
 240   Return a merged list of the attributes of exactly one class (not
 241   considering subclasses, auxillary classes etc)
 242 */
 243 
 244 const char **dsdb_attribute_list(TALLOC_CTX *mem_ctx, const struct dsdb_class *sclass, enum dsdb_attr_list_query query)
     /* [<][>][^][v][top][bottom][index][help] */
 245 {
 246         const char **attr_list = NULL;
 247         switch (query) {
 248         case DSDB_SCHEMA_ALL_MAY:
 249                 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->mayContain);
 250                 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->systemMayContain);
 251                 break;
 252                 
 253         case DSDB_SCHEMA_ALL_MUST:
 254                 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->mustContain);
 255                 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->systemMustContain);
 256                 break;
 257                 
 258         case DSDB_SCHEMA_SYS_MAY:
 259                 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->systemMayContain);
 260                 break;
 261                 
 262         case DSDB_SCHEMA_SYS_MUST:
 263                 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->systemMustContain);
 264                 break;
 265                 
 266         case DSDB_SCHEMA_MAY:
 267                 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->mayContain);
 268                 break;
 269                 
 270         case DSDB_SCHEMA_MUST:
 271                 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->mustContain);
 272                 break;
 273                 
 274         case DSDB_SCHEMA_ALL:
 275                 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->mayContain);
 276                 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->systemMayContain);
 277                 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->mustContain);
 278                 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->systemMustContain);
 279                 break;
 280         }
 281         return attr_list;
 282 }
 283 
 284 static const char **dsdb_full_attribute_list_internal(TALLOC_CTX *mem_ctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 285                                                 const struct dsdb_schema *schema, 
 286                                                 const char **class_list,
 287                                                 enum dsdb_attr_list_query query)
 288 {
 289         int i;
 290         const struct dsdb_class *sclass;
 291         
 292         const char **attr_list = NULL;
 293         const char **this_class_list;
 294         const char **recursive_list;
 295 
 296         for (i=0; class_list && class_list[i]; i++) {
 297                 sclass = dsdb_class_by_lDAPDisplayName(schema, class_list[i]);
 298                 
 299                 this_class_list = dsdb_attribute_list(mem_ctx, sclass, query);
 300                 attr_list = merge_attr_list(mem_ctx, attr_list, this_class_list);
 301 
 302                 recursive_list = dsdb_full_attribute_list_internal(mem_ctx, schema, 
 303                                                                    sclass->systemAuxiliaryClass,
 304                                                                    query);
 305                 
 306                 attr_list = merge_attr_list(mem_ctx, attr_list, recursive_list);
 307                 
 308                 recursive_list = dsdb_full_attribute_list_internal(mem_ctx, schema, 
 309                                                                    sclass->auxiliaryClass,
 310                                                                    query);
 311                 
 312                 attr_list = merge_attr_list(mem_ctx, attr_list, recursive_list);
 313                 
 314         }
 315         return attr_list;
 316 }
 317 
 318 const char **dsdb_full_attribute_list(TALLOC_CTX *mem_ctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 319                                 const struct dsdb_schema *schema, 
 320                                 const char **class_list,
 321                                 enum dsdb_attr_list_query query)
 322 {
 323         const char **attr_list = dsdb_full_attribute_list_internal(mem_ctx, schema, class_list, query);
 324         size_t new_len = str_list_length(attr_list);
 325 
 326         /* Remove duplicates */
 327         if (new_len > 1) {
 328                 int i;
 329                 qsort(attr_list, new_len,
 330                       sizeof(*attr_list),
 331                       (comparison_fn_t)strcasecmp);
 332                 
 333                 for (i=1 ; i < new_len; i++) {
 334                         const char **val1 = &attr_list[i-1];
 335                         const char **val2 = &attr_list[i];
 336                         if (ldb_attr_cmp(*val1, *val2) == 0) {
 337                                 memmove(val1, val2, (new_len - i) * sizeof( *attr_list)); 
 338                                 new_len--;
 339                                 i--;
 340                         }
 341                 }
 342         }
 343         return attr_list;
 344 }

/* [<][>][^][v][top][bottom][index][help] */