Recent

Author Topic: Run as a different user  (Read 1248 times)

LemonParty

  • Sr. Member
  • ****
  • Posts: 388
Run as a different user
« on: November 16, 2025, 10:18:24 pm »
Hello.

Is there a method to run program as a different user? Interested Windows and Linux OS.
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

Warfley

  • Hero Member
  • *****
  • Posts: 2028
Re: Run as a different user
« Reply #1 on: November 16, 2025, 10:34:50 pm »
On Windows I don't know, on Linux yes

LemonParty

  • Sr. Member
  • ****
  • Posts: 388
Re: Run as a different user
« Reply #2 on: November 16, 2025, 11:51:37 pm »
How do I get TUid if I know user name?

By the way, I found the solution for Windows. It is CreateProcessWithLogonW from JwaWinBase.
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

Khrys

  • Sr. Member
  • ****
  • Posts: 364

MarkMLl

  • Hero Member
  • *****
  • Posts: 8515
Re: Run as a different user
« Reply #4 on: November 17, 2025, 09:30:49 am »
On Windows I don't know, on Linux yes

The problem there is that that requires that the program be started as root, which some widget sets (I forget which) explicitly refuse to accept.

A better way would be to bless the binary with the required capabilities, and then relinquish them as soon as they are no longer needed. Unfortunately that can't be automated at least in Lazarus, since the IDE doesn't have a "run as" option for the "Execute after" operation.

Thread at https://forum.lazarus.freepascal.org/index.php/topic,72090.msg563702.html#msg563702 is relevant.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 18475
  • Here stood a man who saw the Elbe and jumped it.
Re: Run as a different user
« Reply #5 on: November 17, 2025, 01:05:39 pm »
The problem there is that that requires that the program be started as root, which some widget sets (I forget which) explicitly refuse to accept.
No, that is not correct. like su/sudo you can use the underlying for a different user with different credentials and group.
That not necessarily means root, can be any other user. But that was an oversight?

man su.
« Last Edit: November 17, 2025, 01:07:31 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8515
Re: Run as a different user
« Reply #6 on: November 17, 2025, 04:45:37 pm »
The problem there is that that requires that the program be started as root, which some widget sets (I forget which) explicitly refuse to accept.
No, that is not correct. like su/sudo you can use the underlying for a different user with different credentials and group.
That not necessarily means root, can be any other user. But that was an oversight?

man su.

Thaddy, what part of

"fpSetUID sets the user ID of the current process. This call will only work if it is executed as root, or the program is setuid root."

do you find ambiguous?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

LemonParty

  • Sr. Member
  • ****
  • Posts: 388
Re: Run as a different user
« Reply #7 on: November 17, 2025, 05:43:26 pm »
On Windows I don't know, on Linux yes
How exactly should I use this function? Should I call it before runing TProcess?
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

rdxdt

  • New member
  • *
  • Posts: 9
Re: Run as a different user
« Reply #8 on: November 21, 2025, 10:36:45 am »
On Windows I don't know, on Linux yes
How exactly should I use this function? Should I call it before runing TProcess?
If your Linux based system has pkexec i've wrote a simple example, it's not elegant but depending on your needs it can work, please include the units BaseUnix and Process and then
Code: [Select]
if FpGetUID() <> 0 then
  begin
    RunCommand('pkexec',[ParamStr(0)],Dummy);
    Terminate;
  end
  else
  begin
    // Insert your code that must run as root
  end;                 

LemonParty

  • Sr. Member
  • ****
  • Posts: 388
Re: Run as a different user
« Reply #9 on: November 21, 2025, 03:24:28 pm »
I wrote this code that uses sudo:
Code: Pascal  [Select][+][-]
  1. function RunAsUser(User, Executable: String; Parameters: TStringDynArray): Boolean;
  2. var
  3.   P: TProcess;
  4.   i: SizeInt;
  5. begin
  6.   Result:= False;
  7.   P:= TProcess.Create(nil);
  8.   try
  9.     P.Executable:= 'sudo';
  10.     P.Parameters.Append('-H');
  11.     P.Parameters.Append('-u');
  12.     P.Parameters.Append(User);
  13.     P.Parameters.Append(Executable);
  14.     for i:= 0 to High(Parameters) do
  15.       P.Parameters.Append(Parameters[i]);
  16.     P.Execute;
  17.     Result:= True;
  18.   finally
  19.     P.Free;
  20.   end;
  21. end;
