Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-10

How to detect if my program is running with root/elevated privileges?

6 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bart

Hi,

In my program I have some functions that must only be enabled if the program is invoked as root (linux) / administrator (windows).

Is there some cross platform way to detect this?

I thought of trying to write to a "protected" location (/etc/something on linux, C:\ProgramData\something on Windows), but the problem is that Windows virtualizes these calls (it'll end up somewhere lse, where your program will never find it again), so writing will succeed even if user has no administrator rights.

Bart

Marco van de Voort
to Bart

In our previous episode, Bart said:

Show quoted text 6 lines
I thought of trying to write to a "protected" location (/etc/something on linux, C:\ProgramData\something on Windows), but the problem is that Windows virtualizes these calls (it'll end up somewhere lse, where your program will never find it again), so writing will succeed even if user has no administrator rights.

For windows there is winutils.iswindowsadmin(), for unix likes there is fpgeteuid (which should return zero for root).

Mark Morgan Lloyd
to Bart
Bart wrote 6 lines
On 10/27/13, Marco van de Voort wrote: > For windows there is winutils.iswindowsadmin(), for unix likes there is > fpgeteuid (which should return zero for root). Thanks a lot.

Also remember unix-style capabilities.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Bart
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote 6 lines
>> For windows there is winutils.iswindowsadmin(), for unix likes there is >> fpgeteuid (which should return zero for root). > Also remember unix-style capabilities.

Care to elaborate on that?

Bart

Mark Morgan Lloyd
to Bart
Bart wrote 8 lines
On 10/28/13, Mark Morgan Lloyd wrote: >>> For windows there is winutils.iswindowsadmin(), for unix likes there is >>> fpgeteuid (which should return zero for root). > Also remember unix-style capabilities. > Care to elaborate on that?

You can use the setcap utility to add or remove capabilities to a binary. I can't remember how they're stored, or why this is considered even adequately secure. The capabilities library (e.g. libcap.so, don't confuse this with a file from Mozilla of the same name) can be used by a program to add capabilities to itself, provided that it starts off as uid root. Note that gtk2 does not allow a program to be setuid root.

Below cut-and-pasted from my notes from when I was last looking at this, sorry about the poor format. I've translated the appropriate header file and hacked together a shim for the .so, usual cautions about making sure it actually exists.

(* This requires that the program be running with sufficient
capabilities to be *)
(* able to bind to ports < 1024, however immediately after this is done
it goes *)
(* to a lot of trouble to relinquish as many privileges as possible.
         *)
(*
         *)
(*  *   If linked with gtk2, it is not possible to run setuid root but
explicit *)
(*      capabilities may be added during installation:
         *)
(*
         *)
(*              # setcap CAP_NET_BIND_SERVICE=p+e *gtk2
         *)

Final parameter is the name of the program just compiled, which in my case has widget set etc. appended.

(*
         *)
(*      Note that capabilities are stored as extended attributes, which
DO NOT  *)
(*      normally accompany a file if it is subsequently copied.
         *)
(*
         *)
(*  *   If linked with Qt, the program may be run setuid root:
         *)
(*
         *)
(*              # chown root:root *qt
         *)
(*              # chmod u+s *qt
         *)
(*              # chmod g+s *qt
         *)
(*
         *)
(*      or have extra capabilities as above.
         *)
(*
         *)
(*  *   In any case, the program may be started by the superuser (i.e.
run as   *)
(*      root).
         *)

..in which case it does the usual unix thing of grabbing whatever resources it needs, then switching to a safer UID so that if somebody finds a way of forcing it to shell out it doesn't give them unrestricted access to the system.

(*
         *)
(* After the ports have been bound, the CAP_NET_BIND_SERVICE effective
and      *)
(* permitted capabilities are relinquished. If the program is running
setuid    *)
(* root, then it reverts to the actual user; if it is running as root it
        *)
(* assumes group and user IDs as given in the configuration file, or as
given   *)
(* by the ownership of the executable, or ID 65534 as ultimate fallback
         *)
(* ("nobody" in recent Debian releases).                        MarkMLl.
        *)
Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]