⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acm.py

📁 xen虚拟机源代码安装包
💻 PY
📖 第 1 页 / 共 4 页
字号:
    res = get_resource_label(resource)    return format_resource_label(res)def format_resource_label(res):    if res:        if len(res) == 2:            return xsconstants.ACM_POLICY_ID + ":" + res[0] + ":" + res[1]        if len(res) == 3:            return ":".join(res)    return ""def get_resource_label(resource):    """       Xend exports this function via XML-RPC.       Get the assigned resource label of a given resource    @param resource: The name of a resource, i.e., "phy:/dev/hda"    @rtype: list    @return tuple of (policy name, resource label), i.e., (xm-test, blue)    """    try:        resource = unify_resname(resource, mustexist=False)    except Exception:        return []    reslabel_map = get_labeled_resources()    if reslabel_map.has_key(resource):        return list(reslabel_map[resource])    else:        #Try to resolve each label entry        for key, value in reslabel_map.items():            try:                if resource == unify_resname(key):                    return list(value)            except:                pass    return []def get_labeled_resources_xapi():    """ Get a map of all labeled resource with the labels formatted in the        xen-api resource label format.    """    reslabel_map = get_labeled_resources()    for key, labeldata in reslabel_map.items():        reslabel_map[key] = format_resource_label(labeldata)    return reslabel_mapdef get_labeled_resources():    """        Xend exports this function via XML-RPC        Get a map of all labeled resources.    @rtype: list    @return list of labeled resources    """    try:        resfile_lock()        try:            access_control = dictio.dict_read("resources", res_label_filename)        except:            return {}    finally:        resfile_unlock()    return access_controldef relabel_domains(relabel_list):    """      Relabel the given domains to have a new ssidref.      @param relabel_list: a list containing tuples of domid, ssidref                           example: [ [0, 0x00020002] ]    """    rel_rules = ""    for r in relabel_list:        log.info("Relabeling domain with domid %d to new ssidref 0x%08x",                r[0], r[1])        rel_rules += struct.pack("ii", r[0], r[1])    try:        rc, errors = acm.relabel_domains(rel_rules)    except Exception, e:        log.info("Error after relabel_domains: %s" % str(e))        rc = -xsconstants.XSERR_GENERAL_FAILURE        errors = ""    if (len(errors) > 0):        rc = -xsconstants.XSERR_HV_OP_FAILED    return rc, errorsdef __update_label_policy_change(sec_lab,                                 cur_poltype,                                 cur_polname,                                 new_poltype,                                 new_polname,                                 polnew_labels,                                 label_map):    """    Determine a new resource label given the new policy's type    and name and the new policy's (resource/VM) labels and the    (resource/VM) label map that indicates renaming rules for    labels.    """    is_deleted = False    policytype, policy, label = sec_lab    if cur_poltype != policytype or \       cur_polname != policy:        return sec_lab, is_deleted    if policytype != xsconstants.ACM_POLICY_ID:        return sec_lab, is_deleted    elif label_map.has_key(label) and policy == cur_polname:        # renaming of an active label; policy may have been renamed        label = label_map[label]        polname = new_polname    elif label not in polnew_labels:        # label been removed        policytype = xsconstants.INVALID_POLICY_PREFIX + policytype        polname = policy        is_deleted = True    else:        # no change to label        policytype = xsconstants.ACM_POLICY_ID        polname = new_polname    return tuple( [ policytype, polname, label ] ), is_deleteddef change_acm_policy(bin_pol, del_array, chg_array,                      vmlabel_map, reslabel_map, cur_acmpol, new_acmpol,                      is_reset):    """       Change the ACM policy of the system by relabeling       domains and resources first and doing some access checks.       Then update the policy in the hypervisor. If this is all successful,       relabel the domains permanently and commit the relabed resources.       Need to do / check the following:        - relabel all resources where there is a 'from' field in          the policy. [ NOT DOING THIS: and mark those as unlabeled where the label          does not appear in the new policy anymore (deletion) ]        - relabel all VMs where there is a 'from' field in the          policy and mark those as unlabeled where the label          does not appear in the new policy anymore; no running          or paused VM may be unlabeled through this        - check that under the new labeling conditions the VMs          still have access to their resources as before. Unlabeled          resources are inaccessible. If this check fails, the          update failed.        - Attempt changes in the hypervisor; if this step fails,          roll back the relabeling of resources and VMs        - Make the relabeling of resources and VMs permanent       This function should be called with the lock to the domains       held (XendDomain.instance().domains_lock)    """    from xen.util.acmpolicy import ACM_LABEL_UNLABELED    rc = xsconstants.XSERR_SUCCESS    domain_label_map = {}    new_policyname = new_acmpol.get_name()    new_policytype = new_acmpol.get_type_name()    cur_policyname = cur_acmpol.get_name()    cur_policytype = cur_acmpol.get_type_name()    polnew_reslabels = new_acmpol.policy_get_resourcelabel_names()    errors=""    try:        resfile_lock()        mapfile_lock()        # Get all domains' dominfo.        from xen.xend import XendDomain        dominfos = XendDomain.instance().list('all')        log.info("----------------------------------------------")        label_changes = []        # relabel resources        access_control = {}        try:            access_control = dictio.dict_read("resources", res_label_filename)        except:            pass        for key, labeldata in access_control.items():            if len(labeldata) == 2:                policy, label = labeldata                policytype = xsconstants.ACM_POLICY_ID            elif len(labeldata) == 3:                policytype, policy, label = labeldata            else:                return -xsconstants.XSERR_BAD_LABEL_FORMAT, ""            new_sec_lab, is_deleted = \                __update_label_policy_change( tuple([policytype,                                                     policy,                                                     label]),                                             cur_policytype,                                             cur_policyname,                                             new_policytype,                                             new_policyname,                                             polnew_reslabels,                                             reslabel_map)            if is_deleted:                label_changes.append(key)            # Update entry            access_control[key] = new_sec_lab        # All resources have new labels in the access_control map        # There may still be labels in there that are invalid now.        # Do this in memory without writing to disk:        #  - Relabel all domains independent of whether they are running        #    or not        #  - later write back to config files        polnew_vmlabels = new_acmpol.policy_get_virtualmachinelabel_names()        for dominfo in dominfos:            sec_lab = dominfo.get_security_label()            if not sec_lab:                continue            policytype, policy, vmlabel = sec_lab.split(":")            name  = dominfo.getName()            if policytype != cur_policytype or \               policy     != cur_policyname:                continue            new_vmlabel = vmlabel            if vmlabel_map.has_key(vmlabel) and \               (not is_reset or name == "Domain-0") :                # renaming of the label; this is only allowed if it's                # not a reset of the policy or if it is a reset, then                # only for Domain-0                new_vmlabel = vmlabel_map[vmlabel]                polname = new_policyname            elif new_vmlabel not in polnew_vmlabels and \               vmlabel != ACM_LABEL_UNLABELED:                # removal of VM label and not the 'unlabeled' label                policytype = xsconstants.INVALID_POLICY_PREFIX + policytype                polname = policy            else:                polname = new_policyname            new_seclab = "%s:%s:%s" % \                    (policytype, polname, new_vmlabel)            domain_label_map[dominfo] = [ sec_lab, new_seclab ]            if dominfo._stateGet() in (DOM_STATE_PAUSED, DOM_STATE_RUNNING):                compatible = __resources_compatible_with_vmlabel(new_acmpol,                                                      dominfo,                                                      new_vmlabel,                                                      access_control,                                                      is_policy_update=True)                log.info("Domain %s with new label '%s' can access its "                         "resources? : %s" %                         (name, new_vmlabel, str(compatible)))                log.info("VM labels in new policy: %s" %                         new_acmpol.policy_get_virtualmachinelabel_names())                if not compatible:                    return (-xsconstants.XSERR_RESOURCE_ACCESS, "")        for dominfo in dominfos:            # relabel the VIF interfaces            changed = False            for vif_uuid in dominfo.get_vifs():                sec_lab = dominfo.info['devices'][vif_uuid][1]\                                 .get('security_label')                if sec_lab:                    result, _ = \                        __update_label_policy_change(tuple(sec_lab.split(':')),                                                     cur_policytype,                                                     cur_policyname,                                                     new_policytype,                                                     new_policyname,                                                     polnew_reslabels,                                                     reslabel_map)                    new_sec_lab = ':'.join(list(result))                    if new_sec_lab != sec_lab:                        changed = True                        dominfo.info['devices'][vif_uuid][1]\                                    ['security_label'] = new_sec_lab            if changed:                XendDomain.instance().managed_config_save(dominfo)        rc, errors = hv_chg_policy(bin_pol, del_array, chg_array)        if rc == 0:            for key in label_changes:                run_resource_label_change_script(key, "", "remove")            # Write the relabeled resources back into the file            dictio.dict_write(access_control, "resources", res_label_filename)            # Properly update all VMs to their new labels            for dominfo, labels in domain_label_map.items():                sec_lab, new_seclab = labels                if sec_lab != new_seclab:                    log.info("Updating domain %s to new label '%s'." % \                             (dominfo.getName(), new_seclab))                    # This better be working!                    res = dominfo.set_security_label(new_seclab,                                                     sec_lab,                                                     new_acmpol,                                                     cur_acmpol)                    if res[0] != xsconstants.XSERR_SUCCESS:                        log.info("ERROR: Could not chg label on domain %s: %s" %                                 (dominfo.getName(),                                  xsconstants.xserr2string(-int(res[0]))))    finally:        log.info("----------------------------------------------")        mapfile_unlock()        resfile_unlock()    return rc, errorsdef parse_security_label(security_label):    tmp = security_label.split(":")    if len(tmp) != 3:        return ""    else:        return security_labeldef set_security_label(policy, label):    if label and policy and label != "" and policy != "":        return "%s:%s:%s" % (xsconstants.ACM_POLICY_ID, policy, label)    else:        return ""def ssidref2security_label(ssidref):    from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance    return XSPolicyAdminInstance().ssidref_to_vmlabel(ssidref)def get_security_label(self, xspol=None):    """       Get the security label of a domain       @param xspol   The policy to use when converting the ssid into                      a label; only to be passed during the updating                      of the policy    """    domid = self.getDomid()    if not xspol:        from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance        xspol = XSPolicyAdminInstance().get_loaded_policy()    label = ""    if xspol:        label = xspol.policy_get_domain_label_formatted(domid)    if domid != 0:        label = self.info.get('security_label', label)    return labeldef check_can_run(sec_label):    """ Check whether a VM could run, given its vm label. A VM can run if       - it is authorized       - is not in conflict with any running domain    """    try:        mapfile_lock()        if sec_label == None or sec_label == "":            vm_label = ACM_LABEL_UNLABELED        else:            poltype, policy, vm_label = sec_label.split(':')            if policy != get_active_policy_name():                return -xsconstants.XSERR_BAD_POLICY_NAME        ssidref = label2ssidref(vm_label, policy, 'dom')        if ssidref != xsconstants.INVALID_SSIDREF:            if not has_authorization(ssidref):                return -xsconstants.XSERR_VM_NOT_AUTHORIZED            if is_in_conflict(ssidref):                return -xsconstants.XSERR_VM_IN_CONFLICT            return -xsconstants.XSERR_SUCCESS        else:            return -xsconstants.XSERR_BAD_LABEL    finally:        mapfile_unlock()__cond = threading.Condition()__script_runner = None__orders = []def run_resource_label_change_script(resource, label, command):    global __cond, __orders, __script_runner    def __run_resource_label_change_script():        global __cond, __orders        script = XendOptions.instance().get_resource_label_change_script()        if script:            parms = {}            while True:                __cond.acquire()                if len(__orders) == 0:                    __cond.wait()                parms['label'], \                   parms['command'], \                   parms['resource'] = __orders[0]                __orders = __orders[1:]                __cond.release()                log.info("Running resource label change script %s: %s" %                         (script, parms))                parms.update(os.environ)                os.spawnve(os.P_WAIT, script[0], script, parms)        else:            log.info("No script given for relabeling of resources.")    if not __script_runner:        __script_runner = \                 threading.Thread(target=__run_resource_label_change_script,                                  args=())        __script_runner.start()    __cond.acquire()    __orders.append((label,command,resource))    __cond.notify()    __cond.release()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -