123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108(*
* Copyright (C) Citrix Systems Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; version 2.1 only. with the special
* exception on linking described in file LICENSE.
*
* 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 Lesser General Public License for more details.
*)letinfofmt=Logging.info"perms"fmtexceptionPermission_denied(* permission of connections *)openXs_protocol.ACLtypeelt=domid*(permlist)typet={main:elt;target:eltoption;}letsuperuser:t={main=0,[READ;WRITE];target=None}letof_domaindomid:t={main=(domid,[READ;WRITE]);target=None}letset_target(connection:t)domid={connectionwithtarget=Some(domid,[READ;WRITE])}letget_owners(connection:t)=matchconnection.main,connection.targetwith|c1,Somec2->[fstc1;fstc2]|c1,None->[fstc1]letis_owner(connection:t)id=matchconnection.targetwith|Sometarget->fstconnection.main=id||fsttarget=id|None->fstconnection.main=idletis_dom0(connection:t)=is_ownerconnection0letrestrict(connection:t)domid=matchconnection.target,connection.mainwith|None,(0,perms)->info"restricting connection from domid %d to domid %d"0domid;{connectionwithmain=(domid,perms)}|_->raisePermission_deniedtypepermission=|READ|WRITE|CHANGE_ACL|DEBUG|INTRODUCE|ISINTRODUCED|RESUME|RELEASE|SET_TARGET|RESTRICT|CONFIGURElethas(t:t)_p=ifnot(is_dom0t)thenraisePermission_denied(* check if owner of the current connection and of the current node are the same *)letcheck_owner(connection:t)(node:Xs_protocol.ACL.t)=ifnot(is_dom0connection)thenis_ownerconnectionnode.Xs_protocol.ACL.ownerelsetrue(* check if the current connection has the requested perm on the current node *)letcheck(connection:t)request(node:Xs_protocol.ACL.t)=letcheck_acldomainid=letperm=ifList.mem_assocdomainidnode.Xs_protocol.ACL.aclthenList.assocdomainidnode.Xs_protocol.ACL.aclelsenode.Xs_protocol.ACL.otherinmatchperm,requestwith|Xs_protocol.ACL.NONE,_->info"Permission denied: Domain %d has no permission"domainid;false|Xs_protocol.ACL.RDWR,_->true|Xs_protocol.ACL.READ,READ->true|Xs_protocol.ACL.WRITE,WRITE->true|Xs_protocol.ACL.READ,_->info"Permission denied: Domain %d has read only access"domainid;false|Xs_protocol.ACL.WRITE,_->info"Permission denied: Domain %d has write only access"domainid;falseiniftrue&¬(is_dom0connection)&¬(check_ownerconnectionnode)&¬(List.existscheck_acl(get_ownersconnection))thenraisePermission_denied