Line data Source code
1 : /* 2 : ldb database library 3 : 4 : Copyright (C) Andrew Tridgell 2004 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 : /* 25 : * Name: ldb 26 : * 27 : * Component: ldb utf8 handling 28 : * 29 : * Description: case folding and case comparison for UTF8 strings 30 : * 31 : * Author: Andrew Tridgell 32 : */ 33 : 34 : #include "ldb_private.h" 35 : #include "system/locale.h" 36 : 37 : 38 : /* 39 : this allow the user to pass in a caseless comparison 40 : function to handle utf8 caseless comparisons 41 : */ 42 1507584 : void ldb_set_utf8_fns(struct ldb_context *ldb, 43 : void *context, 44 : char *(*casefold)(void *, void *, const char *, size_t)) 45 : { 46 1507584 : if (context) 47 0 : ldb->utf8_fns.context = context; 48 1507584 : if (casefold) 49 1507584 : ldb->utf8_fns.casefold = casefold; 50 1507584 : } 51 : 52 : /* 53 : a simple case folding function 54 : NOTE: does not handle UTF8 55 : */ 56 931736 : char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n) 57 : { 58 127698 : size_t i; 59 931736 : char *ret = talloc_strndup(mem_ctx, s, n); 60 931736 : if (!s) { 61 0 : errno = ENOMEM; 62 0 : return NULL; 63 : } 64 6286631 : for (i=0;ret[i];i++) { 65 5354895 : ret[i] = ldb_ascii_toupper((unsigned char)ret[i]); 66 : } 67 804038 : return ret; 68 : } 69 : 70 756824 : void ldb_set_utf8_default(struct ldb_context *ldb) 71 : { 72 756824 : ldb_set_utf8_fns(ldb, NULL, ldb_casefold_default); 73 756824 : } 74 : 75 762151893 : char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n) 76 : { 77 762151893 : return ldb->utf8_fns.casefold(ldb->utf8_fns.context, mem_ctx, s, n); 78 : } 79 : 80 : /* 81 : check the attribute name is valid according to rfc2251 82 : returns 1 if the name is ok 83 : */ 84 : 85 218036 : int ldb_valid_attr_name(const char *s) 86 : { 87 38896 : size_t i; 88 : 89 218036 : if (!s || !s[0]) 90 0 : return 0; 91 : 92 : /* handle special ldb_tdb wildcard */ 93 218036 : if (strcmp(s, "*") == 0) return 1; 94 : 95 3974011 : for (i = 0; s[i]; i++) { 96 3755977 : if (! isascii(s[i])) { 97 0 : return 0; 98 : } 99 3755977 : if (i == 0) { /* first char must be an alpha (or our special '@' identifier) */ 100 218036 : if (! (isalpha(s[i]) || (s[i] == '@'))) { 101 2 : return 0; 102 : } 103 : } else { 104 3537941 : if (! (isalnum(s[i]) || (s[i] == '-'))) { 105 0 : return 0; 106 : } 107 : } 108 : } 109 179138 : return 1; 110 : } 111 : 112 785371963 : char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s) 113 : { 114 14557609 : size_t i; 115 785371963 : char *ret = talloc_strdup(mem_ctx, s); 116 785371963 : if (!ret) { 117 0 : errno = ENOMEM; 118 0 : return NULL; 119 : } 120 2689150356 : for (i = 0; ret[i]; i++) { 121 1903778393 : ret[i] = ldb_ascii_toupper((unsigned char)ret[i]); 122 : } 123 770814354 : return ret; 124 : } 125 : 126 : /* 127 : we accept either 'dn' or 'distinguishedName' for a distinguishedName 128 : */ 129 480594418 : int ldb_attr_dn(const char *attr) 130 : { 131 480594418 : if (ldb_attr_cmp(attr, "dn") == 0 || 132 480593553 : ldb_attr_cmp(attr, "distinguishedName") == 0) { 133 6421990 : return 0; 134 : } 135 463298309 : return -1; 136 : } 137 : 138 2176954578 : _PRIVATE_ char ldb_ascii_toupper(char c) { 139 2176954578 : return ('a' <= c && c <= 'z') ? c ^ 0x20 : toupper(c); 140 : }