2006-01-06 07:01:23 +03:00
/*
Unix SMB / CIFS mplementation .
LDAP protocol helper functions for SAMBA
Copyright ( C ) Simo Sorce 2005
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"
# include "libcli/util/asn_1.h"
# include "libcli/ldap/ldap.h"
# include "lib/ldb/include/ldb.h"
struct control_handler {
const char * oid ;
BOOL ( * decode ) ( void * mem_ctx , DATA_BLOB in , void * * out ) ;
BOOL ( * encode ) ( void * mem_ctx , void * in , DATA_BLOB * out ) ;
} ;
static BOOL decode_server_sort_response ( void * mem_ctx , DATA_BLOB in , void * * out )
{
DATA_BLOB attr ;
struct asn1_data data ;
struct ldb_sort_resp_control * lsrc ;
if ( ! asn1_load ( & data , in ) ) {
return False ;
}
lsrc = talloc ( mem_ctx , struct ldb_sort_resp_control ) ;
if ( ! lsrc ) {
return False ;
}
if ( ! asn1_start_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_read_enumerated ( & data , & ( lsrc - > result ) ) ) {
return False ;
}
lsrc - > attr_desc = NULL ;
if ( asn1_peek_tag ( & data , ASN1_OCTET_STRING ) ) {
if ( ! asn1_read_OctetString ( & data , & attr ) ) {
return False ;
}
2006-01-17 21:56:04 +03:00
lsrc - > attr_desc = talloc_strndup ( lsrc , ( const char * ) attr . data , attr . length ) ;
2006-01-06 07:01:23 +03:00
if ( ! lsrc - > attr_desc ) {
return False ;
}
}
if ( ! asn1_end_tag ( & data ) ) {
return False ;
}
* out = lsrc ;
return True ;
}
static BOOL decode_server_sort_request ( void * mem_ctx , DATA_BLOB in , void * * out )
{
DATA_BLOB attr ;
DATA_BLOB rule ;
struct asn1_data data ;
struct ldb_server_sort_control * * lssc ;
int num ;
if ( ! asn1_load ( & data , in ) ) {
return False ;
}
if ( ! asn1_start_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
lssc = NULL ;
for ( num = 0 ; asn1_peek_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ; num + + ) {
lssc = talloc_realloc ( mem_ctx , lssc , struct ldb_server_sort_control * , num + 2 ) ;
if ( ! lssc ) {
return False ;
}
2006-02-15 16:33:33 +03:00
lssc [ num ] = talloc_zero ( lssc , struct ldb_server_sort_control ) ;
2006-01-06 07:01:23 +03:00
if ( ! lssc [ num ] ) {
return False ;
}
if ( ! asn1_start_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_read_OctetString ( & data , & attr ) ) {
return False ;
}
2006-01-17 21:56:04 +03:00
lssc [ num ] - > attributeName = talloc_strndup ( lssc [ num ] , ( const char * ) attr . data , attr . length ) ;
2006-01-06 07:01:23 +03:00
if ( ! lssc [ num ] - > attributeName ) {
return False ;
}
if ( asn1_peek_tag ( & data , ASN1_OCTET_STRING ) ) {
if ( ! asn1_read_OctetString ( & data , & rule ) ) {
return False ;
}
2006-01-17 21:56:04 +03:00
lssc [ num ] - > orderingRule = talloc_strndup ( lssc [ num ] , ( const char * ) rule . data , rule . length ) ;
2006-01-06 07:01:23 +03:00
if ( ! lssc [ num ] - > orderingRule ) {
return False ;
}
}
if ( asn1_peek_tag ( & data , ASN1_BOOLEAN ) ) {
2006-05-01 00:00:37 +04:00
BOOL reverse ;
2006-04-30 17:54:03 +04:00
if ( ! asn1_read_BOOLEAN ( & data , & reverse ) ) {
2006-01-06 07:01:23 +03:00
return False ;
}
2006-04-30 17:54:03 +04:00
lssc [ num ] - > reverse = reverse ;
2006-01-06 07:01:23 +03:00
}
if ( ! asn1_end_tag ( & data ) ) {
return False ;
}
}
2006-03-15 08:31:51 +03:00
if ( lssc ! = NULL ) {
lssc [ num ] = NULL ;
}
2006-01-06 07:01:23 +03:00
if ( ! asn1_end_tag ( & data ) ) {
return False ;
}
* out = lssc ;
return True ;
}
static BOOL decode_extended_dn_request ( void * mem_ctx , DATA_BLOB in , void * * out )
{
struct asn1_data data ;
struct ldb_extended_dn_control * ledc ;
if ( ! asn1_load ( & data , in ) ) {
return False ;
}
ledc = talloc ( mem_ctx , struct ldb_extended_dn_control ) ;
if ( ! ledc ) {
return False ;
}
if ( ! asn1_start_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_read_Integer ( & data , & ( ledc - > type ) ) ) {
return False ;
}
if ( ! asn1_end_tag ( & data ) ) {
return False ;
}
* out = ledc ;
return True ;
}
2006-08-05 14:26:23 +04:00
static BOOL decode_sd_flags_request ( void * mem_ctx , DATA_BLOB in , void * * out )
{
struct asn1_data data ;
struct ldb_sd_flags_control * lsdfc ;
if ( ! asn1_load ( & data , in ) ) {
return False ;
}
lsdfc = talloc ( mem_ctx , struct ldb_sd_flags_control ) ;
if ( ! lsdfc ) {
return False ;
}
if ( ! asn1_start_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_read_Integer ( & data , & ( lsdfc - > secinfo_flags ) ) ) {
return False ;
}
if ( ! asn1_end_tag ( & data ) ) {
return False ;
}
* out = lsdfc ;
return True ;
}
2006-08-05 15:18:14 +04:00
static BOOL decode_search_options_request ( void * mem_ctx , DATA_BLOB in , void * * out )
{
struct asn1_data data ;
struct ldb_search_options_control * lsoc ;
if ( ! asn1_load ( & data , in ) ) {
return False ;
}
lsoc = talloc ( mem_ctx , struct ldb_search_options_control ) ;
if ( ! lsoc ) {
return False ;
}
if ( ! asn1_start_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_read_Integer ( & data , & ( lsoc - > search_options ) ) ) {
return False ;
}
if ( ! asn1_end_tag ( & data ) ) {
return False ;
}
* out = lsoc ;
return True ;
}
2006-01-06 07:01:23 +03:00
static BOOL decode_paged_results_request ( void * mem_ctx , DATA_BLOB in , void * * out )
{
DATA_BLOB cookie ;
struct asn1_data data ;
struct ldb_paged_control * lprc ;
if ( ! asn1_load ( & data , in ) ) {
return False ;
}
lprc = talloc ( mem_ctx , struct ldb_paged_control ) ;
if ( ! lprc ) {
return False ;
}
if ( ! asn1_start_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_read_Integer ( & data , & ( lprc - > size ) ) ) {
return False ;
}
if ( ! asn1_read_OctetString ( & data , & cookie ) ) {
return False ;
}
lprc - > cookie_len = cookie . length ;
if ( lprc - > cookie_len ) {
lprc - > cookie = talloc_memdup ( lprc , cookie . data , cookie . length ) ;
if ( ! ( lprc - > cookie ) ) {
return False ;
}
} else {
lprc - > cookie = NULL ;
}
if ( ! asn1_end_tag ( & data ) ) {
return False ;
}
* out = lprc ;
return True ;
}
2006-01-17 07:04:57 +03:00
static BOOL decode_dirsync_request ( void * mem_ctx , DATA_BLOB in , void * * out )
{
DATA_BLOB cookie ;
struct asn1_data data ;
struct ldb_dirsync_control * ldc ;
if ( ! asn1_load ( & data , in ) ) {
return False ;
}
ldc = talloc ( mem_ctx , struct ldb_dirsync_control ) ;
if ( ! ldc ) {
return False ;
}
if ( ! asn1_start_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_read_Integer ( & data , & ( ldc - > flags ) ) ) {
return False ;
}
if ( ! asn1_read_Integer ( & data , & ( ldc - > max_attributes ) ) ) {
return False ;
}
if ( ! asn1_read_OctetString ( & data , & cookie ) ) {
return False ;
}
ldc - > cookie_len = cookie . length ;
if ( ldc - > cookie_len ) {
ldc - > cookie = talloc_memdup ( ldc , cookie . data , cookie . length ) ;
if ( ! ( ldc - > cookie ) ) {
return False ;
}
} else {
ldc - > cookie = NULL ;
}
if ( ! asn1_end_tag ( & data ) ) {
return False ;
}
* out = ldc ;
return True ;
}
2006-01-14 04:06:16 +03:00
/* seem that this controls has 2 forms one in case it is used with
* a Search Request and another when used ina Search Response
*/
static BOOL decode_asq_control ( void * mem_ctx , DATA_BLOB in , void * * out )
{
DATA_BLOB source_attribute ;
struct asn1_data data ;
struct ldb_asq_control * lac ;
if ( ! asn1_load ( & data , in ) ) {
return False ;
}
lac = talloc ( mem_ctx , struct ldb_asq_control ) ;
if ( ! lac ) {
return False ;
}
if ( ! asn1_start_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( asn1_peek_tag ( & data , ASN1_OCTET_STRING ) ) {
if ( ! asn1_read_OctetString ( & data , & source_attribute ) ) {
return False ;
}
lac - > src_attr_len = source_attribute . length ;
if ( lac - > src_attr_len ) {
2006-02-15 18:19:10 +03:00
lac - > source_attribute = talloc_strndup ( lac , ( const char * ) source_attribute . data , source_attribute . length ) ;
2006-01-14 04:06:16 +03:00
if ( ! ( lac - > source_attribute ) ) {
return False ;
}
} else {
lac - > source_attribute = NULL ;
}
lac - > request = 1 ;
} else if ( asn1_peek_tag ( & data , ASN1_ENUMERATED ) ) {
if ( ! asn1_read_enumerated ( & data , & ( lac - > result ) ) ) {
return False ;
}
lac - > request = 0 ;
} else {
return False ;
}
if ( ! asn1_end_tag ( & data ) ) {
return False ;
}
* out = lac ;
return True ;
}
2006-08-05 15:38:50 +04:00
static BOOL decode_domain_scope_request ( void * mem_ctx , DATA_BLOB in , void * * out )
{
if ( in . length ! = 0 ) {
return False ;
}
return True ;
}
2006-01-17 21:56:04 +03:00
static BOOL decode_notification_request ( void * mem_ctx , DATA_BLOB in , void * * out )
{
if ( in . length ! = 0 ) {
return False ;
}
return True ;
}
2006-08-05 23:35:00 +04:00
static BOOL decode_show_deleted_request ( void * mem_ctx , DATA_BLOB in , void * * out )
{
if ( in . length ! = 0 ) {
return False ;
}
return True ;
}
2006-08-05 23:50:58 +04:00
static BOOL decode_permissive_modify_request ( void * mem_ctx , DATA_BLOB in , void * * out )
{
if ( in . length ! = 0 ) {
return False ;
}
return True ;
}
2006-02-05 20:28:27 +03:00
static BOOL decode_manageDSAIT_request ( void * mem_ctx , DATA_BLOB in , void * * out )
{
if ( in . length ! = 0 ) {
return False ;
}
return True ;
}
2006-02-06 04:21:17 +03:00
static BOOL decode_vlv_request ( void * mem_ctx , DATA_BLOB in , void * * out )
{
DATA_BLOB assertion_value , context_id ;
struct asn1_data data ;
struct ldb_vlv_req_control * lvrc ;
if ( ! asn1_load ( & data , in ) ) {
return False ;
}
lvrc = talloc ( mem_ctx , struct ldb_vlv_req_control ) ;
if ( ! lvrc ) {
return False ;
}
if ( ! asn1_start_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_read_Integer ( & data , & ( lvrc - > beforeCount ) ) ) {
return False ;
}
if ( ! asn1_read_Integer ( & data , & ( lvrc - > afterCount ) ) ) {
return False ;
}
2006-02-22 04:31:35 +03:00
if ( asn1_peek_tag ( & data , ASN1_CONTEXT ( 0 ) ) ) {
2006-02-06 04:21:17 +03:00
lvrc - > type = 0 ;
2006-02-22 04:31:35 +03:00
if ( ! asn1_start_tag ( & data , ASN1_CONTEXT ( 0 ) ) ) {
return False ;
}
2006-02-06 04:21:17 +03:00
if ( ! asn1_start_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_read_Integer ( & data , & ( lvrc - > match . byOffset . offset ) ) ) {
return False ;
}
if ( ! asn1_read_Integer ( & data , & ( lvrc - > match . byOffset . contentCount ) ) ) {
return False ;
}
2006-02-22 04:31:35 +03:00
if ( ! asn1_end_tag ( & data ) ) { /*SEQUENCE*/
return False ;
}
if ( ! asn1_end_tag ( & data ) ) { /*CONTEXT*/
2006-02-06 04:21:17 +03:00
return False ;
}
} else {
lvrc - > type = 1 ;
2006-02-22 04:31:35 +03:00
if ( ! asn1_start_tag ( & data , ASN1_CONTEXT ( 1 ) ) ) {
return False ;
}
2006-02-06 04:21:17 +03:00
if ( ! asn1_read_OctetString ( & data , & assertion_value ) ) {
return False ;
}
lvrc - > match . gtOrEq . value_len = assertion_value . length ;
if ( lvrc - > match . gtOrEq . value_len ) {
lvrc - > match . gtOrEq . value = talloc_memdup ( lvrc , assertion_value . data , assertion_value . length ) ;
if ( ! ( lvrc - > match . gtOrEq . value ) ) {
return False ;
}
} else {
lvrc - > match . gtOrEq . value = NULL ;
}
2006-02-22 04:31:35 +03:00
if ( ! asn1_end_tag ( & data ) ) { /*CONTEXT*/
return False ;
}
2006-02-06 04:21:17 +03:00
}
if ( asn1_peek_tag ( & data , ASN1_OCTET_STRING ) ) {
if ( ! asn1_read_OctetString ( & data , & context_id ) ) {
return False ;
}
lvrc - > ctxid_len = context_id . length ;
if ( lvrc - > ctxid_len ) {
lvrc - > contextId = talloc_memdup ( lvrc , context_id . data , context_id . length ) ;
if ( ! ( lvrc - > contextId ) ) {
return False ;
}
} else {
lvrc - > contextId = NULL ;
}
} else {
lvrc - > contextId = NULL ;
lvrc - > ctxid_len = 0 ;
}
if ( ! asn1_end_tag ( & data ) ) {
return False ;
}
* out = lvrc ;
return True ;
}
static BOOL decode_vlv_response ( void * mem_ctx , DATA_BLOB in , void * * out )
{
DATA_BLOB context_id ;
struct asn1_data data ;
struct ldb_vlv_resp_control * lvrc ;
if ( ! asn1_load ( & data , in ) ) {
return False ;
}
lvrc = talloc ( mem_ctx , struct ldb_vlv_resp_control ) ;
if ( ! lvrc ) {
return False ;
}
if ( ! asn1_start_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_read_Integer ( & data , & ( lvrc - > targetPosition ) ) ) {
return False ;
}
if ( ! asn1_read_Integer ( & data , & ( lvrc - > contentCount ) ) ) {
return False ;
}
if ( ! asn1_read_enumerated ( & data , & ( lvrc - > vlv_result ) ) ) {
return False ;
}
if ( asn1_peek_tag ( & data , ASN1_OCTET_STRING ) ) {
if ( ! asn1_read_OctetString ( & data , & context_id ) ) {
return False ;
}
lvrc - > contextId = talloc_strndup ( lvrc , ( const char * ) context_id . data , context_id . length ) ;
if ( ! lvrc - > contextId ) {
return False ;
}
lvrc - > ctxid_len = context_id . length ;
} else {
lvrc - > contextId = NULL ;
lvrc - > ctxid_len = 0 ;
}
if ( ! asn1_end_tag ( & data ) ) {
return False ;
}
* out = lvrc ;
return True ;
}
2006-01-06 07:01:23 +03:00
static BOOL encode_server_sort_response ( void * mem_ctx , void * in , DATA_BLOB * out )
{
struct ldb_sort_resp_control * lsrc = talloc_get_type ( in , struct ldb_sort_resp_control ) ;
struct asn1_data data ;
ZERO_STRUCT ( data ) ;
if ( ! asn1_push_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_write_enumerated ( & data , lsrc - > result ) ) {
return False ;
}
if ( lsrc - > attr_desc ) {
if ( ! asn1_write_OctetString ( & data , lsrc - > attr_desc , strlen ( lsrc - > attr_desc ) ) ) {
return False ;
}
}
if ( ! asn1_pop_tag ( & data ) ) {
return False ;
}
* out = data_blob_talloc ( mem_ctx , data . data , data . length ) ;
if ( out - > data = = NULL ) {
return False ;
}
return True ;
}
static BOOL encode_server_sort_request ( void * mem_ctx , void * in , DATA_BLOB * out )
{
struct ldb_server_sort_control * * lssc = talloc_get_type ( in , struct ldb_server_sort_control * ) ;
struct asn1_data data ;
int num ;
ZERO_STRUCT ( data ) ;
if ( ! asn1_push_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
for ( num = 0 ; lssc [ num ] ; num + + ) {
if ( ! asn1_push_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_write_OctetString ( & data , lssc [ num ] - > attributeName , strlen ( lssc [ num ] - > attributeName ) ) ) {
return False ;
}
if ( lssc [ num ] - > orderingRule ) {
if ( ! asn1_write_OctetString ( & data , lssc [ num ] - > orderingRule , strlen ( lssc [ num ] - > orderingRule ) ) ) {
return False ;
}
}
if ( lssc [ num ] - > reverse ) {
if ( ! asn1_write_BOOLEAN ( & data , lssc [ num ] - > reverse ) ) {
return False ;
}
}
if ( ! asn1_pop_tag ( & data ) ) {
return False ;
}
}
if ( ! asn1_pop_tag ( & data ) ) {
return False ;
}
* out = data_blob_talloc ( mem_ctx , data . data , data . length ) ;
if ( out - > data = = NULL ) {
return False ;
}
return True ;
}
static BOOL encode_extended_dn_request ( void * mem_ctx , void * in , DATA_BLOB * out )
{
struct ldb_extended_dn_control * ledc = talloc_get_type ( in , struct ldb_extended_dn_control ) ;
struct asn1_data data ;
ZERO_STRUCT ( data ) ;
if ( ! asn1_push_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_write_Integer ( & data , ledc - > type ) ) {
return False ;
}
if ( ! asn1_pop_tag ( & data ) ) {
return False ;
}
* out = data_blob_talloc ( mem_ctx , data . data , data . length ) ;
if ( out - > data = = NULL ) {
return False ;
}
return True ;
}
2006-08-05 14:26:23 +04:00
static BOOL encode_sd_flags_request ( void * mem_ctx , void * in , DATA_BLOB * out )
{
struct ldb_sd_flags_control * lsdfc = talloc_get_type ( in , struct ldb_sd_flags_control ) ;
struct asn1_data data ;
ZERO_STRUCT ( data ) ;
if ( ! asn1_push_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_write_Integer ( & data , lsdfc - > secinfo_flags ) ) {
return False ;
}
if ( ! asn1_pop_tag ( & data ) ) {
return False ;
}
* out = data_blob_talloc ( mem_ctx , data . data , data . length ) ;
if ( out - > data = = NULL ) {
return False ;
}
return True ;
}
2006-08-05 15:18:14 +04:00
static BOOL encode_search_options_request ( void * mem_ctx , void * in , DATA_BLOB * out )
{
struct ldb_search_options_control * lsoc = talloc_get_type ( in , struct ldb_search_options_control ) ;
struct asn1_data data ;
ZERO_STRUCT ( data ) ;
if ( ! asn1_push_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_write_Integer ( & data , lsoc - > search_options ) ) {
return False ;
}
if ( ! asn1_pop_tag ( & data ) ) {
return False ;
}
* out = data_blob_talloc ( mem_ctx , data . data , data . length ) ;
if ( out - > data = = NULL ) {
return False ;
}
return True ;
}
2006-01-06 07:01:23 +03:00
static BOOL encode_paged_results_request ( void * mem_ctx , void * in , DATA_BLOB * out )
{
struct ldb_paged_control * lprc = talloc_get_type ( in , struct ldb_paged_control ) ;
struct asn1_data data ;
ZERO_STRUCT ( data ) ;
if ( ! asn1_push_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_write_Integer ( & data , lprc - > size ) ) {
return False ;
}
if ( ! asn1_write_OctetString ( & data , lprc - > cookie , lprc - > cookie_len ) ) {
return False ;
}
if ( ! asn1_pop_tag ( & data ) ) {
return False ;
}
* out = data_blob_talloc ( mem_ctx , data . data , data . length ) ;
if ( out - > data = = NULL ) {
return False ;
}
return True ;
}
2006-01-14 04:06:16 +03:00
/* seem that this controls has 2 forms one in case it is used with
* a Search Request and another when used ina Search Response
*/
static BOOL encode_asq_control ( void * mem_ctx , void * in , DATA_BLOB * out )
{
struct ldb_asq_control * lac = talloc_get_type ( in , struct ldb_asq_control ) ;
struct asn1_data data ;
ZERO_STRUCT ( data ) ;
if ( ! asn1_push_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( lac - > request ) {
if ( ! asn1_write_OctetString ( & data , lac - > source_attribute , lac - > src_attr_len ) ) {
return False ;
}
} else {
if ( ! asn1_write_enumerated ( & data , lac - > result ) ) {
return False ;
}
}
if ( ! asn1_pop_tag ( & data ) ) {
return False ;
}
* out = data_blob_talloc ( mem_ctx , data . data , data . length ) ;
if ( out - > data = = NULL ) {
return False ;
}
return True ;
}
2006-01-17 07:04:57 +03:00
static BOOL encode_dirsync_request ( void * mem_ctx , void * in , DATA_BLOB * out )
{
struct ldb_dirsync_control * ldc = talloc_get_type ( in , struct ldb_dirsync_control ) ;
struct asn1_data data ;
ZERO_STRUCT ( data ) ;
if ( ! asn1_push_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_write_Integer ( & data , ldc - > flags ) ) {
return False ;
}
if ( ! asn1_write_Integer ( & data , ldc - > max_attributes ) ) {
return False ;
}
if ( ! asn1_write_OctetString ( & data , ldc - > cookie , ldc - > cookie_len ) ) {
return False ;
}
if ( ! asn1_pop_tag ( & data ) ) {
return False ;
}
* out = data_blob_talloc ( mem_ctx , data . data , data . length ) ;
if ( out - > data = = NULL ) {
return False ;
}
return True ;
}
2006-08-05 15:38:50 +04:00
static BOOL encode_domain_scope_request ( void * mem_ctx , void * in , DATA_BLOB * out )
{
if ( in ) {
return False ;
}
* out = data_blob ( NULL , 0 ) ;
return True ;
}
2006-01-17 21:56:04 +03:00
static BOOL encode_notification_request ( void * mem_ctx , void * in , DATA_BLOB * out )
{
if ( in ) {
return False ;
}
* out = data_blob ( NULL , 0 ) ;
return True ;
}
2006-08-05 23:35:00 +04:00
static BOOL encode_show_deleted_request ( void * mem_ctx , void * in , DATA_BLOB * out )
{
if ( in ) {
return False ;
}
* out = data_blob ( NULL , 0 ) ;
return True ;
}
2006-08-05 23:50:58 +04:00
static BOOL encode_permissive_modify_request ( void * mem_ctx , void * in , DATA_BLOB * out )
{
if ( in ) {
return False ;
}
* out = data_blob ( NULL , 0 ) ;
return True ;
}
2006-02-05 20:28:27 +03:00
static BOOL encode_manageDSAIT_request ( void * mem_ctx , void * in , DATA_BLOB * out )
{
if ( in ) {
return False ;
}
* out = data_blob ( NULL , 0 ) ;
return True ;
}
2006-02-06 04:21:17 +03:00
static BOOL encode_vlv_request ( void * mem_ctx , void * in , DATA_BLOB * out )
{
struct ldb_vlv_req_control * lvrc = talloc_get_type ( in , struct ldb_vlv_req_control ) ;
struct asn1_data data ;
ZERO_STRUCT ( data ) ;
if ( ! asn1_push_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_write_Integer ( & data , lvrc - > beforeCount ) ) {
return False ;
}
if ( ! asn1_write_Integer ( & data , lvrc - > afterCount ) ) {
return False ;
}
if ( lvrc - > type = = 0 ) {
2006-02-22 04:31:35 +03:00
if ( ! asn1_push_tag ( & data , ASN1_CONTEXT ( 0 ) ) ) {
return False ;
}
2006-02-07 01:55:34 +03:00
if ( ! asn1_push_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
2006-02-06 04:21:17 +03:00
if ( ! asn1_write_Integer ( & data , lvrc - > match . byOffset . offset ) ) {
return False ;
}
if ( ! asn1_write_Integer ( & data , lvrc - > match . byOffset . contentCount ) ) {
return False ;
}
2006-02-07 01:55:34 +03:00
2006-02-22 04:31:35 +03:00
if ( ! asn1_pop_tag ( & data ) ) { /*SEQUENCE*/
return False ;
}
if ( ! asn1_pop_tag ( & data ) ) { /*CONTEXT*/
2006-02-07 01:55:34 +03:00
return False ;
}
2006-02-06 04:21:17 +03:00
} else {
2006-02-22 04:31:35 +03:00
if ( ! asn1_push_tag ( & data , ASN1_CONTEXT ( 1 ) ) ) {
return False ;
}
2006-02-06 04:21:17 +03:00
if ( ! asn1_write_OctetString ( & data , lvrc - > match . gtOrEq . value , lvrc - > match . gtOrEq . value_len ) ) {
return False ;
}
2006-02-22 04:31:35 +03:00
if ( ! asn1_pop_tag ( & data ) ) { /*CONTEXT*/
return False ;
}
2006-02-06 04:21:17 +03:00
}
if ( lvrc - > ctxid_len ) {
if ( ! asn1_write_OctetString ( & data , lvrc - > contextId , lvrc - > ctxid_len ) ) {
return False ;
}
}
if ( ! asn1_pop_tag ( & data ) ) {
return False ;
}
* out = data_blob_talloc ( mem_ctx , data . data , data . length ) ;
if ( out - > data = = NULL ) {
return False ;
}
return True ;
}
static BOOL encode_vlv_response ( void * mem_ctx , void * in , DATA_BLOB * out )
{
struct ldb_vlv_resp_control * lvrc = talloc_get_type ( in , struct ldb_vlv_resp_control ) ;
struct asn1_data data ;
ZERO_STRUCT ( data ) ;
if ( ! asn1_push_tag ( & data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_write_Integer ( & data , lvrc - > targetPosition ) ) {
return False ;
}
if ( ! asn1_write_Integer ( & data , lvrc - > contentCount ) ) {
return False ;
}
if ( ! asn1_write_enumerated ( & data , lvrc - > vlv_result ) ) {
return False ;
}
if ( lvrc - > ctxid_len ) {
if ( ! asn1_write_OctetString ( & data , lvrc - > contextId , lvrc - > ctxid_len ) ) {
return False ;
}
}
if ( ! asn1_pop_tag ( & data ) ) {
return False ;
}
* out = data_blob_talloc ( mem_ctx , data . data , data . length ) ;
if ( out - > data = = NULL ) {
return False ;
}
return True ;
}
2006-01-06 07:01:23 +03:00
struct control_handler ldap_known_controls [ ] = {
{ " 1.2.840.113556.1.4.319 " , decode_paged_results_request , encode_paged_results_request } ,
{ " 1.2.840.113556.1.4.529 " , decode_extended_dn_request , encode_extended_dn_request } ,
{ " 1.2.840.113556.1.4.473 " , decode_server_sort_request , encode_server_sort_request } ,
{ " 1.2.840.113556.1.4.474 " , decode_server_sort_response , encode_server_sort_response } ,
2006-01-14 04:06:16 +03:00
{ " 1.2.840.113556.1.4.1504 " , decode_asq_control , encode_asq_control } ,
2006-01-17 07:04:57 +03:00
{ " 1.2.840.113556.1.4.841 " , decode_dirsync_request , encode_dirsync_request } ,
2006-01-17 21:56:04 +03:00
{ " 1.2.840.113556.1.4.528 " , decode_notification_request , encode_notification_request } ,
2006-08-05 23:35:00 +04:00
{ " 1.2.840.113556.1.4.417 " , decode_show_deleted_request , encode_show_deleted_request } ,
2006-08-05 23:50:58 +04:00
{ " 1.2.840.113556.1.4.1413 " , decode_permissive_modify_request , encode_permissive_modify_request } ,
2006-08-05 14:26:23 +04:00
{ " 1.2.840.113556.1.4.801 " , decode_sd_flags_request , encode_sd_flags_request } ,
2006-08-05 15:38:50 +04:00
{ " 1.2.840.113556.1.4.1339 " , decode_domain_scope_request , encode_domain_scope_request } ,
2006-08-05 15:18:14 +04:00
{ " 1.2.840.113556.1.4.1340 " , decode_search_options_request , encode_search_options_request } ,
2006-02-05 20:28:27 +03:00
{ " 2.16.840.1.113730.3.4.2 " , decode_manageDSAIT_request , encode_manageDSAIT_request } ,
2006-02-06 04:21:17 +03:00
{ " 2.16.840.1.113730.3.4.9 " , decode_vlv_request , encode_vlv_request } ,
{ " 2.16.840.1.113730.3.4.10 " , decode_vlv_response , encode_vlv_response } ,
2007-03-13 03:59:06 +03:00
/* DSDB_CONTROL_CURRENT_PARTITION_OID is internal only, and has no network representation */
{ " 1.3.6.1.4.1.7165.4.3.2 " , NULL , NULL } ,
/* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */
{ " 1.3.6.1.4.1.7165.4.4.1 " , NULL , NULL } ,
2006-01-06 07:01:23 +03:00
{ NULL , NULL , NULL }
} ;
2007-03-13 03:59:06 +03:00
BOOL ldap_decode_control_value ( void * mem_ctx , DATA_BLOB value , struct ldb_control * ctrl )
2006-01-06 07:01:23 +03:00
{
int i ;
2007-03-13 03:59:06 +03:00
for ( i = 0 ; ldap_known_controls [ i ] . oid ! = NULL ; i + + ) {
if ( strcmp ( ldap_known_controls [ i ] . oid , ctrl - > oid ) = = 0 ) {
if ( ! ldap_known_controls [ i ] . decode | | ! ldap_known_controls [ i ] . decode ( mem_ctx , value , & ctrl - > data ) ) {
return False ;
}
break ;
}
}
if ( ldap_known_controls [ i ] . oid = = NULL ) {
return False ;
}
return True ;
}
BOOL ldap_decode_control_wrapper ( void * mem_ctx , struct asn1_data * data , struct ldb_control * ctrl , DATA_BLOB * value )
{
2006-01-06 07:01:23 +03:00
DATA_BLOB oid ;
if ( ! asn1_start_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
if ( ! asn1_read_OctetString ( data , & oid ) ) {
return False ;
}
ctrl - > oid = talloc_strndup ( mem_ctx , ( char * ) oid . data , oid . length ) ;
2006-02-15 18:19:10 +03:00
if ( ! ctrl - > oid ) {
2006-01-06 07:01:23 +03:00
return False ;
}
if ( asn1_peek_tag ( data , ASN1_BOOLEAN ) ) {
2006-05-01 00:00:37 +04:00
BOOL critical ;
2006-04-30 17:54:03 +04:00
if ( ! asn1_read_BOOLEAN ( data , & critical ) ) {
2006-01-06 07:01:23 +03:00
return False ;
}
2006-05-01 00:00:37 +04:00
ctrl - > critical = critical ;
2006-01-06 07:01:23 +03:00
} else {
ctrl - > critical = False ;
}
2006-02-22 04:31:35 +03:00
ctrl - > data = NULL ;
2006-01-06 07:01:23 +03:00
2006-02-15 18:19:10 +03:00
if ( ! asn1_peek_tag ( data , ASN1_OCTET_STRING ) ) {
goto end_tag ;
}
2007-03-13 03:59:06 +03:00
if ( ! asn1_read_OctetString ( data , value ) ) {
2006-01-06 07:01:23 +03:00
return False ;
}
2006-02-15 18:19:10 +03:00
end_tag :
2006-01-06 07:01:23 +03:00
if ( ! asn1_end_tag ( data ) ) {
return False ;
}
return True ;
}
2006-02-22 04:31:35 +03:00
BOOL ldap_encode_control ( void * mem_ctx , struct asn1_data * data , struct ldb_control * ctrl )
2006-01-06 07:01:23 +03:00
{
DATA_BLOB value ;
int i ;
2007-03-13 03:59:06 +03:00
for ( i = 0 ; ldap_known_controls [ i ] . oid ! = NULL ; i + + ) {
if ( strcmp ( ldap_known_controls [ i ] . oid , ctrl - > oid ) = = 0 ) {
if ( ! ldap_known_controls [ i ] . encode ) {
if ( ctrl - > critical ) {
return False ;
} else {
/* not encoding this control */
return True ;
}
}
if ( ! ldap_known_controls [ i ] . encode ( mem_ctx , ctrl - > data , & value ) ) {
return False ;
}
break ;
}
}
if ( ldap_known_controls [ i ] . oid = = NULL ) {
return False ;
}
2006-01-06 07:01:23 +03:00
if ( ! asn1_push_tag ( data , ASN1_SEQUENCE ( 0 ) ) ) {
return False ;
}
2006-02-15 18:19:10 +03:00
2006-01-06 07:01:23 +03:00
if ( ! asn1_write_OctetString ( data , ctrl - > oid , strlen ( ctrl - > oid ) ) ) {
return False ;
}
2006-02-15 18:19:10 +03:00
2006-01-06 07:01:23 +03:00
if ( ctrl - > critical ) {
if ( ! asn1_write_BOOLEAN ( data , ctrl - > critical ) ) {
return False ;
}
}
2006-02-22 04:31:35 +03:00
if ( ! ctrl - > data ) {
2006-02-15 18:19:10 +03:00
goto pop_tag ;
}
if ( ! asn1_write_OctetString ( data , value . data , value . length ) ) {
return False ;
2006-01-06 07:01:23 +03:00
}
2006-02-15 18:19:10 +03:00
pop_tag :
2006-01-06 07:01:23 +03:00
if ( ! asn1_pop_tag ( data ) ) {
return False ;
}
return True ;
}