~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/lib/ldb/common/ldb_attributes.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   ldb database library
 
3
 
 
4
   Copyright (C) Andrew Tridgell  2005
 
5
 
 
6
     ** NOTE! The following LGPL license applies to the ldb
 
7
     ** library. This does NOT imply that all of Samba is released
 
8
     ** under the LGPL
 
9
   
 
10
   This library is free software; you can redistribute it and/or
 
11
   modify it under the terms of the GNU Lesser General Public
 
12
   License as published by the Free Software Foundation; either
 
13
   version 3 of the License, or (at your option) any later version.
 
14
 
 
15
   This library is distributed in the hope that it will be useful,
 
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
18
   Lesser General Public License for more details.
 
19
 
 
20
   You should have received a copy of the GNU Lesser General Public
 
21
   License along with this library; if not, see <http://www.gnu.org/licenses/>.
 
22
*/
 
23
/*
 
24
  register handlers for specific attributes and objectclass relationships
 
25
 
 
26
  this allows a backend to store its schema information in any format
 
27
  it likes (or to not have any schema information at all) while keeping the 
 
28
  message matching logic generic
 
29
*/
 
30
 
 
31
#include "ldb_private.h"
 
32
#include "ldb_handlers.h"
 
33
 
 
34
/*
 
35
  add a attribute to the ldb_schema
 
36
 
 
37
  if flags contains LDB_ATTR_FLAG_ALLOCATED
 
38
  the attribute name string will be copied using
 
39
  talloc_strdup(), otherwise it needs to be a static const
 
40
  string at least with a lifetime longer than the ldb struct!
 
41
  
 
42
  the ldb_schema_syntax structure should be a pointer
 
43
  to a static const struct or at least it needs to be
 
44
  a struct with a longer lifetime than the ldb context!
 
45
 
 
46
*/
 
47
int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb, 
 
48
                                         const char *attribute,
 
49
                                         unsigned flags,
 
50
                                         const struct ldb_schema_syntax *syntax)
 
51
{
 
52
        int i, n;
 
53
        struct ldb_schema_attribute *a;
 
54
 
 
55
        if (!syntax) {
 
56
                return LDB_ERR_OPERATIONS_ERROR;
 
57
        }
 
58
 
 
59
        n = ldb->schema.num_attributes + 1;
 
60
 
 
61
        a = talloc_realloc(ldb, ldb->schema.attributes,
 
62
                           struct ldb_schema_attribute, n);
 
63
        if (a == NULL) {
 
64
                ldb_oom(ldb);
 
65
                return -1;
 
66
        }
 
67
        ldb->schema.attributes = a;
 
68
 
 
69
        for (i = 0; i < ldb->schema.num_attributes; i++) {
 
70
                int cmp = ldb_attr_cmp(attribute, a[i].name);
 
71
                if (cmp == 0) {
 
72
                        /* silently ignore attempts to overwrite fixed attributes */
 
73
                        if (a[i].flags & LDB_ATTR_FLAG_FIXED) {
 
74
                                return 0;
 
75
                        }
 
76
                        if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) {
 
77
                                talloc_free(discard_const_p(char, a[i].name));
 
78
                        }
 
79
                        /* To cancel out increment below */
 
80
                        ldb->schema.num_attributes--;
 
81
                        break;
 
82
                } else if (cmp < 0) {
 
83
                        memmove(a+i+1, a+i, sizeof(*a) * (ldb->schema.num_attributes-i));
 
84
                        break;
 
85
                }
 
86
        }
 
87
        ldb->schema.num_attributes++;
 
88
 
 
89
        a[i].name       = attribute;
 
90
        a[i].flags      = flags;
 
91
        a[i].syntax     = syntax;
 
92
 
 
93
        if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) {
 
94
                a[i].name = talloc_strdup(a, a[i].name);
 
95
                if (a[i].name == NULL) {
 
96
                        ldb_oom(ldb);
 
97
                        return -1;
 
98
                }
 
99
        }
 
100
 
 
101
        return 0;
 
102
}
 
103
 
 
104
static const struct ldb_schema_syntax ldb_syntax_default = {
 
105
        .name            = LDB_SYNTAX_OCTET_STRING,
 
106
        .ldif_read_fn    = ldb_handler_copy,
 
107
        .ldif_write_fn   = ldb_handler_copy,
 
108
        .canonicalise_fn = ldb_handler_copy,
 
109
        .comparison_fn   = ldb_comparison_binary
 
110
};
 
111
 
 
112
static const struct ldb_schema_attribute ldb_attribute_default = {
 
113
        .name   = NULL,
 
114
        .flags  = 0,
 
115
        .syntax = &ldb_syntax_default
 
116
};
 
117
 
 
118
/*
 
119
  return the attribute handlers for a given attribute
 
120
*/
 
121
const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb,
 
122
                                                                const char *name)
 
