Coverage Report

Created: 2023-03-26 06:19

/src/proftpd/lib/pwgrent.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
2
3
This library is free software; you can redistribute it and/or
4
modify it under the terms of the GNU Library General Public License as
5
published by the Free Software Foundation; either version 2 of the
6
License, or (at your option) any later version.
7
8
This library is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
Library General Public License for more details.
12
13
You should have received a copy of the GNU Library General Public
14
License along with this library; see the file COPYING.LIB.  If
15
not, write to the Free Software Foundation, Inc., 51 Franklin Street,
16
Suite 500, Boston, MA 02110-1335, USA.  */
17
18
/* Required to tell conf.h not to include the standard ProFTPD
19
 * header files
20
 */
21
22
#define __PROFTPD_SUPPORT_LIBRARY
23
24
#include "conf.h"
25
#include "base.h"
26
27
/* From log.c/log.h */
28
0
#define PR_LOG_ERR LOG_ERR
29
extern void pr_log_pri(int, char *, ...);
30
31
/* From support.c */
32
extern int sstrncpy(char *dst, const char *src, size_t n);
33
34
0
#define NPWDFIELDS  7
35
0
#define NGRPFIELDS  4
36
37
#ifndef BUFSIZ
38
#define BUFSIZ    PR_TUNABLE_BUFFER_SIZE
39
#endif
40
41
/* Provides fgetpwent()/fgetgrent() functions.  Note that the format of the
42
 * files is probably NOT platform dependent, so use of these functions will
43
 * require a strict format:
44
 *
45
 *   "username:password:uid:gid:gecos:home:shell"
46
 */
