]> git.sur5r.net Git - openldap/blob - clients/ud/util.c
Initial implementation of Kerberos password verification for
[openldap] / clients / ud / util.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /*
7  * Copyright (c) 1992, 1993  Regents of the University of Michigan.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms are permitted
11  * provided that this notice is preserved and that due credit is given
12  * to the University of Michigan at Ann Arbor. The name of the University
13  * may not be used to endorse or promote products derived from this
14  * software without specific prior written permission. This software
15  * is provided ``as is'' without express or implied warranty.
16  */
17
18 #include "portable.h"
19
20 #include <stdio.h>
21
22 #include <ac/stdlib.h>
23
24 #include <ac/ctype.h>
25 #include <ac/errno.h>
26 #include <ac/signal.h>
27 #include <ac/string.h>
28 #include <ac/termios.h>
29 #include <ac/time.h>
30 #include <ac/unistd.h>
31
32 #include <lber.h>
33 #include <ldap.h>
34
35 #include "ldap_defaults.h"
36 #include "ud.h"
37
38 void
39 printbase( char *lead, char *s )
40 {
41         register char **cp;
42         char **rdns;
43
44 #ifdef DEBUG
45         if (debug & D_TRACE)
46                 printf("->printbase(%s, %s)\n", lead, s);
47 #endif
48         if (s == NULL) {
49                 printf("%sroot\n", lead);
50                 return;
51         }
52         printf("%s", lead);
53         rdns = ldap_explode_dn(s, TRUE);
54         for (cp = rdns; ; ) {
55                 printf("%s", friendly_name(*cp));
56                 cp++;
57                 if (*cp == NULL) {
58                         printf("\n");
59                         break;
60                 }
61                 else
62                         printf(", ");
63         }
64         ldap_value_free(rdns);
65         return;
66 }
67
68 void
69 fetch_buffer( char *buffer, int length, FILE *where )
70 {
71         register int i;
72         char *p;
73
74 #ifdef DEBUG
75         if (debug & D_TRACE)
76                 printf("->fetch_buffer(%x, %d, %x)\n", buffer, length, where);
77 #endif
78         /*
79          *  Fetch a buffer and strip off any leading or trailing non-printing
80          *  characters, namely newlines and carriage returns.
81          */
82         if (fgets(buffer, length, where) == NULL) {
83                 if (feof(where))
84                         errno = 0;       /* so fatal() doesn't bitch */
85                 fatal("fgets");
86         }
87         for (i = strlen(buffer) - 1;
88              i >= 0 && !isprint((unsigned char) buffer[i]); i--)
89                 buffer[i] = '\0';
90
91         p = buffer;
92         while ( *p != '\0' ) {
93                 if ( isprint( (unsigned char) *p )) {
94                         ++p;
95                 } else {
96                         SAFEMEMCPY( p, p + 1, strlen( p + 1 ) + 1 ); 
97                 }
98         }
99
100 }
101
102 void
103 fatal( char *s )
104 {
105         if (errno != 0)
106                 perror(s);
107 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
108         destroy_tickets();
109 #endif
110         exit( EXIT_FAILURE );
111 }
112
113 int
114 isgroup( void )
115 {
116         char **vp;
117         register int i;
118         int group = FALSE;
119
120 #ifdef DEBUG
121         if (debug & D_TRACE)
122                 printf("->isgroup()\n");
123 #endif
124         if ((i = attr_to_index("objectClass")) == -1)
125                 return(FALSE);
126         vp = Entry.attrs[i].values;
127         for (i = 0; *vp != NULL; vp++) {
128 #ifdef DEBUG
129                 i++;
130                 if (debug & D_GROUPS)
131                         printf("class #%1d: (%s)\n", i, *vp);
132 #endif
133                 if (!strcmp(*vp, "rfc822MailGroup"))
134                         group = TRUE;
135         }
136         return(group);
137 }
138
139 /*
140  *  Print out the string 's' on a field of 'width' chracters.  Each line
141  *  should be indented 'lead' characters.
142  */
143 void
144 format( char *str, int width, int lead )
145 {
146         char *s, *original, *leader = "";
147         register char *cp;
148
149 #ifdef DEBUG
150         if (debug & D_TRACE)
151                 printf("->format(%s, %d, %d)\n", str, width, lead);
152 #endif
153         if (lead >= width) {
154                 fprintf(stderr, "  Cannot format (%s, %d, %d)\n", str, width, lead);
155                 return;
156         }
157         if (lead > 0) {
158                 leader = (char *) Malloc((unsigned) (lead + 1));
159                 (void) memset(leader, ' ', lead);
160                 *(leader + lead) = '\0';
161         }
162
163         /*
164          *  Some compilers get really unhappy with this function since it
165          *  fiddles around with the first argument, which could be a string
166          *  constant.  We do a strdup() here so we can do whatever the hell
167          *  we want.
168          */
169         s = original = strdup(str);
170         for (;;) {
171                 if (((int) strlen(s) + lead) < width) {
172                         printf("%s%s\n", leader, s);
173                         Free(leader);
174                         Free(original);
175                         return; 
176                         /*NOTREACHED*/
177                 }
178                 cp = s + width - lead;
179                 while (!isspace((unsigned char)*cp) && (cp != s))
180                         cp--;
181                 *cp = '\0';
182                 while (isspace((unsigned char)*s))
183                         s++;
184                 printf("%s%s\n", leader, s);
185                 s = cp + 1;
186         }
187 }
188
189 /*
190  *  Print out the string 's' on a field of 'width' chracters.  The first line
191  *  should be indented 'first_indent' spaces, then followed by 'first_tag', 
192  *  and then followed by the first line of 's'.  Subsequent lines should be
193  *  indented 'indent' spaces, then followed by 'tag', and then followed by
194  *  subsequent lines of 's'.
195  */
196 void
197 format2(
198     char *s,
199     char *first_tag,
200     char *tag,
201     int first_indent,
202     int indent,
203     int width
204 )
205 {
206         char c, *fi, *i;
207         register char *cp;
208
209         if (first_tag == NULL)
210                 first_tag = "";
211         if (tag == NULL)
212                 tag = "";
213 #ifdef DEBUG
214         if (debug & D_TRACE)
215                 printf("format2(\"%s\", \"%s\", \"%s\", %1d, %1d, %1d)\n", s, 
216                                 first_tag, tag, first_indent, indent, width);
217 #endif
218
219         /* make sure the indents are sane */
220         if ((first_indent >= width) || (indent >= width)) {
221                 fprintf(stderr, "  Cannot format:  indent too large\n");
222                 return;
223         }
224
225         /* make the indentations */
226         if (first_indent > 0) {
227                 fi = (char *) Malloc((unsigned) (first_indent + 1));
228                 (void) memset(fi, ' ', first_indent);
229                 *(fi + first_indent) = '\0';
230         }
231         else
232                 fi = "";
233         if (indent > 0) {
234                 i = (char *) Malloc((unsigned) (indent + 1));
235                 (void) memset(i, ' ', indent);
236                 *(i + indent) = '\0';
237         }
238         else
239                 i = "";
240
241         /* now do the first line */
242         if (((int) strlen(s) + (int) strlen(first_tag) + first_indent) < width) {
243                 printf("%s%s%s\n", fi, first_tag, s);
244                 Free(fi);
245                 Free(i);
246                 return; 
247                 /*NOTREACHED*/
248         }
249
250         /*
251          *  's' points to the beginning of the string we want to print.
252          *  We point 'cp' to the end of the maximum amount of text we
253          *  can print (i.e., total width less the indentation and the
254          *  length of the tag).  Once we have set 'cp' initially we
255          *  back it up to the first space character.
256          */
257         cp = s + width - first_indent - strlen(first_tag);
258         while (!isspace((unsigned char)*cp) && (cp != s))
259                 cp--;
260
261         /*
262          *  Once there, we change that space character to a null, print the
263          *  string, and then restore the space character.
264          */
265         c = *cp;
266         *cp = '\0';
267         printf("%s%s%s\n", fi, first_tag, s);
268         *cp = c;
269
270         /*
271          *  Since 'cp' may have been set to a space initially (and so no
272          *  back-tracking was performed), it could have a space after it
273          *  as well.  We should gobble up all of these since we don't want
274          *  unexpected leading blanks.
275          */  
276         for (s = cp + 1; isspace((unsigned char)*s); s++)
277                 ;
278
279         /* now do all of the other lines */
280         for (;;) {
281                 if (((int) strlen(s) + (int) strlen(tag) + indent) < width) {
282                         printf("%s%s%s\n", i, tag, s);
283                         Free(fi);
284                         Free(i);
285                         return; 
286                         /*NOTREACHED*/
287                 }
288                 cp = s + width - indent - strlen(tag);
289                 while (!isspace((unsigned char)*cp) && (cp != s))
290                         cp--;
291                 c = *cp;
292                 *cp = '\0';
293                 printf("%s%s%s\n", i, tag, s);
294                 s = cp + 1;
295                 *cp = c;                        /* don't mess up 's' */
296         }
297 }
298
299 #define IN_A_QUOTE   0
300 #define OUT_OF_QUOTE 1
301
302 char *
303 strip_ignore_chars( char *cp )
304 {
305         int had_a_comma = FALSE;
306         int flag = OUT_OF_QUOTE;
307         register char *rcp, *cp1;
308         char *tmp;
309
310 #ifdef DEBUG
311         if (debug & D_TRACE)
312                 printf("strip_ignore_chars(%s)\n", cp);
313 #endif
314         for (rcp = cp; *rcp != '\0'; rcp++)
315                 if (isignorechar(*rcp) || (*rcp == '"'))
316                         break;
317         if (*rcp == '\0')
318                 return(cp);
319
320         cp1 = tmp = (char *) Malloc((unsigned) strlen(cp));
321         for (rcp = cp; *rcp != '\0'; rcp++) {
322                 /* toss quotes and flip the flag */
323                 if (*rcp == '"')
324                         flag = OUT_OF_QUOTE - flag;
325                 else if (isignorechar(*rcp)) {
326                         if (flag == OUT_OF_QUOTE)
327                                 *cp1++ = ' ';
328                         else
329                                 *cp1++ = *rcp;
330                 }
331                 else if (*rcp == ',') {
332                         *cp1++ = *rcp;
333                         had_a_comma = TRUE;
334                 }
335                 else 
336                         *cp1++ = *rcp;
337         }
338         *cp1 = '\0';
339
340         /* re-quote the name if it had a comma in it */
341         if (had_a_comma == TRUE) {
342                 rcp = cp1 = (char *) Malloc((unsigned) (strlen(tmp) + 3));
343                 *rcp++ = '"';
344                 *rcp = '\0';
345                 strcat(rcp, tmp);
346                 strcat(rcp, "\"");
347                 Free(tmp);
348                 tmp = cp1;
349         }
350         return(tmp);
351 }
352
353 char *
354 code_to_str( int i )
355 {
356         switch(i) {
357         case LDAP_MOD_ADD : return("ADD");
358         case LDAP_MOD_DELETE : return("DELETE");
359         case LDAP_MOD_REPLACE : return("REPLACE");
360         default : return("?????");
361         }
362 }
363
364 char *
365 friendly_name( char *s )
366 {
367         static LDAPFriendlyMap *map = NULL;
368         static char *cp;
369
370         cp = ldap_friendly_name(FRIENDLYFILE, s, &map);
371         if (cp == NULL)
372                 return(s);
373         return(cp);
374 }
375
376 #ifdef UOFM
377
378 /* return TRUE if s has the syntax of a uniqname */
379 int
380 isauniqname( char *s )
381 {
382         int i = strlen(s);
383
384         if ((i < 3) || (i > 8))         /* uniqnames are 3-8 chars */
385                 return(FALSE);
386         if (!isalpha((unsigned char)*s)) /* uniqnames begin with a letter */
387                 return(FALSE);
388         for ( ; *s != '\0'; s++)        /* uniqnames are alphanumeric */
389                 if (!isalnum((unsigned char)*s))
390                         return(FALSE);
391         return(TRUE);
392 }
393 #endif
394
395 /* return TRUE if this attribute should be printed as a DN */
396 int
397 isadn( char *s )
398 {
399         register int i;
400
401         for (i = 0; attrlist[i].quipu_name != NULL; i++)
402                 if (!strcasecmp(s, attrlist[i].quipu_name))
403                         break;
404         if (attrlist[i].flags & ATTR_FLAG_IS_A_DN)
405                 return(TRUE);
406         return(FALSE);
407 }
408
409 char *
410 my_ldap_dn2ufn( char *s )
411 {
412 #ifdef UD_BASE
413         register char **cpp;
414         static char short_DN[BUFSIZ];
415
416         if (strstr(s, UD_BASE) == NULL)
417                 return(ldap_dn2ufn(s));
418         cpp = ldap_explode_dn(s, TRUE);
419         sprintf(short_DN, "%s, %s", *cpp, *(cpp + 1));
420         ldap_value_free(cpp);
421         return(short_DN);
422 #else
423         return(ldap_dn2ufn(s));
424 #endif
425 }
426
427 /* return TRUE if this attribute should be printed as a URL */
428 int
429 isaurl( char *s )
430 {
431         register int i;
432
433         for (i = 0; attrlist[i].quipu_name != NULL; i++)
434                 if (!strcasecmp(s, attrlist[i].quipu_name))
435                         break;
436         if (attrlist[i].flags & ATTR_FLAG_IS_A_URL)
437                 return(TRUE);
438         return(FALSE);
439 }
440
441 /* return TRUE if this attribute should be printed as a date and time */
442 int
443 isadate( char *s )
444 {
445         register int i;
446
447         for (i = 0; attrlist[i].quipu_name != NULL; i++)
448                 if (!strcasecmp(s, attrlist[i].quipu_name))
449                         break;
450         if (attrlist[i].flags & ATTR_FLAG_IS_A_DATE)
451                 return(TRUE);
452         return(FALSE);
453 }
454
455 void *
456 Malloc( unsigned int size )
457 {
458         void *void_ptr;
459
460         void_ptr = (void *) malloc(size);
461         if (void_ptr == NULL) {
462                 perror("malloc");
463                 exit( EXIT_FAILURE );
464                 /*NOTREACHED*/
465         }
466         return(void_ptr);
467 }
468
469 void
470 Free( void *ptr )
471 {
472         free(ptr);
473 }
474
475 char *
476 nextstr( char *s )
477 {
478         while (isspace((unsigned char) *s) && (*s != '\0'))
479                 s++;
480         if (s == NULL)
481                 return(NULL);
482         if (*s == '\0')
483                 return(NULL);
484         return(s);
485 }
486
487 void
488 free_mod_struct( LDAPMod *modp )
489 {
490         if (modp->mod_values != NULL)
491                 (void) ldap_value_free(modp->mod_values);
492         Free(modp->mod_type);
493         Free(modp);
494 }
495
496 void
497 StrFreeDup( char **ptr, char *new_value )
498 {
499         if (*ptr != NULL)
500                 Free(*ptr);
501         if (new_value == NULL)
502                 *ptr = NULL;
503         else
504                 *ptr = strdup(new_value);
505 }
506
507
508 int
509 confirm_action( char *msg )
510
511         char    tmp[SMALL_BUF_SIZE];
512         int     i;
513
514         if ( msg != NULL ) {
515                 putchar( '\n' );
516                 format( msg, 75, 2 );
517         }
518
519         printf("\n  Is this OK? ");
520         fflush(stdout);
521         tmp[0] = '\0';
522         fetch_buffer(tmp, sizeof(tmp), stdin);
523         i = strlen(tmp);
524         return( i > 0 &&
525             ( !strncasecmp(tmp, "YES", i) || !strncasecmp(tmp, "OK", i)));
526 }