/src/sudo/lib/util/gidlist.c
Line  | Count  | Source  | 
1  |  | /*  | 
2  |  |  * SPDX-License-Identifier: ISC  | 
3  |  |  *  | 
4  |  |  * Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@sudo.ws>  | 
5  |  |  *  | 
6  |  |  * Permission to use, copy, modify, and distribute this software for any  | 
7  |  |  * purpose with or without fee is hereby granted, provided that the above  | 
8  |  |  * copyright notice and this permission notice appear in all copies.  | 
9  |  |  *  | 
10  |  |  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES  | 
11  |  |  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF  | 
12  |  |  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR  | 
13  |  |  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES  | 
14  |  |  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN  | 
15  |  |  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  | 
16  |  |  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  | 
17  |  |  */  | 
18  |  |  | 
19  |  | #include <config.h>  | 
20  |  |  | 
21  |  | #include <stdlib.h>  | 
22  |  | #include <grp.h>  | 
23  |  |  | 
24  |  | #include <sudo_compat.h>  | 
25  |  | #include <sudo_debug.h>  | 
26  |  | #include <sudo_fatal.h>  | 
27  |  | #include <sudo_gettext.h>  | 
28  |  | #include <sudo_util.h>  | 
29  |  |  | 
30  |  | /*  | 
31  |  |  * Parse a comma-separated list of gids into an allocated array of GETGROUPS_T.  | 
32  |  |  * If a pointer to the base gid is specified, it is stored as the first element  | 
33  |  |  * in the array.  | 
34  |  |  * Returns the number of gids in the allocated array.  | 
35  |  |  */  | 
36  |  | int  | 
37  |  | sudo_parse_gids_v1(const char *gidstr, const gid_t *basegid, GETGROUPS_T **gidsp)  | 
38  | 1.18k  | { | 
39  | 1.18k  |     int ngids = 0;  | 
40  | 1.18k  |     GETGROUPS_T *gids;  | 
41  | 1.18k  |     const char *cp = gidstr;  | 
42  | 1.18k  |     const char *errstr;  | 
43  | 1.18k  |     char *ep;  | 
44  | 1.18k  |     debug_decl(sudo_parse_gids, SUDO_DEBUG_UTIL);  | 
45  |  |  | 
46  |  |     /* Count groups. */  | 
47  | 1.18k  |     if (*cp != '\0') { | 
48  | 1.18k  |   ngids++;  | 
49  | 2.17M  |   do { | 
50  | 2.17M  |       if (*cp++ == ',')  | 
51  | 825k  |     ngids++;  | 
52  | 2.17M  |   } while (*cp != '\0');  | 
53  | 1.18k  |     }  | 
54  |  |     /* Base gid is optional. */  | 
55  | 1.18k  |     if (basegid != NULL)  | 
56  | 1.18k  |   ngids++;  | 
57  |  |     /* Allocate and fill in array. */  | 
58  | 1.18k  |     if (ngids != 0) { | 
59  | 1.18k  |   gids = reallocarray(NULL, (size_t)ngids, sizeof(GETGROUPS_T));  | 
60  | 1.18k  |   if (gids == NULL) { | 
61  | 0  |       sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); | 
62  | 0  |       debug_return_int(-1);  | 
63  | 0  |   }  | 
64  | 1.18k  |   ngids = 0;  | 
65  | 1.18k  |   if (basegid != NULL)  | 
66  | 1.18k  |       gids[ngids++] = *basegid;  | 
67  | 1.18k  |   cp = gidstr;  | 
68  | 794k  |   do { | 
69  | 794k  |       gids[ngids] = (GETGROUPS_T) sudo_strtoidx(cp, ",", &ep, &errstr);  | 
70  | 794k  |       if (errstr != NULL) { | 
71  | 50  |     sudo_warnx(U_("%s: %s"), cp, U_(errstr)); | 
72  | 50  |     free(gids);  | 
73  | 50  |     debug_return_int(-1);  | 
74  | 50  |       }  | 
75  | 794k  |       if (basegid == NULL || gids[ngids] != *basegid)  | 
76  | 742k  |     ngids++;  | 
77  | 794k  |       cp = ep + 1;  | 
78  | 794k  |   } while (*ep != '\0');  | 
79  | 1.13k  |   *gidsp = gids;  | 
80  | 1.13k  |     }  | 
81  | 1.13k  |     debug_return_int(ngids);  | 
82  | 1.13k  | }  |