Check active directory attribute permission (UnlockAccount, PasswordNeverExpires, ExpirePasswordNow, ....) - c#

In my small tool, I give the service desk user the ability to reset user passwords from "Active Directory Users and Computer Console".
The user can also change some AD attributes.
Now I have a problem
Admin-User1 = can do everything
Admin-User2 = is not allowed to write the attribute "UserCannotChangePassword".
Here is an example how I do it:
PrincipalContext AdPrincipalContextUsers = new PrincipalContext(ContextType.Domain, "DC01", #"MyDom.local\Admin-User2", "PWD123");
string strDistinguishedName = "CN=Test-User1,OU=Users,OU=MYC,DC=MyDom,DC=local";
UserPrincipal objAdUser = UserPrincipal.FindByIdentity(AdPrincipalContextUsers, strDistinguishedName);
objAdUser.UserCannotChangePassword = (bool)ChkUserCannotChangePassword.IsChecked;
objAdUser.Save();
About "try, catch" I can intercept, but this is not a nice solution.
I would love to solve it like this: When the program starts I check if the Admin-UserX has permission on the attribute. The checkbox is then "checkbox.enable=true" else "checkbox.enable=false".
I found this one: How can I check if a user has write rights in Active Directory using C#?
The objAdUser Attribute:
UserCannotChangePassword
UnlockAccount
Enabled
PasswordNeverExpires
ExpirePasswordNow
are unfortunately not found under "allowedAttributesEffective".
Now my question:
How can I check the permission on the Active Directoy attribute.
Thanks for your help.
Greeting Brauschi

Related

How to create GMSA account via C#

I have tried to look for the c# code example to see how the AD service account is created but not much luck. Anyone can provide an example code for creating AD service account please?
I have tried UserPrincipal with $ at the end of the name but not much luck. Errors with Access Denied (Cant create under root MyDomain or under a CN)
// Domain Context to use specific LDAP path.
domainContext = new PrincipalContext(ContextType.Domain, domainContext.ConnectedServer, "CN=Managed Service Accounts,dc=mydomain");
UserPrincipal userAccount = new UserPrincipal(domainContext)
{
DisplayName = userName,
SamAccountName = $"{userName}$",
Description = description
};
userAccount.Save();
Little late, but I think I can answer it. You need to use the NetAddServiceAccount function through logoncli.dll. I hadn't been able to get it to work in PowerShell, even with adding what I thought was an appropriate type shim, but I just came across a module that seems to work.
https://github.com/beatcracker/Powershell-Misc/blob/master/Use-ServiceAccount.ps1
The C# code for the type definition in that script should have everything you need to implement it for yourself.

Login to different active directories programaticly in c#

The company that I work for has two active directories (ad1.com, ad2.com) because it has two different stores that had nothing to do with each other and plenty of users but now the managers of both stores need a page in common.
So I need to create a login where the users could access using just their Active Directory username and password.
In the login page there should be a list to choose the active directory and after that the user Paul(paul#ad1.com) and the user Paul(paul#ad2.com) with their respective password should be able to access to the page.
I have the code needed for the logIn page for one AD and works great but I don't know if it's possible to make the page available for two ADs.
Do I need some extra configuration on the server?
I google this but didn't find anything related.
If you have the code required for one AD, you could very well use the same code with slight modifications to authenticate against another AD.
Based on the domain name, you can identify the settings for AD and perform your authentication.
In cases where you use two AD, only identifying the domain name matters E.g.
ad1\username or username#ad1.com. You will not be able to achieve a login without the user specifying the domain name.
Have you tried using LDAP Authentication and just definining it differently based on the dropdown list?
Something like:
string adPath = string.Empty;
string domainName = string.Empty;
switch (ddlOption.ToString())
{
case "ad1":
adPath = "ad1Path";
domainName = "ad1";
break;
case "ad2":
adPath = "ad2Path";
domainName = "ad2";
break;
}
LdapAuthentication adAuth = new LdapAuthentication(adPath);
if (adAuth.IsAuthenticated(domainName, username, password))
{
//redirect Logic
}

C# Distribution list attributes (active directory)

Hi I'm trying to update my distribution lists menagers using LDAP
And I need to know what is the attribute of the "manager can update membership list" checkbox
I want only use c# NOT vbs or powershell
I can update the menageby but I prefer that you write it for the exmple..
The simple answer is there is no attribute for the "Manager can update membership list" checkbox, the check box is a security setting. When you check it the security of the group is modified to include the manager with the required permissions, unticking removes the managers rights under the security tab to modify the group.
You can use the ObjectSecurity to see if a SID has a unique ACL entry, in a standard environment this should be enough. This code should give you an idea of how to do it.
NTAccount acc = new NTAccount(managersam);
SecurityIdentifier sid = (SecurityIdentifier)acc.Translate(typeof(SecurityIdentifier));
ActiveDirectorySecurity sdc = YourGroupObject.ObjectSecurity;
AuthorizationRuleCollection arc= sdc.GetAccessRules(true, false, Type.GetType("System.Security.Principal.SecurityIdentifier"));
foreach (AuthorizationRule ar in arc) {
if (ar.IdentityReference== sid
{
managercanedit= true;
}
}

How to tell if SPUser is Active Directory account

I'm working on a project where the client wants to restrict some content to only Active Directory users . Is there any way to identify that a SPUser is an AD user short of parsing the username string for the domain (or something along those lines). Something like SPUser.IsADUser would be awesome.
Edit
This seems to work, but I'm not sure if this is reliable enough? For this use case, identifying that a user is a windows user is enough (there are no local system accounts)
SPUser user = SPContext.Current.Web.CurrentUser;
string userName = user.LoginName.Substring(user.LoginName.IndexOf('|') + 1);
SPPrincipalInfo info = SPUtility.ResolveWindowsPrincipal(SPContext.Current.Site.WebApplication, userName, SPPrincipalType.User, false);
if(info != null){
//THIS IS A WINDOWS ACCOUNT
}
In my experience it is much better to use audiences for this purpose. You then can easily trim any web part using "Audience" property. You can read about audiences here. Of course it will only work if you have user profile synchronization configured.

How to edit the registry keys of a specific user programatically?

I want to change a few settings of a Windows user that I created in my application. If I understand correctly, his "HKEY_CURRENT_USER" values will be under HKEY_USERS/<sid>/.... Is this correct? How can I get the sid of the user, if I know the user name and the domain?
Edit: How can I correctly edit the HKCU keys of that user, if I have the sid already?
I have a program that does exactly that. Here is the relevant part of the code:
NTAccount ntuser = new NTAccount(strUser);
SecurityIdentifier sID = (SecurityIdentifier) ntuser.Translate(typeof(SecurityIdentifier));
strSID = sID.ToString();
You will need to import two namespaces:
using System.DirectoryServices;
using System.Security.Principal;
Hope this helps.
Then use Registry.Users.SetValue with SID string\path to set the registry value.
This might not work as intended if you are editing a logged-off profile, especially a roaming profile.
There are two steps to this. First you must get the users sid. Second you must load the users registry hive. Other users hives are not loaded by default so you must load it explicitly.
The answer in Daniel White's comment is the best way to get the sid.
To load the user's registry hive, use the LoadUserProfile windows API via pinvoke. There is a complementary UnloadUserProfile to unload the hive when you are done with it.
You can use Query by example and search using PrincipalSearcher for appropriate UserPrincipal
// Since you know the domain and user
PrincipalContext context = new PrincipalContext(ContextType.Domain);
// Create the principal user object from the context
UserPrincipal usr = new UserPrincipal(context);
usr .GivenName = "Jim";
usr .Surname = "Daly";
// Create a PrincipalSearcher object.
PrincipalSearcher ps = new PrincipalSearcher(usr);
PrincipalSearchResult<Principal> results = ps.FindAll();
foreach (UserPrincipal user in results) {
if(user.DisplayName == userName) {
var usersSid = user.Sid.ToString();
}
}

Categories