Beispiel #1
0
 def _convert_to_smtp(self, props, tag_data):
     if not hasattr(self.server, '_smtp_cache'): # XXX speed hack, discuss
         self.server._smtp_cache = {}
     for addrtype, email, entryid, name, searchkey in ADDR_PROPS:
         if addrtype not in tag_data or entryid not in tag_data or name not in tag_data:
             continue
         if tag_data[addrtype][1] in (u'SMTP', u'MAPIPDL'): # XXX MAPIPDL==distlist.. can we just dump this?
             continue
         eid = tag_data[entryid][1]
         if eid in self.server._smtp_cache:
             email_addr = self.server._smtp_cache[eid]
         else:
             try:
                 mailuser = self.server.ab.OpenEntry(eid, IID_IMailUser, 0)
                 email_addr = HrGetOneProp(mailuser, PR_SMTP_ADDRESS_W).Value
             except MAPIErrorUnknownEntryid: # XXX corrupt data? keep going but log problem
                 continue
             except MAPIErrorNotFound: # XXX deleted user, or no email address? or user with multiple entryids..heh?
                 continue
             except MAPIErrorInterfaceNotSupported: # XXX ZARAFA group?
                 continue
             self.server._smtp_cache[eid] = email_addr
         tag_data[addrtype][1] = u'SMTP'
         if email in tag_data:
             tag_data[email][1] = email_addr
         else:
             props.append([email, email_addr, None])
         tag_data[entryid][1] = self.server.ab.CreateOneOff(tag_data[name][1], u'SMTP', email_addr, MAPI_UNICODE)
         key = b'SMTP:' + email_addr.upper().encode('ascii')
         if searchkey in tag_data: # XXX probably need to create, also email
             tag_data[searchkey][1] = key
         else:
             props.append([searchkey, key, None])
Beispiel #2
0
    def _arch_item(
        self
    ):  # open archive store explicitly so we can handle otherwise silenced errors (MAPI errors in mail bodies for example)
        if self._architem is None:
            if self.stubbed:
                ids = self.mapiobj.GetIDsFromNames(NAMED_PROPS_ARCHIVER, 0)
                PROP_STORE_ENTRYIDS = CHANGE_PROP_TYPE(ids[0], PT_MV_BINARY)
                PROP_ITEM_ENTRYIDS = CHANGE_PROP_TYPE(ids[1], PT_MV_BINARY)

                # support for multiple archives was a mistake, and is not and _should not_ be used. so we just pick nr 0.
                arch_storeid = HrGetOneProp(self.mapiobj,
                                            PROP_STORE_ENTRYIDS).Value[0]
                item_entryid = HrGetOneProp(self.mapiobj,
                                            PROP_ITEM_ENTRYIDS).Value[0]

                try:
                    arch_store = self.server._store2(arch_storeid)
                except MAPIErrorUnconfigured:
                    raise Error(
                        'could not open archive store (check SSL settings?)')

                self._architem = arch_store.OpenEntry(item_entryid, None, 0)
            else:
                self._architem = self.mapiobj
        return self._architem
Beispiel #3
0
def prop(self, mapiobj, proptag, create=False, value=None, proptype=None):
    if isinstance(proptag, int) or \
       (isinstance(proptag, str) and ':' not in proptag):
        # search for property
        if isinstance(proptag, str):
            proptag = getattr(MAPI.Tags, proptag)
        try:
            sprop = HrGetOneProp(mapiobj, proptag)
        except MAPIErrorNotEnoughMemory:
            data = _utils.stream(mapiobj, proptag)
            sprop = SPropValue(proptag, data)
        except MAPIErrorNotFound:
            # not found, create it?
            if create:
                return create_prop(self,
                                   mapiobj,
                                   proptag,
                                   value=value,
                                   proptype=proptype)
            else:
                raise NotFoundError('no such property: %s' %
                                    REV_TAG.get(proptag, hex(proptag)))
        return Property(mapiobj, sprop)

    else:  # named property
        proptag2, proptype2, namespace, name = \
            _name_to_proptag(proptag, mapiobj, proptype)

        # search for property
        if proptype2:
            try:
                # TODO merge two main branches?
                sprop = HrGetOneProp(mapiobj, proptag2)
                return Property(mapiobj, sprop)
            except MAPIErrorNotEnoughMemory:
                data = _utils.stream(mapiobj, proptag2)
                sprop = SPropValue(proptag2, data)
                return Property(mapiobj, sprop)
            except MAPIErrorNotFound:
                pass
        else:
            # TODO sloow, streaming? default pidlid type-db?
            for prop in self.props(namespace=namespace):
                if prop.name == name:
                    return prop

        # not found, create it?
        if create:
            return create_prop(self,
                               mapiobj,
                               proptag,
                               value=value,
                               proptype=proptype)
        else:
            raise NotFoundError('no such property: %s' % proptag)
