Back to index

avfs  1.0.1
ugid.c
Go to the documentation of this file.
00001 /*
00002     AVFS: A Virtual File System Library
00003     Copyright (C) 1998-2001  Miklos Szeredi <miklos@szeredi.hu>
00004 
00005     This program can be distributed under the terms of the GNU GPL.
00006     See the file COPYING.
00007 */
00008 
00009 #include "avfs.h"
00010 #include "config.h"
00011 
00012 #include <string.h>
00013 #include <unistd.h>
00014 #include <pwd.h>
00015 #include <grp.h>
00016 
00017 #define NAMLEN 256
00018 
00019 struct ugidcache {
00020     int uid;
00021     char *uname;
00022     int myuid;
00023 
00024     int gid;
00025     char *gname;
00026     int mygid;
00027 };
00028 
00029 static void free_ugidcache(struct ugidcache *cache)
00030 {
00031     av_free(cache->uname);
00032     av_free(cache->gname);
00033 }
00034 
00035 struct ugidcache *av_new_ugidcache()
00036 {
00037     struct ugidcache *cache;
00038 
00039     AV_NEW_OBJ(cache, free_ugidcache);
00040 
00041     cache->uname = NULL;
00042     cache->myuid = getuid();
00043   
00044     cache->gname = NULL;
00045     cache->mygid = getgid();
00046 
00047     return cache;
00048 }
00049 
00050 char *av_finduname(struct ugidcache *cache, int uid, const char *deflt)
00051 {
00052     if(uid == -1)
00053         return av_strdup(deflt);
00054 
00055     if(cache->uname == NULL || uid != cache->uid) {
00056         int res;
00057         struct passwd pw;
00058         struct passwd *pwres;
00059         char *buf = NULL;
00060         size_t bufsize = 0;
00061 
00062 #ifdef HAVE_GETPWUID_R
00063         do {
00064             bufsize += 256;
00065             buf = av_realloc(buf, bufsize);
00066             res = getpwuid_r(uid, &pw, buf, bufsize, &pwres);
00067         } while(res == ERANGE);
00068 #else
00069        pwres = getpwuid(uid);
00070 #endif
00071 
00072         av_free(cache->uname);
00073         if(pwres == NULL)
00074             cache->uname = av_strdup("");
00075         else
00076             cache->uname = av_strdup(pwres->pw_name);
00077 
00078         cache->uid = uid;
00079 #ifdef HAVE_GETPWUID_R
00080         av_free(buf);
00081 #endif
00082     }
00083 
00084     if(!cache->uname[0])
00085         return av_strdup(deflt);
00086     else
00087         return av_strdup(cache->uname);
00088 }
00089 
00090 int av_finduid(struct ugidcache *cache, const char *uname, int deflt)
00091 {
00092     if(uname == NULL || !uname[0])
00093         return deflt == -1 ? cache->myuid : deflt;
00094 
00095     if(cache->uname == NULL || strcmp(uname, cache->uname) != 0) {
00096         int res;
00097         struct passwd pw;
00098         struct passwd *pwres;
00099         char *buf = NULL;
00100         size_t bufsize = 0;
00101 
00102 #ifdef HAVE_GETPWNAM_R
00103         do {
00104             bufsize += 256;
00105             buf = av_realloc(buf, bufsize);
00106             res = getpwnam_r(uname, &pw, buf, bufsize, &pwres);
00107         } while(res == ERANGE);
00108 #else
00109        pwres = getpwnam(uname);
00110 #endif
00111 
00112         if(pwres == NULL)
00113             cache->uid = -1;
00114         else
00115             cache->uid = pwres->pw_uid;
00116 
00117         av_free(cache->uname);
00118         cache->uname = av_strdup(uname);
00119 #ifdef HAVE_GETPWNAM_R
00120         av_free(buf);
00121 #endif
00122     }
00123     
00124     if(cache->uid == -1)
00125         return deflt == -1 ? cache->myuid : deflt;
00126     else
00127         return cache->uid;
00128 }
00129 
00130 char *av_findgname(struct ugidcache *cache, int gid, const char *deflt)
00131 {
00132     if(gid == -1)
00133         return av_strdup(deflt);
00134 
00135     if(cache->gname == NULL || gid != cache->gid) {
00136         int res;
00137         struct group gr;
00138         struct group *grres;
00139         char *buf = NULL;
00140         size_t bufsize = 0;
00141 
00142 #ifdef HAVE_GETGRGID_R
00143         do {
00144             bufsize += 256;
00145             buf = av_realloc(buf, bufsize);
00146             res = getgrgid_r(gid, &gr, buf, bufsize, &grres);
00147         } while(res == ERANGE);
00148 #else
00149        grres = getgrgid(gid);
00150 #endif
00151 
00152         av_free(cache->gname);
00153         if(grres == NULL)
00154             cache->gname = av_strdup("");
00155         else
00156             cache->gname = av_strdup(grres->gr_name);
00157 
00158         cache->gid = gid;
00159 #ifdef HAVE_GETGRGID_R
00160         av_free(buf);
00161 #endif
00162     }
00163     
00164     if(!cache->gname[0])
00165         return av_strdup(deflt);
00166     else
00167         return av_strdup(cache->gname);
00168 }
00169 
00170 int av_findgid(struct ugidcache *cache, const char *gname, int deflt)
00171 {
00172     if(gname == NULL || !gname[0])
00173         return deflt == -1 ? cache->mygid : deflt;
00174 
00175     if(cache->gname == NULL || strcmp(gname, cache->gname) != 0) {
00176         int res;
00177         struct group gr;
00178         struct group *grres;
00179         char *buf = NULL;
00180         size_t bufsize = 0;
00181 
00182 #ifdef HAVE_GETGRNAM_R
00183         do {
00184             bufsize += 256;
00185             buf = av_realloc(buf, bufsize);
00186             res = getgrnam_r(gname, &gr, buf, bufsize, &grres);
00187         } while(res == ERANGE);
00188 #else
00189        grres = getgrnam(gname);
00190 #endif
00191 
00192         if(grres == NULL)
00193             cache->gid = -1;
00194         else
00195             cache->gid = grres->gr_gid;
00196 
00197         av_free(cache->gname);
00198         cache->gname = av_strdup(gname);
00199 #ifdef HAVE_GETGRNAM_R
00200         av_free(buf);
00201 #endif
00202     }
00203  
00204     if(cache->gid == -1)
00205         return deflt == -1 ? cache->mygid : deflt;
00206     else
00207         return cache->gid;
00208 }
00209