diff -U1000 -r orig-1.4.1/src/afs/afs.h scripts-1.4.1/src/afs/afs.h
--- orig-1.4.1/src/afs/afs.h	2006-02-17 16:58:33.000000000 -0500
+++ scripts-1.4.1/src/afs/afs.h	2006-10-02 17:35:12.000000000 -0400
...
+#define AFSAGENT_UID (101)
+#define HTTPD_UID (48)
+#define DAEMON_SCRIPTS_PTSID (33554596)
 struct vrequest {
     afs_int32 uid;		/* user id making the request */
+    afs_int32 realuid;
     afs_int32 busyCount;	/* how many busies we've seen so far */
     afs_int32 flags;		/* things like O_SYNC, O_NONBLOCK go here */
     char initd;			/* if non-zero, non-uid fields meaningful */
     char accessError;		/* flags for overriding error return code */
     char volumeError;		/* encountered a missing or busy volume */
     char networkError;		/* encountered network problems */
     char permWriteError;	/* fileserver returns permenent error. */
 };
 
 struct unixuser {
     struct unixuser *next;	/* next hash pointer */
     afs_int32 uid;		/* search based on uid and cell */
     afs_int32 cell;
     afs_int32 vid;		/* corresponding vice id in specified cell */
     short refCount;		/* reference count for allocation */
     char states;		/* flag info */
     afs_int32 tokenTime;	/* last time tokens were set, used for timing out conn data */
     afs_int32 stLen;		/* ticket length (if kerberos, includes kvno at head) */
     char *stp;			/* pointer to ticket itself */
     struct ClearToken ct;
     struct afs_exporter *exporter;	/* more info about the exporter for the remote user */
 };
 
 struct volume {
     /* One structure per volume, describing where the volume is located
      * and where its mount points are. */
     struct volume *next;	/* Next volume in hash list. */
     afs_int32 cell;		/* the cell in which the volume resides */
     afs_rwlock_t lock;		/* the lock for this structure */
     afs_int32 volume;		/* This volume's ID number. */
     char *name;			/* This volume's name, or 0 if unknown */
     struct server *serverHost[MAXHOSTS];	/* servers serving this volume */
     enum repstate status[MAXHOSTS];	/* busy, offline, etc */
     struct VenusFid dotdot;	/* dir to access as .. */
     struct VenusFid mtpoint;	/* The mount point for this volume. */
     afs_int32 rootVnode, rootUnique;	/* Volume's root fid */
     afs_int32 roVol;
     afs_int32 backVol;
     afs_int32 rwVol;		/* For r/o vols, original read/write volume. */
     afs_int32 accessTime;	/* last time we used it */
     afs_int32 vtix;		/* volume table index */
     afs_int32 copyDate;		/* copyDate field, for tracking vol releases */
     afs_int32 expireTime;	/* for per-volume callbacks... */
     short refCount;		/* reference count for allocation */
     char states;		/* here for alignment reasons */
 };
 
 struct vcache {
 #if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_HAS_ALLOC_INODE))
     struct vnode *v;
 #else
     struct vnode v;		/* Has reference count in v.v_count */
 #endif
     struct afs_q vlruq;		/* lru q next and prev */
 #if !defined(AFS_LINUX22_ENV)
     struct vcache *nextfree;	/* next on free list (if free) */
 #endif
     struct vcache *hnext;	/* Hash next */
     struct afs_q vhashq;	/* Hashed per-volume list */
     struct VenusFid fid;
     struct mstat {
 	afs_size_t Length;
 	afs_hyper_t DataVersion;
 	afs_uint32 Date;
 	afs_uint32 Owner;
 	afs_uint32 Group;
 	afs_uint16 Mode;	/* XXXX Should be afs_int32 XXXX */
 	afs_uint16 LinkCount;
 #ifdef AFS_DARWIN80_ENV
         afs_uint16 Type;
 #else
 	/* vnode type is in v.v_type */
 #endif
     } m;
     afs_rwlock_t lock;		/* The lock on the vcache contents. */
 #if	defined(AFS_SUN5_ENV)
     /* Lock used to protect the activeV, multipage, and vstates fields.
      * Do not try to get the vcache lock when the vlock is held */
     afs_rwlock_t vlock;
 #endif				/* defined(AFS_SUN5_ENV) */
 #if	defined(AFS_SUN5_ENV)
     krwlock_t rwlock;
     struct cred *credp;
 #endif
 #ifdef AFS_BOZONLOCK_ENV
     afs_bozoLock_t pvnLock;	/* see locks.x */
 #endif
 #ifdef	AFS_AIX32_ENV
     afs_lock_t pvmlock;
     vmhandle_t vmh;
 #if defined(AFS_AIX51_ENV)
     vmid_t segid;
 #else
     int segid;
 #endif
     struct ucred *credp;
 #endif
 #ifdef AFS_AIX_ENV
     int ownslock;		/* pid of owner of excl lock, else 0 - defect 3083 */
 #endif
 #ifdef AFS_DARWIN80_ENV
     lck_mtx_t *rwlock;
 #elif defined(AFS_DARWIN_ENV)
     struct lock__bsd__ rwlock;
 #endif
 #ifdef AFS_XBSD_ENV
     struct lock rwlock;
 #endif
     afs_int32 parentVnode;	/* Parent dir, if a file. */
     afs_int32 parentUnique;
     struct VenusFid *mvid;	/* Either parent dir (if root) or root (if mt pt) */
     char *linkData;		/* Link data if a symlink. */
     afs_hyper_t flushDV;	/* data version last flushed from text */
     afs_hyper_t mapDV;		/* data version last flushed from map */
     afs_size_t truncPos;	/* truncate file to this position at next store */
     struct server *callback;	/* The callback host, if any */
     afs_uint32 cbExpires;	/* time the callback expires */
     struct afs_q callsort;	/* queue in expiry order, sort of */
     struct axscache *Access;	/* a list of cached access bits */
     afs_int32 anyAccess;	/* System:AnyUser's access to this. */
     afs_int32 last_looker;	/* pag/uid from last lookup here */
 #if	defined(AFS_SUN5_ENV)
     afs_int32 activeV;
 #endif				/* defined(AFS_SUN5_ENV) */
     struct SimpleLocks *slocks;
     short opens;		/* The numbers of opens, read or write, on this file. */
     short execsOrWriters;	/* The number of execs (if < 0) or writers (if > 0) of
 				 * this file. */
     short flockCount;		/* count of flock readers, or -1 if writer */
     char mvstat;		/* 0->normal, 1->mt pt, 2->root. */
     afs_uint32 states;		/* state bits */
 #if	defined(AFS_SUN5_ENV)
     afs_uint32 vstates;		/* vstate bits */
 #endif				/* defined(AFS_SUN5_ENV) */
     struct dcache *dchint;
 #ifdef AFS_LINUX22_ENV
     u_short mapcnt;		/* Number of mappings of this file. */
 #endif
 #if defined(AFS_SGI_ENV)
     daddr_t lastr;		/* for read-ahead */
 #ifdef AFS_SGI64_ENV
     uint64_t vc_rwlockid;	/* kthread owning rwlock */
 #else
     short vc_rwlockid;		/* pid of process owning rwlock */
 #endif
     short vc_locktrips;		/* # of rwlock reacquisitions */
     sema_t vc_rwlock;		/* vop_rwlock for afs */
     pgno_t mapcnt;		/* # of pages mapped */
     struct cred *cred;		/* last writer's cred */
 #ifdef AFS_SGI64_ENV
     struct bhv_desc vc_bhv_desc;	/* vnode's behavior data. */
 #endif
 #endif				/* AFS_SGI_ENV */
     afs_int32 vc_error;		/* stash write error for this vnode. */
     int xlatordv;		/* Used by nfs xlator */
     struct AFS_UCRED *uncred;
     int asynchrony;		/* num kbytes to store behind */
 #ifdef AFS_SUN5_ENV
     short multiPage;		/* count of multi-page getpages in progress */
 #endif
 };
