Mercurial > hg > octave-nkf > gnulib-hg
annotate lib/getugroups.c @ 9703:e29f811d31c0
Don't rely on signed integer overflowing to negative value.
* lib/getugroups.c (getugroups): Include <limits.h>.
Instead, compare against INT_MAX, and increment only if the test passes.
author | Lasse Collin <lasse.collin@tukaani.org> |
---|---|
date | Wed, 23 Jan 2008 17:48:40 +0100 |
parents | bbbbbf4cd1c5 |
children | 85800f596ad2 |
rev | line source |
---|---|
9 | 1 /* getugroups.c -- return a list of the groups a user is in |
5159 | 2 |
9043
c69012fcd861
* lib/getugroups.h: New file.
Jim Meyering <jim@meyering.net>
parents:
7302
diff
changeset
|
3 Copyright (C) 1990, 1991, 1998-2000, 2003-2007 Free Software Foundation. |
9 | 4 |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
9049
diff
changeset
|
5 This program is free software: you can redistribute it and/or modify |
9 | 6 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
9049
diff
changeset
|
7 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
9049
diff
changeset
|
8 (at your option) any later version. |
9 | 9 |
10 This program 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 General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
9049
diff
changeset
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
9 | 17 |
18 /* Written by David MacKenzie. */ | |
19 | |
7302
8a1a9361108c
* _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents:
6793
diff
changeset
|
20 #include <config.h> |
578
3cea4259ae09
Include stdio.h before grp.h.
Jim Meyering <jim@meyering.net>
parents:
9
diff
changeset
|
21 |
9043
c69012fcd861
* lib/getugroups.h: New file.
Jim Meyering <jim@meyering.net>
parents:
7302
diff
changeset
|
22 #include "getugroups.h" |
c69012fcd861
* lib/getugroups.h: New file.
Jim Meyering <jim@meyering.net>
parents:
7302
diff
changeset
|
23 |
9703
e29f811d31c0
Don't rely on signed integer overflowing to negative value.
Lasse Collin <lasse.collin@tukaani.org>
parents:
9309
diff
changeset
|
24 #include <limits.h> |
578
3cea4259ae09
Include stdio.h before grp.h.
Jim Meyering <jim@meyering.net>
parents:
9
diff
changeset
|
25 #include <stdio.h> /* grp.h on alpha OSF1 V2.0 uses "FILE *". */ |
9 | 26 #include <grp.h> |
27 | |
6275 | 28 #include <unistd.h> |
9 | 29 |
5159 | 30 #include <errno.h> |
31 #ifndef EOVERFLOW | |
32 # define EOVERFLOW EINVAL | |
33 #endif | |
34 | |
6793
211a3b19d9ef
Correct an outdated comment. From Bruno Haible.
Jim Meyering <jim@meyering.net>
parents:
6275
diff
changeset
|
35 /* Some old header files might not declare setgrent, getgrent, and endgrent. |
9 | 36 If you don't have them at all, we can't implement this function. |
37 You lose! */ | |
38 struct group *getgrent (); | |
39 | |
4654 | 40 #include <string.h> |
9 | 41 |
1843
d9e10c329845
(getugroups): Don't dereference a null pointer when
Jim Meyering <jim@meyering.net>
parents:
1733
diff
changeset
|
42 #define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) |
d9e10c329845
(getugroups): Don't dereference a null pointer when
Jim Meyering <jim@meyering.net>
parents:
1733
diff
changeset
|
43 |
1733
6b0ff21d3888
(getugroups): Take new parameter, gid.
Jim Meyering <jim@meyering.net>
parents:
1731
diff
changeset
|
44 /* Like `getgroups', but for user USERNAME instead of for the current |
6b0ff21d3888
(getugroups): Take new parameter, gid.
Jim Meyering <jim@meyering.net>
parents:
1731
diff
changeset
|
45 process. Store at most MAXCOUNT group IDs in the GROUPLIST array. |
6b0ff21d3888
(getugroups): Take new parameter, gid.
Jim Meyering <jim@meyering.net>
parents:
1731
diff
changeset
|
46 If GID is not -1, store it first (if possible). GID should be the |
6b0ff21d3888
(getugroups): Take new parameter, gid.
Jim Meyering <jim@meyering.net>
parents:
1731
diff
changeset
|
47 group ID (pw_gid) obtained from getpwuid, in case USERNAME is not |
9049
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
48 listed in /etc/groups. Upon failure, set errno and return -1. |
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
49 Otherwise, return the number of IDs we've written into GROUPLIST. */ |
9 | 50 |
51 int | |
9043
c69012fcd861
* lib/getugroups.h: New file.
Jim Meyering <jim@meyering.net>
parents:
7302
diff
changeset
|
52 getugroups (int maxcount, GETGROUPS_T *grouplist, char const *username, |
c69012fcd861
* lib/getugroups.h: New file.
Jim Meyering <jim@meyering.net>
parents:
7302
diff
changeset
|
53 gid_t gid) |
9 | 54 { |
9043
c69012fcd861
* lib/getugroups.h: New file.
Jim Meyering <jim@meyering.net>
parents:
7302
diff
changeset
|
55 int count = 0; |
9 | 56 |
2571
a3aef28bde56
(getugroups): Cast -1 to gid_t, for systems like
Jim Meyering <jim@meyering.net>
parents:
1843
diff
changeset
|
57 if (gid != (gid_t) -1) |
1733
6b0ff21d3888
(getugroups): Take new parameter, gid.
Jim Meyering <jim@meyering.net>
parents:
1731
diff
changeset
|
58 { |
6b0ff21d3888
(getugroups): Take new parameter, gid.
Jim Meyering <jim@meyering.net>
parents:
1731
diff
changeset
|
59 if (maxcount != 0) |
6b0ff21d3888
(getugroups): Take new parameter, gid.
Jim Meyering <jim@meyering.net>
parents:
1731
diff
changeset
|
60 grouplist[count] = gid; |
6b0ff21d3888
(getugroups): Take new parameter, gid.
Jim Meyering <jim@meyering.net>
parents:
1731
diff
changeset
|
61 ++count; |
6b0ff21d3888
(getugroups): Take new parameter, gid.
Jim Meyering <jim@meyering.net>
parents:
1731
diff
changeset
|
62 } |
1730
05413a4755ee
(getugroups): Take new parameter, gid.
Jim Meyering <jim@meyering.net>
parents:
1263
diff
changeset
|
63 |
9 | 64 setgrent (); |
9049
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
65 while (1) |
1843
d9e10c329845
(getugroups): Don't dereference a null pointer when
Jim Meyering <jim@meyering.net>
parents:
1733
diff
changeset
|
66 { |
9043
c69012fcd861
* lib/getugroups.h: New file.
Jim Meyering <jim@meyering.net>
parents:
7302
diff
changeset
|
67 char **cp; |
9049
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
68 struct group *grp; |
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
69 |
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
70 errno = 0; |
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
71 grp = getgrent (); |
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
72 if (grp == NULL) |
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
73 break; |
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
74 |
1843
d9e10c329845
(getugroups): Don't dereference a null pointer when
Jim Meyering <jim@meyering.net>
parents:
1733
diff
changeset
|
75 for (cp = grp->gr_mem; *cp; ++cp) |
9 | 76 { |
1262
662622cf616f
(getugroups): Don't add a group number if it would be a duplicate.
Jim Meyering <jim@meyering.net>
parents:
653
diff
changeset
|
77 int n; |
662622cf616f
(getugroups): Don't add a group number if it would be a duplicate.
Jim Meyering <jim@meyering.net>
parents:
653
diff
changeset
|
78 |
1843
d9e10c329845
(getugroups): Don't dereference a null pointer when
Jim Meyering <jim@meyering.net>
parents:
1733
diff
changeset
|
79 if ( ! STREQ (username, *cp)) |
d9e10c329845
(getugroups): Don't dereference a null pointer when
Jim Meyering <jim@meyering.net>
parents:
1733
diff
changeset
|
80 continue; |
d9e10c329845
(getugroups): Don't dereference a null pointer when
Jim Meyering <jim@meyering.net>
parents:
1733
diff
changeset
|
81 |
1262
662622cf616f
(getugroups): Don't add a group number if it would be a duplicate.
Jim Meyering <jim@meyering.net>
parents:
653
diff
changeset
|
82 /* See if this group number is already on the list. */ |
662622cf616f
(getugroups): Don't add a group number if it would be a duplicate.
Jim Meyering <jim@meyering.net>
parents:
653
diff
changeset
|
83 for (n = 0; n < count; ++n) |
1843
d9e10c329845
(getugroups): Don't dereference a null pointer when
Jim Meyering <jim@meyering.net>
parents:
1733
diff
changeset
|
84 if (grouplist && grouplist[n] == grp->gr_gid) |
1262
662622cf616f
(getugroups): Don't add a group number if it would be a duplicate.
Jim Meyering <jim@meyering.net>
parents:
653
diff
changeset
|
85 break; |
662622cf616f
(getugroups): Don't add a group number if it would be a duplicate.
Jim Meyering <jim@meyering.net>
parents:
653
diff
changeset
|
86 |
662622cf616f
(getugroups): Don't add a group number if it would be a duplicate.
Jim Meyering <jim@meyering.net>
parents:
653
diff
changeset
|
87 /* If it's a new group number, then try to add it to the list. */ |
662622cf616f
(getugroups): Don't add a group number if it would be a duplicate.
Jim Meyering <jim@meyering.net>
parents:
653
diff
changeset
|
88 if (n == count) |
9 | 89 { |
1262
662622cf616f
(getugroups): Don't add a group number if it would be a duplicate.
Jim Meyering <jim@meyering.net>
parents:
653
diff
changeset
|
90 if (maxcount != 0) |
9 | 91 { |
1262
662622cf616f
(getugroups): Don't add a group number if it would be a duplicate.
Jim Meyering <jim@meyering.net>
parents:
653
diff
changeset
|
92 if (count >= maxcount) |
9044
20fba8637b7d
Close the group DB even when failing with 2^31 or more members.
Jim Meyering <jim@meyering.net>
parents:
9043
diff
changeset
|
93 goto done; |
1262
662622cf616f
(getugroups): Don't add a group number if it would be a duplicate.
Jim Meyering <jim@meyering.net>
parents:
653
diff
changeset
|
94 grouplist[count] = grp->gr_gid; |
9 | 95 } |
9703
e29f811d31c0
Don't rely on signed integer overflowing to negative value.
Lasse Collin <lasse.collin@tukaani.org>
parents:
9309
diff
changeset
|
96 if (count == INT_MAX) |
5159 | 97 { |
98 errno = EOVERFLOW; | |
9044
20fba8637b7d
Close the group DB even when failing with 2^31 or more members.
Jim Meyering <jim@meyering.net>
parents:
9043
diff
changeset
|
99 goto done; |
5159 | 100 } |
9703
e29f811d31c0
Don't rely on signed integer overflowing to negative value.
Lasse Collin <lasse.collin@tukaani.org>
parents:
9309
diff
changeset
|
101 count++; |
9 | 102 } |
103 } | |
1843
d9e10c329845
(getugroups): Don't dereference a null pointer when
Jim Meyering <jim@meyering.net>
parents:
1733
diff
changeset
|
104 } |
9044
20fba8637b7d
Close the group DB even when failing with 2^31 or more members.
Jim Meyering <jim@meyering.net>
parents:
9043
diff
changeset
|
105 |
9049
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
106 if (errno != 0) |
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
107 count = -1; |
da9a878d7b51
* lib/getugroups.c (getugroups): Detect getgrent failure.
Jim Meyering <jim@meyering.net>
parents:
9045
diff
changeset
|
108 |
9044
20fba8637b7d
Close the group DB even when failing with 2^31 or more members.
Jim Meyering <jim@meyering.net>
parents:
9043
diff
changeset
|
109 done: |
9045
11f2466d2f5b
Don't let endgrent clobber errno, no matter how improbable.
Jim Meyering <jim@meyering.net>
parents:
9044
diff
changeset
|
110 { |
11f2466d2f5b
Don't let endgrent clobber errno, no matter how improbable.
Jim Meyering <jim@meyering.net>
parents:
9044
diff
changeset
|
111 int saved_errno = errno; |
11f2466d2f5b
Don't let endgrent clobber errno, no matter how improbable.
Jim Meyering <jim@meyering.net>
parents:
9044
diff
changeset
|
112 endgrent (); |
11f2466d2f5b
Don't let endgrent clobber errno, no matter how improbable.
Jim Meyering <jim@meyering.net>
parents:
9044
diff
changeset
|
113 errno = saved_errno; |
11f2466d2f5b
Don't let endgrent clobber errno, no matter how improbable.
Jim Meyering <jim@meyering.net>
parents:
9044
diff
changeset
|
114 } |
1843
d9e10c329845
(getugroups): Don't dereference a null pointer when
Jim Meyering <jim@meyering.net>
parents:
1733
diff
changeset
|
115 |
9 | 116 return count; |
117 } |