I am using the following code to change the credentials of a windows service. Before I display the message that credentials were successfully changed, I want to confirm the new credentials have been applied. How can I do that?
using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
{
object[] wmiParams = new object[11];
wmiParams[6] = _username;
wmiParams[7] = _password;
service.InvokeMethod("Change", wmiParams);
Thread.Sleep(2000);
//check if new credentials in order
//Console.WriteLine("Service credentials changed");
}
The new credentials won't apply until you restart the service, and I suggest you use the ServiceController instead of WMI.
You should be able to check the returned object from InvokeMethod and just handle errors without any further complexity. The only issue is working out what returned value implies success.
object result = service.InvokeMethod("Change", wmiParams);
// if result 'is bad', handle error
Related
I have an instance of AD/LDS running on my machine and I'm trying to connect to it using the System.DirectoryServices.Protocols.LdapConnection class. For some reason every time I call the Bind() method it throws an LdapException complaining about invalid credentials.
Here's the code I'm using to set up the connection:
var ldapDirectoryIdentifier = new LdapDirectoryIdentifier(config.Server.Host, config.Server.Port);
var creds = new NetworkCredential(config.Credentials.Username, config.Credentials.Password)
{
Domain = config.Credentials.
};
ldapConnection = new LdapConnection(ldapDirectoryIdentifier, creds, AuthType.Basic);
if (config.Server.Secure)
{
cert = new X509Certificate(config.Server.Certificate);
ldapConnection.SessionOptions.SecureSocketLayer = true;
ldapConnection.SessionOptions.VerifyServerCertificate = CheckCertificate;
}
ldapConnection.SessionOptions.ProtocolVersion = 3;
try
{
ldapConnection.Bind();
}
catch (LdapException e)
{
Log.LogException(e);
Environment.Exit(e.ErrorCode);
}
The configuration is coming from an App.config file as in the following example:
<server host="host" port="389"/>
<credentials username="username" password="password" domain="domain"/>
<usersearch base="ou=test,dc=test,dc=com" filter="(middlename=user)" objectclass="inetorgperson"/>
<devicesearch base="ou=test,dc=test,dc=com" filter="(sn=device)" objectclass="inetorgperson"/>
I've tried modifying the credentials part to get it connecting; setting username="DOMAIN\user", with and without the domain entry to credentials. I've tried messing with the connection strings, e.g. <server host="LDAP://host[:389]"/>. It just says the credentials, which I use to connect to the instance with both ADSI Edit and ldp, are invalid.
I CAN connect with the same domain credentials (local user account) using System.DirectoryServices.DirectoryEntry so I suspect it's the AD bit of AD/LDS being picky.
Anyone got any ideas?
It's probably on the session option. Try to force authentication type:
ldapConnection.AuthType = AuthType.Negotiate;
It may also be the way you handle the certificate. Try to add it this way:
ldapConnection.ClientCertificates.Add(cert);
I went ahead and double checked what AuthTypes were available and setting it to Ntlm works.
I need to connect to NetIQ eDirectory using .NET & C#. The connection must be opened using application credentials. Once the connection is opened, I need to validate user credentials under the authority of the application credentials using a similar method as S.DS.AccountManagement.
using (var context = new PrincipalContext(ContextType.Domain, path, appUserDn, appPassword))
{
//Username and password for authentication.
var valid = context.ValidateCredentials(userDn, password);
}
I tried Novell.Directory.Ldap, S.DS.DirectoryEntry, & S.DS.AccountManagement. The last one requires AD and does not apply.
Test using Novell.Directory.Ldap..
using (var cn = new LdapConnection())
{
cn.Connect(server, int.Parse(port));
cn.Bind(appUserDn, appPassword); //throws exception if invalid credentials..
var passwordAttr = new LdapAttribute("userPassword", password);
cn.Compare(userDn, passwordAttr); // Only compares password, so no locked account check, etc.
}
My current prototype uses S.DS.Protocols.
var networkCredential = new NetworkCredential(
appUserDn,
appPassword);
using (proto.LdapConnection cn = new proto.LdapConnection(new proto.LdapDirectoryIdentifier(server, int.Parse(port)), networkCredential, proto.AuthType.Basic))
{
cn.Bind();
/// Next validate user credentials..
}
I cannot find a way to validate user credentials other than reassigning NetworkCrentials and rebinding using the individual's username & password. How should I proceed?
It turns out our client got it wrong. The correct way is to bind the connection directly to an individual's credentials as I demonstrate in the Novell.Directory.Ldap example.
There was a posting on NetIQ's forum about executing a shell script but I did not get it working.
Every time I try to call the server, I get an error code : ErrorConnectionFailed with Connection failed. Try later. message.
I suspect that it comes from the fact that the credentials of service are empty. Although I have no idea why. If I create the credentials manually using my windows account login and password, it works fine : new WebCredentials(login, password, domain);
I have a console program that works fine (see below), but it does not on a web site.
static void Main(string[] args)
{
var service = GetContextualService(email);
EmailMessage email = EmailMessage.Bind(service, new ItemId(validEmailId));
Console.ReadKey();
}
private static ExchangeService GetContextualService(string email)
{
ExchangeService service = new ExchangeService();
// I don't even need credentials on a Console program to make it work
//service.Credentials = new WebCredentials(CredentialCache.DefaultCredentials);
//service.UseDefaultCredentials = true;
service.AutodiscoverUrl(email, RedirectionUrlValidationCallback);
return service;
}
private static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
// The default for the validation callback is to reject the URL.
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
// Validate the contents of the redirection URL. In this simple validation
// callback, the redirection URL is considered valid if it is using HTTPS
// to encrypt the authentication credentials.
if (redirectionUri.Scheme == "https")
{
result = true;
}
return result;
}
While using on a website even with new WebCredentials(CredentialCache.DefaultCredentials);, it returns an exception. (see below)
private ExchangeService GetContextualService(string email)
{
ExchangeService service = new ExchangeService();
service.Credentials = new WebCredentials(CredentialCache.DefaultCredentials);
//service.UseDefaultCredentials = true;
service.AutodiscoverUrl(email, RedirectionUrlValidationCallback);
return service;
}
[HttpPost]
public List<InternetMessageHeader> GetMailHeader(JObject data)
{
ExchangeService service = GetContextualService(data.GetValue("email").Value<string>());
ItemId id = new ItemId(data.GetValue("mailId").Value<string>());
// EXCEPTION BELOW
EmailMessage email = EmailMessage.Bind(service, id);
return email.InternetMessageHeaders.ToList();
}
Why does any call to EWS returns me an exception ?
Why is it working fine on a console program and not on a web server ?
Any thought is welcome !
Strictly based on the code you posted, all I can say is that when you call AutoDiscoverUrl() it may not be talking to the same server that you need to talk to with EWS. Altho typically AD and EWS are on the CAS, it's possible (I think) to get an EWS URL that points to some other server. I've not been in the code in the EWS Editor in some time, but if it does not call the Managed API, it might do AD slightly differently. I'd suggest calling out the EWS URL before you try the Bind() and seeing if you can paste it into a browser. (It'll redirect you OWA, but the connection will be proven.) I'd also call out the AD URL in the redirection callback so you know who you're talking to. Sorry I can't be of more help.
I have tried both the methods below but both return the result "The Autodiscover service couldn't be located."
http://msdn.microsoft.com/en-us/library/gg591267(v=EXCHG.140).aspx
service.Credentials = new NetworkCredential(userData.EmailAddress, userData.Password);
if (userData.AutodiscoverUrl == null)
{
service.AutodiscoverUrl(userData.EmailAddress, RedirectionUrlValidationCallback);
userData.AutodiscoverUrl = service.Url;
}
else
{
service.Url = userData.AutodiscoverUrl;
}
return service;
}
http://code.msdn.microsoft.com/Exchange-2013-Set-pull-14c8360b#content
static ExchangeService GetBinding()
{
// Create the binding.
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
// Define credentials.
service.Credentials = new WebCredentials("myemail#work.com", "password");
// Use the AutodiscoverUrl method to locate the service endpoint.
try
{
service.AutodiscoverUrl("myemail#work.com", RedirectionUrlValidationCallback);
}
catch (AutodiscoverRemoteException ex)
{
Console.WriteLine("Exception thrown: " + ex.Error.Message);
}
// Display the service URL.
Console.WriteLine("AutodiscoverURL: " + service.Url);
return service;
}
In the one instance I enter my email and password, in the other its hard-coded. Both hang when attempting Autodiscoverurl and eventually fail with the message "The Autodiscover service couldn't be located." I added the references as per the tutorials and Autodiscover appears under Microsoft.Exchange.WebServices.dll ... Is there something else I'm missing?
try adding:
service.UseDefaultCredentials = false;
after you set the credentials
I don't know if you have resolved it yet, I bumped into your post as I was searching for a solution for the same (or similar?) problem.
The peculiar thing was:
Since it worked perfectly in Debug mode, but not once installed as Windows service, I changed the 'Log On' settings in the Windows Service Properties (services.msc, right click on installed service, Properties, Log On Tab) and set it to 'Local System account' and checked the 'Allow service to interact with desktop' option.
That did the trick for me.
I have attempted this with not much success. Basically I need to login to Exchange using EWS remotely.
The issue is I don't know if the user has logged in OK or if the credentials are wrong as I get nothing back! If I provide wrong credentials the software just carries on!
Is there something I'm missing, I've checked the MSDN stuff about EWS which shows you how to connect to exchange but nothing about validating credentials!
Below is the code I currently have to connect.
public void connect(string Email, string Password)
{
try
{
_useremail = Email;
_userpass = Password;
// Define the credentials to use.
var credentials = new WebCredentials(_useremail, _userpass);
_ExchangeServer = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
_ExchangeServer.Credentials = credentials;
_ExchangeServer.Url = new Uri(_ExchangeEWSURL);
_ExchangeServer.Timeout = 60;
_ExchangeServer.KeepAlive = true;
_ExchangeConnected = true;
}
catch (Exception ex)
{
_ExchangeConnected = false;
throw ex;
}
}
as you can see at present I just set a bool value to true in the class. Any ideas?
In order to check whether the given credentials are valid, you must query resources you expect the user to have access to (calendar, inbox, contacts, etc.). There is no explicit login method - the authentication occurs implicitly when you request user resources (via FindItems, FindFolders, FindAppointments, etc.).