File indexing completed on 2025-05-11 08:24:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #ifdef HAVE_CONFIG_H
0022 #include "config.h"
0023 #endif
0024
0025 #include <sys/stat.h>
0026 #include <pwd.h>
0027 #include <grp.h>
0028 #include <errno.h>
0029 #include <fcntl.h>
0030 #include <unistd.h>
0031 #include <stdlib.h>
0032 #include <string.h>
0033 #include <limits.h>
0034 #include <ctype.h>
0035 #include <pthread.h>
0036 #include <stdint.h>
0037
0038 #include <rtems/seterr.h>
0039 #include <rtems/score/assert.h>
0040
0041 #include "pwdgrp.h"
0042
0043 static pthread_once_t pwdgrp_once = PTHREAD_ONCE_INIT;
0044
0045 static void init_file(const char *name, const char *content)
0046 {
0047
0048
0049
0050
0051
0052
0053 int fd = open(name, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
0054
0055 if (fd >= 0) {
0056 write(fd, content, strlen(content));
0057 close(fd);
0058 }
0059 }
0060
0061
0062
0063
0064 static void pwdgrp_init(void)
0065 {
0066
0067
0068
0069
0070
0071
0072 (void) mkdir("/etc", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
0073
0074
0075
0076
0077 init_file("/etc/passwd", "root::0:0::::\n");
0078
0079
0080
0081
0082 init_file("/etc/group", "root::0:\n");
0083 }
0084
0085 void _libcsupport_pwdgrp_init(void)
0086 {
0087 pthread_once(&pwdgrp_once, pwdgrp_init);
0088 }
0089
0090
0091
0092
0093 static int
0094 scanString(FILE *fp, char **name, char **bufp, size_t *nleft, int nlFlag)
0095 {
0096 int c;
0097
0098 *name = *bufp;
0099 for (;;) {
0100 c = getc(fp);
0101 if (c == ':') {
0102 if (nlFlag)
0103 return 0;
0104 break;
0105 }
0106 if (c == '\n') {
0107 if (!nlFlag)
0108 return 0;
0109 break;
0110 }
0111 if (c == EOF)
0112 return 0;
0113 if (*nleft < 2)
0114 return 0;
0115 **bufp = c;
0116 ++(*bufp);
0117 --(*nleft);
0118 }
0119 **bufp = '\0';
0120 ++(*bufp);
0121 --(*nleft);
0122 return 1;
0123 }
0124
0125
0126
0127
0128 static int
0129 scanInt(FILE *fp, int *val)
0130 {
0131 int c;
0132 unsigned int i = 0;
0133 unsigned int limit = INT_MAX;
0134 int sign = 0;
0135 int d;
0136
0137 for (;;) {
0138 c = getc(fp);
0139 if (c == ':')
0140 break;
0141 if (sign == 0) {
0142 if (c == '-') {
0143 sign = -1;
0144 limit++;
0145 continue;
0146 }
0147 sign = 1;
0148 }
0149 if (!isdigit(c))
0150 return 0;
0151 d = c - '0';
0152 if ((i > (limit / 10))
0153 || ((i == (limit / 10)) && (d > (limit % 10))))
0154 return 0;
0155 i = i * 10 + d;
0156 }
0157 if (sign == 0)
0158 return 0;
0159 *val = i * sign;
0160 return 1;
0161 }
0162
0163
0164
0165
0166 int _libcsupport_scanpw(
0167 FILE *fp,
0168 struct passwd *pwd,
0169 char *buffer,
0170 size_t bufsize
0171 )
0172 {
0173 int pwuid, pwgid;
0174
0175 if (!scanString(fp, &pwd->pw_name, &buffer, &bufsize, 0)
0176 || !scanString(fp, &pwd->pw_passwd, &buffer, &bufsize, 0)
0177 || !scanInt(fp, &pwuid)
0178 || !scanInt(fp, &pwgid)
0179 || !scanString(fp, &pwd->pw_comment, &buffer, &bufsize, 0)
0180 || !scanString(fp, &pwd->pw_gecos, &buffer, &bufsize, 0)
0181 || !scanString(fp, &pwd->pw_dir, &buffer, &bufsize, 0)
0182 || !scanString(fp, &pwd->pw_shell, &buffer, &bufsize, 1))
0183 return 0;
0184 pwd->pw_uid = pwuid;
0185 pwd->pw_gid = pwgid;
0186 return 1;
0187 }
0188
0189 static int getpw_r(
0190 const char *name,
0191 int uid,
0192 struct passwd *pwd,
0193 char *buffer,
0194 size_t bufsize,
0195 struct passwd **result
0196 )
0197 {
0198 FILE *fp;
0199 int match;
0200
0201 _libcsupport_pwdgrp_init();
0202
0203 if ((fp = fopen("/etc/passwd", "r")) == NULL)
0204 rtems_set_errno_and_return_minus_one( EINVAL );
0205
0206 for(;;) {
0207 if (!_libcsupport_scanpw(fp, pwd, buffer, bufsize))
0208 goto error_einval;
0209
0210 if (name) {
0211 match = (strcmp(pwd->pw_name, name) == 0);
0212 } else {
0213 match = (pwd->pw_uid == uid);
0214 }
0215
0216 if (match) {
0217 fclose(fp);
0218 *result = pwd;
0219 return 0;
0220 }
0221 }
0222 error_einval:
0223 fclose(fp);
0224 rtems_set_errno_and_return_minus_one( EINVAL );
0225 }
0226
0227 int getpwnam_r(
0228 const char *name,
0229 struct passwd *pwd,
0230 char *buffer,
0231 size_t bufsize,
0232 struct passwd **result
0233 )
0234 {
0235 return getpw_r(name, 0, pwd, buffer, bufsize, result);
0236 }
0237
0238 int getpwuid_r(
0239 uid_t uid,
0240 struct passwd *pwd,
0241 char *buffer,
0242 size_t bufsize,
0243 struct passwd **result
0244 )
0245 {
0246 return getpw_r(NULL, uid, pwd, buffer, bufsize, result);
0247 }
0248
0249
0250
0251
0252 int _libcsupport_scangr(
0253 FILE *fp,
0254 struct group *grp,
0255 char *buffer,
0256 size_t bufsize
0257 )
0258 {
0259 int grgid;
0260 char *grmem, *cp;
0261 int memcount;
0262
0263 if (!scanString(fp, &grp->gr_name, &buffer, &bufsize, 0)
0264 || !scanString(fp, &grp->gr_passwd, &buffer, &bufsize, 0)
0265 || !scanInt(fp, &grgid)
0266 || !scanString(fp, &grmem, &buffer, &bufsize, 1))
0267 return 0;
0268 grp->gr_gid = grgid;
0269
0270
0271
0272
0273 if (grmem[0] == '\0') {
0274 memcount = 0;
0275 } else {
0276 for (cp = grmem, memcount = 1 ; *cp != 0 ; cp++) {
0277 if(*cp == ',')
0278 memcount++;
0279 }
0280 }
0281
0282
0283
0284
0285 if (bufsize < (((memcount+1)*sizeof(char *)) + 15))
0286 return 0;
0287 grp->gr_mem = (char **)(((uintptr_t)buffer + 15) & ~15);
0288
0289
0290
0291
0292 if (grmem[0] == '\0') {
0293 memcount = 0;
0294 } else {
0295 grp->gr_mem[0] = grmem;
0296 for (cp = grmem, memcount = 1 ; *cp != 0 ; cp++) {
0297 if(*cp == ',') {
0298 *cp = '\0';
0299 grp->gr_mem[memcount++] = cp + 1;
0300 }
0301 }
0302 }
0303
0304 grp->gr_mem[memcount] = NULL;
0305 return 1;
0306 }
0307
0308 static int getgr_r(
0309 const char *name,
0310 int gid,
0311 struct group *grp,
0312 char *buffer,
0313 size_t bufsize,
0314 struct group **result
0315 )
0316 {
0317 FILE *fp;
0318 int match;
0319
0320 _libcsupport_pwdgrp_init();
0321
0322 if ((fp = fopen("/etc/group", "r")) == NULL)
0323 rtems_set_errno_and_return_minus_one( EINVAL );
0324
0325 for(;;) {
0326 if (!_libcsupport_scangr(fp, grp, buffer, bufsize))
0327 goto error_einval;
0328
0329 if (name) {
0330 match = (strcmp(grp->gr_name, name) == 0);
0331 } else {
0332 match = (grp->gr_gid == gid);
0333 }
0334
0335 if (match) {
0336 fclose(fp);
0337 *result = grp;
0338 return 0;
0339 }
0340 }
0341 error_einval:
0342 fclose(fp);
0343 rtems_set_errno_and_return_minus_one( EINVAL );
0344 }
0345
0346 int getgrnam_r(
0347 const char *name,
0348 struct group *grp,
0349 char *buffer,
0350 size_t bufsize,
0351 struct group **result
0352 )
0353 {
0354 return getgr_r(name, 0, grp, buffer, bufsize, result);
0355 }
0356
0357 int getgrgid_r(
0358 gid_t gid,
0359 struct group *grp,
0360 char *buffer,
0361 size_t bufsize,
0362 struct group **result
0363 )
0364 {
0365 return getgr_r(NULL, gid, grp, buffer, bufsize, result);
0366 }