comparison cpy.c @ 2:0b424b791e12

Uploaded
author david-hoover
date Tue, 28 Feb 2012 12:32:29 -0500
parents
children
comparison
equal deleted inserted replaced
1:6962544aa394 2:0b424b791e12
1 #include <sys/stat.h>
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <stdio.h>
5 #include <errno.h>
6 #include <stdlib.h>
7 #include <pwd.h>
8 #include <grp.h> // declares struct group
9 #include <libgen.h> // for dirname
10 #include <string.h> // for strcpy
11
12 /* cpy.c David Hoover 1/20/12
13 usage:
14 cpy from.file to.file login
15
16 cpy copies a file from one location to another, and then sets the ownership to a given user. The
17 program is expected to be setuid and owned by root.
18
19 */
20
21 int notWriteable(char *file, char *user)
22 /* Returns 1 if file not writeable by given user */
23 {
24 struct stat fileStat;
25 struct passwd *own,*usr;
26 struct group *grp;
27 int i=0;
28
29 usr = getpwnam(user);
30
31 /* does user exist? */
32 if (! usr)
33 {
34 fprintf(stderr,"%s: No such user\n",user);
35 exit(1);
36 }
37
38 /* must be able to stat file */
39 if (stat(file, &fileStat) < 0)
40 {
41 fprintf(stderr,"%s: No such directory\n",file);
42 exit(1);
43 }
44
45 /* get the owner and group information for the file */
46 own = getpwuid(fileStat.st_uid);
47 grp = getgrgid(fileStat.st_gid);
48
49 /* does the file owner match the argument? */
50 // if (!strcmp(own->pw_name,user))
51 if (usr->pw_uid == fileStat.st_uid)
52 {
53 // printf("owners match!\n");
54
55 /* is file writeable? */
56 if (fileStat.st_mode & S_IWUSR)
57 {
58 // printf("%s is writeable by %s\n",file,user);
59 return 0;
60 }
61 else
62 {
63 // printf("%s is not writeable by %s\n",file,user);
64 }
65 }
66 else {
67 // printf("owners don't match!\n");
68 }
69
70 /* is the file group readable by the given group? */
71 if (fileStat.st_mode & S_IWGRP)
72 {
73 // printf("%s is writeable by group %s\n",file,grp->gr_name);
74
75
76 /* is the user's gid the same as the file? */
77 // printf("%d\n",usr->pw_gid);
78 // printf("%d\n",fileStat.st_gid);
79 if (usr->pw_gid == fileStat.st_gid)
80 {
81 // printf("groups match!\n");
82
83 /* if the path a directory is it executable? */
84 if (S_ISDIR(fileStat.st_mode))
85 {
86 if (fileStat.st_mode & S_IXGRP)
87 {
88 return 0;
89 }
90 }
91 else {
92 return 0;
93 }
94 }
95 else
96 {
97
98 /* is the user a member of the group that owns the file? */
99 while(grp->gr_mem[i] != NULL)
100 {
101 if(!strcmp(grp->gr_mem[i],user))
102 {
103 // printf("%s is a member of the %s group\n",user,grp->gr_name);
104 /* if the path a directory is it executable? */
105 if (S_ISDIR(fileStat.st_mode))
106 {
107 if (fileStat.st_mode & S_IXGRP)
108 {
109 return 0;
110 }
111 }
112 else {
113 return 0;
114 }
115 }
116 i++;
117 }
118
119 // printf("%s is not a member of the %s group\n",user,grp->gr_name);
120
121 }
122 }
123 else
124 {
125 // printf("%s is not writeable by group %s\n",file,grp->gr_name);
126 }
127
128 /* is the e world writeable? */
129 if (fileStat.st_mode & S_IWOTH)
130 {
131 // printf("%s is world writeable\n",file);
132 return 0;
133 }
134 else
135 {
136 // printf("%s is not world writeable\n",file);
137 }
138
139 return 1;
140 }
141
142 int notReadable(char *file, char *user)
143 /* Returns 1 if file not readable by given user */
144 {
145 struct stat fileStat;
146 struct passwd *own,*usr;
147 struct group *grp;
148 int i=0;
149
150 usr = getpwnam(user);
151
152 /* does user exist? */
153 if (! usr)
154 {
155 fprintf(stderr,"%s: No such user\n",user);
156 exit(1);
157 }
158
159 /* must be able to stat file */
160 if (stat(file, &fileStat) < 0)
161 {
162 fprintf(stderr,"%s: No such directory\n",file);
163 exit(1);
164 }
165
166 /* get the owner and group information for the file */
167 own = getpwuid(fileStat.st_uid);
168 grp = getgrgid(fileStat.st_gid);
169
170 /* does the file owner match the argument? */
171 // if (!strcmp(own->pw_name,user))
172 if (usr->pw_uid == fileStat.st_uid)
173 {
174 // printf("owners match!\n");
175
176 /* is file readable? */
177 if (fileStat.st_mode & S_IRUSR)
178 {
179 // printf("%s is readable by %s\n",file,user);
180 return 0;
181 }
182 else
183 {
184 // printf("%s is not readable by %s\n",file,user);
185 }
186 }
187 else {
188 // printf("owners don't match!\n");
189 }
190
191 /* is the file group readable by the given group? */
192 if (fileStat.st_mode & S_IRGRP)
193 {
194 // printf("%s is readable by group %s\n",file,grp->gr_name);
195
196
197 /* is the user's gid the same as the file? */
198 // printf("%d\n",usr->pw_gid);
199 // printf("%d\n",fileStat.st_gid);
200 if (usr->pw_gid == fileStat.st_gid)
201 {
202 // printf("groups match!\n");
203
204 /* if the path a directory is it executable? */
205 if (S_ISDIR(fileStat.st_mode))
206 {
207 if (fileStat.st_mode & S_IXGRP)
208 {
209 return 0;
210 }
211 }
212 else {
213 return 0;
214 }
215 }
216 else
217 {
218
219 /* is the user a member of the group that owns the file? */
220 while(grp->gr_mem[i] != NULL)
221 {
222 if(!strcmp(grp->gr_mem[i],user))
223 {
224 // printf("%s is a member of the %s group\n",user,grp->gr_name);
225 /* if the path a directory is it executable? */
226 if (S_ISDIR(fileStat.st_mode))
227 {
228 if (fileStat.st_mode & S_IXGRP)
229 {
230 return 0;
231 }
232 }
233 else {
234 return 0;
235 }
236 }
237 i++;
238 }
239
240 // printf("%s is not a member of the %s group\n",user,grp->gr_name);
241
242 }
243 }
244 else
245 {
246 // printf("%s is not readable by group %s\n",file,grp->gr_name);
247 }
248
249 /* is the e world readable? */
250 if (fileStat.st_mode & S_IROTH)
251 {
252 // printf("%s is world readable\n",file);
253 return 0;
254 }
255 else
256 {
257 // printf("%s is not world readable\n",file);
258 }
259
260 return 1;
261 }
262
263 int copyFile(char *src, char *dst)
264 {
265 // printf("Copying %s to %s\n",src,dst);
266
267 int c;
268 FILE *fs,*ft;
269 struct stat fileStat;
270
271 /* must be able to stat file */
272 if (stat(src, &fileStat) < 0)
273 {
274 fprintf(stderr,"%s: No such file\n",src);
275 exit(1);
276 }
277
278 /* is path a regular file? */
279 if (S_ISDIR(fileStat.st_mode))
280 {
281 fprintf(stderr,"%s: Is a directory\n",src);
282 exit(1);
283 }
284
285 fs = fopen(src,"r");
286 if (fs==NULL) {
287 fprintf(stderr,"Can't read from file %s!\n",src);
288 exit(1);
289 }
290 ft = fopen(dst,"w");
291 if (ft==NULL) {
292 fprintf(stderr,"Can't write to file %s!\n",dst);
293 exit(1);
294 }
295
296 c = getc(fs);
297 while (c != EOF) {
298 putc(c,ft);
299 c = getc(fs);
300 }
301
302 fclose(fs);
303 fclose(ft);
304
305 return 0;
306
307 }
308
309 int chownToGivenUser(char *file, char *user)
310 /* chown a file to the given user */
311 {
312 struct passwd *usr;
313
314 usr = getpwnam(user);
315
316 // printf("UID = %d\n",usr->pw_uid);
317 // printf("GID = %d\n",usr->pw_gid);
318
319 // printf("chown %s %d,%d\n",file,usr->pw_uid,usr->pw_gid);
320 if (chown(file,usr->pw_uid,usr->pw_gid))
321 {
322 fprintf(stderr,"Can't chown %s\n",file);
323 exit(1);
324 }
325 return 0;
326 }
327
328 int explodePath(char *file, char *user)
329 /* Returns 1 if file not readable by given user */
330 {
331 char **path;
332 char *dir;
333 char newfile[10000];
334 int i;
335
336 strcpy(newfile,file);
337 if (!notReadable(newfile,user))
338 {
339 dir = dirname(newfile);
340 if (strcmp(dir,"/"))
341 explodePath(dir,user);
342 }
343 else
344 {
345 fprintf(stderr,"%s: Permission denied.\n",file);
346 exit(1);
347 }
348
349 return 0;
350 }
351
352 main(int argc, char **argv)
353 {
354 char *dir;
355 char newfile[10000];
356 struct stat fileStat;
357
358 /* must have two arguments */
359 if (argc != 4)
360 {
361 fprintf(stderr,"usage: cpy source dest user\n");
362 exit(1);
363 }
364
365 /* is filepath writeable by given user? */
366 strcpy(newfile,argv[2]);
367 dir = dirname(newfile);
368 if (!notWriteable(dir,argv[3]))
369 {
370
371 /* is filepath readable by given user? */
372 explodePath(dir,argv[3]);
373
374 /* dest file must not exist yet */
375 if (!(stat(argv[2], &fileStat) < 0))
376 {
377 fprintf(stderr,"%s: File already exists.\n",argv[2]);
378 exit(1);
379 }
380
381 /* copy the file and change the owner */
382 copyFile(argv[1],argv[2]);
383 chownToGivenUser(argv[2],argv[3]);
384 }
385 else
386 {
387 fprintf(stderr,"%s: Permission denied.\n",argv[2]);
388 exit(1);
389 }
390
391 exit(0);
392 }