source: branches/fc15-dev/server/common/patches/openafs-scripts.patch @ 2032

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