2 * Copyright (c) 1991, 1992, 1993
3 * Regents of the University of Michigan. All rights reserved.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that this notice is preserved and that due credit is given
7 * to the University of Michigan at Ann Arbor. The name of the University
8 * may not be used to endorse or promote products derived from this
9 * software without specific prior written permission. This software
10 * is provided ``as is'' without express or implied warranty.
23 extern char *search_base; /* search base */
24 extern int verbose; /* verbose mode flag */
25 extern LDAP *ld; /* our ldap descriptor */
27 static int num_picked = 0; /* used when user picks entry at More prompt */
30 extern int debug; /* debug flag */
37 static char *attrs[2] = { "objectClass", NULL };
41 printf("->vrfy(%s)\n", dn);
43 /* verify that this DN exists in the directory */
44 (void) ldap_search_s(ld, dn, LDAP_SCOPE_BASE, "objectClass=*", attrs, TRUE, &results);
45 (void) ldap_msgfree(results);
46 if ((ld->ld_errno == LDAP_NO_SUCH_OBJECT) || (ld->ld_errno == LDAP_INVALID_DN_SYNTAX))
48 else if (ld->ld_errno == LDAP_SUCCESS)
51 ldap_perror(ld, "ldap_search");
57 static LDAPMessage * disambiguate( result, matches, read_attrs, who )
63 int choice; /* entry that user chooses */
65 char *namelist[MAX_NUM_NAMES]; /* names found */
66 char response[SMALL_BUF_SIZE]; /* results from user */
67 char *name = NULL; /* DN to lookup */
73 printf("->disambiguate(%x, %d, %x, %s)\n", result, matches,
77 * If we are here, it means that we got back multiple answers.
79 if ((ld->ld_errno == LDAP_TIMELIMIT_EXCEEDED)
80 || (ld->ld_errno == LDAP_SIZELIMIT_EXCEEDED)) {
82 printf(" Your query was too general and a limit was exceeded. The results listed\n");
83 printf(" are not complete. You may want to try again with a more refined query.\n\n");
86 printf(" Time or size limit exceeded. Partial results follow.\n\n");
88 printf(" %1d names matched \"%s\".\n", matches, who);
90 printf(" Do you wish to see a list of names? ");
92 (void) memset(response, 0, sizeof(response));
93 fetch_buffer(response, sizeof(response), stdin);
94 switch (response[0]) {
103 print_list(result, namelist, &matches);
105 choice = pick_one(matches);
110 name = strdup(namelist[choice]);
112 * Now free up all of the pointers allocated in
113 * namelist. The print_list() routine that filled
114 * in this collection of strings starts at 1, not 0.
116 for (i = 1; namelist[i] != NULL; i++)
124 if (debug & D_FIND) {
125 printf(" Calling ldap_search_s()\n");
126 printf(" ld = 0x%x\n", ld);
127 printf(" search base = %s\n", name);
128 printf(" scope = LDAP_SCOPE_BASE\n");
129 printf(" filter = objectClass=*\n");
130 for (i = 0; read_attrs[i] != NULL; i++)
131 printf(" read_attrs[%d] = %s\n", i, read_attrs[i]);
132 printf(" read_attrs[%d] = NULL\n", i);
133 printf(" attrsonly = FALSE\n");
134 printf(" &mp = 0x%x\n", &mp);
137 if (ldap_search_s(ld, name, LDAP_SCOPE_BASE, "objectClass=*", read_attrs, FALSE, &mp) != LDAP_SUCCESS) {
138 ldap_perror(ld, "ldap_search_s");
147 printf(" Please enter 'y', 'n', or RETURN.\n");
153 LDAPMessage * find(who, quiet)
157 register int i, j, k; /* general ints */
158 int matches; /* from ldap_count_entries() */
159 int admonished = FALSE;
160 static int attrs_set = 0;
161 static char *read_attrs[MAX_ATTRS]; /* attrs to use in a read op */
162 static char *search_attrs[MAX_ATTRS]; /* attrs to use in a srch op */
163 static int rc; /* return from ldap_search */
164 LDAPMessage *ldtmp, *res; /* results returned from search */
165 char name[MED_BUF_SIZE];
166 char response[SMALL_BUF_SIZE];
167 char *cp, *dn, **rdns;
169 extern LDAPFiltDesc *lfdp; /* LDAP filter descriptor */
170 extern struct attribute attrlist[]; /* complete list of attrs */
175 fprintf(stderr, "->find(%s)\n", who);
177 /* did not specify a 'who' */
179 printf(" Locate whose entry? ");
181 fetch_buffer(name, sizeof(name), stdin);
187 if (attrs_set == 0) {
190 for (i = 0; attrlist[i].quipu_name != NULL; i++) {
191 if (attrlist[i].flags & ATTR_FLAG_READ)
192 read_attrs[j++] = attrlist[i].quipu_name;
193 if (attrlist[i].flags & ATTR_FLAG_SEARCH)
194 search_attrs[k++] = attrlist[i].quipu_name;
196 read_attrs[j] = NULL;
197 search_attrs[k] = NULL;
201 * If the user-supplied name has any commas in it, we
202 * assume that it is a UFN, and do everything right
203 * here. If we don't find it, treat it as NOT a UFN.
205 if (strchr(who, ',') != NULL) {
209 printf("\"%s\" appears to be a UFN\n", who);
211 savederef = ld->ld_deref;
212 ld->ld_deref = LDAP_DEREF_FINDING;
213 if ((rc = ldap_ufn_search_s(ld, who, search_attrs, FALSE, &res)) !=
214 LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED &&
215 rc != LDAP_TIMELIMIT_EXCEEDED) {
216 ldap_perror(ld, "ldap_ufn_search_s");
217 ld->ld_deref = savederef;
220 if ((matches = ldap_count_entries(ld, res)) < 0) {
221 ldap_perror(ld, "ldap_count_entries");
222 ld->ld_deref = savederef;
224 } else if (matches == 1) {
225 if (ldap_search_s(ld, ldap_get_dn(ld, ldap_first_entry(ld, res)), LDAP_SCOPE_BASE, "objectClass=*", read_attrs, FALSE, &res) != LDAP_SUCCESS) {
226 if (ld->ld_errno == LDAP_UNAVAILABLE)
227 printf(" Could not contact the X.500 server to find \"%s\".\n", who);
229 ldap_perror(ld, "ldap_search_s");
232 ld->ld_deref = savederef;
234 } else if (matches > 1 ) {
235 return( disambiguate( ld, res, matches, read_attrs,
238 ld->ld_deref = savederef;
242 * Old users of the MTS *USERDIRECTORY will likely wrap the name
243 * in quotes. Not only is this unnecessary, but it also won't work.
245 for (cp = strchr(who, '"'); cp != NULL; cp = strchr(cp, '"')) {
247 printf(" You do not need to enclose names in quotes.\n");
256 * It wasn't a UFN, so look it up in the usual method.
258 for (fi = ldap_getfirstfilter(lfdp, "ud", who); fi != NULL;
259 fi = ldap_getnextfilter(lfdp)) {
262 printf("Searching, filter = %s\n", fi->lfi_filter);
265 if ((rc = ldap_search_s(ld, search_base, fi->lfi_scope,
266 fi->lfi_filter, search_attrs, FALSE, &res)) != LDAP_SUCCESS &&
267 rc != LDAP_SIZELIMIT_EXCEEDED && rc != LDAP_TIMELIMIT_EXCEEDED) {
268 ldap_perror(ld, "ldap_search_s");
272 if ((matches = ldap_count_entries(ld, res)) < 0) {
273 ldap_perror(ld, "ldap_count_entries");
277 else if (matches == 1) {
278 dn = ldap_get_dn(ld, ldap_first_entry(ld, res));
281 printf(" Found one %s match for \"%s\"\n",
283 if (!fi->lfi_isexact) {
284 rdns = ldap_explode_dn(dn, TRUE);
285 printf(" Do you mean %s? ", *rdns);
286 (void) ldap_value_free(rdns);
288 fetch_buffer(response, sizeof(response), stdin);
289 if ((response[0] == 'n') || (response[0] == 'N'))
293 if (debug & D_FIND) {
294 printf(" Calling ldap_search_s()\n");
295 printf(" ld = 0x%x\n", ld);
296 printf(" dn = %s\n", dn);
297 printf(" scope = LDAP_SCOPE_BASE\n");
298 printf(" filter = %s\n", "objectClass=*");
299 for (i = 0; read_attrs[i] != NULL; i++)
300 printf(" read_attrs[%d] = %s\n", i, read_attrs[i]);
301 printf(" read_attrs[%d] = NULL\n", i);
302 printf(" attrsonly = FALSE\n");
303 printf(" &results = 0x%x\n", &res);
306 if (ldap_search_s(ld, dn, LDAP_SCOPE_BASE, "objectClass=*", read_attrs, FALSE, &res) != LDAP_SUCCESS) {
307 ldap_perror(ld, "ldap_search_s");
314 else if (matches > 0) {
315 ldtmp = disambiguate(res, matches, read_attrs, who);
319 /* if we're here, there were zero matches */
329 char user_pick[SMALL_BUF_SIZE];
333 printf("->pick_one(%d)\n", i);
336 /* make the user pick an entry */
338 printf(" Enter the number of the name you want or Q to quit: ");
340 fetch_buffer(user_pick, sizeof(user_pick), stdin);
341 if (user_pick[0] == 'q' || user_pick[0] == 'Q')
344 if ((n > 0) && (n <= i))
346 printf(" Invalid response\n");
351 print_list(list, names, matches)
358 char resp[SMALL_BUF_SIZE];
359 register LDAPMessage *ep;
361 register int rest = 4; /* 4, not 1 */
365 printf("->print_list(%x, %x, %x)\n", list, names, matches);
367 /* print a list of names from which the user will select */
368 for (ep = ldap_first_entry(ld, list); ep != NULL; ep = ldap_next_entry(ld, ep)) {
370 names[i] = ldap_get_dn(ld, ep);
371 rdns = ldap_explode_dn(names[i], TRUE);
372 cpp = ldap_get_values(ld, ep, "title");
374 printf(" %3d. %s\n", i, *rdns);
376 printf(" %3d. %s, %s\n", i, *rdns, *cpp);
377 ldap_value_free(rdns);
378 ldap_value_free(cpp);
380 if ((rest++ > (lpp - 1)) && (i < *matches)) {
384 fetch_buffer(resp, sizeof(resp), stdin);
385 if ((resp[0] == 'n') || (resp[0] == 'N'))
387 else if ((num_picked = atoi(resp)) != 0) {
401 find_all_subscribers(sub, group)
407 static char *attributes[] = { "cn", NULL };
408 char filter[MED_BUF_SIZE];
409 register LDAPMessage *ep;
414 printf("->find_all_subscribers(%x, %s)\n", sub, group);
417 sprintf(filter, "%s=%s", "memberOfGroup", group);
418 if (ldap_search_s(ld, search_base, LDAP_SCOPE_SUBTREE, filter, attributes, FALSE, &result) != LDAP_SUCCESS) {
419 if (ld->ld_errno == LDAP_NO_SUCH_ATTRIBUTE)
421 ldap_perror(ld, "ldap_search_s");
424 count = ldap_count_entries(ld, result);
426 ldap_msgfree(result);
429 if ( count > MAX_VALUES ) {
430 printf( " Only retrieving the first %d subscribers....\n",
434 for (ep = ldap_first_entry(ld, result); i < MAX_VALUES && ep != NULL; ep = ldap_next_entry(ld, ep)) {
435 sub[i++] = ldap_get_dn(ld, ep);
438 printf("sub[%d] = %s\n", i - 1, sub[i - 1]);
442 ldap_msgfree(result);
446 char * fetch_boolean_value(who, attr)
448 struct attribute attr;
450 LDAPMessage *result; /* from the search below */
451 register LDAPMessage *ep; /* entry pointer */
452 register char **vp; /* for parsing the result */
453 static char *attributes[] = { NULL, NULL };
457 printf("->fetch_boolean_value(%s, %s)\n", who, attr.quipu_name);
459 attributes[0] = attr.quipu_name;
460 if (ldap_search_s(ld, who, LDAP_SCOPE_BASE, "objectClass=*", attributes, FALSE, &result) != LDAP_SUCCESS) {
461 if (ld->ld_errno == LDAP_NO_SUCH_ATTRIBUTE)
463 ldap_perror(ld, "ldap_search_s");
464 ldap_msgfree(result);
469 * We did a read on one name and only asked for one attribute.
470 * There's no reason to loop through any of these structures.
472 * If ldap_first_attribute() returns NULL, then this entry did
473 * not have this particular attribute.
475 ep = ldap_first_entry(ld, result);
476 if ((vp = (char **) ldap_get_values(ld, ep, attr.quipu_name)) == NULL) {
477 ldap_msgfree(result);
481 ldap_msgfree(result);
482 if (!strcasecmp(*vp, "TRUE")) {
486 else if (!strcasecmp(*vp, "FALSE")) {
491 fprintf(stderr, " Got garbage -> [%s]\n", *vp);