Beispiel #4
0
    def subtree(self):
        """:class:`Folder` designated as IPM.Subtree."""
        try:
            if self.public:
                ipmsubtreeid = HrGetOneProp(self.mapiobj, PR_IPM_PUBLIC_FOLDERS_ENTRYID).Value
            else:
                ipmsubtreeid = HrGetOneProp(self.mapiobj, PR_IPM_SUBTREE_ENTRYID).Value

            return _folder.Folder(self, _benc(ipmsubtreeid))
        except (MAPIErrorNotFound, NotFoundError):
            pass
Beispiel #5
0
    def subtree(self):
        """The user-visible store root :class:`Folder`."""
        try:
            if self.public:
                ipmsubtreeid = HrGetOneProp(
                    self.mapiobj, PR_IPM_PUBLIC_FOLDERS_ENTRYID).Value
            else:
                ipmsubtreeid = HrGetOneProp(self.mapiobj,
                                            PR_IPM_SUBTREE_ENTRYID).Value

            return _folder.Folder(self, _benc(ipmsubtreeid))
        except (MAPIErrorNotFound, NotFoundError):
            pass
Beispiel #6
0
    def _fbmsg_delgs(self):
        fbeid = self.root.prop(PR_FREEBUSY_ENTRYIDS).value[1]
        fbmsg = self.mapiobj.OpenEntry(fbeid, None, MAPI_MODIFY)

        try:
            entryids = HrGetOneProp(fbmsg, PR_SCHDINFO_DELEGATE_ENTRYIDS)
            names = HrGetOneProp(fbmsg, PR_SCHDINFO_DELEGATE_NAMES_W)
            flags = HrGetOneProp(fbmsg, PR_DELEGATE_FLAGS)
        except MAPIErrorNotFound:
            entryids = SPropValue(PR_SCHDINFO_DELEGATE_ENTRYIDS, [])
            names = SPropValue(PR_SCHDINFO_DELEGATE_NAMES_W, [])
            flags = SPropValue(PR_DELEGATE_FLAGS, [])

        return fbmsg, (entryids, names, flags)
Beispiel #7
0
 def journal(self):
     """The store :class:`journal folder <Folder>`."""
     try:
         return _folder.Folder(self, _benc(HrGetOneProp(
             self._root, PR_IPM_JOURNAL_ENTRYID).Value))
     except (MAPIErrorNotFound, NotFoundError):
         pass
Beispiel #8
0
 def _resolve_email(self, entryid=None):
     try:
         mailuser = self.mapisession.OpenEntry(entryid, None, 0)
         return self.user(HrGetOneProp(mailuser, PR_ACCOUNT_W).Value
                          ).email  # XXX PR_SMTP_ADDRESS_W from mailuser?
     except (Error, MAPIErrorNotFound):  # XXX deleted user
         return ''  # XXX groups