47
48
#ifndef HAVE_FGETPWENT
49
50
static char pwdbuf[BUFSIZ];
51
static char *pwdfields[NPWDFIELDS];
52
static struct passwd pwent;
53
54
0
static struct passwd *supp_getpwent(const char *buf) {
55
0
  register unsigned int i;
56
0
  register char *cp;
57
0
  char *ep = NULL, *buffer = NULL;
58
0
  char **fields = NULL;
59
0
  struct passwd *pwd = NULL;
60
61
0
  fields = pwdfields;
62
0
  buffer = pwdbuf;
63
0
  pwd = &pwent;
64
65
0
  sstrncpy(buffer, buf, BUFSIZ-1);
66
0
  buffer[BUFSIZ-1] = '\0';
67
68
0
  for(cp = buffer, i = 0; i < NPWDFIELDS && cp; i++) {
69
0
    fields[i] = cp;
70
0
    while (*cp && *cp != ':')
71
0
      ++cp;
72
73
0
    if (*cp)
74
0
      *cp++ = '\0';
75
0
    else
76
0
      cp = 0;
77
0
  }
78
79
0
  if (i != NPWDFIELDS || *fields[2] == '\0' || *fields[3] == '\0')
80
0
    return 0;
81
82
0
  pwd->pw_name = fields[0];
83
0
  pwd->pw_passwd = fields[1];
84
85
0
  if (fields[2][0] == '\0' ||
86
0
     ((pwd->pw_uid = strtol(fields[2], &ep, 10)) == 0 && *ep))
87
0
       return 0;
88
89
0
  if (fields[3][0] == '\0' ||
90
0
     ((pwd->pw_gid = strtol(fields[3], &ep, 10)) == 0 && *ep))
91
0
       return 0;
92
93
0
  pwd->pw_gecos = fields[4];
94
0
  pwd->pw_dir = fields[5];
95
0
  pwd->pw_shell = fields[6];
96
97
0
  return pwd;
98
0
}
99
100
0
struct passwd *fgetpwent(FILE *fp) {
101
0
  char buf[BUFSIZ] = {'\0'};
102
103
0
  while (fgets(buf, sizeof(buf), fp) != (char*) 0) {
104
105
    /* ignore empty and comment lines */
106
0
    if (buf[0] == '\0' || buf[0] == '#')
107
0
      continue;
108
109
0
    buf[strlen(buf)-1] = '\0';
110
0
    return supp_getpwent(buf);
111
0
  }
112
113
0
  return NULL;
114
0
}
115
#endif /* HAVE_FGETPWENT */
116
117
#ifndef HAVE_FGETGRENT
118
0
#define MAXMEMBERS 4096
119
120
static char *grpbuf = NULL;
121
static struct group grent;
122
static char *grpfields[NGRPFIELDS];
123
static char *members[MAXMEMBERS+1];
124
125
0
static char *fgetbufline(char **buf, int *buflen, FILE *fp) {
126
0
  char *cp = *buf;
127
128
0
  while (fgets(cp, (*buflen) - (cp - *buf), fp) != NULL) {
129
130
    /* Is this a full line? */
131
0
    if (strchr(cp, '\n'))
132
0
      return *buf;
133
134
    /* No -- allocate a larger buffer, doubling buflen. */
135
0
    *buflen += *buflen;
136
137
0
    {
138
0
      char *new_buf;
139
140
0
      new_buf = realloc(*buf, *buflen);
141
0
      if (new_buf == NULL)
142
0
        break;
143
144
0
      *buf = new_buf;
145
0
    }
146
147
0
    cp = *buf + (cp - *buf);
148
0
    cp = strchr(cp, '\0');
149
0
  }
150
151
0
  free(*buf);
152
0
  *buf = NULL;
153
0
  *buflen = 0;
154
155
0
  return NULL;
156
0
}
157
158
0
static char **supp_grplist(char *s) {
159
0
  int nmembers = 0;
160
161
0
  while (s && *s && nmembers < MAXMEMBERS) {
162
0
    members[nmembers++] = s;
163
0
    while (*s && *s != ',')
164
0
      s++;
165
166
0
    if (*s)
167
0
      *s++ = '\0';
168
0
  }
169
170
0
  members[nmembers] = NULL;
171
0
  return members;
172
0
}
173
174
0
static struct group *supp_getgrent(const char *buf) {
175
0
  int i;
176
0
  char *cp;
177
178
0
  i = strlen(buf) + 1;
179
180
0
  if (!grpbuf) {
181
0
    grpbuf = malloc(i);
182
183
0
  } else {
184
0
    char *new_buf;
185
186
0
    new_buf = realloc(grpbuf, i);
187
0
    if (new_buf == NULL)
188
0
      return NULL;
189
190
0
    grpbuf = new_buf;
191
0
  }
192
193
0
  if (!grpbuf)
194
0
    return NULL;
195
196
0
  sstrncpy(grpbuf, buf, i);
197
198
0
  if ((cp = strrchr(grpbuf, '\n')))
199
0
    *cp = '\0';
200
201
0
  for (cp = grpbuf, i = 0; i < NGRPFIELDS && cp; i++) {
202
0
    grpfields[i] = cp;
203
204
0
    if ((cp = strchr(cp, ':')))
205
0
      *cp++ = 0;
206
0
  }
207
208
0
  if (i < (NGRPFIELDS - 1)) {
209
0
    pr_log_pri(PR_LOG_ERR, "Malformed entry in group file: %s", buf);
210
0
    return NULL;
211
0
  }
212
213
0
  if (*grpfields[2] == '\0')
214
0
    return NULL;
215
216
0
  grent.gr_name = grpfields[0];
217
0
  grent.gr_passwd = grpfields[1];
218
0
  grent.gr_gid = atoi(grpfields[2]);
219
0
  grent.gr_mem = supp_grplist(grpfields[3]);
220
221
0
  return &grent;
222
0
}
223
224
0
struct group *fgetgrent(FILE *fp) {
225
0
  char *cp = NULL, *buf = malloc(BUFSIZ);
226
0
  int buflen = BUFSIZ;
227
0
  struct group *grp = NULL;
228
229
0
  if (!buf)
230
0
    return NULL;
231
232
0
  while (fgetbufline(&buf, &buflen, fp) != NULL) {
233
234
    /* ignore comment and empty lines */
235
0
    if (buf[0] == '\0' || buf[0] == '#')
236
0
      continue;
237
238
0
    if ((cp = strchr(buf, '\n')) != NULL)
239
0
      *cp = '\0';
240
241
0
    grp = supp_getgrent(buf);
242
0
    free(buf);
243
244
0
    return grp;
245
0
  }
246
247
0
  return NULL;
248
0
}
249
250
#endif /* HAVE_FGETGRENT */