]> git.sur5r.net Git - openldap/blob - servers/slapd/back-dnssrv/request.c
Merge latest devel codes into releng 2 branch.
[openldap] / servers / slapd / back-dnssrv / request.c
1 /* add.c - DNS SRV backend request handler */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/string.h>
13 #include <ac/socket.h>
14
15 #include "slap.h"
16 #include "back-dnssrv.h"
17
18 int
19 dnssrv_back_request(
20     Backend     *be,
21     Connection  *conn,
22     Operation   *op,
23     const char *dn,
24     const char *ndn,
25         int scope, Filter *filter,
26         char **attrs, int attrsonly )
27 {
28         int i;
29         int rc;
30         char *domain = NULL;
31         char *hostlist = NULL;
32         char **hosts = NULL;
33         struct berval **urls = NULL;
34         int             manageDSAit = get_manageDSAit( op );
35
36         if( ndn == NULL || *ndn == '\0' ) {
37                 send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
38                         NULL, "operation upon null (empty) DN disallowed",
39                         NULL, NULL );
40                 goto done;
41         }
42
43         if( ldap_dn2domain( dn, &domain ) ) {
44                 send_ldap_result( conn, op, LDAP_REFERRAL,
45                         NULL, NULL, default_referral, NULL );
46                 goto done;
47         }
48
49         Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n",
50                 dn == NULL ? "" : dn,
51                 domain == NULL ? "" : domain,
52                 0 );
53
54         if( rc = ldap_domain2hostlist( domain, &hostlist ) ) {
55                 Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist returned %d\n",
56                         rc, 0, 0 );
57                 send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
58                         NULL, "no DNS SRV RR available for DN", NULL, NULL );
59                 goto done;
60         }
61
62         hosts = str2charray( hostlist, " " );
63
64         if( hosts == NULL ) {
65                 Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charrary error\n", 0, 0, 0 );
66                 send_ldap_result( conn, op, LDAP_OTHER,
67                         NULL, "problem processing DNS SRV records for DN", NULL, NULL );
68                 goto done;
69         }
70
71         for( i=0; hosts[i] != NULL; i++) {
72                 struct berval *url = ch_malloc( sizeof( struct berval ) ); 
73
74                 url->bv_len = sizeof("ldap://")-1 + strlen(hosts[i]);
75                 url->bv_val = ch_malloc( url->bv_len + 1 );
76
77                 strcpy( url->bv_val, "ldap://" );
78                 strcpy( &url->bv_val[sizeof("ldap://")-1], hosts[i] );
79
80                 if( ber_bvecadd( &urls, url ) < 0 ) {
81                         ber_bvfree( url );
82                         send_ldap_result( conn, op, LDAP_OTHER,
83                                 NULL, "problem processing DNS SRV records for DN",
84                                 NULL, NULL );
85                         goto done;
86                 }
87         }
88
89         Statslog( LDAP_DEBUG_STATS,
90             "conn=%ld op=%d DNSSRV p=%d dn=\"%s\" url=\"%s\"\n",
91             op->o_connid, op->o_opid, op->o_protocol, dn, urls[0]->bv_val );
92
93         Debug( LDAP_DEBUG_TRACE, "DNSSRV: %sdn=\"%s\" -> url=\"%s\"\n",
94                 manageDSAit ? "ManageDSAit " : "",
95                 dn == NULL ? "" : dn,
96                 urls[0]->bv_val );
97
98         if( manageDSAit ) {
99                 char *refdn, *nrefdn;
100                 rc = ldap_domain2dn(domain, &refdn);
101
102                 if( rc != LDAP_SUCCESS ) {
103                         send_ldap_result( conn, op, LDAP_OTHER,
104                                 NULL, "DNS SRV problem processing manageDSAit control",
105                                 NULL, NULL );
106                         goto done;
107                 }
108
109                 nrefdn = ch_strdup( refdn );
110                 dn_normalize(nrefdn);
111
112                 if( strcmp( nrefdn, ndn ) != 0 ) {
113                         /* requested dn is subordinate */
114
115                         Debug( LDAP_DEBUG_TRACE,
116                                         "DNSSRV: dn=\"%s\" subordindate to refdn=\"%s\"\n",
117                                         dn == NULL ? "" : dn,
118                                         refdn == NULL ? "" : refdn,
119                                         NULL );
120
121                         send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
122                                 refdn, NULL,
123                                 NULL, NULL );
124
125                 } else if( op->o_tag != LDAP_REQ_SEARCH ) {
126                         send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
127                                 dn, "DNS SRV ManageDSAIT control disallowed",
128                                 NULL, NULL );
129
130                 } else if ( scope != LDAP_SCOPE_ONELEVEL ) {
131                         struct berval   val;
132                         struct berval   *vals[2];
133                         Entry *e = ch_calloc( 1, sizeof(Entry) );
134                         AttributeDescription *ad_objectClass
135                                 = slap_schema.si_ad_objectClass;
136                         AttributeDescription *ad_ref = slap_schema.si_ad_ref;
137                         e->e_dn = strdup( dn );
138                         e->e_ndn = strdup( ndn );
139
140                         e->e_attrs = NULL;
141                         e->e_private = NULL;
142
143                         vals[0] = &val;
144                         vals[1] = NULL;
145
146                         val.bv_val = "top";
147                         val.bv_len = sizeof("top")-1;
148                         attr_merge( e, ad_objectClass, vals );
149
150                         val.bv_val = "referral";
151                         val.bv_len = sizeof("referral")-1;
152                         attr_merge( e, ad_objectClass, vals );
153
154                         val.bv_val = "extensibleObject";
155                         val.bv_len = sizeof("extensibleObject")-1;
156                         attr_merge( e, ad_objectClass, vals );
157
158                         {
159                                 AttributeDescription *ad = NULL;
160                                 const char *text;
161
162                                 rc = slap_str2ad( "dc", &ad, &text );
163
164                                 if( rc == LDAP_SUCCESS ) {
165                                         char *p;
166                                         val.bv_val = ch_strdup( domain );
167
168                                         p = strchr( val.bv_val, '.' );
169                                         
170                                         if( p == val.bv_val ) {
171                                                 val.bv_val[1] = '\0';
172                                         } else if ( p != NULL ) {
173                                                 *p = '\0';
174                                         }
175
176                                         val.bv_len = strlen(val.bv_val);
177                                         attr_merge( e, ad, vals );
178
179                                         ad_free( ad, 1 );
180                                 }
181                         }
182
183                         {
184                                 AttributeDescription *ad = NULL;
185                                 const char *text;
186
187                                 rc = slap_str2ad( "associatedDomain", &ad, &text );
188
189                                 if( rc == LDAP_SUCCESS ) {
190                                         val.bv_val = domain;
191                                         val.bv_len = strlen(domain);
192                                         attr_merge( e, ad, vals );
193
194                                         ad_free( ad, 1 );
195                                 }
196                         }
197
198                         attr_merge( e, ad_ref, urls );
199
200                         rc = test_filter( be, conn, op, e, filter ); 
201
202                         if( rc == LDAP_COMPARE_TRUE ) {
203                                 send_search_entry( be, conn, op,
204                                         e, attrs, attrsonly, NULL );
205                         }
206
207                         entry_free( e );
208                         
209                         send_ldap_result( conn, op, LDAP_SUCCESS,
210                                 NULL, NULL, NULL, NULL );
211
212                 } else {
213                         send_ldap_result( conn, op, LDAP_SUCCESS,
214                                 NULL, NULL, NULL, NULL );
215                 }
216
217                 free( refdn );
218                 free( nrefdn );
219
220         } else {
221                 send_ldap_result( conn, op, LDAP_REFERRAL,
222                         NULL, "DNS SRV generated referrals", urls, NULL );
223         }
224
225 done:
226         if( domain != NULL ) ch_free( domain );
227         if( hostlist != NULL ) ch_free( hostlist );
228         if( hosts != NULL ) charray_free( hosts );
229         if( urls != NULL ) ber_bvecfree( urls );
230         return 0;
231 }