Beispiel #9
0
    def rules_dumps(self, stats=None):
        server = self.server
        log = server.log

        ruledata = None
        with _log.log_exc(log, stats):
            try:
                ruledata = self.prop(PR_RULES_DATA).value
            except (MAPIErrorNotFound, NotFoundError):
                pass
            else:
                etxml = ElementTree.fromstring(ruledata)
                for actions in etxml.findall('./item/item/actions'):
                    for movecopy in actions.findall('.//moveCopy'):
                        try:
                            s = movecopy.findall('store')[0]
                            store = server.mapisession.OpenMsgStore(
                                0, _unbase64(s.text), None, 0)
                            entryid = HrGetOneProp(store,
                                                   PR_STORE_ENTRYID).Value
                            store = server.store(entryid=_benc(entryid))
                            if store.public:
                                s.text = 'public'
                            else:
                                s.text = store.user.name if store != self.store else ''
                            f = movecopy.findall('folder')[0]
                            path = store.folder(
                                entryid=_benc(_unbase64(f.text))).path
                            f.text = path
                        except Exception as e:
                            log.warning("could not resolve rule target: %s",
                                        str(e))
                ruledata = ElementTree.tostring(etxml)

        return _utils.pickle_dumps({b'data': ruledata})
Beispiel #10
0
    def _set_special_folder(self, folder, proptag, container_class=None):
        _root = self.mapiobj.OpenEntry(None, None, MAPI_MODIFY)

        if isinstance(proptag, tuple):
            proptag, idx = proptag
            try:
                value = HrGetOneProp(self._root, proptag).Value
            except MAPIErrorNotFound:
                value = 5 * [b'']
            value[idx] = _bdec(folder.entryid)
            _root.SetProps([SPropValue(proptag, value)])
            if self.inbox:
                self.inbox.mapiobj.SetProps([SPropValue(proptag, value)])
        else:
            _root.SetProps([SPropValue(proptag, _bdec(folder.entryid))])
            if self.inbox:
                self.inbox.mapiobj.SetProps(
                    [SPropValue(proptag, _bdec(folder.entryid))])
        _utils._save(self._root)

        if container_class:
            folder.container_class = container_class
        else:
            prop = folder.get_prop(PR_CONTAINER_CLASS_W)
            if prop:
                folder.delete(prop)
Beispiel #11
0
def dump_rules(folder, user, server, stats, log):
    """ dump rules for given folder """

    ruledata = None
    with log_exc(log, stats):
        try:
            ruledata = folder.prop(PR_RULES_DATA).value
        except (MAPIErrorNotFound, kopano.NotFoundError):
            pass
        else:
            etxml = ElementTree.fromstring(ruledata)
            for actions in etxml.findall('./item/item/actions'):
                for movecopy in actions.findall('.//moveCopy'):
                    try:
                        s = movecopy.findall('store')[0]
                        store = server.mapisession.OpenMsgStore(0, _unbase64(s.text), None, 0)
                        guid = _hex(HrGetOneProp(store, PR_STORE_RECORD_KEY).Value)
                        store = server.store(guid) # XXX guid doesn't work for multiserver?
                        if store.public:
                            s.text = 'public'
                        else:
                            s.text = store.user.name if store != user.store else ''
                        f = movecopy.findall('folder')[0]
                        path = store.folder(entryid=_hex(_unbase64(f.text))).path
                        f.text = path
                    except (MAPIErrorNotFound, kopano.NotFoundError, binascii.Error):
                        log.warning("cannot serialize rule for unknown store/folder")
            ruledata = ElementTree.tostring(etxml)
    return pickle_dumps(ruledata)
Beispiel #12
0
 def enabled(self):
     """Auto-processing is enabled."""
     prop = CHANGE_PROP_TYPE(self._ids[0], PT_BOOLEAN)
     try:
         return HrGetOneProp(self._fb, prop).Value
     except MAPIErrorNotFound:
         return True
Beispiel #13
0
 def user(self):
     """Store :class:`owner <User>`."""
     try:
         userid = HrGetOneProp(self.mapiobj, PR_MAILBOX_OWNER_ENTRYID).Value # XXX
         return _user.User(self.server.sa.GetUser(userid, MAPI_UNICODE).Username, self.server)
     except (MAPIErrorNotFound, NotFoundError):
         pass
