📄 ldap.c
字号:
/* Unix SMB/CIFS mplementation. LDAP protocol helper functions for SAMBA Copyright (C) Andrew Tridgell 2004 Copyright (C) Volker Lendecke 2004 Copyright (C) Stefan Metzmacher 2004 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 3 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, see <http://www.gnu.org/licenses/>. */#include "includes.h"#include "lib/util/asn1.h"#include "libcli/ldap/ldap.h"#include "libcli/ldap/ldap_proto.h"static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree){ int i; switch (tree->operation) { case LDB_OP_AND: case LDB_OP_OR: asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); for (i=0; i<tree->u.list.num_elements; i++) { if (!ldap_push_filter(data, tree->u.list.elements[i])) { return false; } } asn1_pop_tag(data); break; case LDB_OP_NOT: asn1_push_tag(data, ASN1_CONTEXT(2)); if (!ldap_push_filter(data, tree->u.isnot.child)) { return false; } asn1_pop_tag(data); break; case LDB_OP_EQUALITY: /* equality test */ asn1_push_tag(data, ASN1_CONTEXT(3)); asn1_write_OctetString(data, tree->u.equality.attr, strlen(tree->u.equality.attr)); asn1_write_OctetString(data, tree->u.equality.value.data, tree->u.equality.value.length); asn1_pop_tag(data); break; case LDB_OP_SUBSTRING: /* SubstringFilter ::= SEQUENCE { type AttributeDescription, -- at least one must be present substrings SEQUENCE OF CHOICE { initial [0] LDAPString, any [1] LDAPString, final [2] LDAPString } } */ asn1_push_tag(data, ASN1_CONTEXT(4)); asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); asn1_push_tag(data, ASN1_SEQUENCE(0)); i = 0; if ( ! tree->u.substring.start_with_wildcard) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); asn1_pop_tag(data); i++; } while (tree->u.substring.chunks[i]) { int ctx; if (( ! tree->u.substring.chunks[i + 1]) && (tree->u.substring.end_with_wildcard == 0)) { ctx = 2; } else { ctx = 1; } asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); asn1_pop_tag(data); i++; } asn1_pop_tag(data); asn1_pop_tag(data); break; case LDB_OP_GREATER: /* greaterOrEqual test */ asn1_push_tag(data, ASN1_CONTEXT(5)); asn1_write_OctetString(data, tree->u.comparison.attr, strlen(tree->u.comparison.attr)); asn1_write_OctetString(data, tree->u.comparison.value.data, tree->u.comparison.value.length); asn1_pop_tag(data); break; case LDB_OP_LESS: /* lessOrEqual test */ asn1_push_tag(data, ASN1_CONTEXT(6)); asn1_write_OctetString(data, tree->u.comparison.attr, strlen(tree->u.comparison.attr)); asn1_write_OctetString(data, tree->u.comparison.value.data, tree->u.comparison.value.length); asn1_pop_tag(data); break; case LDB_OP_PRESENT: /* present test */ asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); asn1_write_LDAPString(data, tree->u.present.attr); asn1_pop_tag(data); return !data->has_error; case LDB_OP_APPROX: /* approx test */ asn1_push_tag(data, ASN1_CONTEXT(8)); asn1_write_OctetString(data, tree->u.comparison.attr, strlen(tree->u.comparison.attr)); asn1_write_OctetString(data, tree->u.comparison.value.data, tree->u.comparison.value.length); asn1_pop_tag(data); break; case LDB_OP_EXTENDED: /* MatchingRuleAssertion ::= SEQUENCE { matchingRule [1] MatchingRuleID OPTIONAL, type [2] AttributeDescription OPTIONAL, matchValue [3] AssertionValue, dnAttributes [4] BOOLEAN DEFAULT FALSE } */ asn1_push_tag(data, ASN1_CONTEXT(9)); if (tree->u.extended.rule_id) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); asn1_write_LDAPString(data, tree->u.extended.rule_id); asn1_pop_tag(data); } if (tree->u.extended.attr) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); asn1_write_LDAPString(data, tree->u.extended.attr); asn1_pop_tag(data); } asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); asn1_pop_tag(data); asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); asn1_write_uint8(data, tree->u.extended.dnAttributes); asn1_pop_tag(data); asn1_pop_tag(data); break; default: return false; } return !data->has_error;}static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result){ asn1_write_enumerated(data, result->resultcode); asn1_write_OctetString(data, result->dn, (result->dn) ? strlen(result->dn) : 0); asn1_write_OctetString(data, result->errormessage, (result->errormessage) ? strlen(result->errormessage) : 0); if (result->referral) { asn1_push_tag(data, ASN1_CONTEXT(3)); asn1_write_OctetString(data, result->referral, strlen(result->referral)); asn1_pop_tag(data); }}_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx){ struct asn1_data *data = asn1_init(mem_ctx); int i, j; if (!data) return false; asn1_push_tag(data, ASN1_SEQUENCE(0)); asn1_write_Integer(data, msg->messageid); switch (msg->type) { case LDAP_TAG_BindRequest: { struct ldap_BindRequest *r = &msg->r.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); switch (r->mechanism) { case LDAP_AUTH_MECH_SIMPLE: /* context, primitive */ 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, ASN1_CONTEXT(3)); asn1_write_OctetString(data, r->creds.SASL.mechanism, strlen(r->creds.SASL.mechanism)); if (r->creds.SASL.secblob) { asn1_write_OctetString(data, r->creds.SASL.secblob->data, r->creds.SASL.secblob->length); } asn1_pop_tag(data); break; default: return false; } asn1_pop_tag(data); break; } case LDAP_TAG_BindResponse: { 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) { asn1_write_ContextSimple(data, 7, r->SASL.secblob); } asn1_pop_tag(data); break; } case LDAP_TAG_UnbindRequest: {/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ break; } case LDAP_TAG_SearchRequest: { struct ldap_SearchRequest *r = &msg->r.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); asn1_write_Integer(data, r->sizelimit); asn1_write_Integer(data, r->timelimit); asn1_write_BOOLEAN(data, r->attributesonly); if (!ldap_push_filter(data, r->tree)) { return false; } asn1_push_tag(data, ASN1_SEQUENCE(0)); for (i=0; i<r->num_attributes; i++) { asn1_write_OctetString(data, r->attributes[i], strlen(r->attributes[i])); } asn1_pop_tag(data); asn1_pop_tag(data); break; } case LDAP_TAG_SearchResultEntry: { struct ldap_SearchResEntry *r = &msg->r.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++) { struct ldb_message_element *attr = &r->attributes[i]; asn1_push_tag(data, ASN1_SEQUENCE(0)); asn1_write_OctetString(data, attr->name, strlen(attr->name)); asn1_push_tag(data, ASN1_SEQUENCE(1)); for (j=0; j<attr->num_values; j++) { asn1_write_OctetString(data, attr->values[j].data, attr->values[j].length); } asn1_pop_tag(data); asn1_pop_tag(data); } asn1_pop_tag(data); asn1_pop_tag(data); break; } case LDAP_TAG_SearchResultDone: { struct ldap_Result *r = &msg->r.SearchResultDone; 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(msg->type)); asn1_write_OctetString(data, r->dn, strlen(r->dn)); asn1_push_tag(data, ASN1_SEQUENCE(0)); for (i=0; i<r->num_mods; i++) { struct ldb_message_element *attrib = &r->mods[i].attrib; asn1_push_tag(data, ASN1_SEQUENCE(0)); asn1_write_enumerated(data, r->mods[i].type); asn1_push_tag(data, ASN1_SEQUENCE(0)); asn1_write_OctetString(data, attrib->name, strlen(attrib->name)); asn1_push_tag(data, ASN1_SET); for (j=0; j<attrib->num_values; j++) { asn1_write_OctetString(data, attrib->values[j].data, attrib->values[j].length); } asn1_pop_tag(data); asn1_pop_tag(data); asn1_pop_tag(data); } asn1_pop_tag(data); asn1_pop_tag(data); break; } case LDAP_TAG_ModifyResponse: { struct ldap_Result *r = &msg->r.ModifyResponse; 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(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++) { struct ldb_message_element *attrib = &r->attributes[i]; asn1_push_tag(data, ASN1_SEQUENCE(0)); asn1_write_OctetString(data, attrib->name, strlen(attrib->name)); asn1_push_tag(data, ASN1_SET); for (j=0; j<r->attributes[i].num_values; j++) { asn1_write_OctetString(data, attrib->values[j].data, attrib->values[j].length); } asn1_pop_tag(data); asn1_pop_tag(data); } asn1_pop_tag(data); asn1_pop_tag(data); break; } case LDAP_TAG_AddResponse: { struct ldap_Result *r = &msg->r.AddResponse; 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(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; 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(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); if (r->newsuperior) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); asn1_write(data, r->newsuperior, strlen(r->newsuperior)); asn1_pop_tag(data); } asn1_pop_tag(data); break; } case LDAP_TAG_ModifyDNResponse: { struct ldap_Result *r = &msg->r.ModifyDNResponse; 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(msg->type)); asn1_write_OctetString(data, r->dn, strlen(r->dn)); asn1_push_tag(data, ASN1_SEQUENCE(0)); asn1_write_OctetString(data, r->attribute, strlen(r->attribute)); asn1_write_OctetString(data, r->value.data, r->value.length); asn1_pop_tag(data); asn1_pop_tag(data); break; } case LDAP_TAG_CompareResponse: { struct ldap_Result *r = &msg->r.ModifyDNResponse; 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(msg->type)); asn1_write_implicit_Integer(data, r->messageid); asn1_pop_tag(data); break; } case LDAP_TAG_SearchResultReference: { struct ldap_SearchResRef *r = &msg->r.SearchResultReference; asn1_push_tag(data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(data, r->referral, strlen(r->referral)); asn1_pop_tag(data); break; } case LDAP_TAG_ExtendedRequest: { struct ldap_ExtendedRequest *r = &msg->r.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); if (r->value) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); asn1_write(data, r->value->data, r->value->length); asn1_pop_tag(data); } asn1_pop_tag(data); break; } case LDAP_TAG_ExtendedResponse: { struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; asn1_push_tag(data, ASN1_APPLICATION(msg->type)); ldap_encode_response(data, &r->response); if (r->oid) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); asn1_write(data, r->oid, strlen(r->oid)); asn1_pop_tag(data); } if (r->value) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); asn1_write(data, r->value->data, r->value->length); asn1_pop_tag(data); } asn1_pop_tag(data); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -