Can't access user Exchange mailbox on certain machines - c#

I'm trying to run the following code as my own user.
var email = UserPrincipal.Current.EmailAddress;
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.AutodiscoverUrl(email);
FolderId inbox = new FolderId(WellKnownFolderName.Inbox, new Mailbox(email));
service.FindItems(inbox, new ItemView(1000));
This code works on one machine, but not on a new machine. Instead I get this exception
Microsoft.Exchange.WebServices.Data.ServiceResponseException was unhandled
HResult=-2146233088
Message=The specified object was not found in the store., The process failed to get the correct properties.
Source=Microsoft.Exchange.WebServices
StackTrace:
at Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary() in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\Responses\ServiceResponse.cs:line 277
at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute() in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\Requests\MultiResponseServiceRequest.cs:line 166
at Microsoft.Exchange.WebServices.Data.ExchangeService.FindItems[TItem](IEnumerable`1 parentFolderIds, SearchFilter searchFilter, String queryString, ViewBase view, Grouping groupBy, ServiceErrorHandling errorHandlingMode) in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\ExchangeService.cs:line 832
at Microsoft.Exchange.WebServices.Data.ExchangeService.FindItems(FolderId parentFolderId, ViewBase view) in \\REDMOND\EXCHANGE\BUILD\E15\15.00.0913.015\SOURCES\sources\dev\EwsManagedApi\src\EwsManagedApi\Core\ExchangeService.cs:line 956
I can't really see any differences between the machines other than
The failing machine is a new install, so it might be missing some framework components or something?
I don't have admin rights on the failing machine, but I'm not running as admin on either machine.
The failing machine has Outlook 365 installed while the working machine has Outlook 2013 installed. I'm not sure why this would be an issue though, since they are both talking to the same Exchange server.
The really confusing thing is that I have two accounts configured in Outlook under Account Settings (the second one is a service account mailbox). If I change the email variable to the second account's email address, everything works fine. This is leading me to believe it's not strictly an issue with admin rights, but I can't quite figure out what the issue is.

Related

Create a user on a remote machine using c#

i am trying to create an app, which automatically creates and configures merge replication between the 2 PCs in the same local network.
To achieve this, i need to programaticaly create one user on each of the two PCs, this user should have exactly the same user name and passwords as it is required by the replication.
There is no DOMAIN on the network.
I did everything using GUI on both machines and replication works, now i need to do this using a C#. The replication part is done using SQL server 2012 RMO and SMO SDKs.
While googling, i found this (and many many other results which are more or less identical to this). But i believe, that these all examples are meant for local PCs, as it seems people were not getting errors like i do.
My sample code is:
DirectoryEntry directoryEntry = new DirectoryEntry(#"WinNT://WORKGROUP/WIN7-PC,computer", #"admin", "123456");
DirectoryEntry user = directoryEntry.Children.Add("RepTest", "user");
user.Invoke("SetPassword", new object[] { "rep123" });
user.CommitChanges();
I get an error at user.CommitChanges() saying that Access is denied, so i figured i had made a mistake in the authentication details provided to new DirectoryEntry(.... I fixed that and tried again:
DirectoryEntry directoryEntry = new DirectoryEntry(#"WinNT://WORKGROUP/WIN7-PC,computer", #"win7-pc\admin", "123456");
DirectoryEntry user = directoryEntry.Children.Add("RepTest", "user");
user.Invoke("SetPassword", new object[] { "rep123" });
user.CommitChanges();
Now I get the error on the line of .Children.Add(... stating that Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed.
When the first time i did it, i checked the Path of user object, which was WinNT://WORKGROUP/WIN7-PC/RepTest, not sure if it has anything to do with anything, but maybe it is trying to use the yet to be created new user folder while being connected as admin user?
Is there a way to get this thing going?

Exchange server 2010 Version support on folder search for asp.net

I am trying to sync to an exchange folders by trying to run the below command to find all the folders in asp.net c#.
view.Traversal = FolderTraversal.Deep;
FindFoldersResults findFolderResults = service.FindFolders(new FolderId(WellKnownFolderName.Root, mailbox), view);
However this command previously worked on another mail server have failed for the current one I am using. The error returned on this line is
Microsoft.Exchange.WebServices.Data.ServiceVersionException: Exchange Server doesn't support the requested version.
at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ProcessWebException(WebException webException)
at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest request)
at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(IEwsHttpWebRequest& request)
at Microsoft.Exchange.WebServices.Data.SimpleServiceRequestBase.InternalExecute()
at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute()
at Microsoft.Exchange.WebServices.Data.ExchangeService.InternalFindFolders(IEnumerable`1 parentFolderIds, SearchFilter searchFilter, FolderView view, ServiceErrorHandling errorHandlingMode)
at Microsoft.Exchange.WebServices.Data.ExchangeService.FindFolders(FolderId parentFolderId, FolderView view)
The funny thing is both of exchange server are exchange 2010 so anyone have any idea what problem this really is? or exactly what is causing the command not supported.
The successful run server is version 14.03.0195.001
The failed server version is 14.00.0722.000
Is this error really caused by this Minor error? I mean both of them are exchange 2010 server really shouldn't the commands be the same?
Try instantiating the ExchangeService object with ExchangeVersion.Exchange2010. (There are ExchangeVersions for SP1 and SP2 also.) I don't know the 14.x.y.z numbers on each, but clearly the failing server is down-level from the working one. EWS is not complaining about the function you want, but rather about the version you're requesting. Thus if the failing server was running E2010 SP1, and your EWS DLL was defaulting to Exchange2010_SP2, things would not work. You're probably safe dropping down to RTM-flavor of E2010, unless other pieces of your code need something specific in SP1 or SP2, in which case you'll have to determine exactly what the 14.x.y.z number correspond to.

