Windows security and identifying privilages in .Net - c#

I have a windows forms application that will be run in both domain and on non-domain (local desktop) environments. I'm trying to understand how the windows security works in these different environments. I need to programmatically identify when the windows user running my application as an Administrator which I'm assuming is different for domain and local environments (and possibly when the UAC is in control?? ).
I'm also a little confused as to whether the UAC supersedes a domain log in if turned on?
I expect most remote users of the product will be set as local Administrators too, and restricted by the UAC.
How do you check for privileges under these conditions? (vb.net app but c# is also fine - thank you)
Cheers, Tim.

Public Function isWindowsAdministrator() As Boolean
My.User.InitializeWithWindowsUser()
If My.User.IsAuthenticated Then
If My.User.IsInRole(Microsoft.VisualBasic.ApplicationServices.BuiltInRole.Administrator) Then
Return True
End If
End If
Return False
End Function
There is probably a nonVB/'pure' NET alternative, I just dont know the equivalents. There is also a way to test if the user can elevate to Admin, but it is a PInvoke, messy win32 thing, and doesnt actually elevate, just tests.
UAC will still pop up, the above just lets you know in advance if the user can authorize.

Vb.Net:
Public Function IsUserAnAdmin() As Boolean
End Function
C#:
[DllImport("shell32.dll")]
public static extern bool IsUserAnAdmin();
As you can see returns a Boolean by calling IsUserAnAdmin (you could obviously use an alias). for clarity I believe this works in all scenarios I mentioned but I haven't fully completed my Domain testing.... yet

Related

Why can't a windows service created in C# detect that a screen saver is currently running?

As part of some work I need to get done for Windows 10, I have written a code in C# that essentially detects every minute whether a PC is in screen saver mode or not, and it writes to a table in MySQL the relevant status ("PC in use" if the screen saver is off, "available PC" if the screen saver is on).
I did this using (full link if required - https://www.codeproject.com/Articles/17067/Controlling-The-Screen-Saver-With-C):
// Returns TRUE if the screen saver is actually running
public static bool GetScreenSaverRunning( )
{
bool isRunning = false;
SystemParametersInfo( SPI_GETSCREENSAVERRUNNING, 0,
ref isRunning, 0 );
return isRunning;
}
The code works flawlessly in console application mode (I made a loop to test it out over a minute with a check up on screen save status every 10 seconds), this means in MySQL the status was set correctly every time, depending on the screen save status at the moment of the check up.
The problem occurs when I use this code for a windows service. The service is installed correctly, the log on tab is set on Local System (I also tried with the logged in user instead, same results) and I allow the service to interact with the desktop, just in case, but the difference here is that no matter if the PC enters screen save or not, it always returns false on GetScreenSaverRunning(), thus setting the status of the PC in MySQL as "PC in use", even if the screen saver is on at the moment of check up.
I get the sense that the problem isn't in the code itself, since it works without any issues as a console application, but perhaps something behind the scenes. I tried to search here and on many other websites, haven't found anything related to such a problem.
Does anyone have any idea at all what might be the issue? Any help and/or suggestions will be greatly appreciated!
Thank you in advance.
(I could post the code if required, but it is pretty much straight forward and the main part of it, controlling the screen save detection, is taken from the website mentioned above, afterwards it's a simple if (GetScreenSaverRunning() == true) )
Ever since Vista, Services are barred from a Interactive Session. Even if they run under the same rights, they do not get a interactive Session. I would guess that is getting in the way here.
While you can overwrite this behavior in the Service settings, this is not adviseable for new code. Consider making this a Background Task started by the Task Sheduler instead.
Because the windows service runs in different session then the windows logon. You can't interact with the desktop related services unless you run the windows service in win logon session. There used to be an option in Windows service manager where you can set the properties to "Interact with desktop session" but I don't think that ever worked.
There's a work around to run the windows service using the win logo session.
See this helper class that can get the current logged on user session and interact with the desktop services. https://github.com/murrayju/CreateProcessAsUser/blob/master/ProcessExtensions/ProcessExtensions.cs

windows: XP -> current: how to tell if in CONSOLE or RDP session?

I have a messy collection of Windows platforms in various labs. Everything from XP to the latest. I have a simple C#/.NET app that runs at user login and logout. I need to differentiate between true Console logins and RDP sessions. I am using
System.Diagnostics.Process.GetCurrentProcess().SessionId
to get a sessionId but I don't see anything that says "you are on the Console" or "you are in an RDP session". Is there such a thing?
For my needs it turns out that the windows environment variable %sessionname% holds the info I am looking for. In my C# code I can say:
string sessionName = Environment.GetEnvironmentVariable("SESSIONNAME")
?? "CONSOLE";
%sessionname% seems to hold either the string "console" or "rdp-(something)#(number)", ex "rdt-tcp#1234". I don't know the whole range of possible values but it looks like it will work for my needs.
You can determine which session ID (if any) is currently attached to the physical console by calling the WTSGetActiveConsoleSessionId() function.

UnauthorizedAccessException when creating directory but only when impersonating myself

I'm currently running into an odd little problem in an installation wizard. On one single test VM--all the others are fine--I cannot create subdirectories in a directory I created. On the first screen I select an install location and, if it doesn't exist, create it:
c:\Program Files\Foo
Then a couple screens later, I get user credentials for the software to use and, to make sure they have the appropriate permissions, use them via impersonation to create subdirectories under Foo, say Bar and Baz. The impersonation I'm using is based on link.
The thing is, if I'm logged in as myself, that first directory is created just fine. But if I put my EXACT SAME CREDENTIALS into that later screen, it fails to create those subdirs. Despite the fact that it's the same creds that the program itself are currently running under.
Also, as I said, this works literally everywhere else except this one machine. So it doesn't make any sense. All we can figure is something broken about the impersonation system. That's all we can figure. But you'd think it would show up elsewhere. If it was something with the VM, then how did we create the Foo directory in the first place?
Anyway, any suggestions would be most welcome. This is really nutso.
EDIT: I have verified my account is local Admin on the VM. Nothing helpful in the Event viewer. Also, fixed link to MS impersonator code.

Run as SYSTEM and logoff user "USER" Pin

I have a program that runs as a scheduled task. The program runs on XP as SYSTEM.
The idea is that the program will run in the background, while USER is active.
I need the program to logoff USER when specific conditions occur.
I tried using:
[DllImport("user32.dll")]
public static extern int ExitWindowsEx(int uFlags, int dwReason);
but that appears to not log USER off.
I think maybe it's logging SYSTEM off, as it is running as SYSTEM.
How can i logogg USER?
Thanks,
SummerBulb.
I think that you will need to run some code as that user. Create an app that runs when a user logs in and then monitors an event. Have your service set the event and then the code will call the ExitWindowsEx method. You will still need to use the forceifhung and logoff params as James mentioned.
It would help if you showed the flags for ExitWindowsEx, but you may need to impersonate the user, though I think this is unlikely. If I remember logging off the current user was enough, but you may have to force the logoff, as it can be cancelled otherwise, if the user hasn't saved some changes for example.
But to impersonate a user you can look at this:
http://www.codeproject.com/KB/system/UserImpersonation.aspx
I would start with looking here, and include both the logoff and forceifhung values:
http://msdn.microsoft.com/en-us/library/aa376868(VS.85).aspx
It would be similar to EWX_FORCEIFHUNG | EWX_LOGOFF as the parameter.
UPDATE:
I expect Mike is correct that impersonation won't help here.

UAC gives me fits!

The code I am currently working on runs on Windows Server 2003, but needs to be able to write to EventLogs on multiple machines. I am coding in C#, using VS2008 Pro, and .NET Framework 3.5.
The code itself is relatively simple (thanks to the framework):
using (EventLog remoteEvtLog = new EventLog(LogName, HostName, EventSource))
{
remoteEvtLog.WriteEntry(Body);
}
"LogName" is a string containing the name of the log to write to - in most cases "Application".
"HostName" is a string containing the NetBIOS Name of the machine where the log entry should be written.
"EventSource" is a string containing the name of the event sender (this is a utility used by multiple apps, so usually it will have the name of the consuming application).
"Body" is a string containing the text to be written to the event log.
In most cases this works fine, but when the machine being written to uses UAC, any write which creates a new EventSource fails. This occurs even though the Security credentials used are members of the Administrators group - and I have not been able to find a way to specify the elevated priviledge level. Apparently, members of the Administrators goroup get two tokens - one limited, and one elevated, but as far as I can tell, the only way to specifiy the elevated token is through the UI - which is obviously a problem when remotely accessing the Logs.
Any ideas out there?
Your code is not supposed to create new event sources (the legacy auto-create behavior is unfortunate, but still wrong). If you need a separate event source for your application, then the installer for that application - which runs with elevated administrative privileges - should create it.

Categories

Resources