You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Dirk-Willem van Gulik <di...@elect6.jrc.it> on 1997/11/14 14:30:45 UTC

AllowDev module

Dean,

Cool. put it to good use. Feel free to play with these mod's. It
should have been a flat list; as a hashed/linked list is just
sheer overkill IMHO, but I realized that too late.

Dw.

*** a	Fri Nov 14 14:28:16 1997
--- mod_allowdev.c	Fri Nov 14 14:26:46 1997
***************
*** 3,8 ****
--- 3,9 ----
   * on a listed device.
   * 
   * Author: Dean Gaudet <dg...@arctic.org>
+  *         dirkx@webweaving.org  did some horrible things to it.
   */
  
  /*
***************
*** 14,61 ****
  
  /* TODO: Add a config directive "AllowDev" which takes a
   * filename, stats the file to find out what device it is on.
   * Fail gracefully, if the file doesn't exist, it's fine to
   * continue, you're not going to allow files to be served which
   * wouldn't otherwise be serveable.
   *
   * TODO: Device numbers should be easy to hash.
   */
  
  #include "httpd.h"
  #include "http_config.h"
  #include "http_log.h"
  
  /* don't ask why we run this in header_parse phase ... well ok,
   * go ahead, ask.  It's because there's no other way to protect
   * against the Satisfy directive.
   */
  static int check_device(request_rec *r)
  {
      if (r->finfo.st_mode == 0) {
  	return DECLINED;
      }
!     switch (r->finfo.st_dev) {
!     /* hard code the list of acceptable devices here */
!     case 0x0303:
!     case 0x1602:
! 	return DECLINED;
!     }
      aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
  	"mod_allowdev: request to %s is on device 0x%x, forbidden",
  	r->uri, r->finfo.st_dev);
      return HTTP_FORBIDDEN;
  }
  
- 
  module MODULE_VAR_EXPORT allowdev_module =
  {
      STANDARD_MODULE_STUFF,
      NULL,			/* initializer */
!     NULL,			/* dir config creater */
      NULL,			/* dir merger --- default is to override */
      NULL,			/* server config */
      NULL,			/* merge server config */
!     NULL,
      NULL,			/* handlers */
      NULL,			/* filename translation */
      NULL,			/* check_user_id */
--- 15,146 ----
  
  /* TODO: Add a config directive "AllowDev" which takes a
   * filename, stats the file to find out what device it is on.
+  *
+  * done-ish (dirkx)
+  *
   * Fail gracefully, if the file doesn't exist, it's fine to
   * continue, you're not going to allow files to be served which
   * wouldn't otherwise be serveable.
   *
   * TODO: Device numbers should be easy to hash.
+  *
+  * not-done-ish (dirkx) as we use a lazy linked list. Which actualy
+  *	is noncence; as the number of devices on a given machine
+  *	is not going to be bigger than say 16 or so. So just a
+  *	flat search would have done.
+  *
   */
  
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <errno.h>
+ #include <string.h>
+ 
  #include "httpd.h"
  #include "http_config.h"
  #include "http_log.h"
  
+ module MODULE_VAR_EXPORT allowdev_module;
+ 
+ typedef struct devnos {
+ 	dev_t no;		/* device number */
+ 	struct devnos * nxt;
+ } devnos;
+ 
+ typedef struct allowdev_config_rec {
+ 	devnos * lst;
+ 	/* that is all we need */
+ } allowdev_config_rec;
+ 
+ void * create_allowdev_dir_config(pool *p, char *d)
+ {
+ 	allowdev_config_rec *sec = (allowdev_config_rec *)
+ 		pcalloc(p, sizeof(allowdev_config_rec));
+ 		/* relying on Ouch! No memory trapping... */
+ 
+ 	sec -> lst = NULL;
+ 
+ 	return sec;
+ }
+ 
+ const char * add_dev_slot( cmd_parms * cmd,
+ 	allowdev_config_rec * sec,
+ 	char *args)
+ {
+ 	devnos * first;
+ 	dev_t no;
+     	struct stat buf;
+ 
+ 
+ 	if ((!(*args)) || (strlen(args)==0))	
+ 		return "Must define a file/device to stat";
+ 
+     	if (stat ( args, &buf) == -1) 
+ 		return "Cannot stat file/device";
+ 
+ 	no = buf.st_dev;
+ 
+ 	/* though we could return an error; we try to
+ 	 * just silently avoid putting the same device
+ 	 * in twice.
+ 	 */
+ 	for( p = sec->list; p; p=p->nxt )
+ 		if (p->no == no) return NULL
+ 
+ 	first = sec->lst;
+ 	sec-> lst = (devnos *) palloc( cmd->pool, sizeof( devnos ));
+ 		/* relying on Ouch! No memory trapping... */
+ 
+ 	sec->lst->no = no;
+ 	sec->lst->nxt = first;
+ 
+ 	return NULL;
+ }
+ 
+ command_rec allowdev_cmds [] =
+ {
+ 	{"AllowDevs", add_dev_slot, NULL, OR_AUTHCFG, ITERATE,
+ 	 "A space seperated list of devices or files"
+ 	}, 
+ 	{ NULL }
+ };
+ 	
  /* don't ask why we run this in header_parse phase ... well ok,
   * go ahead, ask.  It's because there's no other way to protect
   * against the Satisfy directive.
   */
  static int check_device(request_rec *r)
  {
+     allowdev_config_rec *sec =
+     (allowdev_config_rec *) get_module_config(r->per_dir_config,
+                                                &allowdev_module);
+     devnos * p;
+ 
      if (r->finfo.st_mode == 0) {
  	return DECLINED;
      }
! 
!     for( p=sec->lst; p != NULL; p=p->nxt ) 
! 	if ( p->no == r->finfo.st_dev )
! 	    return DECLINED;
! 
      aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
  	"mod_allowdev: request to %s is on device 0x%x, forbidden",
  	r->uri, r->finfo.st_dev);
      return HTTP_FORBIDDEN;
  }
  
  module MODULE_VAR_EXPORT allowdev_module =
  {
      STANDARD_MODULE_STUFF,
      NULL,			/* initializer */
!     create_allowdev_dir_config,	/* dir config creater */
      NULL,			/* dir merger --- default is to override */
      NULL,			/* server config */
      NULL,			/* merge server config */
!     allowdev_cmds,		/* command handlers */
      NULL,			/* handlers */
      NULL,			/* filename translation */
      NULL,			/* check_user_id */
***************
*** 69,72 ****
--- 154,158 ----
      NULL,			/* child_exit */
      NULL			/* post read-request */
  };
+