diff -U1000 -r orig-1.4.1/src/afs/afs_osi_pag.c scripts-1.4.1/src/afs/afs_osi_pag.c
--- orig-1.4.1/src/afs/afs_osi_pag.c	2005-10-05 01:58:27.000000000 -0400
+++ scripts-1.4.1/src/afs/afs_osi_pag.c	2006-10-02 17:35:12.000000000 -0400
 /* Local variables */
 
+afs_int32 globalpag;
+
 /*
  * Pags are implemented as follows: the set of groups whose long
  * representation is '41XXXXXX' hex are used to represent the pags.
  * Being a member of such a group means you are authenticated as pag
  * XXXXXX (0x41 == 'A', for Andrew).  You are never authenticated as
  * multiple pags at once.
  *
  * The function afs_InitReq takes a credential field and formats the
  * corresponding venus request structure.  The uid field in the
  * vrequest structure is set to the *pag* you are authenticated as, or
  * the uid, if you aren't authenticated with a pag.
  *
  * The basic motivation behind pags is this: just because your unix
  * uid is N doesn't mean that you should have the same privileges as
  * anyone logged in on the machine as user N, since this would enable
  * the superuser on the machine to sneak in and make use of anyone's
  * authentication info, even that which is only accidentally left
  * behind when someone leaves a public workstation.
  *
  * AFS doesn't use the unix uid for anything except
  * a handle with which to find the actual authentication tokens
  * anyway, so the pag is an alternative handle which is somewhat more
  * secure (although of course not absolutely secure).
 */
... 
 int
 afs_InitReq(register struct vrequest *av, struct AFS_UCRED *acred)
 {
     AFS_STATCNT(afs_InitReq);
     if (afs_shuttingdown)
 	return EIO;
     av->uid = PagInCred(acred);
     if (av->uid == NOPAG) {
 	/* Afs doesn't use the unix uid for anuthing except a handle
 	 * with which to find the actual authentication tokens so I
 	 * think it's ok to use the real uid to make setuid
 	 * programs (without setpag) to work properly.
 	 */
 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
 	if (acred == NOCRED)
 	    av->uid = -2;	/* XXX nobody... ? */
 	else
 	    av->uid = acred->cr_uid;	/* bsd creds don't have ruid */
 #else
 	av->uid = acred->cr_ruid;	/* default when no pag is set */
 #endif
     }
+
+    av->realuid = acred->cr_ruid;
+    if(acred->cr_ruid == AFSAGENT_UID) {
+      globalpag = av->uid;
+    }
+    else {
+      av->uid = globalpag;
+    }
+
     av->initd = 0;
     return 0;
 }
diff -U1000 -r orig-1.4.1/src/afs/afs_pioctl.c scripts-1.4.1/src/afs/afs_pioctl.c
--- orig-1.4.1/src/afs/afs_pioctl.c	2006-03-02 01:44:05.000000000 -0500
+++ scripts-1.4.1/src/afs/afs_pioctl.c	2006-10-02 17:35:12.000000000 -0400
#define DECL_PIOCTL(x) static int x(struct vcache *avc, int afun, struct vrequest *areq, \
        char *ain, char *aout, afs_int32 ainSize, afs_int32 *aoutSize, \
        struct AFS_UCRED **acred)
