mirror of
https://github.com/samba-team/samba.git
synced 2025-01-27 14:04:05 +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:
parent
49bc2672f8
commit
ec4a99ffe8
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user