Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 24 Oct 1997 15:08:03 EDT
From:      Hetzels <Hetzels@aol.com>
To:        ports@freebsd.org
Subject:   Re: Apache w/FrontPage Module Port
Message-ID:  <5020794.3450f1ea@aol.com>

next in thread | raw e-mail | index | archive | help
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 <stdio.h>

/* 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 ---



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5020794.3450f1ea>