[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] | 45 | diff -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] | 57 | diff -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 |
---|
[1274] | 60 | @@ -896,6 +896,28 @@ |
---|
[1134] | 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()? */ |
---|
| 89 | diff -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] | 105 | diff -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 |
---|
[1259] | 129 | + int apache_access; /* whether or not Apache has access to a file */ |
---|
[1134] | 130 | }; |
---|
| 131 | |
---|
| 132 | #define DONT_CHECK_MODE_BITS 0 |
---|
[628] | 133 | diff -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] | 161 | diff -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 |
---|
[1274] | 164 | @@ -1221,6 +1221,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; |
---|
[1274] | 175 | @@ -1441,6 +1445,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; |
---|
[1274] | 186 | @@ -1800,6 +1808,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 */ |
---|
[1274] | 197 | @@ -1883,6 +1895,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] | 208 | diff -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] | 249 | diff -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) |
---|