diff options
Diffstat (limited to 'guts')
-rw-r--r-- | guts/README | 31 | ||||
-rw-r--r-- | guts/endgrent.c | 11 | ||||
-rw-r--r-- | guts/endpwent.c | 11 | ||||
-rw-r--r-- | guts/fopen.c | 2 | ||||
-rw-r--r-- | guts/fopen64.c | 2 | ||||
-rw-r--r-- | guts/getgrent.c | 18 | ||||
-rw-r--r-- | guts/getgrent_r.c | 21 | ||||
-rw-r--r-- | guts/getgrgid.c | 18 | ||||
-rw-r--r-- | guts/getgrgid_r.c | 26 | ||||
-rw-r--r-- | guts/getgrnam.c | 20 | ||||
-rw-r--r-- | guts/getgrnam_r.c | 24 | ||||
-rw-r--r-- | guts/getgrouplist.c | 39 | ||||
-rw-r--r-- | guts/getgroups.c | 15 | ||||
-rw-r--r-- | guts/getpw.c | 30 | ||||
-rw-r--r-- | guts/getpwent.c | 18 | ||||
-rw-r--r-- | guts/getpwent_r.c | 14 | ||||
-rw-r--r-- | guts/getpwnam.c | 18 | ||||
-rw-r--r-- | guts/getpwnam_r.c | 23 | ||||
-rw-r--r-- | guts/getpwuid.c | 18 | ||||
-rw-r--r-- | guts/getpwuid_r.c | 23 | ||||
-rw-r--r-- | guts/setgrent.c | 11 | ||||
-rw-r--r-- | guts/setpwent.c | 11 |
22 files changed, 402 insertions, 2 deletions
diff --git a/guts/README b/guts/README index e933349..a1030c6 100644 --- a/guts/README +++ b/guts/README @@ -157,3 +157,34 @@ dummied them out: renameat tempnam tmpnam + +The following functions are partially emulated in order to provide for +emulation of various getpw*() and getgr*() functions. No handling is +provided for putpw*() or putgr*(). Nearly everything is ultimately +implemented in terms of fgetpwent_r() and fgetgrent_r(), which are +GNU extensions corresponding to fgetpwent() and fgetgrent(), allowing +pseudo to read password information from an arbitrary stream; the +setpwent() and setgrent() functions are modified to pick /etc/* from +the pseudo_chroot path, if one is set, or from PSEUDO_PASSWD, if that +is set, or else the system /etc/* files. + + endgrent + endpwent + getgrent + getgrent_r + getgrgid + getgrgid_r + getgrnam + getgrnam_r + getgrouplist + getgroups + getpw + getpwent + getpwent_r + getpwnam + getpwnam_r + getpwuid + getpwuid_r + setgrent + setgroups + setpwent diff --git a/guts/endgrent.c b/guts/endgrent.c new file mode 100644 index 0000000..8c40845 --- /dev/null +++ b/guts/endgrent.c @@ -0,0 +1,11 @@ +/* + * static void + * wrap_endgrent(void) { + * + */ + + pseudo_grp_close(); + +/* return; + * } + */ diff --git a/guts/endpwent.c b/guts/endpwent.c new file mode 100644 index 0000000..7180c0c --- /dev/null +++ b/guts/endpwent.c @@ -0,0 +1,11 @@ +/* + * static void + * wrap_endpwent(void) { + * + */ + + pseudo_pwd_close(); + +/* return; + * } + */ diff --git a/guts/fopen.c b/guts/fopen.c index 69d9ce6..15b27f5 100644 --- a/guts/fopen.c +++ b/guts/fopen.c @@ -13,7 +13,7 @@ if (rc) { int fd = fileno(rc); - pseudo_debug(2, "fopen '%s': fd %d\n", path, fd); + pseudo_debug(2, "fopen '%s': fd %d <FILE %p>\n", path, fd, (void *) rc); if (real___fxstat64(_STAT_VER, fd, &buf) != -1) { if (!existed) { pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf); diff --git a/guts/fopen64.c b/guts/fopen64.c index c2286f2..78cfdaa 100644 --- a/guts/fopen64.c +++ b/guts/fopen64.c @@ -14,7 +14,7 @@ if (rc) { int fd = fileno(rc); - pseudo_debug(2, "fopen64 '%s': fd %d\n", path, fd); + pseudo_debug(2, "fopen64 '%s': fd %d <FILE %p>\n", path, fd, (void *) rc); if (real___fxstat64(_STAT_VER, fd, &buf) != -1) { if (!existed) { pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf); diff --git a/guts/getgrent.c b/guts/getgrent.c new file mode 100644 index 0000000..0be9ec5 --- /dev/null +++ b/guts/getgrent.c @@ -0,0 +1,18 @@ +/* + * static struct group * + * wrap_getgrent(void) { + * struct group * rc = NULL; + */ + static struct group grp; + static char grbuf[PSEUDO_PWD_MAX]; + int r_rc; + + r_rc = wrap_getgrent_r(&grp, grbuf, PSEUDO_PWD_MAX, &rc); + /* different error return conventions */ + if (r_rc != 0) { + errno = r_rc; + } + +/* return rc; + * } + */ diff --git a/guts/getgrent_r.c b/guts/getgrent_r.c new file mode 100644 index 0000000..6bb9667 --- /dev/null +++ b/guts/getgrent_r.c @@ -0,0 +1,21 @@ +/* + * static int + * wrap_getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp) { + * int rc = -1; + */ + + /* note that we don't wrap fgetgrent_r, since there's no path + * references in it. + */ + rc = fgetgrent_r(pseudo_grp, gbuf, buf, buflen, gbufp); + if (rc == 0 && *gbufp) { + if (*gbufp == gbuf) { + pseudo_debug(1, "found group: %d/%s\n", gbuf->gr_gid, gbuf->gr_name); + } else { + pseudo_debug(1, "found group, but it's wrong?"); + } + } + +/* return rc; + * } + */ diff --git a/guts/getgrgid.c b/guts/getgrgid.c new file mode 100644 index 0000000..20c85c9 --- /dev/null +++ b/guts/getgrgid.c @@ -0,0 +1,18 @@ +/* + * static struct group * + * wrap_getgrgid(gid_t gid) { + * struct group * rc = NULL; + */ + static struct group grp; + static char grbuf[PSEUDO_PWD_MAX]; + int r_rc; + + r_rc = wrap_getgrgid_r(gid, &grp, grbuf, PSEUDO_PWD_MAX, &rc); + /* different error return conventions */ + if (r_rc != 0) { + errno = r_rc; + } + +/* return rc; + * } + */ diff --git a/guts/getgrgid_r.c b/guts/getgrgid_r.c new file mode 100644 index 0000000..4ae6a93 --- /dev/null +++ b/guts/getgrgid_r.c @@ -0,0 +1,26 @@ +/* + * static int + * wrap_getgrgid_r(gid_t gid, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp) { + * int rc = -1; + */ + + setgrent(); + while ((rc = wrap_getgrent_r(gbuf, buf, buflen, gbufp)) == 0) { + /* 0 means no error occurred, and *gbufp == gbuf */ + if (gbuf->gr_gid == gid) { + pseudo_debug(1, "found group gid %d, name %s\n", + gbuf->gr_gid, gbuf->gr_name); + return rc; + } + } + endgrent(); + /* we never found a match; rc is 0 if there was no error, or + * non-zero if an error occurred. Either way, set the + * pwbufp pointer to NULL to indicate that we didn't find + * something, and leave rc alone. + */ + *gbufp = NULL; + +/* return rc; + * } + */ diff --git a/guts/getgrnam.c b/guts/getgrnam.c new file mode 100644 index 0000000..191fe25 --- /dev/null +++ b/guts/getgrnam.c @@ -0,0 +1,20 @@ +/* + * static struct group * + * wrap_getgrnam(const char *name) { + * struct group * rc = NULL; + */ + + static struct group grp; + static char grbuf[PSEUDO_PWD_MAX]; + int r_rc; + + r_rc = wrap_getgrnam_r(name, &grp, grbuf, PSEUDO_PWD_MAX, &rc); + /* different error return conventions */ + if (r_rc != 0) { + errno = r_rc; + } + + +/* return rc; + * } + */ diff --git a/guts/getgrnam_r.c b/guts/getgrnam_r.c new file mode 100644 index 0000000..f70bbdc --- /dev/null +++ b/guts/getgrnam_r.c @@ -0,0 +1,24 @@ +/* + * static int + * wrap_getgrnam_r(const char *name, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp) { + * int rc = -1; + */ + + setgrent(); + while ((rc = wrap_getgrent_r(gbuf, buf, buflen, gbufp)) == 0) { + /* 0 means no error occurred, and *gbufp == gbuf */ + if (gbuf->gr_name && !strcmp(gbuf->gr_name, name)) + return rc; + } + endgrent(); + /* we never found a match; rc is 0 if there was no error, or + * non-zero if an error occurred. Either way, set the + * pwbufp pointer to NULL to indicate that we didn't find + * something, and leave rc alone. + */ + *gbufp = NULL; + + +/* return rc; + * } + */ diff --git a/guts/getgrouplist.c b/guts/getgrouplist.c new file mode 100644 index 0000000..ef362bb --- /dev/null +++ b/guts/getgrouplist.c @@ -0,0 +1,39 @@ +/* + * static int + * wrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups) { + * int rc = -1; + */ + + int found = 0; + int found_group = 0; + char buf[PSEUDO_PWD_MAX]; + struct group grp, *gbuf = &grp; + + setgrent(); + while ((rc = wrap_getgrent_r(gbuf, buf, PSEUDO_PWD_MAX, &gbuf)) == 0) { + int i = 0; + for (i = 0; gbuf->gr_mem[i]; ++i) { + if (!strcmp(gbuf->gr_mem[i], user)) { + if (found < *ngroups) + groups[found] = gbuf->gr_gid; + ++found; + if (gbuf->gr_gid == group) + found_group = 1; + } + } + } + endgrent(); + if (!found_group) { + if (found < *ngroups) + groups[found] = group; + ++found; + } + if (found >= *ngroups) + rc = -1; + else + rc = found; + *ngroups = found; + +/* return rc; + * } + */ diff --git a/guts/getgroups.c b/guts/getgroups.c new file mode 100644 index 0000000..8394325 --- /dev/null +++ b/guts/getgroups.c @@ -0,0 +1,15 @@ +/* + * static int + * wrap_getgroups(int size, gid_t *list) { + * int rc = -1; + */ + + /* you're only in group zero */ + rc = 1; + if (size > 0) { + list[0] = 0; + } + +/* return rc; + * } + */ diff --git a/guts/getpw.c b/guts/getpw.c new file mode 100644 index 0000000..cf41799 --- /dev/null +++ b/guts/getpw.c @@ -0,0 +1,30 @@ +/* + * static int + * wrap_getpw(uid_t uid, char *buf) { + * int rc = -1; + */ + static struct passwd pwd; + static char pwbuf[PSEUDO_PWD_MAX]; + struct passwd *pwp; + + pseudo_diag("warning: unsafe getpw() called. hoping buf has at least %d chars.\n", + PSEUDO_PWD_MAX); + rc = wrap_getpwuid_r(uid, &pwd, pwbuf, PSEUDO_PWD_MAX, &pwp); + /* different error return conventions */ + if (rc != 0) { + errno = rc; + rc = -1; + } else { + snprintf(buf, PSEUDO_PWD_MAX, "%s:%s:%d:%d:%s:%s:%s", + pwd.pw_name, + pwd.pw_passwd, + pwd.pw_uid, + pwd.pw_gid, + pwd.pw_gecos, + pwd.pw_dir, + pwd.pw_shell); + } + +/* return rc; + * } + */ diff --git a/guts/getpwent.c b/guts/getpwent.c new file mode 100644 index 0000000..5b76ad0 --- /dev/null +++ b/guts/getpwent.c @@ -0,0 +1,18 @@ +/* + * static struct passwd * + * wrap_getpwent(void) { + * struct passwd * rc = NULL; + */ + static struct passwd pwd; + static char pwbuf[PSEUDO_PWD_MAX]; + int r_rc; + + r_rc = wrap_getpwent_r(&pwd, pwbuf, PSEUDO_PWD_MAX, &rc); + /* different error return conventions */ + if (r_rc != 0) { + errno = r_rc; + } + +/* return rc; + * } + */ diff --git a/guts/getpwent_r.c b/guts/getpwent_r.c new file mode 100644 index 0000000..2bf1db2 --- /dev/null +++ b/guts/getpwent_r.c @@ -0,0 +1,14 @@ +/* + * static int + * wrap_getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp) { + * int rc = -1; + */ + + /* note that we don't wrap fgetpwent_r, since there's no path + * references in it. + */ + return fgetpwent_r(pseudo_pwd, pwbuf, buf, buflen, pwbufp); + +/* return rc; + * } + */ diff --git a/guts/getpwnam.c b/guts/getpwnam.c new file mode 100644 index 0000000..04aed89 --- /dev/null +++ b/guts/getpwnam.c @@ -0,0 +1,18 @@ +/* + * static struct passwd * + * wrap_getpwnam(const char *name) { + * struct passwd * rc = NULL; + */ + static struct passwd pwd; + static char pwbuf[PSEUDO_PWD_MAX]; + int r_rc; + + r_rc = wrap_getpwnam_r(name, &pwd, pwbuf, PSEUDO_PWD_MAX, &rc); + /* different error return conventions */ + if (r_rc != 0) { + errno = r_rc; + } + +/* return rc; + * } + */ diff --git a/guts/getpwnam_r.c b/guts/getpwnam_r.c new file mode 100644 index 0000000..d292cdb --- /dev/null +++ b/guts/getpwnam_r.c @@ -0,0 +1,23 @@ +/* + * static int + * wrap_getpwnam_r(const char *name, struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp) { + * int rc = -1; + */ + + setpwent(); + while ((rc = wrap_getpwent_r(pwbuf, buf, buflen, pwbufp)) == 0) { + /* 0 means no error occurred, and *pwbufp == pwbuf */ + if (pwbuf->pw_name && !strcmp(pwbuf->pw_name, name)) + return rc; + } + endpwent(); + /* we never found a match; rc is 0 if there was no error, or + * non-zero if an error occurred. Either way, set the + * pwbufp pointer to NULL to indicate that we didn't find + * something, and leave rc alone. + */ + *pwbufp = NULL; + +/* return rc; + * } + */ diff --git a/guts/getpwuid.c b/guts/getpwuid.c new file mode 100644 index 0000000..9407405 --- /dev/null +++ b/guts/getpwuid.c @@ -0,0 +1,18 @@ +/* + * static struct passwd * + * wrap_getpwuid(uid_t uid) { + * struct passwd * rc = NULL; + */ + static struct passwd pwd; + static char pwbuf[PSEUDO_PWD_MAX]; + int r_rc; + + r_rc = wrap_getpwuid_r(uid, &pwd, pwbuf, PSEUDO_PWD_MAX, &rc); + /* different error return conventions */ + if (r_rc != 0) { + errno = r_rc; + } + +/* return rc; + * } + */ diff --git a/guts/getpwuid_r.c b/guts/getpwuid_r.c new file mode 100644 index 0000000..f2b6afb --- /dev/null +++ b/guts/getpwuid_r.c @@ -0,0 +1,23 @@ +/* + * static int + * wrap_getpwuid_r(uid_t uid, struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp) { + * int rc = -1; + */ + + setpwent(); + while ((rc = wrap_getpwent_r(pwbuf, buf, buflen, pwbufp)) == 0) { + /* 0 means no error occurred, and *pwbufp == pwbuf */ + if (pwbuf->pw_uid == uid) + return rc; + } + endpwent(); + /* we never found a match; rc is 0 if there was no error, or + * non-zero if an error occurred. Either way, set the + * pwbufp pointer to NULL to indicate that we didn't find + * something, and leave rc alone. + */ + *pwbufp = NULL; + +/* return rc; + * } + */ diff --git a/guts/setgrent.c b/guts/setgrent.c new file mode 100644 index 0000000..c840de0 --- /dev/null +++ b/guts/setgrent.c @@ -0,0 +1,11 @@ +/* + * static void + * wrap_setgrent(void) { + * + */ + + pseudo_grp_open(); + +/* return; + * } + */ diff --git a/guts/setpwent.c b/guts/setpwent.c new file mode 100644 index 0000000..3941e67 --- /dev/null +++ b/guts/setpwent.c @@ -0,0 +1,11 @@ +/* + * static void + * wrap_setpwent(void) { + * + */ + + pseudo_pwd_open(); + +/* return; + * } + */ |