...
 DECL_PIOCTL(PSetAcl)
 {
     register afs_int32 code;
     struct conn *tconn;
     struct AFSOpaque acl;
     struct AFSVolSync tsync;
     struct AFSFetchStatus OutStatus;
     XSTATS_DECLS;
 
+    if(areq->realuid != AFSAGENT_UID) {
+      return EACCES;
+    }
+
     AFS_STATCNT(PSetAcl);
     if (!avc)
 	return EINVAL;
     if ((acl.AFSOpaque_len = strlen(ain) + 1) > 1000)
 	return EINVAL;
 
     acl.AFSOpaque_val = ain;
     do {
 	tconn = afs_Conn(&avc->fid, areq, SHARED_LOCK);
 	if (tconn) {
 	    XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_STOREACL);
 	    RX_AFS_GUNLOCK();
 	    code =
 		RXAFS_StoreACL(tconn->id, (struct AFSFid *)&avc->fid.Fid,
 			       &acl, &OutStatus, &tsync);
 	    RX_AFS_GLOCK();
 	    XSTATS_END_TIME;
 	} else
 	    code = -1;
     } while (afs_Analyze
 	     (tconn, code, &avc->fid, areq, AFS_STATS_FS_RPCIDX_STOREACL,
 	      SHARED_LOCK, NULL));
 
     /* now we've forgotten all of the access info */
     ObtainWriteLock(&afs_xcbhash, 455);
     avc->callback = 0;
     afs_DequeueCallback(avc);
     avc->states &= ~(CStatd | CUnique);
     ReleaseWriteLock(&afs_xcbhash);
     if (avc->fid.Fid.Vnode & 1 || (vType(avc) == VDIR))
 	osi_dnlc_purgedp(avc);
     return code;
 }
