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

Last change on this file was 2820, checked in by andersk, 4 years ago
OpenAFS: Interpret daemon.scripts C bit to allow cross-locker access
File size: 10.3 KB
  • src/afs/LINUX/osi_vnodeops.c

    # scripts.mit.edu openafs patch
    # Copyright (C) 2006  Jeff Arnold <jbarnold@mit.edu>
    # with modifications by Joe Presbrey <presbrey@mit.edu>
    # 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.
    #
    
    # Permission is hereby granted, free of charge, to any person obtaining a copy
    # of this software and associated documentation files (the "Software"), to deal
    # in the Software without restriction, including without limitation the rights
    # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    # copies of the Software, and to permit persons to whom the Software is
    # furnished to do so, subject to the following conditions:
    # 
    # The above copyright notice and this permission notice shall be included in
    # all copies or substantial portions of the Software.
    # 
    # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    # THE SOFTWARE.
    #
    
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License
    # as published by the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
    #
    # See /COPYRIGHT in this repository for more information.
    #
    diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c
    index 91c09ed..86e2f26 100644
    a b afs_linux_dentry_revalidate(struct dentry *dp, int flags) 
    12961296        /* should we always update the attributes at this point? */
    12971297        /* unlikely--the vcache entry hasn't changed */
    12981298
     1299        /* [scripts] This code makes hardlinks work correctly.
     1300        *
     1301        * We want Apache to be able to read a file with hardlinks
     1302        * named .htaccess and foo to be able to read it via .htaccess
     1303        * and not via foo, regardless of which name was looked up
     1304        * (remember, inodes do not have filenames associated with them.)
     1305        *
     1306        * It is important that we modify the existing cache entry even
     1307        * if it is otherwise totally valid and would not be reloaded.
     1308        * Otherwise, it won't recover from repeatedly reading the same
     1309        * inode via multiple hardlinks or different names.  Specifically,
     1310        * Apache will be able to read both names if it was first looked
     1311        * up (by anyone!) via .htaccess, and neither if it was first
     1312        * looked up via foo.
     1313        *
     1314        * With regards to performance, the strncmp() is bounded by
     1315        * three characters, so it takes O(3) operations.  If this code
     1316        * is extended to all static-cat extensions, we'll want to do
     1317        * some clever hashing using gperf here.
     1318        */
     1319        vcp->apache_access = strncmp(dp->d_name.name, ".ht", 3) == 0;
     1320
    12991321        dput(parent);
    13001322    } else {
    13011323#ifdef notyet
  • src/afs/VNOPS/afs_vnop_access.c

    diff --git a/src/afs/VNOPS/afs_vnop_access.c b/src/afs/VNOPS/afs_vnop_access.c
    index 0087073..df3e4ef 100644
    a b afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq, 
    130130            dirBits = PRSFS_LOOKUP | PRSFS_READ;
    131131            return (arights == (dirBits & arights));
    132132        }
     133        if ( areq->uid == globalpag &&
     134            !(areq->realuid == avc->f.fid.Fid.Volume) &&
     135            !((avc->f.anyAccess | arights) == avc->f.anyAccess) &&
     136            !(((arights & ~(PRSFS_LOOKUP|PRSFS_READ)) == 0) && areq->realuid == HTTPD_UID) &&
     137            !(((arights & ~(PRSFS_LOOKUP|PRSFS_READ)) == 0) && areq->realuid == POSTFIX_UID) &&
     138            !(PRSFS_USR2 == afs_GetAccessBits(avc, PRSFS_USR2, areq)) &&
     139            !(areq->realuid == 0 && PRSFS_USR3 == afs_GetAccessBits(avc, PRSFS_USR3, areq)) &&
     140            !((areq->realuid == 0 || areq->realuid == SIGNUP_UID) && PRSFS_USR4 == afs_GetAccessBits(avc, PRSFS_USR4, areq)) ) {
     141            return 0;
     142        }
    133143        return (arights == afs_GetAccessBits(avc, arights, areq));
    134144    } else {
    135145        /* some rights come from dir and some from file.  Specifically, you
    afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq, 
    183192                    fileBits |= PRSFS_READ;
    184193            }
    185194        }
     195
     196        if ( areq->uid == globalpag &&
     197            !(areq->realuid == avc->f.fid.Fid.Volume) &&
     198            !((avc->f.anyAccess | arights) == avc->f.anyAccess) &&
     199            !(arights == PRSFS_LOOKUP && areq->realuid == HTTPD_UID) &&
     200            !(arights == PRSFS_LOOKUP && areq->realuid == POSTFIX_UID) &&
     201            !(arights == PRSFS_READ && areq->realuid == HTTPD_UID &&
     202                (avc->f.m.Mode == 0100777 || avc->apache_access)) &&
     203            !(PRSFS_USR2 == afs_GetAccessBits(avc, PRSFS_USR2, areq)) &&
     204            !(areq->realuid == 0 && PRSFS_USR3 == afs_GetAccessBits(avc, PRSFS_USR3, areq)) &&
     205            !((areq->realuid == 0 || areq->realuid == SIGNUP_UID) && PRSFS_USR4 == afs_GetAccessBits(avc, PRSFS_USR4, areq)) ) {
     206            return 0;
     207        }
     208
    186209        return ((fileBits & arights) == arights);       /* true if all rights bits are on */
    187210    }
    188211}
  • src/afs/VNOPS/afs_vnop_attrs.c

    diff --git a/src/afs/VNOPS/afs_vnop_attrs.c b/src/afs/VNOPS/afs_vnop_attrs.c
    index 2eb228f..d5d6e4a 100644
    a b afs_CopyOutAttrs(struct vcache *avc, struct vattr *attrs) 
    9090        }
    9191    }
    9292#endif /* AFS_DARWIN_ENV */
    93     attrs->va_uid = fakedir ? 0 : avc->f.m.Owner;
    94     attrs->va_gid = fakedir ? 0 : avc->f.m.Group;       /* yeah! */
     93    attrs->va_uid = fakedir ? 0 : avc->f.fid.Fid.Volume;
     94    attrs->va_gid = (avc->f.m.Owner == DAEMON_SCRIPTS_PTSID ? avc->f.m.Group : avc->f.m.Owner);
    9595#if defined(AFS_SUN56_ENV)
    9696    attrs->va_fsid = avc->v.v_vfsp->vfs_fsid.val[0];
    9797#elif defined(AFS_DARWIN80_ENV)
  • src/afs/VNOPS/afs_vnop_lookup.c

    diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c
    index d8205b6..5010486 100644
    a b afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, afs_ucred_t *acr 
    19151915    }
    19161916
    19171917  done:
     1918    if (tvc) {
     1919    /* [scripts] check Apache's ability to read this file, so that
     1920    * we can figure this out on an access() call */
     1921    tvc->apache_access = strncmp(aname, ".ht", 3) == 0;
     1922    }
     1923
    19181924    /* put the network buffer back, if need be */
    19191925    if (tname != aname && tname)
    19201926        osi_FreeLargeSpace(tname);
  • src/afs/afs.h

    diff --git a/src/afs/afs.h b/src/afs/afs.h
    index 0dbc11b..ab6c0d9 100644
    a b struct afs_slotlist { 
    237237    struct afs_slotlist *next;
    238238};
    239239
     240#define AFSAGENT_UID (101)
     241#define SIGNUP_UID (102)
     242#define HTTPD_UID (48)
     243#define POSTFIX_UID (89)
     244#define DAEMON_SCRIPTS_PTSID (33554596)
     245extern afs_int32 globalpag;
     246
    240247struct vrequest {
    241248    afs_int32 uid;              /* user id making the request */
     249    afs_int32 realuid;
    242250    afs_int32 busyCount;        /* how many busies we've seen so far */
    243251    afs_int32 flags;            /* things like O_SYNC, O_NONBLOCK go here */
    244252    char initd;                 /* if non-zero, Error fields meaningful */
    struct vcache { 
    902910    spinlock_t pagewriter_lock;
    903911    struct list_head pagewriters;       /* threads that are writing vm pages */
    904912#endif
     913    int apache_access;          /* whether or not Apache has access to a file */
    905914};
    906915
    907916#ifdef AFS_LINUX26_ENV
  • src/afs/afs_analyze.c

    diff --git a/src/afs/afs_analyze.c b/src/afs/afs_analyze.c
    index dea580b..6021cc2 100644
    a b afs_Analyze(struct afs_conn *aconn, struct rx_connection *rxconn, 
    482482                         (afid ? afid->Fid.Volume : 0));
    483483        }
    484484
    485         if (areq->busyCount > 100) {
     485        if (1) {
    486486            if (aerrP)
    487487                (aerrP->err_Volume)++;
    488488            areq->volumeError = VOLBUSY;
  • src/afs/afs_osi_pag.c

    diff --git a/src/afs/afs_osi_pag.c b/src/afs/afs_osi_pag.c
    index afbb1cf..43ffdfd 100644
    a b afs_uint32 pagCounter = 0; 
    4949#endif
    5050/* Local variables */
    5151
     52afs_int32 globalpag = 0;
     53
    5254/*
    5355 * Pags are implemented as follows: the set of groups whose long
    5456 * representation is '41XXXXXX' hex are used to represent the pags.
    afs_InitReq(struct vrequest *av, afs_ucred_t *acred) 
    484486        av->uid = afs_cr_ruid(acred);   /* default when no pag is set */
    485487#endif
    486488    }
     489
     490    av->realuid = afs_cr_uid(acred);
     491    if(!globalpag && av->realuid == AFSAGENT_UID) {
     492      globalpag = av->uid;
     493    }
     494    else if (globalpag && av->uid == av->realuid) {
     495      av->uid = globalpag;
     496    }
     497
    487498    return 0;
    488499}
    489500
  • src/afs/afs_pioctl.c

    diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c
    index e9a84e3..047b3b5 100644
    a b DECL_PIOCTL(PSetAcl) 
    14221422    struct rx_connection *rxconn;
    14231423    XSTATS_DECLS;
    14241424
     1425    if (areq->uid == globalpag && areq->realuid != AFSAGENT_UID) {
     1426       return EACCES;
     1427    }
     1428
    14251429    AFS_STATCNT(PSetAcl);
    14261430    if (!avc)
    14271431        return EINVAL;
    DECL_PIOCTL(PSetTokens) 
    18091813    afs_int32 flag, set_parent_pag = 0;
    18101814    int code;
    18111815
     1816    if (areq->uid == globalpag && areq->realuid != AFSAGENT_UID) {
     1817        return EACCES;
     1818    }
     1819
    18121820    AFS_STATCNT(PSetTokens);
    18131821    if (!afs_resourceinit_flag) {
    18141822        return EIO;
    DECL_PIOCTL(PGetTokens) 
    22732281    int newStyle;
    22742282    int code = E2BIG;
    22752283
     2284    if (areq->uid == globalpag && areq->realuid != AFSAGENT_UID &&
     2285        areq->realuid != 0 && areq->realuid != SIGNUP_UID) {
     2286        return EDOM;
     2287    }
     2288
    22762289    AFS_STATCNT(PGetTokens);
    22772290    if (!afs_resourceinit_flag) /* afs daemons haven't started yet */
    22782291        return EIO;             /* Inappropriate ioctl for device */
    DECL_PIOCTL(PUnlog) 
    23832396    afs_int32 i;
    23842397    struct unixuser *tu;
    23852398
     2399    if (areq->uid == globalpag && areq->realuid != AFSAGENT_UID) {
     2400        return EACCES;
     2401    }
     2402
    23862403    AFS_STATCNT(PUnlog);
    23872404    if (!afs_resourceinit_flag) /* afs daemons haven't started yet */
    23882405        return EIO;             /* Inappropriate ioctl for device */
Note: See TracBrowser for help on using the repository browser.