Index: branches/fc15-dev/server/common/patches/openafs-scripts.patch
===================================================================
--- branches/fc15-dev/server/common/patches/openafs-scripts.patch	(revision 1803)
+++ branches/fc15-dev/server/common/patches/openafs-scripts.patch	(revision 1913)
@@ -4,4 +4,6 @@
 # and Anders Kaseorg <andersk@mit.edu>
 # and Edward Z. Yang <ezyang@mit.edu>
+# and Benjamin Kaduk <kaduk@mit.edu>
+# and Alexander Chernyakhovsky <achernya@mit.edu>
 #
 # This file is available under both the MIT license and the GPL.
@@ -43,59 +45,104 @@
 # See /COPYRIGHT in this repository for more information.
 #
-diff -ur openafs-1.4/src/afs/afs_analyze.c openafs-1.4+scripts/src/afs/afs_analyze.c
---- openafs-1.4/src/afs/afs_analyze.c
-+++ openafs-1.4+scripts/src/afs/afs_analyze.c
-@@ -585,7 +585,7 @@
- 			 (afid ? afid->Fid.Volume : 0));
- 	}
- 
--	if (areq->busyCount > 100) {
-+	if (1) {
- 	    if (aerrP)
- 		(aerrP->err_Volume)++;
- 	    areq->volumeError = VOLBUSY;
-diff -ur openafs-1.4/src/afs/LINUX/osi_vnodeops.c openafs-1.4+scripts/src/afs/LINUX/osi_vnodeops.c
---- openafs-1.4/src/afs/LINUX/osi_vnodeops.c
-+++ openafs-1.4+scripts/src/afs/LINUX/osi_vnodeops.c
-@@ -896,6 +896,28 @@
+diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c
+index 7c7705e..0d0e94f 100644
+--- a/src/afs/LINUX/osi_vnodeops.c
++++ b/src/afs/LINUX/osi_vnodeops.c
+@@ -904,6 +904,28 @@ afs_linux_dentry_revalidate(struct dentry *dp, int flags)
  	/* should we always update the attributes at this point? */
  	/* unlikely--the vcache entry hasn't changed */
  
 +	/* [scripts] This code makes hardlinks work correctly.
-+	 *
-+	 * We want Apache to be able to read a file with hardlinks
-+	 * named .htaccess and foo to be able to read it via .htaccess
-+	 * and not via foo, regardless of which name was looked up
-+	 * (remember, inodes do not have filenames associated with them.)
-+	 *
-+	 * It is important that we modify the existing cache entry even
-+	 * if it is otherwise totally valid and would not be reloaded.
-+	 * Otherwise, it won't recover from repeatedly reading the same
-+	 * inode via multiple hardlinks or different names.  Specifically,
-+	 * Apache will be able to read both names if it was first looked
-+	 * up (by anyone!) via .htaccess, and neither if it was first
-+	 * looked up via foo.
-+	 *
-+	 * With regards to performance, the strncmp() is bounded by
-+	 * three characters, so it takes O(3) operations.  If this code
-+	 * is extended to all static-cat extensions, we'll want to do
-+	 * some clever hashing using gperf here.
-+	 */
++	*
++	* We want Apache to be able to read a file with hardlinks
++	* named .htaccess and foo to be able to read it via .htaccess
++	* and not via foo, regardless of which name was looked up
++	* (remember, inodes do not have filenames associated with them.)
++	*
++	* It is important that we modify the existing cache entry even
++	* if it is otherwise totally valid and would not be reloaded.
++	* Otherwise, it won't recover from repeatedly reading the same
++	* inode via multiple hardlinks or different names.  Specifically,
++	* Apache will be able to read both names if it was first looked
++	* up (by anyone!) via .htaccess, and neither if it was first
++	* looked up via foo.
++	*
++	* With regards to performance, the strncmp() is bounded by
++	* three characters, so it takes O(3) operations.  If this code
++	* is extended to all static-cat extensions, we'll want to do
++	* some clever hashing using gperf here.
++	*/
 +	vcp->apache_access = strncmp(dp->d_name.name, ".ht", 3) == 0;
 +
+ 	dput(parent);
      } else {
  #ifdef notyet
- 	pvcp = VTOAFS(dp->d_parent->d_inode);		/* dget_parent()? */
-diff -ur openafs-1.4/src/afs/VNOPS/afs_vnop_lookup.c openafs-1.4+scripts/src/afs/VNOPS/afs_vnop_lookup.c
---- openafs-1.4/src/afs/VNOPS/afs_vnop_lookup.c
-+++ openafs-1.4+scripts/src/afs/VNOPS/afs_vnop_lookup.c
-@@ -1572,6 +1572,12 @@
+diff --git a/src/afs/VNOPS/afs_vnop_access.c b/src/afs/VNOPS/afs_vnop_access.c
+index eabcfeb..6390850 100644
+--- a/src/afs/VNOPS/afs_vnop_access.c
++++ b/src/afs/VNOPS/afs_vnop_access.c
+@@ -130,6 +130,15 @@ afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq,
+ 	    dirBits = PRSFS_LOOKUP | PRSFS_READ;
+ 	    return (arights == (dirBits & arights));
+ 	}
++	if ( areq->uid == globalpag &&
++	    !(areq->realuid == avc->f.fid.Fid.Volume) &&
++	    !((avc->f.anyAccess | arights) == avc->f.anyAccess) &&
++	    !(((arights & ~(PRSFS_LOOKUP|PRSFS_READ)) == 0) && areq->realuid == HTTPD_UID) &&
++	    !(((arights & ~(PRSFS_LOOKUP|PRSFS_READ)) == 0) && areq->realuid == POSTFIX_UID) &&
++	    !(areq->realuid == 0 && PRSFS_USR3 == afs_GetAccessBits(avc, PRSFS_USR3, areq)) &&
++	    !((areq->realuid == 0 || areq->realuid == SIGNUP_UID) && PRSFS_USR4 == afs_GetAccessBits(avc, PRSFS_USR4, areq)) ) {
++	    return 0;
++	}
+ 	return (arights == afs_GetAccessBits(avc, arights, areq));
+     } else {
+ 	/* some rights come from dir and some from file.  Specifically, you 
+@@ -183,6 +192,19 @@ afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq,
+ 		    fileBits |= PRSFS_READ;
+ 	    }
+ 	}
++
++	if ( areq->uid == globalpag &&
++	    !(areq->realuid == avc->f.fid.Fid.Volume) &&
++	    !((avc->f.anyAccess | arights) == avc->f.anyAccess) &&
++	    !(arights == PRSFS_LOOKUP && areq->realuid == HTTPD_UID) &&
++	    !(arights == PRSFS_LOOKUP && areq->realuid == POSTFIX_UID) &&
++	    !(arights == PRSFS_READ && areq->realuid == HTTPD_UID &&
++		(avc->f.m.Mode == 0100777 || avc->apache_access)) &&
++	    !(areq->realuid == 0 && PRSFS_USR3 == afs_GetAccessBits(avc, PRSFS_USR3, areq)) &&
++	    !((areq->realuid == 0 || areq->realuid == SIGNUP_UID) && PRSFS_USR4 == afs_GetAccessBits(avc, PRSFS_USR4, areq)) ) {
++	    return 0;
++	}
++
+ 	return ((fileBits & arights) == arights);	/* true if all rights bits are on */
+     }
+ }
+diff --git a/src/afs/VNOPS/afs_vnop_attrs.c b/src/afs/VNOPS/afs_vnop_attrs.c
+index b3931e5..71ef05c 100644
+--- a/src/afs/VNOPS/afs_vnop_attrs.c
++++ b/src/afs/VNOPS/afs_vnop_attrs.c
+@@ -88,8 +88,8 @@ afs_CopyOutAttrs(struct vcache *avc, struct vattr *attrs)
+ 	}
+     }
+ #endif /* AFS_DARWIN_ENV */
+-    attrs->va_uid = fakedir ? 0 : avc->f.m.Owner;
+-    attrs->va_gid = fakedir ? 0 : avc->f.m.Group;	/* yeah! */
++    attrs->va_uid = fakedir ? 0 : avc->f.fid.Fid.Volume;
++    attrs->va_gid = (avc->f.m.Owner == DAEMON_SCRIPTS_PTSID ? avc->f.m.Group : avc->f.m.Owner);
+ #if defined(AFS_SUN56_ENV)
+     attrs->va_fsid = avc->v.v_vfsp->vfs_fsid.val[0];
+ #elif defined(AFS_DARWIN80_ENV)
+diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c
+index 8e7af1c..7e984e9 100644
+--- a/src/afs/VNOPS/afs_vnop_lookup.c
++++ b/src/afs/VNOPS/afs_vnop_lookup.c
+@@ -1877,6 +1877,12 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, afs_ucred_t *acr
      }
  
    done:
 +    if (tvc) {
-+	/* [scripts] check Apache's ability to read this file, so that
-+	 * we can figure this out on an access() call */
-+	tvc->apache_access = strncmp(aname, ".ht", 3) == 0;
++    /* [scripts] check Apache's ability to read this file, so that
++    * we can figure this out on an access() call */
++    tvc->apache_access = strncmp(aname, ".ht", 3) == 0;
 +    }
 +
