Provided I have admin access, I need a way to manage (Create, modify, remove) local accounts in a remote machine from an ASP.NET client.
I'm clueless in how to approach this. Is WMI a possibility (System.Management namespace)?
Any pointers?
Give this a try:
DirectoryEntry directoryEntry = new DirectoryEntry("WinNT://ComputerName" & ",computer", "AdminUN", "AdminPW");
DirectoryEntry user = directoryEntry.Children.Add("username", "user");
user.Invoke("SetPassword", new object[] { "password"});
ser.CommitChanges();
If you do need to go the Active Directory route, you can change the directoryEntry path string to something like this: LDAP://CN=ComputerName,DC=MySample,DC=com
I used System.DirectoryServices to get data from users in a n ActiveDirectory (LDAP).
I don't know if that's the kind of thing you're looking for.
Hope it helps.
You should be able to do this via DirectoryEntry.
Related
Ive written a program to manage our Active Directory in c# - windows forms.
I'm stuck at the following point:
For managing the Active Directory and Commiting Changes, you have to run the program as administrator.
I want to include a login button to verify as admin and be able to commit changes without starting the .exe directly as admin.
Something like:
group.Properties["member"].Add(distinguishedName);
group.CommitChanges();
If this is not possible I was thinking it could maybe be possible to restart the program when the user has typed in his credentials and putting in the admin-credentials directly into the username and password field as parameters.
Is that possible? If not, do you have other suggestions?
Your program does not need to run as admin. You just need to connect to Active Directory using credentials that have permissions to update that group. By default, it will use the credentials that the program is running with. So it sounds like whichever credentials you are using to run as admin also has permissions to update that group.
If it helps you, you can use alternate credentials for connecting to AD by using the constructor for DirectoryEntry that accepts credentials. For example:
var group = new DirectoryEntry($"LDAP://{groupDn}", "username", "password");
group.Properties["member"].Add(distinguishedName);
group.CommitChanges();
I hope somebody could help me to solve my problem.
There is some domain, and some shared directory in that domain. User has domain username and password, to get access to that shared directory, but his computer is not in domain most of time. I mean, when he need to connect to that directory he is typing network path (for example "\\fileserver"), than windows asks for username and password, and after writing it he will get the access until restart windows or logout.
So my question is, how can i get domain user name that user uses to connect to network, by using C# code?
I tryed to use CredentialCache.GetCredential, but i think it works only if user connect to shared directory by using NetworkCredentials in C# program. If connection already was before C# program started, it will be empty.
I also tryed Environment.UserName, but since computer is not in domain, it returns only local user name, that different from domain username.
Sorry for my bad english, i hope you could understand my explanation.
Have you took a look at the nugget package CredentialManagement ?
I used it already, but couldn't roam credential saved with enterprise persistence
using CredentialManagement;
using (CredentialSet credentials = new CredentialSet())
{
Debug.Print(credentials.Count.ToString() + " credential(s) found.");
foreach (Credential credential in credentials)
{
Debug.Print(credential.Target); //This is domain/IP of the saved credential.
Debug.Print(credential.Type.ToString());
Debug.Print(credential.Username);
Debug.Print(credential.PersistanceType.ToString());
Debug.Print(credential.Description);
Debug.Print(credential.LastWriteTime.ToString());
}
Debug.Print("End");
}
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?
I have been requested to expose a web service for managing Active Directory Users via an intranet. I have been advised that LDAP is viewed as a security vulnerability and is not to be used.
Given this constraint, I have managed to connect via ADSI with a DirectoryEntry object like this:
DirectoryEntry de = new DirectoryEntry();
de.Path = "WinNT://TheDomain.local";
de.Username = "NTUser1";
de.Password = "pwdpwdpwd2";
I can loop through the children of this DirectoryEntry get the ones that are users. On the Users, I can see these basic properties: UserFlags, MaxStorage, PasswordAge, PasswordExpired, LoginHours, FullName, Description, BadPasswordAttempts, LastLogin, HomeDirectory, LoginScript, Profile, HomeDirDrive, Parameters, PrimaryGroupID, Name, MinPasswordLength, MaxPasswordAge, MinPasswordAge, PasswordHistoryLength, AutoUnlockInterval, LockoutObservationInterval, MaxBadPasswordsAllowed, objectSid.
There are a number of User properties that are visible in the Active Directory MMC that are not accessible from the DirectoryEntry object including: LastName, NameSuffix, Department, etc...
These other properties are all documented in msdn as being exposed by IADsUser (http://msdn.microsoft.com/en-us/library/aa746340%28VS.85%29.aspx).
1) Is LDAP actually a vulnerable protocol? More so than the ADSI (WinNT) connection shown above? LDAP seems to be pretty common for this purpose.
2) How can I retrieve/set these other properties of the User?
TIA
1- LDAP packet transmission is performed as plaintext, so somebody can capture your data.
If you use LDAPS protocol or TLS-enable your LDAP connection, it is safe. ADSI is just an implementation of LDAP client by Microsoft, and it supports both LDAP and LDAPS connections.
When you use ADSI against your corporate Active Directory, it primarily tries to start a LDAPS connection.
So you are safe of you use ADSI; or you can use any other client or programming library as well if you use secure connection. the default port for LDAPS is 636.
2- To get more information about directory objects, you can use the GetInfoEx method, it loads exactly the attributes you want. Below you can see an example:
http://msdn.microsoft.com/en-us/library/aa746411%28v=vs.85%29.aspx
But some of the properties that you look for, are stored in the Active Directory by attribute names different from the MMC console. e.g. First name is stored as 'givenName' and Last name is stored as 'sn'. Look here to find names of attributes you need;
You can find more information here.
http://www.techgalaxy.net/Docs/Dev/Using_ADSI_and_LDAP_with_AD.htm explains the difference between LDAP and ADSI: http://technet.microsoft.com/en-us/library/cc755809(v=ws.10).aspx includes illustrations.
In short, ADSI is a simplified wrapper around LDAP. If there's any insecurity to it, it's in the binding, which here appears to be SIMPLE (unencrypted plaintext username and password). If you bind the LDAP connection using any other method (or over an SSL connection), it should be secure.
Seems that everything I do involves win services copying files across servers. I seem to get a lot of security & securityaccess type exceptions and never fully understand the causes. I am wondering if fileinfo or file.copy is a good solution or if there is a better. Is there a particular attribute I should be using or something to avoid these errors? Issue is not account or password related. example are \ipaddress\sharename \ipaddress\drive\path using domain accounts.
---Added Specific example.---
- I log on to serverA as domain\username. (including domain name)
- I open file eplorer in the address bar enter \\serverB\c$\folder hit enter, I right-click, create new file. No problem.
- I install service, go to properties select Log On, This Account and set the username as domain\username (including the domain name) same password I logged onto serverA with. It accepts it no problem.
Application does a FileSystemWatcher on \\serverA and copy to \\serverB when changed to keep the config files in sync.
private void CopyNewFileToClone()
{
FileInfo OriginalConfigFile = new FileInfo(Path.Combine(ConfigurationManager.AppSettings.Get("directoryToWatch"), ConfigurationManager.AppSettings.Get("fileToWatch")));
FileInfo CloneConfigFile = new FileInfo(Path.Combine(ConfigurationManager.AppSettings.Get("directoryToCopyTo"), ConfigurationManager.AppSettings.Get("fileToCopyTo")));
FileInfo tmp = new FileInfo(Path.Combine(CloneConfigFile.DirectoryName,"~" + CloneConfigFile.Name));
OriginalConfigFile.CopyTo(tmp.FullName, true);
tmp.CopyTo(CloneConfigFile.FullName, true);
tmp.Delete();
}
When I start the service I get Service cannot be started.
System.UnauthorizedAccessException: Access to the path '\\serverB\C$\folder\filename' is denied.
I use fileinfo to copy files from servers and it seems to work fine. If your sure it's not a account or password issue I would start looking at your DNS. If the network can't resolve what account is trying to access the network folder it won't matter if you are using a valid account. You may get lucky some/most of the time with cached accounts but there is no telling when it might not work and when it will work.
I would trace the network if you are getting a lot of broadcast messages for failed responses.
This was due to Code Access Security policy. Ran
c:\Windows\Microsoft.NET\Framework\v2.0.50727\CasPol.exe -af <path\application.exe>
and error resolved.
Adding as a installation step in all apps that need to write to HD, especially accross network via unc such as \server\share\file.