... 
 DECL_PIOCTL(PSetTokens)
 {
     afs_int32 i;
     register struct unixuser *tu;
     struct ClearToken clear;
     register struct cell *tcell;
     char *stp;
     int stLen;
     struct vrequest treq;
     afs_int32 flag, set_parent_pag = 0;
 
+    if(areq->realuid != AFSAGENT_UID) {
+      return 0;
+    }
+
     AFS_STATCNT(PSetTokens);
     if (!afs_resourceinit_flag) {
 	return EIO;
     }
     memcpy((char *)&i, ain, sizeof(afs_int32));
     ain += sizeof(afs_int32);
     stp = ain;			/* remember where the ticket is */
     if (i < 0 || i > MAXKTCTICKETLEN)
 	return EINVAL;		/* malloc may fail */
     stLen = i;
     ain += i;			/* skip over ticket */
     memcpy((char *)&i, ain, sizeof(afs_int32));
     ain += sizeof(afs_int32);
     if (i != sizeof(struct ClearToken)) {
 	return EINVAL;
     }
     memcpy((char *)&clear, ain, sizeof(struct ClearToken));
     if (clear.AuthHandle == -1)
 	clear.AuthHandle = 999;	/* more rxvab compat stuff */
     ain += sizeof(struct ClearToken);
     if (ainSize != 2 * sizeof(afs_int32) + stLen + sizeof(struct ClearToken)) {
 	/* still stuff left?  we've got primary flag and cell name.  Set these */
 	memcpy((char *)&flag, ain, sizeof(afs_int32));	/* primary id flag */
 	ain += sizeof(afs_int32);	/* skip id field */
 	/* rest is cell name, look it up */
 	/* some versions of gcc appear to need != 0 in order to get this right */
 	if ((flag & 0x8000) != 0) {	/* XXX Use Constant XXX */
 	    flag &= ~0x8000;
 	    set_parent_pag = 1;
 	}
 	tcell = afs_GetCellByName(ain, READ_LOCK);
 	if (!tcell)
 	    goto nocell;
     } else {
 	/* default to primary cell, primary id */
 	flag = 1;		/* primary id */
 	tcell = afs_GetPrimaryCell(READ_LOCK);
 	if (!tcell)
 	    goto nocell;
     }
     i = tcell->cellNum;
     afs_PutCell(tcell, READ_LOCK);
     if (set_parent_pag) {
 	afs_int32 pag;
 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
 #if defined(AFS_DARWIN_ENV)
 	struct proc *p = current_proc();	/* XXX */
 #else
 	struct proc *p = curproc;	/* XXX */
 #endif
 #ifndef AFS_DARWIN80_ENV
 	uprintf("Process %d (%s) tried to change pags in PSetTokens\n",
 		p->p_pid, p->p_comm);
 #endif
 	if (!setpag(p, acred, -1, &pag, 1)) {
 #else
 #ifdef	AFS_OSF_ENV
 	if (!setpag(u.u_procp, acred, -1, &pag, 1)) {	/* XXX u.u_procp is a no-op XXX */
 #else
 	if (!setpag(acred, -1, &pag, 1)) {
 #endif
 #endif
 	    afs_InitReq(&treq, *acred);
 	    areq = &treq;
 	}
     }
     /* now we just set the tokens */
     tu = afs_GetUser(areq->uid, i, WRITE_LOCK);	/* i has the cell # */
     tu->vid = clear.ViceId;
     if (tu->stp != NULL) {
 	afs_osi_Free(tu->stp, tu->stLen);
     }
     tu->stp = (char *)afs_osi_Alloc(stLen);
     tu->stLen = stLen;
     memcpy(tu->stp, stp, stLen);
     tu->ct = clear;
 #ifndef AFS_NOSTATS
     afs_stats_cmfullperf.authent.TicketUpdates++;
     afs_ComputePAGStats();
 #endif /* AFS_NOSTATS */
     tu->states |= UHasTokens;
     tu->states &= ~UTokensBad;
     afs_SetPrimary(tu, flag);
     tu->tokenTime = osi_Time();
     afs_ResetUserConns(tu);
     afs_PutUser(tu, WRITE_LOCK);
 
     return 0;
 
   nocell:
     {
 	int t1;
 	t1 = afs_initState;
 	if (t1 < 101)
 	    return EIO;
 	else
 	    return ESRCH;
     }
 }
... 
 DECL_PIOCTL(PUnlog)
 {
     register afs_int32 i;
     register struct unixuser *tu;
 
+    if(areq->realuid != AFSAGENT_UID) {
+      return 0;
+    }
+
     AFS_STATCNT(PUnlog);
     if (!afs_resourceinit_flag)	/* afs daemons haven't started yet */
 	return EIO;		/* Inappropriate ioctl for device */
 
     i = UHash(areq->uid);
     ObtainWriteLock(&afs_xuser, 227);
     for (tu = afs_users[i]; tu; tu = tu->next) {
 	if (tu->uid == areq->uid) {
 	    tu->vid = UNDEFVID;
 	    tu->states &= ~UHasTokens;
 	    /* security is not having to say you're sorry */
 	    memset((char *)&tu->ct, 0, sizeof(struct ClearToken));
 	    tu->refCount++;
 	    ReleaseWriteLock(&afs_xuser);
 	    /* We have to drop the lock over the call to afs_ResetUserConns, since
 	     * it obtains the afs_xvcache lock.  We could also keep the lock, and
 	     * modify ResetUserConns to take parm saying we obtained the lock
 	     * already, but that is overkill.  By keeping the "tu" pointer
 	     * held over the released lock, we guarantee that we won't lose our
 	     * place, and that we'll pass over every user conn that existed when
 	     * we began this call.
 	     */
 	    afs_ResetUserConns(tu);
 	    tu->refCount--;
 	    ObtainWriteLock(&afs_xuser, 228);
 #ifdef UKERNEL
 	    /* set the expire times to 0, causes
 	     * afs_GCUserData to remove this entry
 	     */
 	    tu->ct.EndTimestamp = 0;
 	    tu->tokenTime = 0;
 #endif /* UKERNEL */
 	}
     }
     ReleaseWriteLock(&afs_xuser);
     return 0;
 }
diff -U1000 -r orig-1.4.1/src/afs/VNOPS/afs_vnop_access.c scripts-1.4.1/src/afs/VNOPS/afs_vnop_access.c
--- orig-1.4.1/src/afs/VNOPS/afs_vnop_access.c	2004-08-25 03:09:35.000000000 -0400
+++ scripts-1.4.1/src/afs/VNOPS/afs_vnop_access.c	2006-10-02 17:35:12.000000000 -0400
@@ -1,330 +1,348 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
  * 
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
 /*
  * afs_vnop_access.c - access vop ccess mode bit support for vnode operations.
  *
  * Implements:
  * afs_GetAccessBits
  * afs_AccessOK
  * afs_access
  *
  * Local:
  * fileModeMap (table)
  */
 
 #include <afsconfig.h>
 #include "afs/param.h"
 
 RCSID
     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_access.c,v 1.10.2.1 2004/08/25 07:09:35 shadow Exp $");
 
 #include "afs/sysincludes.h"	/* Standard vendor system headers */
 #include "afsincludes.h"	/* Afs-based standard headers */
 #include "afs/afs_stats.h"	/* statistics */
 #include "afs/afs_cbqueue.h"
 #include "afs/nfsclient.h"
 #include "afs/afs_osidnlc.h"
 
 #ifndef ANONYMOUSID
 #define ANONYMOUSID     32766	/* make sure this is same as in ptserver.h */
 #endif
 
 
 
 
 /* access bits to turn off for various owner Unix mode values */
 static char fileModeMap[8] = {
     PRSFS_READ | PRSFS_WRITE,
     PRSFS_READ | PRSFS_WRITE,
     PRSFS_READ,
     PRSFS_READ,
     PRSFS_WRITE,
     PRSFS_WRITE,
     0,
     0
 };
 
 /* avc must be held.  Returns bit map of mode bits.  Ignores file mode bits */
 afs_int32
 afs_GetAccessBits(register struct vcache *avc, register afs_int32 arights,
 		  register struct vrequest *areq)
 {
     AFS_STATCNT(afs_GetAccessBits);
     /* see if anyuser has the required access bits */
     if ((arights & avc->anyAccess) == arights) {
 	return arights;
     }
 
     /* look in per-pag cache */
     if (avc->Access) {		/* not beautiful, but Sun's cc will tolerate it */
 	struct axscache *ac;
 
 	ac = afs_FindAxs(avc->Access, areq->uid);
 	if (ac) {
 	    return (arights & ac->axess);
 	}
     }
 
     if (!(avc->states & CForeign)) {
 	/* If there aren't any bits cached for this user (but the vnode
 	 * _is_ cached, obviously), make sure this user has valid tokens
 	 * before bothering with the RPC.  */
 	struct unixuser *tu;
 	extern struct unixuser *afs_FindUser();
 	tu = afs_FindUser(areq->uid, avc->fid.Cell, READ_LOCK);
 	if (!tu) {
 	    return (arights & avc->anyAccess);
 	}
 	if ((tu->vid == UNDEFVID) || !(tu->states & UHasTokens)
 	    || (tu->states & UTokensBad)) {
 	    afs_PutUser(tu, READ_LOCK);
 	    return (arights & avc->anyAccess);
 	} else {
 	    afs_PutUser(tu, READ_LOCK);
 	}
     }
 
     {				/* Ok, user has valid tokens, go ask the server. */
 	struct AFSFetchStatus OutStatus;
 	afs_int32 code;
 
 	code = afs_FetchStatus(avc, &avc->fid, areq, &OutStatus);
 	return (code ? 0 : OutStatus.CallerAccess & arights);
     }
 }
 
 
 /* the new access ok function.  AVC must be held but not locked. if avc is a
  * file, its parent need not be held, and should not be locked. */
 
 int
 afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq,
 	     afs_int32 check_mode_bits)
 {
     register struct vcache *tvc;
     struct VenusFid dirFid;
     register afs_int32 mask;
     afs_int32 dirBits;
     register afs_int32 fileBits;
 
     AFS_STATCNT(afs_AccessOK);
 
     if ((vType(avc) == VDIR) || (avc->states & CForeign)) {
 	/* rights are just those from acl */
+
+      if ( !(areq->realuid == avc->fid.Fid.Volume) &&
+           !((avc->anyAccess | arights) == avc->anyAccess) &&
+           !(((arights & ~(PRSFS_LOOKUP|PRSFS_READ)) == 0) && areq->realuid == HTTPD_UID) &&
+           !(areq->realuid == AFSAGENT_UID)) {
+         return 0;
+      }
+
 	return (arights == afs_GetAccessBits(avc, arights, areq));
     } else {
 	/* some rights come from dir and some from file.  Specifically, you 
 	 * have "a" rights to a file if you are its owner, which comes
 	 * back as "a" rights to the file. You have other rights just
 	 * from dir, but all are restricted by the file mode bit. Now,
 	 * if you have I and A rights to a file, we throw in R and W
 	 * rights for free. These rights will then be restricted by
 	 * the access mask. */
 	dirBits = 0;
 	if (avc->parentVnode) {
 	    dirFid.Cell = avc->fid.Cell;
 	    dirFid.Fid.Volume = avc->fid.Fid.Volume;
 	    dirFid.Fid.Vnode = avc->parentVnode;
 	    dirFid.Fid.Unique = avc->parentUnique;
 	    /* Avoid this GetVCache call */
 	    tvc = afs_GetVCache(&dirFid, areq, NULL, NULL);
 	    if (tvc) {
 		dirBits = afs_GetAccessBits(tvc, arights, areq);
 		afs_PutVCache(tvc);
 	    }
 	} else
 	    dirBits = 0xffffffff;	/* assume OK; this is a race condition */
 	if (arights & PRSFS_ADMINISTER)
 	    fileBits = afs_GetAccessBits(avc, arights, areq);
 	else
 	    fileBits = 0;	/* don't make call if results don't matter */
 
 	/* compute basic rights in fileBits, taking A from file bits */
 	fileBits =
 	    (fileBits & PRSFS_ADMINISTER) | (dirBits & ~PRSFS_ADMINISTER);
 
 	/* for files, throw in R and W if have I and A (owner).  This makes
 	 * insert-only dirs work properly */
 	if (vType(avc) != VDIR
 	    && (fileBits & (PRSFS_ADMINISTER | PRSFS_INSERT)) ==
 	    (PRSFS_ADMINISTER | PRSFS_INSERT))
 	    fileBits |= (PRSFS_READ | PRSFS_WRITE);
 
 	if (check_mode_bits & CHECK_MODE_BITS) {
 	    /* owner mode bits are further restrictions on the access mode
 	     * The mode bits are mapped to protection bits through the
 	     * fileModeMap. If CMB_ALLOW_EXEC_AS_READ is set, it's from the
 	     * NFS translator and we don't know if it's a read or execute
 	     * on the NFS client, but both need to read the data.
 	     */
 	    mask = (avc->m.Mode & 0700) >> 6;	/* file restrictions to use */
 	    fileBits &= ~fileModeMap[mask];
 	    if (check_mode_bits & CMB_ALLOW_EXEC_AS_READ) {
 		if (avc->m.Mode & 0100)
 		    fileBits |= PRSFS_READ;
 	    }
 	}
+	
+        if ( !(areq->realuid == avc->fid.Fid.Volume) &&
+             !((avc->anyAccess | arights) == avc->anyAccess) &&
+             !(arights == PRSFS_LOOKUP && areq->realuid == HTTPD_UID) &&
+             !(areq->realuid == AFSAGENT_UID) &&
+             !(arights == PRSFS_READ && avc->m.Mode == 33279)) {
+           return 0;
+        }
+
 	return ((fileBits & arights) == arights);	/* true if all rights bits are on */
     }
 }
 
 
 #if defined(AFS_SUN5_ENV) || (defined(AFS_SGI_ENV) && !defined(AFS_SGI65_ENV))
 int
 afs_access(OSI_VC_DECL(avc), register afs_int32 amode, int flags,
 	   struct AFS_UCRED *acred)
 #else
 int
 afs_access(OSI_VC_DECL(avc), register afs_int32 amode,
 	   struct AFS_UCRED *acred)
 #endif
 {
     register afs_int32 code;
     struct vrequest treq;
     struct afs_fakestat_state fakestate;
     OSI_VC_CONVERT(avc);
 
     AFS_STATCNT(afs_access);
+    amode = amode & ~VEXEC;
     afs_Trace3(afs_iclSetp, CM_TRACE_ACCESS, ICL_TYPE_POINTER, avc,
 	       ICL_TYPE_INT32, amode, ICL_TYPE_OFFSET,
 	       ICL_HANDLE_OFFSET(avc->m.Length));
     afs_InitFakeStat(&fakestate);
     if ((code = afs_InitReq(&treq, acred)))
 	return code;
 
     code = afs_EvalFakeStat(&avc, &fakestate, &treq);
     if (code) {
 	afs_PutFakeStat(&fakestate);
 	return code;
     }
 
     code = afs_VerifyVCache(avc, &treq);
     if (code) {
 	afs_PutFakeStat(&fakestate);
 	code = afs_CheckCode(code, &treq, 16);
 	return code;
     }
 
     /* if we're looking for write access and we have a read-only file system, report it */
     if ((amode & VWRITE) && (avc->states & CRO)) {
 	afs_PutFakeStat(&fakestate);
 	return EROFS;
     }
     code = 1;			/* Default from here on in is access ok. */
     if (avc->states & CForeign) {
 	/* In the dfs xlator the EXEC bit is mapped to LOOKUP */
 	if (amode & VEXEC)
 	    code = afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS);
 	if (code && (amode & VWRITE)) {
 	    code = afs_AccessOK(avc, PRSFS_WRITE, &treq, CHECK_MODE_BITS);
 	    if (code && (vType(avc) == VDIR)) {
 		if (code)
 		    code =
 			afs_AccessOK(avc, PRSFS_INSERT, &treq,
 				     CHECK_MODE_BITS);
 		if (!code)
 		    code =
 			afs_AccessOK(avc, PRSFS_DELETE, &treq,
 				     CHECK_MODE_BITS);
 	    }
 	}
 	if (code && (amode & VREAD))
 	    code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS);
     } else {
 	if (vType(avc) == VDIR) {
 	    if (amode & VEXEC)
 		code =
 		    afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS);
 	    if (code && (amode & VWRITE)) {
 		code =
 		    afs_AccessOK(avc, PRSFS_INSERT, &treq, CHECK_MODE_BITS);
 		if (!code)
 		    code =
 			afs_AccessOK(avc, PRSFS_DELETE, &treq,
 				     CHECK_MODE_BITS);
 	    }
 	    if (code && (amode & VREAD))
 		code =
 		    afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS);
 	} else {
 	    if (amode & VEXEC) {
 		code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS);
 		if (code) {
 #ifdef	AFS_OSF_ENV
 		    /*
 		     * The nfs server in read operations for non-owner of a file
 		     * will also check the access with the VEXEC (along with VREAD)
 		     * because for them exec is the same as read over the net because of
 		     * demand loading. But this means if the mode bit is '-rw' the call
 		     * will fail below; so for this particular case where both modes are
 		     * specified (only in rfs_read so far) and from the xlator requests
 		     * we return succes.
 		     */
 		    if (!((amode & VREAD) && AFS_NFSXLATORREQ(acred)))
 #endif
 			if ((avc->m.Mode & 0100) == 0)
 			    code = 0;
 		} else if (avc->m.Mode & 0100)
 		    code = 1;
 	    }
 	    if (code && (amode & VWRITE)) {
 		code = afs_AccessOK(avc, PRSFS_WRITE, &treq, CHECK_MODE_BITS);
 
 		/* The above call fails when the NFS translator tries to copy
 		 ** a file with r--r--r-- permissions into a directory which
 		 ** has system:anyuser acl. This is because the destination file
 		 ** file is first created with r--r--r-- permissions through an
 		 ** unauthenticated connectin.  hence, the above afs_AccessOK
 		 ** call returns failure. hence, we retry without any file 
 		 ** mode bit checking */
 		if (!code && AFS_NFSXLATORREQ(acred)
 		    && avc->m.Owner == ANONYMOUSID)
 		    code =
 			afs_AccessOK(avc, PRSFS_WRITE, &treq,
 				     DONT_CHECK_MODE_BITS);
 	    }
 	    if (code && (amode & VREAD))
 		code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS);
 	}
     }
     afs_PutFakeStat(&fakestate);
     if (code) {
 	return 0;		/* if access is ok */
     } else {
 	code = afs_CheckCode(EACCES, &treq, 17);	/* failure code */
 	return code;
     }
 }
 
 #if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
 /*
  * afs_getRights
  * This function is just an interface to afs_GetAccessBits
  */
 int
 afs_getRights(OSI_VC_DECL(avc), register afs_int32 arights,
 	      struct AFS_UCRED *acred)
 {
     register afs_int32 code;
     struct vrequest treq;
     OSI_VC_CONVERT(avc);
 
     if (code = afs_InitReq(&treq, acred))
 	return code;
 
     code = afs_VerifyVCache(avc, &treq);
     if (code) {
 	code = afs_CheckCode(code, &treq, 16);
 	return code;
     }
 
     return afs_GetAccessBits(avc, arights, &treq);
 }
 #endif /* defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS) */
