0

I need your help again :)

What I want to do:
I have a c# program which runs with normal user permissions - those can't be raised - and I want to change the system date (not time) from that program.

[EDIT] To be a bit more specific: I do have administrator credentials which could be embedded to the program (yikes, I know), but I want to avoid an UAC prompt.

When I launch cmd from outside Visual Studio and try to change the date, it fails with "missing client permission" (roughly translated from German). When I launch cmd as administrator, confirm the UAC prompt the same command succeeds.

I am writing from home, so I cant provide running code at the moment. But all my tries did compile and run without error but the date wasn't changed.

What I've tried:

  1. Created a Process instance, applied admin credentials to ProcessStartInfo, set the FileName to c:\windows\system32\cmd.exe and the argument to /C date {thedate}. I redirected StandardOutput and StandardError and after execution StandardError contains the same message as stated above: "missing client permission"

  2. I've modified this example MSDN: WindowsIdentity.Impersonate using PInvoke with AdvAPI32.LogonUser to raise permissions and Kernel32.SetSystemTime to change the system time. AdvAPI32.LogonUser succeeds and WindowsIdentity.GetCurrent().Name returns the admin name, but calling Kernel32.SetSystemTime fails with "missing client permission".

  3. I've tried opening the current process AdvApi32.OpenCurrentProcess and adjusting the permissions using AdvApi32.AdjustTokenPrivileges following this example StackOverflow: Change system time programmaticaly using datetimepeaker and the code runs totally fine but Kernel32.SetSystemTime fails...

[EDIT] Solution:
I ended up writing a small program with an embedded app.manifest that requests administrator privilegs. This app is called from the main program so this can still be run by a normal user.

Michael
  • 1,931
  • 2
  • 8
  • 22
  • 2
    I don´t understand your question. When you need privileges for some task, you surely have to provide some. Or in other words: you **need** admin-privileges to change the system-date. – MakePeaceGreatAgain Jan 18 '21 at 16:23
  • Does this answer your question? [How do you do Impersonation in .NET?](https://stackoverflow.com/questions/125341/how-do-you-do-impersonation-in-net) – Charlieface Jan 18 '21 at 16:31
  • 2
    You need privileges. Turn of UAC in Windows to remove popup and create a short cut to always run as admin. – clamchoda Jan 18 '21 at 16:32
  • @HimBromBeere i do have the administrator credentials and i used them to create the process/to impersonate but it seems without app.manifest/UAC prompt for the program a restricted token will be used which does not allow me to change the date. – Michael Jan 19 '21 at 15:55
  • @Charlieface Thanks for the link. The code is easier to read, but the code from MSDN did work. `WindowsIdentity.GetCurrent().Name` did confirm that I am the administrator, but even that didnt allow me to change the date. – Michael Jan 19 '21 at 15:58

2 Answers2

1

It is not possible to change the privileges of the process, once it's started. The original process has to start another process with elevated privileges. This second process can actually be the same .exe file, but with a command parameter that tells the process to do some small stuff and exit immediately.

To start a process with elevated privileges use Process.Start, but with .Verb = "runas", as described in another question. This will of course cause UAC prompt to pop up, if it's enabled on the machine. At least one UAC prompt has to be shown, because UAC prompt is the whole point if this defense mechanism.

If you want to reduce many UAC prompts to just one then you can set the original app to be started as administrator (UAC prompt shows when original process starts) and have just one process. Or have some interprocess communication between original process and elevated process, so that elevated process is started only once and made to finish when original process ends. In the second case UAC prompt shows the first time it's needed.

Dialecticus
  • 16,400
  • 7
  • 43
  • 103
  • I've upvoted since its the solution I ended up with, but its not the solution (authenticating as administrator without UAC prompt) I was looking for - but it seems to be to only way to go. – Michael Jan 19 '21 at 15:52
0

Can I ask why you are needing to change the system time from an unprivileged application?

If it is to influence other applications then you will need admin privilege since date time is such a vital system function to many other applications. However if you are just needing to adjust the date in your application only then I would suggest creating your own date/time provider that can return the date offset to the date that you desire in your application.

For example.

 public DateTime GetDateWithOffset(int daysToOffset)
    {
        return DateTime.UtcNow.AddDays(daysToOffset);
    }
Jake Cozart
  • 43
  • 2
  • 8