]> git.sur5r.net Git - openldap/blob - servers/slapd/back-dnssrv/search.c
Major API change - (SLAP_OP_BLOCKS) All request parameters are
[openldap] / servers / slapd / back-dnssrv / search.c
1 /* search.c - DNS SRV backend search function */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 2000-2003 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8
9 #include "portable.h"
10
11 #include <stdio.h>
12
13 #include <ac/socket.h>
14 #include <ac/string.h>
15 #include <ac/time.h>
16
17 #include "slap.h"
18 #include "external.h"
19
20 int
21 dnssrv_back_search(
22     Operation   *op,
23     SlapReply   *rs )
24 {
25         int i;
26         int rc;
27         char *domain = NULL;
28         char *hostlist = NULL;
29         char **hosts = NULL;
30         char *refdn;
31         struct berval nrefdn = { 0, NULL };
32         BerVarray urls = NULL;
33
34         assert( get_manageDSAit( op ) );
35
36         if( ldap_dn2domain( op->o_req_dn.bv_val, &domain ) || domain == NULL ) {
37                 rs->sr_err = LDAP_REFERRAL;
38                 rs->sr_ref = default_referral;
39                 send_ldap_result( op, rs );
40                 goto done;
41         }
42
43         Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n",
44                 op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", domain, 0 );
45
46         if( ( rc = ldap_domain2hostlist( domain, &hostlist ) ) ) {
47                 Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist returned %d\n",
48                         rc, 0, 0 );
49                 send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT,
50                         "no DNS SRV RR available for DN" );
51                 goto done;
52         }
53
54         hosts = ldap_str2charray( hostlist, " " );
55
56         if( hosts == NULL ) {
57                 Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charrary error\n", 0, 0, 0 );
58                 send_ldap_error( op, rs, LDAP_OTHER,
59                         "problem processing DNS SRV records for DN" );
60                 goto done;
61         }
62
63         for( i=0; hosts[i] != NULL; i++) {
64                 struct berval url;
65
66                 url.bv_len = sizeof("ldap://")-1 + strlen(hosts[i]);
67                 url.bv_val = ch_malloc( url.bv_len + 1 );
68
69                 strcpy( url.bv_val, "ldap://" );
70                 strcpy( &url.bv_val[sizeof("ldap://")-1], hosts[i] );
71
72                 if( ber_bvarray_add( &urls, &url ) < 0 ) {
73                         free( url.bv_val );
74                         send_ldap_error( op, rs, LDAP_OTHER,
75                         "problem processing DNS SRV records for DN" );
76                         goto done;
77                 }
78         }
79
80         Statslog( LDAP_DEBUG_STATS,
81             "conn=%lu op=%lu DNSSRV p=%d dn=\"%s\" url=\"%s\"\n",
82             op->o_connid, op->o_opid, op->o_protocol,
83                 op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", urls[0].bv_val );
84
85         Debug( LDAP_DEBUG_TRACE,
86                 "DNSSRV: ManageDSAit scope=%d dn=\"%s\" -> url=\"%s\"\n",
87                 op->oq_search.rs_scope,
88                 op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "",
89                 urls[0].bv_val );
90
91         rc = ldap_domain2dn(domain, &refdn);
92
93         if( rc != LDAP_SUCCESS ) {
94                 send_ldap_error( op, rs, LDAP_OTHER,
95                         "DNS SRV problem processing manageDSAit control" );
96                 goto done;
97
98         } else {
99                 struct berval bv;
100                 bv.bv_val = refdn;
101                 bv.bv_len = strlen( refdn );
102
103                 rc = dnNormalize2( NULL, &bv, &nrefdn );
104                 if( rc != LDAP_SUCCESS ) {
105                         send_ldap_error( op, rs, LDAP_OTHER,
106                                 "DNS SRV problem processing manageDSAit control" );
107                         goto done;
108                 }
109         }
110
111         if( !dn_match( &nrefdn, &op->o_req_ndn ) ) {
112                 /* requested dn is subordinate */
113
114                 Debug( LDAP_DEBUG_TRACE,
115                         "DNSSRV: dn=\"%s\" subordinate to refdn=\"%s\"\n",
116                         op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "",
117                         refdn == NULL ? "" : refdn,
118                         NULL );
119
120                 rs->sr_matched = refdn;
121                 rs->sr_err = LDAP_NO_SUCH_OBJECT;
122                 send_ldap_result( op, rs );
123
124         } else if ( op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL ) {
125                 send_ldap_error( op, rs, LDAP_SUCCESS, NULL );
126
127         } else {
128                 struct berval   vals[2];
129                 Entry *e = ch_calloc( 1, sizeof(Entry) );
130                 AttributeDescription *ad_objectClass
131                         = slap_schema.si_ad_objectClass;
132                 AttributeDescription *ad_ref = slap_schema.si_ad_ref;
133                 e->e_name.bv_val = strdup( op->o_req_dn.bv_val );
134                 e->e_name.bv_len = op->o_req_dn.bv_len;
135                 e->e_nname.bv_val = strdup( op->o_req_ndn.bv_val );
136                 e->e_nname.bv_len = op->o_req_ndn.bv_len;
137
138                 e->e_attrs = NULL;
139                 e->e_private = NULL;
140
141                 vals[1].bv_val = NULL;
142
143                 vals[0].bv_val = "top";
144                 vals[0].bv_len = sizeof("top")-1;
145                 attr_mergeit( e, ad_objectClass, vals );
146
147                 vals[0].bv_val = "referral";
148                 vals[0].bv_len = sizeof("referral")-1;
149                 attr_mergeit( e, ad_objectClass, vals );
150
151                 vals[0].bv_val = "extensibleObject";
152                 vals[0].bv_len = sizeof("extensibleObject")-1;
153                 attr_mergeit( e, ad_objectClass, vals );
154
155                 {
156                         AttributeDescription *ad = NULL;
157                         const char *text;
158
159                         rc = slap_str2ad( "dc", &ad, &text );
160
161                         if( rc == LDAP_SUCCESS ) {
162                                 char *p;
163                                 vals[0].bv_val = ch_strdup( domain );
164
165                                 p = strchr( vals[0].bv_val, '.' );
166                                         
167                                 if( p == vals[0].bv_val ) {
168                                         vals[0].bv_val[1] = '\0';
169                                 } else if ( p != NULL ) {
170                                         *p = '\0';
171                                 }
172
173                                 vals[0].bv_len = strlen(vals[0].bv_val);
174                                 attr_mergeit( e, ad, vals );
175                         }
176                 }
177
178                 {
179                         AttributeDescription *ad = NULL;
180                         const char *text;
181
182                         rc = slap_str2ad( "associatedDomain", &ad, &text );
183
184                         if( rc == LDAP_SUCCESS ) {
185                                 vals[0].bv_val = domain;
186                                 vals[0].bv_len = strlen(domain);
187                                 attr_mergeit( e, ad, vals );
188                         }
189                 }
190
191                 attr_mergeit( e, ad_ref, urls );
192
193                 rc = test_filter( op, e, op->oq_search.rs_filter ); 
194
195                 if( rc == LDAP_COMPARE_TRUE ) {
196                         rs->sr_entry = e;
197                         rs->sr_attrs = op->oq_search.rs_attrs;
198                         send_search_entry( op, rs );
199                 }
200
201                 entry_free( e );
202
203                 rs->sr_err = LDAP_SUCCESS;
204                 send_ldap_result( op, rs );
205         }
206
207         if ( refdn ) free( refdn );
208         if ( nrefdn.bv_val ) free( nrefdn.bv_val );
209
210 done:
211         if( domain != NULL ) ch_free( domain );
212         if( hostlist != NULL ) ch_free( hostlist );
213         if( hosts != NULL ) ldap_charray_free( hosts );
214         if( urls != NULL ) ber_bvarray_free( urls );
215         return 0;
216 }