1 /* search.c - DNS SRV backend search function */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/search.c,v 1.44.2.4 2008/02/11 23:26:46 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2000-2008 The OpenLDAP Foundation.
6 * Portions Copyright 2000-2003 Kurt D. Zeilenga.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
18 * This work was originally developed by Kurt D. Zeilenga for inclusion
19 * in OpenLDAP Software.
26 #include <ac/socket.h>
27 #include <ac/string.h>
31 #include "proto-dnssrv.h"
41 char *hostlist
= NULL
;
44 struct berval nrefdn
= BER_BVNULL
;
45 BerVarray urls
= NULL
;
50 if ( BER_BVISEMPTY( &op
->o_req_ndn
) ) {
51 /* FIXME: need some means to determine whether the database
52 * is a glue instance; if we got here with empty DN, then
53 * we passed this same test in dnssrv_back_referrals() */
54 if ( !SLAP_GLUE_INSTANCE( op
->o_bd
) ) {
55 rs
->sr_err
= LDAP_UNWILLING_TO_PERFORM
;
56 rs
->sr_text
= "DNS SRV operation upon null (empty) DN disallowed";
59 rs
->sr_err
= LDAP_SUCCESS
;
64 manageDSAit
= get_manageDSAit( op
);
66 * FIXME: we may return a referral if manageDSAit is not set
69 send_ldap_error( op
, rs
, LDAP_UNWILLING_TO_PERFORM
,
70 "manageDSAit must be set" );
74 if( ldap_dn2domain( op
->o_req_dn
.bv_val
, &domain
) || domain
== NULL
) {
75 rs
->sr_err
= LDAP_REFERRAL
;
76 rs
->sr_ref
= default_referral
;
77 send_ldap_result( op
, rs
);
82 Debug( LDAP_DEBUG_TRACE
, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n",
83 op
->o_req_dn
.bv_len
? op
->o_req_dn
.bv_val
: "", domain
, 0 );
85 if( ( rc
= ldap_domain2hostlist( domain
, &hostlist
) ) ) {
86 Debug( LDAP_DEBUG_TRACE
, "DNSSRV: domain2hostlist returned %d\n",
88 send_ldap_error( op
, rs
, LDAP_NO_SUCH_OBJECT
,
89 "no DNS SRV RR available for DN" );
93 hosts
= ldap_str2charray( hostlist
, " " );
96 Debug( LDAP_DEBUG_TRACE
, "DNSSRV: str2charrary error\n", 0, 0, 0 );
97 send_ldap_error( op
, rs
, LDAP_OTHER
,
98 "problem processing DNS SRV records for DN" );
102 for( i
=0; hosts
[i
] != NULL
; i
++) {
105 url
.bv_len
= STRLENOF( "ldap://" ) + strlen(hosts
[i
]);
106 url
.bv_val
= ch_malloc( url
.bv_len
+ 1 );
108 strcpy( url
.bv_val
, "ldap://" );
109 strcpy( &url
.bv_val
[STRLENOF( "ldap://" )], hosts
[i
] );
111 if( ber_bvarray_add( &urls
, &url
) < 0 ) {
113 send_ldap_error( op
, rs
, LDAP_OTHER
,
114 "problem processing DNS SRV records for DN" );
119 Statslog( LDAP_DEBUG_STATS
,
120 "%s DNSSRV p=%d dn=\"%s\" url=\"%s\"\n",
121 op
->o_log_prefix
, op
->o_protocol
,
122 op
->o_req_dn
.bv_len
? op
->o_req_dn
.bv_val
: "", urls
[0].bv_val
, 0 );
124 Debug( LDAP_DEBUG_TRACE
,
125 "DNSSRV: ManageDSAit scope=%d dn=\"%s\" -> url=\"%s\"\n",
126 op
->oq_search
.rs_scope
,
127 op
->o_req_dn
.bv_len
? op
->o_req_dn
.bv_val
: "",
130 rc
= ldap_domain2dn(domain
, &refdn
);
132 if( rc
!= LDAP_SUCCESS
) {
133 send_ldap_error( op
, rs
, LDAP_OTHER
,
134 "DNS SRV problem processing manageDSAit control" );
140 bv
.bv_len
= strlen( refdn
);
142 rc
= dnNormalize( 0, NULL
, NULL
, &bv
, &nrefdn
, op
->o_tmpmemctx
);
143 if( rc
!= LDAP_SUCCESS
) {
144 send_ldap_error( op
, rs
, LDAP_OTHER
,
145 "DNS SRV problem processing manageDSAit control" );
150 if( !dn_match( &nrefdn
, &op
->o_req_ndn
) ) {
151 /* requested dn is subordinate */
153 Debug( LDAP_DEBUG_TRACE
,
154 "DNSSRV: dn=\"%s\" subordinate to refdn=\"%s\"\n",
155 op
->o_req_dn
.bv_len
? op
->o_req_dn
.bv_val
: "",
156 refdn
== NULL
? "" : refdn
,
159 rs
->sr_matched
= refdn
;
160 rs
->sr_err
= LDAP_NO_SUCH_OBJECT
;
161 send_ldap_result( op
, rs
);
162 rs
->sr_matched
= NULL
;
164 } else if ( op
->oq_search
.rs_scope
== LDAP_SCOPE_ONELEVEL
) {
165 send_ldap_error( op
, rs
, LDAP_SUCCESS
, NULL
);
169 AttributeDescription
*ad_objectClass
170 = slap_schema
.si_ad_objectClass
;
171 AttributeDescription
*ad_ref
= slap_schema
.si_ad_ref
;
172 e
.e_name
.bv_val
= strdup( op
->o_req_dn
.bv_val
);
173 e
.e_name
.bv_len
= op
->o_req_dn
.bv_len
;
174 e
.e_nname
.bv_val
= strdup( op
->o_req_ndn
.bv_val
);
175 e
.e_nname
.bv_len
= op
->o_req_ndn
.bv_len
;
180 attr_merge_one( &e
, ad_objectClass
, &slap_schema
.si_oc_referral
->soc_cname
, NULL
);
181 attr_merge_one( &e
, ad_objectClass
, &slap_schema
.si_oc_extensibleObject
->soc_cname
, NULL
);
189 p
= strchr( bv
.bv_val
, '.' );
191 if ( p
== bv
.bv_val
) {
194 } else if ( p
!= NULL
) {
195 bv
.bv_len
= p
- bv
.bv_val
;
198 bv
.bv_len
= strlen( bv
.bv_val
);
201 attr_merge_normalize_one( &e
, ad_dc
, &bv
, NULL
);
204 if ( ad_associatedDomain
) {
207 ber_str2bv( domain
, 0, 0, &bv
);
208 attr_merge_normalize_one( &e
, ad_associatedDomain
, &bv
, NULL
);
211 attr_merge_normalize_one( &e
, ad_ref
, urls
, NULL
);
213 rc
= test_filter( op
, &e
, op
->oq_search
.rs_filter
);
215 if( rc
== LDAP_COMPARE_TRUE
) {
217 rs
->sr_attrs
= op
->oq_search
.rs_attrs
;
218 rs
->sr_flags
= REP_ENTRY_MODIFIABLE
;
219 send_search_entry( op
, rs
);
226 rs
->sr_err
= LDAP_SUCCESS
;
227 send_ldap_result( op
, rs
);
230 if ( refdn
) free( refdn
);
231 if ( nrefdn
.bv_val
) free( nrefdn
.bv_val
);
234 if( domain
!= NULL
) ch_free( domain
);
235 if( hostlist
!= NULL
) ch_free( hostlist
);
236 if( hosts
!= NULL
) ldap_charray_free( hosts
);
237 if( urls
!= NULL
) ber_bvarray_free( urls
);