Changeset b471854b in rtems


Ignore:
Timestamp:
Nov 14, 2014, 10:01:48 AM (5 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
80055514
Parents:
d82f9de1
git-author:
Sebastian Huber <sebastian.huber@…> (11/14/14 10:01:48)
git-committer:
Sebastian Huber <sebastian.huber@…> (11/20/14 09:30:21)
Message:

libcsupport: Split passwd/group support

Location:
cpukit/libcsupport
Files:
3 added
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libcsupport/Makefile.am

    rd82f9de1 rb471854b  
    109109    src/rtems_heap_greedy.c
    110110
    111 PASSWORD_GROUP_C_FILES = src/getpwent.c
     111PASSWORD_GROUP_C_FILES = src/pwdgrp.c
     112PASSWORD_GROUP_C_FILES += src/getgrent.c
     113PASSWORD_GROUP_C_FILES += src/getpwent.c
    112114
    113115TERMINAL_IDENTIFICATION_C_FILES = src/ctermid.c
  • cpukit/libcsupport/src/getpwent.c

    rd82f9de1 rb471854b  
    2323#endif
    2424
    25 #include <stdio.h>
    26 #include <sys/types.h>
    27 #include <pwd.h>
    28 #include <grp.h>
    29 #include <errno.h>
    30 #include <unistd.h>
    31 #include <stdlib.h>
    32 #include <string.h>
    33 #include <limits.h>
    34 #include <ctype.h>
    35 
    36 #include <rtems/libio_.h>
    37 #include <rtems/seterr.h>
    38 
    39 /**
    40  *  POSIX 1003.1b - 9.2.2 - User Database Access Routines
    41  */
     25#include "pwdgrp.h"
    4226
    4327/*
     
    4731static char pwbuf[200];
    4832static struct passwd pwent;
    49 static FILE *group_fp;
    50 static char grbuf[200];
    51 static struct group grent;
    52 
    53 /*
    54  *  Prototype to avoid warning
    55  */
    56 void init_etc_passwd_group(void);
    57 
    58 /**
    59  *  Initialize useable but dummy databases
    60  */
    61 void init_etc_passwd_group(void)
    62 {
    63   FILE *fp;
    64   static char etc_passwd_initted = 0;
    65 
    66   if (etc_passwd_initted)
    67     return;
    68   etc_passwd_initted = 1;
    69   mkdir("/etc", 0777);
    70 
    71   /*
    72    *  Initialize /etc/passwd
    73    */
    74   if ((fp = fopen("/etc/passwd", "r")) != NULL) {
    75     fclose(fp);
    76   }
    77   else if ((fp = fopen("/etc/passwd", "w")) != NULL) {
    78     fprintf(fp, "root:*:0:0:root::/:/bin/sh\n"
    79                  "rtems:*:1:1:RTEMS Application::/:/bin/sh\n"
    80                  "tty:!:2:2:tty owner::/:/bin/false\n" );
    81     fclose(fp);
    82   }
    83 
    84   /*
    85    *  Initialize /etc/group
    86    */
    87   if ((fp = fopen("/etc/group", "r")) != NULL) {
    88     fclose(fp);
    89   }
    90   else if ((fp = fopen("/etc/group", "w")) != NULL) {
    91     fprintf( fp, "root:x:0:root\n"
    92                  "rtems:x:1:rtems\n"
    93                  "tty:x:2:tty\n" );
    94     fclose(fp);
    95   }
    96 }
    97 
    98 /**
    99  *  Extract a string value from the database
    100  */
    101 static int
    102 scanString(FILE *fp, char **name, char **bufp, size_t *nleft, int nlFlag)
    103 {
    104   int c;
    105 
    106   *name = *bufp;
    107   for (;;) {
    108     c = getc(fp);
    109     if (c == ':') {
    110         if (nlFlag)
    111             return 0;
    112         break;
    113     }
    114     if (c == '\n') {
    115         if (!nlFlag)
    116             return 0;
    117         break;
    118     }
    119     if (c == EOF)
    120       return 0;
    121     if (*nleft < 2)
    122       return 0;
    123     **bufp = c;
    124     ++(*bufp);
    125     --(*nleft);
    126   }
    127   **bufp = '\0';
    128   ++(*bufp);
    129   --(*nleft);
    130   return 1;
    131 }
    132 
    133 /**
    134  *  Extract an integer value from the database
    135  */
    136 static int
    137 scanInt(FILE *fp, int *val)
    138 {
    139   int c;
    140   unsigned int i = 0;
    141   unsigned int limit = INT_MAX;
    142   int sign = 0;
    143   int d;
    144 
    145   for (;;) {
    146     c = getc(fp);
    147     if (c == ':')
    148       break;
    149     if (sign == 0) {
    150       if (c == '-') {
    151         sign = -1;
    152         limit++;
    153         continue;
    154       }
    155       sign = 1;
    156     }
    157     if (!isdigit(c))
    158       return 0;
    159     d = c - '0';
    160     if ((i > (limit / 10))
    161      || ((i == (limit / 10)) && (d > (limit % 10))))
    162       return 0;
    163     i = i * 10 + d;
    164   }
    165   if (sign == 0)
    166     return 0;
    167   *val = i * sign;
    168   return 1;
    169 }
    170 
    171 /*
    172  * Extract a single password record from the database
    173  */
    174 static int scanpw(
    175   FILE *fp,
    176   struct passwd *pwd,
    177   char *buffer,
    178   size_t bufsize
    179 )
    180 {
    181   int pwuid, pwgid;
    182 
    183   if (!scanString(fp, &pwd->pw_name, &buffer, &bufsize, 0)
    184    || !scanString(fp, &pwd->pw_passwd, &buffer, &bufsize, 0)
    185    || !scanInt(fp, &pwuid)
    186    || !scanInt(fp, &pwgid)
    187    || !scanString(fp, &pwd->pw_comment, &buffer, &bufsize, 0)
    188    || !scanString(fp, &pwd->pw_gecos, &buffer, &bufsize, 0)
    189    || !scanString(fp, &pwd->pw_dir, &buffer, &bufsize, 0)
    190    || !scanString(fp, &pwd->pw_shell, &buffer, &bufsize, 1))
    191     return 0;
    192   pwd->pw_uid = pwuid;
    193   pwd->pw_gid = pwgid;
    194   return 1;
    195 }
    196 
    197 static int getpw_r(
    198   const char     *name,
    199   int             uid,
    200   struct passwd  *pwd,
    201   char           *buffer,
    202   size_t          bufsize,
    203   struct passwd **result
    204 )
    205 {
    206   FILE *fp;
    207   int match;
    208 
    209   init_etc_passwd_group();
    210 
    211   if ((fp = fopen("/etc/passwd", "r")) == NULL)
    212     rtems_set_errno_and_return_minus_one( EINVAL );
    213 
    214   for(;;) {
    215     if (!scanpw(fp, pwd, buffer, bufsize))
    216       goto error_einval;
    217 
    218     if (name) {
    219       match = (strcmp(pwd->pw_name, name) == 0);
    220     } else {
    221       match = (pwd->pw_uid == uid);
    222     }
    223 
    224     if (match) {
    225       fclose(fp);
    226       *result = pwd;
    227       return 0;
    228     }
    229   }
    230 error_einval:
    231   fclose(fp);
    232   rtems_set_errno_and_return_minus_one( EINVAL );
    233 }
    234 
    235 int getpwnam_r(
    236   const char     *name,
    237   struct passwd  *pwd,
    238   char           *buffer,
    239   size_t          bufsize,
    240   struct passwd **result
    241 )
    242 {
    243   return getpw_r(name, 0, pwd, buffer, bufsize, result);
    244 }
    24533
    24634struct passwd *getpwnam(
     
    25341    return NULL;
    25442  return p;
    255 }
    256 
    257 int getpwuid_r(
    258   uid_t           uid,
    259   struct passwd  *pwd,
    260   char           *buffer,
    261   size_t          bufsize,
    262   struct passwd **result
    263 )
    264 {
    265   return getpw_r(NULL, uid, pwd, buffer, bufsize, result);
    26643}
    26744
     
    28158  if (passwd_fp == NULL)
    28259    return NULL;
    283   if (!scanpw(passwd_fp, &pwent, pwbuf, sizeof pwbuf))
     60  if (!_libcsupport_scanpw(passwd_fp, &pwent, pwbuf, sizeof pwbuf))
    28461    return NULL;
    28562  return &pwent;
     
    28865void setpwent(void)
    28966{
    290   init_etc_passwd_group();
     67  _libcsupport_pwdgrp_init();
    29168
    29269  if (passwd_fp != NULL)
     
    30077    fclose(passwd_fp);
    30178}
    302 
    303 /**
    304  *  Extract a single group record from the database
    305  */
    306 static int scangr(
    307   FILE *fp,
    308   struct group *grp,
    309   char *buffer,
    310   size_t bufsize
    311 )
    312 {
    313   int grgid;
    314   char *grmem, *cp;
    315   int memcount;
    316 
    317   if (!scanString(fp, &grp->gr_name, &buffer, &bufsize, 0)
    318    || !scanString(fp, &grp->gr_passwd, &buffer, &bufsize, 0)
    319    || !scanInt(fp, &grgid)
    320    || !scanString(fp, &grmem, &buffer, &bufsize, 1))
    321     return 0;
    322   grp->gr_gid = grgid;
    323 
    324   /*
    325    * Determine number of members
    326    */
    327   for (cp = grmem, memcount = 1 ; *cp != 0 ; cp++) {
    328     if(*cp == ',')
    329       memcount++;
    330   }
    331 
    332   /*
    333    * Hack to produce (hopefully) a suitably-aligned array of pointers
    334    */
    335   if (bufsize < (((memcount+1)*sizeof(char *)) + 15))
    336     return 0;
    337   grp->gr_mem = (char **)(((uintptr_t)buffer + 15) & ~15);
    338 
    339   /*
    340    * Fill in pointer array
    341    */
    342   grp->gr_mem[0] = grmem;
    343   for (cp = grmem, memcount = 1 ; *cp != 0 ; cp++) {
    344     if(*cp == ',') {
    345       *cp = '\0';
    346       grp->gr_mem[memcount++] = cp + 1;
    347     }
    348   }
    349   grp->gr_mem[memcount] = NULL;
    350   return 1;
    351 }
    352 
    353 static int getgr_r(
    354   const char     *name,
    355   int             gid,
    356   struct group   *grp,
    357   char           *buffer,
    358   size_t          bufsize,
    359   struct group  **result
    360 )
    361 {
    362   FILE *fp;
    363   int match;
    364 
    365   init_etc_passwd_group();
    366 
    367   if ((fp = fopen("/etc/group", "r")) == NULL)
    368     rtems_set_errno_and_return_minus_one( EINVAL );
    369 
    370   for(;;) {
    371     if (!scangr(fp, grp, buffer, bufsize))
    372       goto error_einval;
    373 
    374     if (name) {
    375       match = (strcmp(grp->gr_name, name) == 0);
    376     } else {
    377       match = (grp->gr_gid == gid);
    378     }
    379 
    380     if (match) {
    381       fclose(fp);
    382       *result = grp;
    383       return 0;
    384     }
    385   }
    386 error_einval:
    387   fclose(fp);
    388   rtems_set_errno_and_return_minus_one( EINVAL );
    389 }
    390 
    391 int getgrnam_r(
    392   const char     *name,
    393   struct group   *grp,
    394   char           *buffer,
    395   size_t          bufsize,
    396   struct group  **result
    397 )
    398 {
    399   return getgr_r(name, 0, grp, buffer, bufsize, result);
    400 }
    401 
    402 struct group *getgrnam(
    403   const char *name
    404 )
    405 {
    406   struct group *p;
    407 
    408   if(getgrnam_r(name, &grent, grbuf, sizeof grbuf, &p))
    409     return NULL;
    410   return p;
    411 }
    412 
    413 int getgrgid_r(
    414   gid_t           gid,
    415   struct group   *grp,
    416   char           *buffer,
    417   size_t          bufsize,
    418   struct group  **result
    419 )
    420 {
    421   return getgr_r(NULL, gid, grp, buffer, bufsize, result);
    422 }
    423 
    424 struct group *getgrgid(
    425   gid_t gid
    426 )
    427 {
    428   struct group *p;
    429 
    430   if(getgrgid_r(gid, &grent, grbuf, sizeof grbuf, &p))
    431     return NULL;
    432   return p;
    433 }
    434 
    435 struct group *getgrent(void)
    436 {
    437   if (group_fp == NULL)
    438     return NULL;
    439   if (!scangr(group_fp, &grent, grbuf, sizeof grbuf))
    440     return NULL;
    441   return &grent;
    442 }
    443 
    444 void setgrent(void)
    445 {
    446   init_etc_passwd_group();
    447 
    448   if (group_fp != NULL)
    449     fclose(group_fp);
    450   group_fp = fopen("/etc/group", "r");
    451 }
    452 
    453 void endgrent(void)
    454 {
    455   if (group_fp != NULL)
    456     fclose(group_fp);
    457 }
Note: See TracChangeset for help on using the changeset viewer.