*
*/
-static char *make_disk_path(char *user, char *path, char **storage_root);
+static char *make_disk_path(char *dom_user, char *path, gss_buffer_t authuser, char **storage_root);
static evhtp_res serve_directory(evhtp_request_t *request, char *disk_path,
struct stat *stat_buf);
static evhtp_res serve_file_head(evhtp_request_t *request_t, char *disk_path,
struct stat *stat_buf,const char *mime_type);
static evhtp_res serve_file(evhtp_request_t *request, const char *disk_path,
struct stat *stat_buf);
-static evhtp_res handle_get_or_head(evhtp_request_t *request, int include_body);
+static evhtp_res handle_get_or_head(evhtp_request_t *request, gss_buffer_t authuser, int include_body);
-evhtp_res storage_handle_head(evhtp_request_t *request) {
+evhtp_res storage_handle_head(evhtp_request_t *request, gss_buffer_t authuser) {
if(RS_EXPERIMENTAL) {
- return handle_get_or_head(request, 0);
+ return handle_get_or_head(request, authuser, 0);
} else {
return EVHTP_RES_METHNALLOWED;
}
}
-evhtp_res storage_handle_get(evhtp_request_t *request) {
+evhtp_res storage_handle_get(evhtp_request_t *request, gss_buffer_t authuser) {
log_debug("storage_handle_get()");
- return handle_get_or_head(request, 1);
+ return handle_get_or_head(request, authuser, 1);
}
-evhtp_res storage_handle_put(evhtp_request_t *request) {
+evhtp_res storage_handle_put(evhtp_request_t *request, gss_buffer_t authuser) {
log_debug("HANDLE PUT");
if(request->uri->path->file == NULL) {
char *storage_root = NULL;
char *disk_path = make_disk_path(REQUEST_GET_USER(request),
REQUEST_GET_PATH(request),
+ authuser,
&storage_root);
if(disk_path == NULL) {
return EVHTP_RES_SERVERR;
} while(0);
+#if 0
// look up uid and gid of current user, so we can chown() correctly.
uid_t uid;
gid_t gid;
return EVHTP_RES_SERVERR;
}
} while(0);
+#endif
// create parent directories
do {
return EVHTP_RES_SERVERR;
}
+#if 0
if(fchownat(dirfd, dir_name, uid, gid, AT_SYMLINK_NOFOLLOW) != 0) {
log_warn("failed to chown() newly created directory: %s", strerror(errno));
}
+#endif
}
prevfd = dirfd;
dirfd = openat(prevfd, dir_name, O_RDONLY);
}
if(! exists) {
+#if 0
if(fchown(fd, uid, gid) != 0) {
log_warn("Failed to chown() newly created file: %s", strerror(errno));
}
+#endif
}
// write buffered data
return exists ? EVHTP_RES_OK : EVHTP_RES_CREATED;
}
-evhtp_res storage_handle_delete(evhtp_request_t *request) {
+evhtp_res storage_handle_delete(evhtp_request_t *request, gss_buffer_t authuser) {
if(request->uri->path->file == NULL) {
// DELETE to directories aren't allowed
char *storage_root = NULL;
char *disk_path = make_disk_path(REQUEST_GET_USER(request),
REQUEST_GET_PATH(request),
+ authuser,
&storage_root);
if(disk_path == NULL) {
return EVHTP_RES_SERVERR;
return EVHTP_RES_OK;
}
-static char *make_disk_path(char *user, char *path, char **storage_root) {
+static char *make_disk_path(char *dom_user, char *path, gss_buffer_t authuser, char **storage_root) {
// FIXME: use passwd->pwdir instead of /home/{user}/
// calculate maximum length of path
- int pathlen = ( strlen(user) + strlen(path) +
+ int pathlen = ( strlen(dom_user) + strlen(path) +
6 + // "/home/"
1 + // another slash
RS_HOME_SERVE_ROOT_LEN );
char *disk_path = malloc(pathlen + 1);
+ char *xsfile = NULL;
+ FILE *xsf;
+ char principal [1026];
+ bool authorized;
if(disk_path == NULL) {
log_error("malloc() failed: %s", strerror(errno));
return NULL;
}
- if(storage_root) {
- *storage_root = malloc( 7 + RS_HOME_SERVE_ROOT_LEN + strlen(user) + 1);
- if(*storage_root == NULL) {
- log_error("malloc() failed: %s", strerror(errno));
- free(disk_path);
- return NULL;
+ log_debug("Constructing disk_path for dom_user = \"%s\"", dom_user);
+ xsfile = malloc( 7 + RS_HOME_SERVE_ROOT_LEN + strlen(dom_user) + 1 + 17);
+ if(xsfile == NULL) {
+ log_error("malloc() failed: %s", strerror(errno));
+ free(disk_path);
+ return NULL;
+ }
+ sprintf(xsfile, "/home/%s/%s/.k5remotestorage", dom_user, RS_HOME_SERVE_ROOT);
+ log_debug("Access control list = \"%s\"", xsfile);
+ xsf = fopen (xsfile, "r");
+ authorized = false;
+ if (xsf) {
+ while ((!authorized) && fgets (principal, sizeof (principal)-1, xsf)) {
+ int len = strlen (principal);
+ if ((len > 1) && (principal [len-1] == '\n')) {
+ principal [--len] = '\0';
+ }
+ log_debug("Considering acceptable principal \"%s\"", principal);
+ authorized = (len == authuser->length) && (0 == memcmp (principal, authuser->value, len));
}
- sprintf(*storage_root, "/home/%s/%s", user, RS_HOME_SERVE_ROOT);
+ fclose (xsf);
+ } else {
+ log_error ("Failed to open access control list");
+ free(xsfile);
+ free(disk_path);
+ return NULL;
+ }
+ if (!authorized) {
+ log_error ("Access control list does not contain authorized user");
+ free(xsfile);
+ free(disk_path);
+ return NULL;
+ }
+ log_debug ("xsfile = \"%s\"", xsfile);
+ if(storage_root) {
+ // Cut off .k5remotestorage and reuse for *storage_root
+ xsfile [7 + RS_HOME_SERVE_ROOT_LEN + strlen (dom_user)] = '\0';
+ *storage_root = xsfile;
+ log_debug ("storage_root = \"%s\"", storage_root);
+ } else {
+ free (xsfile);
+ xsfile = NULL;
}
// remove all /.. segments
// (we don't try to resolve them, but instead treat them as garbage)
pos[restlen] = 0;
}
// build path
- sprintf(disk_path, "/home/%s/%s%s", user, RS_HOME_SERVE_ROOT, path);
+ sprintf(disk_path, "/home/%s/%s%s", dom_user, RS_HOME_SERVE_ROOT, path);
+ log_debug ("disk_path = \"%s\"", disk_path);
return disk_path;
}
-static evhtp_res handle_get_or_head(evhtp_request_t *request, int include_body) {
+static evhtp_res handle_get_or_head(evhtp_request_t *request, gss_buffer_t authuser, int include_body) {
log_debug("HANDLE GET / HEAD (body: %s)", include_body ? "true" : "false");
char *disk_path = make_disk_path(REQUEST_GET_USER(request),
REQUEST_GET_PATH(request),
+ authuser,
NULL);
if(disk_path == NULL) {
return EVHTP_RES_SERVERR;