httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@ast.cam.ac.uk (David Robinson)
Subject Re: Bug ?in Apache 0.8.14
Date Wed, 25 Oct 1995 17:55:00 GMT
Attached below is a patch which seems to fix the problem.
It does not read the group file into memory at all, but builds a list
of all the groups to which the user belongs which 'require' needs to know
about. It also allows arbitrary length lines in the group file.

The patch (in particular the new init_group()) is somewhat bigger than I'd
like. If anyone can come up with a smaller version, then please do.
Note that I have taken great care not to change the code which handles
the details and interactions of the 'require' commands.

Also, the implementation is not optimised; it uses getc() to read every
character from the group file. However, because of the better design,
it does seem to be > 3 times faster that 0.6.5.

From: drtr@ast.cam.ac.uk (David Robinson)
Subject: Fix problem with multiple lines in htgroup for same group
Affects: mod_auth.c
ChangeLog: Stream through .htgroup file looking for groups to which the user
           belongs instead of reading the group file into memory.

*** mod_auth.c.orig	Tue Oct 10 23:00:29 1995
--- mod_auth.c	Wed Oct 25 17:42:08 1995
***************
*** 110,145 ****
      return NULL;
  }
  
! table *init_group(pool *p, char *grpfile) {
      FILE *f;
!     table *grps = make_table (p, 15);
      char l[MAX_STRING_LEN];
!     char *name, *ll;
  
      if(!(f=pfopen(p, grpfile, "r")))
          return NULL;
  
!     while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
!         if((l[0] == '#') || (!l[0])) continue;
! 	ll = l;
!         name = getword(p, &ll, ':');
! 	table_set (grps, name, ll);
      }
      pfclose(p, f);
      return grps;
  }
  
! int in_group(pool *p, char *user, char *group, table *grps) {
!     char *l = table_get (grps, group);
!     char *w;
! 
!     if (!l) return 0;
! 
!     while(l[0]) {
!         w = getword_conf (p, &l);
! 	if(!strcmp(w,user))
! 	    return 1;
!     }
      
      return 0;
  }
--- 110,223 ----
      return NULL;
  }
  
! static int
! skip2char(FILE *f, int end)
! {
!     register int ch;
! 
!     do ch = getc(f); while (ch != end && ch != '\n' && ch != EOF);
!     return ch;
! }
! 
! /*
!  * Takes a user and a list of possible groups. Reads the .htgroup file
!  * and returns an array containing those of the requested groups to which
!  * the user belongs.
!  * Does not place any restriction on the file format; allows arbitrary long
!  * lines.
!  */
! array_header *
! init_group(pool *p, const char *user, array_header *ingrp,
! 	   const char *grpfile) 
! {
      FILE *f;
!     array_header *grps = make_array (p, ingrp->nelts, sizeof(char *));
      char l[MAX_STRING_LEN];
!     char **inelts;
!     int len, grpid, ch, i;
! 
!     if (ingrp == NULL || ingrp->nelts == 0) return grps;
  
      if(!(f=pfopen(p, grpfile, "r")))
          return NULL;
  
!     inelts = (char **)ingrp->elts;
!     while (!feof(f) && ingrp->nelts != 0)
!     {
! 	ch = getc(f);
! 	if (ch == EOF) break;
! 	if (ch == '#' || ch == ':') /* skip lines with no group name */
! 	{
! 	    skip2char(f, '\n');
! 	    continue;
! 	}
! /* read group name */
! 	len = 0;
! 	do
! 	{
! 	    l[len++] = ch;
! 	    ch = getc(f);
! 	} while (ch != ':' && len<MAX_STRING_LEN-1 && ch != '\n' &&
ch != EOF);
! 	if (ch == '\n' || ch == EOF) continue;  /* bad line */
! 	l[len] = '\0';
! 	grpid = -1;
! 	if (ch == ':') /* if group name not too long, then search for it */
! 	{
! 	    for (i=0; i < ingrp->nelts; i++)
! 		if (strcmp(l, inelts[i]) == 0) break;
! 	    if (i < ingrp->nelts) grpid = i;
! 	}
! 
! /* interested in this group */
! 	if (grpid >= 0)
! 	{
! 	    ch = getc(f);  /* read past ':' */
! 	    for (;;)
! 	    {
! /* skip whitespace */
! 		while (ch == ' ') ch = getc(f);
! 		if (ch == '\n' || ch == EOF) break; /* no more */
! /* read the username */
! 		len = 0;
! 		do
! 		{
! 		    l[len++] = ch;
! 		    ch = getc(f);
! 		} while (ch != ' ' && len < MAX_STRING_LEN-1 && ch != '\n' &&
! 			 ch != EOF);
! 		if (len == MAX_STRING_LEN-1) /* username too long */
! 		{
! 		    ch = skip2char(f, ' '); /* skip it */
! 		    continue;
! 		}
! 		l[len] = '\0';
! 		if (strcmp(l, user) == 0)
! 		{
! 		    char **ngrp=push_array(grps); /* copy it to output list */
! 		    *ngrp = inelts[grpid];
! 		    for (i=grpid; i < ingrp->nelts; i++) /* del from inp list*/
! 			inelts[i] = inelts[i+1];
! 		    ingrp->nelts--;
! 		    break; /* finish with this line */
! 		}
! 	    }
! 	}
! 
! 	if (ch != '\n') skip2char(f, '\n');
      }
      pfclose(p, f);
      return grps;
  }
  
! int in_group(const char *group, array_header *grps) {
!     int i, ne;
!     const char **elts;
! 
!     if (grps == NULL) return 0;
!     elts = (const char **)grps->elts;
!     ne = grps->nelts;
! 
!     for (i=0; i < ne; i++) if(strcmp(group, elts[i]) == 0) return 1;
      
      return 0;
  }
***************
*** 201,210 ****
  
      register int x;
      char *t, *w;
!     table *grpstatus;
      
      if(sec->auth_grpfile)
!         grpstatus = init_group(r->pool, sec->auth_grpfile);
      else
          grpstatus = NULL;
  
--- 279,304 ----
  
      register int x;
      char *t, *w;
!     array_header *grpstatus;
      
      if(sec->auth_grpfile)
!     {
! 	grpstatus = make_array(r->pool, 5, sizeof(char *));    
! 	for(x=0; x < reqs_arr->nelts; x++)
! 	{
! 	    if (! (reqs[x].method_mask & (1 << m))) continue;
! 	    t = reqs[x].requirement;
! 	    w = getword(r->pool, &t, ' ');
! 	    if (strcmp(w, "group") != 0) continue;
! 	    while(t[0])
! 	    {
! 		char **ngrp=push_array(grpstatus);
! 		*ngrp = getword_conf(r->pool, &t);
! 	    }
! 	}
! /* find to which of those groups the user actually belongs */
! 	grpstatus = init_group(r->pool, user, grpstatus, sec->auth_grpfile);
!     }
      else
          grpstatus = NULL;
  
***************
*** 229,235 ****
  	    
              while(t[0]) {
                  w = getword_conf(r->pool, &t);
!                 if(in_group(r->pool, user, w, grpstatus))
  		    return OK;
              }
          }
--- 323,329 ----
  	    
              while(t[0]) {
                  w = getword_conf(r->pool, &t);
!                 if(in_group(w, grpstatus))
  		    return OK;
              }
          }

Mime
View raw message