HRESULT ExchangeMigrationSetup::Clean() { try { m_exchAdmin->DeleteProfile(DEFAULT_ADMIN_PROFILE_NAME); } catch (Zimbra::MAPI::ExchangeAdminException &ex) { dloge("DeleteProfile exception: %S", ex.Description().c_str()); throw; } try { m_exchAdmin->DeleteExchangeMailBox(DEFAULT_ADMIN_MAILBOX_NAME, m_ExchangeAdminName.c_str(), m_ExchangeAdminPwd.c_str()); } catch (Zimbra::MAPI::ExchangeAdminException &ex) { dloge("DeleteExchangeMailBox exception: %S", ex.Description().c_str()); throw; } catch (Zimbra::MAPI::Util::MapiUtilsException &ex) { dloge("DeleteExchangeMailBox(MAPIUtils) exception: %S", ex.Description().c_str()); throw; } return S_OK; }
HRESULT ExchangeAdmin::DeleteExchangeMailBox(LPCWSTR lpwstrMailBox, LPCWSTR lpwstrlogonuser, LPCWSTR lpwstrLogonUsrPwd) { HRESULT hr; wstring UserDN; wstring LegacyName; Zimbra::Util::ScopedInterface<IDirectoryObject> pDirContainer; try { Zimbra::MAPI::Util::GetUserDNAndLegacyName(m_strServer.c_str(), lpwstrlogonuser, lpwstrLogonUsrPwd, UserDN, LegacyName); } catch (Zimbra::MAPI::ExchangeAdminException &ex) { dloge("ExchangeAdmin::DeleteExchangeMailBox ExchangeAdminException exception: %S", ex.Description().c_str()); throw; } catch (Zimbra::MAPI::Util::MapiUtilsException &ex) { dloge("ExchangeAdmin::DeleteExchangeMailBox MapiUtilsException exception: %S", ex.Description().c_str()); throw; } wstring twtsrlogonuserDN = UserDN; size_t nPos = twtsrlogonuserDN.find(_T("DC="), 0); wstring wstrServerDN = twtsrlogonuserDN.substr(nPos); wstring wstrADSPath = _T("LDAP://CN=Users,") + wstrServerDN; // get dir container if (FAILED(hr = ADsOpenObject(wstrADSPath.c_str(), lpwstrlogonuser, lpwstrLogonUsrPwd, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (void **)pDirContainer.getptr()))) throw ExchangeAdminException(hr, L"DeleteExchangeMailBox(): ADsOpenObject Failed.", ERR_DELETE_MBOX, __LINE__, __FILE__); wstring mailboxcn = L"CN="; mailboxcn += lpwstrMailBox; hr = pDirContainer->DeleteDSObject((LPWSTR)mailboxcn.c_str()); return hr; }
HRESULT ExchangeMigrationSetup::Setup() { try { Clean(); } catch (Zimbra::MAPI::ExchangeAdminException &ex) { dloge("Setup: Clean exception: %S",ex.Description().c_str()); } catch(...) { dloge("Setup: Unknown Clean exception"); } try { dloge("Going for CreateExchangeMailbox..."); m_exchAdmin->CreateExchangeMailBox(DEFAULT_ADMIN_MAILBOX_NAME, m_ExchangeAdminPwd.c_str(), m_ExchangeAdminName.c_str(), m_ExchangeAdminPwd.c_str()); dloge("CreateExchangeMailbox success."); } catch (Zimbra::MAPI::ExchangeAdminException &ex) { dloge("ExchangeMigrationSetup::Setup::CreateExchangeMailBox ExchangeAdminException exception: %S", ex.Description().c_str()); throw; } catch (Zimbra::MAPI::Util::MapiUtilsException &ex) { dloge("ExchangeMigrationSetup::Setup::CreateExchangeMailBox MapiUtilsException exception: %S", ex.Description().c_str()); throw; } try { m_exchAdmin->CreateProfile(DEFAULT_ADMIN_PROFILE_NAME, DEFAULT_ADMIN_MAILBOX_NAME, m_ExchangeAdminPwd.c_str()); } catch (Zimbra::MAPI::ExchangeAdminException &ex) { dloge("ExchangeMigrationSetup::Setup::CreateProfile ExchangeAdminException exception: %S", ex.Description().c_str()); throw; } catch(...) { dloge("ExchangeMigrationSetup::Setup::CreateProfile Unknown exception"); throw; } return S_OK; }
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Exchange Admin class // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ExchangeAdmin::ExchangeAdmin(wstring strExchangeServer) { m_pProfAdmin = NULL; m_strServer = strExchangeServer; try { Init(); } catch (ExchangeAdminException &exc) { dloge("ExchangeAdmin::ExchangeAdmin exception: %S", exc.Description().c_str()); } }
LPCWSTR ExchangeOps::GlobalInit(LPCWSTR lpMAPITarget, LPCWSTR lpAdminUsername, LPCWSTR lpAdminPassword) { LPWSTR exceptionmsg=NULL; internalEOInit(); __try { return _GlobalInit(lpMAPITarget, lpAdminUsername, lpAdminPassword); } __except(Zimbra::Util::MiniDumpGenerator::GenerateCoreDump(GetExceptionInformation(),exceptionmsg)) { dloge(exceptionmsg); } return exceptionmsg; }
LPCWSTR ExchangeOps::_GlobalInit(LPCWSTR lpMAPITarget, LPCWSTR lpAdminUsername, LPCWSTR lpAdminPassword) { LPWSTR lpwstrStatus = NULL; LPWSTR lpwstrRetVal=NULL; // if lpAdminUsername is NULL then we assume that Outlook admin profile exists and we should use it // else create a Admin mailbox and create corresponding profile on local machine dloge("Check AdminUserName"); if (lstrlen(lpAdminUsername) > 0) { dloge("Check Initialized:%d",Initialized); if (Initialized == EXCH_UNINITIALIZED) { dloge("Do ExchangeMigrationSetup"); m_exchmigsetup = new ExchangeMigrationSetup(lpMAPITarget, lpAdminUsername, lpAdminPassword); Initialized = EXCH_INITIALIZED_PROFCREATE; } try { dloge("Going for Exchange mig setup"); m_exchmigsetup->Setup(); lpMAPITarget = DEFAULT_ADMIN_PROFILE_NAME; } catch (Zimbra::MAPI::ExchangeAdminException &ex) { lpwstrStatus = FormatExceptionInfo(ex.ErrCode(), (LPWSTR)ex.Description().c_str(), (LPSTR)ex.SrcFile().c_str(), ex.SrcLine()); dloge(lpwstrStatus); Zimbra::Util::CopyString(lpwstrRetVal, ex.ShortDescription().c_str()); } catch (Zimbra::MAPI::Util::MapiUtilsException &ex) { lpwstrStatus = FormatExceptionInfo(ex.ErrCode(), (LPWSTR)ex.Description().c_str(), (LPSTR)ex.SrcFile().c_str(), ex.SrcLine()); dloge(lpwstrStatus); Zimbra::Util::CopyString(lpwstrRetVal, ex.ShortDescription().c_str()); } } //check for any exception or error if(lpwstrStatus) { Zimbra::Util::FreeString(lpwstrStatus); return lpwstrRetVal; } // Create Session and Open admin store with profile lpwstrStatus = (LPWSTR)MAPIAccessAPI::InitGlobalSessionAndStore(lpMAPITarget); if (!lpwstrStatus) Initialized = EXCH_INITIALIZED_PROFEXIST; return lpwstrStatus; }
LPCWSTR ExchangeOps::SelectExchangeUsers(vector<ObjectPickerData> &vUserList) { LPWSTR lpwstrStatus = NULL; try { Zimbra::MAPI::Util::GetExchangeUsersUsingObjectPicker(vUserList); } catch (Zimbra::MAPI::Util::MapiUtilsException &ex) { lpwstrStatus = FormatExceptionInfo(ex.ErrCode(), (LPWSTR)ex.Description().c_str(), (LPSTR)ex.SrcFile().c_str(), ex.SrcLine()); dloge(lpwstrStatus); Zimbra::Util::FreeString(lpwstrStatus); Zimbra::Util::CopyString(lpwstrStatus, ex.ShortDescription().c_str()); } return lpwstrStatus; }
HRESULT ExchangeAdmin::CreateExchangeMailBox(LPCWSTR lpwstrNewUser, LPCWSTR lpwstrNewUserPwd, LPCWSTR lpwstrlogonuser, LPCWSTR lpwstrLogonUsrPwd) { HRESULT hr = S_OK; // Get Logon user DN wstring LogonUserDN; wstring legacyName; wstring msExchHomeSvrName; Zimbra::MAPI::Util::GetUserDNAndLegacyName(m_strServer.c_str(), lpwstrlogonuser, lpwstrLogonUsrPwd, LogonUserDN, legacyName); Zimbra::MAPI::Util::GetmsExchHomeServerName(m_strServer.c_str(), lpwstrlogonuser, lpwstrLogonUsrPwd, msExchHomeSvrName); Zimbra::Util::ScopedInterface<IDirectoryObject> pLogonContainer; Zimbra::Util::ScopedInterface<IADsUser> pIAdUser; Zimbra::Util::ScopedInterface<IADs> pIAds; wstring strContainer = L"LDAP://"; strContainer += LogonUserDN.c_str(); dloge("strContainer %S msExchHomeSvrName: %S", strContainer.c_str(), msExchHomeSvrName.c_str()); // Get loggedin user container hr = ADsOpenObject(strContainer.c_str(), NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (void **)pLogonContainer.getptr()); if (FAILED(hr)) { if (hr == 0x8007052e) // credentials are not valid { hr = ADsOpenObject((LPTSTR)strContainer.c_str(), lpwstrlogonuser, lpwstrLogonUsrPwd, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (void **)pLogonContainer.getptr()); if (FAILED(hr)||(pLogonContainer.get()==NULL)) throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): ADsOpenObject Failed.", ERR_ADOBJECT_OPEN, __LINE__, __FILE__); } else { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsOpenObject Failed.", ERR_ADOBJECT_OPEN, __LINE__, __FILE__); } } ADS_ATTR_INFO *pAttrInfo = NULL; DWORD dwReturn; LPWSTR pAttrNames[] = { L"mail", L"homeMDB", L"homeMTA" }; DWORD dwNumAttr = sizeof (pAttrNames) / sizeof (LPWSTR); wstring strLogonHomeMDB; wstring strLogonHomeMTA; wstring strLogonMail; // Get attribute values requested. Its not necessary the order is same as requested. if (FAILED(hr = pLogonContainer->GetObjectAttributes(pAttrNames, dwNumAttr, &pAttrInfo, &dwReturn))) throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): GetObjectAttributes Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); for (DWORD idx = 0; idx < dwReturn; idx++) { if (_wcsicmp(pAttrInfo[idx].pszAttrName, L"mail") == 0) strLogonMail = pAttrInfo[idx].pADsValues->Email.Address; else if (_wcsicmp(pAttrInfo[idx].pszAttrName, L"homeMTA") == 0) strLogonHomeMTA = pAttrInfo[idx].pADsValues->DNString; else if (_wcsicmp(pAttrInfo[idx].pszAttrName, L"homeMDB") == 0) strLogonHomeMDB = pAttrInfo[idx].pADsValues->DNString; } // Use FreeADsMem for all memory obtained from the ADSI call. FreeADsMem(pAttrInfo); wstring twtsrlogonuserDN = LogonUserDN; size_t nPos = twtsrlogonuserDN.find(_T("DC="), 0); wstring wstrServerDN = twtsrlogonuserDN.substr(nPos); wstring wstrADSPath = _T("LDAP://CN=Users,") + wstrServerDN; ADSVALUE cnValue; ADSVALUE classValue; ADSVALUE sAMValue; ADSVALUE uPNValue; ADSVALUE controlValue; ADS_ATTR_INFO attrInfo[] = { { L"objectClass", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &classValue, 1 }, { L"cn", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &cnValue, 1 }, { L"sAMAccountName", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &sAMValue, 1 }, { L"userPrincipalName", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &uPNValue, 1 }, {L"userAccountControl", ADS_ATTR_UPDATE, ADSTYPE_INTEGER,&controlValue, 1}, }; DWORD dwAttrs = sizeof (attrInfo) / sizeof (ADS_ATTR_INFO); classValue.dwType = ADSTYPE_CASE_IGNORE_STRING; classValue.CaseIgnoreString = L"user"; //int UF_ACCOUNTDISABLE = 0x0002; int UF_PASSWD_NOTREQD = 0x0020; //int UF_PASSWD_CANT_CHANGE = 0x0040; int UF_NORMAL_ACCOUNT = 0x0200; int UF_DONT_EXPIRE_PASSWD = 0x10000; //int UF_PASSWORD_EXPIRED = 0x800000; controlValue.dwType = ADSTYPE_INTEGER; controlValue.Integer=UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD |UF_DONT_EXPIRE_PASSWD; cnValue.dwType = ADSTYPE_CASE_IGNORE_STRING; cnValue.CaseIgnoreString = (LPWSTR)lpwstrNewUser; sAMValue.dwType = ADSTYPE_CASE_IGNORE_STRING; sAMValue.CaseIgnoreString = (LPWSTR)lpwstrNewUser; wstring wstrMail; size_t nPosMail = strLogonMail.find(_T("@"), 0); wstrMail = strLogonMail.substr(nPosMail); wstrMail = lpwstrNewUser + wstrMail; LPWSTR upnval = (LPWSTR)wstrMail.c_str(); uPNValue.dwType = ADSTYPE_CASE_IGNORE_STRING; uPNValue.CaseIgnoreString = upnval; Zimbra::Util::ScopedInterface<IDirectoryObject> pDirContainer; Zimbra::Util::ScopedInterface<IDispatch> pDisp; Zimbra::Util::ScopedInterface<IADsUser> pIADNewUser; wstring wstrLoggedUserName(LogonUserDN); size_t snPos = 0; size_t enPos = 0; if ((snPos = wstrLoggedUserName.find(L"CN=")) != wstring::npos) { if ((enPos = wstrLoggedUserName.find(L",", snPos)) != wstring::npos) wstrLoggedUserName = wstrLoggedUserName.substr(snPos + 3, (enPos - (snPos + 3))); } // get dir container if (FAILED(hr = ADsOpenObject(wstrADSPath.c_str(), wstrLoggedUserName.c_str(), lpwstrLogonUsrPwd, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (void **)pDirContainer.getptr()))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsOpenObject Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); wstring wstrUserCN = L"CN="; wstrUserCN += lpwstrNewUser; dloge("CreateDSObject: %S",wstrUserCN.c_str()); if (FAILED(hr = pDirContainer->CreateDSObject((LPWSTR)wstrUserCN.c_str(), attrInfo, dwAttrs, pDisp.getptr()))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): CreateDSObject Failed.", ERR_CREATE_EXCHMBX,__LINE__, __FILE__); if (FAILED(hr = pDisp->QueryInterface(IID_IADsUser, (void **)pIADNewUser.getptr()))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): QueryInterface Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); CComVariant varProp; varProp.Clear(); // set samAccount varProp = lpwstrNewUser; if (FAILED(hr = pIADNewUser->Put(CComBSTR(L"sAMAccountName"), varProp))) throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): Put(sAMAccountName) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if(FAILED(hr = pIADNewUser->SetInfo())) throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): Put(sAMAccountName) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); // set userAccountControl varProp.Clear(); hr = pIADNewUser->Get(CComBSTR(L"userAccountControl"), &varProp); varProp = varProp.lVal & ~(ADS_UF_ACCOUNTDISABLE); if (FAILED(hr = pIADNewUser->Put(CComBSTR(L"userAccountControl"), varProp))) throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): Put(userAccountControl) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(userAccountControl) Failed."); // set Account enabled if (FAILED(hr = pIADNewUser->put_AccountDisabled(VARIANT_FALSE))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): put_AccountDisabled Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - put_AccountDisabled Failed."); // set password if (FAILED(hr = pIADNewUser->SetPassword(CComBSTR(lpwstrNewUserPwd)))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): SetPassword Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - SetPassword Failed."); // user account password does not expire varProp.Clear(); VARIANT var; VariantInit(&var); if (!FAILED(hr = pIADNewUser->Get(CComBSTR(L"userAccountControl"), &var))) { V_I4(&var) |= ADS_UF_DONT_EXPIRE_PASSWD; if (FAILED(hr = pIADNewUser->Put(CComBSTR(L"userAccountControl"), var))) { throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): Put(userAccountControl) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - userAccountControl Failed."); varProp.Clear(); // set the homeMDB; if (!strLogonHomeMDB.empty()) { varProp = strLogonHomeMDB.c_str(); if (FAILED(hr = pIADNewUser->Put(CComBSTR("homeMDB"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(homeMDB) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(homeMDB) Failed."); varProp.Clear(); if (!strLogonHomeMTA.empty()) { varProp = strLogonHomeMTA.c_str(); if (FAILED(hr = pIADNewUser->Put(CComBSTR("homeMTA"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(homeMTA) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(homeMTA) Failed."); varProp.Clear(); if (!msExchHomeSvrName.empty()) { varProp = msExchHomeSvrName.c_str(); if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchHomeServerName"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(msExchHomeServerName) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(msExchHomeServerName) Failed."); varProp.Clear(); varProp.Clear(); wstring newUsrLegacyName=legacyName; size_t nwpos=newUsrLegacyName.rfind(L"cn="); if(nwpos !=wstring::npos) { newUsrLegacyName = newUsrLegacyName.substr(0,nwpos); newUsrLegacyName += L"cn="; newUsrLegacyName += lpwstrNewUser; } if (!newUsrLegacyName.empty()) { varProp = newUsrLegacyName.c_str(); if (FAILED(hr = pIADNewUser->Put(CComBSTR("legacyExchangeDN"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(legacyExchangeDN) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(legacyExchangeDN) Failed."); // set nickname varProp.Clear(); varProp = lpwstrNewUser; if (FAILED(hr = pIADNewUser->Put(CComBSTR("mailNickname"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(mailNickname) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(mailNickname) Failed."); // set the displayName varProp.Clear(); varProp = lpwstrNewUser; if (FAILED(hr = pIADNewUser->Put(CComBSTR("displayName"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(displayName) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(displayName) Failed."); // set the mail atrribute varProp.Clear(); varProp = wstrMail.c_str(); if (FAILED(hr = pIADNewUser->Put(CComBSTR("mail"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(mail) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(mail) Failed."); // set email if (FAILED(hr = pIADNewUser->put_EmailAddress(CComBSTR(wstrMail.c_str())))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): put_EmailAddress Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - put_EmailAddress Failed."); varProp.Clear(); wstrMail=L"SMTP:"+wstrMail; varProp = wstrMail.c_str(); if (FAILED(hr = pIADNewUser->Put(CComBSTR("proxyAddresses"),varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): proxyAddressess Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - proxyAddressess Failed."); // add to Domain Admins group BSTR bstrADSPath; if (FAILED(hr = pIADNewUser->get_ADsPath(&bstrADSPath))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): get_ADsPath Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); wstring wstrGroup = _T("LDAP://CN=Domain Admins,CN=Users,") + wstrServerDN; Zimbra::Util::ScopedInterface<IADsGroup> pGroup; if (FAILED(hr = ADsGetObject(wstrGroup.c_str(), IID_IADsGroup, (void **)pGroup.getptr()))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsGetObject Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if (FAILED(hr = ADsOpenObject(wstrGroup.c_str(), wstrLoggedUserName.c_str(), lpwstrLogonUsrPwd, ADS_SECURE_AUTHENTICATION, IID_IADsGroup, (void **)pGroup.getptr()))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsOpenObject Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if (SUCCEEDED(hr = pGroup->Add(bstrADSPath))) { if (FAILED(hr = pGroup->SetInfo())) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): pGroup SetInfo Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } else { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): pGroup Add Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } GUID guid; if(FAILED(hr = CoCreateGuid(&guid))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): CoCreateGuid Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } BYTE *str; hr = UuidToString((UUID *)&guid, (RPC_WSTR *)&str); if (hr != RPC_S_OK) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): UuidToString Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } varProp.Clear(); //BYTE bytArr[]="3429bb3084703348b8023e94fabf16ea"; PutBinaryIntoVariant(&varProp,str,16); RpcStringFree((RPC_WSTR *)&str); if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchMailboxGuid"), varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put msExchMailboxGuid Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - msExchMailboxGuid Failed."); if (FAILED(hr = ADsOpenObject(strContainer.c_str(), NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (void **)pIAdUser.getptr()))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsOpenObject2 Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if (FAILED(hr = pIAdUser->QueryInterface(IID_IADs, (void**) pIAds.getptr()))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): pIAdUser->QueryInterface Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } varProp.Clear(); if( FAILED(hr= pIAds->Get(CComBSTR("msExchMailboxSecurityDescriptor"),&varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Get msExchMailboxSecurityDescriptor Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchMailboxSecurityDescriptor"), varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put msExchMailboxSecurityDescriptor Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - msExchMailboxSecurityDescriptor Failed."); varProp.Clear(); if( FAILED(hr=pIAds->Get(CComBSTR("msExchPoliciesIncluded"),&varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Get msExchPoliciesIncluded Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchPoliciesIncluded"), varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put msExchPoliciesIncluded Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - msExchPoliciesIncluded Failed."); varProp.Clear(); if( FAILED(hr= pIAds->Get(CComBSTR("msExchUserAccountControl"),&varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Get msExchUserAccountControl Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchUserAccountControl"), varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put msExchUserAccountControl Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - msExchUserAccountControl Failed."); varProp.Clear(); if(FAILED(hr = pIAds->GetEx(CComBSTR("showInAddressBook"), &varProp ))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Get showInAddressBook Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->Put(CComBSTR("showInAddressBook"), varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put showInAddressBook Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - showInAddressBook Failed."); return hr; }
void ThrowSetInfoException(HRESULT hr, LPWSTR wstrmsg) { dloge("SetInfoException : %S",wstrmsg); throw ExchangeAdminException(hr,wstrmsg, ERR_CREATE_EXCHMBX, __LINE__, __FILE__); }
HRESULT MAPIRfc2445::ExtractAttachments() { // may need to break this up so we can call for exceptions, cancel exceptions LPCWSTR errMsg; Zimbra::Util::ScopedInterface<IStream> pIStream; UINT mimeLen = 0; HRESULT hr = ConvertIt( m_pMessage, pIStream.getptr(), mimeLen ); if (FAILED(hr)) { errMsg = FormatExceptionInfo(hr, L"Mime conversion of message with attachments failed", __FILE__, __LINE__); dlogw(errMsg); return hr; } mimepp::Message mimeMsg; Zimbra::Util::ScopedBuffer<CHAR> pszMimeMsg; // go to the beginning of the stream LARGE_INTEGER li = { 0 }; hr = pIStream->Seek(li, STREAM_SEEK_SET, NULL); if (FAILED(hr)) { errMsg = FormatExceptionInfo(hr, L"Stream seek failed", __FILE__, __LINE__); dlogw(errMsg); return hr; } // +1 for NULL terminator Zimbra::Mapi::Memory::AllocateBuffer(mimeLen + 1, (LPVOID *)pszMimeMsg.getptr()); if (!pszMimeMsg.get()) { errMsg = FormatExceptionInfo(S_OK, L"Mime msg Memory alloc failed", __FILE__, __LINE__); dlogw(errMsg); return hr; } ULONG ulNumRead = 0; hr = pIStream->Read((LPVOID)(pszMimeMsg.get()), mimeLen, &ulNumRead); if (FAILED(hr)) { errMsg = FormatExceptionInfo(hr, L"Mime msg read failed", __FILE__, __LINE__); dlogw(errMsg); return hr; } if (ulNumRead != mimeLen) { errMsg = FormatExceptionInfo(hr, L"Mime msg read error", __FILE__, __LINE__); dlogw(errMsg); return hr; } // terminating string pszMimeMsg.get()[mimeLen] = '\0'; mimeMsg.setString(pszMimeMsg.get()); mimeMsg.parse(); // let's see if this message is a multipart alternative before we continue mimepp::Headers &theHeaders = mimeMsg.headers(); LPSTR pszContentType; GetContentType(theHeaders, &pszContentType); if(strncmp(pszContentType, "multipart/mixed", strlen("multipart/mixed")) != 0) { // not what we are looking for delete[] pszContentType; return S_OK; } const mimepp::Body& theBody = mimeMsg.body(); int numParts = theBody.numBodyParts(); // FBS bug 73682 -- 5/23/12 int numHiddenAttachments = GetNumHiddenAttachments(); int totalAttachments = numParts - 1; if (totalAttachments == numHiddenAttachments) { return S_OK; } // let's look for a multipart mixed and grab the attachments int ctr = numHiddenAttachments; for(int i = 0; i < numParts; i++) { // now look for attachments const mimepp::BodyPart& thePart = theBody.bodyPartAt(i); mimepp::DispositionType& disposition = thePart.headers().contentDisposition(); if(disposition.asEnum() == mimepp::DispositionType::ATTACHMENT) { const mimepp::String& theFilename = disposition.filename(); LPSTR pszAttachContentType; LPSTR pszCD; LPSTR lpszRealName = new char[256]; GetContentType(thePart.headers(), &pszAttachContentType); // FBS bug 73682 -- Exceptions are at the beginning. Don't make attachments for those if (ctr > 0) { if (0 == strcmpi(pszAttachContentType, "message/rfc822")) { ctr--; continue; } } // if((LPSTR)theFilename.length()>0) { GenerateContentDisposition(&pszCD, (LPSTR)theFilename.c_str()); strcpy(lpszRealName, (LPSTR)theFilename.c_str()); } else { char cfilename[64]; sprintf(cfilename,"attachment-%d",i); GenerateContentDisposition(&pszCD, cfilename); strcpy(lpszRealName, cfilename); } // now deal with the encoding LPSTR pContent = NULL; const mimepp::String &theContent = thePart.body().getString(); mimepp::String outputString; UINT size = 0; mimepp::TransferEncodingType& transferEncoding = thePart.headers().contentTransferEncoding(); if(transferEncoding.asEnum() == mimepp::TransferEncodingType::BASE64) { // let's decode the buffer mimepp::Base64Decoder decoder; outputString = decoder.decode(theContent); pContent = (LPSTR)outputString.c_str(); size = (UINT)outputString.size(); } else if(transferEncoding.asEnum() == mimepp::TransferEncodingType::QUOTED_PRINTABLE) { mimepp::QuotedPrintableDecoder decoder; outputString = decoder.decode(theContent); pContent = (LPSTR)outputString.c_str(); size = (UINT)outputString.size(); } else { pContent = (LPSTR)theContent.c_str(); size = (UINT)theContent.size(); } // Save stream to temp file in temp dir. We'll delete in ZimbraAPI // LPCWSTR errMsg; HRESULT hr = S_OK; wstring wstrTempAppDirPath; LPSTR lpszFQFileName = new char[256]; LPSTR lpszDirName = NULL; LPSTR lpszUniqueName = NULL; Zimbra::Util::ScopedInterface<IStream> pStream; if (!Zimbra::MAPI::Util::GetAppTemporaryDirectory(wstrTempAppDirPath)) { errMsg = FormatExceptionInfo(S_OK, L"GetAppTemporaryDirectory Failed", __FILE__, __LINE__); dloge("MAPIRfc2445 -- exception"); dloge(errMsg); return E_FAIL; } WtoA((LPWSTR)wstrTempAppDirPath.c_str(), lpszDirName); WtoA((LPWSTR)Zimbra::MAPI::Util::GetUniqueName().c_str(), lpszUniqueName); strcpy(lpszFQFileName, lpszDirName); strcat(lpszFQFileName, "\\"); strcat(lpszFQFileName, lpszUniqueName); SafeDelete(lpszDirName); SafeDelete(lpszUniqueName); // Open stream on file if (FAILED(hr = OpenStreamOnFile(MAPIAllocateBuffer, MAPIFreeBuffer, STGM_CREATE | STGM_READWRITE, (LPTSTR)lpszFQFileName, NULL, pStream.getptr()))) { errMsg = FormatExceptionInfo(hr, L"Error: OpenStreamOnFile Failed.", __FILE__, __LINE__); dloge("MAPIRfc2445 -- exception"); dloge(errMsg); return hr; } ULONG nBytesToWrite = size; ULONG nBytesWritten = 0; LPBYTE pCur = (LPBYTE)pContent; while (!FAILED(hr) && nBytesToWrite > 0) { hr = pStream->Write(pCur, nBytesToWrite, &nBytesWritten); pCur += nBytesWritten; nBytesToWrite -= nBytesWritten; } if (FAILED(hr = pStream->Commit(0))) { errMsg = FormatExceptionInfo(hr, L"Error: Stream Write Failed.", __FILE__, __LINE__); dloge("MAPIRfc2445 -- exception"); dloge(errMsg); } /////////// // delete all this in MAPIAccessWrap AttachmentInfo* pAttachmentInfo = new AttachmentInfo(); pAttachmentInfo->pszTempFile = lpszFQFileName; pAttachmentInfo->pszRealName = lpszRealName; pAttachmentInfo->pszContentDisposition = pszCD; pAttachmentInfo->pszContentType = pszAttachContentType; m_vAttachments.push_back(pAttachmentInfo); } } delete[] pszContentType; return S_OK; }