Get WindowsIdentifiy from Operating system using a SID - c#

I am sending request via WCF from Machine A to Machine B.
The domain and users are same on both machines.
In Machine B, using a given parameters, I want to create a WindowsIdentity for that user that invoked the operation from Machine A.
I know there is technology to do this via WCF infrastructure - but this technology is not enabled in my project.
So i need to send OperationContext.Current.ServiceSecurityContext.WindowsIdentity.User.Value from Machine A to Machine B.
My question is how do I create a WindowsIdentity using a SID ? Or do i need to send different parameters ?
Notes:
I was trying this:
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "My_Domain");
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, "userSID");
ofcourse with the right parameters, and then iterated all the GRP.GetMembers(true) to seek for mine - but it was not there.
Update:
The User is: DOMAIN_NT/MyUser123 -> If i change it to MyUser123#DOMAIN_NT and create instance of WindowsIdentity identity = new WindowsIdentitiy("MyUser123#DOMAIN_NT"); - It will work, but its an ugly way.

Related

c# check if a windows account is locked out in a specific domain

I'm trying to do something that I don't even know if it is possible.
I have a web application based on C# that runs on a specific server. I want to build a code where the user introduces the domain where the app runs (this server depends on the client, for each client it runs on different servers obviously) and the app returns the local windows user accounts of that domain and information saying if the users are locked out or not.
I've tried to use Win32_UserAccount but it seems to get the users of the network I'm currently using.
Is this possible to do?
Thank you so much
Regards,
Flávio Justino
Try
using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "domain"))
{
using(UserPrincipal usr = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "username"))
{
usr.IsAccountLockedOut(); //Gets if account is locked out
}
}
You need to add dpendency System.DirectoryServices.AccountManagement.dll for the above code to work.

impersonate multiple users at the same time

I'm making a service in .net that copy files from one domain (Domain A) to other domain (Domain B)
both domain need credentials in order to connect to them so i'm using impersonation.
using (new Impersonator(usr_name_source, domain_source, password_source))
the impersonation is working only for one domain each time, so actually i cannot work how to impersonate both domains at the same time in order to copy the files
so i'm trying this:
using (new Impersonator(usr_name_source, domain_source, password_source))//server authentication
{
using (new Impersonator(usr_name_target, domain_target, password_target))//server authentication
{
DeleteOldFiles(targetPath);
Copy(sourcePath, targetPath);
}
}
but its not working as when i impersonate the inside new Impersonator(usr_name_target, domain_target, password_target)
it forget the outer impersonation.
does anyone has any idea how to do that without mapping drives etc...?
You can only impersonate one user at a time, so your current solution will not work. Basically you are trying to connect to two different network resources. You can P/Invoke WNetAddConnection2 function to connect to network resource of different domain and perform operation as needed. See here for details on WNetAddConnection2: https://msdn.microsoft.com/en-us/library/windows/desktop/aa385413(v=vs.85).aspx
Go through this post to see how you P/Invoke WNetAddConnection2: How to provide user name and password when connecting to a network share

Finding last AD logon timestamp from remote machine

I'm trying to determine the last domain connection made by a user from a remote machine, regardless of if the machine is currently connected to the domain or not.
The closest I can get is using the System.DirectoryServices.ActiveDirectory and System.DirectoryServices.AccountManagement namespaces that do something similar to this:
Domain d = Domain.GetComputerDomain();
PrincipalContext c = new PrincipalContext(ContextType.Domain, d.Name);
UserPrincipal uc = UserPrincipal.FindByIdentity(c, "johndoe");
And then using the LastLogon property of the UserPrincipal.
This works fine, as long as the machine my application is running on is connected to the domain. If it isn't, Domain.GetComputerDomain() returns null, and I'm out of luck (even if I hardcode the domain name to the PrincipalContext constructor, it throws an exception when not connected to the domain). Is there some other AD property or registry key that gets stored locally on the remote machine when it makes an AD connection to the server that I could use?
The following link describing the LSA Cache seems promising, but, to my knowledge, there is nothing regarding domain connection timestamps that gets cached.
Determine User Active Directory Groups from Local Machine off Network

TFS 2010 - Why am I getting "TF30063 You are not authorized to access.." error when impersonating?

