1/* $NetBSD: tilde-luzah-bozo.c,v 1.10 2014/01/02 08:21:38 mrg Exp $ */ 2 3/* $eterna: tilde-luzah-bozo.c,v 1.16 2011/11/18 09:21:15 mrg Exp $ */ 4 5/* 6 * Copyright (c) 1997-2014 Matthew R. Green 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer and 16 * dedication in the documentation and/or other materials provided 17 * with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 */ 32 33/* this code implements ~user support for bozohttpd */ 34 35#ifndef NO_USER_SUPPORT 36 37#include <sys/param.h> 38 39#include <errno.h> 40#include <pwd.h> 41#include <stdlib.h> 42#include <string.h> 43#include <unistd.h> 44 45#include "bozohttpd.h" 46 47/* 48 * bozo_user_transform does this: 49 * - chdir's /~user/public_html 50 * - returns the rest of the file, index.html appended if required 51 * - returned malloced file to serve in request->hr_file, 52 * ala transform_request(). 53 * 54 * transform_request() is supposed to check that we have user support 55 * enabled. 56 */ 57int 58bozo_user_transform(bozo_httpreq_t *request, int *isindex) 59{ 60 bozohttpd_t *httpd = request->hr_httpd; 61 char c, *s, *file = NULL; 62 struct passwd *pw; 63 64 *isindex = 0; 65 66 if ((s = strchr(request->hr_file + 2, '/')) != NULL) { 67 *s++ = '\0'; 68 c = s[strlen(s)-1]; 69 *isindex = (c == '/' || c == '\0'); 70 } 71 72 debug((httpd, DEBUG_OBESE, "looking for user %s", 73 request->hr_file + 2)); 74 pw = getpwnam(request->hr_file + 2); 75 /* fix this up immediately */ 76 if (s) 77 s[-1] = '/'; 78 if (pw == NULL) { 79 (void)bozo_http_error(httpd, 404, request, "no such user"); 80 return 0; 81 } 82 83 debug((httpd, DEBUG_OBESE, "user %s dir %s/%s uid %d gid %d", 84 pw->pw_name, pw->pw_dir, httpd->public_html, 85 pw->pw_uid, pw->pw_gid)); 86 87 if (chdir(pw->pw_dir) < 0) { 88 bozo_warn(httpd, "chdir1 error: %s: %s", pw->pw_dir, 89 strerror(errno)); 90 (void)bozo_http_error(httpd, 404, request, 91 "can't chdir to homedir"); 92 return 0; 93 } 94 if (chdir(httpd->public_html) < 0) { 95 bozo_warn(httpd, "chdir2 error: %s: %s", httpd->public_html, 96 strerror(errno)); 97 (void)bozo_http_error(httpd, 404, request, 98 "can't chdir to public_html"); 99 return 0; 100 } 101 if (s == NULL || *s == '\0') { 102 file = bozostrdup(httpd, httpd->index_html); 103 } else { 104 file = bozomalloc(httpd, strlen(s) + 105 (*isindex ? strlen(httpd->index_html) + 1 : 1)); 106 strcpy(file, s); 107 if (*isindex) 108 strcat(file, httpd->index_html); 109 } 110 111 /* see transform_request() */ 112 if (*file == '/' || strcmp(file, "..") == 0 || 113 strstr(file, "/..") || strstr(file, "../")) { 114 (void)bozo_http_error(httpd, 403, request, "illegal request"); 115 free(file); 116 return 0; 117 } 118 119 if (bozo_auth_check(request, file)) { 120 free(file); 121 return 0; 122 } 123 124 free(request->hr_file); 125 request->hr_file = file; 126 127 debug((httpd, DEBUG_FAT, "transform_user returning %s under %s", file, 128 pw->pw_dir)); 129 return 1; 130} 131#endif /* NO_USER_SUPPORT */ 132