4 Copyright (C) Andrew Tridgell 2004
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
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 2 of the License, or (at your option) any later version.
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.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * Component: ldb utf8 handling
30 * Description: case folding and case comparison for UTF8 strings
32 * Author: Andrew Tridgell
36 #include "ldb/include/ldb.h"
37 #include "ldb/include/ldb_private.h"
42 a simple case folding function - will be replaced by a UTF8 aware function later
44 char *ldb_casefold(struct ldb_context *ldb, const char *s)
47 char *ret = talloc_strdup(ldb, s);
52 for (i=0;ret[i];i++) {
53 ret[i] = toupper(ret[i]);
59 a caseless compare, optimised for 7 bit
60 TODO: doesn't yet handle UTF8
62 static int ldb_caseless_cmp(const char *s1, const char *s2)
65 for (i=0;s1[i] != 0;i++) {
66 int c1 = toupper(s1[i]), c2 = toupper(s2[i]);
75 compare two basedn fields
78 int ldb_dn_cmp(const char *dn1, const char *dn2)
80 return ldb_caseless_cmp(dn1, dn2);
84 compare two attributes
87 int ldb_attr_cmp(const char *dn1, const char *dn2)
89 return ldb_caseless_cmp(dn1, dn2);
94 casefold a dn. We need to uppercase the attribute names, and the
95 attribute values of case insensitive attributes. We also need to remove
96 extraneous spaces between elements
98 char *ldb_dn_fold(struct ldb_module *module, const char *dn, int (*case_fold_attr_fn)(struct ldb_module * module, char * attr))
100 const char *dn_orig = dn;
101 struct ldb_context *ldb = module->ldb;
102 TALLOC_CTX *tmp_ctx = talloc_new(ldb);
106 ret = talloc_strdup(tmp_ctx, "");
107 if (ret == NULL) goto failed;
109 while ((len = strcspn(dn, ",")) > 0) {
110 char *p = strchr(dn, '=');
112 int case_fold_required;
114 if (p == NULL || (p-dn) > len) goto failed;
116 attr = talloc_strndup(tmp_ctx, dn, p-dn);
117 if (attr == NULL) goto failed;
119 /* trim spaces from the attribute name */
120 while (' ' == *attr) attr++;
121 while (' ' == attr[strlen(attr)-1]) {
122 attr[strlen(attr)-1] = 0;
124 if (*attr == 0) goto failed;
126 value = talloc_strndup(tmp_ctx, p+1, len-(p+1-dn));
127 if (value == NULL) goto failed;
129 /* trim spaces from the value */
130 while (' ' == *value) value++;
131 while (' ' == value[strlen(value)-1]) {
132 value[strlen(value)-1] = 0;
134 if (*value == 0) goto failed;
136 case_fold_required = (* case_fold_attr_fn)(module, attr);
138 attr = ldb_casefold(ldb, attr);
139 if (attr == NULL) goto failed;
140 talloc_steal(tmp_ctx, attr);
142 if (case_fold_required) {
143 value = ldb_casefold(ldb, value);
144 if (value == NULL) goto failed;
145 talloc_steal(tmp_ctx, value);
148 if (dn[len] == ',') {
149 ret = talloc_asprintf_append(ret, "%s=%s,", attr, value);
151 ret = talloc_asprintf_append(ret, "%s=%s", attr, value);
153 if (ret == NULL) goto failed;
156 if (*dn == ',') dn++;
159 talloc_steal(ldb, ret);
160 talloc_free(tmp_ctx);
164 talloc_free(tmp_ctx);
165 return ldb_casefold(ldb, dn_orig);