I am attempting to create a bug in TFS2010 by impersonating a user but always get
"TF30063 You are not authorized to access.."
I first authenticate using a service account and then attempt to impersonate a separate user account. I can successfully create Work Items using either account both programmatically and in the web UI. However, when I try to create the Work Item used an impersonated account (either way around) I always get this error. My code is:
public int Save(List<KeyValuePair<string, string>> values, ticketType type,string user)
{
// get the Uri to the project collection to use
Uri tfsuri = new Uri("http://94.23.12.119:8085/tfs");
// get a reference to the team project collection (authenticate as generic service account)
using (var tfs = new TfsTeamProjectCollection(tfsuri, new System.Net.NetworkCredential("username", "password", "servername")))
{
tfs.EnsureAuthenticated();
//Now get the details of the user we want to impersonate
TeamFoundationIdentity identity = GetImpersonatedIdentity(tfsuri,tfs,user);
//Now connect as the impersonated user
using (TfsTeamProjectCollection ImpersonatedTFS = new TfsTeamProjectCollection(tfsuri, identity.Descriptor))
{
ImpersonatedTFS.EnsureAuthenticated();
var workItemStore = GetWorkItemStore(ImpersonatedTFS);
// create a new work item
WorkItem wi = new WorkItem(GetWorkItemType(type, workItemStore));
{
//Values are supplied as a KVP - Field Name/Value
foreach (KeyValuePair<string,string> kvp in values)
{
if (wi.Fields.Contains(kvp.Key))
{
wi.Fields[kvp.Key].Value = kvp.Value;
}
}
ValidationResult = wi.Validate();
}
if (ValidationResult.Count == 0)
{
wi.Save();
return wi.Id;
}
else
{
return 0;
}
}
}
}
It successfully gets the impersonated identity but falls over on
ImpersonatedTFS.EnsureAuthenticated();
Both accounts have the 'Make requests on behalf of others' permission set.
First let me clarify one thing first. It seems your application is a server application, in which case there is no value in using EnsureAuthenticated(). It is just a performance tuning trick to help UI/desktop clients.
Now back to your main issue:
- If your application works as expected when you access locally but fails when you access remotely, then please read on, otherwise this is not the solution for you.
The reason it is failing is because the SPN needs to be added to the service account on the active directory. It is necessary for Kerberos authentication to take place.
This is something that TFS team needs to explain because many developers will forget about it while focusing at the job it hand. Hope this helps.
To learn more about SPN's and Kerberos fundamentals, check out these resources:
Kerberos for the busy admin.
Introduction to Kerberos SPN
I hope this helps.
Thanks!
Where do your users have the Make requests on behalf of others permission set? Is it at the Project Collection level (accessed via Team > Team Project Collection Settings > Security..) or at the TFS server level (accessed via Team Foundation Administration Console > Application Tier > Security..) ?
I think your problem is that you only have permission to impersonate at the 'Server' level, but you're trying to impersonate in a collection.
This is what Taylor has to say in his Introducing TFS Impersonation blog post:
This permission is encapsulated within each Team Project Collection
and within the Configuration Server. This means that if User A has
this permission on TPC1 he will not be allowed to impersonate users
when talking to TPC2 or the Configuration Server. Similarly, if User
B has this permission on the Configuration Server she will not be able
impersonate users when talking to any of the Team Project Collections.

DirectoryServicesCOMException when working with System.DirectoryServices.AccountManagement

I'm attempting to determine whether a user is a member of a given group using System.DirectoryServices.AccountManagment.
I'm doing this inside a SharePoint WebPart in SharePoint 2007 on a 64-bit system.
Project targets .NET 3.5
Impersonation is enabled in the web.config.
The IIS Site in question is using an IIS App Pool with a domain user configured as the identity.
I am able to instantiate a PrincipalContext as such:
PrincipalContext pc = new PrincipalContext(ContextType.Domain)
Next, I try to grab a principal:
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain))
{
GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, "MYDOMAIN\somegroup");
// snip: exception thrown by line above.
}
Both the above and UserPrincipal.FindByIdentity with a user SAM throw a DirectoryServicesCOMException: "Logon failure: Unknown user name or bad password"
I've tried passing in a complete SAMAccountName to either FindByIdentity (in the form of MYDOMAIN\username) or just the username with no change in behavior. I've tried executing the code with other credentials using both the HostingEnvironment.Impersonate and SPSecurity.RunWithElevatedPrivileges approaches and also experience the same result.
I've also tried instantiating my context with the domain name in place:
Principal Context pc = new PrincipalContext(ContextType.Domain, "MYDOMAIN");
This throws a PrincipalServerDownException: "The server could not be contacted."
I'm working on a reasonably hardened server. I did not lock the system down so I am unsure exactly what has been done to it. If there are credentials I need to allocate to my pool identity's user or in the domain security policy in order for these to work, I can configure the domain accordingly. Are there any settings that would be preventing my code from running? Am I missing something in the code itself? Is this just not possible in a SharePoint web?
EDIT:
Given further testing, my code functions correctly when tested in a Console application targeting .NET 4.0. I targeted a different framework because I didn't have AccountManagement available to me in the console app when targeting .NET 3.5 for some reason.
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain))
using (UserPrincipal adUser = UserPrincipal.FindByIdentity(pc, "MYDOMAIN\joe.user"))
using (GroupPrincipal adGroup = GroupPrincipal.FindByIdentity(pc, "MYDOMAIN\user group"))
{
if (adUser.IsMemberOf(adGroup))
{
Console.WriteLine("User is a member!");
}
else
{
Console.WriteLine("User is NOT a member.");
}
}
What varies in my SharePoint environment that might prohibit this function from executing?
I added the account used by the IIS Application Pool to the Administrators group and this issue was resolved.

Categories

Resources