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
18 #include "ldapconfig.h"
25 extern int derefaliases;
28 extern char *ldaphost;
29 extern char *searchbase;
31 extern char *filterfile;
32 extern char *templatefile;
34 static char buf[ MAXSIZE ];
35 static char *errpreface = "Your query failed: ";
37 extern int strcasecmp();
43 query_cmd( msgp, reply )
48 LDAPMessage *ldmsgp, *entry;
53 struct ldap_disptmpl *tmpllist = NULL;
54 static char *attrs[] = { "cn", "title",
55 #ifdef RCPT500_SORT_ATTR
62 if ( msgp->msg_arg == NULL ) {
63 return( help_cmd( msgp, reply ));
66 remove_trailing_space( msgp->msg_arg );
67 if ( *msgp->msg_arg == '\0' ) {
68 return( help_cmd( msgp, reply ));
71 if (( lfdp = ldap_init_getfilter( filterfile )) == NULL ) {
72 strcat( reply, errpreface );
73 strcat( reply, "filter file configuration error. Try again later." );
78 * open connection to LDAP server and bind as dapuser
82 ldp = cldap_open( ldaphost, ldapport );
85 ldp = ldap_open( ldaphost, ldapport );
88 strcat( reply, errpreface );
89 strcat( reply, "X.500 service unavailable. Try again later." );
90 ldap_getfilter_free( lfdp );
97 if ( ldap_simple_bind_s( ldp, dapuser, NULL ) != LDAP_SUCCESS ) {
98 report_ldap_err( ldp, reply );
100 ldap_getfilter_free( lfdp );
105 * set options for search and build filter
107 ldp->ld_deref = derefaliases;
108 ldp->ld_sizelimit = sizelimit;
114 if ( !do_cldap && strchr( msgp->msg_arg, ',' ) != NULL ) {
116 if ( strchr( msgp->msg_arg, ',' ) != NULL ) {
120 ldap_ufn_setprefix( ldp, searchbase );
121 if (( rc = ldap_ufn_search_s( ldp, msgp->msg_arg, attrs, 0, &ldmsgp ))
122 != LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED
123 && rc != LDAP_TIMELIMIT_EXCEEDED ) {
124 report_ldap_err( ldp, reply );
126 ldap_getfilter_free( lfdp );
129 matches = ldap_count_entries( ldp, ldmsgp );
132 #endif /* RCPT500_UFN */
134 for ( lfi = ldap_getfirstfilter( lfdp, "rcpt500", msgp->msg_arg );
135 lfi != NULL; lfi = ldap_getnextfilter( lfdp )) {
138 rc = cldap_search_s( ldp, searchbase, LDAP_SCOPE_SUBTREE,
139 lfi->lfi_filter, attrs, 0, &ldmsgp, dapuser );
142 rc = ldap_search_s( ldp, searchbase, LDAP_SCOPE_SUBTREE,
143 lfi->lfi_filter, attrs, 0, &ldmsgp );
145 if ( rc != LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED
146 && rc != LDAP_TIMELIMIT_EXCEEDED ) {
147 report_ldap_err( ldp, reply );
149 ldap_getfilter_free( lfdp );
153 if (( matches = ldap_count_entries( ldp, ldmsgp )) != 0 ) {
157 if ( ldmsgp != NULL ) {
158 ldap_msgfree( ldmsgp );
163 #endif /* RCPT500_UFN */
165 if ( matches == 0 ) {
166 sprintf( buf, "No matches were found for '%s'\n", msgp->msg_arg );
167 strcat( reply, buf );
169 ldap_getfilter_free( lfdp );
173 if ( ldp->ld_errno == LDAP_TIMELIMIT_EXCEEDED
174 || ldp->ld_errno == LDAP_SIZELIMIT_EXCEEDED ) {
175 strcat( reply, "(Partial results only - a limit was exceeded)\n" );
178 if ( matches <= RCPT500_LISTLIMIT ) {
179 sprintf( buf, "%d %s match%s found for '%s':\n\n", matches,
180 ufn ? "UFN" : lfi->lfi_desc,
181 ( matches > 1 ) ? "es" : "", msgp->msg_arg );
182 strcat( reply, buf );
184 if (( rc = ldap_init_templates( templatefile, &tmpllist )) != 0 ) {
185 sprintf( buf, "%s ldap_init_templates( %s ) failed (error %d)\n",
186 errpreface, templatefile, rc );
187 strcat( reply, buf );
190 for ( entry = ldap_first_entry( ldp, ldmsgp ); entry != NULL; ) {
191 dn = ldap_get_dn( ldp, entry );
192 if ( do_read( ldp, dn, reply, tmpllist ) != LDAP_SUCCESS ) {
193 report_ldap_err( ldp, reply );
196 if (( entry = ldap_next_entry( ldp, entry )) != NULL ) {
197 strcat( reply, "\n-------\n\n" );
201 if ( tmpllist != NULL ) {
202 ldap_free_templates( tmpllist );
204 ldap_msgfree( ldmsgp );
207 sprintf( buf, "%d %s matches were found for '%s':\n",
208 matches, ufn ? "UFN" : lfi->lfi_desc, msgp->msg_arg );
209 strcat( reply, buf );
210 append_entry_list( reply, msgp->msg_arg, ldp, ldmsgp );
211 ldap_msgfree( ldmsgp );
215 ldap_getfilter_free( lfdp );
221 close_ldap( LDAP *ld )
232 append_entry_list( reply, query, ldp, ldmsgp )
239 char *dn, *rdn, *s, **title;
242 #ifdef RCPT500_SORT_ATTR
243 ldap_sort_entries( ldp, &ldmsgp, RCPT500_SORT_ATTR, strcasecmp );
246 for ( e = ldap_first_entry( ldp, ldmsgp ); e != NULL;
247 e = ldap_next_entry( ldp, e )) {
248 dn = ldap_get_dn( ldp, e );
249 if (( s = strchr( dn, ',' )) != NULL ) {
252 if (( s = strchr( dn, '=' )) == NULL ) {
260 * if this entry's rdn is an exact match for the thing looked up, we
261 * return the CN that has a digit after it, so that the user is
262 * returned something guaranteed to yield exactly one match if they
263 * pick it from the list and query it
266 if ( strcasecmp( rdn, query ) == 0 ) {
270 if (( cn = ldap_get_values( ldp, e, "cn" )) != NULL ) {
271 for ( i = 0; cn[i] != NULL; i++ ) {
272 if ( isdigit( *( cn[i] + strlen( cn[i] ) - 1 ))) {
273 rdn = strdup( cn[i] );
278 ldap_value_free( cn );
283 title = ldap_get_values( ldp, e, "title" );
284 sprintf( buf, " %-20s %s\n", rdn, title ? title[0] : "" );
285 strcat( reply, buf );
286 if ( title != NULL ) {
287 ldap_value_free( title );
298 append_text( reply, text, len )
303 strcat( reply, text );
309 do_read( ldp, dn, reply, tmpll )
313 struct ldap_disptmpl *tmpll;
316 static char *maildefvals[] = { "None registered in this service", NULL };
317 static char *defattrs[] = { "mail", NULL };
318 static char **defvals[] = { maildefvals, NULL };
321 rc = ldap_entry2text_search( ldp, dn, searchbase, NULLMSG, tmpll,
322 defattrs, defvals, (void *)append_text, (void *)reply, "\n",
323 rdncount, LDAP_DISP_OPT_DOSEARCHACTIONS );
329 report_ldap_err( ldp, reply )
333 strcat( reply, errpreface );
334 strcat( reply, ldap_err2string( ldp->ld_errno ));
335 strcat( reply, "\n" );
339 remove_trailing_space( s )
342 char *p = s + strlen( s ) - 1;
344 while ( isspace( *p ) && p > s ) {