blob: 1d0c3ae68cc6bfca7f4f400f09d825e8e2fd3859 [file] [log] [blame]
Skyler Grey3919fc32023-02-26 13:06:50 +00001#include <unistd.h>
2#include <errno.h>
3#include <stdio.h>
4#include <sys/param.h>
5#include <sys/types.h>
6#include <stdlib.h>
7#include <unistd.h>
8#include <grp.h>
9
10static int orig_ngroups = -1;
11static gid_t orig_gid = -1;
12static uid_t orig_uid = -1;
13static gid_t orig_groups[NGROUPS_MAX];
14
15void spc_drop_privileges(int permanent) {
16 gid_t newgid = getgid( ), oldgid = getegid( );
17 uid_t newuid = getuid( ), olduid = geteuid( );
18
19 if (!permanent) {
20 /* Save information about the privileges that are being dropped so that they
21 * can be restored later.
22 */
23 orig_gid = oldgid;
24 orig_uid = olduid;
25 orig_ngroups = getgroups(NGROUPS_MAX, orig_groups);
26 }
27
28 /* If root privileges are to be dropped, be sure to pare down the ancillary
29 * groups for the process before doing anything else because the setgroups( )
30 * system call requires root privileges. Drop ancillary groups regardless of
31 * whether privileges are being dropped temporarily or permanently.
32 */
33 if (!olduid) setgroups(1, &newgid);
34
35 if (newgid != oldgid) {
36#if !defined(linux)
37 setegid(newgid);
38 if (permanent && setgid(newgid) = = -1) abort( );
39#else
40 if (setregid((permanent ? newgid : -1), newgid) == -1) abort( );
41#endif
42 }
43
44 if (newuid != olduid) {
45#if !defined(linux)
46 seteuid(newuid);
47 if (permanent && setuid(newuid) = = -1) abort( );
48#else
49 if (setreuid((permanent ? newuid : -1), newuid) == -1) abort( );
50#endif
51 }
52
53 /* verify that the changes were successful */
54 if (permanent) {
55 if (newgid != oldgid && (setegid(oldgid) != -1 || getegid( ) != newgid))
56 abort( );
57 if (newuid != olduid && (seteuid(olduid) != -1 || geteuid( ) != newuid))
58 abort( );
59 } else {
60 if (newgid != oldgid && getegid( ) != newgid) abort( );
61 if (newuid != olduid && geteuid( ) != newuid) abort( );
62 }
63}
64
65void spc_restore_privileges(void) {
66 if (geteuid( ) != orig_uid)
67 if (seteuid(orig_uid) == -1 || geteuid( ) != orig_uid) abort( );
68 if (getegid( ) != orig_gid)
69 if (setegid(orig_gid) == -1 || getegid( ) != orig_gid) abort( );
70 if (!orig_uid)
71 setgroups(orig_ngroups, orig_groups);
72}
73
74int main(int argc, char *argv[])
75{
76 freopen("/run/secrets/keepassPassword", "r", stdin);
77 spc_drop_privileges(1);
78 system("keepassxc --pw-stdin ~/Sync/KeePass\\ Vaults/Passwords.kdbx");
79}
80