1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00
samba-mirror/source4/ldap_server/ldap_parse.c
Stefan Metzmacher 85428819e3 r2825: fix the build
this function names are unsed elsewhere in the code too

metze
(This used to be commit a8f2fe0ff0)
2007-10-10 12:59:37 -05:00

237 lines
5.8 KiB
C

/*
Unix SMB/CIFS implementation.
LDAP server
Copyright (C) Simo Sorce 2004
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "ldap_parse.h"
static char char_from_hex(char a, char b) {
char m, l;
if ('0' <= a && a <= '9') {
m = a - '0';
} else if ('A' <= a && a <= 'F') {
m = 10 + (a - 'A');
} else if ('a' <= a && a <= 'f') {
m = 10 + (a - 'a');
} else {
return a;
}
if ('0' <= b && b <= '9') {
l = b - '0';
} else if ('A' <= b && b <= 'F') {
l = 10 + (b - 'A');
} else if ('a' <= b && b <= 'f') {
l = 10 + (b - 'a');
} else {
return a;
}
return ((m << 4) + l);
}
static char *parse_slash(char *p, char *end) {
switch (*(p + 1)) {
case ',':
case '=':
case '\n':
case '+':
case '<':
case '>':
case '#':
case ';':
case '\\':
case '"':
memmove(p, p + 1, end - (p + 1));
return (end - 1);
default:
*p = char_from_hex(*(p + 1), *(p + 2));
memmove(p + 1, p + 3, end - (p + 3));
return (end - 2);
}
}
struct ldap_dn *ldap_parse_dn(TALLOC_CTX *mem_ctx, const char *orig_dn)
{
struct ldap_dn *dn;
struct dn_component *component;
struct dn_attribute *attribute;
char *p, *start, *separator, *src, *dest, *dn_copy, *dn_end;
int i, size;
dn = talloc_p(mem_ctx, struct ldap_dn);
dn->comp_num = 0;
dn->components = talloc_array_p(dn, struct dn_component *, 1);
component = talloc_p(dn, struct dn_component);
component->attr_num = 0;
dn_copy = p = talloc_strdup(mem_ctx, orig_dn);
dn_end = dn_copy + strlen(orig_dn) + 1;
do {
component->attributes = talloc_array_p(component, struct dn_attribute *, 1);
attribute = talloc_p(component, struct dn_attribute);
/* skip "spaces" */
while (*p == ' ' || *p == '\n') {
p++;
}
/* start parsing this component */
do {
start = p;
/* find out key separator '=' */
while (*p && *p != '=') {
if (*p == '\\') {
dn_end = parse_slash(p, dn_end);
}
p++;
}
separator = p;
/* remove spaces */
while (*(p - 1) == ' ' || *(p - 1) == '\n') {
p--;
}
/* save key name */
attribute->name = talloc_strndup(attribute, start, p - start);
DEBUG(10, ("attribute name: [%s]\n", attribute->name));
p = separator + 1;
/* skip spaces past the separator */
p = separator + strspn(p, " \n") + 1;
start = p;
/* check if the value is enclosed in QUOTATION */
if (*p == '"') {
start = p + 1;
while (*p && *p != '"') {
if (*p == '\\') {
dn_end = parse_slash(p, dn_end);
}
p++;
}
/* skip spaces until the separator */
separator = p + strspn(p, " \n");
if (*separator != ',' && *separator != ';' && *separator != '+') { /* there must be a separator here */
/* Error Malformed DN */
DEBUG (0, ("Error: Malformed DN!\n"));
break;
}
} else {
while (*p && !(*p == ',' || *p == ';' || *p == '+')) {
if (*p == '\\') {
dn_end = parse_slash(p, dn_end);
}
p++;
} /* found separator */
separator = p;
/* remove spaces */
while (*(p - 1) == ' ' || *(p - 1) == '\n') {
p--;
}
}
/* save the value */
attribute->value = talloc_strndup(attribute, start, p - start);
DEBUG(10, ("attribute value: [%s]\n", attribute->value));
attribute->attribute = talloc_asprintf(attribute,"%s=%s", attribute->name, attribute->value);
DEBUG(10, ("attribute: [%s]\n", attribute->attribute));
/* save the attribute */
component->attributes[component->attr_num] = attribute;
component->attr_num++;
if (*separator == '+') { /* expect other attributes in this component */
component->attributes = talloc_realloc_p(component, component->attributes, struct dn_attribute *, component->attr_num + 1);
/* allocate new attribute structure */
attribute = talloc_p(component, struct dn_attribute);
/* skip spaces past the separator */
p = separator + strspn(p, " \n");
}
} while (*separator == '+');
/* found component bounds */
for (i = 0, size = 0; i < component->attr_num; i++) {
size = size + strlen(component->attributes[i]->attribute) + 1;
}
/* rebuild the normlaized component and put it here */
component->component = dest = talloc(component, size);
for (i = 0; i < component->attr_num; i++) {
if (i != 0) {
*dest = '+';
dest++;
}
src = component->attributes[i]->attribute;
do {
*(dest++) = *(src++);
} while(*src);
*dest = '\0';
}
DEBUG(10, ("component: [%s]\n", component->component));
dn->components[dn->comp_num] = component;
dn->comp_num++;
if (*separator == ',' || *separator == ';') {
dn->components = talloc_realloc_p(dn, dn->components, struct dn_component *, dn->comp_num + 1);
component = talloc_p(dn, struct dn_component);
component->attr_num = 0;
}
p = separator + 1;
} while(*separator == ',' || *separator == ';');
for (i = 0, size = 0; i < dn->comp_num; i++) {
size = size + strlen(dn->components[i]->component) + 1;
}
/* rebuild the normlaized dn and put it here */
dn->dn = dest = talloc(dn, size);
for (i = 0; i < dn->comp_num; i++) {
if (i != 0) {
*dest = ',';
dest++;
}
src = dn->components[i]->component;
do {
*(dest++) = *(src++);
} while(*src);
*dest = '\0';
}
DEBUG(10, ("dn: [%s]\n", dn->dn));
talloc_free(dn_copy);
return dn;
}