2 * query.c: for rcpt500 (X.500 email query responder)
4 * 18 June 1992 by Mark C Smith
5 * Copyright (c) 1992 The Regents of The University of Michigan
14 #include <ac/string.h>
15 #include <ac/syslog.h>
23 #include "ldapconfig.h"
28 extern int derefaliases;
31 extern char *ldaphost;
32 extern char *searchbase;
34 extern char *filterfile;
35 extern char *templatefile;
37 static char buf[ MAXSIZE ];
38 static char *errpreface = "Your query failed: ";
40 extern int strcasecmp();
46 query_cmd( msgp, reply )
51 LDAPMessage *ldmsgp, *entry;
56 struct ldap_disptmpl *tmpllist = NULL;
57 static char *attrs[] = { "cn", "title",
58 #ifdef RCPT500_SORT_ATTR
65 if ( msgp->msg_arg == NULL ) {
66 return( help_cmd( msgp, reply ));
69 remove_trailing_space( msgp->msg_arg );
70 if ( *msgp->msg_arg == '\0' ) {
71 return( help_cmd( msgp, reply ));
74 if (( lfdp = ldap_init_getfilter( filterfile )) == NULL ) {
75 strcat( reply, errpreface );
76 strcat( reply, "filter file configuration error. Try again later." );
81 * open connection to LDAP server and bind as dapuser
83 #ifdef LDAP_CONNECTIONLESS
85 ldp = cldap_open( ldaphost, ldapport );
87 #endif /* LDAP_CONNECTIONLESS */
88 ldp = ldap_open( ldaphost, ldapport );
91 strcat( reply, errpreface );
92 strcat( reply, "X.500 service unavailable. Try again later." );
93 ldap_getfilter_free( lfdp );
97 #ifdef LDAP_CONNECTIONLESS
99 #endif /* LDAP_CONNECTIONLESS */
100 if ( ldap_simple_bind_s( ldp, dapuser, NULL ) != LDAP_SUCCESS ) {
101 report_ldap_err( ldp, reply );
103 ldap_getfilter_free( lfdp );
108 * set options for search and build filter
110 ldp->ld_deref = derefaliases;
111 ldp->ld_sizelimit = sizelimit;
116 #ifdef LDAP_CONNECTIONLESS
117 if ( !do_cldap && strchr( msgp->msg_arg, ',' ) != NULL ) {
118 #else /* LDAP_CONNECTIONLESS */
119 if ( strchr( msgp->msg_arg, ',' ) != NULL ) {
120 #endif /* LDAP_CONNECTIONLESS */
123 ldap_ufn_setprefix( ldp, searchbase );
124 if (( rc = ldap_ufn_search_s( ldp, msgp->msg_arg, attrs, 0, &ldmsgp ))
125 != LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED
126 && rc != LDAP_TIMELIMIT_EXCEEDED ) {
127 report_ldap_err( ldp, reply );
129 ldap_getfilter_free( lfdp );
132 matches = ldap_count_entries( ldp, ldmsgp );
135 #endif /* RCPT500_UFN */
137 for ( lfi = ldap_getfirstfilter( lfdp, "rcpt500", msgp->msg_arg );
138 lfi != NULL; lfi = ldap_getnextfilter( lfdp )) {
139 #ifdef LDAP_CONNECTIONLESS
141 rc = cldap_search_s( ldp, searchbase, LDAP_SCOPE_SUBTREE,
142 lfi->lfi_filter, attrs, 0, &ldmsgp, dapuser );
144 #endif /* LDAP_CONNECTIONLESS */
145 rc = ldap_search_s( ldp, searchbase, LDAP_SCOPE_SUBTREE,
146 lfi->lfi_filter, attrs, 0, &ldmsgp );
148 if ( rc != LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED
149 && rc != LDAP_TIMELIMIT_EXCEEDED ) {
150 report_ldap_err( ldp, reply );
152 ldap_getfilter_free( lfdp );
156 if (( matches = ldap_count_entries( ldp, ldmsgp )) != 0 ) {
160 if ( ldmsgp != NULL ) {
161 ldap_msgfree( ldmsgp );
166 #endif /* RCPT500_UFN */
168 if ( matches == 0 ) {
169 sprintf( buf, "No matches were found for '%s'\n", msgp->msg_arg );
170 strcat( reply, buf );
172 ldap_getfilter_free( lfdp );
176 if ( ldp->ld_errno == LDAP_TIMELIMIT_EXCEEDED
177 || ldp->ld_errno == LDAP_SIZELIMIT_EXCEEDED ) {
178 strcat( reply, "(Partial results only - a limit was exceeded)\n" );
181 if ( matches <= RCPT500_LISTLIMIT ) {
182 sprintf( buf, "%d %s match%s found for '%s':\n\n", matches,
183 ufn ? "UFN" : lfi->lfi_desc,
184 ( matches > 1 ) ? "es" : "", msgp->msg_arg );
185 strcat( reply, buf );
187 if (( rc = ldap_init_templates( templatefile, &tmpllist )) != 0 ) {
188 sprintf( buf, "%s ldap_init_templates( %s ) failed (error %d)\n",
189 errpreface, templatefile, rc );
190 strcat( reply, buf );
193 for ( entry = ldap_first_entry( ldp, ldmsgp ); entry != NULL; ) {
194 dn = ldap_get_dn( ldp, entry );
195 if ( do_read( ldp, dn, reply, tmpllist ) != LDAP_SUCCESS ) {
196 report_ldap_err( ldp, reply );
199 if (( entry = ldap_next_entry( ldp, entry )) != NULL ) {
200 strcat( reply, "\n-------\n\n" );
204 if ( tmpllist != NULL ) {
205 ldap_free_templates( tmpllist );
207 ldap_msgfree( ldmsgp );
210 sprintf( buf, "%d %s matches were found for '%s':\n",
211 matches, ufn ? "UFN" : lfi->lfi_desc, msgp->msg_arg );
212 strcat( reply, buf );
213 append_entry_list( reply, msgp->msg_arg, ldp, ldmsgp );
214 ldap_msgfree( ldmsgp );
218 ldap_getfilter_free( lfdp );
224 close_ldap( LDAP *ld )
226 #ifdef LDAP_CONNECTIONLESS
230 #endif /* LDAP_CONNECTIONLESS */
235 append_entry_list( reply, query, ldp, ldmsgp )
242 char *dn, *rdn, *s, **title;
245 #ifdef RCPT500_SORT_ATTR
246 ldap_sort_entries( ldp, &ldmsgp, RCPT500_SORT_ATTR, strcasecmp );
249 for ( e = ldap_first_entry( ldp, ldmsgp ); e != NULL;
250 e = ldap_next_entry( ldp, e )) {
251 dn = ldap_get_dn( ldp, e );
252 if (( s = strchr( dn, ',' )) != NULL ) {
255 if (( s = strchr( dn, '=' )) == NULL ) {
263 * if this entry's rdn is an exact match for the thing looked up, we
264 * return the CN that has a digit after it, so that the user is
265 * returned something guaranteed to yield exactly one match if they
266 * pick it from the list and query it
269 if ( strcasecmp( rdn, query ) == 0 ) {
273 if (( cn = ldap_get_values( ldp, e, "cn" )) != NULL ) {
274 for ( i = 0; cn[i] != NULL; i++ ) {
275 if ( isdigit( *( cn[i] + strlen( cn[i] ) - 1 ))) {
276 rdn = strdup( cn[i] );
281 ldap_value_free( cn );
286 title = ldap_get_values( ldp, e, "title" );
287 sprintf( buf, " %-20s %s\n", rdn, title ? title[0] : "" );
288 strcat( reply, buf );
289 if ( title != NULL ) {
290 ldap_value_free( title );
301 append_text( reply, text, len )
306 strcat( reply, text );
312 do_read( ldp, dn, reply, tmpll )
316 struct ldap_disptmpl *tmpll;
319 static char *maildefvals[] = { "None registered in this service", NULL };
320 static char *defattrs[] = { "mail", NULL };
321 static char **defvals[] = { maildefvals, NULL };
324 rc = ldap_entry2text_search( ldp, dn, searchbase, NULLMSG, tmpll,
325 defattrs, defvals, append_text, (void *)reply, "\n",
326 rdncount, LDAP_DISP_OPT_DOSEARCHACTIONS );
332 report_ldap_err( ldp, reply )
336 strcat( reply, errpreface );
337 strcat( reply, ldap_err2string( ldp->ld_errno ));
338 strcat( reply, "\n" );
342 remove_trailing_space( s )
345 char *p = s + strlen( s ) - 1;
347 while ( isspace( *p ) && p > s ) {