Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBlake Setlow <csetlow@tower-research.com>2008-01-22 22:40:07 (GMT)
committer Michael Stone <michael@laptop.org>2008-01-22 22:40:07 (GMT)
commitc8e10eb4ae55f5986344ddc8c230ee9f89fc429e (patch)
treea1682990624f5a537bcfaee29442f02130cbb63a
parent63865355abb28047bfb2eb152094b65f9c0a220c (diff)
getpwuid_r and getpwnam_r prototypes.
-rw-r--r--nss-rainbow.c94
1 files changed, 80 insertions, 14 deletions
diff --git a/nss-rainbow.c b/nss-rainbow.c
index f898ecc..f0fc376 100644
--- a/nss-rainbow.c
+++ b/nss-rainbow.c
@@ -39,6 +39,22 @@ _nss_rainbow_setpwent(void) {
g_done = false;
}
+int write_buf(char* home, char** buf, size_t * buflen)
+{
+ size_t homelen;
+ homelen = strnlen(home, *buflen);
+ if (homelen == *buflen)
+ {
+ errno = ERANGE;
+ return -1;
+ }
+ strncpy(*buf, home, homelen);
+ (*buf)[homelen] = '\0';
+ *buflen -= homelen + 1;
+ *buf += homelen + 1;
+ return 0;
+}
+
enum nss_status
_nss_rainbow_getpwent_r(struct passwd *result, char* buf, size_t buflen, int *errnop) {
/* I'm going to interpret the reentrancy requirement on this function to mean
@@ -56,23 +72,15 @@ _nss_rainbow_getpwent_r(struct passwd *result, char* buf, size_t buflen, int *er
getenv("USER"),
out_error_unavail, "Unable to retrieve $USER.");
- LET(size_t, homelen, buflen,
- strnlen(home, buflen),
- out_error_buffer, "$HOME too long.");
- strncpy(buf, home, homelen);
result->pw_dir = buf;
- buf[homelen] = '\0';
- buf += homelen + 1;
- buflen -= homelen + 1;
+ CHECK(int, -1,
+ write_buf(home, &buf, &buflen),
+ out_error_buffer, "Not enough buffer for $HOME.");
- LET(size_t, userlen, buflen,
- strnlen(user, buflen),
- out_error_buffer, "$USER too long.");
- strncpy(buf, user, userlen);
result->pw_gecos = result->pw_name = result->pw_passwd = buf;
- buf[userlen] = '\0';
- buf += userlen + 1;
- buflen -= userlen + 1;
+ CHECK(int, -1,
+ write_buf(user, &buf, &buflen),
+ out_error_buffer, "Not enough buffer for $USER.");
CHECK(bool, true,
strlen(SHELL) > buflen,
@@ -95,3 +103,61 @@ out_error_buffer:
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
+
+enum nss_status _nss_rainbow_getpwbyuid_r(uid_t uid, struct passwd *result, char* buf, size_t buflen, int *errnop) {
+ if (uid < 10000)
+ return NSS_STATUS_NOTFOUND;
+ int homelen = snprintf(buf, buflen, "/home/olpc/isolation/1/%d", uid);
+ if ((homelen <= 0) || (((unsigned int) homelen) >= buflen)) {
+ PERROR("Insufficient HOMEBUFLEN for the home for user uid.");
+ goto out_error_buffer;}
+ buf[homelen] = '\0';
+ struct stat statbuf;
+ CHECK(int, -1,
+ stat(buf, &statbuf),
+ out_error_errno, "Stat failed for homebuf.");
+ result->pw_uid = uid;
+ result->pw_gid = statbuf.st_gid;
+ result->pw_dir = buf;
+ buf += homelen + 1;
+ buflen -= homelen + 1;
+ homelen = snprintf(buf, buflen, "%d", uid);
+ if ((homelen <= 0) || (((unsigned int ) homelen ) >= buflen)) {
+ PERROR("Insufficient HOMEBUFLEN for user uid as a string.");
+ goto out_error_buffer;
+ }
+ result->pw_gecos = result->pw_name = result->pw_passwd = buf;
+ buf += homelen + 1;
+ buflen -= homelen + 1;
+ CHECK(bool, true,
+ strlen(SHELL) > buflen,
+ out_error_buffer, "Shell string constant too long.");
+ strcpy(buf, SHELL);
+ result->pw_shell = buf;
+ // DO NOT USE BUF UNLESS YOU INCREMENT IT NOW.
+ // YOU ARE DONE.
+
+ return NSS_STATUS_SUCCESS;
+
+out_error_buffer:
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+out_error_errno:
+ return NSS_STATUS_TRYAGAIN;
+}
+enum nss_status _nss_rainbow_getpwbynam_r(const char * name, struct passwd *result, char* buf, size_t buflen, int *errnop) {
+ const char * endptr = name + strlen(name);
+ char * endptrt = (char *) (uintptr_t) endptr;
+ long uid = strtol(name, &endptrt, 10);
+ if (endptr != endptrt) {
+ PERROR("Entire name is not an integer.");
+ goto out_error_badname;
+ }
+
+ // YOU ARE DONE.
+ return _nss_rainbow_getpwbyuid_r((uid_t)uid, result, buf, buflen, errnop);
+
+out_error_badname:
+ *errnop = EINVAL;
+ return NSS_STATUS_NOTFOUND;
+}