What is the difference between these two ways of obtaining Domain names? - c#

What is the difference between these two statements.
System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName;
and
Environment.UserName;
Is there any way to retrieve the machine domain without using System.DirectoryServices?

I hope this helps:
From: https://msdn.microsoft.com/en-us/library/system.environment.userdomainname(v=vs.110).aspx
The UserName property wraps a call to the Windows GetUserName function. The domain account credentials for a user are formatted as the user's domain name, the '\' character, and user name. Use the UserDomainName property to obtain the user's domain name and the UserName property to obtain the user name.
The Environment.UserName uses GetUserName
Environment.UserDomainName
Will get the User's domain name.
https://msdn.microsoft.com/en-us/library/system.environment.userdomainname(v=vs.110).aspx

Related

store (get and set) data in Active directory , for example connection string

is there a way to store global data (like connect string etc. ) in active directory and get it in c# function ?
somthing like
AD ad = new ...
ad.Save ("MyConnString",connectionString);
ad.get...
This is how you would update a text attribute on an AD object:
var adObj = new DirectoryEntry($"LDAP://{distinguishedName}");
adObj.Properties[attribute].Value = "my connection string";
adObj.CommitChanges();
Actually doing it is the easy part. Planning it will be the harder part.
Active Directory consists of objects with attributes. So yes, you can store text in any text attribute, but you would have to decide:
Which object you will store the data on (distinguishedName in the code), and
Which attribute you will use (attribute in the code)
If the connection string is common for everyone on the domain, you could store it at the root of the domain, but that comes with two problems:
Permissions to write to the root of the domain are usually only given to domain admins
There are fewer unused attributes that you could choose from.
If you write the connection string to each user object, then it will be easier to find an unused attribute (if you use Exchange, then there are several that start with extensionAttribute that are often unused), but you are also duplicating that data on every account and you'll have to hope no one changes it.
Like the commenters above, I would suggest you store this somewhere else. If it is a unique connection string per-domain, then you could just store a mapping table (this domain = this connection string). Once the user logs in, you can see which AD domain they're on and grab the correct connection string.

How do I compare UserPrincipal with WindowsIdentity?

When binding a user to a Windows Account Im using the UserPrincipal SamAccountName according to this post(binding saved in database). Then when doing a login I need to check this binded user(from database) against the loggedin Windows Account and this is done with a WindowsIdentity objeckt.
The problem is that WindowsClient.Name will state Group\SamAccountName instead of just the SamAccount? It would be good to use the group but the UserPrincipal does not seem to return this?
So how should I match thay to? Should I just remove the Group in WindowsClient.Name or is there a way to add it in the UserPrincipal?
There are a few options here:
Don't compare principals using SamAccountName only, theyre only unique within a single domain, use SID instead: UserPrincipal.Sid and WindowsIdentity.User
Don't use WindowsIdentity to get the current user, use UserPrincipal.Current instead.

How to check if input string is valid active directory userPrincipalName?

User will input his wanted login name and I need to create active directory user by given name. So I need to validate it for AD userPrincipalName rules. How can I do it?
You need only query the UPN (Forest wide so do a globalcatalog search). If the DirectorySearcher returns an object, the UPN is in use.
You would also need to check that the planed samAccountName is not in use in the target domain, and that the planed user Name is not in the destination OU or Container. In both searches, as above, if the DirectorySearcher returns results, you must not continue, but chose alternatives.
Look here to find which attributes must be unique, but bear in mind, although the user's Name attribute is not mentioned in the table, it is being refered to in example 1.

Is there a better way to access Active Directory Organizational Units than by name?

I'm having issues with our Domain Administrator changing the name of our domain org units without any warning. I have the AD path listed in my web.config. When he changes the names my reference in the code breaks. Is there another way to reference i.e. some sort of 'OU ID'?
<appSettings>
<add key="adStructure" value="OU=Org Name 2,OU=Org Name 1,dc=test,dc=test2,dc=test3"/>
</appSettings>
I'm trying to get a list of all groups within OU Org Name 2.
Yes, you can take advantage of otherWellKnownObjects. http://msdn.microsoft.com/en-us/library/ms679095(v=vs.85).aspx. You will need to populate a GUID and initial path to each OU in there, and then in the future when the OU is moved or renamed, AD will keep track. You simply bind by GUID instead of DN.
This link explains how - http://msdn.microsoft.com/en-us/library/ms676295(v=vs.85).aspx.
If the user accounts or other bjects you are accessing have an unique property for accessing them you could perform an LDAP/AD search query for getting the list of objects you need - independent of the distinguished name (DN) and therefore independent of the OU the are located in.
For details how to search in the AD see here:
How to get AD User Groups for user in Asp.Net?
http://www.codeproject.com/KB/system/QueryADwithDotNet.aspx
If you are looking for user objects an alternative would be a group containing all user accounts related to your application - as the Active Directory automatically updates/generates the distinguished name of the members.

IPrincipal.IsInRole() only works when I truncate the role names - why?

I have an application that relies heavily on authorization of users. Within it, I am using IPrincipal.IsInRole() to check whether users are in the correct groups:
IPrincipal principal = Thread.CurrentPrincipal;
bool inRole = principal.IsInRole("mydomainname\some role with a long name");
This works fine for the most part, but fails (returns an incorrect result) if the principal is an instance of a WindowsPrincipal. I have found that to make it work correctly, I have to truncate the name of the role that I pass in to be 32 characters long (including the domain name and the \):
IPrincipal principal = Thread.CurrentPrincipal; // <- returns a WindowsPrincipal
bool inRole = principal.IsInRole("mydomainname\some role with a lo");
Truncating the role name then works correctly. Why? Is this a bug/feature/documented issue? I have an inkling that it may be related to Win2000 domains, but cannot find any info on it.
Some extra info:
This is a problem because the application can be configured to use either active directory or "custom" for its authorization ("custom" being any authorization provider that supports an interface - could be SQL-based, file-based, etc..). When custom is configured, the roles most likely do not need truncating and so I don't want to have to deal with this special case in my code. Additionally, I have another part of the application that uses classes in the System.DirectoryServices.AccountManagement namespace to look up groups memberships. This requires the full role name and does not work if they are truncated.
After much trial and error, I have figured out what is going on.
When a group is created in Active Directory, it is given two names:
It seems to be that WindowsPrincipal uses the pre-Windows 2000 group name when IsInRole is called.
After searching extensively, this does not seem to be documented anywhere. The closest I got was this speculative answer to a similar question here on SO.
In my case, the groups I was querying against on the domain had a long name, but a truncated pre-Windows 2000 name (truncated to 32 characters for some reason). Passing in the long name does not work as it was checking against the wrong group name.

Categories

Resources