From owner-freebsd-ports Fri Oct 24 12:12:41 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id MAA12453 for ports-outgoing; Fri, 24 Oct 1997 12:12:41 -0700 (PDT) (envelope-from owner-freebsd-ports) Received: from imo05.mx.aol.com (imo05.mx.aol.com [198.81.11.107]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id MAA12439 for ; Fri, 24 Oct 1997 12:12:27 -0700 (PDT) (envelope-from Hetzels@aol.com) From: Hetzels Message-ID: <5020794.3450f1ea@aol.com> Date: Fri, 24 Oct 1997 15:08:03 EDT To: ports@freebsd.org Subject: Re: Apache w/FrontPage Module Port Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7bit Organization: AOL (http://www.aol.com) X-Mailer: Inet_Mail_Out (IMOv10) Sender: owner-freebsd-ports@freebsd.org X-Loop: FreeBSD.org Precedence: bulk I am sorry I opened a BIG can of worms about Apache & FrontPage, But at least once a month someone asks on the ISP list how to install the FrontPage Extentions. Since, I was creating an apache server with frontpage extentions I decided to make a port out of it. The default httpd.conf file has the server running as user nobody in group nogroup. When the install script is run under root the apache files get installed as: /usr/local/etc/apache/* root wheel /usr/local/www/* root wheel Directories have permission 755, while files are 644. Now when the install script for the FrontPage Extentions runs (fp_install.sh), it reads the httpd.conf file and uses the user that the server runs as (nobody) to chown the data directory, which renders the FrontPage Extentions useless in creating new sub-webs. /usrlocal/www/data/* nobody [GROUP] NOTE: GROUP can be anything as the frontpage install script also changes it, as specified by the user. The only way to correct it is to chown -R the data & apache directories so that they are owned by the same user & group. The apache server starts up as root, then chown to user nobody & group nogroup. I have the frontpage extenstions setup so that they run as user www, in group www. Is there any security problems with running it this way? I have atached the old version of the FrontPage Module, if anyone wants to go through it. Don't have the source for fpexe. :( Scot --- mod_frontpage.c --- /* ==================================================================== * * Apache frontpage module. * * Copyright 1996-1997 Microsoft Corporation -- All Rights Reserved. * * Author: Jeff Moskow -- Ready-to-Run Software, Inc. * * $Revision: 1.2 $ * $Date: 1997/06/12 17:23:14 $ * */ #include "httpd.h" #include "http_config.h" #include /* Static SUID key value used by this module */ static char fpsuidkeyval[129]; static char fpsuidkeyfile[80]; /* * Declare ourselves so the configuration routines can find us. * Struct is filled it at the bottom of this file. */ module frontpage_module; #define FP "/usr/local/frontpage/currentversion" #define FPSTUB "/usr/local/frontpage/currentversion/apache- fp/_vti_bin/fpexe" #define SHTML "/_vti_bin/shtml.exe" #define SHTML_LEN 19 #define FPCOUNT "/_vti_bin/fpcount.exe" #define FPCOUNT_LEN 21 #define AUTHOR "/_vti_bin/_vti_aut/author.exe" #define AUTHOR_LEN 29 #define ADMIN "/_vti_bin/_vti_adm/admin.exe" #define ADMIN_LEN 28 #define KEYFILE "/usr/local/frontpage/currentversion/apache-fp/suidkey.%d" #define FPLOCKFILE "/usr/local/frontpage/currentversion/apache-fp/fpclean.lck" #define FPKEYDIR "/usr/local/frontpage/currentversion/apache-fp" /* * Clean up obsolete keyfiles */ void fp_cleanup() { int fd; DIR *d; struct DIR_TYPE *dstruct; int pid; char buf[MAXPATHLEN]; fd = creat( FPLOCKFILE, O_CREAT|0600); #if defined(SOLARIS2) || defined(AIX) || defined(hpux) lockf( fd, F_LOCK, 0 ); #else flock( fd, LOCK_EX ); #endif if(d=opendir(FPKEYDIR)) { while((dstruct=readdir(d))) { if(strncmp("suidkey.", dstruct->d_name, 8) == 0) { pid = atoi(dstruct->d_name+8); if (kill(pid,0) == -1) { sprintf(buf,"%s/%s",FPKEYDIR,dstruct->d_name); unlink(buf); } } } closedir(d); } close(fd); } /* * module-initialiser: * * create the suidkey file and local value */ static void frontpage_init (server_rec *s, pool *p) { int fd; unsigned int v1, v2, v3, v4; int fdpipe[2]; int pid; fp_cleanup(); /* Clean up old key files before we start */ pipe( fdpipe ); if (pid = fork()) { int stat; close(fdpipe[1]); waitpid( pid, &stat, 0 ); read( fdpipe[0], fpsuidkeyval, 129 ); sscanf( fpsuidkeyval, "%u %u %u %u", &v2, &v1, &v4, &v3 ); #if !defined(hpux) && !defined(SOLARIS2) srandom( fd = (v1 << 10) + v2 + (v4 << 12) + v3 ); #else srand( fd = (v1 << 10) + v2 + (v4 << 12) + v3 ); #endif for ( v1 = 0 ; v1 < 129 ; v1++ ) { #if !defined(hpux) && !defined(SOLARIS2) v2 = random() & 0xf; #else v2 = rand() & 0xf; #endif if (v2 < 10) fpsuidkeyval[v1] = v2+'0'; else fpsuidkeyval[v1] = v2+'A'-10; } fpsuidkeyval[128] = '\0'; } else { dup2( fdpipe[1], 1 ); close(fdpipe[0]); /* Get data for a seed for rand which can't be duplicated */ execl( "/bin/sh", "/bin/sh", "-c", #ifdef linux "echo `/bin/ps | /usr/bin/sum ; /bin/ps | /usr/bin/sum`", NULL ); #else #if defined( bsdi ) || defined (__FreeBSD__) "echo `/bin/ps | /usr/bin/cksum -o 1 ; /bin/ps | /usr/bin/cksum -o 1`", NULL ); #else "echo `/bin/ps -ea | /bin/sum ; /bin/ps -ea | /bin/sum`", NULL ); #endif #endif } #if defined sun && ! defined __SVR4 sprintf( fpsuidkeyfile, KEYFILE, getpgrp(0) ); #else sprintf( fpsuidkeyfile, KEYFILE, getpgrp() ); #endif fd = creat( fpsuidkeyfile, 0600); write( fd, fpsuidkeyval, strlen(fpsuidkeyval) ); close(fd); // atexit(&fp_cleanup); } /* * look for a valid FP scenario and fake a scriptalias it appropriate */ int fp_alias(request_rec *r, char *cgi, char *fpexe, int len) { struct stat webroot; struct stat vti_pvt; struct stat stub; char buf[MAXPATHLEN]; char save = *(cgi+1); *(cgi+1) = '\0'; translate_name(r); *(cgi+1) = save; sprintf( buf, "%s_vti_pvt", r->filename ); r->filename[strlen(r->filename)-1] = '\0'; /* make sure that we can run the stub */ if (stat(FPSTUB,&stub) || !(stub.st_mode | S_IXOTH)) return DECLINED; /* only run if webroot and webroot/_vti_pvt are both have the same user/group and neither have uid == 0 or gid == 0 */ if (stat(buf,&vti_pvt) || !vti_pvt.st_uid || !vti_pvt.st_gid || stat(r->filename, &webroot) || webroot.st_uid != vti_pvt.st_uid || webroot.st_gid != vti_pvt.st_gid) { /* FP Security Violation */ return DECLINED; } r->handler = pstrdup(r->pool, "cgi-script"); table_set (r->notes, "alias-forced-type", r->handler); sprintf( buf, "%d", webroot.st_uid ); table_set (r->subprocess_env, "FPUID", pstrdup(r->pool, buf)); sprintf( buf, "%d", webroot.st_gid ); table_set (r->subprocess_env, "FPGID", pstrdup(r->pool, buf)); table_set (r->subprocess_env, "FPEXE", pstrdup(r->pool, fpexe)); table_set (r->subprocess_env, "FPKEY", pstrdup(r->pool, fpsuidkeyval)); r->execfilename = pstrcat(r->pool,FPSTUB,cgi+len,NULL); r->filename = pstrcat(r->pool,r->filename,cgi,NULL); return OK; } /* * This routine looks for shtml.exe, author.exe and admin.exe in a URI * if found, we call fp_alias to check for a valid FP scenario * * The return value is OK or DECLINED. */ static int frontpage_xlate (request_rec *r) { char *cgi; /* Test for FrontPage server extenders... .../_vti_bin/shtml.exe .../_vti_bin/_vti_aut/author.exe or .../_vti_bin/_vti_adm/admin.exe */ r->execfilename = r->filename; /* only do this for ScriptAlias processing.... */ if (cgi = strstr(r->uri, AUTHOR )) return fp_alias(r,cgi,AUTHOR,AUTHOR_LEN); if (cgi = strstr(r->uri, SHTML )) return fp_alias(r,cgi,SHTML, SHTML_LEN); if (cgi = strstr(r->uri, ADMIN )) return fp_alias(r,cgi,ADMIN, ADMIN_LEN); if (cgi = strstr(r->uri, FPCOUNT)) return fp_alias(r,cgi,FPCOUNT,FPCOUNT_LEN); return DECLINED; } module frontpage_module = { STANDARD_MODULE_STUFF, frontpage_init, /* initializer */ NULL, /* per-directory config creater */ NULL, /* dir config merger - default is to override */ NULL, /* server config creator */ NULL, /* server config merger */ NULL, /* command table */ NULL, /* [6] list of handlers */ frontpage_xlate, /* [1] filename-to-URI translation */ NULL, /* [4] check/validate HTTP user_id */ NULL, /* [5] check HTTP user_id is valid *here* */ NULL, /* [3] check access by host address, etc. */ NULL, /* [6] MIME type checker/setter */ NULL, /* [7] fixups */ NULL, /* [9] logger */ NULL, /* [2] header parser */ }; --- mod_frontpage.c ---