1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-26 10:04:02 +03:00

r7599: it turns out we were not using the ldif code in libcli/ldap/ at all,

so best to just remove it. If we need it again, then it will be easy
to just use a wrapper around the ldb code.
(This used to be commit b316e1c2d3e4dc09c321ec72b40d78ffb855e101)
This commit is contained in:
Andrew Tridgell 2005-06-15 01:22:30 +00:00 committed by Gerald (Jerry) Carter
parent 49bc2672f8
commit ec4a99ffe8

View File

@ -27,136 +27,6 @@
#include "system/iconv.h"
#include "libcli/ldap/ldap.h"
/****************************************************************************
*
* LDIF parser
*
* Shamelessly stolen and adapted from ldb.
*
***************************************************************************/
/*
pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF
this routine removes any RFC2849 continuations and comments
caller frees
*/
static char *next_chunk(TALLOC_CTX *mem_ctx,
int (*fgetc_fn)(void *), void *private_data)
{
size_t alloc_size=0, chunk_size = 0;
char *chunk = NULL;
int c;
int in_comment = 0;
while ((c = fgetc_fn(private_data)) != EOF) {
if (chunk_size+1 >= alloc_size) {
char *c2;
alloc_size += 1024;
c2 = talloc_realloc(mem_ctx, chunk, char, alloc_size);
if (!c2) {
errno = ENOMEM;
return NULL;
}
chunk = c2;
}
if (in_comment) {
if (c == '\n') {
in_comment = 0;
}
continue;
}
/* handle continuation lines - see RFC2849 */
if (c == ' ' && chunk_size > 1 &&
chunk[chunk_size-1] == '\n') {
chunk_size--;
continue;
}
/* chunks are terminated by a double line-feed */
if (c == '\n' && chunk_size > 0 &&
chunk[chunk_size-1] == '\n') {
chunk[chunk_size-1] = 0;
return chunk;
}
if (c == '#' &&
(chunk_size == 0 || chunk[chunk_size-1] == '\n')) {
in_comment = 1;
continue;
}
/* ignore leading blank lines */
if (chunk_size == 0 && c == '\n') {
continue;
}
chunk[chunk_size++] = c;
}
if (chunk) {
chunk[chunk_size] = 0;
}
return chunk;
}
/* simple ldif attribute parser */
static int next_attr(char **s, const char **attr, struct ldb_val *value)
{
char *p;
int base64_encoded = 0;
if (strncmp(*s, "-\n", 2) == 0) {
value->length = 0;
*attr = "-";
*s += 2;
return 0;
}
p = strchr(*s, ':');
if (!p) {
return -1;
}
*p++ = 0;
if (*p == ':') {
base64_encoded = 1;
p++;
}
*attr = *s;
while (isspace(*p)) {
p++;
}
value->data = p;
p = strchr(p, '\n');
if (!p) {
value->length = strlen((char *)value->data);
*s = ((char *)value->data) + value->length;
} else {
value->length = p - (char *)value->data;
*s = p+1;
*p = 0;
}
if (base64_encoded) {
DATA_BLOB blob = base64_decode_data_blob(value->data);
memcpy(value->data, blob.data, blob.length);
value->length = blob.length;
((char *)value->data)[value->length] = '\0';
}
return 0;
}
BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value,
struct ldb_message_element *attrib)
{
@ -191,47 +61,6 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx,
return True;
}
static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk)
{
struct ldap_AddRequest *r = &msg->r.AddRequest;
const char *attr_name;
struct ldb_val value;
r->num_attributes = 0;
r->attributes = NULL;
while (next_attr(chunk, &attr_name, &value) == 0) {
int i;
struct ldb_message_element *attrib = NULL;
for (i=0; i<r->num_attributes; i++) {
if (strequal(r->attributes[i].name, attr_name)) {
attrib = &r->attributes[i];
break;
}
}
if (attrib == NULL) {
r->attributes = talloc_realloc(msg,
r->attributes,
struct ldb_message_element,
r->num_attributes+1);
if (r->attributes == NULL)
return False;
attrib = &(r->attributes[r->num_attributes]);
r->num_attributes += 1;
ZERO_STRUCTP(attrib);
attrib->name = talloc_strdup(msg,
attr_name);
}
if (!add_value_to_attrib(msg, &value, attrib))
return False;
}
return True;
}
BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx,
struct ldap_mod *mod,
struct ldap_mod **mods,
@ -247,225 +76,3 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx,
return True;
}
static BOOL fill_mods(struct ldap_message *msg, char **chunk)
{
struct ldap_ModifyRequest *r = &msg->r.ModifyRequest;
const char *attr_name;
struct ldb_val value;
r->num_mods = 0;
r->mods = NULL;
while (next_attr(chunk, &attr_name, &value) == 0) {
struct ldap_mod mod;
mod.type = LDAP_MODIFY_NONE;
mod.attrib.name = talloc_strdup(msg, value.data);
if (strequal(attr_name, "add"))
mod.type = LDAP_MODIFY_ADD;
if (strequal(attr_name, "delete"))
mod.type = LDAP_MODIFY_DELETE;
if (strequal(attr_name, "replace"))
mod.type = LDAP_MODIFY_REPLACE;
if (mod.type == LDAP_MODIFY_NONE) {
DEBUG(2, ("ldif modification type %s unsupported\n",
attr_name));
return False;
}
mod.attrib.num_values = 0;
mod.attrib.values = NULL;
while (next_attr(chunk, &attr_name, &value) == 0) {
if (strequal(attr_name, "-"))
break;
if (!strequal(attr_name, mod.attrib.name)) {
DEBUG(3, ("attrib name %s does not "
"match %s\n", attr_name,
mod.attrib.name));
return False;
}
if (!add_value_to_attrib(msg, &value,
&mod.attrib)) {
DEBUG(3, ("Could not add value\n"));
return False;
}
}
if (!add_mod_to_array_talloc(msg, &mod, &r->mods,
&r->num_mods))
return False;
}
return True;
}
static BOOL fill_modrdn(struct ldap_message *msg, char **chunk)
{
struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest;
const char *attr_name;
struct ldb_val value;
r->newrdn = NULL;
r->deleteolddn = False;
r->newsuperior = NULL;
if (next_attr(chunk, &attr_name, &value) != 0) {
return False;
}
if (!strequal(attr_name, "newrdn")) {
return False;
}
r->newrdn = value.data;
if (next_attr(chunk, &attr_name, &value) != 0) {
return False;
}
if (!strequal(attr_name, "deleteoldrdn")) {
return False;
}
if (value.data && (((char *)value.data)[0] != '0')) {
r->deleteolddn = True;
}
if (next_attr(chunk, &attr_name, &value) != 0) {
/* newsuperior is optional */
return True;
}
if (!strequal(attr_name, "newsuperior")) {
return False;
}
r->newsuperior = value.data;
return True;
}
/*
read from a LDIF source, creating a ldap_message
*/
static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void *),
void *private_data)
{
struct ldap_message *msg;
const char *attr=NULL;
const char *dn;
char *chunk=NULL, *s;
struct ldb_val value;
value.data = NULL;
msg = new_ldap_message(mem_ctx);
if (msg == NULL)
return NULL;
chunk = next_chunk(msg, fgetc_fn, private_data);
if (!chunk) {
goto failed;
}
s = chunk;
if (next_attr(&s, &attr, &value) != 0) {
goto failed;
}
/* first line must be a dn */
if (!strequal(attr, "dn")) {
DEBUG(5, ("Error: First line of ldif must be a dn not '%s'\n",
attr));
goto failed;
}
dn = talloc_strdup(msg, value.data);
if (next_attr(&s, &attr, &value) != 0) {
goto failed;
}
if (!strequal(attr, "changetype")) {
DEBUG(5, ("Error: Second line of ldif must be a changetype "
"not '%s'\n", attr));
goto failed;
}
if (strequal(value.data, "delete")) {
msg->type = LDAP_TAG_DelRequest;
msg->r.DelRequest.dn = dn;
return msg;
}
if (strequal(value.data, "add")) {
msg->type = LDAP_TAG_AddRequest;
msg->r.AddRequest.dn = dn;
if (!fill_add_attributes(msg, &s))
goto failed;
return msg;
}
if (strequal(value.data, "modify")) {
msg->type = LDAP_TAG_ModifyRequest;
msg->r.ModifyRequest.dn = dn;
if (!fill_mods(msg, &s))
goto failed;
return msg;
}
if (strequal(value.data, "modrdn")) {
msg->type = LDAP_TAG_ModifyDNRequest;
msg->r.ModifyDNRequest.dn = dn;
if (!fill_modrdn(msg, &s))
goto failed;
return msg;
}
DEBUG(3, ("changetype %s not supported\n", (char *)value.data));
failed:
talloc_free(msg);
return NULL;
}
/*
a wrapper around ldif_read() for reading from const char*
*/
struct ldif_read_string_state {
const char *s;
};
static int fgetc_string(void *private_data)
{
struct ldif_read_string_state *state = private_data;
if (state->s[0] != 0) {
return *state->s++;
}
return EOF;
}
struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s)
{
struct ldif_read_string_state state;
state.s = s;
return ldif_read(mem_ctx, fgetc_string, &state);
}