Beispiel #14
0
 def junk(self):
     """:class:`Folder` designated as junk."""
     # PR_ADDITIONAL_REN_ENTRYIDS is a multi-value property, 4th entry is the junk folder
     try:
         return _folder.Folder(self, _benc(HrGetOneProp(self._root, PR_ADDITIONAL_REN_ENTRYIDS).Value[4]))
     except (MAPIErrorNotFound, NotFoundError):
         pass
Beispiel #15
0
    def __init__(self, parent_mapiobj,
                 mapiobj):  # XXX rethink attributes, names.. add guidname..?
        self._parent_mapiobj = parent_mapiobj
        #: Property tag, e.g. 0x37001f for PR_SUBJECT
        self.proptag = mapiobj.ulPropTag

        if PROP_TYPE(
                mapiobj.ulPropTag
        ) == PT_ERROR and mapiobj.Value == MAPI_E_NOT_ENOUGH_MEMORY:
            if PROP_ID(
                    self.proptag) == PROP_ID(PR_BODY_W):  # avoid slow guessing
                self.proptag = PR_BODY_W
                mapiobj = SPropDelayedValue(parent_mapiobj, self.proptag)
            elif PROP_ID(self.proptag) in (PROP_ID(PR_RTF_COMPRESSED),
                                           PROP_ID(PR_HTML)):
                self.proptag = PROP_TAG(PT_BINARY, PROP_ID(self.proptag))
                mapiobj = SPropDelayedValue(parent_mapiobj, self.proptag)
            else:  # XXX possible to use above trick to infer all proptags?
                for proptype in (PT_BINARY,
                                 PT_UNICODE):  # XXX slow, incomplete?
                    proptag = (mapiobj.ulPropTag & 0xffff0000) | proptype
                    try:
                        HrGetOneProp(
                            parent_mapiobj, proptag
                        )  # XXX: Unicode issue?? calls GetProps([proptag], 0)
                        self.proptag = proptag  # XXX isn't it strange we can get here
                    except MAPIErrorNotEnoughMemory:
                        mapiobj = SPropDelayedValue(parent_mapiobj, proptag)
                        self.proptag = proptag
                        break
                    except MAPIErrorNotFound:
                        pass

        self.id_ = self.proptag >> 16
        self.mapiobj = mapiobj
        self._value = None

        self.idname = REV_TAG.get(self.proptag)
        self.type_ = PROP_TYPE(self.proptag)
        self.typename = REV_TYPE.get(self.type_)
        self.named = False
        self.kind = None
        self.kindname = None
        self.guid = None
        self.name = None
        self.namespace = None

        if self.id_ >= 0x8000:  # possible named prop
            try:
                lpname = self._parent_mapiobj.GetNamesFromIDs([self.proptag],
                                                              None, 0)[0]
                if lpname:
                    self.guid = bin2hex(lpname.guid)
                    self.namespace = GUID_NAMESPACE.get(lpname.guid)
                    self.name = lpname.id
                    self.kind = lpname.kind
                    self.kindname = 'MNID_STRING' if lpname.kind == MNID_STRING else 'MNID_ID'
                    self.named = True
            except MAPIErrorNoSupport:  # XXX user.props()?
                pass
Beispiel #16
0
 def tasks(self):
     """The store :class:`tasks folder <Folder>`."""
     try:
         return _folder.Folder(self,
             _benc(HrGetOneProp(self._root, PR_IPM_TASK_ENTRYID).Value))
     except (MAPIErrorNotFound, NotFoundError):
         pass
Beispiel #17
0
 def root(self):
     """:class:`Folder` designated as store root."""
     try:
         return _folder.Folder(
             self, _benc(HrGetOneProp(self._root, PR_ENTRYID).Value))
     except (MAPIErrorNotFound, NotFoundError):
         pass
Beispiel #18
0
    def __init__(self, parent_mapiobj, mapiobj):
        self._parent_mapiobj = parent_mapiobj
        #: MAPI proptag, for example 0x37001f for PR_SUBJECT_W
        self.proptag = mapiobj.ulPropTag

        if (PROP_TYPE(mapiobj.ulPropTag) == PT_ERROR and \
            mapiobj.Value == MAPI_E_NOT_ENOUGH_MEMORY):
            # avoid slow guessing
            if PROP_ID(self.proptag) == PROP_ID(PR_BODY_W):
                self.proptag = PR_BODY_W
                mapiobj = SPropDelayedValue(parent_mapiobj, self.proptag)
            elif PROP_ID(self.proptag) in \
                (PROP_ID(PR_RTF_COMPRESSED), PROP_ID(PR_HTML)):
                self.proptag = CHANGE_PROP_TYPE(self.proptag, PT_BINARY)
                mapiobj = SPropDelayedValue(parent_mapiobj, self.proptag)
            else:  # TODO possible to use above trick to infer all proptags?
                # TODO slow, incomplete?
                for proptype in (PT_BINARY, PT_UNICODE):
                    proptag = (mapiobj.ulPropTag & 0xffff0000) | proptype
                    try:
                        # TODO: Unicode issue?? calls GetProps([proptag], 0)
                        HrGetOneProp(parent_mapiobj, proptag)
                        # TODO how did we end up here, why is this possible
                        self.proptag = proptag
                    except MAPIErrorNotEnoughMemory:
                        mapiobj = SPropDelayedValue(parent_mapiobj, proptag)
                        self.proptag = proptag
                        break
                    except MAPIErrorNotFound:
                        pass

        self.mapiobj = mapiobj

        self._value = None
        self.__lpname = None
Beispiel #19
0
 def findroot(self):
     """The user-invisible store search folder :class:`Folder`."""
     try:
         return _folder.Folder(self,
             _benc(HrGetOneProp(self.mapiobj, PR_FINDER_ENTRYID).Value))
     except (MAPIErrorNotFound, NotFoundError):
         pass
Beispiel #20
0
    def __init__(self,
                 store=None,
                 entryid=None,
                 associated=False,
                 deleted=False,
                 mapiobj=None,
                 _check_mapiobj=True,
                 cache={}):
        if store:
            self.store = store
            self.server = store.server
        # XXX else, determine store dynamically?
        if mapiobj:
            self._mapiobj = mapiobj
            self._entryid = HrGetOneProp(self.mapiobj, PR_ENTRYID).Value
        elif entryid:
            try:
                self._entryid = _bdec(entryid)
            except:
                raise ArgumentError('invalid entryid: %r' % entryid)

        self.content_flag = MAPI_ASSOCIATED if associated else (
            SHOW_SOFT_DELETES if deleted else 0)
        self._sourcekey = None
        self._mapiobj = None

        if _check_mapiobj:  # raise error for specific key
            self.mapiobj

        self._cache = cache
        self._iter = None
Beispiel #21
0
 def calendar(self):
     """The store (default) :class:`calendar <Folder>`."""
     try:
         return _folder.Folder(self,_benc(HrGetOneProp(
             self._root, PR_IPM_APPOINTMENT_ENTRYID).Value))
     except (MAPIErrorNotFound, NotFoundError):
         pass
Beispiel #22
0
    def __init__(self, parent_mapiobj, mapiobj):
        self._parent_mapiobj = parent_mapiobj
        self.proptag = mapiobj.ulPropTag

        if PROP_TYPE(
                mapiobj.ulPropTag
        ) == PT_ERROR and mapiobj.Value == MAPI_E_NOT_ENOUGH_MEMORY:
            if PROP_ID(
                    self.proptag) == PROP_ID(PR_BODY_W):  # avoid slow guessing
                self.proptag = PR_BODY_W
                mapiobj = SPropDelayedValue(parent_mapiobj, self.proptag)
            elif PROP_ID(self.proptag) in (PROP_ID(PR_RTF_COMPRESSED),
                                           PROP_ID(PR_HTML)):
                self.proptag = CHANGE_PROP_TYPE(self.proptag, PT_BINARY)
                mapiobj = SPropDelayedValue(parent_mapiobj, self.proptag)
            else:  # XXX possible to use above trick to infer all proptags?
                for proptype in (PT_BINARY,
                                 PT_UNICODE):  # XXX slow, incomplete?
                    proptag = (mapiobj.ulPropTag & 0xffff0000) | proptype
                    try:
                        HrGetOneProp(
                            parent_mapiobj, proptag
                        )  # XXX: Unicode issue?? calls GetProps([proptag], 0)
                        self.proptag = proptag  # XXX isn't it strange we can get here
                    except MAPIErrorNotEnoughMemory:
                        mapiobj = SPropDelayedValue(parent_mapiobj, proptag)
                        self.proptag = proptag
                        break
                    except MAPIErrorNotFound:
                        pass

        self.mapiobj = mapiobj

        self._value = None
        self.__lpname = None
