Mercurial > repos > david-hoover > local_export_tools
view cpy.c @ 2:0b424b791e12
Uploaded
author | david-hoover |
---|---|
date | Tue, 28 Feb 2012 12:32:29 -0500 |
parents | |
children |
line wrap: on
line source
#include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <pwd.h> #include <grp.h> // declares struct group #include <libgen.h> // for dirname #include <string.h> // for strcpy /* cpy.c David Hoover 1/20/12 usage: cpy from.file to.file login cpy copies a file from one location to another, and then sets the ownership to a given user. The program is expected to be setuid and owned by root. */ int notWriteable(char *file, char *user) /* Returns 1 if file not writeable by given user */ { struct stat fileStat; struct passwd *own,*usr; struct group *grp; int i=0; usr = getpwnam(user); /* does user exist? */ if (! usr) { fprintf(stderr,"%s: No such user\n",user); exit(1); } /* must be able to stat file */ if (stat(file, &fileStat) < 0) { fprintf(stderr,"%s: No such directory\n",file); exit(1); } /* get the owner and group information for the file */ own = getpwuid(fileStat.st_uid); grp = getgrgid(fileStat.st_gid); /* does the file owner match the argument? */ // if (!strcmp(own->pw_name,user)) if (usr->pw_uid == fileStat.st_uid) { // printf("owners match!\n"); /* is file writeable? */ if (fileStat.st_mode & S_IWUSR) { // printf("%s is writeable by %s\n",file,user); return 0; } else { // printf("%s is not writeable by %s\n",file,user); } } else { // printf("owners don't match!\n"); } /* is the file group readable by the given group? */ if (fileStat.st_mode & S_IWGRP) { // printf("%s is writeable by group %s\n",file,grp->gr_name); /* is the user's gid the same as the file? */ // printf("%d\n",usr->pw_gid); // printf("%d\n",fileStat.st_gid); if (usr->pw_gid == fileStat.st_gid) { // printf("groups match!\n"); /* if the path a directory is it executable? */ if (S_ISDIR(fileStat.st_mode)) { if (fileStat.st_mode & S_IXGRP) { return 0; } } else { return 0; } } else { /* is the user a member of the group that owns the file? */ while(grp->gr_mem[i] != NULL) { if(!strcmp(grp->gr_mem[i],user)) { // printf("%s is a member of the %s group\n",user,grp->gr_name); /* if the path a directory is it executable? */ if (S_ISDIR(fileStat.st_mode)) { if (fileStat.st_mode & S_IXGRP) { return 0; } } else { return 0; } } i++; } // printf("%s is not a member of the %s group\n",user,grp->gr_name); } } else { // printf("%s is not writeable by group %s\n",file,grp->gr_name); } /* is the e world writeable? */ if (fileStat.st_mode & S_IWOTH) { // printf("%s is world writeable\n",file); return 0; } else { // printf("%s is not world writeable\n",file); } return 1; } int notReadable(char *file, char *user) /* Returns 1 if file not readable by given user */ { struct stat fileStat; struct passwd *own,*usr; struct group *grp; int i=0; usr = getpwnam(user); /* does user exist? */ if (! usr) { fprintf(stderr,"%s: No such user\n",user); exit(1); } /* must be able to stat file */ if (stat(file, &fileStat) < 0) { fprintf(stderr,"%s: No such directory\n",file); exit(1); } /* get the owner and group information for the file */ own = getpwuid(fileStat.st_uid); grp = getgrgid(fileStat.st_gid); /* does the file owner match the argument? */ // if (!strcmp(own->pw_name,user)) if (usr->pw_uid == fileStat.st_uid) { // printf("owners match!\n"); /* is file readable? */ if (fileStat.st_mode & S_IRUSR) { // printf("%s is readable by %s\n",file,user); return 0; } else { // printf("%s is not readable by %s\n",file,user); } } else { // printf("owners don't match!\n"); } /* is the file group readable by the given group? */ if (fileStat.st_mode & S_IRGRP) { // printf("%s is readable by group %s\n",file,grp->gr_name); /* is the user's gid the same as the file? */ // printf("%d\n",usr->pw_gid); // printf("%d\n",fileStat.st_gid); if (usr->pw_gid == fileStat.st_gid) { // printf("groups match!\n"); /* if the path a directory is it executable? */ if (S_ISDIR(fileStat.st_mode)) { if (fileStat.st_mode & S_IXGRP) { return 0; } } else { return 0; } } else { /* is the user a member of the group that owns the file? */ while(grp->gr_mem[i] != NULL) { if(!strcmp(grp->gr_mem[i],user)) { // printf("%s is a member of the %s group\n",user,grp->gr_name); /* if the path a directory is it executable? */ if (S_ISDIR(fileStat.st_mode)) { if (fileStat.st_mode & S_IXGRP) { return 0; } } else { return 0; } } i++; } // printf("%s is not a member of the %s group\n",user,grp->gr_name); } } else { // printf("%s is not readable by group %s\n",file,grp->gr_name); } /* is the e world readable? */ if (fileStat.st_mode & S_IROTH) { // printf("%s is world readable\n",file); return 0; } else { // printf("%s is not world readable\n",file); } return 1; } int copyFile(char *src, char *dst) { // printf("Copying %s to %s\n",src,dst); int c; FILE *fs,*ft; struct stat fileStat; /* must be able to stat file */ if (stat(src, &fileStat) < 0) { fprintf(stderr,"%s: No such file\n",src); exit(1); } /* is path a regular file? */ if (S_ISDIR(fileStat.st_mode)) { fprintf(stderr,"%s: Is a directory\n",src); exit(1); } fs = fopen(src,"r"); if (fs==NULL) { fprintf(stderr,"Can't read from file %s!\n",src); exit(1); } ft = fopen(dst,"w"); if (ft==NULL) { fprintf(stderr,"Can't write to file %s!\n",dst); exit(1); } c = getc(fs); while (c != EOF) { putc(c,ft); c = getc(fs); } fclose(fs); fclose(ft); return 0; } int chownToGivenUser(char *file, char *user) /* chown a file to the given user */ { struct passwd *usr; usr = getpwnam(user); // printf("UID = %d\n",usr->pw_uid); // printf("GID = %d\n",usr->pw_gid); // printf("chown %s %d,%d\n",file,usr->pw_uid,usr->pw_gid); if (chown(file,usr->pw_uid,usr->pw_gid)) { fprintf(stderr,"Can't chown %s\n",file); exit(1); } return 0; } int explodePath(char *file, char *user) /* Returns 1 if file not readable by given user */ { char **path; char *dir; char newfile[10000]; int i; strcpy(newfile,file); if (!notReadable(newfile,user)) { dir = dirname(newfile); if (strcmp(dir,"/")) explodePath(dir,user); } else { fprintf(stderr,"%s: Permission denied.\n",file); exit(1); } return 0; } main(int argc, char **argv) { char *dir; char newfile[10000]; struct stat fileStat; /* must have two arguments */ if (argc != 4) { fprintf(stderr,"usage: cpy source dest user\n"); exit(1); } /* is filepath writeable by given user? */ strcpy(newfile,argv[2]); dir = dirname(newfile); if (!notWriteable(dir,argv[3])) { /* is filepath readable by given user? */ explodePath(dir,argv[3]); /* dest file must not exist yet */ if (!(stat(argv[2], &fileStat) < 0)) { fprintf(stderr,"%s: File already exists.\n",argv[2]); exit(1); } /* copy the file and change the owner */ copyFile(argv[1],argv[2]); chownToGivenUser(argv[2],argv[3]); } else { fprintf(stderr,"%s: Permission denied.\n",argv[2]); exit(1); } exit(0); }