« Last Edit: November 21, 2025, 03:26:35 pm by LemonParty »
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

MarkMLl

  • Hero Member
  • *****
  • Posts: 8515
Re: Run as a different user
« Reply #10 on: November 22, 2025, 07:21:58 pm »
I wrote this code that uses sudo:

As I've said, you will get into trouble if trying to invoke arbitrary GUI-oriented programs because some widget sets explicitly refuse to run as root (rationale: far too much code and far too difficult logic paths which make the maintainers worried about security).

/What/ are you trying to do? In a lot of cases "the right way" is simply to make sure that you're a member of a specific group, or failing that to write a udev rule.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

LemonParty

  • Sr. Member
  • ****
  • Posts: 388
Re: Run as a different user
« Reply #11 on: November 23, 2025, 03:15:29 pm »
I just wrote a function for Windows that runs program as a different user because when I run program under administrator rights it is not working good. Then I thought it would be good to have a crossplatform version of this function.
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

MarkMLl

  • Hero Member
  • *****
  • Posts: 8515
Re: Run as a different user
« Reply #12 on: November 24, 2025, 09:27:38 am »
I just wrote a function for Windows that runs program as a different user because when I run program under administrator rights it is not working good. Then I thought it would be good to have a crossplatform version of this function.

On Linux with reference to the patch etc. described in the link I posted earlier, the contributed file runexecuteafterasuser.pas contains this:

Code: Pascal  [Select][+][-]
  1. (* The user has requested that the command passed as the parameter be run as a
  2.   different (usually more-privileged) user. Construct an appropriate prefix.
  3. *)
  4. function Prefix(const command, asUser: string): string; platform; experimental;
  5.  
  6. begin
  7.   if (asUser = '') or (asUser = 'root') then
  8.     result := 'sudo --askpass --reset-timestamp ' + command
  9.   else
  10.     result := 'sudo --askpass --reset-timestamp --user=' + asUser + ' ' + command
  11. end { Prefix } ;
  12.  

I did it like that after a lot of fiddling around because one can almost always rely on sudo being installed, and the --askpass option is generally set up to call into whatever graphical environment is running to bring up a dialog(ue), although this might require a line in /etc/sudo.conf or that the SUDO_ASKPASS shell variable has to be set somewhere.

However as I've said: making sure that the user is a member of the appropriate group, and/or that there are suitable udev rules in place, is almost always to be preferred. If that doesn't work, for example if a program is to listen on a low-numbered port, then use an appropriate POSIX capability.

There's problems there, which I'm sure I've touched on before (i.e. cited thread): in order to set a capability, you either need to be root or the capability-setting program needs to be blessed with the "this can set capabilities" capability. However if you bless something like an IDE with "this can set capabilities", then it can subsequently bless any program it generates with "this can set capabilities": if the POSIX people had really thought things through then there'd be a special "this can set any capability except for the 'this can set capabilities' capability".

MarkMLl
« Last Edit: November 24, 2025, 10:39:13 am by MarkMLl »
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

AlexTP

  • Hero Member
  • *****
  • Posts: 2647
    • UVviewsoft
Re: Run as a different user
« Reply #13 on: November 24, 2025, 05:02:27 pm »
Is this what you need?

Code: Pascal  [Select][+][-]
  1. function RunElevated(const AProgram, AParameters: UnicodeString; AHideWindow: boolean): boolean;

« Last Edit: November 24, 2025, 08:21:24 pm by AlexTP »

LemonParty

  • Sr. Member
  • ****
  • Posts: 388
Re: Run as a different user
« Reply #14 on: November 24, 2025, 06:27:40 pm »
Not exactly. I need to run from a different user, not Administrator. CreateProcessWithLogonW works fine with this. I guess for now this topic may be closed.
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

 

TinyPortal © 2005-2018