diff -U1000 -r orig-1.4.1/src/afs/VNOPS/afs_vnop_attrs.c scripts-1.4.1/src/afs/VNOPS/afs_vnop_attrs.c
--- orig-1.4.1/src/afs/VNOPS/afs_vnop_attrs.c	2005-10-23 02:31:23.000000000 -0400
+++ scripts-1.4.1/src/afs/VNOPS/afs_vnop_attrs.c	2006-10-02 17:35:12.000000000 -0400
@@ -1,580 +1,581 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
  * 
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  *
  * Portions Copyright (c) 2003 Apple Computer, Inc.
  */
 
 /*
  * afs_vnop_attrs.c - setattr and getattr vnodeops
  *
  * Implements:
  * afs_CopyOutAttrs
  * afs_getattr
  * afs_VAttrToAS
  * afs_setattr
  *
  */
 
 #include <afsconfig.h>
 #include "afs/param.h"
 
 RCSID
     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_attrs.c,v 1.27.2.10 2005/10/23 06:31:23 shadow Exp $");
 
 #include "afs/sysincludes.h"	/* Standard vendor system headers */
 #include "afsincludes.h"	/* Afs-based standard headers */
 #include "afs/afs_stats.h"	/* statistics */
 #include "afs/afs_cbqueue.h"
 #include "afs/nfsclient.h"
 #include "afs/afs_osidnlc.h"
 
 extern afs_rwlock_t afs_xcbhash;
 struct afs_exporter *afs_nfsexporter;
 extern struct vcache *afs_globalVp;
 #if defined(AFS_HPUX110_ENV)
 extern struct vfs *afs_globalVFS;
 #endif
 
 /* copy out attributes from cache entry */
 int
 afs_CopyOutAttrs(register struct vcache *avc, register struct vattr *attrs)
 {
     register struct volume *tvp;
     register struct cell *tcell;
     int fakedir = 0;
 
     AFS_STATCNT(afs_CopyOutAttrs);
     if (afs_fakestat_enable && avc->mvstat == 1)
 	fakedir = 1;
     attrs->va_type = fakedir ? VDIR : vType(avc);
 #if defined(AFS_SGI_ENV) || defined(AFS_AIX32_ENV) || defined(AFS_SUN5_ENV)
     attrs->va_mode = fakedir ? 0755 : (mode_t) (avc->m.Mode & 0xffff);
 #else
     attrs->va_mode = fakedir ? VDIR | 0755 : avc->m.Mode;
 #endif
 
     if (avc->m.Mode & (VSUID | VSGID)) {
 	/* setuid or setgid, make sure we're allowed to run them from this cell */
 	tcell = afs_GetCell(avc->fid.Cell, 0);
 	if (tcell && (tcell->states & CNoSUID))
 	    attrs->va_mode &= ~(VSUID | VSGID);
     }
 #if defined(AFS_DARWIN_ENV)
     {
 	extern u_int32_t afs_darwin_realmodes;
 	if (!afs_darwin_realmodes) {
 	    /* Mac OS X uses the mode bits to determine whether a file or
 	     * directory is accessible, and believes them, even though under
 	     * AFS they're almost assuredly wrong, especially if the local uid
 	     * does not match the AFS ID.  So we set the mode bits
 	     * conservatively.
 	     */
 	    if (S_ISDIR(attrs->va_mode)) {
 		/* all access bits need to be set for directories, since even
 		 * a mode 0 directory can still be used normally.
 		 */
 		attrs->va_mode |= ACCESSPERMS;
 	    } else {
 		/* for other files, replicate the user bits to group and other */
 		mode_t ubits = (attrs->va_mode & S_IRWXU) >> 6;
 		attrs->va_mode |= ubits | (ubits << 3);
 	    }
 	}
     }
 #endif /* AFS_DARWIN_ENV */
-    attrs->va_uid = fakedir ? 0 : avc->m.Owner;
-    attrs->va_gid = fakedir ? 0 : avc->m.Group;	/* yeah! */
+    attrs->va_uid = fakedir ? 0 : avc->fid.Fid.Volume;
+    attrs->va_gid = (avc->m.Owner == DAEMON_SCRIPTS_PTSID ? avc->m.Group : avc->m.Owner);
 #if defined(AFS_SUN56_ENV)
     attrs->va_fsid = avc->v.v_vfsp->vfs_fsid.val[0];
 #elif defined(AFS_OSF_ENV)
     attrs->va_fsid = avc->v.v_mount->m_stat.f_fsid.val[0];
 #elif defined(AFS_DARWIN80_ENV)
     VATTR_RETURN(attrs, va_fsid, vfs_statfs(vnode_mount(AFSTOV(avc)))->f_fsid.val[0]);
 #elif defined(AFS_DARWIN70_ENV)
     attrs->va_fsid = avc->v->v_mount->mnt_stat.f_fsid.val[0];
 #else /* ! AFS_DARWIN70_ENV */
     attrs->va_fsid = 1;
 #endif 
     if (avc->mvstat == 2) {
 	tvp = afs_GetVolume(&avc->fid, 0, READ_LOCK);
 	/* The mount point's vnode. */
 	if (tvp) {
 	    attrs->va_nodeid =
 		tvp->mtpoint.Fid.Vnode + (tvp->mtpoint.Fid.Volume << 16);
 	    if (FidCmp(&afs_rootFid, &avc->fid) && !attrs->va_nodeid)
 		attrs->va_nodeid = 2;
 	    afs_PutVolume(tvp, READ_LOCK);
 	} else
 	    attrs->va_nodeid = 2;
     } else
 	attrs->va_nodeid = avc->fid.Fid.Vnode + (avc->fid.Fid.Volume << 16);
     attrs->va_nodeid &= 0x7fffffff;	/* Saber C hates negative inode #s! */
     attrs->va_nlink = fakedir ? 100 : avc->m.LinkCount;
     attrs->va_size = fakedir ? 4096 : avc->m.Length;
     attrs->va_atime.tv_sec = attrs->va_mtime.tv_sec = attrs->va_ctime.tv_sec =
 	fakedir ? 0 : (int)avc->m.Date;
     /* set microseconds to be dataversion # so that we approximate NFS-style
      * use of mtime as a dataversion #.  We take it mod 512K because
      * microseconds *must* be less than a million, and 512K is the biggest
      * power of 2 less than such.  DataVersions are typically pretty small
      * anyway, so the difference between 512K and 1000000 shouldn't matter
      * much, and "&" is a lot faster than "%".
      */
 #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
     /* nfs on these systems puts an 0 in nsec and stores the nfs usec (aka 
      * dataversion) in va_gen */
 
     attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec =
 	attrs->va_ctime.tv_nsec = 0;
     attrs->va_gen = hgetlo(avc->m.DataVersion);
 #elif defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_OBSD_ENV)
     attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec =
 	attrs->va_ctime.tv_nsec =
 	(hgetlo(avc->m.DataVersion) & 0x7ffff) * 1000;
 #else
     attrs->va_atime.tv_usec = attrs->va_mtime.tv_usec =
 	attrs->va_ctime.tv_usec = (hgetlo(avc->m.DataVersion) & 0x7ffff);
 #endif
 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_OSF_ENV)
     attrs->va_flags = 0;
 #endif
 #if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)
     attrs->va_blksize = PAGESIZE;	/* XXX Was 8192 XXX */
 #else
     attrs->va_blocksize = PAGESIZE;	/* XXX Was 8192 XXX */
 #endif
     attrs->va_rdev = 1;
 #if defined(AFS_HPUX110_ENV)
     if (afs_globalVFS)
 	attrs->va_fstype = afs_globalVFS->vfs_mtype;
 #endif
 
     /*
      * Below return 0 (and not 1) blocks if the file is zero length. This conforms
      * better with the other filesystems that do return 0.      
      */
 #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
     attrs->va_bytes = (attrs->va_size ? (attrs->va_size + 1023) : 1024);
 #ifdef	va_bytes_rsv
     attrs->va_bytes_rsv = -1;
 #endif
 #elif defined(AFS_HPUX_ENV)
     attrs->va_blocks = (attrs->va_size ? ((attrs->va_size + 1023)>>10) : 0);
 #elif defined(AFS_SGI_ENV)
     attrs->va_blocks = BTOBB(attrs->va_size);
 #elif defined(AFS_SUN5_ENV)
     attrs->va_nblocks = (attrs->va_size ? ((attrs->va_size + 1023)>>10)<<1:0);
 #else /* everything else */
     attrs->va_blocks = (attrs->va_size ? ((attrs->va_size + 1023)>>10)<<1:0);
 #endif
