source: branches/samba-3.3.x/examples/auth/crackcheck/packlib.c

Last change on this file was 374, checked in by Herwig Bauernfeind, 16 years ago

Update Samba 3.3 to 3.3.10 (new files)

File size: 12.2 KB
Line 
1/*
2 * This program is copyright Alec Muffett 1993, portions copyright other authors.
3 * The authors disclaim all responsibility or liability with respect to it's usage
4 * or its effect upon hardware or computer systems.
5 */
6
7#include "config.h"
8#include <string.h>
9#include <stdlib.h>
10#ifdef HAVE_ZLIB_H
11#include <zlib.h>
12#endif
13#ifdef HAVE_INTTYPES_H
14#include <inttypes.h>
15#endif
16#include "packer.h"
17
18static char vers_id[] = "packlib.c : v2.3p2 Alec Muffett 18 May 1993";
19
20#define DEBUG 0
21
22/* Structures for processing "broken" 64bit dictionary files */
23
24struct pi_header64
25{
26 uint64_t pih_magic;
27 uint64_t pih_numwords;
28 uint16_t pih_blocklen;
29 uint16_t pih_pad;
30};
31
32typedef struct
33{
34 FILE *ifp;
35 FILE *dfp;
36 FILE *wfp;
37 uint64_t flags;
38 uint64_t hwms[256];
39 struct pi_header64 header;
40 int count;
41 char data[NUMWORDS][MAXWORDLEN];
42} PWDICT64;
43
44
45static int
46_PWIsBroken64(FILE *ifp)
47{
48 PWDICT64 pdesc64;
49
50 rewind(ifp);
51 if (!fread((char *) &pdesc64.header, sizeof(pdesc64.header), 1, ifp))
52 {
53 return 0;
54 }
55
56 return (pdesc64.header.pih_magic == PIH_MAGIC);
57}
58
59
60PWDICT *
61PWOpen(prefix, mode)
62 const char *prefix;
63 char *mode;
64{
65 int use64 = 0;
66 static PWDICT pdesc;
67 static PWDICT64 pdesc64;
68 char iname[STRINGSIZE];
69 char dname[STRINGSIZE];
70 char wname[STRINGSIZE];
71 FILE *dfp;
72 FILE *ifp;
73 FILE *wfp;
74
75 if (pdesc.header.pih_magic == PIH_MAGIC)
76 {
77 fprintf(stderr, "%s: another dictionary already open\n", prefix);
78 return ((PWDICT *) 0);
79 }
80
81 memset(&pdesc, '\0', sizeof(pdesc));
82 memset(&pdesc64, '\0', sizeof(pdesc64));
83
84 snprintf(iname, STRINGSIZE, "%s.pwi", prefix);
85 snprintf(dname, STRINGSIZE, "%s.pwd", prefix);
86 snprintf(wname, STRINGSIZE, "%s.hwm", prefix);
87
88 if (mode[0] == 'r')
89 {
90 pdesc.flags &= ~PFOR_USEZLIB;
91 /* first try the normal db file */
92 if (!(pdesc.dfp = fopen(dname, mode)))
93 {
94#ifdef HAVE_ZLIB_H
95 pdesc.flags |= PFOR_USEZLIB;
96 /* try extension .gz */
97 snprintf(dname, STRINGSIZE, "%s.pwd.gz", prefix);
98 if (!(pdesc.dfp = gzopen(dname, mode)))
99 {
100 perror(dname);
101 return ((PWDICT *) 0);
102 }
103#else
104 perror(dname);
105 return ((PWDICT *) 0);
106#endif
107 }
108 }
109 else
110 {
111 pdesc.flags &= ~PFOR_USEZLIB;
112 /* write mode: use fopen */
113 if (!(pdesc.dfp = fopen(dname, mode)))
114 {
115 perror(dname);
116 return ((PWDICT *) 0);
117 }
118 }
119
120 if (!(pdesc.ifp = fopen(iname, mode)))
121 {
122#ifdef HAVE_ZLIB_H
123 if(pdesc.flags & PFOR_USEZLIB)
124 gzclose(pdesc.dfp);
125 else
126#endif
127 fclose(pdesc.dfp);
128 perror(iname);
129 return ((PWDICT *) 0);
130 }
131
132 if ((pdesc.wfp = fopen(wname, mode)))
133 {
134 pdesc.flags |= PFOR_USEHWMS;
135 }
136
137 ifp = pdesc.ifp;
138 dfp = pdesc.dfp;
139 wfp = pdesc.wfp;
140
141 if (mode[0] == 'w')
142 {
143 pdesc.flags |= PFOR_WRITE;
144 pdesc.header.pih_magic = PIH_MAGIC;
145 pdesc.header.pih_blocklen = NUMWORDS;
146 pdesc.header.pih_numwords = 0;
147
148 fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp);
149 } else
150 {
151 pdesc.flags &= ~PFOR_WRITE;
152
153 if (!fread((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp))
154 {
155 fprintf(stderr, "%s: error reading header\n", prefix);
156
157 pdesc.header.pih_magic = 0;
158 fclose(ifp);
159#ifdef HAVE_ZLIB_H
160 if(pdesc.flags & PFOR_USEZLIB)
161 gzclose(dfp);
162 else
163#endif
164 fclose(dfp);
165 if(wfp)
166 {
167 fclose(wfp);
168 }
169 return ((PWDICT *) 0);
170 }
171
172 if ((pdesc.header.pih_magic == 0) || (pdesc.header.pih_numwords == 0))
173 {
174 /* uh-oh. either a broken "64-bit" file or a garbage file. */
175 rewind (ifp);
176 if (!fread((char *) &pdesc64.header, sizeof(pdesc64.header), 1, ifp))
177 {
178 fprintf(stderr, "%s: error reading header\n", prefix);
179
180 pdesc.header.pih_magic = 0;
181 fclose(ifp);
182#ifdef HAVE_ZLIB_H
183 if(pdesc.flags & PFOR_USEZLIB)
184 gzclose(dfp);
185 else
186#endif
187 fclose(dfp);
188 if(wfp)
189 {
190 fclose(wfp);
191 }
192 return ((PWDICT *) 0);
193 }
194 if (pdesc64.header.pih_magic != PIH_MAGIC)
195 {
196 /* nope, not "64-bit" after all */
197 fprintf(stderr, "%s: error reading header\n", prefix);
198
199 pdesc.header.pih_magic = 0;
200 fclose(ifp);
201#ifdef HAVE_ZLIB_H
202 if(pdesc.flags & PFOR_USEZLIB)
203 gzclose(dfp);
204 else
205#endif
206 fclose(dfp);
207
208 if(wfp)
209 {
210 fclose(wfp);
211 }
212 return ((PWDICT *) 0);
213 }
214 pdesc.header.pih_magic = pdesc64.header.pih_magic;
215 pdesc.header.pih_numwords = pdesc64.header.pih_numwords;
216 pdesc.header.pih_blocklen = pdesc64.header.pih_blocklen;
217 pdesc.header.pih_pad = pdesc64.header.pih_pad;
218 use64 = 1;
219 }
220
221 if (pdesc.header.pih_magic != PIH_MAGIC)
222 {
223 fprintf(stderr, "%s: magic mismatch\n", prefix);
224
225 pdesc.header.pih_magic = 0;
226 fclose(ifp);
227#ifdef HAVE_ZLIB_H
228 if(pdesc.flags & PFOR_USEZLIB)
229 gzclose(dfp);
230 else
231#endif
232 fclose(dfp);
233
234 if(wfp)
235 {
236 fclose(wfp);
237 }
238 return ((PWDICT *) 0);
239 }
240
241 if (pdesc.header.pih_numwords < 1)
242 {
243 fprintf(stderr, "%s: invalid word count\n", prefix);
244
245 pdesc.header.pih_magic = 0;
246 fclose(ifp);
247#ifdef HAVE_ZLIB_H
248 if(pdesc.flags & PFOR_USEZLIB)
249 gzclose(dfp);
250 else
251#endif
252 fclose(dfp);
253 if(wfp)
254 {
255 fclose(wfp);
256 }
257 return ((PWDICT *) 0);
258 }
259
260 if (pdesc.header.pih_blocklen != NUMWORDS)
261 {
262 fprintf(stderr, "%s: size mismatch\n", prefix);
263
264 pdesc.header.pih_magic = 0;
265 fclose(ifp);
266#ifdef HAVE_ZLIB_H
267 if(pdesc.flags & PFOR_USEZLIB)
268 gzclose(dfp);
269 else
270#endif
271 fclose(dfp);
272 if(wfp)
273 {
274 fclose(wfp);
275 }
276 return ((PWDICT *) 0);
277 }
278
279 if (pdesc.flags & PFOR_USEHWMS)
280 {
281 int i;
282
283 if (use64)
284 {
285 if (fread(pdesc64.hwms, 1, sizeof(pdesc64.hwms), wfp) != sizeof(pdesc64.hwms))
286 {
287 pdesc.flags &= ~PFOR_USEHWMS;
288 }
289 for (i = 0; i < sizeof(pdesc.hwms) / sizeof(pdesc.hwms[0]); i++)
290 {
291 pdesc.hwms[i] = pdesc64.hwms[i];
292 }
293 }
294 else if (fread(pdesc.hwms, 1, sizeof(pdesc.hwms), wfp) != sizeof(pdesc.hwms))
295 {
296 pdesc.flags &= ~PFOR_USEHWMS;
297 }
298#if DEBUG
299 for (i=1; i<=0xff; i++)
300 {
301 printf("hwm[%02x] = %d\n", i, pdesc.hwms[i]);
302 }
303#endif
304 }
305 }
306
307 return (&pdesc);
308}
309
310int
311PWClose(pwp)
312 PWDICT *pwp;
313{
314 if (pwp->header.pih_magic != PIH_MAGIC)
315 {
316 fprintf(stderr, "PWClose: close magic mismatch\n");
317 return (-1);
318 }
319
320 if (pwp->flags & PFOR_WRITE)
321 {
322 pwp->flags |= PFOR_FLUSH;
323 PutPW(pwp, (char *) 0); /* flush last index if necess */
324
325 if (fseek(pwp->ifp, 0L, 0))
326 {
327 fprintf(stderr, "index magic fseek failed\n");
328 return (-1);
329 }
330
331 if (!fwrite((char *) &pwp->header, sizeof(pwp->header), 1, pwp->ifp))
332 {
333 fprintf(stderr, "index magic fwrite failed\n");
334 return (-1);
335 }
336
337 if (pwp->flags & PFOR_USEHWMS)
338 {
339 int i;
340 for (i=1; i<=0xff; i++)
341 {
342 if (!pwp->hwms[i])
343 {
344 pwp->hwms[i] = pwp->hwms[i-1];
345 }
346#if DEBUG
347 printf("hwm[%02x] = %d\n", i, pwp->hwms[i]);
348#endif
349 }
350 fwrite(pwp->hwms, 1, sizeof(pwp->hwms), pwp->wfp);
351 }
352 }
353
354 fclose(pwp->ifp);
355#ifdef HAVE_ZLIB_H
356 if(pwp->flags & PFOR_USEZLIB)
357 gzclose(pwp->dfp);
358 else
359#endif
360 fclose(pwp->dfp);
361 if(pwp->wfp)
362 {
363 fclose(pwp->wfp);
364 }
365
366 pwp->header.pih_magic = 0;
367
368 return (0);
369}
370
371int
372PutPW(pwp, string)
373 PWDICT *pwp;
374 char *string;
375{
376 if (!(pwp->flags & PFOR_WRITE))
377 {
378 return (-1);
379 }
380
381 if (string)
382 {
383 strncpy(pwp->data[pwp->count], string, MAXWORDLEN);
384 pwp->data[pwp->count][MAXWORDLEN - 1] = '\0';
385
386 pwp->hwms[string[0] & 0xff]= pwp->header.pih_numwords;
387
388 ++(pwp->count);
389 ++(pwp->header.pih_numwords);
390
391 } else if (!(pwp->flags & PFOR_FLUSH))
392 {
393 return (-1);
394 }
395
396 if ((pwp->flags & PFOR_FLUSH) || !(pwp->count % NUMWORDS))
397 {
398 int i;
399 uint32_t datum;
400 register char *ostr;
401
402 datum = (uint32_t) ftell(pwp->dfp);
403
404 fwrite((char *) &datum, sizeof(datum), 1, pwp->ifp);
405
406 fputs(pwp->data[0], pwp->dfp);
407 putc(0, pwp->dfp);
408
409 ostr = pwp->data[0];
410
411 for (i = 1; i < NUMWORDS; i++)
412 {
413 register int j;
414 register char *nstr;
415 nstr = pwp->data[i];
416
417 if (nstr[0])
418 {
419 for (j = 0; ostr[j] && nstr[j] && (ostr[j] == nstr[j]); j++);
420 putc(j & 0xff, pwp->dfp);
421 fputs(nstr + j, pwp->dfp);
422 }
423 putc(0, pwp->dfp);
424
425 ostr = nstr;
426 }
427
428 memset(pwp->data, '\0', sizeof(pwp->data));
429 pwp->count = 0;
430 }
431 return (0);
432}
433
434char *
435GetPW(pwp, number)
436 PWDICT *pwp;
437 uint32_t number;
438{
439 uint32_t datum;
440 register int i;
441 register char *ostr;
442 register char *nstr;
443 register char *bptr;
444 char buffer[NUMWORDS * MAXWORDLEN];
445 static char data[NUMWORDS][MAXWORDLEN];
446 static uint32_t prevblock = 0xffffffff;
447 uint32_t thisblock;
448
449 thisblock = number / NUMWORDS;
450
451 if (prevblock == thisblock)
452 {
453#if DEBUG
454 fprintf(stderr, "returning (%s)\n", data[number % NUMWORDS]);
455#endif
456 return (data[number % NUMWORDS]);
457 }
458
459 if (_PWIsBroken64(pwp->ifp))
460 {
461 uint64_t datum64;
462 if (fseek(pwp->ifp, sizeof(struct pi_header64) + (thisblock * sizeof(uint64_t)), 0))
463 {
464 perror("(index fseek failed)");
465 return ((char *) 0);
466 }
467
468 if (!fread((char *) &datum64, sizeof(datum64), 1, pwp->ifp))
469 {
470 perror("(index fread failed)");
471 return ((char *) 0);
472 }
473 datum = datum64;
474 } else {
475 if (fseek(pwp->ifp, sizeof(struct pi_header) + (thisblock * sizeof(uint32_t)), 0))
476 {
477 perror("(index fseek failed)");
478 return ((char *) 0);
479 }
480
481 if (!fread((char *) &datum, sizeof(datum), 1, pwp->ifp))
482 {
483 perror("(index fread failed)");
484 return ((char *) 0);
485 }
486 }
487
488 int r = 1;
489#ifdef HAVE_ZLIB_H
490 if (pwp->flags & PFOR_USEZLIB)
491 {
492 r = gzseek(pwp->dfp, datum, 0);
493 if(r >= 0)
494 r = 0;
495 }
496 else
497#endif
498 r = fseek(pwp->dfp, datum, 0);
499
500
501 if (r)
502 {
503 perror("(data fseek failed)");
504 return ((char *) 0);
505 }
506 r = 0;
507
508#ifdef HAVE_ZLIB_H
509 if (pwp->flags & PFOR_USEZLIB)
510 {
511 r = gzread(pwp->dfp, buffer, sizeof(buffer));
512 if(r < 0)
513 r = 0;
514 }
515 else
516#endif
517 r = fread(buffer, 1, sizeof(buffer), pwp->dfp);
518
519
520
521 if (!r)
522 {
523 perror("(data fread failed)");
524 return ((char *) 0);
525 }
526
527 prevblock = thisblock;
528
529 bptr = buffer;
530
531 for (ostr = data[0]; (*(ostr++) = *(bptr++)); /* nothing */ );
532
533 ostr = data[0];
534
535 for (i = 1; i < NUMWORDS; i++)
536 {
537 nstr = data[i];
538 strcpy(nstr, ostr);
539
540 ostr = nstr + *(bptr++);
541 while ((*(ostr++) = *(bptr++)));
542
543 ostr = nstr;
544 }
545
546 return (data[number % NUMWORDS]);
547}
548
549unsigned int
550FindPW(pwp, string)
551 PWDICT *pwp;
552 char *string;
553{
554 register uint32_t lwm;
555 register uint32_t hwm;
556 register uint32_t middle;
557 register char *this;
558 int idx;
559
560#if DEBUG
561fprintf(stderr, "look for (%s)\n", string);
562#endif
563
564 if (pwp->flags & PFOR_USEHWMS)
565 {
566 idx = string[0] & 0xff;
567 lwm = idx ? pwp->hwms[idx - 1] : 0;
568 hwm = pwp->hwms[idx];
569
570#if DEBUG
571 fprintf(stderr, "idx = %d\n", idx);
572 fprintf(stderr, "lwm = %d, hwm = %d\n", lwm, hwm);
573#endif
574 } else
575 {
576 lwm = 0;
577 hwm = PW_WORDS(pwp) - 1;
578 }
579
580 /* if the high water mark is lower than the low water mark, something is screwed up */
581 if ( hwm < lwm )
582 {
583 lwm = 0;
584 hwm = PW_WORDS(pwp) - 1;
585 }
586
587#if DEBUG
588 fprintf(stderr, "---- %lu, %lu ----\n", lwm, hwm);
589#endif
590
591 for (;;)
592 {
593 int cmp;
594
595 middle = lwm + ((hwm - lwm + 1) / 2);
596
597#if DEBUG
598 fprintf(stderr, "lwm = %lu, middle = %lu, hwm = %lu\n", lwm, middle, hwm);
599#endif
600
601 this = GetPW(pwp, middle);
602 if ( ! this )
603 {
604#if DEBUG
605 fprintf(stderr, "getpw returned null, returning null in FindPW\n");
606#endif
607 return(PW_WORDS(pwp));
608 }
609 else
610 {
611#if DEBUG
612 fprintf(stderr, "comparing %s against found %s\n", string, this);
613#endif
614 }
615
616 cmp = strcmp(string, this);
617 if (cmp == 0)
618 {
619 return(middle);
620 }
621
622 if (middle == hwm)
623 {
624#if DEBUG
625 fprintf(stderr, "at terminal subdivision, stopping search\n");
626#endif
627 break;
628 }
629
630 if (cmp < 0)
631 {
632 hwm = middle;
633 }
634 else if (cmp > 0)
635 {
636 lwm = middle;
637 }
638 }
639
640 return (PW_WORDS(pwp));
641}
Note: See TracBrowser for help on using the repository browser.