Copy files to a network drive (without Impersonation) - c#

I have a WindowsForms vb.net Framework 4.6 Application which must copy some files from c:\sample to a network drive (\\servername\sample).
I must use other credentials to access the share. But I can't use impersonate, because i have to use a local user on the Server. The Login on the server is something like <.\Username> <password>.
Is there a way to copy my files to the network drive using the server's local user credentials?
EDIT 18.06:
I also tried this way, but it did not work for me.
Dim domain, username, passwordStr, remoteServerName As String
Dim password As New System.Security.SecureString
Dim command As New Process
domain = "servername"
username = "username"
passwordStr = "password"
remoteServerName = "\\servername\path\"
Dim impersonator As New AliasAccount(username, passwordStr)
For Each c As Char In passwordStr.ToCharArray
password.AppendChar(c)
Next
command.StartInfo.FileName = "test.pdf"
command.StartInfo.Arguments = remoteServerName
command.StartInfo.UserName = username
command.StartInfo.Password = password
command.StartInfo.Domain = domain
command.StartInfo.Verb = "open"
command.StartInfo.UseShellExecute = False
impersonator.BeginImpersonation()
command.Start()
impersonator.EndImpersonation()
My user on the server does not a have a specific domain, because the user only exists on the server. So i'm using the servername as the domain. I also tried using ".\".
I'm always getting the same error "wrong username or password" (translated from german to englisch). I've checked the username and password more than 30 times... It is definitely correct. I'm also able to connect a network drive with the credentials... So they are correct.
Do you have any other suggestions?

Related

How to keep my application "authenticated" with an AD account? c#

I am pretty new to C#
I have been using Powershell scripts to code things like Unlocking an AD user or Enabling/Disabling an account. however, I do this with a different account, so I will log in with the admin account (Get-Credential) and storing it as '$cred' for example.
I am currently trying to do a similar thing in C# and I have found how to effectively "Authenticate"
But I am not sure how to store that Authentication, or have my app Authenticated to do things with it like Disable or Unlock an AD Account.
I have this:
public bool ADauthenticate(string username, string password)
{
bool result = false;
using (DirectoryEntry _entry = new DirectoryEntry())
{
_entry.Username = username;
_entry.Password = password;
DirectorySearcher _searcher = new DirectorySearcher(_entry);
_searcher.Filter = "(objectclass=user)";
try
{
SearchResult _sr = _searcher.FindOne();
string _name = _sr.Properties["displayname"][0].ToString();
MessageBox.Show("authenticated!");
result = true;
this.Close();
}
catch
{
MessageBox.Show("Incorrect credentials");
this.ADUsername.Text = "";
this.ADPwd.Text = "";
}
}
return result; //true = user Authenticated.
}
Which just tells me that the account is correct of course, but doesn't keep my application "authenticated", any ideas?
It's not accurate to say that your "application" was authenticated. All that was authenticated is a single network connection to your domain controller. As soon as _entry is destroyed, you lose that authentication.
If you want everything to happen using those credentials, then you have several options, ranging from easy (for you) to more difficult:
Have your users run your application under the credentials they need. Then you don't need to bother getting their username and password or setting the username and password on the DirectoryEntry object. Users can do this by:
Using Shift + right-click on the application icon and click "Run as a different user", or
Create a shortcut to: runas.exe /user:DOMAIN\username "yourapplication.exe". This will open a command window asking for the password, then start your application under those credentials.
You still ask for the username and password, but restart your application under those credentials using Process.Start().
Keep the username and password variables alive for the life of the application and pass them to every DirectoryEntry object you create in your application.
Options 1 and 2 require the computer that you're running this from is joined to the same or trusted domain as the domain you are connecting to. But since I see you're not specifying the domain name, I'm guessing that's the case.
You can do this a lot easier by using the System.DirectoryServices.AccountManagement assembly and namespace.
Add a reference to the System.DirectoryServices.AccountManagement assembly to your project, and then use this code to validate username/password against AD:
using System.DirectoryServices.AccountManagement;
// create the principal context
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YourDomain"))
{
bool accountValidated = ctx.ValidateCredentials(userName, password);
// do whatever you want to do with this information
}

The user name or password is incorrect-8009030C: LdapErr: DSID-0C090579, comment: AcceptSecurityContext error, data 52e, v3839

I am trying to connect AD with the following code
VMADProfile _VMADProfile = new VMADProfile();
DirectoryEntry searchRoot = new DirectoryEntry("Test AD LDAP Path", "DomainName\\username", "password");
directorySearcher.Filter = "(&(objectCategory=user)(samAccountName=" + username + "))";
directorySearcher.PropertiesToLoad.Add("displayname");
SearchResult one = directorySearcher.FindOne();
but it is giving me following Error
The user name or password is incorrect.
8009030C: LdapErr: DSID-0C090579, comment: AcceptSecurityContext error, data 52e, v3839
I am able to login with same user name and password if I login directly.
My AD that I am trying to connect is different from from which i am running code. Same code works fine if i change test AD to the production AD
I think this is the key:
My AD that I am trying to connect is different from from which i am running code.
It's probably trying to authenticate you on your domain, not the other one. Make sure your LDAP path includes the server to connect to for the other domain, and not just the distinguished name of the domain. The server name can just be the DNS name for the domain. It should look something like this:
DirectoryEntry searchRoot = new DirectoryEntry("LDAP://otherdomain.com/DC=otherdomain,DC=com", "DomainName\\username", "password");
If you just use "LDAP://DC=otherdomain,DC=com", it will try to connect to the domain the current computer is joined to first. That would actually work if there is a trust between the two domains, but if not, you need to specifically give it the server name to connect to.

