Mercurial > repos > david-hoover > local_export_tools
diff cpy.c @ 2:0b424b791e12
Uploaded
author | david-hoover |
---|---|
date | Tue, 28 Feb 2012 12:32:29 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cpy.c Tue Feb 28 12:32:29 2012 -0500 @@ -0,0 +1,392 @@ +#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); +}