0

I have a WinForms application and want to be able to offer users an update if one is available (download and install .msi) and if possible. Some users are part of our domain, interns can be part of the domain of school, university or have a personal laptop. I want to detect if a user has administrator rights and is able to perform an update anyway.

I've seen solutions making use of WMI, "SELECT * FROM Win32_UserAccount" (tried, didn't work or maybe I'm missing something). I've seen solution querying the active directory (doesn't work if user has taken laptop home, disconnected). The below solution always returns false and I don't want to require my application to run in elevated mode.

public static bool IsAdministrator()
{
    using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
    {
        WindowsPrincipal principal = new WindowsPrincipal(identity);
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
}
  • But in order to perform an update, you will need to ask the user to elevate eventually, one way or another. Consider the (completely valid) setup where the user is using a regular account that has no admin permissions at all, and when elevating enters credentials for an admin account. If you simply check if the user would be an admin if elevated (which is possible, but requires more complicated code) then that scenario will still fail, for no good reason -- this is a personal pet peeve, by the way. :P – Jeroen Mostert Feb 18 '22 at 20:54
  • Not necessarily, for users of our domain, PsExec can be used with some credentials. Seems to work even if I briefly go into airplane mode, for some weird reason (maybe because I am also administrator on my laptop). For interns, it's a different story. – Dev MacDevface Feb 18 '22 at 21:06
  • So basically, I just want to check if Environment.Username is one of the user names in this window and is in the group "Administrators". Code should work when disconnected from domain / even no internet. https://i.imgur.com/K0terpK.png – Dev MacDevface Feb 18 '22 at 21:12
  • You can use domain admin accounts if you're disconnected, so long as the authentication ticket is locally cached and not yet invalidated -- in this case no roundtrip to the domain controller is needed. This might be what you're seeing. However, I don't see how that's relevant, since (presumably) your question is about whether the user is a *local* administrator (which might happen to include domain accounts that are local administrators). – Jeroen Mostert Feb 18 '22 at 21:12
  • See also [this question](https://stackoverflow.com/q/1220213/4137916), with the caveat that you have to ignore the answers that are specifically talking about elevation. Detecting whether the user is a non-elevated member of the local admin group is not particularly easy (also probably because it's mostly not very interesting; if the user is not currently an administrator, you can't reliably determine if they have the ability to log in as one -- they might, but beyond your knowledge). – Jeroen Mostert Feb 18 '22 at 21:19
  • The code you showed works fine, but only when the user is already elevated. As other comments say, you can't know if the user is able to run elevated. – Poul Bak Feb 18 '22 at 21:22
  • If you're truly looking for the user's *domain group* memberships when they're disconnected, by the way, I'm pretty sure that in particular is not possible, since you do need an active domain connection. Some details of that may be cached, but certainly not indefinitely (and even if they were, you couldn't rely on them, since the domain knows better). Probably not relevant since you presumably only care about being a local admin, but still worth mentioning. – Jeroen Mostert Feb 18 '22 at 21:23
  • Well, I would simply try to launch a process that requires elevation. If that succeeds, you have your answer. – Poul Bak Feb 18 '22 at 21:24
  • How I intend to use it (if possible): 1. Domain account (connected or disconnected): detect whether domain is ours or sister company, if so use PsExec with admin credentials in background and do not prompt user anything. 2. Everyone else: check whether the user has rights to install updates (is administrator somehow), if so prompt "Run as admin". If not, dialog window to the nature: "Info: update available, but you do not have rights to install". – Dev MacDevface Feb 18 '22 at 21:24
  • The first part should be covered with `Environment.UserDomainName` (that should give the same result for a disconnected account with cached credentials). The second part is complicated since Windows really wants you to just rely on elevation and UAC and not just perform a check for group membership, but it should be possible (see linked question). This does mean users who are not admins, but do have credentials for an admin account, will get the "you have no rights" prompt and then have to manually re-launch your app as an admin, which is a bit bothersome. – Jeroen Mostert Feb 18 '22 at 21:30
  • Just read the most recent comments. So, basically, what I am asking is impossible: "if the user is not currently an administrator, you can't reliably determine if they have the ability to log in as one". Poul's suggestion is interesting, to launch a process that requires elevation. But that would require user input anyway, right? I'm trying to avoid that, I just want to show users who won't be able to perform an update a notification. – Dev MacDevface Feb 18 '22 at 21:31
  • You can do that as long as you're willing to accept that you'll annoy "pro" users who *can* perform the update, but not as the account they're logged in with but a dedicated admin account they use when elevating, as there's obviously no way you can know that in advance. Again, though, the code for this is more complicated (detecting if the current credential is a member of the administrators group even if the token is not elevated), so you may not even want to bother. You could just run the process with elevation, detect failure and *then* display the notice. – Jeroen Mostert Feb 18 '22 at 21:39
  • Well, users will be people from our company or a sister company who are domain users but never an admin in the domain, only locally on their computer or interns, domain users of highschool or university or no domain (own laptop), same story. Anyway, thanks a lot for all the comments so far. Going to think about it. – Dev MacDevface Feb 18 '22 at 21:53

0 Answers0