diff options
-rw-r--r-- | source4/cldap_server/netlogon.c | 10 | ||||
-rw-r--r-- | source4/libcli/ldap/ldap.c | 392 | ||||
-rw-r--r-- | source4/libcli/ldap/ldap.h | 38 | ||||
-rw-r--r-- | source4/libcli/ldap/ldap_ldif.c | 12 | ||||
-rw-r--r-- | source4/libcli/ldap/ldap_ndr.c | 22 |
5 files changed, 48 insertions, 426 deletions
diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c index 9e7ddc6989..f4f1c226af 100644 --- a/source4/cldap_server/netlogon.c +++ b/source4/cldap_server/netlogon.c @@ -181,7 +181,7 @@ void cldapd_netlogon_request(struct cldap_socket *cldap, const char *src_address, int src_port) { struct cldapd_server *cldapd = talloc_get_type(cldap->incoming.private, struct cldapd_server); - struct ldap_parse_tree *tree; + struct ldb_parse_tree *tree; int i; const char *domain = NULL; const char *host = NULL; @@ -197,15 +197,15 @@ void cldapd_netlogon_request(struct cldap_socket *cldap, DEBUG(5,("cldap filter='%s'\n", filter)); - tree = ldap_parse_filter_string(tmp_ctx, filter); + tree = ldb_parse_tree(tmp_ctx, filter); if (tree == NULL) goto failed; - if (tree->operation != LDAP_OP_AND) goto failed; + if (tree->operation != LDB_OP_AND) goto failed; /* extract the query elements */ for (i=0;i<tree->u.list.num_elements;i++) { - struct ldap_parse_tree *t = tree->u.list.elements[i]; - if (t->operation != LDAP_OP_SIMPLE) goto failed; + struct ldb_parse_tree *t = tree->u.list.elements[i]; + if (t->operation != LDB_OP_SIMPLE) goto failed; if (strcasecmp(t->u.simple.attr, "DnsDomain") == 0) { domain = talloc_strndup(tmp_ctx, t->u.simple.value.data, diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 0c6a466f27..f383d08074 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -28,350 +28,11 @@ #include "asn_1.h" #include "libcli/ldap/ldap.h" -/**************************************************************************** - * - * LDAP filter parser -- main routine is ldap_parse_filter - * - * Shamelessly stolen and adapted from ldb. - * - ***************************************************************************/ - -/* - return next token element. Caller frees -*/ -static char *ldap_parse_lex(TALLOC_CTX *mem_ctx, const char **s, - const char *sep) -{ - const char *p = *s; - char *ret; - - while (isspace(*p)) { - p++; - } - *s = p; - - if (*p == 0) { - return NULL; - } - - if (strchr(sep, *p)) { - (*s) = p+1; - ret = talloc_strndup(mem_ctx, p, 1); - if (!ret) { - errno = ENOMEM; - } - return ret; - } - - while (*p && (isalnum(*p) || !strchr(sep, *p))) { - p++; - } - - if (p == *s) { - return NULL; - } - - ret = talloc_strndup(mem_ctx, *s, p - *s); - if (!ret) { - errno = ENOMEM; - } - - *s = p; - - return ret; -} - - -/* - find a matching close brace in a string -*/ -static const char *match_brace(const char *s) -{ - unsigned int count = 0; - while (*s && (count != 0 || *s != ')')) { - if (*s == '(') { - count++; - } - if (*s == ')') { - count--; - } - s++; - } - if (! *s) { - return NULL; - } - return s; -} - -static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, - const char **s); - -/* - decode a RFC2254 binary string representation of a buffer. - Used in LDAP filters. -*/ -struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) -{ - int i, j; - struct ldap_val ret; - int slen = strlen(str); - - ret.data = talloc_size(mem_ctx, slen); - ret.length = 0; - if (ret.data == NULL) return ret; - - for (i=j=0;i<slen;i++) { - if (str[i] == '\\') { - unsigned c; - if (sscanf(&str[i+1], "%02X", &c) != 1) { - talloc_free(ret.data); - ZERO_STRUCT(ret); - return ret; - } - ((uint8_t *)ret.data)[j++] = c; - i += 2; - } else { - ((uint8_t *)ret.data)[j++] = str[i]; - } - } - ret.length = j; - - return ret; -} - - -/* - encode a blob as a RFC2254 binary string, escaping any - non-printable or '\' characters -*/ -const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob) -{ - int i; - char *ret; - int len = blob.length; - for (i=0;i<blob.length;i++) { - if (!isprint(blob.data[i]) || strchr(" *()\\&|!", blob.data[i])) { - len += 2; - } - } - ret = talloc_array(mem_ctx, char, len+1); - if (ret == NULL) return NULL; - - len = 0; - for (i=0;i<blob.length;i++) { - if (!isprint(blob.data[i]) || strchr(" *()\\&|!", blob.data[i])) { - snprintf(ret+len, 4, "\\%02X", blob.data[i]); - len += 3; - } else { - ret[len++] = blob.data[i]; - } - } - ret[len] = 0; - - return ret; -} - - -/* - <simple> ::= <attributetype> <filtertype> <attributevalue> -*/ -static struct ldap_parse_tree *ldap_parse_simple(TALLOC_CTX *mem_ctx, - const char *s) -{ - char *eq, *val, *l; - struct ldap_parse_tree *ret; - - l = ldap_parse_lex(mem_ctx, &s, LDAP_ALL_SEP); - if (!l) { - return NULL; - } - - if (strchr("()&|=", *l)) - return NULL; - - eq = ldap_parse_lex(mem_ctx, &s, LDAP_ALL_SEP); - if (!eq || strcmp(eq, "=") != 0) - return NULL; - - val = ldap_parse_lex(mem_ctx, &s, ")"); - if (val && strchr("()&|", *val)) - return NULL; - - ret = talloc(mem_ctx, struct ldap_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = LDAP_OP_SIMPLE; - ret->u.simple.attr = l; - ret->u.simple.value = ldap_binary_decode(ret, val); - - return ret; -} - - -/* - parse a filterlist - <and> ::= '&' <filterlist> - <or> ::= '|' <filterlist> - <filterlist> ::= <filter> | <filter> <filterlist> -*/ -static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, - enum ldap_parse_op op, - const char *s) -{ - struct ldap_parse_tree *ret, *next; - - ret = talloc(mem_ctx, struct ldap_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = op; - ret->u.list.num_elements = 1; - ret->u.list.elements = talloc(mem_ctx, struct ldap_parse_tree *); - if (!ret->u.list.elements) { - errno = ENOMEM; - return NULL; - } - - ret->u.list.elements[0] = ldap_parse_filter(mem_ctx, &s); - if (!ret->u.list.elements[0]) { - return NULL; - } - - while (isspace(*s)) s++; - - while (*s && (next = ldap_parse_filter(mem_ctx, &s))) { - struct ldap_parse_tree **e; - e = talloc_realloc(ret, - ret->u.list.elements, - struct ldap_parse_tree *, - ret->u.list.num_elements+1); - if (!e) { - errno = ENOMEM; - return NULL; - } - ret->u.list.elements = e; - ret->u.list.elements[ret->u.list.num_elements] = next; - ret->u.list.num_elements++; - while (isspace(*s)) s++; - } - - return ret; -} - - -/* - <not> ::= '!' <filter> -*/ -static struct ldap_parse_tree *ldap_parse_not(TALLOC_CTX *mem_ctx, const char *s) -{ - struct ldap_parse_tree *ret; - - ret = talloc(mem_ctx, struct ldap_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = LDAP_OP_NOT; - ret->u.not.child = ldap_parse_filter(mem_ctx, &s); - if (!ret->u.not.child) - return NULL; - - return ret; -} - -/* - parse a filtercomp - <filtercomp> ::= <and> | <or> | <not> | <simple> -*/ -static struct ldap_parse_tree *ldap_parse_filtercomp(TALLOC_CTX *mem_ctx, - const char *s) -{ - while (isspace(*s)) s++; - - switch (*s) { - case '&': - return ldap_parse_filterlist(mem_ctx, LDAP_OP_AND, s+1); - - case '|': - return ldap_parse_filterlist(mem_ctx, LDAP_OP_OR, s+1); - - case '!': - return ldap_parse_not(mem_ctx, s+1); - - case '(': - case ')': - return NULL; - } - - return ldap_parse_simple(mem_ctx, s); -} - - -/* - <filter> ::= '(' <filtercomp> ')' -*/ -static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, - const char **s) -{ - char *l, *s2; - const char *p, *p2; - struct ldap_parse_tree *ret; - - l = ldap_parse_lex(mem_ctx, s, LDAP_ALL_SEP); - if (!l) { - return NULL; - } - - if (strcmp(l, "(") != 0) { - return NULL; - } - - p = match_brace(*s); - if (!p) { - return NULL; - } - p2 = p + 1; - - s2 = talloc_strndup(mem_ctx, *s, p - *s); - if (!s2) { - errno = ENOMEM; - return NULL; - } - - ret = ldap_parse_filtercomp(mem_ctx, s2); - - *s = p2; - - return ret; -} - -/* - main parser entry point. Takes a search string and returns a parse tree - - expression ::= <simple> | <filter> -*/ -static struct ldap_parse_tree *ldap_parse_tree(TALLOC_CTX *mem_ctx, const char *s) -{ - while (isspace(*s)) s++; - - if (*s == '(') { - return ldap_parse_filter(mem_ctx, &s); - } - - return ldap_parse_simple(mem_ctx, s); -} - -static BOOL ldap_push_filter(struct asn1_data *data, struct ldap_parse_tree *tree) +static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) { switch (tree->operation) { - case LDAP_OP_SIMPLE: { + case LDB_OP_SIMPLE: { if ((tree->u.simple.value.length == 1) && (((char *)(tree->u.simple.value.data))[0] == '*')) { /* Just a presence test */ @@ -392,7 +53,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldap_parse_tree *tre break; } - case LDAP_OP_AND: { + case LDB_OP_AND: { int i; asn1_push_tag(data, 0xa0); @@ -403,7 +64,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldap_parse_tree *tre break; } - case LDAP_OP_OR: { + case LDB_OP_OR: { int i; asn1_push_tag(data, 0xa1); @@ -481,9 +142,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) struct ldap_BindResponse *r = &msg->r.BindResponse; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); ldap_encode_response(&data, &r->response); - if (r->SASL.secblob.length > 0) { - asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); - } + asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); asn1_pop_tag(&data); break; } @@ -493,6 +152,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_SearchRequest: { struct ldap_SearchRequest *r = &msg->r.SearchRequest; + struct ldb_parse_tree *tree; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->basedn, strlen(r->basedn)); asn1_write_enumerated(&data, r->scope); @@ -501,22 +161,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_Integer(&data, r->timelimit); asn1_write_BOOLEAN(&data, r->attributesonly); - { - TALLOC_CTX *mem_ctx = talloc_init("ldap_parse_tree"); - struct ldap_parse_tree *tree; - - if (mem_ctx == NULL) - return False; + tree = ldb_parse_tree(NULL, r->filter); - tree = ldap_parse_tree(mem_ctx, r->filter); - - if (tree == NULL) - return False; + if (tree == NULL) + return False; - ldap_push_filter(&data, tree); + ldap_push_filter(&data, tree); - talloc_free(mem_ctx); - } + talloc_free(tree); asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; i<r->num_attributes; i++) { @@ -830,6 +482,8 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, /* equalityMatch */ const char *attrib; DATA_BLOB value; + struct ldb_val val; + if (tag_desc != 0xa0) /* context compound */ return False; asn1_start_tag(data, ASN1_CONTEXT(3)); @@ -838,8 +492,10 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) return False; + val.data = value.data; + val.length = value.length; filter = talloc_asprintf(mem_ctx, "(%s=%s)", - attrib, ldap_binary_encode(mem_ctx, value)); + attrib, ldb_binary_encode(mem_ctx, val)); data_blob_free(&value); break; } @@ -881,7 +537,7 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_start_tag(data, ASN1_SET); while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { DATA_BLOB blob; - struct ldap_val value; + struct ldb_val value; asn1_read_OctetString(data, &blob); value.data = blob.data; value.length = blob.length; @@ -1334,17 +990,3 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, return (*host != NULL); } - - -/* - externally callable version of filter string parsing - used in the - cldap server -*/ -struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, - const char *s) -{ - return ldap_parse_filter(mem_ctx, &s); -} - - - diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 54a96d9672..12d30a2610 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -22,6 +22,9 @@ #ifndef _SMB_LDAP_H #define _SMB_LDAP_H +#include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_parse.h" + enum ldap_request_tag { LDAP_TAG_BindRequest = 0, LDAP_TAG_BindResponse = 1, @@ -288,33 +291,6 @@ struct ldap_connection { struct gensec_security *gensec; }; -/* Hmm. A blob might be more appropriate here :-) */ - -struct ldap_val { - unsigned int length; - void *data; -}; - -enum ldap_parse_op {LDAP_OP_SIMPLE, LDAP_OP_AND, LDAP_OP_OR, LDAP_OP_NOT}; - -struct ldap_parse_tree { - enum ldap_parse_op operation; - union { - struct { - char *attr; - struct ldap_val value; - } simple; - struct { - unsigned int num_elements; - struct ldap_parse_tree **elements; - } list; - struct { - struct ldap_parse_tree *child; - } not; - } u; -}; - -#define LDAP_ALL_SEP "()&|=!" #define LDAP_CONNECTION_TIMEOUT 10000 /* The following definitions come from libcli/ldap/ldap.c */ @@ -323,10 +299,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result); BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg); BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, char **host, uint16_t *port, BOOL *ldaps); -struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, - const char *s); -const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob); -struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str); /* The following definitions come from libcli/ldap/ldap_client.c */ @@ -368,7 +340,7 @@ NTSTATUS ldap2nterror(int ldaperror); /* The following definitions come from libcli/ldap/ldap_ldif.c */ -BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, +BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, struct ldap_attribute *attrib); BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, const struct ldap_attribute *attrib, @@ -385,6 +357,6 @@ struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s); const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid); const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldap_val val, struct GUID *guid); +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); #endif diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index c36106e116..2489a97748 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -104,7 +104,7 @@ static char *next_chunk(TALLOC_CTX *mem_ctx, } /* simple ldif attribute parser */ -static int next_attr(char **s, const char **attr, struct ldap_val *value) +static int next_attr(char **s, const char **attr, struct ldb_val *value) { char *p; int base64_encoded = 0; @@ -157,7 +157,7 @@ static int next_attr(char **s, const char **attr, struct ldap_val *value) return 0; } -BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, +BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, struct ldap_attribute *attrib) { attrib->values = talloc_realloc(mem_ctx, @@ -195,7 +195,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) { struct ldap_AddRequest *r = &msg->r.AddRequest; const char *attr_name; - struct ldap_val value; + struct ldb_val value; r->num_attributes = 0; r->attributes = NULL; @@ -251,7 +251,7 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) { struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; const char *attr_name; - struct ldap_val value; + struct ldb_val value; r->num_mods = 0; r->mods = NULL; @@ -309,7 +309,7 @@ static BOOL fill_modrdn(struct ldap_message *msg, char **chunk) { struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; const char *attr_name; - struct ldap_val value; + struct ldb_val value; r->newrdn = NULL; r->deleteolddn = False; @@ -362,7 +362,7 @@ static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void const char *attr=NULL; const char *dn; char *chunk=NULL, *s; - struct ldap_val value; + struct ldb_val value; value.data = NULL; diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 2db85d8f09..720022c6c2 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -25,17 +25,25 @@ #include "libcli/ldap/ldap.h" #include "librpc/gen_ndr/ndr_security.h" +struct ldb_val ldb_blob(DATA_BLOB blob) +{ + struct ldb_val val; + val.data = blob.data; + val.length = blob.length; + return val; +} + /* encode a NDR uint32 as a ldap filter element */ const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) { uint8_t buf[4]; - DATA_BLOB blob; + struct ldb_val val; SIVAL(buf, 0, value); - blob.data = buf; - blob.length = 4; - return ldap_binary_encode(mem_ctx, blob); + val.data = buf; + val.length = 4; + return ldb_binary_encode(mem_ctx, val); } /* @@ -51,7 +59,7 @@ const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid) if (!NT_STATUS_IS_OK(status)) { return NULL; } - ret = ldap_binary_encode(mem_ctx, blob); + ret = ldb_binary_encode(mem_ctx, ldb_blob(blob)); data_blob_free(&blob); return ret; } @@ -70,7 +78,7 @@ const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) if (!NT_STATUS_IS_OK(status)) { return NULL; } - ret = ldap_binary_encode(mem_ctx, blob); + ret = ldb_binary_encode(mem_ctx, ldb_blob(blob)); data_blob_free(&blob); return ret; } @@ -78,7 +86,7 @@ const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) /* decode a NDR GUID from a ldap filter element */ -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldap_val val, struct GUID *guid) +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid) { DATA_BLOB blob; NTSTATUS status; |