source: trunk/server/common/patches/openafs-scripts.patch @ 1134

Last change on this file since 1134 was 1134, checked in by ezyang, 13 years ago
Update OpenAFS patch to not need 777 for .htaccess files. Symlinks to files that are not named .htaccess still need to be 777; if a file is hard linked, Apache can access it through its .htaccess name but not through any other name.
File size: 9.9 KB
RevLine 
[1]1# scripts.mit.edu openafs patch
2# Copyright (C) 2006  Jeff Arnold <jbarnold@mit.edu>
[259]3# with modifications by Joe Presbrey <presbrey@mit.edu>
[628]4# and Anders Kaseorg <andersk@mit.edu>
[1134]5# and Edward Z. Yang <ezyang@mit.edu>
[1]6#
[622]7# This file is available under both the MIT license and the GPL.
8#
9
10# Permission is hereby granted, free of charge, to any person obtaining a copy
11# of this software and associated documentation files (the "Software"), to deal
12# in the Software without restriction, including without limitation the rights
13# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14# copies of the Software, and to permit persons to whom the Software is
15# furnished to do so, subject to the following conditions:
16#
17# The above copyright notice and this permission notice shall be included in
18# all copies or substantial portions of the Software.
19#
20# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26# THE SOFTWARE.
27#
28
[1]29# This program is free software; you can redistribute it and/or
30# modify it under the terms of the GNU General Public License
31# as published by the Free Software Foundation; either version 2
32# of the License, or (at your option) any later version.
33#
34# This program is distributed in the hope that it will be useful,
35# but WITHOUT ANY WARRANTY; without even the implied warranty of
36# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37# GNU General Public License for more details.
38#
39# You should have received a copy of the GNU General Public License
40# along with this program; if not, write to the Free Software
41# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
42#
43# See /COPYRIGHT in this repository for more information.
44#
[628]45diff -ur openafs-1.4/src/afs/afs_analyze.c openafs-1.4+scripts/src/afs/afs_analyze.c
[1134]46--- openafs-1.4/src/afs/afs_analyze.c
47+++ openafs-1.4+scripts/src/afs/afs_analyze.c
[1070]48@@ -585,7 +585,7 @@
[1]49                         (afid ? afid->Fid.Volume : 0));
50        }
51 
52-       if (areq->busyCount > 100) {
53+       if (1) {
54            if (aerrP)
55                (aerrP->err_Volume)++;
56            areq->volumeError = VOLBUSY;
[1134]57diff -ur openafs-1.4/src/afs/LINUX/osi_vnodeops.c openafs-1.4+scripts/src/afs/LINUX/osi_vnodeops.c
58--- openafs-1.4/src/afs/LINUX/osi_vnodeops.c
59+++ openafs-1.4+scripts/src/afs/LINUX/osi_vnodeops.c
60@@ -875,6 +875,28 @@
61        /* should we always update the attributes at this point? */
62        /* unlikely--the vcache entry hasn't changed */
63 
64+       /* [scripts] This code makes hardlinks work correctly.
65+        *
66+        * We want Apache to be able to read a file with hardlinks
67+        * named .htaccess and foo to be able to read it via .htaccess
68+        * and not via foo, regardless of which name was looked up
69+        * (remember, inodes do not have filenames associated with them.)
70+        *
71+        * It is important that we modify the existing cache entry even
72+        * if it is otherwise totally valid and would not be reloaded.
73+        * Otherwise, it won't recover from repeatedly reading the same
74+        * inode via multiple hardlinks or different names.  Specifically,
75+        * Apache will be able to read both names if it was first looked
76+        * up (by anyone!) via .htaccess, and neither if it was first
77+        * looked up via foo.
78+        *
79+        * With regards to performance, the strncmp() is bounded by
80+        * three characters, so it takes O(3) operations.  If this code
81+        * is extended to all static-cat extensions, we'll want to do
82+        * some clever hashing using gperf here.
83+        */
84+       vcp->apache_access = strncmp(dp->d_name.name, ".ht", 3) == 0;
85+
86     } else {
87 #ifdef notyet
88        pvcp = VTOAFS(dp->d_parent->d_inode);           /* dget_parent()? */
89diff -ur openafs-1.4/src/afs/VNOPS/afs_vnop_lookup.c openafs-1.4+scripts/src/afs/VNOPS/afs_vnop_lookup.c
90--- openafs-1.4/src/afs/VNOPS/afs_vnop_lookup.c
91+++ openafs-1.4+scripts/src/afs/VNOPS/afs_vnop_lookup.c
92@@ -1572,6 +1572,12 @@
93     }
94 
95   done:
96+    if (tvc) {
97+       /* [scripts] check Apache's ability to read this file, so that
98+        * we can figure this out on an access() call */
99+       tvc->apache_access = strncmp(aname, ".ht", 3) == 0;
100+    }
101+
102     /* put the network buffer back, if need be */
103     if (tname != aname && tname)
104        osi_FreeLargeSpace(tname);
[628]105diff -ur openafs-1.4/src/afs/afs.h openafs-1.4+scripts/src/afs/afs.h
[1134]106--- openafs-1.4/src/afs/afs.h
107+++ openafs-1.4+scripts/src/afs/afs.h
[1070]108@@ -208,8 +208,16 @@
109 #define QTOC(e)            QEntry(e, struct cell, lruq)
110 #define QTOVH(e)    QEntry(e, struct vcache, vhashq)
[628]111 
[1]112+#define AFSAGENT_UID (101)
[258]113+#define SIGNUP_UID (102)
[1]114+#define HTTPD_UID (48)
[83]115+#define POSTFIX_UID (89)
[1]116+#define DAEMON_SCRIPTS_PTSID (33554596)
[628]117+extern afs_int32 globalpag;
118+
[1]119 struct vrequest {
120     afs_int32 uid;             /* user id making the request */
121+    afs_int32 realuid;
122     afs_int32 busyCount;       /* how many busies we've seen so far */
123     afs_int32 flags;           /* things like O_SYNC, O_NONBLOCK go here */
[1070]124     char initd;                        /* if non-zero, Error fields meaningful */
[1134]125@@ -743,6 +751,7 @@
126 #ifdef AFS_SUN5_ENV
127     short multiPage;           /* count of multi-page getpages in progress */
128 #endif
129+    bool apache_access;                /* whether or not Apache has access to a file */
130 };
131 
132 #define        DONT_CHECK_MODE_BITS    0
[628]133diff -ur openafs-1.4/src/afs/afs_osi_pag.c openafs-1.4+scripts/src/afs/afs_osi_pag.c
[1134]134--- openafs-1.4/src/afs/afs_osi_pag.c
135+++ openafs-1.4+scripts/src/afs/afs_osi_pag.c
[628]136@@ -51,6 +51,8 @@
137 #endif
[1]138 /* Local variables */
139 
[55]140+afs_int32 globalpag = 0;
[1]141+
142 /*
143  * Pags are implemented as follows: the set of groups whose long
144  * representation is '41XXXXXX' hex are used to represent the pags.
[1070]145@@ -458,6 +460,15 @@
[1]146        av->uid = acred->cr_ruid;       /* default when no pag is set */
147 #endif
148     }
149+
150+    av->realuid = acred->cr_ruid;
[55]151+    if(!globalpag && acred->cr_ruid == AFSAGENT_UID) {
[1]152+      globalpag = av->uid;
153+    }
[628]154+    else if (globalpag && av->uid == acred->cr_ruid) {
[1]155+      av->uid = globalpag;
156+    }
157+
158     av->initd = 0;
159     return 0;
160 }
[628]161diff -ur openafs-1.4/src/afs/afs_pioctl.c openafs-1.4+scripts/src/afs/afs_pioctl.c
[1134]162--- openafs-1.4/src/afs/afs_pioctl.c
163+++ openafs-1.4+scripts/src/afs/afs_pioctl.c
[1070]164@@ -1217,6 +1217,10 @@
[1]165     struct AFSFetchStatus OutStatus;
166     XSTATS_DECLS;
167 
[628]168+    if (areq->uid == globalpag && areq->realuid != AFSAGENT_UID) {
[1]169+      return EACCES;
170+    }
171+
172     AFS_STATCNT(PSetAcl);
173     if (!avc)
174        return EINVAL;
[1070]175@@ -1437,6 +1441,10 @@
[1]176     struct vrequest treq;
177     afs_int32 flag, set_parent_pag = 0;
178 
[628]179+    if (areq->uid == globalpag && areq->realuid != AFSAGENT_UID) {
180+       return 0;
[1]181+    }
182+
183     AFS_STATCNT(PSetTokens);
184     if (!afs_resourceinit_flag) {
185        return EIO;
[1070]186@@ -1796,6 +1804,10 @@
[936]187     afs_int32 iterator;
188     int newStyle;
189 
190+    if (areq->uid == globalpag && areq->realuid != AFSAGENT_UID &&
[937]191+       areq->realuid != 0 && areq->realuid != SIGNUP_UID)
[936]192+       return 0;
193+
194     AFS_STATCNT(PGetTokens);
[1070]195     if (!afs_resourceinit_flag)        /* afs daemons haven't started yet */
196        return EIO;             /* Inappropriate ioctl for device */
197@@ -1879,6 +1891,10 @@
[1]198     register afs_int32 i;
199     register struct unixuser *tu;
200 
[628]201+    if (areq->uid == globalpag && areq->realuid != AFSAGENT_UID) {
202+       return 0;
[1]203+    }
204+
205     AFS_STATCNT(PUnlog);
206     if (!afs_resourceinit_flag)        /* afs daemons haven't started yet */
207        return EIO;             /* Inappropriate ioctl for device */
[628]208diff -ur openafs-1.4/src/afs/VNOPS/afs_vnop_access.c openafs-1.4+scripts/src/afs/VNOPS/afs_vnop_access.c
[1134]209--- openafs-1.4/src/afs/VNOPS/afs_vnop_access.c
210+++ openafs-1.4+scripts/src/afs/VNOPS/afs_vnop_access.c
[628]211@@ -118,6 +118,17 @@
[1]212 
213     if ((vType(avc) == VDIR) || (avc->states & CForeign)) {
214        /* rights are just those from acl */
215+
[628]216+      if ( areq->uid == globalpag &&
217+           !(areq->realuid == avc->fid.Fid.Volume) &&
[1]218+           !((avc->anyAccess | arights) == avc->anyAccess) &&
219+           !(((arights & ~(PRSFS_LOOKUP|PRSFS_READ)) == 0) && areq->realuid == HTTPD_UID) &&
[258]220+           !(((arights & ~(PRSFS_LOOKUP|PRSFS_READ)) == 0) && areq->realuid == POSTFIX_UID) &&
[1047]221+           !(areq->realuid == 0 && PRSFS_USR3 == afs_GetAccessBits(avc, PRSFS_USR3, areq)) &&
222+           !((areq->realuid == 0 || areq->realuid == SIGNUP_UID) && PRSFS_USR4 == afs_GetAccessBits(avc, PRSFS_USR4, areq)) ) {
[1]223+         return 0;
224+      }
225+
226        return (arights == afs_GetAccessBits(avc, arights, areq));
227     } else {
228        /* some rights come from dir and some from file.  Specifically, you
[1134]229@@ -171,6 +182,19 @@
[1]230                    fileBits |= PRSFS_READ;
231            }
232        }
233+       
[628]234+        if ( areq->uid == globalpag &&
235+             !(areq->realuid == avc->fid.Fid.Volume) &&
[1]236+             !((avc->anyAccess | arights) == avc->anyAccess) &&
237+             !(arights == PRSFS_LOOKUP && areq->realuid == HTTPD_UID) &&
[83]238+             !(arights == PRSFS_LOOKUP && areq->realuid == POSTFIX_UID) &&
[1134]239+             !(arights == PRSFS_READ && areq->realuid == HTTPD_UID &&
240+                 (avc->m.Mode == 0100777 || avc->apache_access)) &&
[1047]241+             !(areq->realuid == 0 && PRSFS_USR3 == afs_GetAccessBits(avc, PRSFS_USR3, areq)) &&
[1048]242+             !((areq->realuid == 0 || areq->realuid == SIGNUP_UID) && PRSFS_USR4 == afs_GetAccessBits(avc, PRSFS_USR4, areq)) ) {
[1]243+           return 0;
244+        }
245+
246        return ((fileBits & arights) == arights);       /* true if all rights bits are on */
247     }
248 }
[628]249diff -ur openafs-1.4/src/afs/VNOPS/afs_vnop_attrs.c openafs-1.4+scripts/src/afs/VNOPS/afs_vnop_attrs.c
[1134]250--- openafs-1.4/src/afs/VNOPS/afs_vnop_attrs.c
251+++ openafs-1.4+scripts/src/afs/VNOPS/afs_vnop_attrs.c
[1]252@@ -87,8 +87,8 @@
253        }
254     }
255 #endif /* AFS_DARWIN_ENV */
256-    attrs->va_uid = fakedir ? 0 : avc->m.Owner;
257-    attrs->va_gid = fakedir ? 0 : avc->m.Group;        /* yeah! */
258+    attrs->va_uid = fakedir ? 0 : avc->fid.Fid.Volume;
259+    attrs->va_gid = (avc->m.Owner == DAEMON_SCRIPTS_PTSID ? avc->m.Group : avc->m.Owner);
260 #if defined(AFS_SUN56_ENV)
261     attrs->va_fsid = avc->v.v_vfsp->vfs_fsid.val[0];
262 #elif defined(AFS_OSF_ENV)
Note: See TracBrowser for help on using the repository browser.