2004-08-12 08:55:59 +04:00
/*
2016-04-20 08:10:41 +03:00
Unix SMB / CIFS implementation .
2004-08-12 08:55:59 +04:00
LDAP protocol helper functions for SAMBA
Copyright ( C ) Andrew Tridgell 2004
Copyright ( C ) Volker Lendecke 2004
2004-08-13 11:10:46 +04:00
Copyright ( C ) Stefan Metzmacher 2004
Copyright ( C ) Simo Sorce 2004
2004-08-12 08:55:59 +04:00
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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2004-08-12 08:55:59 +04:00
( 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
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-08-12 08:55:59 +04:00
*/
# include "includes.h"
2008-10-11 23:31:42 +04:00
# include "../lib/util/asn1.h"
2009-02-24 14:13:41 +03:00
# include "../libcli/ldap/ldap_message.h"
2004-08-12 08:55:59 +04:00
2009-02-24 13:40:18 +03:00
_PUBLIC_ struct ldap_message * new_ldap_message ( TALLOC_CTX * mem_ctx )
{
return talloc_zero ( mem_ctx , struct ldap_message ) ;
}
static bool add_value_to_attrib ( TALLOC_CTX * mem_ctx , struct ldb_val * value ,
struct ldb_message_element * attrib )
{
attrib - > values = talloc_realloc ( mem_ctx ,
attrib - > values ,
DATA_BLOB ,
attrib - > num_values + 1 ) ;
if ( attrib - > values = = NULL )
return false ;
attrib - > values [ attrib - > num_values ] . data = talloc_steal ( attrib - > values ,
value - > data ) ;
attrib - > values [ attrib - > num_values ] . length = value - > length ;
attrib - > num_values + = 1 ;
return true ;
}
static bool add_attrib_to_array_talloc ( TALLOC_CTX * mem_ctx ,
const struct ldb_message_element * attrib ,
struct ldb_message_element * * attribs ,
int * num_attribs )
{
* attribs = talloc_realloc ( mem_ctx ,
* attribs ,
struct ldb_message_element ,
* num_attribs + 1 ) ;
if ( * attribs = = NULL )
return false ;
( * attribs ) [ * num_attribs ] = * attrib ;
talloc_steal ( * attribs , attrib - > values ) ;
talloc_steal ( * attribs , attrib - > name ) ;
* num_attribs + = 1 ;
return true ;
}
static bool add_mod_to_array_talloc ( TALLOC_CTX * mem_ctx ,
struct ldap_mod * mod ,
struct ldap_mod * * mods ,
int * num_mods )
{
* mods = talloc_realloc ( mem_ctx , * mods , struct ldap_mod , ( * num_mods ) + 1 ) ;
if ( * mods = = NULL )
return false ;
( * mods ) [ * num_mods ] = * mod ;
* num_mods + = 1 ;
return true ;
}
2005-05-11 09:59:46 +04:00
2009-02-24 18:49:26 +03:00
static bool ldap_decode_control_value ( void * mem_ctx , DATA_BLOB value ,
const struct ldap_control_handler * handlers ,
struct ldb_control * ctrl )
{
int i ;
if ( ! handlers ) {
return true ;
}
for ( i = 0 ; handlers [ i ] . oid ! = NULL ; i + + ) {
if ( strcmp ( handlers [ i ] . oid , ctrl - > oid ) = = 0 ) {
if ( ! handlers [ i ] . decode | | ! handlers [ i ] . decode ( mem_ctx , value , & ctrl - > data ) ) {
return false ;
}
break ;
}
}
if ( handlers [ i ] . oid = = NULL ) {
return false ;
}
return true ;
}
static bool ldap_decode_control_wrapper ( void * mem_ctx , struct asn1_data * data ,
struct ldb_control * ctrl , DATA_BLOB * value )
{
DATA_BLOB oid ;
if ( ! asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) {
return false ;
}
if ( ! asn1_read_OctetString ( data , mem_ctx , & oid ) ) {
return false ;
}
ctrl - > oid = talloc_strndup ( mem_ctx , ( char * ) oid . data , oid . length ) ;
if ( ! ctrl - > oid ) {
return false ;
}
if ( asn1_peek_tag ( data , ASN1_BOOLEAN ) ) {
bool critical ;
if ( ! asn1_read_BOOLEAN ( data , & critical ) ) {
return false ;
}
ctrl - > critical = critical ;
} else {
ctrl - > critical = false ;
}
ctrl - > data = NULL ;
if ( ! asn1_peek_tag ( data , ASN1_OCTET_STRING ) ) {
* value = data_blob ( NULL , 0 ) ;
goto end_tag ;
}
if ( ! asn1_read_OctetString ( data , mem_ctx , value ) ) {
return false ;
}
end_tag :
if ( ! asn1_end_tag ( data ) ) {
return false ;
}
return true ;
}
static bool ldap_encode_control ( void * mem_ctx , struct asn1_data * data ,
const struct ldap_control_handler * handlers ,
struct ldb_control * ctrl )
{
DATA_BLOB value ;
int i ;
if ( ! handlers ) {
return false ;
}
for ( i = 0 ; handlers [ i ] . oid ! = NULL ; i + + ) {
2010-10-20 07:27:57 +04:00
if ( ! ctrl - > oid ) {
/* not encoding this control, the OID has been
* set to NULL indicating it isn ' t really
* here */
return true ;
}
2009-02-24 18:49:26 +03:00
if ( strcmp ( handlers [ i ] . oid , ctrl - > oid ) = = 0 ) {
if ( ! handlers [ i ] . encode ) {
if ( ctrl - > critical ) {
return false ;
} else {
/* not encoding this control */
return true ;
}
}
if ( ! handlers [ i ] . encode ( mem_ctx , ctrl - > data , & value ) ) {
return false ;
}
break ;
}
}
if ( handlers [ i ] . oid = = NULL ) {
return false ;
}
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) {
return false ;
}
if ( ! asn1_write_OctetString ( data , ctrl - > oid , strlen ( ctrl - > oid ) ) ) {
return false ;
}
if ( ctrl - > critical ) {
if ( ! asn1_write_BOOLEAN ( data , ctrl - > critical ) ) {
return false ;
}
}
if ( ! ctrl - > data ) {
goto pop_tag ;
}
if ( ! asn1_write_OctetString ( data , value . data , value . length ) ) {
return false ;
}
pop_tag :
if ( ! asn1_pop_tag ( data ) ) {
return false ;
}
return true ;
}
2007-10-07 02:28:14 +04:00
static bool ldap_push_filter ( struct asn1_data * data , struct ldb_parse_tree * tree )
2004-08-12 08:55:59 +04:00
{
2005-06-14 07:53:35 +04:00
int i ;
2004-08-12 08:55:59 +04:00
switch ( tree - > operation ) {
2005-07-17 18:16:41 +04:00
case LDB_OP_AND :
case LDB_OP_OR :
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT ( tree - > operation = = LDB_OP_AND ? 0 : 1 ) ) ) return false ;
2005-07-17 18:16:41 +04:00
for ( i = 0 ; i < tree - > u . list . num_elements ; i + + ) {
if ( ! ldap_push_filter ( data , tree - > u . list . elements [ i ] ) ) {
2007-10-07 02:28:14 +04:00
return false ;
2005-07-17 18:16:41 +04:00
}
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) return false ;
2005-07-17 18:16:41 +04:00
break ;
case LDB_OP_NOT :
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT ( 2 ) ) ) return false ;
2005-07-17 18:16:41 +04:00
if ( ! ldap_push_filter ( data , tree - > u . isnot . child ) ) {
2007-10-07 02:28:14 +04:00
return false ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) return false ;
2005-07-17 18:16:41 +04:00
break ;
2004-08-12 08:55:59 +04:00
2005-07-19 13:09:00 +04:00
case LDB_OP_EQUALITY :
2005-06-14 07:53:35 +04:00
/* equality test */
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT ( 3 ) ) ) return false ;
if ( ! asn1_write_OctetString ( data , tree - > u . equality . attr ,
strlen ( tree - > u . equality . attr ) ) ) return false ;
if ( ! asn1_write_OctetString ( data , tree - > u . equality . value . data ,
tree - > u . equality . value . length ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
2004-08-12 08:55:59 +04:00
break ;
2005-07-17 18:16:41 +04:00
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 } }
*/
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT ( 4 ) ) ) return false ;
if ( ! asn1_write_OctetString ( data , tree - > u . substring . attr , strlen ( tree - > u . substring . attr ) ) ) return false ;
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) return false ;
2013-06-22 11:01:42 +04:00
if ( tree - > u . substring . chunks & & tree - > u . substring . chunks [ 0 ] ) {
i = 0 ;
if ( ! tree - > u . substring . start_with_wildcard ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( 0 ) ) ) return false ;
if ( ! asn1_write_DATA_BLOB_LDAPString ( data , tree - > u . substring . chunks [ i ] ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
2013-06-22 11:01:42 +04:00
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 ;
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( ctx ) ) ) return false ;
if ( ! asn1_write_DATA_BLOB_LDAPString ( data , tree - > u . substring . chunks [ i ] ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
2013-06-22 11:01:42 +04:00
i + + ;
2005-07-17 18:16:41 +04:00
}
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
2005-07-17 18:16:41 +04:00
break ;
2005-07-19 13:09:00 +04:00
case LDB_OP_GREATER :
/* greaterOrEqual test */
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT ( 5 ) ) ) return false ;
if ( ! asn1_write_OctetString ( data , tree - > u . comparison . attr ,
strlen ( tree - > u . comparison . attr ) ) ) return false ;
if ( ! asn1_write_OctetString ( data , tree - > u . comparison . value . data ,
tree - > u . comparison . value . length ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
2005-07-19 13:09:00 +04:00
break ;
case LDB_OP_LESS :
/* lessOrEqual test */
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT ( 6 ) ) ) return false ;
if ( ! asn1_write_OctetString ( data , tree - > u . comparison . attr ,
strlen ( tree - > u . comparison . attr ) ) ) return false ;
if ( ! asn1_write_OctetString ( data , tree - > u . comparison . value . data ,
tree - > u . comparison . value . length ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
2005-07-19 13:09:00 +04:00
break ;
2005-07-17 18:16:41 +04:00
case LDB_OP_PRESENT :
/* present test */
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( 7 ) ) ) return false ;
if ( ! asn1_write_LDAPString ( data , tree - > u . present . attr ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
2016-01-02 20:11:00 +03:00
return ! asn1_has_error ( data ) ;
2005-07-17 18:16:41 +04:00
2005-07-19 13:09:00 +04:00
case LDB_OP_APPROX :
/* approx test */
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT ( 8 ) ) ) return false ;
if ( ! asn1_write_OctetString ( data , tree - > u . comparison . attr ,
strlen ( tree - > u . comparison . attr ) ) ) return false ;
if ( ! asn1_write_OctetString ( data , tree - > u . comparison . value . data ,
tree - > u . comparison . value . length ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
2005-07-19 13:09:00 +04:00
break ;
2005-06-14 07:53:35 +04:00
case LDB_OP_EXTENDED :
/*
MatchingRuleAssertion : : = SEQUENCE {
matchingRule [ 1 ] MatchingRuleID OPTIONAL ,
type [ 2 ] AttributeDescription OPTIONAL ,
matchValue [ 3 ] AssertionValue ,
dnAttributes [ 4 ] BOOLEAN DEFAULT FALSE
}
*/
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT ( 9 ) ) ) return false ;
2005-06-14 07:53:35 +04:00
if ( tree - > u . extended . rule_id ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( 1 ) ) ) return false ;
if ( ! asn1_write_LDAPString ( data , tree - > u . extended . rule_id ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
2005-06-14 07:53:35 +04:00
}
if ( tree - > u . extended . attr ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( 2 ) ) ) return false ;
if ( ! asn1_write_LDAPString ( data , tree - > u . extended . attr ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
2005-06-14 07:53:35 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( 3 ) ) ) return false ;
if ( ! asn1_write_DATA_BLOB_LDAPString ( data , & tree - > u . extended . value ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( 4 ) ) ) return false ;
if ( ! asn1_write_uint8 ( data , tree - > u . extended . dnAttributes ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
2004-08-12 08:55:59 +04:00
break ;
2005-06-18 14:38:06 +04:00
2004-08-12 08:55:59 +04:00
default :
2007-10-07 02:28:14 +04:00
return false ;
2004-08-12 08:55:59 +04:00
}
2016-01-02 20:11:00 +03:00
return ! asn1_has_error ( data ) ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
static bool ldap_encode_response ( struct asn1_data * data , struct ldap_Result * result )
2004-08-12 08:55:59 +04:00
{
2014-09-23 03:08:26 +04:00
if ( ! asn1_write_enumerated ( data , result - > resultcode ) ) return false ;
if ( ! asn1_write_OctetString ( data , result - > dn ,
( result - > dn ) ? strlen ( result - > dn ) : 0 ) ) return false ;
if ( ! asn1_write_OctetString ( data , result - > errormessage ,
2004-08-12 08:55:59 +04:00
( result - > errormessage ) ?
2014-09-23 03:08:26 +04:00
strlen ( result - > errormessage ) : 0 ) ) return false ;
2004-11-06 23:43:36 +03:00
if ( result - > referral ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT ( 3 ) ) ) return false ;
if ( ! asn1_write_OctetString ( data , result - > referral ,
strlen ( result - > referral ) ) ) return false ;
if ( ! asn1_pop_tag ( data ) ) return false ;
2004-11-06 23:43:36 +03:00
}
2014-09-23 03:08:26 +04:00
return true ;
2004-08-12 08:55:59 +04:00
}
2009-02-24 18:49:26 +03:00
_PUBLIC_ bool ldap_encode ( struct ldap_message * msg ,
const struct ldap_control_handler * control_handlers ,
DATA_BLOB * result , TALLOC_CTX * mem_ctx )
2004-08-12 08:55:59 +04:00
{
2020-04-03 02:18:03 +03:00
struct asn1_data * data = asn1_init ( mem_ctx , ASN1_MAX_TREE_DEPTH ) ;
2004-08-12 08:55:59 +04:00
int i , j ;
2007-10-07 02:28:14 +04:00
if ( ! data ) return false ;
2007-05-21 16:47:18 +04:00
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto err ;
if ( ! asn1_write_Integer ( data , msg - > messageid ) ) goto err ;
2004-08-12 08:55:59 +04:00
switch ( msg - > type ) {
case LDAP_TAG_BindRequest : {
struct ldap_BindRequest * r = & msg - > r . BindRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! asn1_write_Integer ( data , r - > version ) ) goto err ;
if ( ! asn1_write_OctetString ( data , r - > dn ,
( r - > dn ! = NULL ) ? strlen ( r - > dn ) : 0 ) ) goto err ;
2004-08-12 08:55:59 +04:00
switch ( r - > mechanism ) {
case LDAP_AUTH_MECH_SIMPLE :
/* context, primitive */
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( 0 ) ) ) goto err ;
if ( ! asn1_write ( data , r - > creds . password ,
strlen ( r - > creds . password ) ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
case LDAP_AUTH_MECH_SASL :
/* context, constructed */
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT ( 3 ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , r - > creds . SASL . mechanism ,
strlen ( r - > creds . SASL . mechanism ) ) ) goto err ;
2006-02-15 18:19:10 +03:00
if ( r - > creds . SASL . secblob ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_write_OctetString ( data , r - > creds . SASL . secblob - > data ,
r - > creds . SASL . secblob - > length ) ) goto err ;
2006-02-04 14:19:09 +03:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
default :
2014-09-23 03:08:26 +04:00
goto err ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_BindResponse : {
struct ldap_BindResponse * r = & msg - > r . BindResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! ldap_encode_response ( data , & r - > response ) ) goto err ;
2006-02-15 18:19:10 +03:00
if ( r - > SASL . secblob ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_write_ContextSimple ( data , 7 , r - > SASL . secblob ) ) goto err ;
2006-02-04 14:19:09 +03:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_UnbindRequest : {
/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION_SIMPLE ( msg - > type ) ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_SearchRequest : {
struct ldap_SearchRequest * r = & msg - > r . SearchRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , r - > basedn , strlen ( r - > basedn ) ) ) goto err ;
if ( ! asn1_write_enumerated ( data , r - > scope ) ) goto err ;
if ( ! asn1_write_enumerated ( data , r - > deref ) ) goto err ;
if ( ! asn1_write_Integer ( data , r - > sizelimit ) ) goto err ;
if ( ! asn1_write_Integer ( data , r - > timelimit ) ) goto err ;
if ( ! asn1_write_BOOLEAN ( data , r - > attributesonly ) ) goto err ;
2007-05-21 10:12:06 +04:00
if ( ! ldap_push_filter ( data , r - > tree ) ) {
2014-09-23 03:08:26 +04:00
goto err ;
2005-06-18 16:45:28 +04:00
}
2004-08-12 08:55:59 +04:00
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto err ;
2004-08-12 08:55:59 +04:00
for ( i = 0 ; i < r - > num_attributes ; i + + ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_write_OctetString ( data , r - > attributes [ i ] ,
strlen ( r - > attributes [ i ] ) ) ) goto err ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_SearchResultEntry : {
struct ldap_SearchResEntry * r = & msg - > r . SearchResultEntry ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , r - > dn , strlen ( r - > dn ) ) ) goto err ;
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto err ;
2004-08-12 08:55:59 +04:00
for ( i = 0 ; i < r - > num_attributes ; i + + ) {
2005-06-15 05:02:53 +04:00
struct ldb_message_element * attr = & r - > attributes [ i ] ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , attr - > name ,
strlen ( attr - > name ) ) ) goto err ;
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 1 ) ) ) goto err ;
2004-08-12 08:55:59 +04:00
for ( j = 0 ; j < attr - > num_values ; j + + ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_write_OctetString ( data ,
2004-08-12 08:55:59 +04:00
attr - > values [ j ] . data ,
2014-09-23 03:08:26 +04:00
attr - > values [ j ] . length ) ) goto err ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_SearchResultDone : {
2004-08-12 10:37:12 +04:00
struct ldap_Result * r = & msg - > r . SearchResultDone ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! ldap_encode_response ( data , r ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_ModifyRequest : {
struct ldap_ModifyRequest * r = & msg - > r . ModifyRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , r - > dn , strlen ( r - > dn ) ) ) goto err ;
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto err ;
2004-08-12 08:55:59 +04:00
for ( i = 0 ; i < r - > num_mods ; i + + ) {
2005-06-15 05:02:53 +04:00
struct ldb_message_element * attrib = & r - > mods [ i ] . attrib ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto err ;
if ( ! asn1_write_enumerated ( data , r - > mods [ i ] . type ) ) goto err ;
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , attrib - > name ,
strlen ( attrib - > name ) ) ) goto err ;
if ( ! asn1_push_tag ( data , ASN1_SET ) ) goto err ;
2004-08-12 08:55:59 +04:00
for ( j = 0 ; j < attrib - > num_values ; j + + ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_write_OctetString ( data ,
2004-08-12 08:55:59 +04:00
attrib - > values [ j ] . data ,
2014-09-23 03:08:26 +04:00
attrib - > values [ j ] . length ) ) goto err ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_ModifyResponse : {
struct ldap_Result * r = & msg - > r . ModifyResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! ldap_encode_response ( data , r ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_AddRequest : {
struct ldap_AddRequest * r = & msg - > r . AddRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , r - > dn , strlen ( r - > dn ) ) ) goto err ;
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto err ;
2004-08-12 08:55:59 +04:00
for ( i = 0 ; i < r - > num_attributes ; i + + ) {
2005-06-15 05:02:53 +04:00
struct ldb_message_element * attrib = & r - > attributes [ i ] ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto err ;
2023-07-07 01:37:09 +03:00
if ( attrib - > name = = NULL ) {
goto err ;
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_write_OctetString ( data , attrib - > name ,
strlen ( attrib - > name ) ) ) goto err ;
if ( ! asn1_push_tag ( data , ASN1_SET ) ) goto err ;
2004-08-12 08:55:59 +04:00
for ( j = 0 ; j < r - > attributes [ i ] . num_values ; j + + ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_write_OctetString ( data ,
2004-08-12 08:55:59 +04:00
attrib - > values [ j ] . data ,
2014-09-23 03:08:26 +04:00
attrib - > values [ j ] . length ) ) goto err ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_AddResponse : {
struct ldap_Result * r = & msg - > r . AddResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! ldap_encode_response ( data , r ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
2004-09-27 19:40:12 +04:00
case LDAP_TAG_DelRequest : {
struct ldap_DelRequest * r = & msg - > r . DelRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION_SIMPLE ( msg - > type ) ) ) goto err ;
if ( ! asn1_write ( data , r - > dn , strlen ( r - > dn ) ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
2004-09-27 19:40:12 +04:00
case LDAP_TAG_DelResponse : {
struct ldap_Result * r = & msg - > r . DelResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! ldap_encode_response ( data , r ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_ModifyDNRequest : {
struct ldap_ModifyDNRequest * r = & msg - > r . ModifyDNRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , r - > dn , strlen ( r - > dn ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , r - > newrdn , strlen ( r - > newrdn ) ) ) goto err ;
if ( ! asn1_write_BOOLEAN ( data , r - > deleteolddn ) ) goto err ;
2006-02-15 18:19:10 +03:00
if ( r - > newsuperior ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( 0 ) ) ) goto err ;
if ( ! asn1_write ( data , r - > newsuperior ,
strlen ( r - > newsuperior ) ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_ModifyDNResponse : {
2004-08-17 15:22:44 +04:00
struct ldap_Result * r = & msg - > r . ModifyDNResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! ldap_encode_response ( data , r ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_CompareRequest : {
struct ldap_CompareRequest * r = & msg - > r . CompareRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , r - > dn , strlen ( r - > dn ) ) ) goto err ;
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , r - > attribute ,
strlen ( r - > attribute ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , r - > value . data ,
r - > value . length ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_CompareResponse : {
2004-09-29 16:18:06 +04:00
struct ldap_Result * r = & msg - > r . ModifyDNResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! ldap_encode_response ( data , r ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_AbandonRequest : {
struct ldap_AbandonRequest * r = & msg - > r . AbandonRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION_SIMPLE ( msg - > type ) ) ) goto err ;
if ( ! asn1_write_implicit_Integer ( data , r - > messageid ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_SearchResultReference : {
2004-11-06 23:43:36 +03:00
struct ldap_SearchResRef * r = & msg - > r . SearchResultReference ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! asn1_write_OctetString ( data , r - > referral , strlen ( r - > referral ) ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_ExtendedRequest : {
struct ldap_ExtendedRequest * r = & msg - > r . ExtendedRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( 0 ) ) ) goto err ;
if ( ! asn1_write ( data , r - > oid , strlen ( r - > oid ) ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2006-02-15 18:19:10 +03:00
if ( r - > value ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( 1 ) ) ) goto err ;
if ( ! asn1_write ( data , r - > value - > data , r - > value - > length ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2006-02-15 18:19:10 +03:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_ExtendedResponse : {
struct ldap_ExtendedResponse * r = & msg - > r . ExtendedResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_APPLICATION ( msg - > type ) ) ) goto err ;
if ( ! ldap_encode_response ( data , & r - > response ) ) goto err ;
2006-02-15 18:19:10 +03:00
if ( r - > oid ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( 10 ) ) ) goto err ;
if ( ! asn1_write ( data , r - > oid , strlen ( r - > oid ) ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2006-02-15 18:19:10 +03:00
}
if ( r - > value ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT_SIMPLE ( 11 ) ) ) goto err ;
if ( ! asn1_write ( data , r - > value - > data , r - > value - > length ) ) goto err ;
if ( ! asn1_pop_tag ( data ) ) goto err ;
2006-02-15 18:19:10 +03:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
2004-08-12 08:55:59 +04:00
break ;
}
default :
2014-09-23 03:08:26 +04:00
goto err ;
2004-08-12 08:55:59 +04:00
}
2006-01-06 07:01:23 +03:00
if ( msg - > controls ! = NULL ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_push_tag ( data , ASN1_CONTEXT ( 0 ) ) ) goto err ;
2006-01-06 07:01:23 +03:00
for ( i = 0 ; msg - > controls [ i ] ! = NULL ; i + + ) {
2009-02-24 18:49:26 +03:00
if ( ! ldap_encode_control ( mem_ctx , data ,
control_handlers ,
msg - > controls [ i ] ) ) {
2012-05-15 21:10:16 +04:00
DEBUG ( 0 , ( " Unable to encode control %s \n " ,
2009-12-16 06:57:32 +03:00
msg - > controls [ i ] - > oid ) ) ;
2014-09-23 03:08:26 +04:00
goto err ;
2006-01-06 07:01:23 +03:00
}
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
2006-01-06 07:01:23 +03:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_pop_tag ( data ) ) goto err ;
2005-06-18 16:45:28 +04:00
2016-01-02 22:10:53 +03:00
if ( ! asn1_extract_blob ( data , mem_ctx , result ) ) {
goto err ;
}
2007-05-21 10:12:06 +04:00
asn1_free ( data ) ;
2014-09-23 03:08:26 +04:00
2007-10-07 02:28:14 +04:00
return true ;
2014-09-23 03:08:26 +04:00
err :
asn1_free ( data ) ;
return false ;
2004-08-12 08:55:59 +04:00
}
static const char * blob2string_talloc ( TALLOC_CTX * mem_ctx ,
DATA_BLOB blob )
{
2007-09-07 19:08:14 +04:00
char * result = talloc_array ( mem_ctx , char , blob . length + 1 ) ;
2015-06-16 01:49:07 +03:00
if ( result = = NULL ) {
return NULL ;
}
2004-08-12 08:55:59 +04:00
memcpy ( result , blob . data , blob . length ) ;
result [ blob . length ] = ' \0 ' ;
return result ;
}
2008-12-16 10:27:51 +03:00
bool asn1_read_OctetString_talloc ( TALLOC_CTX * mem_ctx ,
struct asn1_data * data ,
const char * * result )
2004-08-12 08:55:59 +04:00
{
DATA_BLOB string ;
2007-05-21 10:12:06 +04:00
if ( ! asn1_read_OctetString ( data , mem_ctx , & string ) )
2007-10-07 02:28:14 +04:00
return false ;
2004-08-12 08:55:59 +04:00
* result = blob2string_talloc ( mem_ctx , string ) ;
data_blob_free ( & string ) ;
2015-06-16 01:49:07 +03:00
return * result ? true : false ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
static bool ldap_decode_response ( TALLOC_CTX * mem_ctx ,
2004-11-02 09:42:15 +03:00
struct asn1_data * data ,
2004-08-12 08:55:59 +04:00
struct ldap_Result * result )
{
2014-09-23 03:08:26 +04:00
if ( ! asn1_read_enumerated ( data , & result - > resultcode ) ) return false ;
if ( ! asn1_read_OctetString_talloc ( mem_ctx , data , & result - > dn ) ) return false ;
if ( ! asn1_read_OctetString_talloc ( mem_ctx , data , & result - > errormessage ) ) return false ;
2004-08-17 15:22:44 +04:00
if ( asn1_peek_tag ( data , ASN1_CONTEXT ( 3 ) ) ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT ( 3 ) ) ) return false ;
if ( ! asn1_read_OctetString_talloc ( mem_ctx , data , & result - > referral ) ) return false ;
if ( ! asn1_end_tag ( data ) ) return false ;
2004-08-13 10:27:02 +04:00
} else {
2004-08-17 15:22:44 +04:00
result - > referral = NULL ;
2004-08-13 10:27:02 +04:00
}
2014-09-23 03:08:26 +04:00
return true ;
2004-08-13 10:27:02 +04:00
}
2005-07-17 18:16:41 +04:00
static struct ldb_val * * ldap_decode_substring ( TALLOC_CTX * mem_ctx , struct ldb_val * * chunks , int chunk_num , char * value )
{
chunks = talloc_realloc ( mem_ctx , chunks , struct ldb_val * , chunk_num + 2 ) ;
if ( chunks = = NULL ) {
return NULL ;
}
chunks [ chunk_num ] = talloc ( mem_ctx , struct ldb_val ) ;
if ( chunks [ chunk_num ] = = NULL ) {
return NULL ;
}
2005-10-12 10:10:23 +04:00
chunks [ chunk_num ] - > data = ( uint8_t * ) talloc_strdup ( mem_ctx , value ) ;
2005-07-17 18:16:41 +04:00
if ( chunks [ chunk_num ] - > data = = NULL ) {
return NULL ;
}
2006-06-07 08:23:42 +04:00
chunks [ chunk_num ] - > length = strlen ( value ) ;
2005-07-17 18:16:41 +04:00
2015-10-12 23:10:51 +03:00
chunks [ chunk_num + 1 ] = NULL ;
2005-07-17 18:16:41 +04:00
return chunks ;
}
2005-06-13 13:10:17 +04:00
/*
parse the ASN .1 formatted search string into a ldb_parse_tree
*/
2005-06-13 11:36:52 +04:00
static struct ldb_parse_tree * ldap_decode_filter_tree ( TALLOC_CTX * mem_ctx ,
struct asn1_data * data )
2004-08-12 08:55:59 +04:00
{
2005-06-18 16:45:28 +04:00
uint8_t filter_tag ;
2005-06-13 11:36:52 +04:00
struct ldb_parse_tree * ret ;
2005-05-10 05:57:47 +04:00
2005-06-13 11:36:52 +04:00
if ( ! asn1_peek_uint8 ( data , & filter_tag ) ) {
return NULL ;
}
2004-08-12 08:55:59 +04:00
filter_tag & = 0x1f ; /* strip off the asn1 stuff */
2005-06-13 11:36:52 +04:00
ret = talloc ( mem_ctx , struct ldb_parse_tree ) ;
if ( ret = = NULL ) return NULL ;
2004-08-12 08:55:59 +04:00
2005-06-13 11:36:52 +04:00
switch ( filter_tag ) {
case 0 :
case 1 :
/* AND or OR of one or more filters */
ret - > operation = ( filter_tag = = 0 ) ? LDB_OP_AND : LDB_OP_OR ;
ret - > u . list . num_elements = 0 ;
ret - > u . list . elements = NULL ;
if ( ! asn1_start_tag ( data , ASN1_CONTEXT ( filter_tag ) ) ) {
goto failed ;
}
2004-08-12 08:55:59 +04:00
while ( asn1_tag_remaining ( data ) > 0 ) {
2005-06-13 11:36:52 +04:00
struct ldb_parse_tree * subtree ;
subtree = ldap_decode_filter_tree ( ret , data ) ;
if ( subtree = = NULL ) {
goto failed ;
}
ret - > u . list . elements =
talloc_realloc ( ret , ret - > u . list . elements ,
struct ldb_parse_tree * ,
ret - > u . list . num_elements + 1 ) ;
if ( ret - > u . list . elements = = NULL ) {
goto failed ;
}
talloc_steal ( ret - > u . list . elements , subtree ) ;
ret - > u . list . elements [ ret - > u . list . num_elements ] = subtree ;
ret - > u . list . num_elements + + ;
}
if ( ! asn1_end_tag ( data ) ) {
goto failed ;
2004-08-12 08:55:59 +04:00
}
break ;
2005-06-13 11:36:52 +04:00
2005-06-14 07:53:35 +04:00
case 2 :
/* 'not' operation */
if ( ! asn1_start_tag ( data , ASN1_CONTEXT ( filter_tag ) ) ) {
goto failed ;
}
2005-06-13 10:06:29 +04:00
2005-06-14 07:53:35 +04:00
ret - > operation = LDB_OP_NOT ;
2005-07-13 09:55:28 +04:00
ret - > u . isnot . child = ldap_decode_filter_tree ( ret , data ) ;
if ( ret - > u . isnot . child = = NULL ) {
2005-06-19 14:37:45 +04:00
goto failed ;
}
2005-06-14 07:53:35 +04:00
if ( ! asn1_end_tag ( data ) ) {
2005-06-13 11:36:52 +04:00
goto failed ;
}
2005-06-14 07:53:35 +04:00
break ;
2005-06-13 11:36:52 +04:00
2005-06-14 07:53:35 +04:00
case 3 : {
/* equalityMatch */
const char * attrib ;
DATA_BLOB value ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT ( filter_tag ) ) ) goto failed ;
if ( ! asn1_read_OctetString_talloc ( mem_ctx , data , & attrib ) ) goto failed ;
if ( ! asn1_read_OctetString ( data , mem_ctx , & value ) ) goto failed ;
if ( ! asn1_end_tag ( data ) ) goto failed ;
2016-01-02 20:11:00 +03:00
if ( asn1_has_error ( data ) | | ( attrib = = NULL ) | |
( value . data = = NULL ) ) {
2005-06-13 11:36:52 +04:00
goto failed ;
}
2005-06-14 07:53:35 +04:00
2005-07-19 13:09:00 +04:00
ret - > operation = LDB_OP_EQUALITY ;
ret - > u . equality . attr = talloc_steal ( ret , attrib ) ;
ret - > u . equality . value . data = talloc_steal ( ret , value . data ) ;
ret - > u . equality . value . length = value . length ;
2004-08-12 08:55:59 +04:00
break ;
}
2005-07-17 18:16:41 +04:00
case 4 : {
/* substrings */
DATA_BLOB attr ;
uint8_t subs_tag ;
char * value ;
int chunk_num = 0 ;
if ( ! asn1_start_tag ( data , ASN1_CONTEXT ( filter_tag ) ) ) {
goto failed ;
}
2007-05-21 10:12:06 +04:00
if ( ! asn1_read_OctetString ( data , mem_ctx , & attr ) ) {
2005-07-17 18:16:41 +04:00
goto failed ;
}
ret - > operation = LDB_OP_SUBSTRING ;
2005-10-12 10:10:23 +04:00
ret - > u . substring . attr = talloc_strndup ( ret , ( char * ) attr . data , attr . length ) ;
2015-06-16 01:49:07 +03:00
if ( ret - > u . substring . attr = = NULL ) {
goto failed ;
}
2005-07-17 18:16:41 +04:00
ret - > u . substring . chunks = NULL ;
ret - > u . substring . start_with_wildcard = 1 ;
ret - > u . substring . end_with_wildcard = 1 ;
if ( ! asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) {
goto failed ;
}
2016-01-11 23:49:21 +03:00
while ( asn1_tag_remaining ( data ) > 0 ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_peek_uint8 ( data , & subs_tag ) ) goto failed ;
2005-07-17 18:16:41 +04:00
subs_tag & = 0x1f ; /* strip off the asn1 stuff */
if ( subs_tag > 2 ) goto failed ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT_SIMPLE ( subs_tag ) ) ) goto failed ;
if ( ! asn1_read_LDAPString ( data , mem_ctx , & value ) ) goto failed ;
if ( ! asn1_end_tag ( data ) ) goto failed ;
2005-07-17 18:16:41 +04:00
switch ( subs_tag ) {
case 0 :
if ( ret - > u . substring . chunks ! = NULL ) {
/* initial value found in the middle */
goto failed ;
}
ret - > u . substring . chunks = ldap_decode_substring ( ret , NULL , 0 , value ) ;
if ( ret - > u . substring . chunks = = NULL ) {
goto failed ;
}
ret - > u . substring . start_with_wildcard = 0 ;
chunk_num = 1 ;
break ;
case 1 :
if ( ret - > u . substring . end_with_wildcard = = 0 ) {
/* "any" value found after a "final" value */
goto failed ;
}
ret - > u . substring . chunks = ldap_decode_substring ( ret ,
ret - > u . substring . chunks ,
chunk_num ,
value ) ;
if ( ret - > u . substring . chunks = = NULL ) {
goto failed ;
}
chunk_num + + ;
break ;
case 2 :
ret - > u . substring . chunks = ldap_decode_substring ( ret ,
ret - > u . substring . chunks ,
chunk_num ,
value ) ;
if ( ret - > u . substring . chunks = = NULL ) {
goto failed ;
}
ret - > u . substring . end_with_wildcard = 0 ;
break ;
default :
goto failed ;
}
}
if ( ! asn1_end_tag ( data ) ) { /* SEQUENCE */
goto failed ;
}
if ( ! asn1_end_tag ( data ) ) {
goto failed ;
}
break ;
}
2005-07-19 13:09:00 +04:00
case 5 : {
/* greaterOrEqual */
const char * attrib ;
DATA_BLOB value ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT ( filter_tag ) ) ) goto failed ;
if ( ! asn1_read_OctetString_talloc ( mem_ctx , data , & attrib ) ) goto failed ;
if ( ! asn1_read_OctetString ( data , mem_ctx , & value ) ) goto failed ;
if ( ! asn1_end_tag ( data ) ) goto failed ;
2016-01-02 20:11:00 +03:00
if ( asn1_has_error ( data ) | | ( attrib = = NULL ) | |
( value . data = = NULL ) ) {
2005-07-19 13:09:00 +04:00
goto failed ;
}
ret - > operation = LDB_OP_GREATER ;
ret - > u . comparison . attr = talloc_steal ( ret , attrib ) ;
ret - > u . comparison . value . data = talloc_steal ( ret , value . data ) ;
ret - > u . comparison . value . length = value . length ;
break ;
}
case 6 : {
/* lessOrEqual */
const char * attrib ;
DATA_BLOB value ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT ( filter_tag ) ) ) goto failed ;
if ( ! asn1_read_OctetString_talloc ( mem_ctx , data , & attrib ) ) goto failed ;
if ( ! asn1_read_OctetString ( data , mem_ctx , & value ) ) goto failed ;
if ( ! asn1_end_tag ( data ) ) goto failed ;
2016-01-02 20:11:00 +03:00
if ( asn1_has_error ( data ) | | ( attrib = = NULL ) | |
( value . data = = NULL ) ) {
2005-07-19 13:09:00 +04:00
goto failed ;
}
ret - > operation = LDB_OP_LESS ;
ret - > u . comparison . attr = talloc_steal ( ret , attrib ) ;
ret - > u . comparison . value . data = talloc_steal ( ret , value . data ) ;
ret - > u . comparison . value . length = value . length ;
break ;
}
2004-08-12 08:55:59 +04:00
case 7 : {
/* Normal presence, "attribute=*" */
2005-06-14 07:53:35 +04:00
char * attr ;
if ( ! asn1_start_tag ( data , ASN1_CONTEXT_SIMPLE ( filter_tag ) ) ) {
2005-06-13 11:36:52 +04:00
goto failed ;
}
2007-05-21 10:12:06 +04:00
if ( ! asn1_read_LDAPString ( data , ret , & attr ) ) {
2005-06-13 11:36:52 +04:00
goto failed ;
}
2005-07-17 18:16:41 +04:00
ret - > operation = LDB_OP_PRESENT ;
ret - > u . present . attr = talloc_steal ( ret , attr ) ;
2005-06-14 07:53:35 +04:00
if ( ! asn1_end_tag ( data ) ) {
2005-06-13 11:36:52 +04:00
goto failed ;
}
2005-06-14 07:53:35 +04:00
break ;
}
2005-07-19 13:09:00 +04:00
case 8 : {
/* approx */
const char * attrib ;
DATA_BLOB value ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT ( filter_tag ) ) ) goto failed ;
if ( ! asn1_read_OctetString_talloc ( mem_ctx , data , & attrib ) ) goto failed ;
if ( ! asn1_read_OctetString ( data , mem_ctx , & value ) ) goto failed ;
if ( ! asn1_end_tag ( data ) ) goto failed ;
2016-01-02 20:11:00 +03:00
if ( asn1_has_error ( data ) | | ( attrib = = NULL ) | |
( value . data = = NULL ) ) {
2005-07-19 13:09:00 +04:00
goto failed ;
}
ret - > operation = LDB_OP_APPROX ;
ret - > u . comparison . attr = talloc_steal ( ret , attrib ) ;
ret - > u . comparison . value . data = talloc_steal ( ret , value . data ) ;
ret - > u . comparison . value . length = value . length ;
break ;
}
2005-06-14 07:53:35 +04:00
case 9 : {
2005-08-02 18:04:22 +04:00
char * oid = NULL , * attr = NULL , * value ;
2005-06-14 07:53:35 +04:00
uint8_t dnAttributes ;
/* an extended search */
if ( ! asn1_start_tag ( data , ASN1_CONTEXT ( filter_tag ) ) ) {
2005-06-13 11:36:52 +04:00
goto failed ;
}
2005-06-14 07:53:35 +04:00
2005-08-02 18:04:22 +04:00
/* FIXME: read carefully rfc2251.txt there are a number of 'MUST's
we need to check we properly implement - - SSS */
/* either oid or type must be defined */
if ( asn1_peek_tag ( data , ASN1_CONTEXT_SIMPLE ( 1 ) ) ) { /* optional */
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT_SIMPLE ( 1 ) ) ) goto failed ;
if ( ! asn1_read_LDAPString ( data , ret , & oid ) ) goto failed ;
if ( ! asn1_end_tag ( data ) ) goto failed ;
2005-08-02 18:04:22 +04:00
}
if ( asn1_peek_tag ( data , ASN1_CONTEXT_SIMPLE ( 2 ) ) ) { /* optional */
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT_SIMPLE ( 2 ) ) ) goto failed ;
if ( ! asn1_read_LDAPString ( data , ret , & attr ) ) goto failed ;
if ( ! asn1_end_tag ( data ) ) goto failed ;
2005-08-02 18:04:22 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT_SIMPLE ( 3 ) ) ) goto failed ;
if ( ! asn1_read_LDAPString ( data , ret , & value ) ) goto failed ;
if ( ! asn1_end_tag ( data ) ) goto failed ;
2005-08-02 18:04:22 +04:00
/* dnAttributes is marked as BOOLEAN DEFAULT FALSE
it is not marked as OPTIONAL but openldap tools
do not set this unless it is to be set as TRUE
NOTE : openldap tools do not work with AD as it
seems that AD always requires the dnAttributes
boolean value to be set */
if ( asn1_peek_tag ( data , ASN1_CONTEXT_SIMPLE ( 4 ) ) ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT_SIMPLE ( 4 ) ) ) goto failed ;
if ( ! asn1_read_uint8 ( data , & dnAttributes ) ) goto failed ;
if ( ! asn1_end_tag ( data ) ) goto failed ;
2005-08-02 18:04:22 +04:00
} else {
dnAttributes = 0 ;
}
if ( ( oid = = NULL & & attr = = NULL ) | | ( value = = NULL ) ) {
2005-06-14 07:53:35 +04:00
goto failed ;
}
2005-08-02 18:04:22 +04:00
if ( oid ) {
ret - > operation = LDB_OP_EXTENDED ;
2005-06-14 07:53:35 +04:00
2005-08-02 18:04:22 +04:00
/* From the RFC2251: If the type field is
absent and matchingRule is present , the matchValue is compared
against all attributes in an entry which support that matchingRule
*/
if ( attr ) {
ret - > u . extended . attr = talloc_steal ( ret , attr ) ;
} else {
ret - > u . extended . attr = talloc_strdup ( ret , " * " ) ;
2015-06-16 01:49:07 +03:00
if ( ret - > u . extended . attr = = NULL ) {
goto failed ;
}
2005-08-02 18:04:22 +04:00
}
ret - > u . extended . rule_id = talloc_steal ( ret , oid ) ;
2009-02-24 14:29:59 +03:00
ret - > u . extended . value . data = ( uint8_t * ) talloc_steal ( ret , value ) ;
2005-08-02 18:04:22 +04:00
ret - > u . extended . value . length = strlen ( value ) ;
ret - > u . extended . dnAttributes = dnAttributes ;
} else {
ret - > operation = LDB_OP_EQUALITY ;
ret - > u . equality . attr = talloc_steal ( ret , attr ) ;
2009-02-24 14:29:59 +03:00
ret - > u . equality . value . data = ( uint8_t * ) talloc_steal ( ret , value ) ;
2005-08-02 18:04:22 +04:00
ret - > u . equality . value . length = strlen ( value ) ;
}
2005-06-13 11:36:52 +04:00
if ( ! asn1_end_tag ( data ) ) {
goto failed ;
}
2004-08-12 08:55:59 +04:00
break ;
}
2005-06-14 07:53:35 +04:00
2004-08-12 08:55:59 +04:00
default :
2005-06-13 11:36:52 +04:00
goto failed ;
2004-08-12 08:55:59 +04:00
}
2005-06-13 11:36:52 +04:00
return ret ;
failed :
talloc_free ( ret ) ;
return NULL ;
}
2005-05-10 05:57:47 +04:00
2008-12-16 10:27:51 +03:00
/* Decode a single LDAP attribute, possibly containing multiple values */
2014-09-23 03:08:26 +04:00
static bool ldap_decode_attrib ( TALLOC_CTX * mem_ctx , struct asn1_data * data ,
2005-06-15 05:02:53 +04:00
struct ldb_message_element * attrib )
2004-08-12 08:55:59 +04:00
{
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) return false ;
if ( ! asn1_read_OctetString_talloc ( mem_ctx , data , & attrib - > name ) ) return false ;
if ( ! asn1_start_tag ( data , ASN1_SET ) ) return false ;
2004-08-12 08:55:59 +04:00
while ( asn1_peek_tag ( data , ASN1_OCTET_STRING ) ) {
DATA_BLOB blob ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_read_OctetString ( data , mem_ctx , & blob ) ) return false ;
2005-06-15 05:12:31 +04:00
add_value_to_attrib ( mem_ctx , & blob , attrib ) ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) return false ;
return asn1_end_tag ( data ) ;
2004-08-12 08:55:59 +04:00
}
2008-12-16 10:27:51 +03:00
/* Decode a set of LDAP attributes, as found in the dereference control */
2014-09-23 03:08:26 +04:00
bool ldap_decode_attribs_bare ( TALLOC_CTX * mem_ctx , struct asn1_data * data ,
2008-12-16 10:27:51 +03:00
struct ldb_message_element * * attributes ,
int * num_attributes )
2004-08-12 08:55:59 +04:00
{
while ( asn1_peek_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) {
2005-06-15 05:02:53 +04:00
struct ldb_message_element attrib ;
2004-08-12 08:55:59 +04:00
ZERO_STRUCT ( attrib ) ;
2014-09-23 03:08:26 +04:00
if ( ! ldap_decode_attrib ( mem_ctx , data , & attrib ) ) return false ;
2004-08-12 08:55:59 +04:00
add_attrib_to_array_talloc ( mem_ctx , & attrib ,
attributes , num_attributes ) ;
}
2014-09-23 03:08:26 +04:00
return true ;
2008-12-16 10:27:51 +03:00
}
/* Decode a set of LDAP attributes, as found in a search entry */
2014-09-23 03:08:26 +04:00
static bool ldap_decode_attribs ( TALLOC_CTX * mem_ctx , struct asn1_data * data ,
2009-02-24 13:40:18 +03:00
struct ldb_message_element * * attributes ,
int * num_attributes )
2008-12-16 10:27:51 +03:00
{
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) return false ;
if ( ! ldap_decode_attribs_bare ( mem_ctx , data ,
attributes , num_attributes ) ) return false ;
return asn1_end_tag ( data ) ;
2004-08-12 08:55:59 +04:00
}
2007-03-13 03:59:06 +03:00
/* This routine returns LDAP status codes */
2009-02-24 18:49:26 +03:00
_PUBLIC_ NTSTATUS ldap_decode ( struct asn1_data * data ,
2020-04-07 23:49:23 +03:00
const struct ldap_request_limits * limits ,
2009-02-24 18:49:26 +03:00
const struct ldap_control_handler * control_handlers ,
struct ldap_message * msg )
2004-08-12 08:55:59 +04:00
{
2005-02-10 08:09:35 +03:00
uint8_t tag ;
2004-08-12 08:55:59 +04:00
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto prot_err ;
if ( ! asn1_read_Integer ( data , & msg - > messageid ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
2014-09-23 03:08:26 +04:00
if ( ! asn1_peek_uint8 ( data , & tag ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
switch ( tag ) {
case ASN1_APPLICATION ( LDAP_TAG_BindRequest ) : {
struct ldap_BindRequest * r = & msg - > r . BindRequest ;
msg - > type = LDAP_TAG_BindRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! asn1_read_Integer ( data , & r - > version ) ) goto prot_err ;
if ( ! asn1_read_OctetString_talloc ( msg , data , & r - > dn ) ) goto prot_err ;
2004-10-08 16:08:43 +04:00
if ( asn1_peek_tag ( data , ASN1_CONTEXT_SIMPLE ( 0 ) ) ) {
2004-08-12 08:55:59 +04:00
int pwlen ;
r - > creds . password = " " ;
2004-10-08 16:08:43 +04:00
r - > mechanism = LDAP_AUTH_MECH_SIMPLE ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT_SIMPLE ( 0 ) ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
pwlen = asn1_tag_remaining ( data ) ;
2006-09-29 08:45:15 +04:00
if ( pwlen = = - 1 ) {
2014-09-23 03:08:26 +04:00
goto prot_err ;
2006-09-29 08:45:15 +04:00
}
2004-08-12 08:55:59 +04:00
if ( pwlen ! = 0 ) {
2007-09-07 19:08:14 +04:00
char * pw = talloc_array ( msg , char , pwlen + 1 ) ;
2006-09-29 08:45:15 +04:00
if ( ! pw ) {
2007-03-13 03:59:06 +03:00
return NT_STATUS_LDAP ( LDAP_OPERATIONS_ERROR ) ;
2006-09-29 08:45:15 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_read ( data , pw , pwlen ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
pw [ pwlen ] = ' \0 ' ;
r - > creds . password = pw ;
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-10-08 16:08:43 +04:00
} else if ( asn1_peek_tag ( data , ASN1_CONTEXT ( 3 ) ) ) {
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT ( 3 ) ) ) goto prot_err ;
2004-10-08 16:08:43 +04:00
r - > mechanism = LDAP_AUTH_MECH_SASL ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_read_OctetString_talloc ( msg , data , & r - > creds . SASL . mechanism ) ) goto prot_err ;
2005-11-05 14:24:10 +03:00
if ( asn1_peek_tag ( data , ASN1_OCTET_STRING ) ) { /* optional */
2006-02-15 18:19:10 +03:00
DATA_BLOB tmp_blob = data_blob ( NULL , 0 ) ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_read_OctetString ( data , msg , & tmp_blob ) ) goto prot_err ;
2006-02-15 18:19:10 +03:00
r - > creds . SASL . secblob = talloc ( msg , DATA_BLOB ) ;
if ( ! r - > creds . SASL . secblob ) {
2007-03-13 03:59:06 +03:00
return NT_STATUS_LDAP ( LDAP_OPERATIONS_ERROR ) ;
2005-11-05 14:24:10 +03:00
}
2006-02-15 18:19:10 +03:00
* r - > creds . SASL . secblob = data_blob_talloc ( r - > creds . SASL . secblob ,
tmp_blob . data , tmp_blob . length ) ;
data_blob_free ( & tmp_blob ) ;
2005-11-05 14:24:10 +03:00
} else {
2006-02-15 18:19:10 +03:00
r - > creds . SASL . secblob = NULL ;
2004-10-08 16:08:43 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2006-09-29 08:45:15 +04:00
} else {
/* Neither Simple nor SASL bind */
2014-09-23 03:08:26 +04:00
goto prot_err ;
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_BindResponse ) : {
struct ldap_BindResponse * r = & msg - > r . BindResponse ;
msg - > type = LDAP_TAG_BindResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! ldap_decode_response ( msg , data , & r - > response ) ) goto prot_err ;
2004-08-17 15:22:44 +04:00
if ( asn1_peek_tag ( data , ASN1_CONTEXT_SIMPLE ( 7 ) ) ) {
DATA_BLOB tmp_blob = data_blob ( NULL , 0 ) ;
2015-12-30 02:07:35 +03:00
if ( ! asn1_read_ContextSimple ( data , msg , 7 , & tmp_blob ) ) goto prot_err ;
2006-02-15 18:19:10 +03:00
r - > SASL . secblob = talloc ( msg , DATA_BLOB ) ;
if ( ! r - > SASL . secblob ) {
2007-03-13 03:59:06 +03:00
return NT_STATUS_LDAP ( LDAP_OPERATIONS_ERROR ) ;
2006-02-15 18:19:10 +03:00
}
* r - > SASL . secblob = data_blob_talloc ( r - > SASL . secblob ,
tmp_blob . data , tmp_blob . length ) ;
2004-08-17 15:22:44 +04:00
data_blob_free ( & tmp_blob ) ;
} else {
2006-02-15 18:19:10 +03:00
r - > SASL . secblob = NULL ;
2004-08-17 15:22:44 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
2004-09-22 14:42:58 +04:00
case ASN1_APPLICATION_SIMPLE ( LDAP_TAG_UnbindRequest ) : {
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_UnbindRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_SearchRequest ) : {
struct ldap_SearchRequest * r = & msg - > r . SearchRequest ;
2009-02-24 14:29:59 +03:00
int sizelimit , timelimit ;
const char * * attrs = NULL ;
2020-04-08 01:46:44 +03:00
size_t request_size = asn1_get_length ( data ) ;
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_SearchRequest ;
2020-04-08 01:46:44 +03:00
if ( request_size > limits - > max_search_size ) {
goto prot_err ;
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! asn1_read_OctetString_talloc ( msg , data , & r - > basedn ) ) goto prot_err ;
if ( ! asn1_read_enumerated ( data , ( int * ) ( void * ) & ( r - > scope ) ) ) goto prot_err ;
if ( ! asn1_read_enumerated ( data , ( int * ) ( void * ) & ( r - > deref ) ) ) goto prot_err ;
if ( ! asn1_read_Integer ( data , & sizelimit ) ) goto prot_err ;
2009-02-24 14:29:59 +03:00
r - > sizelimit = sizelimit ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_read_Integer ( data , & timelimit ) ) goto prot_err ;
2009-02-24 14:29:59 +03:00
r - > timelimit = timelimit ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_read_BOOLEAN ( data , & r - > attributesonly ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
2005-06-15 04:27:51 +04:00
r - > tree = ldap_decode_filter_tree ( msg , data ) ;
2005-06-13 13:10:17 +04:00
if ( r - > tree = = NULL ) {
2014-09-23 03:08:26 +04:00
goto prot_err ;
2005-06-13 13:10:17 +04:00
}
2004-08-12 08:55:59 +04:00
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
r - > num_attributes = 0 ;
r - > attributes = NULL ;
2014-09-23 03:08:26 +04:00
while ( asn1_tag_remaining ( data ) > 0 ) {
2007-03-13 03:59:06 +03:00
2004-08-12 08:55:59 +04:00
const char * attr ;
2005-06-15 04:27:51 +04:00
if ( ! asn1_read_OctetString_talloc ( msg , data ,
2004-08-12 08:55:59 +04:00
& attr ) )
2014-09-23 03:08:26 +04:00
goto prot_err ;
2005-06-15 04:27:51 +04:00
if ( ! add_string_to_array ( msg , attr ,
2009-02-24 14:29:59 +03:00
& attrs ,
2004-08-12 08:55:59 +04:00
& r - > num_attributes ) )
2014-09-23 03:08:26 +04:00
goto prot_err ;
2004-08-12 08:55:59 +04:00
}
2009-02-24 14:29:59 +03:00
r - > attributes = attrs ;
2004-08-12 08:55:59 +04:00
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_SearchResultEntry ) : {
struct ldap_SearchResEntry * r = & msg - > r . SearchResultEntry ;
msg - > type = LDAP_TAG_SearchResultEntry ;
r - > attributes = NULL ;
r - > num_attributes = 0 ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! asn1_read_OctetString_talloc ( msg , data , & r - > dn ) ) goto prot_err ;
if ( ! ldap_decode_attribs ( msg , data , & r - > attributes ,
& r - > num_attributes ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_SearchResultDone ) : {
2004-08-12 10:37:12 +04:00
struct ldap_Result * r = & msg - > r . SearchResultDone ;
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_SearchResultDone ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! ldap_decode_response ( msg , data , r ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_SearchResultReference ) : {
2004-11-06 23:43:36 +03:00
struct ldap_SearchResRef * r = & msg - > r . SearchResultReference ;
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_SearchResultReference ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! asn1_read_OctetString_talloc ( msg , data , & r - > referral ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_ModifyRequest ) : {
struct ldap_ModifyRequest * r = & msg - > r . ModifyRequest ;
msg - > type = LDAP_TAG_ModifyRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_APPLICATION ( LDAP_TAG_ModifyRequest ) ) ) goto prot_err ;
if ( ! asn1_read_OctetString_talloc ( msg , data , & r - > dn ) ) goto prot_err ;
if ( ! asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
r - > num_mods = 0 ;
r - > mods = NULL ;
while ( asn1_tag_remaining ( data ) > 0 ) {
struct ldap_mod mod ;
2004-11-02 14:16:34 +03:00
int v ;
2004-08-12 08:55:59 +04:00
ZERO_STRUCT ( mod ) ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto prot_err ;
if ( ! asn1_read_enumerated ( data , & v ) ) goto prot_err ;
2004-11-02 14:16:34 +03:00
mod . type = v ;
2014-09-23 03:08:26 +04:00
if ( ! ldap_decode_attrib ( msg , data , & mod . attrib ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2005-06-15 04:27:51 +04:00
if ( ! add_mod_to_array_talloc ( msg , & mod ,
2006-09-29 08:45:15 +04:00
& r - > mods , & r - > num_mods ) ) {
2007-03-13 03:59:06 +03:00
return NT_STATUS_LDAP ( LDAP_OPERATIONS_ERROR ) ;
2006-09-29 08:45:15 +04:00
}
2004-08-12 08:55:59 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_ModifyResponse ) : {
2004-08-12 10:37:12 +04:00
struct ldap_Result * r = & msg - > r . ModifyResponse ;
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_ModifyResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! ldap_decode_response ( msg , data , r ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_AddRequest ) : {
struct ldap_AddRequest * r = & msg - > r . AddRequest ;
msg - > type = LDAP_TAG_AddRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! asn1_read_OctetString_talloc ( msg , data , & r - > dn ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
r - > attributes = NULL ;
r - > num_attributes = 0 ;
2014-09-23 03:08:26 +04:00
if ( ! ldap_decode_attribs ( msg , data , & r - > attributes ,
& r - > num_attributes ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_AddResponse ) : {
2004-08-12 10:37:12 +04:00
struct ldap_Result * r = & msg - > r . AddResponse ;
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_AddResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! ldap_decode_response ( msg , data , r ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
2004-09-27 19:40:12 +04:00
case ASN1_APPLICATION_SIMPLE ( LDAP_TAG_DelRequest ) : {
struct ldap_DelRequest * r = & msg - > r . DelRequest ;
2004-08-12 08:55:59 +04:00
int len ;
char * dn ;
2004-09-27 19:40:12 +04:00
msg - > type = LDAP_TAG_DelRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data ,
ASN1_APPLICATION_SIMPLE ( LDAP_TAG_DelRequest ) ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
len = asn1_tag_remaining ( data ) ;
2006-09-29 08:45:15 +04:00
if ( len = = - 1 ) {
2014-09-23 03:08:26 +04:00
goto prot_err ;
2006-09-29 08:45:15 +04:00
}
2007-09-07 19:08:14 +04:00
dn = talloc_array ( msg , char , len + 1 ) ;
2004-08-12 08:55:59 +04:00
if ( dn = = NULL )
break ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_read ( data , dn , len ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
dn [ len ] = ' \0 ' ;
r - > dn = dn ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
2004-09-27 19:40:12 +04:00
case ASN1_APPLICATION ( LDAP_TAG_DelResponse ) : {
struct ldap_Result * r = & msg - > r . DelResponse ;
msg - > type = LDAP_TAG_DelResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! ldap_decode_response ( msg , data , r ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_ModifyDNRequest ) : {
2004-08-17 15:22:44 +04:00
struct ldap_ModifyDNRequest * r = & msg - > r . ModifyDNRequest ;
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_ModifyDNRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data ,
ASN1_APPLICATION ( LDAP_TAG_ModifyDNRequest ) ) ) goto prot_err ;
if ( ! asn1_read_OctetString_talloc ( msg , data , & r - > dn ) ) goto prot_err ;
if ( ! asn1_read_OctetString_talloc ( msg , data , & r - > newrdn ) ) goto prot_err ;
if ( ! asn1_read_BOOLEAN ( data , & r - > deleteolddn ) ) goto prot_err ;
2004-08-17 15:22:44 +04:00
r - > newsuperior = NULL ;
if ( asn1_tag_remaining ( data ) > 0 ) {
int len ;
char * newsup ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT_SIMPLE ( 0 ) ) ) goto prot_err ;
2004-08-17 15:22:44 +04:00
len = asn1_tag_remaining ( data ) ;
2006-09-29 08:45:15 +04:00
if ( len = = - 1 ) {
2014-09-23 03:08:26 +04:00
goto prot_err ;
2006-09-29 08:45:15 +04:00
}
2007-09-07 19:08:14 +04:00
newsup = talloc_array ( msg , char , len + 1 ) ;
2006-09-29 08:45:15 +04:00
if ( newsup = = NULL ) {
2007-03-13 03:59:06 +03:00
return NT_STATUS_LDAP ( LDAP_OPERATIONS_ERROR ) ;
2006-09-29 08:45:15 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_read ( data , newsup , len ) ) goto prot_err ;
2004-08-17 15:22:44 +04:00
newsup [ len ] = ' \0 ' ;
r - > newsuperior = newsup ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-17 15:22:44 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_ModifyDNResponse ) : {
2004-08-12 10:37:12 +04:00
struct ldap_Result * r = & msg - > r . ModifyDNResponse ;
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_ModifyDNResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! ldap_decode_response ( msg , data , r ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_CompareRequest ) : {
2004-09-29 16:18:06 +04:00
struct ldap_CompareRequest * r = & msg - > r . CompareRequest ;
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_CompareRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data ,
ASN1_APPLICATION ( LDAP_TAG_CompareRequest ) ) ) goto prot_err ;
if ( ! asn1_read_OctetString_talloc ( msg , data , & r - > dn ) ) goto prot_err ;
if ( ! asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) goto prot_err ;
if ( ! asn1_read_OctetString_talloc ( msg , data , & r - > attribute ) ) goto prot_err ;
if ( ! asn1_read_OctetString ( data , msg , & r - > value ) ) goto prot_err ;
2004-09-29 16:18:06 +04:00
if ( r - > value . data ) {
2005-06-15 04:27:51 +04:00
talloc_steal ( msg , r - > value . data ) ;
2004-09-29 16:18:06 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_CompareResponse ) : {
2004-08-12 10:37:12 +04:00
struct ldap_Result * r = & msg - > r . CompareResponse ;
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_CompareResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! ldap_decode_response ( msg , data , r ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
2004-09-29 17:06:26 +04:00
case ASN1_APPLICATION_SIMPLE ( LDAP_TAG_AbandonRequest ) : {
struct ldap_AbandonRequest * r = & msg - > r . AbandonRequest ;
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_AbandonRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! asn1_read_implicit_Integer ( data , & r - > messageid ) ) goto prot_err ;
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_ExtendedRequest ) : {
2004-09-22 14:42:58 +04:00
struct ldap_ExtendedRequest * r = & msg - > r . ExtendedRequest ;
DATA_BLOB tmp_blob = data_blob ( NULL , 0 ) ;
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_ExtendedRequest ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
2015-12-30 02:07:35 +03:00
if ( ! asn1_read_ContextSimple ( data , msg , 0 , & tmp_blob ) ) {
2014-09-23 03:08:26 +04:00
goto prot_err ;
2004-09-22 14:42:58 +04:00
}
2005-06-15 04:27:51 +04:00
r - > oid = blob2string_talloc ( msg , tmp_blob ) ;
2004-09-22 14:42:58 +04:00
data_blob_free ( & tmp_blob ) ;
if ( ! r - > oid ) {
2007-03-13 03:59:06 +03:00
return NT_STATUS_LDAP ( LDAP_OPERATIONS_ERROR ) ;
2004-09-22 14:42:58 +04:00
}
if ( asn1_peek_tag ( data , ASN1_CONTEXT_SIMPLE ( 1 ) ) ) {
2015-12-30 02:07:35 +03:00
if ( ! asn1_read_ContextSimple ( data , msg , 1 , & tmp_blob ) ) goto prot_err ;
2006-02-15 18:19:10 +03:00
r - > value = talloc ( msg , DATA_BLOB ) ;
if ( ! r - > value ) {
2007-03-13 03:59:06 +03:00
return NT_STATUS_LDAP ( LDAP_OPERATIONS_ERROR ) ;
2006-02-15 18:19:10 +03:00
}
* r - > value = data_blob_talloc ( r - > value , tmp_blob . data , tmp_blob . length ) ;
2004-09-22 14:42:58 +04:00
data_blob_free ( & tmp_blob ) ;
} else {
2006-02-15 18:19:10 +03:00
r - > value = NULL ;
2004-09-22 14:42:58 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_ExtendedResponse ) : {
struct ldap_ExtendedResponse * r = & msg - > r . ExtendedResponse ;
2006-02-15 18:19:10 +03:00
DATA_BLOB tmp_blob = data_blob ( NULL , 0 ) ;
2004-08-12 08:55:59 +04:00
msg - > type = LDAP_TAG_ExtendedResponse ;
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , tag ) ) goto prot_err ;
if ( ! ldap_decode_response ( msg , data , & r - > response ) ) goto prot_err ;
2006-02-15 18:19:10 +03:00
if ( asn1_peek_tag ( data , ASN1_CONTEXT_SIMPLE ( 10 ) ) ) {
2020-06-23 20:09:28 +03:00
if ( ! asn1_read_ContextSimple ( data , msg , 10 , & tmp_blob ) )
goto prot_err ;
2006-02-15 18:19:10 +03:00
r - > oid = blob2string_talloc ( msg , tmp_blob ) ;
data_blob_free ( & tmp_blob ) ;
if ( ! r - > oid ) {
2007-03-13 03:59:06 +03:00
return NT_STATUS_LDAP ( LDAP_OPERATIONS_ERROR ) ;
2006-02-15 18:19:10 +03:00
}
} else {
r - > oid = NULL ;
}
if ( asn1_peek_tag ( data , ASN1_CONTEXT_SIMPLE ( 11 ) ) ) {
2020-06-23 20:09:28 +03:00
if ( ! asn1_read_ContextSimple ( data , msg , 11 , & tmp_blob ) )
goto prot_err ;
2006-02-15 18:19:10 +03:00
r - > value = talloc ( msg , DATA_BLOB ) ;
if ( ! r - > value ) {
2007-03-13 03:59:06 +03:00
return NT_STATUS_LDAP ( LDAP_OPERATIONS_ERROR ) ;
2006-02-15 18:19:10 +03:00
}
* r - > value = data_blob_talloc ( r - > value , tmp_blob . data , tmp_blob . length ) ;
data_blob_free ( & tmp_blob ) ;
} else {
r - > value = NULL ;
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-08-12 08:55:59 +04:00
break ;
}
2014-09-23 03:08:26 +04:00
default :
goto prot_err ;
2004-08-12 08:55:59 +04:00
}
2004-10-10 03:59:12 +04:00
msg - > controls = NULL ;
2007-11-29 10:00:04 +03:00
msg - > controls_decoded = NULL ;
2004-10-10 03:59:12 +04:00
if ( asn1_peek_tag ( data , ASN1_CONTEXT ( 0 ) ) ) {
2007-03-13 03:59:06 +03:00
int i = 0 ;
2006-02-22 04:31:35 +03:00
struct ldb_control * * ctrl = NULL ;
2007-11-29 10:00:04 +03:00
bool * decoded = NULL ;
2004-10-10 03:59:12 +04:00
2014-09-23 03:08:26 +04:00
if ( ! asn1_start_tag ( data , ASN1_CONTEXT ( 0 ) ) ) goto prot_err ;
2004-10-10 03:59:12 +04:00
2007-03-13 03:59:06 +03:00
while ( asn1_peek_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) {
DATA_BLOB value ;
2006-01-14 01:48:08 +03:00
/* asn1_start_tag(data, ASN1_SEQUENCE(0)); */
2004-10-10 03:59:12 +04:00
2006-02-22 04:31:35 +03:00
ctrl = talloc_realloc ( msg , ctrl , struct ldb_control * , i + 2 ) ;
2004-10-10 03:59:12 +04:00
if ( ! ctrl ) {
2007-03-13 03:59:06 +03:00
return NT_STATUS_LDAP ( LDAP_OPERATIONS_ERROR ) ;
2004-10-10 03:59:12 +04:00
}
2007-11-29 10:00:04 +03:00
decoded = talloc_realloc ( msg , decoded , bool , i + 1 ) ;
if ( ! decoded ) {
return NT_STATUS_LDAP ( LDAP_OPERATIONS_ERROR ) ;
}
2006-02-22 04:31:35 +03:00
ctrl [ i ] = talloc ( ctrl , struct ldb_control ) ;
2006-01-06 07:01:23 +03:00
if ( ! ctrl [ i ] ) {
2007-03-13 03:59:06 +03:00
return NT_STATUS_LDAP ( LDAP_OPERATIONS_ERROR ) ;
2004-10-10 03:59:12 +04:00
}
2011-02-26 21:07:51 +03:00
if ( ! ldap_decode_control_wrapper ( ctrl [ i ] , data , ctrl [ i ] , & value ) ) {
2014-09-23 03:08:26 +04:00
goto prot_err ;
2007-03-13 03:59:06 +03:00
}
2014-09-23 03:08:26 +04:00
2011-02-26 21:07:51 +03:00
if ( ! ldap_decode_control_value ( ctrl [ i ] , value ,
2009-02-24 18:49:26 +03:00
control_handlers ,
ctrl [ i ] ) ) {
2007-03-13 03:59:06 +03:00
if ( ctrl [ i ] - > critical ) {
2007-11-29 10:00:04 +03:00
ctrl [ i ] - > data = NULL ;
decoded [ i ] = false ;
i + + ;
2007-03-13 03:59:06 +03:00
} else {
talloc_free ( ctrl [ i ] ) ;
ctrl [ i ] = NULL ;
}
} else {
2007-11-29 10:00:04 +03:00
decoded [ i ] = true ;
2007-03-13 03:59:06 +03:00
i + + ;
2004-10-10 03:59:12 +04:00
}
}
2006-01-06 07:01:23 +03:00
2006-03-15 08:30:39 +03:00
if ( ctrl ! = NULL ) {
ctrl [ i ] = NULL ;
}
2006-01-06 07:01:23 +03:00
2004-10-10 03:59:12 +04:00
msg - > controls = ctrl ;
2007-11-29 10:00:04 +03:00
msg - > controls_decoded = decoded ;
2004-10-10 03:59:12 +04:00
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2004-10-10 03:59:12 +04:00
}
2014-09-23 03:08:26 +04:00
if ( ! asn1_end_tag ( data ) ) goto prot_err ;
2016-01-04 12:24:01 +03:00
if ( asn1_has_error ( data ) | | asn1_has_nesting ( data ) ) {
2007-03-13 03:59:06 +03:00
return NT_STATUS_LDAP ( LDAP_PROTOCOL_ERROR ) ;
}
return NT_STATUS_OK ;
2014-09-23 03:08:26 +04:00
prot_err :
return NT_STATUS_LDAP ( LDAP_PROTOCOL_ERROR ) ;
2004-08-12 08:55:59 +04:00
}
2005-05-10 05:57:47 +04:00
2005-11-10 03:28:02 +03:00
/*
return NT_STATUS_OK if a blob has enough bytes in it to be a full
ldap packet . Set packet_size if true .
*/
2016-09-22 00:24:45 +03:00
NTSTATUS ldap_full_packet ( struct tstream_context * stream ,
void * private_data ,
DATA_BLOB blob ,
size_t * packet_size )
2005-11-10 03:28:02 +03:00
{
2015-12-21 12:41:39 +03:00
int ret ;
2010-10-04 12:35:32 +04:00
if ( blob . length < 6 ) {
/*
* We need at least 6 bytes to workout the length
* of the pdu .
*/
return STATUS_MORE_ENTRIES ;
}
2015-12-21 12:41:39 +03:00
ret = asn1_peek_full_tag ( blob , ASN1_SEQUENCE ( 0 ) , packet_size ) ;
if ( ret ! = 0 ) {
return map_nt_error_from_unix_common ( ret ) ;
}
return NT_STATUS_OK ;
2005-11-10 03:28:02 +03:00
}