Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/plugins/group_file/getgrent.c
1532 views
1
/*
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2005,2008,2010-2015,2022 Todd C. Miller <[email protected]>
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
/*
20
* Trivial replacements for the libc getgrent() family of functions.
21
*/
22
23
#include <config.h>
24
25
#include <stdio.h>
26
#include <stdlib.h>
27
#include <string.h>
28
#include <fcntl.h>
29
#include <limits.h>
30
#include <grp.h>
31
32
#include <sudo_compat.h>
33
#include <sudo_util.h>
34
35
#undef GRMEM_MAX
36
#define GRMEM_MAX 200
37
38
static FILE *grf;
39
static const char *grfile = "/etc/group";
40
static int gr_stayopen;
41
42
void mysetgrfile(const char *);
43
void mysetgrent(void);
44
void myendgrent(void);
45
int mysetgroupent(int);
46
struct group *mygetgrent(void);
47
struct group *mygetgrnam(const char *);
48
struct group *mygetgrgid(gid_t);
49
50
void
51
mysetgrfile(const char *file)
52
{
53
grfile = file;
54
if (grf != NULL)
55
myendgrent();
56
}
57
58
static int
59
open_group(int reset)
60
{
61
if (grf == NULL) {
62
grf = fopen(grfile, "r");
63
if (grf != NULL) {
64
if (fcntl(fileno(grf), F_SETFD, FD_CLOEXEC) == -1) {
65
fclose(grf);
66
grf = NULL;
67
}
68
}
69
if (grf == NULL)
70
return 0;
71
} else if (reset) {
72
rewind(grf);
73
}
74
return 1;
75
}
76
77
int
78
mysetgroupent(int stayopen)
79
{
80
if (!open_group(1))
81
return 0;
82
gr_stayopen = stayopen;
83
return 1;
84
}
85
86
void
87
mysetgrent(void)
88
{
89
mysetgroupent(0);
90
}
91
92
void
93
myendgrent(void)
94
{
95
if (grf != NULL) {
96
fclose(grf);
97
grf = NULL;
98
}
99
gr_stayopen = 0;
100
}
101
102
struct group *
103
mygetgrent(void)
104
{
105
static struct group gr;
106
static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
107
size_t len;
108
id_t id;
109
char *cp, *colon;
110
const char *errstr;
111
int n;
112
113
if (!open_group(0))
114
return NULL;
115
116
next_entry:
117
if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
118
return NULL;
119
120
memset(&gr, 0, sizeof(gr));
121
if ((colon = strchr(cp = colon, ':')) == NULL)
122
goto next_entry;
123
*colon++ = '\0';
124
gr.gr_name = cp;
125
if ((colon = strchr(cp = colon, ':')) == NULL)
126
goto next_entry;
127
*colon++ = '\0';
128
gr.gr_passwd = cp;
129
if ((colon = strchr(cp = colon, ':')) == NULL)
130
goto next_entry;
131
*colon++ = '\0';
132
id = sudo_strtoid(cp, &errstr);
133
if (errstr != NULL)
134
goto next_entry;
135
gr.gr_gid = (gid_t)id;
136
len = strlen(colon);
137
if (len > 0 && colon[len - 1] == '\n')
138
colon[len - 1] = '\0';
139
if (*colon != '\0') {
140
char *last;
141
142
gr.gr_mem = gr_mem;
143
cp = strtok_r(colon, ",", &last);
144
for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
145
gr.gr_mem[n] = cp;
146
cp = strtok_r(NULL, ",", &last);
147
}
148
gr.gr_mem[n] = NULL;
149
} else
150
gr.gr_mem = NULL;
151
return &gr;
152
}
153
154
struct group *
155
mygetgrnam(const char *name)
156
{
157
struct group *gr;
158
159
if (!open_group(1))
160
return NULL;
161
while ((gr = mygetgrent()) != NULL) {
162
if (strcmp(gr->gr_name, name) == 0)
163
break;
164
}
165
if (!gr_stayopen) {
166
fclose(grf);
167
grf = NULL;
168
}
169
return gr;
170
}
171
172
struct group *
173
mygetgrgid(gid_t gid)
174
{
175
struct group *gr;
176
177
if (!open_group(1))
178
return NULL;
179
while ((gr = mygetgrent()) != NULL) {
180
if (gr->gr_gid == gid)
181
break;
182
}
183
if (!gr_stayopen) {
184
fclose(grf);
185
grf = NULL;
186
}
187
return gr;
188
}
189
190