Changeset ed8c513 in rtems


Ignore:
Timestamp:
Oct 2, 2002, 5:33:17 PM (17 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
bcac0cb
Parents:
f4ceef3e
Message:

2002-10-02 Eric Norum <eric.norum@…>

  • src/getpwent.c: Per PR283, reimplement to address reentrancy problems.
  • src/getgrent.c: Removed as functionality is now just a wrapper for common routines in src/getpwent.c.
  • Makefile.am: Reflect file removal.
Location:
cpukit/libcsupport
Files:
1 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libcsupport/ChangeLog

    rf4ceef3e red8c513  
     12002-10-02      Eric Norum <eric.norum@usask.ca>
     2
     3        * src/getpwent.c: Per PR283, reimplement to address reentrancy problems.
     4        * src/getgrent.c: Removed as functionality is now just a wrapper for
     5        common routines in src/getpwent.c.
     6        * Makefile.am: Reflect file removal.
     7
    182002-09-14      Joel Sherrill <joel@OARcorp.com>
    29
  • cpukit/libcsupport/Makefile.am

    rf4ceef3e red8c513  
    118118MALLOC_C_FILES = src/malloc.c src/mallocfreespace.c src/__brk.c src/__sbrk.c
    119119
    120 PASSWORD_GROUP_C_FILES = src/getpwent.c src/getgrent.c
     120PASSWORD_GROUP_C_FILES = src/getpwent.c
    121121
    122122TERMINAL_IDENTIFICATION_C_FILES = src/ctermid.c src/isatty.c src/ttyname.c \
  • cpukit/libcsupport/src/getpwent.c

    rf4ceef3e red8c513  
    1616#include <sys/types.h>
    1717#include <pwd.h>
     18#include <grp.h>
    1819#include <errno.h>
    1920#include <unistd.h>
     
    2122#include <string.h>
    2223#include <limits.h>
    23 #include <fcntl.h>
    24 #include <unistd.h>
     24#include <ctype.h>
    2525
    2626#include <rtems/libio_.h>
    2727
    28 static struct passwd pw_passwd;  /* password structure */
     28/*
     29 * Static, thread-unsafe, buffers
     30 */
    2931static FILE *passwd_fp;
    30 
    31 /*
    32  *  The size of these buffers is arbitrary and there is no provision
    33  *  to protect any of them from overflowing.  The scanf patterns
    34  *  need to be changed to prevent overflowing.  In addition,
    35  *  the limits on these needs to be examined.
    36  */
    37 
    38 static char logname[8];
    39 static char password[1024];
    40 static char comment[1024];
    41 static char gecos[1024];
    42 static char dir[1024];
    43 static char shell[1024];
    44 
    45 /*
    46  *  Initialize a useable but dummy /etc/passwd
    47  *
    48  *  NOTE: Ignore all errors.
    49  *
    50  */
    51 
    52 static char etc_passwd_initted = 0;
    53 
     32static char pwbuf[200];
     33static struct passwd pwent;
     34static FILE *group_fp;
     35static char grbuf[200];
     36static struct group grent;
     37
     38/*
     39 * Initialize useable but dummy databases
     40 */
    5441void init_etc_passwd_group(void)
    5542{
    5643  FILE *fp;
    57 
    58   if ( etc_passwd_initted )
     44  static char etc_passwd_initted = 0;
     45
     46  if (etc_passwd_initted)
    5947    return;
    6048  etc_passwd_initted = 1;
    61 
    62   (void) mkdir( "/etc", 0777);
     49  mkdir("/etc", 0777);
    6350
    6451  /*
    6552   *  Initialize /etc/passwd
    6653   */
    67 
    68   if ((fp = fopen ("/etc/passwd", "w")) == NULL)
    69     return;
    70 
    71   fprintf( fp, "root:*:0:0:root,,,,:/:/bin/sh\n"
    72                "rtems:*:1:1:RTEMS Application,,,,:/:/bin/sh\n"
    73                "tty:!:2:2:tty owner,,,,:/:/bin/false\n" );
    74 
    75   fclose( fp );
     54  if ((fp = fopen("/etc/passwd", "r")) != NULL) {
     55    fclose(fp);
     56  }
     57  else if ((fp = fopen("/etc/passwd", "w")) != NULL) {
     58    fprintf(fp, "root:*:0:0:root::/:/bin/sh\n"
     59                 "rtems:*:1:1:RTEMS Application::/:/bin/sh\n"
     60                 "tty:!:2:2:tty owner::/:/bin/false\n" );
     61    fclose(fp);
     62  }
    7663
    7764  /*
    7865   *  Initialize /etc/group
    7966   */
    80 
    81   if ((fp = fopen ("/etc/group", "w")) == NULL)
    82     return;
    83 
    84   fprintf( fp, "root:x:0:root\n"
    85                "rtems:x:1:rtems\n"
    86                "tty:x:2:tty\n" );
    87 
    88   fclose( fp );
     67  if ((fp = fopen("/etc/group", "r")) != NULL) {
     68    fclose(fp);
     69  }
     70  else if ((fp = fopen("/etc/group", "w")) != NULL) {
     71    fprintf( fp, "root:x:0:root\n"
     72                 "rtems:x:1:rtems\n"
     73                 "tty:x:2:tty\n" );
     74    fclose(fp);
     75  }
     76}
     77
     78/*
     79 * Extract a string value from the database
     80 */
     81static int
     82scanString(FILE *fp, char **name, char **bufp, size_t *nleft, int nlFlag)
     83{
     84  int c;
     85
     86  *name = *bufp;
     87  for (;;) {
     88    c = getc(fp);
     89    if (c == ':') {
     90        if (nlFlag)
     91            return 0;
     92        break;
     93    }
     94    if (c == '\n') {
     95        if (!nlFlag)
     96            return 0;
     97        break;
     98    }
     99    if (c == EOF)
     100      return 0;
     101    if (*nleft < 2)
     102      return 0;
     103    **bufp = c;
     104    ++(*bufp);
     105    --(*nleft);
     106  }
     107  **bufp = '\0';
     108  ++(*bufp);
     109  --(*nleft);
     110  return 1;
     111}
     112
     113/*
     114 * Extract an integer value from the database
     115 */
     116static int
     117scanInt(FILE *fp, int *val)
     118{
     119  int c;
     120  unsigned int i = 0;
     121  unsigned int limit = INT_MAX;
     122  int sign = 0;
     123  int d;
     124
     125  for (;;) {
     126    c = getc(fp);
     127    if (c == ':')
     128      break;
     129    if (sign == 0) {
     130      if (c == '-') {
     131        sign = -1;
     132        limit++;
     133        continue;
     134      }
     135      sign = 1;
     136    }
     137    if (!isdigit(c))
     138      return 0;
     139    d = c - '0';
     140    if ((i > (limit / 10))
     141     || ((i == (limit / 10)) && (d > (limit % 10))))
     142      return 0;
     143    i = i * 10 + d;
     144  }
     145  if (sign == 0)
     146    return 0;
     147  *val = i * sign;
     148  return 1;
     149}
     150
     151/*
     152 * Extract a single password record from the database
     153 */
     154static int scanpw(
     155  FILE *fp,
     156  struct passwd *pwd,
     157  char *buffer,
     158  size_t bufsize
     159)
     160{
     161  int pwuid, pwgid;
     162
     163  if (!scanString(fp, &pwd->pw_name, &buffer, &bufsize, 0)
     164   || !scanString(fp, &pwd->pw_passwd, &buffer, &bufsize, 0)
     165   || !scanInt(fp, &pwuid)
     166   || !scanInt(fp, &pwgid)
     167   || !scanString(fp, &pwd->pw_comment, &buffer, &bufsize, 0)
     168   || !scanString(fp, &pwd->pw_gecos, &buffer, &bufsize, 0)
     169   || !scanString(fp, &pwd->pw_dir, &buffer, &bufsize, 0)
     170   || !scanString(fp, &pwd->pw_shell, &buffer, &bufsize, 1))
     171    return 0;
     172  pwd->pw_uid = pwuid;
     173  pwd->pw_gid = pwgid;
     174  return 1;
     175}
     176
     177static int getpw_r(
     178  const char     *name,
     179  int             uid,
     180  struct passwd  *pwd,
     181  char           *buffer,
     182  size_t          bufsize,
     183  struct passwd **result
     184)
     185{
     186  FILE *fp;
     187  int match;
     188  rtems_user_env_t * aux=rtems_current_user_env; /* save */
     189
     190  init_etc_passwd_group();
     191  rtems_current_user_env=&rtems_global_user_env; /* set root */
     192
     193  if ((fp = fopen("/etc/passwd", "r")) == NULL) {
     194    errno = EINVAL;
     195    rtems_current_user_env=aux; /* restore */
     196    return -1;
     197  }
     198  for(;;) {
     199    if (!scanpw(fp, pwd, buffer, bufsize)) {
     200      errno = EINVAL;
     201      fclose(fp);
     202      rtems_current_user_env=aux; /* restore */
     203      return -1;
     204    }
     205    if (name) {
     206      match = (strcmp(pwd->pw_name, name) == 0);
     207    }
     208    else {
     209      match = (pwd->pw_uid == uid);
     210    }
     211    if (match) {
     212      fclose(fp);
     213      *result = pwd;
     214      rtems_current_user_env=aux; /* restore */
     215      return 0;
     216    }
     217  }
     218  fclose(fp);
     219  errno = EINVAL;
     220  rtems_current_user_env=aux; /* restore */
     221  return -1;
    89222}
    90223
     
    97230)
    98231{
    99   FILE *fp;
     232  return getpw_r(name, 0, pwd, buffer, bufsize, result);
     233}
     234
     235struct passwd *getpwnam(
     236  const char *name
     237)
     238{
     239  struct passwd *p;
     240
     241  if(getpwnam_r(name, &pwent, pwbuf, sizeof pwbuf, &p))
     242    return NULL;
     243  return p;
     244}
     245
     246int getpwuid_r(
     247  uid_t           uid,
     248  struct passwd  *pwd,
     249  char           *buffer,
     250  size_t          bufsize,
     251  struct passwd **result
     252)
     253{
     254  return getpw_r(NULL, uid, pwd, buffer, bufsize, result);
     255}
     256
     257struct passwd *getpwuid(
     258  uid_t uid
     259)
     260{
     261  struct passwd *p;
     262
     263  if(getpwuid_r(uid, &pwent, pwbuf, sizeof pwbuf, &p))
     264    return NULL;
     265  return p;
     266}
     267
     268struct passwd *getpwent()
     269{
     270  if (passwd_fp == NULL)
     271    return NULL;
     272  if (!scanpw(passwd_fp, &pwent, pwbuf, sizeof pwbuf))
     273    return NULL;
     274  return &pwent;
     275}
     276
     277void setpwent(void)
     278{
    100279  rtems_user_env_t * aux=rtems_current_user_env; /* save */
    101 
    102280  init_etc_passwd_group();
    103281  rtems_current_user_env=&rtems_global_user_env; /* set root */
    104282
    105   if ((fp = fopen ("/etc/passwd", "r")) == NULL) {
     283  if (passwd_fp != NULL)
     284    fclose(passwd_fp);
     285  passwd_fp = fopen("/etc/passwd", "r");
     286  rtems_current_user_env=aux; /* restore */
     287}
     288
     289void endpwent(void)
     290{
     291  if (passwd_fp != NULL)
     292    fclose(passwd_fp);
     293}
     294
     295/*
     296 * Extract a single group record from the database
     297 */
     298static int scangr(
     299  FILE *fp,
     300  struct group *grp,
     301  char *buffer,
     302  size_t bufsize
     303)
     304{
     305  int grgid;
     306  char *grmem, *cp;
     307  int memcount;
     308
     309  if (!scanString(fp, &grp->gr_name, &buffer, &bufsize, 0)
     310   || !scanString(fp, &grp->gr_passwd, &buffer, &bufsize, 0)
     311   || !scanInt(fp, &grgid)
     312   || !scanString(fp, &grmem, &buffer, &bufsize, 1))
     313    return 0;
     314  grp->gr_gid = grgid;
     315
     316  /*
     317   * Determine number of members
     318   */
     319  for (cp = grmem, memcount = 1 ; *cp != 0 ; cp++) {
     320    if(*cp == ',')
     321      memcount++;
     322  }
     323
     324  /*
     325   * Hack to produce (hopefully) a suitably-aligned array of pointers
     326   */
     327  if (bufsize < (((memcount+1)*sizeof(char *)) + 15))
     328    return 0;
     329  grp->gr_mem = (char **)(((unsigned long)buffer + 15) & ~15);
     330
     331  /*
     332   * Fill in pointer array
     333   */
     334  grp->gr_mem[0] = grmem;
     335  for (cp = grmem, memcount = 1 ; *cp != 0 ; cp++) {
     336    if(*cp == ',') {
     337      *cp = '\0';
     338      grp->gr_mem[memcount++] = cp + 1;
     339    }
     340  }
     341  grp->gr_mem[memcount] = NULL;
     342  return 1;
     343}
     344
     345static int getgr_r(
     346  const char     *name,
     347  int             gid,
     348  struct group   *grp,
     349  char           *buffer,
     350  size_t          bufsize,
     351  struct group  **result
     352)
     353{
     354  FILE *fp;
     355  int match;
     356  rtems_user_env_t * aux=rtems_current_user_env; /* save */
     357
     358  init_etc_passwd_group();
     359  rtems_current_user_env=&rtems_global_user_env; /* set root */
     360
     361  if ((fp = fopen("/etc/group", "r")) == NULL) {
    106362    errno = EINVAL;
    107363    rtems_current_user_env=aux; /* restore */
    108364    return -1;
    109365  }
    110 
    111   while (fgets (buffer, bufsize, fp)) {
    112     sscanf (buffer, "%[^:]:%[^:]:%d:%d:%[^:]:%[^:]:%[^:]:%s\n",
    113         logname, password, &pwd->pw_uid,
    114         &pwd->pw_gid, comment, gecos,
    115         dir, shell);
    116     pwd->pw_name = logname;
    117     pwd->pw_passwd = password;
    118     pwd->pw_comment = comment;
    119     pwd->pw_gecos = gecos;
    120     pwd->pw_dir = dir;
    121     pwd->pw_shell = shell;
    122 
    123     if (!strcmp (logname, name)) {
    124       fclose (fp);
    125       *result = pwd;
     366  for(;;) {
     367    if (!scangr(fp, grp, buffer, bufsize)) {
     368      errno = EINVAL;
     369      fclose(fp);
    126370      rtems_current_user_env=aux; /* restore */
    127       return 0;
    128     }
    129   }
    130   fclose (fp);
    131   errno = EINVAL;
    132     rtems_current_user_env=aux; /* restore */
    133   return -1;
    134 }
    135 
    136 struct passwd *getpwnam(
    137   const char *name
    138 )
    139 {
    140   char   buf[1024];
    141   struct passwd *p;
    142 
    143   if ( getpwnam_r( name, &pw_passwd, buf, 1024, &p ) )
    144     return NULL;
    145 
    146   return p;
    147 }
    148 
    149 int getpwuid_r(
    150   uid_t           uid,
    151   struct passwd  *pwd,
    152   char           *buffer,
    153   size_t          bufsize,
    154   struct passwd **result
    155 )
    156 {
    157   FILE *fp;
    158   rtems_user_env_t * aux=rtems_current_user_env; /* save */
    159 
    160   init_etc_passwd_group();
    161   rtems_current_user_env=&rtems_global_user_env; /* set root */
    162 
    163   if ((fp = fopen ("/etc/passwd", "r")) == NULL) {
    164     errno = EINVAL;
    165     rtems_current_user_env=aux; /* restore */
    166     return -1;
    167   }
    168 
    169   while (fgets (buffer, bufsize, fp)) {
    170     sscanf (buffer, "%[^:]:%[^:]:%d:%d:%[^:]:%[^:]:%[^:]:%s\n",
    171      logname, password, &pw_passwd.pw_uid,
    172      &pw_passwd.pw_gid, comment, gecos,
    173      dir, shell);
    174     pwd->pw_name = logname;
    175     pwd->pw_passwd = password;
    176     pwd->pw_comment = comment;
    177     pwd->pw_gecos = gecos;
    178     pwd->pw_dir = dir;
    179     pwd->pw_shell = shell;
    180 
    181     if (uid == pwd->pw_uid) {
    182       fclose (fp);
    183       *result = pwd;
     371      return -1;
     372    }
     373    if (name) {
     374      match = (strcmp(grp->gr_name, name) == 0);
     375    }
     376    else {
     377      match = (grp->gr_gid == gid);
     378    }
     379    if (match) {
     380      fclose(fp);
     381      *result = grp;
    184382      rtems_current_user_env=aux; /* restore */
    185383      return 0;
    186384    }
    187385  }
    188   fclose (fp);
     386  fclose(fp);
    189387  errno = EINVAL;
    190388  rtems_current_user_env=aux; /* restore */
     
    192390}
    193391
    194 struct passwd *getpwuid(
    195   uid_t uid
    196 )
    197 {
    198   char   buf[1024];
    199   struct passwd *p;
    200 
    201   if ( getpwuid_r( uid, &pw_passwd, buf, 1024, &p ) )
    202     return NULL;
    203 
     392int getgrnam_r(
     393  const char     *name,
     394  struct group   *grp,
     395  char           *buffer,
     396  size_t          bufsize,
     397  struct group  **result
     398)
     399{
     400  return getgr_r(name, 0, grp, buffer, bufsize, result);
     401}
     402
     403struct group *getgrnam(
     404  const char *name
     405)
     406{
     407  struct group *p;
     408
     409  if(getgrnam_r(name, &grent, grbuf, sizeof grbuf, &p))
     410    return NULL;
    204411  return p;
    205412}
    206413
    207 struct passwd *getpwent()
    208 {
    209   char buf[1024];
    210 
    211   if (passwd_fp == NULL)
    212     return NULL;
    213 
    214   if (fgets (buf, sizeof (buf), passwd_fp) == NULL)
    215     return NULL;
    216 
    217   sscanf (buf, "%[^:]:%[^:]:%d:%d:%[^:]:%[^:]:%[^:]:%s\n",
    218     logname, password, &pw_passwd.pw_uid,
    219     &pw_passwd.pw_gid, comment, gecos,
    220     dir, shell);
    221   pw_passwd.pw_name = logname;
    222   pw_passwd.pw_passwd = password;
    223   pw_passwd.pw_comment = comment;
    224   pw_passwd.pw_gecos = gecos;
    225   pw_passwd.pw_dir = dir;
    226   pw_passwd.pw_shell = shell;
    227 
    228   return &pw_passwd;
    229 }
    230 
    231 void setpwent( void )
     414int getgrgid_r(
     415  gid_t           gid,
     416  struct group   *grp,
     417  char           *buffer,
     418  size_t          bufsize,
     419  struct group  **result
     420)
     421{
     422  return getgr_r(NULL, gid, grp, buffer, bufsize, result);
     423}
     424
     425struct group *getgrgid(
     426  gid_t gid
     427)
     428{
     429  struct group *p;
     430
     431  if(getgrgid_r(gid, &grent, grbuf, sizeof grbuf, &p))
     432    return NULL;
     433  return p;
     434}
     435
     436struct group *getgrent()
     437{
     438  if (group_fp == NULL)
     439    return NULL;
     440  if (!scangr(group_fp, &grent, grbuf, sizeof grbuf))
     441    return NULL;
     442  return &grent;
     443}
     444
     445void setgrent(void)
    232446{
    233447  rtems_user_env_t * aux=rtems_current_user_env; /* save */
     
    235449  rtems_current_user_env=&rtems_global_user_env; /* set root */
    236450
    237   if (passwd_fp != NULL)
    238     fclose (passwd_fp);
    239 
    240   passwd_fp = fopen ("/etc/passwd", "r");
     451  if (group_fp != NULL)
     452    fclose(group_fp);
     453  group_fp = fopen("/etc/group", "r");
    241454  rtems_current_user_env=aux; /* restore */
    242455}
    243456
    244 void endpwent( void )
    245 {
    246   if (passwd_fp != NULL)
    247     fclose (passwd_fp);
    248 }
     457void endgrent(void)
     458{
     459  if (group_fp != NULL)
     460    fclose(group_fp);
     461}
Note: See TracChangeset for help on using the changeset viewer.