linux/fs/afs/security.c
<<
121212e/spa1on12espa1 class="lxr_search">12121212Search1212e/spa1on12einput typ hidden" nam ajax_lookup" id ajax_lookup" 262" ">1n ediv id file_contents"o
u u1e/a>espa1 class="comment">/* AFS security handlinge/spa1onu u2e/a>espa1 class="comment"> *e/spa1onu u3e/a>espa1 class="comment"> * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.e/spa1onu u4e/a>espa1 class="comment"> * Written by David Howells (dhowells@redhat.com)e/spa1onu u5e/a>espa1 class="comment"> *e/spa1onu u6e/a>espa1 class="comment"> * This program is free software; you ca1 redistribute it and/ore/spa1onu u7e/a>espa1 class="comment"> * modify it under the terms of the GNU General Public Licensee/spa1onu u8e/a>espa1 class="comment"> * as published by the Free Software Founda22.1; either vers2.1e/spa1onu u9e/a>espa1 class="comment"> * 2 of the License, or (at your .622.1) any later vers2.1.e/spa1onu 23.6a>espa1 class="comment"> */e/spa1onu 11e/a>nu 12e/a>#include <linux/init.he/a>>nu 13e/a>#include <linux/slab.he/a>>nu 14e/a>#include <linux/fs.he/a>>nu 15e/a>#include <linux/ctyp
.he/a>>nu 16e/a>#include <linux/sched.he/a>>nu 17e/a>#include <keys/rxrpc-typ
.he/a>>nu 18e/a>#include "internal.he/a>"nu 19e/a>nu 23.6a>espa1 class="comment">/*e/spa1onu 21e/a>espa1 class="comment"> * get a keye/spa1onu 22e/a>espa1 class="comment"> */e/spa1onu 23e/a>structuea href="+code=key" class="sref">keye/a> *ea href="+code=afs_request_key" class="sref">afs_request_keye/a>(structuea href="+code=afs_cell" class="sref">afs_celle/a> *ea href="+code=cell" class="sref">celle/a>)nu 24e/a>{nu 25e/a>        structuea href="+code=key" class="sref">keye/a> *ea href="+code=key" class="sref">keye/a>;nu 26e/a>nu 27e/a>        ea href="+code=_enter" class="sref">_entere/a>(espa1 class="string">"{%x}"key_seriale/a>(ea href="+code=cell" class="sref">celle/a>->ea href="+code=anonymous_key" class="sref">anonymous_keye/a>));nu 28e/a>nu 29e/a>        ea href="+code=_debug" class="sref">_debuge/a>(espa1 class="string">"key %s"celle/a>->ea href="+code=anonymous_key" class="sref">anonymous_keye/a>->ea href="+code=descri622.1" class="sref">descri622.1e/a>);nu 30e/a>        ea href="+code=key" class="sref">keye/a> = ea href="+code=request_key" class="sref">request_keye/a>(&ea href="+code=key_typ
_rxrpc" class="sref">key_typ
_rxrpce/a>,uea href="+code=cell" class="sref">celle/a>->ea href="+code=anonymous_key" class="sref">anonymous_keye/a>->ea href="+code=descri622.1" class="sref">descri622.1e/a>,nu 31e/a>                          ea href="+code=NULL" class="sref">NULLe/a>);nu 32e/a>        if (ea href="+code=IS_ERR" class="sref">IS_ERRe/a>(ea href="+code=key" class="sref">keye/a>)) {nu 33e/a>                if (ea href="+code=PTR_ERR" class="sref">PTR_ERRe/a>(ea href="+code=key" class="sref">keye/a>) != -ea href="+code=ENOKEY" class="sref">ENOKEYe/a>) {nu 34e/a>                        ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">" = %ld"PTR_ERRe/a>(ea href="+code=key" class="sref">keye/a>));nu 35e/a>                        return ea href="+code=key" class="sref">keye/a>;nu 36e/a>                }nu 37e/a>nu 38e/a>                espa1 class="comment">/* actuas anonymous user */e/spa1onu 39e/a>                ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">" = {%x} [anon]"key_seriale/a>(ea href="+code=cell" class="sref">celle/a>->ea href="+code=anonymous_key" class="sref">anonymous_keye/a>));nu 40e/a>                return ea href="+code=key_get" class="sref">key_gete/a>(ea href="+code=cell" class="sref">celle/a>->ea href="+code=anonymous_key" class="sref">anonymous_keye/a>);nu 41e/a>        } else {nu 42e/a>                espa1 class="comment">/* actuas authorised user */e/spa1onu 43e/a>                ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">" = {%x} [auth]"key_seriale/a>(ea href="+code=key" class="sref">keye/a>));nu 44e/a>                return ea href="+code=key" class="sref">keye/a>;nu 45e/a>        }nu 46e/a>}nu 47e/a>nu 48e/a>espa1 class="comment">/*e/spa1onu 49e/a>espa1 class="comment"> * dispose of a permits liste/spa1onu 53.6a>espa1 class="comment"> */e/spa1onu 51e/a>voiduea href="+code=afs_zap_permits" class="sref">afs_zap_permitse/a>(structuea href="+code=rcu_head" class="sref">rcu_heade/a> *ea href="+code=rcu" class="sref">rcue/a>)nu 52e/a>{nu 53e/a>        structuea href="+code=afs_permits" class="sref">afs_permitse/a> *ea href="+code=permits" class="sref">permitse/a> =nu 54e/a>                ea href="+code=container_of" class="sref">container_ofe/a>(ea href="+code=rcu" class="sref">rcue/a>, structuea href="+code=afs_permits" class="sref">afs_permitse/a>,uea href="+code=rcu" class="sref">rcue/a>);nu 55e/a>        intuea href="+code=loop" class="sref">loope/a>;nu 56e/a>nu 57e/a>        ea href="+code=_enter" class="sref">_entere/a>(espa1 class="string">"{%d}"permitse/a>->ea href="+code=count" class="sref">counte/a>);nu 58e/a>nu 59e/a>        for (ea href="+code=loop" class="sref">loope/a> = ea href="+code=permits" class="sref">permitse/a>->ea href="+code=count" class="sref">counte/a> - 1;uea href="+code=loop" class="sref">loope/a> >= 0;uea href="+code=loop" class="sref">loope/a>--)nu 60e/a>                ea href="+code=key_put" class="sref">key_pute/a>(ea href="+code=permits" class="sref">permitse/a>->ea href="+code=permits" class="sref">permitse/a>[ea href="+code=loop" class="sref">loope/a>].ea href="+code=key" class="sref">keye/a>);nu 61e/a>        ea href="+code=kfree" class="sref">kfreee/a>(ea href="+code=permits" class="sref">permitse/a>);nu 62e/a>}nu 63e/a>nu 64e/a>espa1 class="comment">/*e/spa1onu 65e/a>espa1 class="comment"> * dispose of a permits list in which all the key pointers have bee1 copiede/spa1onu 66e/a>espa1 class="comment"> */e/spa1onu 67e/a>static voiduea href="+code=afs_dispose_of_permits" class="sref">afs_dispose_of_permitse/a>(structuea href="+code=rcu_head" class="sref">rcu_heade/a> *ea href="+code=rcu" class="sref">rcue/a>)nu 68e/a>{nu 69e/a>        structuea href="+code=afs_permits" class="sref">afs_permitse/a> *ea href="+code=permits" class="sref">permitse/a> =nu 70e/a>                ea href="+code=container_of" class="sref">container_ofe/a>(ea href="+code=rcu" class="sref">rcue/a>, structuea href="+code=afs_permits" class="sref">afs_permitse/a>,uea href="+code=rcu" class="sref">rcue/a>);nu 71e/a>nu 72e/a>        ea href="+code=_enter" class="sref">_entere/a>(espa1 class="string">"{%d}"permitse/a>->ea href="+code=count" class="sref">counte/a>);nu 73e/a>nu 74e/a>        ea href="+code=kfree" class="sref">kfreee/a>(ea href="+code=permits" class="sref">permitse/a>);nu 75e/a>}nu 76e/a>nu 77e/a>espa1 class="comment">/*e/spa1onu 78e/a>espa1 class="comment"> * get the authorising vnode - this is the specified inode itself if it's ae/spa1onu 79e/a>espa1 class="comment"> * directory or it's the parent directory if the specified inode is a file ore/spa1onu 83.6a>espa1 class="comment"> * symlinke/spa1onu 81e/a>espa1 class="comment"> * - the caller must release the ref .62the inodee/spa1onu 82e/a>espa1 class="comment"> */e/spa1onu 83e/a>static structuea href="+code=afs_vnode" class="sref">afs_vnodee/a> *ea href="+code=afs_get_auth_inode" class="sref">afs_get_auth_inodee/a>(structuea href="+code=afs_vnode" class="sref">afs_vnodee/a> *ea href="+code=vnode" class="sref">vnodee/a>,nu 84e/a>                                            structuea href="+code=key" class="sref">keye/a> *ea href="+code=key" class="sref">keye/a>)nu 85e/a>{nu 86e/a>        structuea href="+code=afs_vnode" class="sref">afs_vnodee/a> *ea href="+code=auth_vnode" class="sref">auth_vnodee/a>;nu 87e/a>        structuea href="+code=inode" class="sref">inodee/a> *ea href="+code=auth_inode" class="sref">auth_inodee/a>;nu 88e/a>nu 89e/a>        ea href="+code=_enter" class="sref">_entere/a>(espa1 class="string">""u 90e/a>nu 91e/a>        if (ea href="+code=S_ISDIR" class="sref">S_ISDIRe/a>(ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=vfs_inode" class="sref">vfs_inodee/a>.ea href="+code=i_mode" class="sref">i_modee/a>)) {nu 92e/a>                ea href="+code=auth_inode" class="sref">auth_inodee/a> = ea href="+code=igrab" class="sref">igrabe/a>(&ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=vfs_inode" class="sref">vfs_inodee/a>);nu 93e/a>                ea href="+code=ASSERT" class="sref">ASSERTe/a>(ea href="+code=auth_inode" class="sref">auth_inodee/a> != ea href="+code=NULL" class="sref">NULLe/a>);nu 94e/a>        } else {nu 95e/a>                ea href="+code=auth_inode" class="sref">auth_inodee/a> = ea href="+code=afs_iget" class="sref">afs_igete/a>(ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=vfs_inode" class="sref">vfs_inodee/a>.ea href="+code=i_sb" class="sref">i_sbe/a>,uea href="+code=key" class="sref">keye/a>,nu 96e/a>                                      &ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=status" class="sref">statuse/a>.ea href="+code=parent" class="sref">parente/a>,uea href="+code=NULL" class="sref">NULLe/a>,uea href="+code=NULL" class="sref">NULLe/a>);nu 97e/a>                if (ea href="+code=IS_ERR" class="sref">IS_ERRe/a>(ea href="+code=auth_inode" class="sref">auth_inodee/a>))nu 98e/a>                        return ea href="+code=ERR_CAST" class="sref">ERR_CASTe/a>(ea href="+code=auth_inode" class="sref">auth_inodee/a>);nu 99e/a>        }nu100e/a>nu101e/a>        ea href="+code=auth_vnode" class="sref">auth_vnodee/a> = ea href="+code=AFS_FS_I" class="sref">AFS_FS_Ie/a>(ea href="+code=auth_inode" class="sref">auth_inodee/a>);nu102e/a>        ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">" = {%x}"auth_vnodee/a>->ea href="+code=fid" class="sref">fide/a>.ea href="+code=vnode" class="sref">vnodee/a>);nu103e/a>        return ea href="+code=auth_vnode" class="sref">auth_vnodee/a>;nu104e/a>}nu105e/a>nu106e/a>espa1 class="comment">/*e/spa1onu107e/a>espa1 class="comment"> * clear the permit cache on a directory vnodee/spa1onu108e/a>espa1 class="comment"> */e/spa1onu109e/a>voiduea href="+code=afs_clear_permits" class="sref">afs_clear_permitse/a>(structuea href="+code=afs_vnode" class="sref">afs_vnodee/a> *ea href="+code=vnode" class="sref">vnodee/a>)nu123.6a>{nu111e/a>        structuea href="+code=afs_permits" class="sref">afs_permitse/a> *ea href="+code=permits" class="sref">permitse/a>;nu112e/a>nu113e/a>        ea href="+code=_enter" class="sref">_entere/a>(espa1 class="string">"{%x:%u}"vnodee/a>->ea href="+code=fid" class="sref">fide/a>.ea href="+code=vid" class="sref">vide/a>,uea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=fid" class="sref">fide/a>.ea href="+code=vnode" class="sref">vnodee/a>);nu114e/a>nu115e/a>        ea href="+code=mutex_lock" class="sref">mutex_locke/a>(&ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=permits_lock" class="sref">permits_locke/a>);nu116e/a>        ea href="+code=permits" class="sref">permitse/a> =uea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=permits" class="sref">permitse/a>;nu117e/a>        ea href="+code=rcu_assign_pointer" class="sref">rcu_assign_pointere/a>(ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=permits" class="sref">permitse/a>,uea href="+code=NULL" class="sref">NULLe/a>);nu118e/a>        ea href="+code=mutex_unlock" class="sref">mutex_unlocke/a>(&ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=permits_lock" class="sref">permits_locke/a>);nu119e/a>nu120e/a>        if (ea href="+code=permits" class="sref">permitse/a>)nu121e/a>                ea href="+code=call_rcu" class="sref">call_rcue/a>(&ea href="+code=permits" class="sref">permitse/a>->ea href="+code=rcu" class="sref">rcue/a>, ea href="+code=afs_zap_permits" class="sref">afs_zap_permitse/a>);nu122e/a>        ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">""u123e/a>}nu124e/a>nu125e/a>espa1 class="comment">/*e/spa1onu126e/a>espa1 class="comment"> * add the result obtained for a vnode to its or its parent directory's cachee/spa1onu127e/a>espa1 class="comment"> * for the key used to access ite/spa1onu128e/a>espa1 class="comment"> */e/spa1onu129e/a>voiduea href="+code=afs_cache_permit" class="sref">afs_cache_permite/a>(structuea href="+code=afs_vnode" class="sref">afs_vnodee/a> *ea href="+code=vnode" class="sref">vnodee/a>, structuea href="+code=key" class="sref">keye/a> *ea href="+code=key" class="sref">keye/a>, longuea href="+code=acl_order" class="sref">acl_ordere/a>)nu133.6a>{nu131e/a>        structuea href="+code=afs_permits" class="sref">afs_permitse/a> *ea href="+code=permits" class="sref">permitse/a>, *ea href="+code=xpermits" class="sref">xpermitse/a>;nu132e/a>        structuea href="+code=afs_permit" class="sref">afs_permite/a> *ea href="+code=permit" class="sref">permite/a>;nu133e/a>        structuea href="+code=afs_vnode" class="sref">afs_vnodee/a> *ea href="+code=auth_vnode" class="sref">auth_vnodee/a>;nu134e/a>        intuea href="+code=count" class="sref">counte/a>, ea href="+code=loop" class="sref">loope/a>;nu135e/a>nu136e/a>        ea href="+code=_enter" class="sref">_entere/a>(espa1 class="string">"{%x:%u},%x,%lx"u137e/a>               ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=fid" class="sref">fide/a>.ea href="+code=vid" class="sref">vide/a>,uea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=fid" class="sref">fide/a>.ea href="+code=vnode" class="sref">vnodee/a>, ea href="+code=key_serial" class="sref">key_seriale/a>(ea href="+code=key" class="sref">keye/a>), ea href="+code=acl_order" class="sref">acl_ordere/a>);nu138e/a>nu139e/a>        ea href="+code=auth_vnode" class="sref">auth_vnodee/a> = ea href="+code=afs_get_auth_inode" class="sref">afs_get_auth_inodee/a>(ea href="+code=vnode" class="sref">vnodee/a>, ea href="+code=key" class="sref">keye/a>);nu140e/a>        if (ea href="+code=IS_ERR" class="sref">IS_ERRe/a>(ea href="+code=auth_vnode" class="sref">auth_vnodee/a>)) {nu141e/a>                ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">" [get error %ld]"PTR_ERRe/a>(ea href="+code=auth_vnode" class="sref">auth_vnodee/a>));nu142e/a>                return;nu143e/a>        }nu144e/a>nu145e/a>        ea href="+code=mutex_lock" class="sref">mutex_locke/a>(&ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=permits_lock" class="sref">permits_locke/a>);nu146e/a>nu147e/a>        espa1 class="comment">/* guard against a renam
 being detected whilst we waited for thee/spa1onu148e/a>espa1 class="comment">         * lock */e/spa1onu149e/a>        if (ea href="+code=memcmp" class="sref">memcmpe/a>(&ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=fid" class="sref">fide/a>, &ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=status" class="sref">statuse/a>.ea href="+code=parent" class="sref">parente/a>,nu150e/a>                   sizeof(structuea href="+code=afs_fid" class="sref">afs_fide/a>)) != 0) {nu151e/a>                ea href="+code=_debug" class="sref">_debuge/a>(espa1 class="string">"renam
d"u152e/a>                goto ea href="+code=out_unlock" class="sref">out_unlocke/a>;nu153e/a>        }nu154e/a>nu155e/a>        espa1 class="comment">/* have to be carefuluas the directory's callback may be broken betwee1e/spa1onu156e/a>espa1 class="comment">         * us receiving the status we're trying to cache and us getting thee/spa1onu157e/a>espa1 class="comment">         * lock to update the cache for the status */e/spa1onu158e/a>        if (ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=acl_order" class="sref">acl_ordere/a> - ea href="+code=acl_order" class="sref">acl_ordere/a> > 0) {nu159e/a>                ea href="+code=_debug" class="sref">_debuge/a>(espa1 class="string">"ACL changed?"u160e/a>                goto ea href="+code=out_unlock" class="sref">out_unlocke/a>;nu161e/a>        }nu162e/a>nu163e/a>        espa1 class="comment">/* always update the anonymous mask */e/spa1onu164e/a>        ea href="+code=_debug" class="sref">_debuge/a>(espa1 class="string">"anon access %x"vnodee/a>->ea href="+code=status" class="sref">statuse/a>.ea href="+code=anon_access" class="sref">anon_accesse/a>);nu165e/a>        ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=status" class="sref">statuse/a>.ea href="+code=anon_access" class="sref">anon_accesse/a> =uea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=status" class="sref">statuse/a>.ea href="+code=anon_access" class="sref">anon_accesse/a>;nu166e/a>        if (ea href="+code=key" class="sref">keye/a> ==uea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=volume" class="sref">volumee/a>->ea href="+code=cell" class="sref">celle/a>->ea href="+code=anonymous_key" class="sref">anonymous_keye/a>)nu167e/a>                goto ea href="+code=out_unlock" class="sref">out_unlocke/a>;nu168e/a>nu169e/a>        ea href="+code=xpermits" class="sref">xpermitse/a> = ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=permits" class="sref">permitse/a>;nu170e/a>        ea href="+code=count" class="sref">counte/a> = 0;nu171e/a>        if (ea href="+code=xpermits" class="sref">xpermitse/a>) {nu172e/a>                espa1 class="comment">/* see if the permit is already in the liste/spa1onu173e/a>espa1 class="comment">                 * - if it is then we just am
nd the liste/spa1onu174e/a>espa1 class="comment">                 */e/spa1onu175e/a>                ea href="+code=count" class="sref">counte/a> = ea href="+code=xpermits" class="sref">xpermitse/a>->ea href="+code=count" class="sref">counte/a>;nu176e/a>                ea href="+code=permit" class="sref">permite/a> = ea href="+code=xpermits" class="sref">xpermitse/a>->ea href="+code=permits" class="sref">permitse/a>;nu177e/a>                for (ea href="+code=loop" class="sref">loope/a> = ea href="+code=count" class="sref">counte/a>;uea href="+code=loop" class="sref">loope/a> > 0;uea href="+code=loop" class="sref">loope/a>--) {nu178e/a>                        if (ea href="+code=permit" class="sref">permite/a>->ea href="+code=key" class="sref">keye/a> ==uea href="+code=key" class="sref">keye/a>) {nu179e/a>                                ea href="+code=permit" class="sref">permite/a>->ea href="+code=access_mask" class="sref">access_maske/a> =nu180e/a>                                        ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=status" class="sref">statuse/a>.ea href="+code=caller_access" class="sref">caller_accesse/a>;nu181e/a>                                goto ea href="+code=out_unlock" class="sref">out_unlocke/a>;nu182e/a>                        }nu183e/a>                        ea href="+code=permit" class="sref">permite/a>++;nu184e/a>                }nu185e/a>        }nu186e/a>nu187e/a>        ea href="+code=permits" class="sref">permitse/a> =uea href="+code=kmalloc" class="sref">kmalloce/a>(sizeof(*ea href="+code=permits" class="sref">permitse/a>) + sizeof(*ea href="+code=permit" class="sref">permite/a>) * (ea href="+code=count" class="sref">counte/a> + 1),nu188e/a>                          ea href="+code=GFP_NOFS" class="sref">GFP_NOFSe/a>);nu189e/a>        if (!ea href="+code=permits" class="sref">permitse/a>)nu190e/a>                goto ea href="+code=out_unlock" class="sref">out_unlocke/a>;nu191e/a>nu192e/a>        if (ea href="+code=xpermits" class="sref">xpermitse/a>)nu193e/a>                ea href="+code=memcpy" class="sref">memcpye/a>(ea href="+code=permits" class="sref">permitse/a>->ea href="+code=permits" class="sref">permitse/a>,uea href="+code=xpermits" class="sref">xpermitse/a>->ea href="+code=permits" class="sref">permitse/a>,nu194e/a>                        ea href="+code=count" class="sref">counte/a> * sizeof(structuea href="+code=afs_permit" class="sref">afs_permite/a>));nu195e/a>nu196e/a>        ea href="+code=_debug" class="sref">_debuge/a>(espa1 class="string">"key %x access %x"u197e/a>               ea href="+code=key_serial" class="sref">key_seriale/a>(ea href="+code=key" class="sref">keye/a>), ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=status" class="sref">statuse/a>.ea href="+code=caller_access" class="sref">caller_accesse/a>);nu198e/a>        ea href="+code=permits" class="sref">permitse/a>->ea href="+code=permits" class="sref">permitse/a>[ea href="+code=count" class="sref">counte/a>].ea href="+code=access_mask" class="sref">access_maske/a> = ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=status" class="sref">statuse/a>.ea href="+code=caller_access" class="sref">caller_accesse/a>;nu199e/a>        ea href="+code=permits" class="sref">permitse/a>->ea href="+code=permits" class="sref">permitse/a>[ea href="+code=count" class="sref">counte/a>].ea href="+code=key" class="sref">keye/a> = ea href="+code=key_get" class="sref">key_gete/a>(ea href="+code=key" class="sref">keye/a>);nu200e/a>        ea href="+code=permits" class="sref">permitse/a>->ea href="+code=count" class="sref">counte/a> = ea href="+code=count" class="sref">counte/a> + 1;nu201e/a>nu202e/a>        ea href="+code=rcu_assign_pointer" class="sref">rcu_assign_pointere/a>(ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=permits" class="sref">permitse/a>,uea href="+code=permits" class="sref">permitse/a>);nu203e/a>        if (ea href="+code=xpermits" class="sref">xpermitse/a>)nu204e/a>                ea href="+code=call_rcu" class="sref">call_rcue/a>(&ea href="+code=xpermits" class="sref">xpermitse/a>->ea href="+code=rcu" class="sref">rcue/a>, ea href="+code=afs_dispose_of_permits" class="sref">afs_dispose_of_permitse/a>);nu205e/a>nu206e/a>ea href="+code=out_unlock" class="sref">out_unlocke/a>:nu207e/a>        ea href="+code=mutex_unlock" class="sref">mutex_unlocke/a>(&ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=permits_lock" class="sref">permits_locke/a>);nu208e/a>        ea href="+code=iput" class="sref">ipute/a>(&ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=vfs_inode" class="sref">vfs_inodee/a>);nu209e/a>        ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">""u223.6a>}nu211e/a>nu212e/a>espa1 class="comment">/*e/spa1onu213e/a>espa1 class="comment"> * check with the fileserver to see if the directory or parent directory ise/spa1onu214e/a>espa1 class="comment"> * permitted to be accessed with this authorisation, and if so, what access ite/spa1onu215e/a>espa1 class="comment"> * is grantede/spa1onu216e/a>espa1 class="comment"> */e/spa1onu217e/a>static intuea href="+code=afs_check_permit" class="sref">afs_check_permite/a>(structuea href="+code=afs_vnode" class="sref">afs_vnodee/a> *ea href="+code=vnode" class="sref">vnodee/a>, structuea href="+code=key" class="sref">keye/a> *ea href="+code=key" class="sref">keye/a>,nu218e/a>                            ea href="+code=afs_access_t" class="sref">afs_access_te/a> *ea href="+code=_access" class="sref">_accesse/a>)nu219e/a>{nu220e/a>        structuea href="+code=afs_permits" class="sref">afs_permitse/a> *ea href="+code=permits" class="sref">permitse/a>;nu221e/a>        structuea href="+code=afs_permit" class="sref">afs_permite/a> *ea href="+code=permit" class="sref">permite/a>;nu222e/a>        structuea href="+code=afs_vnode" class="sref">afs_vnodee/a> *ea href="+code=auth_vnode" class="sref">auth_vnodee/a>;nu223e/a>        ea href="+code=bool" class="sref">boole/a> ea href="+code=valid" class="sref">valide/a>;nu224e/a>        intuea href="+code=loop" class="sref">loope/a>,uea href="+code=ret" class="sref">rete/a>;nu225e/a>nu226e/a>        ea href="+code=_enter" class="sref">_entere/a>(espa1 class="string">"{%x:%u},%x"u227e/a>               ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=fid" class="sref">fide/a>.ea href="+code=vid" class="sref">vide/a>,uea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=fid" class="sref">fide/a>.ea href="+code=vnode" class="sref">vnodee/a>, ea href="+code=key_serial" class="sref">key_seriale/a>(ea href="+code=key" class="sref">keye/a>));nu228e/a>nu229e/a>        ea href="+code=auth_vnode" class="sref">auth_vnodee/a> = ea href="+code=afs_get_auth_inode" class="sref">afs_get_auth_inodee/a>(ea href="+code=vnode" class="sref">vnodee/a>, ea href="+code=key" class="sref">keye/a>);nu230e/a>        if (ea href="+code=IS_ERR" class="sref">IS_ERRe/a>(ea href="+code=auth_vnode" class="sref">auth_vnodee/a>)) {nu231e/a>                *ea href="+code=_access" class="sref">_accesse/a> = 0;nu232e/a>                ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">" = %ld"PTR_ERRe/a>(ea href="+code=auth_vnode" class="sref">auth_vnodee/a>));nu233e/a>                return ea href="+code=PTR_ERR" class="sref">PTR_ERRe/a>(ea href="+code=auth_vnode" class="sref">auth_vnodee/a>);nu234e/a>        }nu235e/a>nu236e/a>        ea href="+code=ASSERT" class="sref">ASSERTe/a>(ea href="+code=S_ISDIR" class="sref">S_ISDIRe/a>(ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=vfs_inode" class="sref">vfs_inodee/a>.ea href="+code=i_mode" class="sref">i_modee/a>));nu237e/a>nu238e/a>        espa1 class="comment">/* check the permits to see if we've got one yet */e/spa1onu239e/a>        if (ea href="+code=key" class="sref">keye/a> ==uea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=volume" class="sref">volumee/a>->ea href="+code=cell" class="sref">celle/a>->ea href="+code=anonymous_key" class="sref">anonymous_keye/a>) {nu240e/a>                ea href="+code=_debug" class="sref">_debuge/a>(espa1 class="string">"anon"u241e/a>                *ea href="+code=_access" class="sref">_accesse/a> = ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=status" class="sref">statuse/a>.ea href="+code=anon_access" class="sref">anon_accesse/a>;nu242e/a>                ea href="+code=valid" class="sref">valide/a> = ea href="+code=true" class="sref">truee/a>;nu243e/a>        } else {nu244e/a>                ea href="+code=valid" class="sref">valide/a> = ea href="+code=false" class="sref">falsee/a>;nu245e/a>                ea href="+code=rcu_read_lock" class="sref">rcu_read_locke/a>();nu246e/a>                ea href="+code=permits" class="sref">permitse/a> =uea href="+code=rcu_dereference" class="sref">rcu_dereferencee/a>(ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=permits" class="sref">permitse/a>);nu247e/a>                if (ea href="+code=permits" class="sref">permitse/a>) {nu248e/a>                        ea href="+code=permit" class="sref">permite/a> =uea href="+code=permits" class="sref">permitse/a>->ea href="+code=permits" class="sref">permitse/a>;nu249e/a>                        for (ea href="+code=loop" class="sref">loope/a> = ea href="+code=permits" class="sref">permitse/a>->ea href="+code=count" class="sref">counte/a>;uea href="+code=loop" class="sref">loope/a> > 0;uea href="+code=loop" class="sref">loope/a>--) {nu250e/a>                                if (ea href="+code=permit" class="sref">permite/a>->ea href="+code=key" class="sref">keye/a> ==uea href="+code=key" class="sref">keye/a>) {nu251e/a>                                        ea href="+code=_debug" class="sref">_debuge/a>(espa1 class="string">"found in cache"u252e/a>                                        *ea href="+code=_access" class="sref">_accesse/a> = ea href="+code=permit" class="sref">permite/a>->ea href="+code=access_mask" class="sref">access_maske/a>;nu253e/a>                                        ea href="+code=valid" class="sref">valide/a> = ea href="+code=true" class="sref">truee/a>;nu254e/a>                                        break;nu255e/a>                                }nu256e/a>                                ea href="+code=permit" class="sref">permite/a>++;nu257e/a>                        }nu258e/a>                }nu259e/a>                ea href="+code=rcu_read_unlock" class="sref">rcu_read_unlocke/a>();nu260e/a>        }nu261e/a>nu262e/a>        if (!ea href="+code=valid" class="sref">valide/a>) {nu263e/a>                espa1 class="comment">/* check the status on the file we're actually interested i1e/spa1onu264e/a>espa1 class="comment">                 * (the post-processing will cache the result on auth_vnode) */e/spa1onu265e/a>                ea href="+code=_debug" class="sref">_debuge/a>(espa1 class="string">"no valid permit"u266e/a>nu267e/a>                ea href="+code=set_bit" class="sref">set_bite/a>(ea href="+code=AFS_VNODE_CB_BROKEN" class="sref">AFS_VNODE_CB_BROKENe/a>, &ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=flags" class="sref">flagse/a>);nu268e/a>                ea href="+code=ret" class="sref">rete/a> = ea href="+code=afs_vnode_fetch_status" class="sref">afs_vnode_fetch_statuse/a>(ea href="+code=vnode" class="sref">vnodee/a>, ea href="+code=auth_vnode" class="sref">auth_vnodee/a>, ea href="+code=key" class="sref">keye/a>);nu269e/a>                if (ea href="+code=ret" class="sref">rete/a> < 0) {nu270e/a>                        ea href="+code=iput" class="sref">ipute/a>(&ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=vfs_inode" class="sref">vfs_inodee/a>);nu271e/a>                        *ea href="+code=_access" class="sref">_accesse/a> = 0;nu272e/a>                        ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">" = %d"rete/a>);nu273e/a>                        return ea href="+code=ret" class="sref">rete/a>;nu274e/a>                }nu275e/a>                *ea href="+code=_access" class="sref">_accesse/a> = ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=status" class="sref">statuse/a>.ea href="+code=caller_access" class="sref">caller_accesse/a>;nu276e/a>        }nu277e/a>nu278e/a>        ea href="+code=iput" class="sref">ipute/a>(&ea href="+code=auth_vnode" class="sref">auth_vnodee/a>->ea href="+code=vfs_inode" class="sref">vfs_inodee/a>);nu279e/a>        ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">" = 0 [access %x]"_accesse/a>);nu280e/a>        return 0;nu281e/a>}nu282e/a>nu283e/a>espa1 class="comment">/*e/spa1onu284e/a>espa1 class="comment"> * check the permissions on a1 AFS filee/spa1onu285e/a>espa1 class="comment"> * - AFS ACLs are attached to directories only, and a file is controlled by itse/spa1onu286e/a>espa1 class="comment"> *   parent directory's ACLe/spa1onu287e/a>espa1 class="comment"> */e/spa1onu288e/a>intuea href="+code=afs_permission" class="sref">afs_permissione/a>(structuea href="+code=inode" class="sref">inodee/a>u*ea href="+code=inode" class="sref">inodee/a>, intuea href="+code=mask" class="sref">maske/a>)nu289e/a>{nu290e/a>        structuea href="+code=afs_vnode" class="sref">afs_vnodee/a> *ea href="+code=vnode" class="sref">vnodee/a> = ea href="+code=AFS_FS_I" class="sref">AFS_FS_Ie/a>(ea href="+code=inode" class="sref">inodee/a>);nu291e/a>        ea href="+code=afs_access_t" class="sref">afs_access_te/a> ea href="+code=uninitialized_var" class="sref">uninitialized_vare/a>(ea href="+code=access" class="sref">accesse/a>);nu292e/a>        structuea href="+code=key" class="sref">keye/a> *ea href="+code=key" class="sref">keye/a>;nu293e/a>        intuea href="+code=ret" class="sref">rete/a>;nu294e/a>nu295e/a>        if (ea href="+code=mask" class="sref">maske/a> &uea href="+code=MAY_NOT_BLOCK" class="sref">MAY_NOT_BLOCKe/a>)nu296e/a>                return -ea href="+code=ECHILD" class="sref">ECHILDe/a>;nu297e/a>nu298e/a>        ea href="+code=_enter" class="sref">_entere/a>(espa1 class="string">"{{%x:%u},%lx},%x,"u299e/a>               ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=fid" class="sref">fide/a>.ea href="+code=vid" class="sref">vide/a>,uea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=fid" class="sref">fide/a>.ea href="+code=vnode" class="sref">vnodee/a>, ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=flags" class="sref">flagse/a>, ea href="+code=mask" class="sref">maske/a>);nu300e/a>nu301e/a>        ea href="+code=key" class="sref">keye/a> = ea href="+code=afs_request_key" class="sref">afs_request_keye/a>(ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=volume" class="sref">volumee/a>->ea href="+code=cell" class="sref">celle/a>);nu302e/a>        if (ea href="+code=IS_ERR" class="sref">IS_ERRe/a>(ea href="+code=key" class="sref">keye/a>)) {nu303e/a>                ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">" = %ld [key]"PTR_ERRe/a>(ea href="+code=key" class="sref">keye/a>));nu304e/a>                return ea href="+code=PTR_ERR" class="sref">PTR_ERRe/a>(ea href="+code=key" class="sref">keye/a>);nu305e/a>        }nu306e/a>nu307e/a>        espa1 class="comment">/* if the promise has expired, we need to check the server again */e/spa1onu308e/a>        if (!ea href="+code=vnode" class="sref">vnodee/a>->ea href="+code=cb_promised" class="sref">cb_promisede/a>) {nu309e/a>                ea href="+code=_debug" class="sref">_debuge/a>(espa1 class="string">"not promised"u310e/a>                ea href="+code=ret" class="sref">rete/a> = ea href="+code=afs_vnode_fetch_status" class="sref">afs_vnode_fetch_statuse/a>(ea href="+code=vnode" class="sref">vnodee/a>, ea href="+code=NULL" class="sref">NULLe/a>, ea href="+code=key" class="sref">keye/a>);nu311e/a>                if (ea href="+code=ret" class="sref">rete/a> < 0)nu312e/a>                        goto ea href="+code=error" class="sref">errore/a>;nu313e/a>                ea href="+code=_debug" class="sref">_debuge/a>(espa1 class="string">"new promise [fl=%lx]"vnodee/a>->ea href="+code=flags" class="sref">flagse/a>);nu314e/a>        }nu315e/a>nu316e/a>        espa1 class="comment">/* check the permits to see if we've got one yet */e/spa1onu317e/a>        ea href="+code=ret" class="sref">rete/a> = ea href="+code=afs_check_permit" class="sref">afs_check_permite/a>(ea href="+code=vnode" class="sref">vnodee/a>, ea href="+code=key" class="sref">keye/a>, &ea href="+code=access" class="sref">accesse/a>);nu318e/a>        if (ea href="+code=ret" class="sref">rete/a> < 0)nu319e/a>                goto ea href="+code=error" class="sref">errore/a>;nu320e/a>nu321e/a>        espa1 class="comment">/* interpret the access mask */e/spa1onu322e/a>        ea href="+code=_debug" class="sref">_debuge/a>(espa1 class="string">"REQ %x ACC %x on %s"u323e/a>               ea href="+code=mask" class="sref">maske/a>, ea href="+code=access" class="sref">accesse/a>, ea href="+code=S_ISDIR" class="sref">S_ISDIRe/a>(ea href="+code=inode" class="sref">inodee/a>->ea href="+code=i_mode" class="sref">i_modee/a>) ? espa1 class="string">"dir""file"u324e/a>nu325e/a>        if (ea href="+code=S_ISDIR" class="sref">S_ISDIRe/a>(ea href="+code=inode" class="sref">inodee/a>->ea href="+code=i_mode" class="sref">i_modee/a>)) {nu326e/a>                if (ea href="+code=mask" class="sref">maske/a> &uea href="+code=MAY_EXEC" class="sref">MAY_EXECe/a>) {nu327e/a>                        if (!(ea href="+code=access" class="sref">accesse/a> &uea href="+code=AFS_ACE_LOOKUP" class="sref">AFS_ACE_LOOKUPe/a>))nu328e/a>                                goto ea href="+code=permission_denied" class="sref">permission_deniede/a>;nu329e/a>                } else if (ea href="+code=mask" class="sref">maske/a> &uea href="+code=MAY_READ" class="sref">MAY_READe/a>) {nu330e/a>                        if (!(ea href="+code=access" class="sref">accesse/a> &uea href="+code=AFS_ACE_READ" class="sref">AFS_ACE_READe/a>))nu331e/a>                                goto ea href="+code=permission_denied" class="sref">permission_deniede/a>;nu332e/a>                } else if (ea href="+code=mask" class="sref">maske/a> &uea href="+code=MAY_WRITE" class="sref">MAY_WRITEe/a>) {nu333e/a>                        if (!(ea href="+code=access" class="sref">accesse/a> &u(ea href="+code=AFS_ACE_DELETE" class="sref">AFS_ACE_DELETEe/a> | espa1 class="comment">/* rmdir, unlink, renam
 from */e/spa1onu334e/a>                                        ea href="+code=AFS_ACE_INSERT" class="sref">AFS_ACE_INSERTe/a> | espa1 class="comment">/* create, mkdir, symlink, renam
 to */e/spa1onu335e/a>                                        ea href="+code=AFS_ACE_WRITE" class="sref">AFS_ACE_WRITEe/a>))) espa1 class="comment">/* chmod */e/spa1onu336e/a>                                goto ea href="+code=permission_denied" class="sref">permission_deniede/a>;nu337e/a>                } else {nu338e/a>                        ea href="+code=BUG" class="sref">BUGe/a>();nu339e/a>                }nu340e/a>        } else {nu341e/a>                if (!(ea href="+code=access" class="sref">accesse/a> &uea href="+code=AFS_ACE_LOOKUP" class="sref">AFS_ACE_LOOKUPe/a>))nu342e/a>                        goto ea href="+code=permission_denied" class="sref">permission_deniede/a>;nu343e/a>                if (ea href="+code=mask" class="sref">maske/a> &u(ea href="+code=MAY_EXEC" class="sref">MAY_EXECe/a> | ea href="+code=MAY_READ" class="sref">MAY_READe/a>)) {nu344e/a>                        if (!(ea href="+code=access" class="sref">accesse/a> &uea href="+code=AFS_ACE_READ" class="sref">AFS_ACE_READe/a>))nu345e/a>                                goto ea href="+code=permission_denied" class="sref">permission_deniede/a>;nu346e/a>                } else if (ea href="+code=mask" class="sref">maske/a> &uea href="+code=MAY_WRITE" class="sref">MAY_WRITEe/a>) {nu347e/a>                        if (!(ea href="+code=access" class="sref">accesse/a> &uea href="+code=AFS_ACE_WRITE" class="sref">AFS_ACE_WRITEe/a>))nu348e/a>                                goto ea href="+code=permission_denied" class="sref">permission_deniede/a>;nu349e/a>                }nu350e/a>        }nu351e/a>nu352e/a>        ea href="+code=key_put" class="sref">key_pute/a>(ea href="+code=key" class="sref">keye/a>);nu353e/a>        ea href="+code=ret" class="sref">rete/a> = ea href="+code=generic_permission" class="sref">generic_permissione/a>(ea href="+code=inode" class="sref">inodee/a>, ea href="+code=mask" class="sref">maske/a>);nu354e/a>        ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">" = %d"rete/a>);nu355e/a>        return ea href="+code=ret" class="sref">rete/a>;nu356e/a>nu357e/a>ea href="+code=permission_denied" class="sref">permission_deniede/a>:nu358e/a>        ea href="+code=ret" class="sref">rete/a> = -ea href="+code=EACCES" class="sref">EACCESe/a>;nu359e/a>ea href="+code=error" class="sref">errore/a>:nu360e/a>        ea href="+code=key_put" class="sref">key_pute/a>(ea href="+code=key" class="sref">keye/a>);nu361e/a>        ea href="+code=_leave" class="sref">_leavee/a>(espa1 class="string">" = %d"rete/a>);nu362e/a>        return ea href="+code=ret" class="sref">rete/a>;nu363e/a>}nu364e/a>e/pre>e/div>


e/div>