1 #pragma ident   "%Z%%M% %I%     %E% SMI"
   2 
   3 /*
   4  * Replacement for getpwnam - we need it to handle files other than
   5  * /etc/passwd so we can permit different passwd files for each different
   6  * host
   7  * (c) 1998-2000 by Bernhard Rosenkränzer <bero@redhat.com>
   8  * 19980930     Initial version
   9  * 20000211     Various fixes
  10  */
  11 
  12 #include "config.h"
  13 #include <pwd.h>
  14 #include <sys/types.h>
  15 #include <stdio.h>
  16 #ifdef SHADOW_PASSWORD
  17 # ifdef HAVE_SHADOW_H
  18 #  include <shadow.h>
  19 # endif
  20 #endif
  21 
  22 #ifndef HAVE_FGETPWENT /* Some systems (*BSD) don't have fgetpwent... */
  23 #ifdef HAVE_STRINGS_H
  24 #include <strings.h>
  25 #else
  26 #include <string.h>
  27 #endif
  28 struct passwd *fgetpwent(FILE *stream)
  29 {
  30         char *entry=(char *) malloc(1024);
  31         struct passwd *p=(struct passwd *) malloc(sizeof(struct passwd));
  32         char *tmp,*tmp2;
  33 
  34         if(!fgets(entry,1024,stream)) {
  35                 free(entry);
  36                 free(p);
  37                 return NULL;
  38         }
  39         tmp=strdup(entry);
  40         if(strchr(tmp,':')) {
  41                 *strchr(tmp,':')=0;
  42                 p->pw_name=tmp;
  43         } else {
  44                 free(tmp); free(entry); free(p); return NULL;
  45         }
  46         tmp2=strchr(entry,':')+1;
  47         tmp=strdup(tmp2);
  48         if(strchr(tmp,':')) {
  49                 *strchr(tmp,':')=0;
  50                 p->pw_passwd=tmp;
  51         } else {
  52                 free(tmp); free(entry); free(p->pw_name); free(p); return NULL;
  53         }
  54         tmp2=strchr(tmp2,':')+1;
  55         tmp=strdup(tmp2);
  56         if(strchr(tmp,':')) {
  57                 *strchr(tmp,':')=0;
  58                 p->pw_uid=(uid_t) atoi(tmp);
  59         } else {
  60                 free(tmp); free(entry); free(p->pw_passwd); free(p->pw_name); free(p); return NULL;
  61         }
  62         free(tmp);
  63         tmp2=strchr(tmp2,':')+1;
  64         tmp=strdup(tmp2);
  65         if(strchr(tmp,':')) {
  66                 *strchr(tmp,':')=0;
  67                 p->pw_gid=(gid_t) atoi(tmp);
  68         } else {
  69                 free(tmp); free(entry); free(p->pw_passwd); free(p->pw_name); free(p); return NULL;
  70         }
  71         free(tmp);
  72         tmp2=strchr(tmp2,':')+1;
  73         tmp=strdup(tmp2);
  74         if(strchr(tmp,':')) {
  75                 *strchr(tmp,':')=0;
  76                 p->pw_gecos=tmp;
  77         } else {
  78                 free(tmp); free(entry); free(p->pw_passwd); free(p->pw_name); free(p); return NULL;
  79         }
  80         tmp2=strchr(tmp2,':')+1;
  81         tmp=strdup(tmp2);
  82         if(strchr(tmp,':')) {
  83                 *strchr(tmp,':')=0;
  84                 p->pw_dir=tmp;
  85         } else {
  86                 free(tmp); free(entry); free(p->pw_gecos); free(p->pw_passwd); free(p->pw_name); free(p); return NULL;
  87         }
  88         tmp2=strchr(tmp2,':')+1;
  89         if(strchr(tmp2,':')) {
  90                 free(entry); free(p->pw_dir); free(p->pw_gecos); free(p->pw_passwd); free(p->pw_name); free(p); return NULL;
  91         }
  92         while(strlen(tmp2) && isspace(tmp2[strlen(tmp2)-1]))
  93                 tmp2[strlen(tmp2)-1]=0;
  94         p->pw_shell=strdup(tmp2);
  95         free(entry);
  96         return p;
  97 }
  98 #endif
  99 
 100 
 101 struct passwd *bero_getpwnam(const char * name, const char * file)
 102 {
 103         FILE *f;
 104         struct passwd *p;
 105         struct passwd *r;
 106         
 107         if (!strcmp(file,"/etc/passwd")) 
 108           return (getpwnam(name));
 109         f=fopen(file,"r");
 110         if(f==NULL)
 111                 return NULL;
 112         p=NULL;
 113         r=NULL;
 114         while((r==NULL) && (p=fgetpwent(f)))
 115                 if(!strcasecmp(p->pw_name,name))
 116                         r=p;
 117         fclose(f);
 118         return r;
 119 }
 120 
 121 struct passwd *bero_getpwuid(uid_t uid, const char * file)
 122 {
 123         FILE *f;
 124         struct passwd *p;
 125         struct passwd *r;
 126         
 127         if (!strcmp(file,"/etc/passwd"))
 128           return getpwuid(uid);
 129         f=fopen(file,"r");
 130         if(f==NULL)
 131                 return NULL;
 132         p=NULL;
 133         r=NULL;
 134         while((r==NULL) && (p=fgetpwent(f)))
 135                 if(p->pw_uid==uid)
 136                         r=p;
 137         fclose(f);
 138         return r;
 139 }
 140 
 141 #ifdef SHADOW_PASSWORD
 142 struct spwd *bero_getspnam(const char * name, const char * file)
 143 {
 144         FILE *f;
 145         struct spwd *s;
 146         struct spwd *r;
 147         f=fopen(file,"r");
 148         if(f==NULL)
 149                 return NULL;
 150         s=NULL;
 151         r=NULL;
 152         while((r==NULL) && (s=fgetspent(f)))
 153                 if(!strcasecmp(s->sp_namp,name))
 154                         r=s;
 155         fclose(f);
 156         return r;
 157 }
 158 #endif