home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume18 / pwdiff / pwdiff.c < prev    next >
C/C++ Source or Header  |  1989-03-26  |  3KB  |  154 lines

  1. /* Check multiple passwd files for uid/name overlap - Don Libes */
  2.  
  3. #include <stdio.h>
  4. #include <pwd.h>
  5.  
  6. #define TRUE 1
  7. #define FALSE 0
  8.  
  9. struct tinypasswd {    /* like struct pwd but missing some entries */
  10.     char *name;
  11.     char *dir;
  12.     struct tinypasswd *next;  /* other entries mapping to same uid */
  13.     char *file;          /* file this entry was found in */
  14. };
  15.  
  16. #define MINUSERUID    20    /* don't check uids below this for */
  17.                 /* names to match directories */
  18. #define MAXLINELEN    132
  19. #define MAXUID        5700        /* largest uid we might possibly see */
  20. #define NOBODY        -2
  21. #define skipuid(x)    (x == NOBODY)    /* any uids to skip.  If none */
  22.                     /* then just define to be 0 */
  23.  
  24. struct tinypasswd *pwds[MAXUID];
  25. char line[MAXLINELEN];
  26. struct tinypasswd *pwd;
  27.  
  28. char *malloc();
  29. char *newstr();
  30. char *rindex();
  31. struct passwd *fgetpwent();
  32. #define new(type)    (type *)malloc(sizeof(type))
  33.  
  34. main(argc,argv)
  35. int argc;
  36. char **argv;
  37. {
  38.     int file;
  39.     int uid;
  40.     FILE *pfp;
  41.     struct passwd *staticpwd;
  42.     char *leaf;
  43.  
  44.     for (uid=0;uid<MAXUID;uid++) pwds[uid] = NULL;
  45.  
  46.     for (file=1;file<argc;file++) {
  47.         if (NULL == (pfp = fopen(argv[file],"r"))) {
  48.             perror(argv[file]);
  49.             continue;
  50.         }
  51.  
  52.         while (NULL != (staticpwd = fgetpwent(pfp))) {
  53.             if (pwd == NULL) {
  54.                 if (NULL == (pwd = new(struct tinypasswd))) {
  55.                     printf("malloc: out of space\n");
  56.                     exit(-1);
  57.                 }
  58.             }
  59.  
  60.             /* skip Sun yp hook */
  61.             if (staticpwd->pw_name[0] == '+') continue;
  62.  
  63.             pwd->name = newstr(staticpwd->pw_name);
  64.             pwd->dir = newstr(staticpwd->pw_dir);
  65.             uid = staticpwd->pw_uid;
  66.  
  67.             if (skipuid(uid)) continue;
  68.             if (uid < 0 || uid >= MAXUID) {
  69.                 printf("%s: uid %d out of range\n",
  70.                     argv[file],uid);
  71.                 continue;
  72.             }
  73.  
  74.             /* check for matching directories on large uids */
  75.             if (uid > MINUSERUID) {
  76.                 if (0 == (leaf = rindex(pwd->dir,'/'))) {
  77.                     printf("%s: no leaf in directory %s\n",
  78.                         argv[file],line);
  79.                 } else if (0 != strcmp(pwd->name,1+leaf)) {
  80.                     printf("%s: nickname %s has directory %s\n",
  81.                         argv[file],pwd->name,pwd->dir);
  82.                 }
  83.             }
  84.  
  85.             pwd->file = argv[file];
  86.             pwd->next = NULL;
  87.  
  88.             if (!hash_pwd(&pwds[uid],pwd)) {
  89.                 free(pwd->name);
  90.                 free(pwd->dir);
  91.             } else pwd = NULL;
  92.         }
  93.         fclose(pfp);
  94.     }
  95.  
  96.     /* scan down list looking for dups */
  97.     for (uid=0;uid<MAXUID;uid++) {
  98.         /* no pwd with this uid */
  99.         if (pwds[uid] == NULL) continue;
  100.  
  101.         /* no other pwd with this uid */
  102.         if (pwds[uid]->next == NULL) continue;
  103.  
  104.         print_pwd(uid);
  105.     }
  106. }
  107.  
  108. print_pwd(uid)
  109. int uid;
  110. {
  111.     struct tinypasswd *p;
  112.  
  113.     for (p = pwds[uid];p;p=p->next) {
  114.         printf("%6d %20s %40s\n",uid,p->name,p->file);
  115.     }
  116. }
  117.  
  118. /* returns TRUE if pwd stored, FALSE if not stored */
  119. hash_pwd(pep,p)
  120. struct tinypasswd **pep;    /* pwds entry pointer */
  121. struct tinypasswd *p;
  122. {
  123.     int different = FALSE;
  124.     struct tinypasswd *pptr;  /* pointer to open-hashed pwd entries */
  125.     struct tinypasswd *lastp; /* where to append new struct passwd */
  126.  
  127.     if (NULL == *pep) {
  128.         *pep = p;
  129.         return(TRUE);
  130.     }
  131.  
  132.     for (pptr = *pep;pptr;pptr=pptr->next) {
  133.         lastp = pptr;
  134.         if (different) continue;    /* just get to end of list */
  135.         if (0 != strcmp(pptr->name,p->name)) different = TRUE;
  136.     }
  137.     if (different) lastp->next = p;
  138.  
  139.     return(different);
  140. }
  141.  
  142. char *newstr(s)
  143. char *s;
  144. {
  145.     char *news;
  146.  
  147.     if (!(news = malloc(1+strlen(s)))) {
  148.         printf("newstr: out of space\n");
  149.         exit(0);
  150.     }
  151.     strcpy(news,s);
  152.     return(news);
  153. }
  154.