diff options
author | 2018-04-09 19:13:33 -0500 | |
---|---|---|
committer | 2018-04-09 19:13:33 -0500 | |
commit | de1a38978be7a7ba01b8d7b2d0efa3337b818731 (patch) | |
tree | 3727a6551d0c0f68fcd8b7eca6b6c46f250f8a3c /src | |
parent | Spotify requires /etc/group when alsa is audio provider (diff) | |
parent | Merge pull request #1875 from glitsj16/sqlitebrowser (diff) | |
download | firejail-de1a38978be7a7ba01b8d7b2d0efa3337b818731.tar.gz firejail-de1a38978be7a7ba01b8d7b2d0efa3337b818731.tar.zst firejail-de1a38978be7a7ba01b8d7b2d0efa3337b818731.zip |
Merge branch 'master' of https://github.com/netblue30/firejail
Diffstat (limited to 'src')
-rw-r--r-- | src/firecfg/firecfg.config | 2 | ||||
-rw-r--r-- | src/firecfg/main.c | 2 | ||||
-rw-r--r-- | src/firejail/firejail.h | 1 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 10 | ||||
-rw-r--r-- | src/firejail/seccomp.c | 10 | ||||
-rw-r--r-- | src/firejail/util.c | 85 | ||||
-rw-r--r-- | src/man/firecfg.txt | 23 | ||||
-rw-r--r-- | src/man/firejail-login.txt | 3 | ||||
-rw-r--r-- | src/man/firejail-profile.txt | 3 | ||||
-rw-r--r-- | src/man/firejail-users.txt | 45 | ||||
-rw-r--r-- | src/man/firejail.txt | 3 | ||||
-rw-r--r-- | src/man/firemon.txt | 1 | ||||
-rw-r--r-- | src/tools/testuid.c | 49 |
13 files changed, 200 insertions, 37 deletions
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config index f8e0f3bc7..e34ac786c 100644 --- a/src/firecfg/firecfg.config +++ b/src/firecfg/firecfg.config | |||
@@ -431,6 +431,8 @@ xonotic-glx | |||
431 | xonotic-sdl | 431 | xonotic-sdl |
432 | xpdf | 432 | xpdf |
433 | xplayer | 433 | xplayer |
434 | xplayer-audio-preview | ||
435 | xplayer-video-thumbnailer | ||
434 | xpra | 436 | xpra |
435 | xreader | 437 | xreader |
436 | xreader-previewer | 438 | xreader-previewer |
diff --git a/src/firecfg/main.c b/src/firecfg/main.c index a54607aec..b79053d3e 100644 --- a/src/firecfg/main.c +++ b/src/firecfg/main.c | |||
@@ -30,7 +30,7 @@ static char *usage_str = | |||
30 | "The symbolic links are placed in /usr/local/bin. For more information, see\n" | 30 | "The symbolic links are placed in /usr/local/bin. For more information, see\n" |
31 | "DESKTOP INTEGRATION section in man 1 firejail.\n\n" | 31 | "DESKTOP INTEGRATION section in man 1 firejail.\n\n" |
32 | "Usage: firecfg [OPTIONS]\n\n" | 32 | "Usage: firecfg [OPTIONS]\n\n" |
33 | " --add-users user [user] - add the users to Firejail access database\n" | 33 | " --add-users user [user] - add the users to Firejail user access database.\n\n" |
34 | " --clean - remove all firejail symbolic links.\n\n" | 34 | " --clean - remove all firejail symbolic links.\n\n" |
35 | " --debug - print debug messages.\n\n" | 35 | " --debug - print debug messages.\n\n" |
36 | " --fix - fix .desktop files.\n\n" | 36 | " --fix - fix .desktop files.\n\n" |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index d6c39260b..4fd11ab4f 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -778,6 +778,7 @@ void build_appimage_cmdline(char **command_line, char **window_title, int argc, | |||
778 | #define PATH_FIREJAIL (PREFIX "/bin/firejail") | 778 | #define PATH_FIREJAIL (PREFIX "/bin/firejail") |
779 | #define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp") | 779 | #define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp") |
780 | #define PATH_FSEC_PRINT (LIBDIR "/firejail/fsec-print") | 780 | #define PATH_FSEC_PRINT (LIBDIR "/firejail/fsec-print") |
781 | #define PATH_FSEC_OPTIMIZE (LIBDIR "/firejail/fsec-optimize") | ||
781 | #define PATH_FCOPY (LIBDIR "/firejail/fcopy") | 782 | #define PATH_FCOPY (LIBDIR "/firejail/fcopy") |
782 | #define SBOX_STDIN_FILE "/run/firejail/mnt/sbox_stdin" | 783 | #define SBOX_STDIN_FILE "/run/firejail/mnt/sbox_stdin" |
783 | #define PATH_FLDD (LIBDIR "/firejail/fldd") | 784 | #define PATH_FLDD (LIBDIR "/firejail/fldd") |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 1e60b6477..709ce96b6 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -1022,19 +1022,17 @@ int sandbox(void* sandbox_arg) { | |||
1022 | #endif | 1022 | #endif |
1023 | 1023 | ||
1024 | //**************************************** | 1024 | //**************************************** |
1025 | // drop privileges or create a new user namespace | 1025 | // create a new user namespace |
1026 | // - too early to drop privileges | ||
1026 | //**************************************** | 1027 | //**************************************** |
1027 | save_nogroups(); | 1028 | save_nogroups(); |
1028 | if (arg_noroot) { | 1029 | if (arg_noroot) { |
1029 | int rv = unshare(CLONE_NEWUSER); | 1030 | int rv = unshare(CLONE_NEWUSER); |
1030 | if (rv == -1) { | 1031 | if (rv == -1) { |
1031 | fwarning("cannot create a new user namespace, going forward without it...\n"); | 1032 | fwarning("cannot create a new user namespace, going forward without it...\n"); |
1032 | drop_privs(arg_nogroups); | ||
1033 | arg_noroot = 0; | 1033 | arg_noroot = 0; |
1034 | } | 1034 | } |
1035 | } | 1035 | } |
1036 | else | ||
1037 | drop_privs(arg_nogroups); | ||
1038 | 1036 | ||
1039 | // notify parent that new user namespace has been created so a proper | 1037 | // notify parent that new user namespace has been created so a proper |
1040 | // UID/GID map can be setup | 1038 | // UID/GID map can be setup |
@@ -1066,8 +1064,9 @@ int sandbox(void* sandbox_arg) { | |||
1066 | } | 1064 | } |
1067 | 1065 | ||
1068 | //**************************************** | 1066 | //**************************************** |
1069 | // fork the application and monitor it | 1067 | // drop privileges, fork the application and monitor it |
1070 | //**************************************** | 1068 | //**************************************** |
1069 | drop_privs(arg_nogroups); | ||
1071 | pid_t app_pid = fork(); | 1070 | pid_t app_pid = fork(); |
1072 | if (app_pid == -1) | 1071 | if (app_pid == -1) |
1073 | errExit("fork"); | 1072 | errExit("fork"); |
@@ -1085,6 +1084,7 @@ int sandbox(void* sandbox_arg) { | |||
1085 | printf("AppArmor enabled\n"); | 1084 | printf("AppArmor enabled\n"); |
1086 | } | 1085 | } |
1087 | #endif | 1086 | #endif |
1087 | |||
1088 | prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died | 1088 | prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died |
1089 | start_application(0); // start app | 1089 | start_application(0); // start app |
1090 | } | 1090 | } |
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c index 0184db65c..1ee6256d4 100644 --- a/src/firejail/seccomp.c +++ b/src/firejail/seccomp.c | |||
@@ -210,6 +210,11 @@ int seccomp_filter_drop(void) { | |||
210 | PATH_FSECCOMP, "default", "drop", RUN_SECCOMP_CFG, RUN_SECCOMP_POSTEXEC, cfg.seccomp_list); | 210 | PATH_FSECCOMP, "default", "drop", RUN_SECCOMP_CFG, RUN_SECCOMP_POSTEXEC, cfg.seccomp_list); |
211 | if (rv) | 211 | if (rv) |
212 | exit(rv); | 212 | exit(rv); |
213 | |||
214 | // optimize the new filter | ||
215 | rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSEC_OPTIMIZE, RUN_SECCOMP_CFG); | ||
216 | if (rv) | ||
217 | exit(rv); | ||
213 | } | 218 | } |
214 | } | 219 | } |
215 | 220 | ||
@@ -232,6 +237,11 @@ int seccomp_filter_drop(void) { | |||
232 | 237 | ||
233 | if (rv) | 238 | if (rv) |
234 | exit(rv); | 239 | exit(rv); |
240 | |||
241 | // optimize the drop filter | ||
242 | rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSEC_OPTIMIZE, RUN_SECCOMP_CFG); | ||
243 | if (rv) | ||
244 | exit(rv); | ||
235 | } | 245 | } |
236 | 246 | ||
237 | // load the filter | 247 | // load the filter |
diff --git a/src/firejail/util.c b/src/firejail/util.c index c644f83a8..14e9f6440 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -32,6 +32,61 @@ | |||
32 | #include <sys/wait.h> | 32 | #include <sys/wait.h> |
33 | 33 | ||
34 | #define MAX_GROUPS 1024 | 34 | #define MAX_GROUPS 1024 |
35 | |||
36 | static void clean_supplementary_groups(gid_t gid) { | ||
37 | assert(cfg.username); | ||
38 | gid_t groups[MAX_GROUPS]; | ||
39 | int ngroups = MAX_GROUPS; | ||
40 | |||
41 | int rv = getgrouplist(cfg.username, gid, groups, &ngroups); | ||
42 | if (rv == -1) | ||
43 | goto clean_all; | ||
44 | |||
45 | // clean supplementary group list | ||
46 | // allow only tty, audio, video, games | ||
47 | gid_t new_groups[MAX_GROUPS]; | ||
48 | int new_ngroups = 0; | ||
49 | char *allowed[] = { | ||
50 | "tty", | ||
51 | "audio", | ||
52 | "video", | ||
53 | "games", | ||
54 | NULL | ||
55 | }; | ||
56 | |||
57 | int i = 0; | ||
58 | while (allowed[i]) { | ||
59 | gid_t g = get_group_id(allowed[i]); | ||
60 | if (g) { | ||
61 | int j; | ||
62 | for (j = 0; j < ngroups; j++) { | ||
63 | if (g == groups[j]) { | ||
64 | new_groups[new_ngroups] = g; | ||
65 | new_ngroups++; | ||
66 | break; | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | i++; | ||
71 | } | ||
72 | |||
73 | if (new_ngroups) { | ||
74 | rv = setgroups(new_ngroups, new_groups); | ||
75 | if (rv) | ||
76 | goto clean_all; | ||
77 | } | ||
78 | else | ||
79 | goto clean_all; | ||
80 | |||
81 | return; | ||
82 | |||
83 | clean_all: | ||
84 | fwarning("cleaning all supplementary groups\n"); | ||
85 | if (setgroups(0, NULL) < 0) | ||
86 | errExit("setgroups"); | ||
87 | } | ||
88 | |||
89 | |||
35 | // drop privileges | 90 | // drop privileges |
36 | // - for root group or if nogroups is set, supplementary groups are not configured | 91 | // - for root group or if nogroups is set, supplementary groups are not configured |
37 | void drop_privs(int nogroups) { | 92 | void drop_privs(int nogroups) { |
@@ -45,34 +100,8 @@ void drop_privs(int nogroups) { | |||
45 | if (arg_debug) | 100 | if (arg_debug) |
46 | printf("Username %s, no supplementary groups\n", cfg.username); | 101 | printf("Username %s, no supplementary groups\n", cfg.username); |
47 | } | 102 | } |
48 | else { | 103 | else if (arg_noroot) |
49 | assert(cfg.username); | 104 | clean_supplementary_groups(gid); |
50 | gid_t groups[MAX_GROUPS]; | ||
51 | int ngroups = MAX_GROUPS; | ||
52 | int rv = getgrouplist(cfg.username, gid, groups, &ngroups); | ||
53 | |||
54 | if (arg_debug && rv) { | ||
55 | printf("Username %s, groups ", cfg.username); | ||
56 | int i; | ||
57 | for (i = 0; i < ngroups; i++) | ||
58 | printf("%u, ", groups[i]); | ||
59 | printf("\n"); | ||
60 | } | ||
61 | |||
62 | if (rv == -1) { | ||
63 | fwarning("cannot extract supplementary group list, dropping them\n"); | ||
64 | if (setgroups(0, NULL) < 0) | ||
65 | errExit("setgroups"); | ||
66 | } | ||
67 | else { | ||
68 | rv = setgroups(ngroups, groups); | ||
69 | if (rv) { | ||
70 | fwarning("cannot set supplementary group list, dropping them\n"); | ||
71 | if (setgroups(0, NULL) < 0) | ||
72 | errExit("setgroups"); | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | 105 | ||
77 | // set uid/gid | 106 | // set uid/gid |
78 | if (setgid(getgid()) < 0) | 107 | if (setgid(getgid()) < 0) |
diff --git a/src/man/firecfg.txt b/src/man/firecfg.txt index e7a7ef6d9..80cb201d9 100644 --- a/src/man/firecfg.txt +++ b/src/man/firecfg.txt | |||
@@ -30,9 +30,31 @@ installing new programs. If the program is supported by Firejail, the symbolic l | |||
30 | will be created. For a full list of programs supported by default run "cat /usr/lib/firejail/firecfg.config". | 30 | will be created. For a full list of programs supported by default run "cat /usr/lib/firejail/firecfg.config". |
31 | 31 | ||
32 | For user-driven manual integration, see \fBDESKTOP INTEGRATION\fR section in \fBman 1 firejail\fR. | 32 | For user-driven manual integration, see \fBDESKTOP INTEGRATION\fR section in \fBman 1 firejail\fR. |
33 | .SH DEFAULT ACTIONS | ||
34 | The following actions are implemented by default by running sudo firecfg: | ||
35 | |||
36 | .RS | ||
37 | - set or update the symbolic links for desktop integration; | ||
38 | .br | ||
39 | |||
40 | .br | ||
41 | - add the current user to Firejail user access database (firecfg --add-users); | ||
42 | .br | ||
43 | |||
44 | .br | ||
45 | -fix desktop files in $HOME/.local/share/applications/ (firecfg --fix). | ||
46 | .RE | ||
33 | 47 | ||
34 | .SH OPTIONS | 48 | .SH OPTIONS |
35 | .TP | 49 | .TP |
50 | \fB\-\-add-users user [user] | ||
51 | Add the list of users to Firejail user access database. | ||
52 | |||
53 | Example: | ||
54 | .br | ||
55 | $ sudo firecfg --add-users dustin lucas mike eleven | ||
56 | |||
57 | .TP | ||
36 | \fB\-\-clean | 58 | \fB\-\-clean |
37 | Remove all firejail symbolic links. | 59 | Remove all firejail symbolic links. |
38 | 60 | ||
@@ -102,3 +124,4 @@ Homepage: https://firejail.wordpress.com | |||
102 | \&\flfiremon\fR\|(1), | 124 | \&\flfiremon\fR\|(1), |
103 | \&\flfirejail-profile\fR\|(5), | 125 | \&\flfirejail-profile\fR\|(5), |
104 | \&\flfirejail-login\fR\|(5) | 126 | \&\flfirejail-login\fR\|(5) |
127 | \&\flfirejail-users\fR\|(5) | ||
diff --git a/src/man/firejail-login.txt b/src/man/firejail-login.txt index 29030ba45..c2fa63dc4 100644 --- a/src/man/firejail-login.txt +++ b/src/man/firejail-login.txt | |||
@@ -1,4 +1,4 @@ | |||
1 | .TH FIREJAIL-LOGIN 5 "MONTH YEAR" "VERSION" "firejail login.users man page" | 1 | .TH FIREJAIL-LOGIN 5 "MONTH YEAR" "VERSION" "login.users man page" |
2 | .SH NAME | 2 | .SH NAME |
3 | login.users \- Login file syntax for Firejail | 3 | login.users \- Login file syntax for Firejail |
4 | 4 | ||
@@ -38,3 +38,4 @@ Homepage: https://firejail.wordpress.com | |||
38 | \&\flfiremon\fR\|(1), | 38 | \&\flfiremon\fR\|(1), |
39 | \&\flfirecfg\fR\|(1), | 39 | \&\flfirecfg\fR\|(1), |
40 | \&\flfirejail-profile\fR\|(5) | 40 | \&\flfirejail-profile\fR\|(5) |
41 | \&\flfirejail-users\fR\|(5) | ||
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index 4b6e9766f..b529f63e3 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt | |||
@@ -232,7 +232,7 @@ All modifications are discarded when the sandbox is closed. | |||
232 | .TP | 232 | .TP |
233 | \fBprivate-lib file,directory | 233 | \fBprivate-lib file,directory |
234 | Build a new /lib directory and bring in the libraries required by the application to run. | 234 | Build a new /lib directory and bring in the libraries required by the application to run. |
235 | This feature is still under development, see man 1 firejail for some examples. | 235 | This feature is still under development, see \fBman 1 firejail\fR for some examples. |
236 | .TP | 236 | .TP |
237 | \fBprivate-opt file,directory | 237 | \fBprivate-opt file,directory |
238 | Build a new /optin a temporary | 238 | Build a new /optin a temporary |
@@ -610,3 +610,4 @@ Homepage: https://firejail.wordpress.com | |||
610 | \&\flfiremon\fR\|(1), | 610 | \&\flfiremon\fR\|(1), |
611 | \&\flfirecfg\fR\|(1), | 611 | \&\flfirecfg\fR\|(1), |
612 | \&\flfirejail-login\fR\|(5) | 612 | \&\flfirejail-login\fR\|(5) |
613 | \&\flfirejail-users\fR\|(5) | ||
diff --git a/src/man/firejail-users.txt b/src/man/firejail-users.txt new file mode 100644 index 000000000..fcc0f914b --- /dev/null +++ b/src/man/firejail-users.txt | |||
@@ -0,0 +1,45 @@ | |||
1 | .TH FIREJAIL-USERS 5 "MONTH YEAR" "VERSION" "firejail.users man page" | ||
2 | .SH NAME | ||
3 | firejail.users \- Firejail user access database | ||
4 | |||
5 | .SH DESCRIPTION | ||
6 | /etc/firejail/firejail.users lists the users allowed to run firejail SUID executable. | ||
7 | If the file is not present in the system, all users are allowed to use the sandbox. | ||
8 | root user is allowed by default. | ||
9 | |||
10 | Example: | ||
11 | |||
12 | $ cat /etc/firejail/firejail.users | ||
13 | .br | ||
14 | dustin | ||
15 | .br | ||
16 | lucas | ||
17 | .br | ||
18 | mike | ||
19 | .br | ||
20 | eleven | ||
21 | |||
22 | Use a text editor to add or remove users from the list. You can also use firecfg \-\-add-users | ||
23 | command. Example: | ||
24 | |||
25 | $ sudo firecfg --add-users dustin lucas mike eleven | ||
26 | |||
27 | By default, running firecfg creates the file and adds the current user to the list. Example: | ||
28 | |||
29 | $ sudo firecfg | ||
30 | |||
31 | See \fBman 1 firecfg\fR for details. | ||
32 | |||
33 | .SH FILES | ||
34 | /etc/firejail/firejail.users | ||
35 | |||
36 | .SH LICENSE | ||
37 | Firejail is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. | ||
38 | .PP | ||
39 | Homepage: https://firejail.wordpress.com | ||
40 | .SH SEE ALSO | ||
41 | \&\flfirejail\fR\|(1), | ||
42 | \&\flfiremon\fR\|(1), | ||
43 | \&\flfirecfg\fR\|(1), | ||
44 | \&\flfirejail-profile\fR\|(5) | ||
45 | \&\flfirejail-login\fR\|(5) | ||
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index e55d01253..6e8e4eb2c 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -2691,7 +2691,7 @@ Child process initialized | |||
2691 | [...] | 2691 | [...] |
2692 | .RE | 2692 | .RE |
2693 | 2693 | ||
2694 | See man 5 firejail-profile for profile file syntax information. | 2694 | See \fBman 5 firejail-profile\fR for profile file syntax information. |
2695 | 2695 | ||
2696 | .SH RESTRICTED SHELL | 2696 | .SH RESTRICTED SHELL |
2697 | To configure a restricted shell, replace /bin/bash with /usr/bin/firejail in | 2697 | To configure a restricted shell, replace /bin/bash with /usr/bin/firejail in |
@@ -2739,3 +2739,4 @@ Homepage: https://firejail.wordpress.com | |||
2739 | \&\flfirecfg\fR\|(1), | 2739 | \&\flfirecfg\fR\|(1), |
2740 | \&\flfirejail-profile\fR\|(5), | 2740 | \&\flfirejail-profile\fR\|(5), |
2741 | \&\flfirejail-login\fR\|(5) | 2741 | \&\flfirejail-login\fR\|(5) |
2742 | \&\flfirejail-users\fR\|(5) | ||
diff --git a/src/man/firemon.txt b/src/man/firemon.txt index 91c59af4d..9cae72b54 100644 --- a/src/man/firemon.txt +++ b/src/man/firemon.txt | |||
@@ -111,3 +111,4 @@ Homepage: http://firejail.wordpress.com | |||
111 | \&\flfirecfg\fR\|(1), | 111 | \&\flfirecfg\fR\|(1), |
112 | \&\flfirejail-profile\fR\|(5), | 112 | \&\flfirejail-profile\fR\|(5), |
113 | \&\flfirejail-login\fR\|(5) | 113 | \&\flfirejail-login\fR\|(5) |
114 | \&\flfirejail-users\fR\|(5) | ||
diff --git a/src/tools/testuid.c b/src/tools/testuid.c new file mode 100644 index 000000000..633b9773e --- /dev/null +++ b/src/tools/testuid.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2018 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | // compile: gcc -o testuid testuid.c | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <string.h> | ||
26 | #include <unistd.h> | ||
27 | #include <sys/types.h> | ||
28 | |||
29 | |||
30 | static void print_status(void) { | ||
31 | FILE *fp = fopen("/proc/self/status", "r"); | ||
32 | if (!fp) { | ||
33 | fprintf(stderr, "Error, cannot open staus file\n"); | ||
34 | exit(1); | ||
35 | } | ||
36 | |||
37 | char buf[4096]; | ||
38 | while (fgets(buf, 4096, fp)) { | ||
39 | if (strncmp(buf, "Uid", 3) == 0 || strncmp(buf, "Gid", 3) == 0) | ||
40 | printf("%s", buf); | ||
41 | } | ||
42 | |||
43 | fclose(fp); | ||
44 | } | ||
45 | |||
46 | int main(void) { | ||
47 | print_status(); | ||
48 | return 0; | ||
49 | } | ||