summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/ldap/ldap.c151
1 files changed, 82 insertions, 69 deletions
diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c
index b589b6dd6d..fbb5a21d84 100644
--- a/source4/libcli/ldap/ldap.c
+++ b/source4/libcli/ldap/ldap.c
@@ -351,11 +351,8 @@ static BOOL ldap_push_filter(ASN1_DATA *data, struct ldap_parse_tree *tree)
return !data->has_error;
}
-static void ldap_encode_response(enum ldap_request_tag tag,
- struct ldap_Result *result,
- ASN1_DATA *data)
+static void ldap_encode_response(ASN1_DATA *data, struct ldap_Result *result)
{
- asn1_push_tag(data, ASN1_APPLICATION(tag));
asn1_write_enumerated(data, result->resultcode);
asn1_write_OctetString(data, result->dn,
(result->dn) ? strlen(result->dn) : 0);
@@ -365,7 +362,6 @@ static void ldap_encode_response(enum ldap_request_tag tag,
if (result->referral != NULL)
asn1_write_OctetString(data, result->referral,
strlen(result->referral));
- asn1_pop_tag(data);
}
BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
@@ -380,7 +376,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
switch (msg->type) {
case LDAP_TAG_BindRequest: {
struct ldap_BindRequest *r = &msg->r.BindRequest;
- asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_BindRequest));
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
asn1_write_Integer(&data, r->version);
asn1_write_OctetString(&data, r->dn,
(r->dn != NULL) ? strlen(r->dn) : 0);
@@ -388,14 +384,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
switch (r->mechanism) {
case LDAP_AUTH_MECH_SIMPLE:
/* context, primitive */
- asn1_push_tag(&data, r->mechanism | 0x80);
+ asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0));
asn1_write(&data, r->creds.password,
strlen(r->creds.password));
asn1_pop_tag(&data);
break;
case LDAP_AUTH_MECH_SASL:
/* context, constructed */
- asn1_push_tag(&data, r->mechanism | 0xa0);
+ asn1_push_tag(&data, ASN1_CONTEXT(3));
asn1_write_OctetString(&data, r->creds.SASL.mechanism,
strlen(r->creds.SASL.mechanism));
asn1_write_OctetString(&data, r->creds.SASL.secblob.data,
@@ -412,7 +408,12 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
}
case LDAP_TAG_BindResponse: {
struct ldap_BindResponse *r = &msg->r.BindResponse;
- ldap_encode_response(msg->type, &r->response, &data);
+ 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_pop_tag(&data);
break;
}
case LDAP_TAG_UnbindRequest: {
@@ -421,7 +422,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
}
case LDAP_TAG_SearchRequest: {
struct ldap_SearchRequest *r = &msg->r.SearchRequest;
- asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_SearchRequest));
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
asn1_write_OctetString(&data, r->basedn, strlen(r->basedn));
asn1_write_enumerated(&data, r->scope);
asn1_write_enumerated(&data, r->deref);
@@ -458,7 +459,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
}
case LDAP_TAG_SearchResultEntry: {
struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry;
- asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_SearchResultEntry));
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
asn1_write_OctetString(&data, r->dn, strlen(r->dn));
asn1_push_tag(&data, ASN1_SEQUENCE(0));
for (i=0; i<r->num_attributes; i++) {
@@ -481,12 +482,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
}
case LDAP_TAG_SearchResultDone: {
struct ldap_Result *r = &msg->r.SearchResultDone;
- ldap_encode_response(msg->type, r, &data);
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
+ ldap_encode_response(&data, r);
+ asn1_pop_tag(&data);
break;
}
case LDAP_TAG_ModifyRequest: {
struct ldap_ModifyRequest *r = &msg->r.ModifyRequest;
- asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest));
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
asn1_write_OctetString(&data, r->dn, strlen(r->dn));
asn1_push_tag(&data, ASN1_SEQUENCE(0));
@@ -515,12 +518,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
}
case LDAP_TAG_ModifyResponse: {
struct ldap_Result *r = &msg->r.ModifyResponse;
- ldap_encode_response(msg->type, r, &data);
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
+ ldap_encode_response(&data, r);
+ asn1_pop_tag(&data);
break;
}
case LDAP_TAG_AddRequest: {
struct ldap_AddRequest *r = &msg->r.AddRequest;
- asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_AddRequest));
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
asn1_write_OctetString(&data, r->dn, strlen(r->dn));
asn1_push_tag(&data, ASN1_SEQUENCE(0));
@@ -544,26 +549,28 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
}
case LDAP_TAG_AddResponse: {
struct ldap_Result *r = &msg->r.AddResponse;
- ldap_encode_response(msg->type, r, &data);
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
+ ldap_encode_response(&data, r);
+ asn1_pop_tag(&data);
break;
}
case LDAP_TAG_DelRequest: {
struct ldap_DelRequest *r = &msg->r.DelRequest;
- asn1_push_tag(&data,
- ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest));
+ asn1_push_tag(&data, ASN1_APPLICATION_SIMPLE(msg->type));
asn1_write(&data, r->dn, strlen(r->dn));
asn1_pop_tag(&data);
break;
}
case LDAP_TAG_DelResponse: {
struct ldap_Result *r = &msg->r.DelResponse;
- ldap_encode_response(msg->type, r, &data);
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
+ ldap_encode_response(&data, r);
+ asn1_pop_tag(&data);
break;
}
case LDAP_TAG_ModifyDNRequest: {
struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest;
- asn1_push_tag(&data,
- ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest));
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
asn1_write_OctetString(&data, r->dn, strlen(r->dn));
asn1_write_OctetString(&data, r->newrdn, strlen(r->newrdn));
asn1_write_BOOLEAN(&data, r->deleteolddn);
@@ -578,13 +585,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
}
case LDAP_TAG_ModifyDNResponse: {
struct ldap_Result *r = &msg->r.ModifyDNResponse;
- ldap_encode_response(msg->type, r, &data);
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
+ ldap_encode_response(&data, r);
+ asn1_pop_tag(&data);
break;
}
case LDAP_TAG_CompareRequest: {
struct ldap_CompareRequest *r = &msg->r.CompareRequest;
- asn1_push_tag(&data,
- ASN1_APPLICATION(LDAP_TAG_CompareRequest));
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
asn1_write_OctetString(&data, r->dn, strlen(r->dn));
asn1_push_tag(&data, ASN1_SEQUENCE(0));
asn1_write_OctetString(&data, r->attribute,
@@ -597,13 +605,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
}
case LDAP_TAG_CompareResponse: {
struct ldap_Result *r = &msg->r.ModifyDNResponse;
- ldap_encode_response(msg->type, r, &data);
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
+ ldap_encode_response(&data, r);
+ asn1_pop_tag(&data);
break;
}
case LDAP_TAG_AbandonRequest: {
struct ldap_AbandonRequest *r = &msg->r.AbandonRequest;
- asn1_push_tag(&data,
- ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest));
+ asn1_push_tag(&data, ASN1_APPLICATION_SIMPLE(msg->type));
asn1_write_implicit_Integer(&data, r->messageid);
asn1_pop_tag(&data);
break;
@@ -614,7 +623,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
}
case LDAP_TAG_ExtendedRequest: {
struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest;
- asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_ExtendedRequest));
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0));
asn1_write(&data, r->oid, strlen(r->oid));
asn1_pop_tag(&data);
@@ -626,7 +635,9 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result)
}
case LDAP_TAG_ExtendedResponse: {
struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse;
- ldap_encode_response(msg->type, &r->response, &data);
+ asn1_push_tag(&data, ASN1_APPLICATION(msg->type));
+ ldap_encode_response(&data, &r->response);
+ asn1_pop_tag(&data);
break;
}
default:
@@ -662,10 +673,8 @@ static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
static void ldap_decode_response(TALLOC_CTX *mem_ctx,
ASN1_DATA *data,
- enum ldap_request_tag tag,
struct ldap_Result *result)
{
- asn1_start_tag(data, ASN1_APPLICATION(tag));
asn1_read_enumerated(data, &result->resultcode);
asn1_read_OctetString_talloc(mem_ctx, data, &result->dn);
asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage);
@@ -676,7 +685,6 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx,
} else {
result->referral = NULL;
}
- asn1_end_tag(data);
}
static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, ASN1_DATA *data,
@@ -834,14 +842,14 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
case ASN1_APPLICATION(LDAP_TAG_BindRequest): {
struct ldap_BindRequest *r = &msg->r.BindRequest;
msg->type = LDAP_TAG_BindRequest;
- asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_BindRequest));
+ asn1_start_tag(data, tag);
asn1_read_Integer(data, &r->version);
asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn);
- if (asn1_peek_tag(data, 0x80)) {
+ if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) {
int pwlen;
r->creds.password = "";
- /* Mechanism 0 (SIMPLE) */
- asn1_start_tag(data, 0x80);
+ r->mechanism = LDAP_AUTH_MECH_SIMPLE;
+ asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0));
pwlen = asn1_tag_remaining(data);
if (pwlen != 0) {
char *pw = talloc(msg->mem_ctx, pwlen+1);
@@ -850,6 +858,15 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
r->creds.password = pw;
}
asn1_end_tag(data);
+ } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){
+ asn1_start_tag(data, ASN1_CONTEXT(3));
+ r->mechanism = LDAP_AUTH_MECH_SASL;
+ asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->creds.SASL.mechanism);
+ asn1_read_OctetString(data, &r->creds.SASL.secblob);
+ if (r->creds.SASL.secblob.data) {
+ talloc_steal(msg->mem_ctx, r->creds.SASL.secblob.data);
+ }
+ asn1_end_tag(data);
}
asn1_end_tag(data);
break;
@@ -858,17 +875,8 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
case ASN1_APPLICATION(LDAP_TAG_BindResponse): {
struct ldap_BindResponse *r = &msg->r.BindResponse;
msg->type = LDAP_TAG_BindResponse;
- asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_BindResponse));
- asn1_read_enumerated(data, &r->response.resultcode);
- asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.dn);
- asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.errormessage);
- if (asn1_peek_tag(data, ASN1_CONTEXT(3))) {
- asn1_start_tag(data, ASN1_CONTEXT(3));
- asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.referral);
- asn1_end_tag(data);
- } else {
- r->response.referral = NULL;
- }
+ asn1_start_tag(data, tag);
+ ldap_decode_response(msg->mem_ctx, data, &r->response);
if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) {
DATA_BLOB tmp_blob = data_blob(NULL, 0);
asn1_read_ContextSimple(data, 7, &tmp_blob);
@@ -883,7 +891,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): {
msg->type = LDAP_TAG_UnbindRequest;
- asn1_start_tag(data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest));
+ asn1_start_tag(data, tag);
asn1_end_tag(data);
break;
}
@@ -891,7 +899,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
case ASN1_APPLICATION(LDAP_TAG_SearchRequest): {
struct ldap_SearchRequest *r = &msg->r.SearchRequest;
msg->type = LDAP_TAG_SearchRequest;
- asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_SearchRequest));
+ asn1_start_tag(data, tag);
asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->basedn);
asn1_read_enumerated(data, (int *)&(r->scope));
asn1_read_enumerated(data, (int *)&(r->deref));
@@ -929,8 +937,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
msg->type = LDAP_TAG_SearchResultEntry;
r->attributes = NULL;
r->num_attributes = 0;
- asn1_start_tag(data,
- ASN1_APPLICATION(LDAP_TAG_SearchResultEntry));
+ asn1_start_tag(data, tag);
asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn);
ldap_decode_attribs(msg->mem_ctx, data, &r->attributes,
&r->num_attributes);
@@ -941,8 +948,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): {
struct ldap_Result *r = &msg->r.SearchResultDone;
msg->type = LDAP_TAG_SearchResultDone;
- ldap_decode_response(msg->mem_ctx, data,
- LDAP_TAG_SearchResultDone, r);
+ asn1_start_tag(data, tag);
+ ldap_decode_response(msg->mem_ctx, data, r);
+ asn1_end_tag(data);
break;
}
@@ -982,15 +990,16 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): {
struct ldap_Result *r = &msg->r.ModifyResponse;
msg->type = LDAP_TAG_ModifyResponse;
- ldap_decode_response(msg->mem_ctx, data,
- LDAP_TAG_ModifyResponse, r);
+ asn1_start_tag(data, tag);
+ ldap_decode_response(msg->mem_ctx, data, r);
+ asn1_end_tag(data);
break;
}
case ASN1_APPLICATION(LDAP_TAG_AddRequest): {
struct ldap_AddRequest *r = &msg->r.AddRequest;
msg->type = LDAP_TAG_AddRequest;
- asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_AddRequest));
+ asn1_start_tag(data, tag);
asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn);
r->attributes = NULL;
@@ -1005,8 +1014,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
case ASN1_APPLICATION(LDAP_TAG_AddResponse): {
struct ldap_Result *r = &msg->r.AddResponse;
msg->type = LDAP_TAG_AddResponse;
- ldap_decode_response(msg->mem_ctx, data,
- LDAP_TAG_AddResponse, r);
+ asn1_start_tag(data, tag);
+ ldap_decode_response(msg->mem_ctx, data, r);
+ asn1_end_tag(data);
break;
}
@@ -1031,8 +1041,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
case ASN1_APPLICATION(LDAP_TAG_DelResponse): {
struct ldap_Result *r = &msg->r.DelResponse;
msg->type = LDAP_TAG_DelResponse;
- ldap_decode_response(msg->mem_ctx, data,
- LDAP_TAG_DelResponse, r);
+ asn1_start_tag(data, tag);
+ ldap_decode_response(msg->mem_ctx, data, r);
+ asn1_end_tag(data);
break;
}
@@ -1065,8 +1076,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): {
struct ldap_Result *r = &msg->r.ModifyDNResponse;
msg->type = LDAP_TAG_ModifyDNResponse;
- ldap_decode_response(msg->mem_ctx, data,
- LDAP_TAG_ModifyDNResponse, r);
+ asn1_start_tag(data, tag);
+ ldap_decode_response(msg->mem_ctx, data, r);
+ asn1_end_tag(data);
break;
}
@@ -1090,16 +1102,16 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
case ASN1_APPLICATION(LDAP_TAG_CompareResponse): {
struct ldap_Result *r = &msg->r.CompareResponse;
msg->type = LDAP_TAG_CompareResponse;
- ldap_decode_response(msg->mem_ctx, data,
- LDAP_TAG_CompareResponse, r);
+ asn1_start_tag(data, tag);
+ ldap_decode_response(msg->mem_ctx, data, r);
+ asn1_end_tag(data);
break;
}
case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): {
struct ldap_AbandonRequest *r = &msg->r.AbandonRequest;
msg->type = LDAP_TAG_AbandonRequest;
- asn1_start_tag(data,
- ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest));
+ asn1_start_tag(data, tag);
asn1_read_implicit_Integer(data, &r->messageid);
asn1_end_tag(data);
break;
@@ -1110,7 +1122,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
DATA_BLOB tmp_blob = data_blob(NULL, 0);
msg->type = LDAP_TAG_ExtendedRequest;
- asn1_start_tag(data,ASN1_APPLICATION(LDAP_TAG_ExtendedRequest));
+ asn1_start_tag(data,tag);
if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) {
return False;
}
@@ -1135,14 +1147,15 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg)
case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): {
struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse;
msg->type = LDAP_TAG_ExtendedResponse;
- ldap_decode_response(msg->mem_ctx, data,
- LDAP_TAG_ExtendedResponse, &r->response);
+ asn1_start_tag(data, tag);
+ ldap_decode_response(msg->mem_ctx, data, &r->response);
/* I have to come across an operation that actually sends
* something back to really see what's going on. The currently
* needed pwdchange does not send anything back. */
r->name = NULL;
r->value.data = NULL;
r->value.length = 0;
+ asn1_end_tag(data);
break;
}
default: