"Fossies" - the Fresh Open Source Software Archive

Member "rgdbm-2.1.42/my.c" (20 Jun 2007, 8958 Bytes) of package /linux/privat/old/rgdbm-2.1.42.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "my.c" see the Fossies "Dox" file reference documentation.

    1 /* 
    2  * RGDBM functions that o/w would shadow libc (C) Peter T. Breuer 2007.
    3  *
    4  * This code is releasd under the GNU General Public Licence (GPL)
    5  * version 2 or such later version as the FSF may release in the
    6  * fullness of time (when this licence automatically becomes THAT
    7  * licence). See GPL_V2 file in the code archive for details.
    8  */
    9 
   10 #include "config.h"
   11 
   12 #include <stdio.h>
   13 #if STDC_HEADERS
   14 # include <stdlib.h>
   15 # include <stdarg.h>
   16 # include <string.h>
   17 #else
   18 # ifndef HAVE_STRCHR
   19 #  define strchr index
   20 #  define strrchr rindex
   21 # endif
   22 char *strchr (), *strrchr ();
   23 # ifndef HAVE_MEMCPY
   24 #  define memcpy(d, s, n) bcopy ((s), (d), (n))
   25 #  define memmove(d, s, n) bcopy ((s), (d), (n))
   26 # endif
   27 #endif          /* STDC_HEADERS */
   28 #ifdef HAVE_SYS_TYPES_H
   29 # include <sys/types.h>          /* for read, write etc. */
   30 #endif          /* defined(HAVE_SYS_TYPES_H) */
   31 #ifdef HAVE_UNISTD_H
   32 # include <unistd.h>             /* also for access, read, write etc. */
   33 #endif          /* defined(HAVE_UNISTD_H) */
   34 #include <sys/stat.h>           /* for stat struct */
   35 
   36 #include <errno.h>              /* for EINVAL etc. */
   37 #ifdef HAVE_GDBM_H         /* won't get far without gdbm.h */
   38 # include <gdbm.h>
   39 #elif defined(HAVE_NDBM_H) /* worth checking for ndbm too */
   40 # include <ndbm.h>
   41 #elif defined(HAVE_DBM_H)  /* even worth checking for dbm */
   42 # include <dbm.h>
   43 #endif
   44 #include <grp.h>                /* for group struct */
   45 #include <pwd.h>                /* for passwd struct */
   46 
   47 #include "gdbmd.h"
   48 #include "str.h"
   49 #include "passwd.h"
   50 #include "group.h"
   51 #include "files.h"
   52 #include "my.h"
   53 
   54 
   55 /*
   56  * break out passwd entry for @user from own passwd file 
   57  */
   58 struct passwd *
   59 mygetpwnam (char *user)
   60 {
   61 
   62     char *passwd;
   63     struct passwd *pwe;
   64     FILE *pwf;
   65 
   66     passwd = catstr (rgdbm_ctrldir, "/" GDBMD_PASSWD, NULL);
   67     if (!passwd) {
   68         //GDBMD_ERROR ("out of memory for %ldB\n",
   69         //             (long) strlen (rgdbm_ctrldir) + 1 +
   70         //             (long) strlen (GDBMD_PASSWD) + 1);
   71         return NULL;
   72     }
   73 
   74     pwf = fopen (passwd, "r");
   75     if (!pwf) {
   76         //GDBMD_ERROR ("cannot open passwd file %s\n", passwd);
   77         free (passwd);
   78         return NULL;
   79     }
   80 
   81     pwe = fgetpwnam (pwf, user);
   82     fclose (pwf);
   83     free (passwd);
   84     return pwe;
   85 }
   86 
   87 /*
   88  * break out entry for @gid from own groups file
   89  */
   90 struct group *
   91 mygetgrgid (int gid)
   92 {
   93 
   94     FILE *grf;
   95     struct group *gre;
   96     char *group = catstr (rgdbm_ctrldir, "/" GDBMD_GROUP, NULL);
   97 
   98     if (!group) {
   99         //GDBMD_ERROR ("out of memory for %ldB\n",
  100         //             (long) strlen (rgdbm_ctrldir) + 1 +
  101         //             (long) strlen (GDBMD_GROUP) + 1);
  102         return NULL;
  103     }
  104 
  105     grf = fopen (group, "r");
  106     free (group);
  107 
  108     if (!grf)
  109         return NULL;
  110 
  111     gre = fgetgrgid (grf, gid);
  112     fclose (grf);
  113 
  114     return gre;
  115 }
  116 
  117 /*
  118  * break out entry for @name from own groups file
  119  */
  120 struct group *
  121 mygetgrnam (char *name)
  122 {
  123 
  124     FILE *grf;
  125     struct group *gre;
  126     char *group = catstr (rgdbm_ctrldir, "/" GDBMD_GROUP, NULL);
  127 
  128     if (!group) {
  129         //GDBMD_ERROR ("out of memory for %ldB\n",
  130         //             (long) strlen (rgdbm_ctrldir) + 1 +
  131         //             (long) strlen (GDBMD_GROUP) + 1);
  132         return NULL;
  133     }
  134 
  135     grf = fopen (group, "r");
  136     free (group);
  137 
  138     if (!grf)
  139         return NULL;
  140 
  141     gre = fgetgrnam (grf, name);
  142     fclose (grf);
  143 
  144     return gre;
  145 }
  146 
  147 /*
  148  * find basename and dirname without making any more malloc calls.
  149  * Write zeros at the last '/'s in the @path and return the address
  150  * of the char after them as basename. Return null if there are no
  151  * '/'s.
  152  *
  153  * This is side-effecting. Path is damaged.
  154  */
  155 char *
  156 mybasename(char *path)
  157 {
  158     char *basename = strrchr(path, '/');
  159     int n = 0;
  160 
  161     if (!basename)
  162         return NULL;
  163 
  164     // shorten path
  165     while (*basename == '/' && basename >= path) {
  166         *basename-- = 0;
  167         n++;
  168     }
  169     basename += n + 1;
  170     return basename;
  171 }
  172 
  173 
  174 /*
  175  * return -ve if we don't have access rights to db @name for access
  176  * mode @rw (GDBM_WRITER, etc.). Return 0 or 1 if we do. 1 means we
  177  * have to create it. 0 means it is already there and we can access it.
  178  *
  179  * To determine access rights, we look up the db's stats in the local
  180  * files db (or take them from disk if it's not in there) and see if we
  181  * have read or write capability to it, as indicated by the @rw flag as
  182  * being necesary. We may have to do lookups in the local groups file
  183  * to determine if we are in the db's group or not. If we have the
  184  * right perms, we return 0. o/w we return -ve.
  185  *
  186  * If the db does not yet exist, we just check the @rw value to see if
  187  * we are requesting to make it. If so, we return 1, as the daemon will
  188  * make it, or at least try. o/w we return -ve.
  189  */
  190 int
  191 myaccess (char *name, int rw, uid_t uid)
  192 {
  193     int     err;
  194     struct stat *fle;
  195     int     read_mask = 0, write_mask = 0;
  196 
  197     if (access (name, F_OK) < 0) {
  198         // we are going to have to make this, if at all.
  199         switch (rw) {
  200 #ifdef HAVE_GDBM_H
  201           case GDBM_WRCREAT:
  202           case GDBM_NEWDB:
  203               return 1;         // yes, we will make a db
  204               break;
  205 #endif
  206           default:
  207 #ifdef HAVE_NDBM_H
  208               if (rw & O_CREAT) 
  209                   return 1;
  210 #elif defined(HAVE_DBM_H)
  211               return 1;
  212 #endif
  213               //GDBMD_ERROR ("no db %s and not asking to make it!\n", name);
  214               return -EINVAL;
  215         }
  216     }
  217     // exists
  218 
  219     fle = getflnam (name);
  220     if (!fle) {
  221         // not in db. Use real attributes of real file
  222         fle = malloc (sizeof (*fle));
  223         if (!fle) {
  224             //GDBMD_ERROR ("out of memory for %ldB!\n", (long)sizeof (*fle));
  225             return -ENOMEM;
  226         }
  227         if (err = stat (name, fle), err < 0) {
  228             // impossible
  229             //GDBMD_ERROR ("cannot stat %s!\n", name);
  230             free (fle);
  231             return err;
  232         }
  233         // don't add to txt file .. leave it to admin
  234     }
  235 
  236     if (uid == fle->st_uid) {
  237         // we are the file's owner. Hunky.
  238         read_mask = S_IRUSR;
  239         write_mask = S_IWUSR;
  240     } else if (myingroup (uid, fle->st_gid) > 0) {
  241         // we are in the  file's group. Also hunky.
  242         read_mask = S_IRGRP;
  243         write_mask = S_IWGRP;
  244     } else {
  245         // we are a lowly other. Not so hunky.
  246         read_mask = S_IROTH;
  247         write_mask = S_IWOTH;
  248     }
  249 
  250     switch (rw) {
  251 
  252 #ifdef HAVE_GDBM_H
  253       case GDBM_WRCREAT:
  254       case GDBM_NEWDB:
  255       case GDBM_WRITER:
  256 
  257           if (!(fle->st_mode & write_mask)) {
  258               //GDBMD_ERROR ("don't have permission (%#o) to write db %s!\n",
  259               //  write_mask, name);
  260               free (fle);
  261               return -EINVAL;
  262           }
  263           // fallthru and try read perms too
  264 
  265       case GDBM_READER:
  266 
  267           if (!(fle->st_mode & read_mask)) {
  268               //GDBMD_ERROR ("don't have permission (%#o) to read db %s!\n",
  269               //  read_mask, name);
  270               free (fle);
  271               return -EINVAL;
  272           }
  273           break;
  274 #endif
  275 
  276       default:
  277 
  278 #ifdef HAVE_NDBM_H
  279           if ((rw & O_RDWR) || (rw & O_WRONLY)) {
  280               if (!(fle->st_mode & write_mask)) {
  281                   free (fle);
  282                   return -EINVAL;
  283               }
  284               break;
  285           } else {
  286               // O_RDONLY
  287               if (!(fle->st_mode & read_mask)) {
  288                   free (fle);
  289                   return -EINVAL;
  290               }
  291               break;
  292           }
  293 #elif defined(HAVE_DBM_H)
  294           if (!(fle->st_mode & write_mask)) {
  295               free (fle);
  296               return -EINVAL;
  297           }
  298           break;
  299 #endif
  300           //GDBMD_ERROR ("unknown rw flag %d!\n", rw);
  301           free (fle);
  302           return -EINVAL;
  303     }
  304     free (fle);
  305 
  306     // OK, it's there are we have perms
  307     return 0;
  308 }
  309 
  310 
  311 /*
  312  * return the list of members of the given group, but use our files,
  313  * not the system group file. The list terminates with a -1.
  314  *
  315  * The result is gotten with malloc and can/should be freed.
  316  */
  317 uid_t *
  318 mygetgroupmembers(gid_t gid) {
  319 
  320     struct group *gre;
  321     char **uu;
  322     uid_t *g;
  323     int i, n;
  324 
  325     gre = mygetgrgid (gid);
  326 
  327     if (!gre)
  328         return NULL;
  329 
  330     n = 0;
  331     for (uu = gre->gr_mem; *uu; uu++)
  332         n++;
  333     g = malloc((n + 1)* sizeof(*g));
  334     if (!g)
  335         return NULL;
  336 
  337     for (i = 0, uu = gre->gr_mem; *uu; uu++) {
  338         struct passwd *pwe = mygetpwnam (*uu);
  339         if (!pwe)
  340             continue;
  341         g[i++] = pwe->pw_uid;
  342     }
  343     g[i] = -1;
  344 
  345     return g;
  346 }
  347 
  348 /*
  349  * check if @uid is a member of the group with @gid.
  350  * Use local passwd and group files in daemon area.
  351  */
  352 int
  353 myingroup (uid_t uid, gid_t gid)
  354 {
  355     uid_t *g, u;
  356     int i = 0;
  357 
  358     g = mygetgroupmembers(gid);
  359     if (!g)
  360         return 0;
  361 
  362     while (u = g[i++], u >= 0) {
  363         if (u == uid)
  364             break;
  365     }
  366 
  367     free(g);
  368     return u == uid;
  369 }
  370 
  371 
  372 
  373