123
{
 
124
        int i, e, b = 0, r;
 
125
        const struct ldb_schema_attribute *def = &ldb_attribute_default;
 
126
 
 
127
        /* as handlers are sorted, '*' must be the first if present */
 
128
        if (strcmp(ldb->schema.attributes[0].name, "*") == 0) {
 
129
                def = &ldb->schema.attributes[0];
 
130
                b = 1;
 
131
        }
 
132
 
 
133
        /* do a binary search on the array */
 
134
        e = ldb->schema.num_attributes - 1;
 
135
 
 
136
        while (b <= e) {
 
137
 
 
138
                i = (b + e) / 2;
 
139
 
 
140
                r = ldb_attr_cmp(name, ldb->schema.attributes[i].name);
 
141
                if (r == 0) {
 
142
                        return &ldb->schema.attributes[i];
 
143
                }
 
144
                if (r < 0) {
 
145
                        e = i - 1;
 
146
                } else {
 
147
                        b = i + 1;
 
148
                }
 
149
 
 
150
        }
 
151
 
 
152
        return def;
 
153
}
 
154
 
 
155
 
 
156
/*
 
157
  add to the list of ldif handlers for this ldb context
 
158
*/
 
159
void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name)
 
160
{
 
161
        const struct ldb_schema_attribute *a;
 
162
        int i;
 
163
 
 
164
        a = ldb_schema_attribute_by_name(ldb, name);
 
165
        if (a == NULL || a->name == NULL) {
 
166
                return;
 
167
        }
 
168
 
 
169
        /* FIXED attributes are never removed */
 
170
        if (a->flags & LDB_ATTR_FLAG_FIXED) {
 
171
                return;
 
172
        }
 
173
 
 
174
        if (a->flags & LDB_ATTR_FLAG_ALLOCATED) {
 
175
                talloc_free(discard_const_p(char, a->name));
 
176
        }
 
177
 
 
178
        i = a - ldb->schema.attributes;
 
179
        if (i < ldb->schema.num_attributes - 1) {
 
180
                memmove(&ldb->schema.attributes[i], 
 
181
                        a+1, sizeof(*a) * (ldb->schema.num_attributes-(i+1)));
 
182
        }
 
183
 
 
184
        ldb->schema.num_attributes--;
 
185
}
 
186
 
 
187
/*
 
188
  setup a attribute handler using a standard syntax
 
189
*/
 
190
int ldb_schema_attribute_add(struct ldb_context *ldb,
 
191
                             const char *attribute,
 
192
                             unsigned flags,
 
193
                             const char *syntax)
 
194
{
 
195
        const struct ldb_schema_syntax *s = ldb_standard_syntax_by_name(ldb, syntax);
 
196
        return ldb_schema_attribute_add_with_syntax(ldb, attribute, flags, s);
 
197
}
 
198
 
 
199
/*
 
200
  setup the attribute handles for well known attributes
 
201
*/
 
202
int ldb_setup_wellknown_attributes(struct ldb_context *ldb)
 
203
{
 
204
        const struct {
 
205
                const char *attr;
 
206
                const char *syntax;
 
207
        } wellknown[] = {
 
208
                { "dn", LDB_SYNTAX_DN },
 
209
                { "distinguishedName", LDB_SYNTAX_DN },
 
210
                { "cn", LDB_SYNTAX_DIRECTORY_STRING },
 
211
                { "dc", LDB_SYNTAX_DIRECTORY_STRING },
 
212
                { "ou", LDB_SYNTAX_DIRECTORY_STRING },
 
213
                { "objectClass", LDB_SYNTAX_OBJECTCLASS }
 
214
        };
 
215
        int i;
 
216
        int ret;
 
217
 
 
218
        for (i=0;i<ARRAY_SIZE(wellknown);i++) {
 
219
                ret = ldb_schema_attribute_add(ldb, wellknown[i].attr, 0,
 
220
                                               wellknown[i].syntax);
 
221
                if (ret != LDB_SUCCESS) {
 
222
                        return ret;
 
223
                }
 
224
        }
 
225
 
 
226
        return LDB_SUCCESS;
 
227
}
 
228
 
 
229
 
 
230
/*
 
231
  add a extended dn syntax to the ldb_schema
 
232
*/
 
233
int ldb_dn_extended_add_syntax(struct ldb_context *ldb, 
 
234
                               unsigned flags,
 
235
                               const struct ldb_dn_extended_syntax *syntax)
 
236
{
 
237
        int n;
 
238
        struct ldb_dn_extended_syntax *a;
 
239
 
 
240
        if (!syntax) {
 
241
                return LDB_ERR_OPERATIONS_ERROR;
 
242
        }
 
243
 
 
244
        n = ldb->schema.num_dn_extended_syntax + 1;
 
245
 
 
246
        a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax,
 
247
                           struct ldb_dn_extended_syntax, n);
 
248
 
 
249
        if (!a) {
 
250
                return LDB_ERR_OPERATIONS_ERROR;
 
251
        }
 
252
 
 
253
        a[ldb->schema.num_dn_extended_syntax] = *syntax;
 
254
        ldb->schema.dn_extended_syntax = a;
 
255
 
 
256
        ldb->schema.num_dn_extended_syntax = n;
 
257
 
 
258
        return LDB_SUCCESS;
 
259
}
 
260
 
 
261
/*
 
262
  return the extended dn syntax for a given name
 
263
*/
 
264
const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb,
 
265
                                                                    const char *name)
 
266
{
 
267
        int i;
 
268
        for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) {
 
269
                if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) {
 
270
                        return &ldb->schema.dn_extended_syntax[i];
 
271
                }
 
272
        }
 
273
        return NULL;
 
274
}
 
275