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

📄 acm.py

📁 xen 3.2.2 源码
💻 PY
📖 第 1 页 / 共 4 页
字号:
    try:        resfile_lock()        access_control = {}        try:             access_control = dictio.dict_read("resources", res_label_filename)        except:            pass        if oreslabel:            if not access_control.has_key(resource):                return -xsconstants.XSERR_BAD_LABEL            tmp = access_control[resource]            if len(tmp) != 3:                return -xsconstants.XSERR_BAD_LABEL            if tmp[2] != oreslabel:                return -xsconstants.XSERR_BAD_LABEL        if reslabel != "":            new_entry = { resource : tuple([policytype, policyref, reslabel])}            access_control.update(new_entry)            command = "add"            reslbl = ":".join([policytype, policyref, reslabel])        else:            if access_control.has_key(resource):                del access_control[resource]            command = "remove"            reslbl = ""        run_resource_label_change_script(resource, reslbl, command)        dictio.dict_write(access_control, "resources", res_label_filename)    finally:        resfile_unlock()    return xsconstants.XSERR_SUCCESSdef rm_resource_label(resource, oldlabel_xapi):    """Remove a resource label from a physical resource    @param resource: The name of a resource, i.e., "phy:/dev/hda"    @rtype: int    @return Success (0) or failure value (< 0)    """    tmp = oldlabel_xapi.split(":")    if len(tmp) != 3:        return -xsconstants.XSERR_BAD_LABEL_FORMAT    otyp, opolicyref, olabel = tmp    # Only ACM is supported    if otyp != xsconstants.ACM_POLICY_ID and \       otyp != xsconstants.INVALID_POLICY_PREFIX + xsconstants.ACM_POLICY_ID:        return -xsconstants.XSERR_WRONG_POLICY_TYPE    return set_resource_label(resource, "", "", "", olabel)def get_resource_label_xapi(resource):    """Get the assigned resource label of a physical resource      in the format used by then Xen-API, i.e., "ACM:xm-test:blue"      @rtype: string      @return the string representing policy type, policy name and label of              the resource    """    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 change_acm_policy(bin_pol, del_array, chg_array,                      vmlabel_map, reslabel_map, cur_acmpol, new_acmpol):    """       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("----------------------------------------------")        # 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, ""            if policytype != cur_policytype or \               policy     != cur_policyname:                continue            # label been renamed or deleted?            if policytype != xsconstants.ACM_POLICY_ID:                continue            elif reslabel_map.has_key(label) and cur_policyname == policy:                # renaming of an active label; policy may have been renamed                label = reslabel_map[label]                polname = new_policyname            elif label not in polnew_reslabels:                # label been removed                policytype = xsconstants.INVALID_POLICY_PREFIX + policytype                run_resource_label_change_script(key, "", "remove")                polname = policy            else:                # no change to label                policytype = xsconstants.ACM_POLICY_ID                polname = new_policyname            # Update entry            access_control[key] = \                   tuple([ policytype, polname, label ])        # 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):                # renaming of the label                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, "")        rc, errors = hv_chg_policy(bin_pol, del_array, chg_array)        if rc == 0:            # 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 label__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 + -