home *** CD-ROM | disk | FTP | other *** search
- /* Check multiple passwd files for uid/name overlap - Don Libes */
-
- #include <stdio.h>
- #include <pwd.h>
-
- #define TRUE 1
- #define FALSE 0
-
- struct tinypasswd { /* like struct pwd but missing some entries */
- char *name;
- char *dir;
- struct tinypasswd *next; /* other entries mapping to same uid */
- char *file; /* file this entry was found in */
- };
-
- #define MINUSERUID 20 /* don't check uids below this for */
- /* names to match directories */
- #define MAXLINELEN 132
- #define MAXUID 5700 /* largest uid we might possibly see */
- #define NOBODY -2
- #define skipuid(x) (x == NOBODY) /* any uids to skip. If none */
- /* then just define to be 0 */
-
- struct tinypasswd *pwds[MAXUID];
- char line[MAXLINELEN];
- struct tinypasswd *pwd;
-
- char *malloc();
- char *newstr();
- char *rindex();
- struct passwd *fgetpwent();
- #define new(type) (type *)malloc(sizeof(type))
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- int file;
- int uid;
- FILE *pfp;
- struct passwd *staticpwd;
- char *leaf;
-
- for (uid=0;uid<MAXUID;uid++) pwds[uid] = NULL;
-
- for (file=1;file<argc;file++) {
- if (NULL == (pfp = fopen(argv[file],"r"))) {
- perror(argv[file]);
- continue;
- }
-
- while (NULL != (staticpwd = fgetpwent(pfp))) {
- if (pwd == NULL) {
- if (NULL == (pwd = new(struct tinypasswd))) {
- printf("malloc: out of space\n");
- exit(-1);
- }
- }
-
- /* skip Sun yp hook */
- if (staticpwd->pw_name[0] == '+') continue;
-
- pwd->name = newstr(staticpwd->pw_name);
- pwd->dir = newstr(staticpwd->pw_dir);
- uid = staticpwd->pw_uid;
-
- if (skipuid(uid)) continue;
- if (uid < 0 || uid >= MAXUID) {
- printf("%s: uid %d out of range\n",
- argv[file],uid);
- continue;
- }
-
- /* check for matching directories on large uids */
- if (uid > MINUSERUID) {
- if (0 == (leaf = rindex(pwd->dir,'/'))) {
- printf("%s: no leaf in directory %s\n",
- argv[file],line);
- } else if (0 != strcmp(pwd->name,1+leaf)) {
- printf("%s: nickname %s has directory %s\n",
- argv[file],pwd->name,pwd->dir);
- }
- }
-
- pwd->file = argv[file];
- pwd->next = NULL;
-
- if (!hash_pwd(&pwds[uid],pwd)) {
- free(pwd->name);
- free(pwd->dir);
- } else pwd = NULL;
- }
- fclose(pfp);
- }
-
- /* scan down list looking for dups */
- for (uid=0;uid<MAXUID;uid++) {
- /* no pwd with this uid */
- if (pwds[uid] == NULL) continue;
-
- /* no other pwd with this uid */
- if (pwds[uid]->next == NULL) continue;
-
- print_pwd(uid);
- }
- }
-
- print_pwd(uid)
- int uid;
- {
- struct tinypasswd *p;
-
- for (p = pwds[uid];p;p=p->next) {
- printf("%6d %20s %40s\n",uid,p->name,p->file);
- }
- }
-
- /* returns TRUE if pwd stored, FALSE if not stored */
- hash_pwd(pep,p)
- struct tinypasswd **pep; /* pwds entry pointer */
- struct tinypasswd *p;
- {
- int different = FALSE;
- struct tinypasswd *pptr; /* pointer to open-hashed pwd entries */
- struct tinypasswd *lastp; /* where to append new struct passwd */
-
- if (NULL == *pep) {
- *pep = p;
- return(TRUE);
- }
-
- for (pptr = *pep;pptr;pptr=pptr->next) {
- lastp = pptr;
- if (different) continue; /* just get to end of list */
- if (0 != strcmp(pptr->name,p->name)) different = TRUE;
- }
- if (different) lastp->next = p;
-
- return(different);
- }
-
- char *newstr(s)
- char *s;
- {
- char *news;
-
- if (!(news = malloc(1+strlen(s)))) {
- printf("newstr: out of space\n");
- exit(0);
- }
- strcpy(news,s);
- return(news);
- }
-