C# EWS API - Accessing items on different Exchange server than the server where account accessing is configured

I have an account created on Exchange Server A and I'm trying to access items on shared mailbox X configured on Exchange server B. I have required permissions to access mailbox X and I'm able to do it using MS Outlook, but not able to do it using EWS Managed API. I have used following code:
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.Credentials = new WebCredentials("user.name#organization.com", "password");
service.Url = new Uri("https://organization.com/EWS/Exchange.asmx");
Mailbox somemailbox = new Mailbox("some.mailbox#organization.com");
FolderId folderInbox = new FolderId(WellKnownFolderName.Inbox, somemailbox);
FindFoldersResults findResults = service.FindFolders(folderInbox, new FolderView(int.MaxValue));
This returns an error: "The account accessing the resource must be on the same Mailbox Server version as the delegate account being accessed." pointing last line of the code (service.FindFolders).
At the beginning I thought that version of the servers are not compatible, but when I changed ExchangeVersion in line 1 of the code to any other than "Exchange2007_SP1" I got error message Exchange Server doesn't support the requested version., So I guess that this is not version related problem. I guess that in such case I would not be able to connect using MS Outlook which works fine.
I think that I'm missing something very easy, but I don't know what...
the problem is that you connect to the primary server. If you want to access the delegate-account you will have to change the ews-url to the ews-address of the server where the mailbox is stored. I have nearly the same scenario in my company and with diffrent urls it works fine for me. If your exchange-server is co configured properly you can use the autodiscover function 'service.Autodiscover()' of the managed api to get the right ews-address.

Can't access public folders root

