Mercurial > repos > david-hoover > local_export_tools
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 } |