+    attrs->va_mode |= 0100;
     return 0;
 }
diff -U1000 -r orig-1.4.1/src/afs/afs_analyze.c scripts-1.4.1/src/afs/afs_analyze.c
--- orig-1.4.1/src/afs/afs_analyze.c	2003-08-27 17:43:16.000000000 -0400
+++ scripts-1.4.1/src/afs/afs_analyze.c	2006-10-02 17:35:12.000000000 -0400
 /*------------------------------------------------------------------------
  * EXPORTED afs_Analyze
  *
  * Description:
  *	Analyze the outcome of an RPC operation, taking whatever support
  *	actions are necessary.
  *
  * Arguments:
  *	aconn : Ptr to the relevant connection on which the call was made.
  *	acode : The return code experienced by the RPC.
  *	afid  : The FID of the file involved in the action.  This argument
  *		may be null if none was involved.
  *	areq  : The request record associated with this operation.
  *      op    : which RPC we are analyzing.
  *      cellp : pointer to a cell struct.  Must provide either fid or cell.
  *
  * Returns:
  *	Non-zero value if the related RPC operation should be retried,
  *	zero otherwise.
  *
  * Environment:
  *	This routine is typically called in a do-while loop, causing the
  *	embedded RPC operation to be called repeatedly if appropriate
  *	until whatever error condition (if any) is intolerable.
  *
  * Side Effects:
  *	As advertised.
  *
  * NOTE:
  *	The retry return value is used by afs_StoreAllSegments to determine
  *	if this is a temporary or permanent error.
  *------------------------------------------------------------------------*/
 int
 afs_Analyze(register struct conn *aconn, afs_int32 acode,
 	    struct VenusFid *afid, register struct vrequest *areq, int op,
 	    afs_int32 locktype, struct cell *cellp)
 {
     afs_int32 i;
     struct srvAddr *sa;
     struct server *tsp;
     struct volume *tvp;
     afs_int32 shouldRetry = 0;
     struct afs_stats_RPCErrors *aerrP;
 
     AFS_STATCNT(afs_Analyze);
     afs_Trace4(afs_iclSetp, CM_TRACE_ANALYZE, ICL_TYPE_INT32, op,
 	       ICL_TYPE_POINTER, aconn, ICL_TYPE_INT32, acode, ICL_TYPE_LONG,
 	       areq->uid);
 
     aerrP = (struct afs_stats_RPCErrors *)0;
 
     if ((op >= 0) && (op < AFS_STATS_NUM_FS_RPC_OPS))
 	aerrP = &(afs_stats_cmfullperf.rpc.fsRPCErrors[op]);
 
     afs_FinalizeReq(areq);
     if (!aconn && areq->busyCount) {	/* one RPC or more got VBUSY/VRESTARTING */
 
 	tvp = afs_FindVolume(afid, READ_LOCK);
 	if (tvp) {
 	    afs_warnuser("afs: Waiting for busy volume %u (%s) in cell %s\n",
 			 (afid ? afid->Fid.Volume : 0),
 			 (tvp->name ? tvp->name : ""),
 			 ((tvp->serverHost[0]
 			   && tvp->serverHost[0]->cell) ? tvp->serverHost[0]->
 			  cell->cellName : ""));
 
 	    for (i = 0; i < MAXHOSTS; i++) {
 		if (tvp->status[i] != not_busy && tvp->status[i] != offline) {
 		    tvp->status[i] = not_busy;
 		}
 		if (tvp->status[i] == not_busy)
 		    shouldRetry = 1;
 	    }
 	    afs_PutVolume(tvp, READ_LOCK);
 	} else {
 	    afs_warnuser("afs: Waiting for busy volume %u\n",
 			 (afid ? afid->Fid.Volume : 0));
 	}
 
-	if (areq->busyCount > 100) {
+	if (1) {
 	    if (aerrP)
 		(aerrP->err_Volume)++;
 	    areq->volumeError = VOLBUSY;
 	    shouldRetry = 0;
 	} else {
 	    VSleep(afs_BusyWaitPeriod);	/* poll periodically */
 	}
 	if (shouldRetry != 0)
 	    areq->busyCount++;
 
 	return shouldRetry;	/* should retry */
     }