Beispiel #23
0
 def outbox(self):
     """The store :class:`outbox <Folder>`."""
     try:
         return _folder.Folder(self,
             _benc(HrGetOneProp(self.mapiobj, PR_IPM_OUTBOX_ENTRYID).Value))
     except (MAPIErrorNotFound, NotFoundError):
         pass
Beispiel #24
0
 def root(self):
     """The user-invisible store root :class:`Folder`."""
     try:
         return _folder.Folder(
             self, _benc(HrGetOneProp(self._root, PR_ENTRYID).Value))
     except (MAPIErrorNotFound, NotFoundError):
         pass
Beispiel #25
0
 def contacts(self):
     """The store (default) :class:`contacts folder <Folder>`."""
     try:
         return _folder.Folder(self,
             _benc(HrGetOneProp(self._root, PR_IPM_CONTACT_ENTRYID).Value))
     except (MAPIErrorNotFound, NotFoundError):
         pass
Beispiel #26
0
 def wastebasket(self):
     """The store :class:`wastebasket <Folder>`."""
     try:
         return _folder.Folder(self, _benc(HrGetOneProp(
             self.mapiobj, PR_IPM_WASTEBASKET_ENTRYID).Value))
     except (MAPIErrorNotFound, NotFoundError):
         pass
Beispiel #27
0
 def sentmail(self):
     """The store :class:`sentmail folder <Folder>`."""
     try:
         return _folder.Folder(self, _benc(HrGetOneProp(
             self.mapiobj, PR_IPM_SENTMAIL_ENTRYID).Value))
     except (MAPIErrorNotFound, NotFoundError):
         pass
Beispiel #28
0
    def archive_folder(self):
        """ Archive :class:`Folder` """

        ids = self.mapiobj.GetIDsFromNames(NAMED_PROPS_ARCHIVER, 0) # XXX merge namedprops stuff
        PROP_STORE_ENTRYIDS = CHANGE_PROP_TYPE(ids[0], PT_MV_BINARY)
        PROP_ITEM_ENTRYIDS = CHANGE_PROP_TYPE(ids[1], PT_MV_BINARY)

        try:
            # support for multiple archives was a mistake, and is not and _should not_ be used. so we just pick nr 0.
            arch_storeid = HrGetOneProp(self.mapiobj, PROP_STORE_ENTRYIDS).Value[0]
            arch_folderid = HrGetOneProp(self.mapiobj, PROP_ITEM_ENTRYIDS).Value[0]
        except MAPIErrorNotFound:
            return

        archive_store = self.server._store2(arch_storeid)
        return _store.Store(mapiobj=archive_store, server=self.server).folder(entryid=_benc(arch_folderid))
Beispiel #29
0
 def company(self):
     """:class:`Company` the user belongs to."""
     try:
         return _company.Company(HrGetOneProp(self.mapiobj,
             PR_EC_COMPANY_NAME_W).Value, self.server)
     except MAPIErrorNoSupport:
         return _company.Company('Default', self.server)
Beispiel #30
0
 def folder(self):
     """ Parent :class:`Folder` of an item """
     if self._folder:
         return self._folder
     try:
         return _folder.Folder(self.store, _benc(HrGetOneProp(self.mapiobj, PR_PARENT_ENTRYID).Value))
     except (MAPIErrorNotFound, NotFoundError):
         pass