2004-08-12 08:55:59 +04:00
/*
Unix SMB / CIFS mplementation .
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
the Free Software Foundation ; either version 2 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 , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2004-11-02 04:42:45 +03:00
# include "system/iconv.h"
2004-11-02 09:42:15 +03:00
# include "asn_1.h"
2005-02-10 10:08:40 +03:00
# include "libcli/ldap/ldap.h"
2004-08-12 08:55:59 +04:00
2005-05-11 09:59:46 +04:00
2005-06-13 10:06:29 +04:00
static BOOL ldap_push_filter ( struct asn1_data * data , struct ldb_parse_tree * tree )
2004-08-12 08:55:59 +04:00
{
switch ( tree - > operation ) {
2005-06-13 10:06:29 +04:00
case LDB_OP_SIMPLE : {
2004-08-12 08:55:59 +04:00
if ( ( tree - > u . simple . value . length = = 1 ) & &
( ( ( char * ) ( tree - > u . simple . value . data ) ) [ 0 ] = = ' * ' ) ) {
/* Just a presence test */
asn1_push_tag ( data , 0x87 ) ;
asn1_write ( data , tree - > u . simple . attr ,
strlen ( tree - > u . simple . attr ) ) ;
asn1_pop_tag ( data ) ;
return ! data - > has_error ;
}
/* Equality is all we currently do... */
asn1_push_tag ( data , 0xa3 ) ;
asn1_write_OctetString ( data , tree - > u . simple . attr ,
strlen ( tree - > u . simple . attr ) ) ;
asn1_write_OctetString ( data , tree - > u . simple . value . data ,
tree - > u . simple . value . length ) ;
asn1_pop_tag ( data ) ;
break ;
}
2005-06-13 10:06:29 +04:00
case LDB_OP_AND : {
2004-08-12 08:55:59 +04:00
int i ;
asn1_push_tag ( data , 0xa0 ) ;
for ( i = 0 ; i < tree - > u . list . num_elements ; i + + ) {
ldap_push_filter ( data , tree - > u . list . elements [ i ] ) ;
}
asn1_pop_tag ( data ) ;
break ;
}
2005-06-13 10:06:29 +04:00
case LDB_OP_OR : {
2004-08-12 08:55:59 +04:00
int i ;
asn1_push_tag ( data , 0xa1 ) ;
for ( i = 0 ; i < tree - > u . list . num_elements ; i + + ) {
ldap_push_filter ( data , tree - > u . list . elements [ i ] ) ;
}
asn1_pop_tag ( data ) ;
break ;
}
default :
return False ;
}
return ! data - > has_error ;
}
2004-11-02 09:42:15 +03:00
static void ldap_encode_response ( struct asn1_data * data , struct ldap_Result * result )
2004-08-12 08:55:59 +04:00
{
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 ) ;
2004-11-06 23:43:36 +03:00
if ( result - > referral ) {
asn1_push_tag ( data , ASN1_CONTEXT ( 3 ) ) ;
2004-08-12 08:55:59 +04:00
asn1_write_OctetString ( data , result - > referral ,
strlen ( result - > referral ) ) ;
2004-11-06 23:43:36 +03:00
asn1_pop_tag ( data ) ;
}
2004-08-12 08:55:59 +04:00
}
BOOL ldap_encode ( struct ldap_message * msg , DATA_BLOB * result )
{
2004-11-02 09:42:15 +03:00
struct asn1_data data ;
2004-08-12 08:55:59 +04:00
int i , j ;
ZERO_STRUCT ( data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
2004-08-12 08:55:59 +04:00
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 */
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_CONTEXT_SIMPLE ( 0 ) ) ;
2004-08-12 08:55:59 +04:00
asn1_write ( & data , r - > creds . password ,
strlen ( r - > creds . password ) ) ;
asn1_pop_tag ( & data ) ;
break ;
case LDAP_AUTH_MECH_SASL :
/* context, constructed */
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_CONTEXT ( 3 ) ) ;
2004-08-12 08:55:59 +04:00
asn1_write_OctetString ( & data , r - > creds . SASL . mechanism ,
strlen ( r - > creds . SASL . mechanism ) ) ;
2004-08-13 09:26:38 +04:00
asn1_write_OctetString ( & data , r - > creds . SASL . secblob . data ,
r - > creds . SASL . secblob . length ) ;
2004-08-12 08:55:59 +04:00
asn1_pop_tag ( & data ) ;
break ;
default :
return False ;
}
asn1_pop_tag ( & data ) ;
asn1_pop_tag ( & data ) ;
break ;
}
case LDAP_TAG_BindResponse : {
struct ldap_BindResponse * r = & msg - > r . BindResponse ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
ldap_encode_response ( & data , & r - > response ) ;
2005-06-13 10:06:29 +04:00
asn1_write_ContextSimple ( & data , 7 , & r - > SASL . secblob ) ;
2004-10-08 16:08:43 +04:00
asn1_pop_tag ( & data ) ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_UnbindRequest : {
/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */
break ;
}
case LDAP_TAG_SearchRequest : {
struct ldap_SearchRequest * r = & msg - > r . SearchRequest ;
2005-06-13 10:06:29 +04:00
struct ldb_parse_tree * tree ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
2004-08-12 08:55:59 +04:00
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 ) ;
2004-09-01 18:49:43 +04:00
asn1_write_BOOLEAN ( & data , r - > attributesonly ) ;
2004-08-12 08:55:59 +04:00
2005-06-13 10:06:29 +04:00
tree = ldb_parse_tree ( NULL , r - > filter ) ;
2004-08-12 08:55:59 +04:00
2005-06-13 10:06:29 +04:00
if ( tree = = NULL )
return False ;
2004-08-12 08:55:59 +04:00
2005-06-13 10:06:29 +04:00
ldap_push_filter ( & data , tree ) ;
2004-08-12 08:55:59 +04:00
2005-06-13 10:06:29 +04:00
talloc_free ( tree ) ;
2004-08-12 08:55:59 +04:00
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 ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
2004-08-12 08:55:59 +04:00
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 ldap_attribute * 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 : {
2004-08-12 10:37:12 +04:00
struct ldap_Result * r = & msg - > r . SearchResultDone ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
ldap_encode_response ( & data , r ) ;
asn1_pop_tag ( & data ) ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_ModifyRequest : {
struct ldap_ModifyRequest * r = & msg - > r . ModifyRequest ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
2004-08-12 08:55:59 +04:00
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 ldap_attribute * 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 ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
ldap_encode_response ( & data , r ) ;
asn1_pop_tag ( & data ) ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_AddRequest : {
struct ldap_AddRequest * r = & msg - > r . AddRequest ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
2004-08-12 08:55:59 +04:00
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 ldap_attribute * 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 ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
ldap_encode_response ( & data , r ) ;
asn1_pop_tag ( & data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION_SIMPLE ( msg - > type ) ) ;
2004-08-12 08:55:59 +04:00
asn1_write ( & data , r - > dn , strlen ( r - > dn ) ) ;
asn1_pop_tag ( & data ) ;
break ;
}
2004-09-27 19:40:12 +04:00
case LDAP_TAG_DelResponse : {
struct ldap_Result * r = & msg - > r . DelResponse ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
ldap_encode_response ( & data , r ) ;
asn1_pop_tag ( & data ) ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_ModifyDNRequest : {
struct ldap_ModifyDNRequest * r = & msg - > r . ModifyDNRequest ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
2004-08-12 08:55:59 +04:00
asn1_write_OctetString ( & data , r - > dn , strlen ( r - > dn ) ) ;
asn1_write_OctetString ( & data , r - > newrdn , strlen ( r - > newrdn ) ) ;
2004-09-01 18:49:43 +04:00
asn1_write_BOOLEAN ( & data , r - > deleteolddn ) ;
2004-08-12 08:55:59 +04:00
if ( r - > newsuperior ! = NULL ) {
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 : {
2004-08-17 15:22:44 +04:00
struct ldap_Result * r = & msg - > r . ModifyDNResponse ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
ldap_encode_response ( & data , r ) ;
asn1_pop_tag ( & data ) ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_CompareRequest : {
struct ldap_CompareRequest * r = & msg - > r . CompareRequest ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
2004-08-12 08:55:59 +04:00
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 ) ) ;
2004-09-29 16:18:06 +04:00
asn1_write_OctetString ( & data , r - > value . data ,
r - > value . length ) ;
2004-08-12 08:55:59 +04:00
asn1_pop_tag ( & data ) ;
asn1_pop_tag ( & data ) ;
break ;
}
case LDAP_TAG_CompareResponse : {
2004-09-29 16:18:06 +04:00
struct ldap_Result * r = & msg - > r . ModifyDNResponse ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
ldap_encode_response ( & data , r ) ;
asn1_pop_tag ( & data ) ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_AbandonRequest : {
struct ldap_AbandonRequest * r = & msg - > r . AbandonRequest ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION_SIMPLE ( msg - > type ) ) ;
2004-09-15 17:29:59 +04:00
asn1_write_implicit_Integer ( & data , r - > messageid ) ;
2004-08-12 08:55:59 +04:00
asn1_pop_tag ( & data ) ;
break ;
}
case LDAP_TAG_SearchResultReference : {
2004-11-06 23:43:36 +03:00
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 ) ;
2004-08-12 08:55:59 +04:00
break ;
}
case LDAP_TAG_ExtendedRequest : {
struct ldap_ExtendedRequest * r = & msg - > r . ExtendedRequest ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
2004-08-12 08:55:59 +04:00
asn1_push_tag ( & data , ASN1_CONTEXT_SIMPLE ( 0 ) ) ;
asn1_write ( & data , r - > oid , strlen ( r - > oid ) ) ;
asn1_pop_tag ( & data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_push_tag ( & data , ASN1_APPLICATION ( msg - > type ) ) ;
ldap_encode_response ( & data , & r - > response ) ;
asn1_pop_tag ( & data ) ;
2004-08-12 08:55:59 +04:00
break ;
}
default :
return False ;
}
asn1_pop_tag ( & data ) ;
* result = data_blob ( data . data , data . length ) ;
asn1_free ( & data ) ;
return True ;
}
static const char * blob2string_talloc ( TALLOC_CTX * mem_ctx ,
DATA_BLOB blob )
{
2005-01-06 06:06:58 +03:00
char * result = talloc_size ( mem_ctx , blob . length + 1 ) ;
2004-08-12 08:55:59 +04:00
memcpy ( result , blob . data , blob . length ) ;
result [ blob . length ] = ' \0 ' ;
return result ;
}
static BOOL asn1_read_OctetString_talloc ( TALLOC_CTX * mem_ctx ,
2004-11-02 09:42:15 +03:00
struct asn1_data * data ,
2004-08-12 08:55:59 +04:00
const char * * result )
{
DATA_BLOB string ;
if ( ! asn1_read_OctetString ( data , & string ) )
return False ;
* result = blob2string_talloc ( mem_ctx , string ) ;
data_blob_free ( & string ) ;
return True ;
}
static void 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 )
{
asn1_read_enumerated ( data , & result - > resultcode ) ;
asn1_read_OctetString_talloc ( mem_ctx , data , & result - > dn ) ;
asn1_read_OctetString_talloc ( mem_ctx , data , & result - > errormessage ) ;
2004-08-17 15:22:44 +04:00
if ( asn1_peek_tag ( data , ASN1_CONTEXT ( 3 ) ) ) {
asn1_start_tag ( data , ASN1_CONTEXT ( 3 ) ) ;
2004-08-12 08:55:59 +04:00
asn1_read_OctetString_talloc ( mem_ctx , data , & result - > referral ) ;
2004-08-17 15:22:44 +04:00
asn1_end_tag ( data ) ;
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
}
}
2004-11-02 09:42:15 +03:00
static BOOL ldap_decode_filter ( TALLOC_CTX * mem_ctx , struct asn1_data * data ,
2005-05-10 05:57:47 +04:00
const char * * filterp )
2004-08-12 08:55:59 +04:00
{
2005-02-10 08:09:35 +03:00
uint8_t filter_tag , tag_desc ;
2005-05-10 05:57:47 +04:00
char * filter = NULL ;
* filterp = NULL ;
2004-08-12 08:55:59 +04:00
if ( ! asn1_peek_uint8 ( data , & filter_tag ) )
return False ;
tag_desc = filter_tag ;
filter_tag & = 0x1f ; /* strip off the asn1 stuff */
tag_desc & = 0xe0 ;
switch ( filter_tag ) {
case 0 : {
/* AND of one or more filters */
if ( tag_desc ! = 0xa0 ) /* context compount */
return False ;
asn1_start_tag ( data , ASN1_CONTEXT ( 0 ) ) ;
2005-05-10 05:57:47 +04:00
filter = talloc_strdup ( mem_ctx , " (& " ) ;
if ( filter = = NULL )
2004-08-12 08:55:59 +04:00
return False ;
while ( asn1_tag_remaining ( data ) > 0 ) {
2005-05-10 05:57:47 +04:00
const char * subfilter ;
2004-08-12 08:55:59 +04:00
if ( ! ldap_decode_filter ( mem_ctx , data , & subfilter ) )
return False ;
2005-05-10 05:57:47 +04:00
filter = talloc_asprintf_append ( filter , " %s " , subfilter ) ;
if ( filter = = NULL )
2004-08-12 08:55:59 +04:00
return False ;
}
asn1_end_tag ( data ) ;
2005-05-11 09:59:46 +04:00
filter = talloc_asprintf_append ( filter , " ) " ) ;
2004-08-12 08:55:59 +04:00
break ;
}
case 1 : {
/* OR of one or more filters */
if ( tag_desc ! = 0xa0 ) /* context compount */
return False ;
asn1_start_tag ( data , ASN1_CONTEXT ( 1 ) ) ;
2005-05-10 05:57:47 +04:00
filter = talloc_strdup ( mem_ctx , " (| " ) ;
if ( filter = = NULL )
2004-08-12 08:55:59 +04:00
return False ;
while ( asn1_tag_remaining ( data ) > 0 ) {
2005-05-10 05:57:47 +04:00
const char * subfilter ;
2004-08-12 08:55:59 +04:00
if ( ! ldap_decode_filter ( mem_ctx , data , & subfilter ) )
return False ;
2005-05-10 05:57:47 +04:00
filter = talloc_asprintf_append ( filter , " %s " , subfilter ) ;
if ( filter = = NULL )
2004-08-12 08:55:59 +04:00
return False ;
}
asn1_end_tag ( data ) ;
2005-05-11 09:59:46 +04:00
filter = talloc_asprintf_append ( filter , " ) " ) ;
2004-08-12 08:55:59 +04:00
break ;
}
case 3 : {
/* equalityMatch */
2005-05-11 09:59:46 +04:00
const char * attrib ;
DATA_BLOB value ;
2005-06-13 10:06:29 +04:00
struct ldb_val val ;
2004-08-12 08:55:59 +04:00
if ( tag_desc ! = 0xa0 ) /* context compound */
return False ;
asn1_start_tag ( data , ASN1_CONTEXT ( 3 ) ) ;
asn1_read_OctetString_talloc ( mem_ctx , data , & attrib ) ;
2005-05-11 09:59:46 +04:00
asn1_read_OctetString ( data , & value ) ;
2004-08-12 08:55:59 +04:00
asn1_end_tag ( data ) ;
2005-05-11 09:59:46 +04:00
if ( ( data - > has_error ) | | ( attrib = = NULL ) | | ( value . data = = NULL ) )
2004-08-12 08:55:59 +04:00
return False ;
2005-06-13 10:06:29 +04:00
val . data = value . data ;
val . length = value . length ;
2005-05-11 09:59:46 +04:00
filter = talloc_asprintf ( mem_ctx , " (%s=%s) " ,
2005-06-13 10:06:29 +04:00
attrib , ldb_binary_encode ( mem_ctx , val ) ) ;
2005-05-11 09:59:46 +04:00
data_blob_free ( & value ) ;
2004-08-12 08:55:59 +04:00
break ;
}
case 7 : {
/* Normal presence, "attribute=*" */
int attr_len ;
char * attr_name ;
if ( tag_desc ! = 0x80 ) /* context simple */
return False ;
if ( ! asn1_start_tag ( data , ASN1_CONTEXT_SIMPLE ( 7 ) ) )
return False ;
attr_len = asn1_tag_remaining ( data ) ;
attr_name = malloc ( attr_len + 1 ) ;
if ( attr_name = = NULL )
return False ;
asn1_read ( data , attr_name , attr_len ) ;
attr_name [ attr_len ] = ' \0 ' ;
2005-05-10 05:57:47 +04:00
filter = talloc_asprintf ( mem_ctx , " (%s=*) " , attr_name ) ;
2004-08-12 08:55:59 +04:00
SAFE_FREE ( attr_name ) ;
asn1_end_tag ( data ) ;
break ;
}
default :
return False ;
}
2005-05-10 05:57:47 +04:00
if ( filter = = NULL )
2004-08-12 08:55:59 +04:00
return False ;
2005-05-10 05:57:47 +04:00
* filterp = filter ;
2004-08-12 08:55:59 +04:00
return True ;
}
2004-11-02 09:42:15 +03:00
static void ldap_decode_attrib ( TALLOC_CTX * mem_ctx , struct asn1_data * data ,
2004-08-12 08:55:59 +04:00
struct ldap_attribute * attrib )
{
asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ;
asn1_read_OctetString_talloc ( mem_ctx , data , & attrib - > name ) ;
asn1_start_tag ( data , ASN1_SET ) ;
while ( asn1_peek_tag ( data , ASN1_OCTET_STRING ) ) {
DATA_BLOB blob ;
2005-06-13 10:06:29 +04:00
struct ldb_val value ;
2004-08-12 08:55:59 +04:00
asn1_read_OctetString ( data , & blob ) ;
value . data = blob . data ;
value . length = blob . length ;
add_value_to_attrib ( mem_ctx , & value , attrib ) ;
data_blob_free ( & blob ) ;
}
asn1_end_tag ( data ) ;
asn1_end_tag ( data ) ;
}
2004-11-02 09:42:15 +03:00
static void ldap_decode_attribs ( TALLOC_CTX * mem_ctx , struct asn1_data * data ,
2004-08-12 08:55:59 +04:00
struct ldap_attribute * * attributes ,
int * num_attributes )
{
asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ;
while ( asn1_peek_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) {
struct ldap_attribute attrib ;
ZERO_STRUCT ( attrib ) ;
ldap_decode_attrib ( mem_ctx , data , & attrib ) ;
add_attrib_to_array_talloc ( mem_ctx , & attrib ,
attributes , num_attributes ) ;
}
asn1_end_tag ( data ) ;
}
2004-11-02 09:42:15 +03:00
BOOL ldap_decode ( struct asn1_data * data , 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
asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ;
asn1_read_Integer ( data , & msg - > messageid ) ;
if ( ! asn1_peek_uint8 ( data , & tag ) )
return False ;
switch ( tag ) {
case ASN1_APPLICATION ( LDAP_TAG_BindRequest ) : {
struct ldap_BindRequest * r = & msg - > r . BindRequest ;
msg - > type = LDAP_TAG_BindRequest ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
2004-08-12 08:55:59 +04:00
asn1_read_Integer ( data , & r - > version ) ;
asn1_read_OctetString_talloc ( msg - > mem_ctx , data , & r - > dn ) ;
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 ;
asn1_start_tag ( data , ASN1_CONTEXT_SIMPLE ( 0 ) ) ;
2004-08-12 08:55:59 +04:00
pwlen = asn1_tag_remaining ( data ) ;
if ( pwlen ! = 0 ) {
2005-01-06 06:06:58 +03:00
char * pw = talloc_size ( msg - > mem_ctx , pwlen + 1 ) ;
2004-08-12 08:55:59 +04:00
asn1_read ( data , pw , pwlen ) ;
pw [ pwlen ] = ' \0 ' ;
r - > creds . password = pw ;
}
asn1_end_tag ( data ) ;
2004-10-08 16:08:43 +04:00
} 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 ) ;
2004-08-12 08:55:59 +04:00
}
asn1_end_tag ( data ) ;
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_BindResponse ) : {
struct ldap_BindResponse * r = & msg - > r . BindResponse ;
msg - > type = LDAP_TAG_BindResponse ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
ldap_decode_response ( msg - > mem_ctx , data , & r - > response ) ;
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 ) ;
asn1_read_ContextSimple ( data , 7 , & tmp_blob ) ;
r - > SASL . secblob = data_blob_talloc ( msg - > mem_ctx , tmp_blob . data , tmp_blob . length ) ;
data_blob_free ( & tmp_blob ) ;
} else {
r - > SASL . secblob = data_blob ( NULL , 0 ) ;
}
asn1_end_tag ( data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
2004-09-22 14:42:58 +04:00
asn1_end_tag ( data ) ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_SearchRequest ) : {
struct ldap_SearchRequest * r = & msg - > r . SearchRequest ;
msg - > type = LDAP_TAG_SearchRequest ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
2004-08-12 08:55:59 +04:00
asn1_read_OctetString_talloc ( msg - > mem_ctx , data , & r - > basedn ) ;
asn1_read_enumerated ( data , ( int * ) & ( r - > scope ) ) ;
asn1_read_enumerated ( data , ( int * ) & ( r - > deref ) ) ;
asn1_read_Integer ( data , & r - > sizelimit ) ;
asn1_read_Integer ( data , & r - > timelimit ) ;
2004-09-01 18:49:43 +04:00
asn1_read_BOOLEAN ( data , & r - > attributesonly ) ;
2004-08-12 08:55:59 +04:00
/* Maybe create a TALLOC_CTX for the filter? This can waste
* quite a bit of memory recursing down . */
ldap_decode_filter ( msg - > mem_ctx , data , & r - > filter ) ;
asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ;
r - > num_attributes = 0 ;
r - > attributes = NULL ;
while ( asn1_tag_remaining ( data ) > 0 ) {
const char * attr ;
if ( ! asn1_read_OctetString_talloc ( msg - > mem_ctx , data ,
& attr ) )
return False ;
if ( ! add_string_to_array ( msg - > mem_ctx , attr ,
& r - > attributes ,
& r - > num_attributes ) )
return False ;
}
asn1_end_tag ( data ) ;
asn1_end_tag ( data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
2004-08-12 08:55:59 +04:00
asn1_read_OctetString_talloc ( msg - > mem_ctx , data , & r - > dn ) ;
ldap_decode_attribs ( msg - > mem_ctx , data , & r - > attributes ,
& r - > num_attributes ) ;
asn1_end_tag ( data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
ldap_decode_response ( msg - > mem_ctx , data , r ) ;
asn1_end_tag ( data ) ;
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 ;
2004-11-06 23:43:36 +03:00
asn1_start_tag ( data , tag ) ;
asn1_read_OctetString_talloc ( msg - > mem_ctx , data , & r - > referral ) ;
asn1_end_tag ( data ) ;
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 ;
asn1_start_tag ( data , ASN1_APPLICATION ( LDAP_TAG_ModifyRequest ) ) ;
asn1_read_OctetString_talloc ( msg - > mem_ctx , data , & r - > dn ) ;
asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ;
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 ) ;
asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ;
2004-11-02 14:16:34 +03:00
asn1_read_enumerated ( data , & v ) ;
mod . type = v ;
2004-08-12 08:55:59 +04:00
ldap_decode_attrib ( msg - > mem_ctx , data , & mod . attrib ) ;
asn1_end_tag ( data ) ;
if ( ! add_mod_to_array_talloc ( msg - > mem_ctx , & mod ,
& r - > mods , & r - > num_mods ) )
break ;
}
asn1_end_tag ( data ) ;
asn1_end_tag ( data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
ldap_decode_response ( msg - > mem_ctx , data , r ) ;
asn1_end_tag ( data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
2004-08-12 08:55:59 +04:00
asn1_read_OctetString_talloc ( msg - > mem_ctx , data , & r - > dn ) ;
r - > attributes = NULL ;
r - > num_attributes = 0 ;
ldap_decode_attribs ( msg - > mem_ctx , data , & r - > attributes ,
& r - > num_attributes ) ;
asn1_end_tag ( data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
ldap_decode_response ( msg - > mem_ctx , data , r ) ;
asn1_end_tag ( data ) ;
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 ;
2004-08-12 08:55:59 +04:00
asn1_start_tag ( data ,
2004-09-27 19:40:12 +04:00
ASN1_APPLICATION_SIMPLE ( LDAP_TAG_DelRequest ) ) ;
2004-08-12 08:55:59 +04:00
len = asn1_tag_remaining ( data ) ;
2005-01-06 06:06:58 +03:00
dn = talloc_size ( msg - > mem_ctx , len + 1 ) ;
2004-08-12 08:55:59 +04:00
if ( dn = = NULL )
break ;
asn1_read ( data , dn , len ) ;
dn [ len ] = ' \0 ' ;
r - > dn = dn ;
asn1_end_tag ( data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
ldap_decode_response ( msg - > mem_ctx , data , r ) ;
asn1_end_tag ( data ) ;
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 ;
2004-08-17 15:22:44 +04:00
asn1_start_tag ( data ,
ASN1_APPLICATION ( LDAP_TAG_ModifyDNRequest ) ) ;
asn1_read_OctetString_talloc ( msg - > mem_ctx , data , & r - > dn ) ;
asn1_read_OctetString_talloc ( msg - > mem_ctx , data , & r - > newrdn ) ;
2004-09-01 18:49:43 +04:00
asn1_read_BOOLEAN ( data , & r - > deleteolddn ) ;
2004-08-17 15:22:44 +04:00
r - > newsuperior = NULL ;
if ( asn1_tag_remaining ( data ) > 0 ) {
int len ;
char * newsup ;
asn1_start_tag ( data , ASN1_CONTEXT_SIMPLE ( 0 ) ) ;
len = asn1_tag_remaining ( data ) ;
2005-01-06 06:06:58 +03:00
newsup = talloc_size ( msg - > mem_ctx , len + 1 ) ;
2004-08-17 15:22:44 +04:00
if ( newsup = = NULL )
break ;
asn1_read ( data , newsup , len ) ;
newsup [ len ] = ' \0 ' ;
r - > newsuperior = newsup ;
asn1_end_tag ( data ) ;
}
asn1_end_tag ( data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
ldap_decode_response ( msg - > mem_ctx , data , r ) ;
asn1_end_tag ( data ) ;
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 ;
2004-09-29 16:18:06 +04:00
asn1_start_tag ( data ,
ASN1_APPLICATION ( LDAP_TAG_CompareRequest ) ) ;
asn1_read_OctetString_talloc ( msg - > mem_ctx , data , & r - > dn ) ;
asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ;
asn1_read_OctetString_talloc ( msg - > mem_ctx , data , & r - > attribute ) ;
asn1_read_OctetString ( data , & r - > value ) ;
if ( r - > value . data ) {
talloc_steal ( msg - > mem_ctx , r - > value . data ) ;
}
asn1_end_tag ( data ) ;
asn1_end_tag ( data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
ldap_decode_response ( msg - > mem_ctx , data , r ) ;
asn1_end_tag ( data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
2004-09-29 17:06:26 +04:00
asn1_read_implicit_Integer ( data , & r - > messageid ) ;
asn1_end_tag ( data ) ;
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 ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
2004-09-22 14:42:58 +04:00
if ( ! asn1_read_ContextSimple ( data , 0 , & tmp_blob ) ) {
return False ;
}
r - > oid = blob2string_talloc ( msg - > mem_ctx , tmp_blob ) ;
data_blob_free ( & tmp_blob ) ;
if ( ! r - > oid ) {
return False ;
}
if ( asn1_peek_tag ( data , ASN1_CONTEXT_SIMPLE ( 1 ) ) ) {
asn1_read_ContextSimple ( data , 1 , & tmp_blob ) ;
r - > value = data_blob_talloc ( msg - > mem_ctx , tmp_blob . data , tmp_blob . length ) ;
data_blob_free ( & tmp_blob ) ;
} else {
r - > value = data_blob ( NULL , 0 ) ;
}
asn1_end_tag ( data ) ;
2004-08-12 08:55:59 +04:00
break ;
}
case ASN1_APPLICATION ( LDAP_TAG_ExtendedResponse ) : {
struct ldap_ExtendedResponse * r = & msg - > r . ExtendedResponse ;
msg - > type = LDAP_TAG_ExtendedResponse ;
2004-10-08 16:08:43 +04:00
asn1_start_tag ( data , tag ) ;
ldap_decode_response ( msg - > mem_ctx , data , & r - > response ) ;
2004-08-12 08:55:59 +04:00
/* 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 ;
2004-10-08 16:08:43 +04:00
asn1_end_tag ( data ) ;
2004-08-12 08:55:59 +04:00
break ;
}
2004-09-22 14:42:58 +04:00
default :
return False ;
2004-08-12 08:55:59 +04:00
}
2004-10-10 03:59:12 +04:00
msg - > num_controls = 0 ;
msg - > controls = NULL ;
if ( asn1_peek_tag ( data , ASN1_CONTEXT ( 0 ) ) ) {
int i ;
struct ldap_Control * ctrl = NULL ;
asn1_start_tag ( data , ASN1_CONTEXT ( 0 ) ) ;
for ( i = 0 ; asn1_peek_tag ( data , ASN1_SEQUENCE ( 0 ) ) ; i + + ) {
asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ;
2005-01-27 10:08:20 +03:00
ctrl = talloc_realloc ( msg - > mem_ctx , ctrl , struct ldap_Control , i + 1 ) ;
2004-10-10 03:59:12 +04:00
if ( ! ctrl ) {
return False ;
}
ctrl [ i ] . oid = NULL ;
ctrl [ i ] . critical = False ;
ctrl [ i ] . value = data_blob ( NULL , 0 ) ;
asn1_read_OctetString_talloc ( ctrl , data , & ctrl [ i ] . oid ) ;
if ( asn1_peek_tag ( data , ASN1_BOOLEAN ) ) {
asn1_read_BOOLEAN ( data , & ctrl [ i ] . critical ) ;
}
if ( asn1_peek_tag ( data , ASN1_OCTET_STRING ) ) {
asn1_read_OctetString ( data , & ctrl [ i ] . value ) ;
if ( ctrl [ i ] . value . data ) {
talloc_steal ( msg - > mem_ctx , ctrl [ i ] . value . data ) ;
}
}
asn1_end_tag ( data ) ;
}
msg - > num_controls = i ;
msg - > controls = ctrl ;
asn1_end_tag ( data ) ;
}
2004-08-12 08:55:59 +04:00
asn1_end_tag ( data ) ;
return ( ( ! data - > has_error ) & & ( data - > nesting = = NULL ) ) ;
}
BOOL ldap_parse_basic_url ( TALLOC_CTX * mem_ctx , const char * url ,
2005-01-31 19:06:21 +03:00
char * * host , uint16_t * port , BOOL * ldaps )
2004-08-12 08:55:59 +04:00
{
int tmp_port = 0 ;
2004-11-06 23:15:39 +03:00
char protocol [ 11 ] ;
char tmp_host [ 255 ] ;
2004-08-12 08:55:59 +04:00
const char * p = url ;
2004-11-07 00:51:22 +03:00
int ret ;
2004-08-12 08:55:59 +04:00
/* skip leading "URL:" (if any) */
2004-09-20 11:24:00 +04:00
if ( strncasecmp ( p , " URL: " , 4 ) = = 0 ) {
2004-08-12 08:55:59 +04:00
p + = 4 ;
}
/* Paranoia check */
SMB_ASSERT ( sizeof ( protocol ) > 10 & & sizeof ( tmp_host ) > 254 ) ;
2004-11-07 00:51:22 +03:00
ret = sscanf ( p , " %10[^:]://%254[^:/]:%d " , protocol , tmp_host , & tmp_port ) ;
if ( ret < 2 ) {
return False ;
}
2004-08-12 08:55:59 +04:00
if ( strequal ( protocol , " ldap " ) ) {
* port = 389 ;
* ldaps = False ;
} else if ( strequal ( protocol , " ldaps " ) ) {
* port = 636 ;
* ldaps = True ;
} else {
DEBUG ( 0 , ( " unrecognised protocol (%s)! \n " , protocol ) ) ;
return False ;
}
if ( tmp_port ! = 0 )
* port = tmp_port ;
2004-11-06 23:15:39 +03:00
2004-08-12 08:55:59 +04:00
* host = talloc_strdup ( mem_ctx , tmp_host ) ;
return ( * host ! = NULL ) ;
}
2005-05-10 05:57:47 +04:00