Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/nss-rainbow.c
diff options
context:
space:
mode:
Diffstat (limited to 'nss-rainbow.c')
-rw-r--r--nss-rainbow.c179
1 files changed, 82 insertions, 97 deletions
diff --git a/nss-rainbow.c b/nss-rainbow.c
index c108799..a7bfd1f 100644
--- a/nss-rainbow.c
+++ b/nss-rainbow.c
@@ -5,7 +5,6 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
-#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
@@ -15,12 +14,10 @@
#include <syslog.h>
/* code generators */
-#define STATIC_ASSERT(expr) extern char __static_assertion_failed [(expr) ? 1 : -1]
-#define SAVE_ERR(EXPR) {int __errno_save = errno; EXPR; errno = __errno_save;}
-#define __XSTRING(X) __STRING(X)
-#define PERROR(msg) {syslog(LOG_ERR, "%s|%d| %s: %s\nError %d: %s", __FILE__, __LINE__, __func__, msg, errno, strerror(errno));}
-#define CHK(EXPR, MSG, ERR_LABEL) {if(EXPR) { PERROR(MSG); goto ERR_LABEL;}}
-#define LET(LETEXPR, CONDEXPR, MSG, ERR_LABEL) LETEXPR; if (CONDEXPR) { PERROR(MSG); goto ERR_LABEL;}
+#include "cgen.h"
+
+#include "buf.h"
+#include "nat.h"
/* constants */
#define SHELL "/sbin/nologin"
@@ -40,79 +37,6 @@ _nss_rainbow_setpwent(void) {
g_done = false;
}
-int write_buf(char** buf, size_t * buflen, const char* val)
-{
- /* write_buf will not write outside of (*buf)[0..(*buflen-1)]
- * if *buflen > strlen(val), then write_buf will ensure that *buf points to a null-terminated string.
- * on success, write_buf will advance *buf to the next free char,
- * set *buflen to indicate the quantity of remaining space,
- * and return 1.
- * on error, write_buf will set errno, return 0, and will not modify *buf or *buflen.
- * *buf and val should not overlap.
- */
-
- LET(size_t copy_amt = strlen(val) + 1, copy_amt == 0,
- "Integer overflow.", out_err_overflow);
-
- if (*buflen < copy_amt)
- goto out_err_range;
-
- memcpy(*buf, val, copy_amt);
-
- *buf += copy_amt;
- *buflen -= copy_amt;
- return 1;
-
-out_err_overflow:
- errno = EOVERFLOW;
- return 0;
-
-out_err_range:
- errno = ERANGE;
- return 0;
-}
-
-int format_buf(char** buf, size_t* buflen, const char* fmt, ...)
-{
- /* format_buf will not write outside of (*buf)[0..(*buflen-1)]
- * if *buflen > 0, format_buf will ensure that *buf points to a null-terminated string.
- * on success, format_buf will advance *buf to the next free char,
- * set *buflen to indicate the quantity of remaining space,
- * and return 1.
- * on error, format_buf will set errno, return 0, and will not modify *buf or *buflen.
- * *buf should know overlap with fmt or any optional arguments.
- */
- if (*buflen < 1)
- {
- errno = ERANGE;
- return 0;
- }
-
- size_t safe_buflen = *buflen - 1;
-
- va_list ap;
- va_start(ap, fmt);
- int status = vsnprintf(*buf, safe_buflen, fmt, ap);
- SAVE_ERR(va_end(ap));
-
- if (status < 0)
- goto out_err;
-
- size_t written = (size_t) status;
- if (safe_buflen < written) {
- errno = ERANGE;
- goto out_err;
- }
-
- *buf += written+1;
- *buflen -= written+1;
- return 1;
-
-out_err:
- (*buf)[safe_buflen] = '\0';
- 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
@@ -133,15 +57,15 @@ _nss_rainbow_getpwent_r(struct passwd *result, char* buf, size_t buflen, int *er
"Unable to retrieve $USER.", out_error_unavail);
result->pw_dir = buf;
- CHK(write_buf(&buf, &buflen, home) == 0,
+ CHK(write_buf(&buf, &buflen, home) == 1,
"Not enough buffer for $HOME.", out_error_again);
result->pw_gecos = result->pw_name = result->pw_passwd = buf;
- CHK(write_buf(&buf, &buflen, user) == 0,
+ CHK(write_buf(&buf, &buflen, user) == 1,
"Not enough buffer for $USER.", out_error_again);
result->pw_shell = buf;
- CHK(write_buf(&buf, &buflen, SHELL) == 0,
+ CHK(write_buf(&buf, &buflen, SHELL) == 1,
"Shell string constant too long.", out_error_again);
syslog(LOG_ERR, "%s success: %s (%d, %d) %s %s %s", __func__,
@@ -169,7 +93,7 @@ enum nss_status _nss_rainbow_getpwuid_r(uid_t uid, struct passwd *result, char*
return NSS_STATUS_NOTFOUND;
result->pw_dir = buf;
- CHK(format_buf(&buf, &buflen, "/home/olpc/isolation/1/uid_to_home_dir/%d", uid) == 0,
+ CHK(format_buf(&buf, &buflen, "/home/olpc/isolation/1/uid_to_home_dir/%d", uid) == 1,
"Unable to calculate home dir.", out_error_errno);
struct stat st;
@@ -179,11 +103,11 @@ enum nss_status _nss_rainbow_getpwuid_r(uid_t uid, struct passwd *result, char*
result->pw_gid = st.st_gid;
result->pw_gecos = result->pw_name = result->pw_passwd = buf;
- CHK(format_buf(&buf, &buflen, "%d", uid) == 0,
+ CHK(format_buf(&buf, &buflen, "%d", uid) == 1,
"Unable to calculate user name.", out_error_errno);
result->pw_shell = buf;
- CHK(write_buf(&buf, &buflen, SHELL) == 0,
+ CHK(write_buf(&buf, &buflen, SHELL) == 1,
"Shell string constant too long.", out_error_errno);
syslog(LOG_ERR, "%s success in uid: %s (%d, %d) %s %s %s", __func__, result->pw_name, result->pw_uid, result->pw_gid, result->pw_dir, result->pw_shell, result->pw_passwd);
@@ -195,22 +119,83 @@ out_error_errno:
return NSS_STATUS_TRYAGAIN;
}
-
enum nss_status _nss_rainbow_getpwnam_r(const char * name, struct passwd *result, char* buf, size_t buflen, int *errnop) {
openlog("nss-rainbow", LOG_PID, LOG_LOCAL0);
- char * endptr = (char*) (uintptr_t) (name + strlen(name));
+ unsigned long val;
+ CHK(parse_nat(&val, name, strlen(name)) == 1,
+ "Unable to parse name into a uid.", out_error_name);
+
+ TST(val < 10000 || val > 60000, EINVAL,
+ "Name specifies a uid outside [10000, 60000].", out_error_name);
+
+ return _nss_rainbow_getpwuid_r((uid_t)val, result, buf, buflen, errnop);
+
+out_error_name:
+ *errnop = errno;
+ return NSS_STATUS_NOTFOUND;
+}
- errno = 0; /* To distinguish success/failure after call */
- long val = strtol(name, &endptr, 10);
+/*
+enum nss_status
+_nss_rainbow_initgroups_dyn(const char *user, gid_t gid, long int *start, long int *size, gid_t **groupsp, long int limit, int *errnop) {
+ openlog("nss-rainbow", LOG_PID, LOG_LOCAL0);
- if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
- || (errno != 0 && val == 0)
- || (name == endptr)) {
- PERROR("Unable to parse name into a uid.");
- *errnop = (errno = 0) ? EINVAL : errno;
+ if (uid < 10000)
return NSS_STATUS_NOTFOUND;
- }
- return _nss_rainbow_getpwuid_r((uid_t)val, result, buf, buflen, errnop);
+ int pathlen = 1024;
+ char pathdata[1024], *pathbuf = pathdata;
+
+ result->pw_dir = buf;
+ CHK(format_buf(&pathbuf, &pathlen, "/home/olpc/isolation/1/uid_to_home_dir/%d", uid) == 1,
+ "Unable to calculate home dir.", out_error_errno);
+
+ struct stat st;
+ CHK(stat(result->pw_dir, &st) == -1,
+ "Stat failed for homebuf.", out_error_errno);
+ result->pw_uid = uid;
+ result->pw_gid = st.st_gid;
+
+ (*groupsp)[*start] =
+
+ return NSS_STATUS_SUCCESS;
+
+out_error_errno:
+ *ernnop = errno;
+ return NSS_STATUS_NOTFOUND;
+}
+enum nss_status _nss_rainbow_setgrent(void) {
+ openlog("nss-rainbow", LOG_PID, LOG_LOCAL0);
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status _nss_rainbow_endgrent(void) {
+ openlog("nss-rainbow", LOG_PID, LOG_LOCAL0);
+ return NSS_STATUS_SUCCESS;
}
+
+struct group
+{
+ char *gr_name;
+ char *gr_passwd;
+ __gid_t gr_gid;
+ char **gr_mem;
+};
+enum nss_status
+_nss_rainbow_getgrent_r(struct group *result, char *buf, size_t buflen, int *errnop) {
+ openlog("nss-rainbow", LOG_PID, LOG_LOCAL0);
+ return NSS_STATUS_NOTFOUND;
+}
+
+enum nss_status
+_nss_rainbow_getgrgid_r(gid_t gid, struct group *gbuf, char *buf, size_t buflen, int *errnop) {
+ return NSS_STATUS_NOTFOUND;
+}
+
+enum nss_status
+_nss_rainbow_getgrnam_r(const char* name, struct group *gbuf, char *buf, size_t buflen, int *errnop) {
+ return NSS_STATUS_NOTFOUND;
+}
+
+*/