root/maint/gnulib/lib/getugroups.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. getugroups
  2. getugroups

   1 /* getugroups.c -- return a list of the groups a user is in
   2 
   3    Copyright (C) 1990-1991, 1998-2000, 2003-2021 Free Software Foundation, Inc.
   4 
   5    This file is free software: you can redistribute it and/or modify
   6    it under the terms of the GNU Lesser General Public License as
   7    published by the Free Software Foundation; either version 2.1 of the
   8    License, or (at your option) any later version.
   9 
  10    This file is distributed in the hope that it will be useful,
  11    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13    GNU Lesser General Public License for more details.
  14 
  15    You should have received a copy of the GNU Lesser General Public License
  16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  17 
  18 /* Written by David MacKenzie. */
  19 
  20 #include <config.h>
  21 
  22 #include "getugroups.h"
  23 
  24 #include <errno.h>
  25 #include <limits.h>
  26 #include <stdio.h> /* grp.h on alpha OSF1 V2.0 uses "FILE *". */
  27 #include <string.h>
  28 #include <unistd.h>
  29 
  30 #if !HAVE_GRP_H || defined __ANDROID__
  31 
  32 /* Mingw lacks all things related to group management.  The best we
  33    can do is fail with ENOSYS.
  34 
  35    Bionic declares e.g. getgrent() in <grp.h> but it isn't actually
  36    defined in the library.  */
  37 
  38 int
  39 getugroups (_GL_UNUSED int maxcount,
     /* [previous][next][first][last][top][bottom][index][help] */
  40             _GL_UNUSED gid_t *grouplist,
  41             _GL_UNUSED char const *username,
  42             _GL_UNUSED gid_t gid)
  43 {
  44   errno = ENOSYS;
  45   return -1;
  46 }
  47 
  48 #else /* HAVE_GRP_H */
  49 # include <grp.h>
  50 
  51 # define STREQ(a, b) (strcmp (a, b) == 0)
  52 
  53 /* Like 'getgroups', but for user USERNAME instead of for the current
  54    process.  Store at most MAXCOUNT group IDs in the GROUPLIST array.
  55    If GID is not -1, store it first (if possible).  GID should be the
  56    group ID (pw_gid) obtained from getpwuid, in case USERNAME is not
  57    listed in /etc/groups.  Upon failure, set errno and return -1.
  58    Otherwise, return the number of IDs we've written into GROUPLIST.  */
  59 
  60 int
  61 getugroups (int maxcount, gid_t *grouplist, char const *username,
     /* [previous][next][first][last][top][bottom][index][help] */
  62             gid_t gid)
  63 {
  64   int count = 0;
  65 
  66   if (gid != (gid_t) -1)
  67     {
  68       if (maxcount != 0)
  69         grouplist[count] = gid;
  70       ++count;
  71     }
  72 
  73   setgrent ();
  74   while (1)
  75     {
  76       char **cp;
  77       struct group *grp;
  78 
  79       errno = 0;
  80       grp = getgrent ();
  81       if (grp == NULL)
  82         break;
  83 
  84       for (cp = grp->gr_mem; *cp; ++cp)
  85         {
  86           int n;
  87 
  88           if ( ! STREQ (username, *cp))
  89             continue;
  90 
  91           /* See if this group number is already on the list.  */
  92           for (n = 0; n < count; ++n)
  93             if (grouplist && grouplist[n] == grp->gr_gid)
  94               break;
  95 
  96           /* If it's a new group number, then try to add it to the list.  */
  97           if (n == count)
  98             {
  99               if (maxcount != 0)
 100                 {
 101                   if (count >= maxcount)
 102                     goto done;
 103                   grouplist[count] = grp->gr_gid;
 104                 }
 105               if (count == INT_MAX)
 106                 {
 107                   errno = EOVERFLOW;
 108                   goto done;
 109                 }
 110               count++;
 111             }
 112         }
 113     }
 114 
 115   if (errno != 0)
 116     count = -1;
 117 
 118  done:
 119   {
 120     int saved_errno = errno;
 121     endgrent ();
 122     errno = saved_errno;
 123   }
 124 
 125   return count;
 126 }
 127 
 128 #endif /* HAVE_GRP_H */

/* [previous][next][first][last][top][bottom][index][help] */