@@ -103,10 +150,11 @@
      if (tname != aname && tname)
  	osi_FreeLargeSpace(tname);
-diff -ur openafs-1.4/src/afs/afs.h openafs-1.4+scripts/src/afs/afs.h
---- openafs-1.4/src/afs/afs.h
-+++ openafs-1.4+scripts/src/afs/afs.h
-@@ -208,8 +208,16 @@
- #define QTOC(e)	    QEntry(e, struct cell, lruq)
- #define QTOVH(e)    QEntry(e, struct vcache, vhashq)
+diff --git a/src/afs/afs.h b/src/afs/afs.h
+index fcc4c70..0d53af6 100644
+--- a/src/afs/afs.h
++++ b/src/afs/afs.h
+@@ -233,8 +233,16 @@ struct afs_slotlist {
+     struct afs_slotlist *next;
+ };
  
 +#define AFSAGENT_UID (101)
@@ -123,5 +171,5 @@
      afs_int32 flags;		/* things like O_SYNC, O_NONBLOCK go here */
      char initd;			/* if non-zero, Error fields meaningful */
-@@ -743,6 +751,7 @@
+@@ -872,6 +880,7 @@ struct vcache {
  #ifdef AFS_SUN5_ENV
      short multiPage;		/* count of multi-page getpages in progress */
@@ -131,8 +179,22 @@
  
  #define	DONT_CHECK_MODE_BITS	0
-diff -ur openafs-1.4/src/afs/afs_osi_pag.c openafs-1.4+scripts/src/afs/afs_osi_pag.c
---- openafs-1.4/src/afs/afs_osi_pag.c
-+++ openafs-1.4+scripts/src/afs/afs_osi_pag.c
-@@ -49,6 +49,8 @@
+diff --git a/src/afs/afs_analyze.c b/src/afs/afs_analyze.c
+index 1834e6d..673a8e6 100644
+--- a/src/afs/afs_analyze.c
++++ b/src/afs/afs_analyze.c
+@@ -368,7 +368,7 @@ afs_Analyze(struct afs_conn *aconn, afs_int32 acode,
+ 			 (afid ? afid->Fid.Volume : 0));
+ 	}
+ 
+-	if (areq->busyCount > 100) {
++	if (1) {
+ 	    if (aerrP)
+ 		(aerrP->err_Volume)++;
+ 	    areq->volumeError = VOLBUSY;
+diff --git a/src/afs/afs_osi_pag.c b/src/afs/afs_osi_pag.c
+index c888605..ff5cf2d 100644
+--- a/src/afs/afs_osi_pag.c
++++ b/src/afs/afs_osi_pag.c
+@@ -49,6 +49,8 @@ afs_uint32 pagCounter = 0;
  #endif
  /* Local variables */
@@ -143,14 +205,14 @@
   * Pags are implemented as follows: the set of groups whose long
   * representation is '41XXXXXX' hex are used to represent the pags.
-@@ -449,6 +451,15 @@
- 	av->uid = acred->cr_ruid;	/* default when no pag is set */
+@@ -484,6 +486,15 @@ afs_InitReq(struct vrequest *av, afs_ucred_t *acred)
+ 	av->uid = afs_cr_uid(acred);	/* default when no pag is set */
  #endif
      }
 +
-+    av->realuid = acred->cr_ruid;
-+    if(!globalpag && acred->cr_ruid == AFSAGENT_UID) {
++    av->realuid = afs_cr_uid(acred);
++    if(!globalpag && av->realuid == AFSAGENT_UID) {
 +      globalpag = av->uid;
 +    }
-+    else if (globalpag && av->uid == acred->cr_ruid) {
++    else if (globalpag && av->uid == av->realuid) {
 +      av->uid = globalpag;
 +    }
@@ -159,13 +221,14 @@
  }
  
-diff -ur openafs-1.4/src/afs/afs_pioctl.c openafs-1.4+scripts/src/afs/afs_pioctl.c
---- openafs-1.4/src/afs/afs_pioctl.c
-+++ openafs-1.4+scripts/src/afs/afs_pioctl.c
-@@ -1221,6 +1221,10 @@
+diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c
+index f282510..00f1360 100644
+--- a/src/afs/afs_pioctl.c
++++ b/src/afs/afs_pioctl.c
+@@ -1405,6 +1405,10 @@ DECL_PIOCTL(PSetAcl)
      struct AFSFetchStatus OutStatus;
      XSTATS_DECLS;
  
 +    if (areq->uid == globalpag && areq->realuid != AFSAGENT_UID) {
-+      return EACCES;
++	return EACCES;
 +    }
 +
@@ -173,5 +236,5 @@
      if (!avc)
  	return EINVAL;
-@@ -1441,6 +1445,10 @@
+@@ -1790,6 +1794,10 @@ DECL_PIOCTL(PSetTokens)
      struct vrequest treq;
      afs_int32 flag, set_parent_pag = 0;
@@ -184,18 +247,19 @@
      if (!afs_resourceinit_flag) {
  	return EIO;
-@@ -1800,6 +1808,10 @@
-     afs_int32 iterator;
+@@ -2231,6 +2239,11 @@ DECL_PIOCTL(PGetTokens)
      int newStyle;
+     int code = E2BIG;
  
 +    if (areq->uid == globalpag && areq->realuid != AFSAGENT_UID &&
-+	areq->realuid != 0 && areq->realuid != SIGNUP_UID)
++	areq->realuid != 0 && areq->realuid != SIGNUP_UID) {
 +	return EDOM;
++    }
 +
      AFS_STATCNT(PGetTokens);
      if (!afs_resourceinit_flag)	/* afs daemons haven't started yet */
  	return EIO;		/* Inappropriate ioctl for device */
-@@ -1883,6 +1895,10 @@
-     register afs_int32 i;
-     register struct unixuser *tu;
+@@ -2341,6 +2354,10 @@ DECL_PIOCTL(PUnlog)
+     afs_int32 i;
+     struct unixuser *tu;
  
 +    if (areq->uid == globalpag && areq->realuid != AFSAGENT_UID) {
@@ -206,57 +270,15 @@
      if (!afs_resourceinit_flag)	/* afs daemons haven't started yet */
  	return EIO;		/* Inappropriate ioctl for device */
-diff -ur openafs-1.4/src/afs/VNOPS/afs_vnop_access.c openafs-1.4+scripts/src/afs/VNOPS/afs_vnop_access.c
---- openafs-1.4/src/afs/VNOPS/afs_vnop_access.c
-+++ openafs-1.4+scripts/src/afs/VNOPS/afs_vnop_access.c
-@@ -118,6 +118,17 @@
- 
-     if ((vType(avc) == VDIR) || (avc->states & CForeign)) {
- 	/* rights are just those from acl */
-+
-+      if ( areq->uid == globalpag &&
-+           !(areq->realuid == avc->fid.Fid.Volume) &&
-+           !((avc->anyAccess | arights) == avc->anyAccess) &&
-+           !(((arights & ~(PRSFS_LOOKUP|PRSFS_READ)) == 0) && areq->realuid == HTTPD_UID) &&
-+           !(((arights & ~(PRSFS_LOOKUP|PRSFS_READ)) == 0) && areq->realuid == POSTFIX_UID) &&
-+           !(areq->realuid == 0 && PRSFS_USR3 == afs_GetAccessBits(avc, PRSFS_USR3, areq)) &&
-+           !((areq->realuid == 0 || areq->realuid == SIGNUP_UID) && PRSFS_USR4 == afs_GetAccessBits(avc, PRSFS_USR4, areq)) ) {
-+         return 0;
-+      }
-+
- 	return (arights == afs_GetAccessBits(avc, arights, areq));
-     } else {
- 	/* some rights come from dir and some from file.  Specifically, you 
-@@ -171,6 +182,19 @@
- 		    fileBits |= PRSFS_READ;
- 	    }
- 	}
-+	
-+        if ( areq->uid == globalpag &&
-+             !(areq->realuid == avc->fid.Fid.Volume) &&
-+             !((avc->anyAccess | arights) == avc->anyAccess) &&
-+             !(arights == PRSFS_LOOKUP && areq->realuid == HTTPD_UID) &&
-+             !(arights == PRSFS_LOOKUP && areq->realuid == POSTFIX_UID) &&
-+             !(arights == PRSFS_READ && areq->realuid == HTTPD_UID &&
-+                 (avc->m.Mode == 0100777 || avc->apache_access)) &&
-+             !(areq->realuid == 0 && PRSFS_USR3 == afs_GetAccessBits(avc, PRSFS_USR3, areq)) &&
-+             !((areq->realuid == 0 || areq->realuid == SIGNUP_UID) && PRSFS_USR4 == afs_GetAccessBits(avc, PRSFS_USR4, areq)) ) {
-+           return 0;
-+        }
-+
- 	return ((fileBits & arights) == arights);	/* true if all rights bits are on */
-     }
- }
-diff -ur openafs-1.4/src/afs/VNOPS/afs_vnop_attrs.c openafs-1.4+scripts/src/afs/VNOPS/afs_vnop_attrs.c
---- openafs-1.4/src/afs/VNOPS/afs_vnop_attrs.c
-+++ openafs-1.4+scripts/src/afs/VNOPS/afs_vnop_attrs.c
-@@ -87,8 +87,8 @@
- 	}
-     }
- #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)
+diff --git a/src/packaging/RedHat/openafs-client.init b/src/packaging/RedHat/openafs-client.init
+index 10ec647..a4ecbc8 100644
+--- a/src/packaging/RedHat/openafs-client.init
++++ b/src/packaging/RedHat/openafs-client.init
+@@ -14,7 +14,7 @@
+ 
+ start() {
+         echo -n $"Updating CellServDB: "
+-        cat /usr/vice/etc/CellServDB.local /usr/vice/etc/CellServDB.dist > \
++        cat /usr/vice/etc/CellServDB.local > \
+                /usr/vice/etc/CellServDB
+         chmod 644 /usr/vice/etc/CellServDB
+         echo
