コード例 #1
0
ファイル: cm_aclent.c プロジェクト: jisqyv/openafs
/*
 * Invalidate all ACL entries for particular user on this particular vnode.
 *
 * The scp must not be locked.
 */
void cm_InvalidateACLUser(cm_scache_t *scp, cm_user_t *userp)
{
    cm_aclent_t *aclp;
    cm_aclent_t **laclpp;
    int found = 0;
    int callback = 0;

    lock_ObtainWrite(&scp->rw);
    lock_ObtainWrite(&cm_aclLock);
    laclpp = &scp->randomACLp;
    for (aclp = *laclpp; aclp; laclpp = &aclp->nextp, aclp = *laclpp) {
        if (userp == aclp->userp) {	/* One for a given user/scache */
            *laclpp = aclp->nextp;
            cm_ReleaseUser(aclp->userp);
            aclp->userp = NULL;
            aclp->backp = (struct cm_scache *) 0;
            found = 1;
            break;
        }
    }
    lock_ReleaseWrite(&cm_aclLock);
    if (found)
        callback = cm_HaveCallback(scp);
    lock_ReleaseWrite(&scp->rw);

    if (found && callback && RDR_Initialized)
        RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
                             scp->fid.hash, scp->fileType, AFS_INVALIDATE_CREDS);
}
コード例 #2
0
ファイル: cm_access.c プロジェクト: chanke/openafs-osd
/* called with scp write-locked, check to see if we have the ACL info we need
 * and can get it w/o blocking for any locks.
 *
 * Never drops the scp lock, but may fail if the access control info comes from
 * the parent directory, and the parent's scache entry can't be found, or it
 * can't be locked.  Thus, this must always be called in a while loop to stabilize
 * things, since we can always lose the race condition getting to the parent vnode.
 */
int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *userp, afs_uint32 rights,
                        afs_uint32 *outRightsp)
{
    cm_scache_t *aclScp;
    long code;
    cm_fid_t tfid;
    int didLock;
    long trights;
    int release = 0;    /* Used to avoid a call to cm_HoldSCache in the directory case */

    didLock = 0;
    if (scp->fileType == CM_SCACHETYPE_DIRECTORY || cm_accessPerFileCheck) {
        aclScp = scp;   /* not held, not released */
    } else {
        cm_SetFid(&tfid, scp->fid.cell, scp->fid.volume, scp->parentVnode, scp->parentUnique);
        aclScp = cm_FindSCache(&tfid);
        if (!aclScp)
            return 0;
        if (aclScp != scp) {
            if (aclScp->fid.vnode < scp->fid.vnode)
                lock_ReleaseWrite(&scp->rw);
            lock_ObtainRead(&aclScp->rw);
            if (aclScp->fid.vnode < scp->fid.vnode)
                lock_ObtainWrite(&scp->rw);

	    /* check that we have a callback, too */
            if (!cm_HaveCallback(aclScp)) {
                /* can't use it */
                lock_ReleaseRead(&aclScp->rw);
                cm_ReleaseSCache(aclScp);
                return 0;
            }
            didLock = 1;
        }
        release = 1;
    }

    lock_AssertAny(&aclScp->rw);

    /* now if rights is a subset of the public rights, we're done.
     * Otherwise, if we an explicit acl entry, we're also in good shape,
     * and can definitively answer.
     */
#ifdef AFS_FREELANCE_CLIENT
    if (cm_freelanceEnabled &&
        aclScp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
        aclScp->fid.volume==AFS_FAKE_ROOT_VOL_ID)
    {
    	*outRightsp = aclScp->anyAccess;
    } else
#endif
    if ((~aclScp->anyAccess & rights) == 0) {
        *outRightsp = rights;
    } else {
        /* we have to check the specific rights info */
        code = cm_FindACLCache(aclScp, userp, &trights);
        if (code) {
            code = 0;
            goto done;
        }
        *outRightsp = trights;
    }

    if (scp->fileType > 0 && scp->fileType != CM_SCACHETYPE_DIRECTORY) {
	/* check mode bits */
	if ((scp->unixModeBits & 0400) == 0) {
	    osi_Log2(afsd_logp,"cm_HaveAccessRights UnixMode removing READ scp 0x%p unix 0%o",
		      scp, scp->unixModeBits);
	    *outRightsp &= ~PRSFS_READ;
	}
	if ((scp->unixModeBits & 0200) == 0 && (rights != (PRSFS_WRITE | PRSFS_LOCK))) {
	    osi_Log2(afsd_logp,"cm_HaveAccessRights UnixMode removing WRITE scp 0x%p unix 0%o",
		      scp, scp->unixModeBits);
	    *outRightsp &= ~PRSFS_WRITE;
	}
	if ((scp->unixModeBits & 0200) == 0 && !cm_deleteReadOnly) {
	    osi_Log2(afsd_logp,"cm_HaveAccessRights UnixMode removing DELETE scp 0x%p unix 0%o",
		      scp, scp->unixModeBits);
	    *outRightsp &= ~PRSFS_DELETE;
	}
    }

    /* if the user can insert, we must assume they can read/write as well
     * because we do not have the ability to determine if the current user
     * is the owner of the file. We will have to make the call to the
     * file server and let the file server tell us if the request should
     * be denied.
     */
    if ((*outRightsp & PRSFS_INSERT) && (scp->creator == userp))
        *outRightsp |= PRSFS_READ | PRSFS_WRITE;

    /* if the user can obtain a write-lock, read-locks are implied */
    if (*outRightsp & PRSFS_WRITE)
	*outRightsp |= PRSFS_LOCK;

    code = 1;
    /* fall through */

  done:
    if (didLock)
        lock_ReleaseRead(&aclScp->rw);
    if (release)
        cm_ReleaseSCache(aclScp);
    return code;
}