I've recently coded a .NET Console app using C#. It's purpose was to read the emails within a specific folder, parse them for specific values and save them to a database.
Our email system, at the time I originally coded this, was Exchange 2003. However, I was made aware we would soon be upgrading to Exchange 2010: ergo, I built the code to work in both environments.
Following the migration to Exchange 2010, however, the app has broken.
The app uses the EWS API for 2010 functionality. When it attempts to use the ExchangeService's FindFolders method to find the publicfoldersroot, it throws an exception. Here's the code:
ExchangeService service = new ExchangeService();
FindFoldersResults findRootFldrs;
service.UseDefaultCredentials = true;
service.AutodiscoverUrl("xxxxx#xxxx.xxx", delegate(string x) {
return true; });
FolderView fview = new FolderView(100);
fview.Traversal = FolderTraversal.Deep;
findRootFldrs = service.FindFolders(WellKnownFolderName.PublicFoldersRoot,
fview);
The exception: ErrorInvalidSchemaVersionForMailboxVersion, aka:
The mailbox that was requested doesn't support the specified RequestServerVersion
I've attempted:
Setting the exchangeservice to 2007 (throws an exception: "An internal server error occurred. The operation failed.")
Giving myself the highest level of permission to the Public Folder (no effect)
Manually setting my credentials (no effect)
I can view the public folders in Outlook 2007; the publicfoldersroot property is available in the intellisense; the code works on local folders (I can parse my inbox).
My current thinking is that it's a setting on the recent setup of Exchange 2010: unfortunately that isn't really my field. The exception tells me it's trying to use a previous version of Exchange. Setting it to 2007 simply causes the code to fail with an internal server error.
Old post, but this turned out to be the answer for me: http://technet.microsoft.com/en-us/library/bb629522.aspx
Essentially the account used to connect with EWS had a mailbox in a mailbox database whose default public folder server was still Exchange 2003. Any and all attempts to enumerate public folders over EWS failed. Swapping it out for a 2010 backend server cured it instantly.
Have you tried esb.RequestServerVersion.Version = ExchangeVersionType. Exchange2010 (or SP1)
Change this line:
ExchangeService service = new ExchangeService();
to something like this:
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
or
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
Depending on your version.

How should I validate a user's credentials against an ADAM instance over SSL?

Apologies in advance as I haven't had much experience with directories before.
I have an ASP.net application, and I have to validate its users against an Active Directory Application Mode instance running on Server 2k3. I was previously attempting a connection with DirectoryEntry and catching the COMException if the user's credentials (userPrincipalName & password) were wrong, but I had a number of problems when trying to bind as users who weren't a member of any ADAM groups (which is a requirement).
I recently found the System.DirectoryServices.AccountManagement library, which seems a lot more promising, but although it works on my local machine, I'm having some troubles when testing this in our testbed environment. Chances are I'm simply misunderstanding how to use these objects correctly, as I wasn't able to find any great documentation on the matter. Currently I am creating a PrincipalContext with a Windows username and password, then calling the AuthenticateCredentials with the user's userPrincipalName and password. Here's a very short exert of what I'm doing:
using (var serviceContext = new PrincipalContext(
ContextType.ApplicationDirectory,
serverAddress,
rootContainer,
ContextOptions.Negotiate | ContextOptions.SecureSocketLayer,
serviceAccountUsername,
serviceAccountPassword)) {
bool credentialsValid = serviceContext.ValidateCredentials(userID, password, ContextOptions.SecureSocketLayer | ContextOptions.SimpleBind)
}
If the user's credentials are valid, I then go on to perform other operations with that principal context. As I said, this works for both users with and without roles in my own environment, but not in our testbed environment. My old DirectoryEntry way of checking the user's credentials still works with the same configuration.
After a very long morning, I was able to figure out the problem!
The exception message I was receiving when calling ValidateCredentials was extremely vague. After installing Visual Studio 2008 in the test environment (which is on the other side of the country, mind you!), I was able to debug and retrieve the HRESULT of the error. After some very deep searching in to Google, I found some very vague comments about "SSL Warnings" being picked up as other exceptions, and that enabling "SCHANNEL logging" (which I'm very unfamiliar with!) might reveal some more insight. So, after switching that on in the registry and retrying the connection, I was presented with this:
The certificate received from the remote server does not contain the expected name. It is therefore not possible to determine whether we are connecting to the correct server. The server name we were expecting is ADAMServer. The SSL connection request has failed. The attached data contains the server certificate.
I found this rather strange, as the old method of connecting via SSL worked fine. In any case, my co-worker was able to spot the problem - the name on the SSL certificate that had been issued on the server was that of the DNS name ("adam2.net") and not the host name ("adamserver"). Although I'm told that's the norm, it just wasn't resolving the correct name when using PrincipalContext.
Long story short; re-issuing a certificate with the computer name and not the DNS name fixed the problem!

Categories