autenticating ldap for web applications

please take a few minutes and read my question completely. here is my problem :
I want to connect to LDAP server by C# for a web application, means clients connecting to the asp.net server.
*- The ldap server and application server are not the same.
**- They are not in a same domain.
I have been trying 4 different ways and could not solve the problem by none of them.
1-
var credentials = new NetworkCredential(username, password);
var serverId = new LdapDirectoryIdentifier("domain.net");
var conn = new LdapConnection(serverId, credentials);
conn.Bind();
2-
System.DirectoryServices.DirectoryEntry entry = new System.DirectoryServices.DirectoryEntry("LDAP://domain.net/DC=domain,DC=net");
entry.Username = "username";
entry.Password = "password";
System.DirectoryServices.DirectorySearcher searcher = new System.DirectoryServices.DirectorySearcher(entry);
searcher.Filter = "(&(objectClass=user))";
var results = searcher.FindAll();
the problem with these 2 ways is that the user must have an access to the server for login and we know that there is only admin of the system who has the permission.
3-
PrincipalContext pc = new PrincipalContext(ContextType.Domain, "domain.net");
var ret = pc.ValidateCredentials(model.UserName, model.Password);
the problem is the server must be in the domain of ldap server. we have this limitation !!
4-
https://auth0.com/blog/using-ldap-with-c-sharp/
public bool validateUser(string username, string password)
{
var sha1 = new SHA1Managed();
var digest = Convert.ToBase64String(sha1.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password)));
var request = new CompareRequest(string.Format("uid={0},ou=users,dc=example,dc=com", username),
"userPassword", "{SHA}" + digest);
var response = (CompareResponse)connection.SendRequest(request);
return response.ResultCode == ResultCode.CompareTrue;
}
this code does not return any thing. it will be very helpful if there is a query to compare usernames and passwords. this code seems to use this way but there are different types of hash algorithms. I tried to use SHA1 and MD5, and userPassword , unicodePwd attribute. but the return is empty all the time.
is it the best solution to put both servers in a same domain? any other solution , Thank you so much.
Method 1 is the simplest way. If that doesn't work, nothing will. So you will have to change your configuration to make it work.
When you say:
the user must have an access to the server for login and we know that there is only admin of the system who has the permission.
What do you mean? Are you explicitly denying login rights to the domain controllers? Are there network issues between the computer this is running on and the domain controller (can you hit port 389 on the domain controller(s))?
Update: PrincipalContext.ValidateCredentials just does an LDAP bind in behind - it uses LdapConnection. You can see the source code here. The probable reason why ValidateCredentials is working on a domain machine and not otherwise is because it uses Kerberos authentication by default, which will only work from a domain computer.
The same is true with LdapConnection. So try setting the authentication mode. For example, try Basic
var credentials = new NetworkCredential(username, password);
var serverId = new LdapDirectoryIdentifier("domain.net");
var conn = new LdapConnection(serverId, credentials, AuthType.Basic);
conn.Bind();
Or look at the available values and try what works.

Remote Connection using Management Scope?

Am trying to connect the remote system from my local machine with the help of Management Scope.
What i tried is:
My code as follows,
ConnectionOptions con= new ConnectionOptions();
con.Username = strUsername;
con.Password = strPassword;
con.Impersonation = ImpersonationLevel.Impersonate;
con.EnablePrivileges = true;
ManagementScope ManagementScope1 = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", strIP), con);
ManagementScope1.Connect();
My Problem is:
With the preceding code, I can connect with remote system when It has some username and password.(strUsername = "User", strPassword="Welcome")
But in case of blank password (strUsername = "User", strPassword = "") , am getting the error named as "Access is Denied". The connecting remote system has no protection from the password.
Remote system user gave all sorts of permission to access the machine, but still am facing with this strange issue.
please let me know where am going wrong. Any help is much appreciated. Thanks in advance.
If you want to use currently logged user to access remote WMI, you have to pass null as Username.
null if the connection will use the currently logged-on user; otherwise, a string representing the user name. The default value is null.
Source: http://msdn.microsoft.com/en-US/library/system.management.connectionoptions.username(v=vs.110).aspx

Change user password on remote computer using WMI

Is there a way to change a users password on a remote computer using WMI? I couldn't locate any resources on this.
I'd just like to add that we are not using active directory and I need to write my code in C#.
Well, these are VB Script examples in this Hey Scripting Guy column, but they should be translatable:
How do I change the local Administrator password for all the computers in an OU?
Set objOU = GetObject("LDAP://OU=Finance, DC=fabrikam, DC=com")
objOU.Filter = Array("Computer")
For Each objItem in objOU
strComputer = objItem.CN
Set objUser = GetObject("WinNT://" & strComputer & "/Administrator")
objUser.SetPassword("i5A2sj*!")
Next
The first part is AD based, but is just being used to find all of the machines in the domain. The second part (that does the actual remote password reset) doesn't rely on AD at all.
So, it's basically bind to WinNT://<ComputeName>/<UserName>, then call SetPassword().
And this other SO question on changing the local admin account password is already in C#:
public static void ResetPassword(string computerName, string username, string newPassword) {
DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("WinNT://{0}/{1}", computerName, username));
directoryEntry.Invoke("SetPassword", newPassword);
}

Categories