Whamcloud - gitweb
LU-14475 log: Rewrite some log messages
[fs/lustre-release.git] / lustre / tests / euid_access.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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 version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2020, Whamcloud.
24  */
25 /*
26  * This file is part of Lustre, http://www.lustre.org/
27  */
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <errno.h>
32 #include <pwd.h>
33 #include <grp.h>
34 #include <fcntl.h>
35
36 void print_groups(int num_groups, gid_t *groups)
37 {
38         int i;
39
40         fprintf(stdout, "\tGroups ");
41         for (i = 0; i < num_groups; i++) {
42                 struct group *gr = getgrgid(groups[i]);
43
44                 if (gr == NULL)
45                         perror("getgrgid");
46                 fprintf(stdout, "%6d - %s, ", gr->gr_gid, gr->gr_name);
47         }
48         fprintf(stdout, "\n");
49 }
50
51 char usage[] =
52 "Usage: %s <user to switch euid to> <path to file to access>\n";
53
54 int main(int argc, char **argv)
55 {
56         char *user_to_euid;
57         char *filename;
58         struct passwd *user_pwd;
59         char *user_name;
60         int num_groups = 0;
61         gid_t *groups;
62         struct passwd *switch_pwd;
63         uid_t switch_uid, switch_gid;
64         int switch_num_groups = 0;
65         gid_t *switch_groups;
66         int final_num_groups = 0;
67         gid_t *final_groups;
68         int fd = 0;
69         int save_errno;
70         int rc;
71
72         if (argc != 3) {
73                 fprintf(stderr, usage, argv[0]);
74                 exit(1);
75         }
76
77         user_to_euid = argv[1];
78         filename = argv[2];
79
80         user_pwd = getpwuid(getuid());
81         if (!user_pwd) {
82                 if (errno) {
83                         save_errno = errno;
84                         perror("getpwuid");
85                 } else {
86                         save_errno = 1;
87                         fprintf(stderr, "Cannot find user in passwd db\n");
88                 }
89                 exit(save_errno);
90         }
91         user_name = user_pwd->pw_name;
92
93         fprintf(stdout, "Initially %s ruid:rgid %d:%d, euid:egid %d:%d\n",
94                 user_name, getuid(), getgid(), geteuid(), getegid());
95
96         num_groups = getgroups(0, NULL);
97         if (num_groups) {
98                 groups = malloc(sizeof(gid_t) * num_groups);
99                 if (!groups) {
100                         save_errno = errno;
101                         perror("groups");
102                         exit(save_errno);
103                 }
104                 rc = getgrouplist(user_name, getgid(), groups, &num_groups);
105                 if (rc == -1) {
106                         save_errno = errno;
107                         free(groups);
108                         perror("groups list");
109                         exit(save_errno);
110                 }
111                 print_groups(num_groups, groups);
112                 free(groups);
113         }
114
115         /* lookup information about switch_user provided */
116         switch_pwd = getpwnam(user_to_euid);
117         if (!switch_pwd) {
118                 if (errno) {
119                         save_errno = errno;
120                         perror("getpwnam");
121                 } else {
122                         save_errno = 1;
123                         fprintf(stderr, "Cannot find user %s in passwd db\n",
124                                 user_to_euid);
125                 }
126                 exit(save_errno);
127         }
128         switch_uid = switch_pwd->pw_uid;
129         switch_gid = switch_pwd->pw_gid;
130
131         fprintf(stdout, "To switch to effective %s uid:gid %d:%d\n",
132                 user_to_euid, switch_uid, switch_gid);
133
134         rc = setegid(switch_gid);
135         if (rc == -1) {
136                 save_errno = errno;
137                 perror("setegid");
138                 exit(save_errno);
139         }
140
141         getgrouplist(user_to_euid, switch_gid, NULL, &switch_num_groups);
142         if (switch_num_groups) {
143                 switch_groups = malloc(sizeof(gid_t) * switch_num_groups);
144                 if (!switch_groups) {
145                         save_errno = errno;
146                         perror("switch_groups");
147                         exit(save_errno);
148                 }
149                 rc = getgrouplist(user_to_euid, switch_gid,
150                                   switch_groups, &switch_num_groups);
151                 if (rc == -1) {
152                         save_errno = errno;
153                         free(switch_groups);
154                         perror("switch_groups list");
155                         exit(save_errno);
156                 }
157                 print_groups(switch_num_groups, switch_groups);
158                 rc = setgroups(switch_num_groups, switch_groups);
159                 save_errno = errno;
160                 free(switch_groups);
161                 if (rc == -1) {
162                         perror("setgroups");
163                         exit(save_errno);
164                 }
165         }
166
167         rc = seteuid(switch_uid);
168         if (rc == -1) {
169                 save_errno = errno;
170                 perror("seteuid");
171                 exit(save_errno);
172         }
173
174         fprintf(stdout, "Now %s ruid:rgid %d:%d, euid:egid %d:%d\n",
175                 user_name, getuid(), getgid(), geteuid(), getegid());
176
177         final_num_groups = getgroups(0, NULL);
178         final_groups = malloc(sizeof(gid_t) * final_num_groups);
179         if (!final_groups) {
180                 save_errno = errno;
181                 perror("final_groups");
182                 exit(save_errno);
183         }
184         rc = getgroups(final_num_groups, final_groups);
185         if (rc == -1) {
186                 save_errno = errno;
187                 free(final_groups);
188                 perror("final_groups list");
189                 exit(save_errno);
190         }
191         print_groups(final_num_groups, final_groups);
192         free(final_groups);
193
194         fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, 0666);
195         if (fd == -1) {
196                 save_errno = errno;
197                 perror("open");
198                 exit(save_errno);
199         }
200         rc = write(fd, "test", 5);
201         if (rc == -1) {
202                 save_errno = errno;
203                 perror("write");
204                 exit(save_errno);
205         }
206         close(fd);
207         fprintf(stdout, "File %s successfully written\n", filename);
208
209         exit(0);
210 }
211