Mercurial > repos > david-hoover > local_file_tools
changeset 0:c772c8912663
Uploaded
author | david-hoover |
---|---|
date | Tue, 28 Feb 2012 12:36:45 -0500 |
parents | |
children | c583eb302c7a |
files | README cpx.c cpy.c export_local_file.sh export_local_file.xml import_local_file.sh import_local_file.xml |
diffstat | 7 files changed, 825 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Tue Feb 28 12:36:45 2012 -0500 @@ -0,0 +1,16 @@ +cpx and cpy will need to be compiled, + + gcc -o cpx cpx.c + +made setuid root, accessible only to the galaxy user, + + chown root.[galaxygroup] cpx + chmod 4770 cpx + +put somewhere that your galaxy user can find it, + + mv cpx /usr/local/galaxy/bin + +and added to your galaxy user PATH. + + export PATH=/usr/local/galaxy/bin:$PATH
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cpx.c Tue Feb 28 12:36:45 2012 -0500 @@ -0,0 +1,251 @@ +#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 + +/* cpx.c David Hoover 1/13/11 +usage: + cpx from.file to.file login + +cpx copies a file from one location to another, but only if the original file is owned by the given login. The +program is expected to be setuid and owned by root. + +*/ + +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 file\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 chownToUser(char *file) +/* chown a file to the user running cpx */ +{ + uid_t uid; + gid_t gid; + + uid = getuid(); + gid = getgid(); + +// printf("UID = %d\n",uid); +// printf("GID = %d\n",gid); + +// printf("chown %s %d,%d\n",file,uid,gid); + if (chown(file,uid,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) +{ + +/* must have two arguments */ + if (argc != 4) + { + fprintf(stderr,"usage: cpx source dest user\n"); + exit(1); + } + +/* is file readable by given user? */ + explodePath(argv[1],argv[3]); + +/* copy the file and change the owner */ + copyFile(argv[1],argv[2]); + chownToUser(argv[2]); + + exit(0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cpy.c Tue Feb 28 12:36:45 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); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/export_local_file.sh Tue Feb 28 12:36:45 2012 -0500 @@ -0,0 +1,43 @@ +### +### The shell script: export_local_file.sh +### +### The script basically copies a Galaxy dataset (param 1, dataset_NNNNN.dat) +### to the destination file (param 2, {/data,/home}/filename +### +#!/bin/sh + +INPUT="$1" +DEST="$2" +EMAIL="$3" +OUTPUT="$4" +USER=`echo $EMAIL | sed -e 's#@.*##'` + +if [ -z "$DEST" ]; then + echo "Usage: $0 [INPUT] [DEST]" >&2 + exit 1 +fi + +# Filter any unwanted directories + +if [[ `echo $DEST | grep -c ^/data/` -lt 1 ]] && [[ `echo $DEST | grep -c ^/home/` -lt 1 ]] ; then + echo "Error: \"$DEST\" is not allowed" >&2 + exit 1 +fi + +# Do the deed + +cpy $INPUT $DEST "$USER" +dataset=`basename $INPUT` +if [ $? != 0 ]; then + echo "Error: $USER failed to copy dataset $dataset to \"$DEST\"" >&2 + exit 1 +fi + +echo "Dataset $dataset successfully exported to \"$DEST\"" >> $OUTPUT + +exit 0 + +### +### +### +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/export_local_file.xml Tue Feb 28 12:36:45 2012 -0500 @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<tool id="export_local_file" name="Export dataset"> + <description>to a local filesytem</description> + <command interpreter="sh">export_local_file.sh $input '$filepath' $userEmail $output</command> + <inputs> + <param name="input" type="data" label="Dataset"/> + <param name="filepath" type="text" size="100" label="Absolute file path" /> + </inputs> + <outputs> + <data format="txt" name="output" label="local export: $filepath" /> + </outputs> + <help> + +.. class:: infomark + +**Copying files** + +This tool will allow you to export a single file from Galaxy to a local filesystem. +You must have permission to write the file to the given directory, and the file must not yet exist. This tool will +not overwrite a pre-existing file. + +.. class:: warningmark + +**Important Notes** + +- The file path must be a file, not a directory +- You must give the fullpath to the file (/home/user/myfile.txt, not ./myfile.txt) +- You must have permission to write the file in the given directory + +----- + +**Example** + +- /home/user/bamfiles/abc123.bam +- /data/anotheruser/data/good_data/very_good_data.txt + + </help> +</tool>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/import_local_file.sh Tue Feb 28 12:36:45 2012 -0500 @@ -0,0 +1,49 @@ +### +### The shell script: import_local.sh +### +### The script copies the source file (param 1) +### to the destination file (param 2, which is galaxy's dataset_NNNNN.dat). +### +### The extra code tries to make it as safe as possible, allowing imports only +### from limited areas. +### +### The script can be changed from copying to linking - would be even faster. +### +### cpx is a C executable that copies a file from a source to a destination +### only if the source file is readable by the user given in the third arg. +### cpx must be setuid root, so be careful who has access to it! It can also +### be allowed using sudo, if you know how to do it. +#!/bin/sh + +INPUT="$1" +OUTPUT="$2" +EMAIL="$3" +USER=`echo $EMAIL | sed -e 's#@.*##'` + +if [ -z "$OUTPUT" ]; then + echo "Usage: $0 [INPUT] [OUTPUT]" >&2 + exit 1 +fi + +# Filter any unwanted directories + +if [[ `echo $INPUT | grep -c ^/data/` -lt 1 ]] && [[ `echo $INPUT | grep -c ^/home/` -lt 1 ]] ; then + echo "Error: \"$INPUT\" is not allowed" >&2 + exit 1 +fi + +# Do the deed +cpx $INPUT $OUTPUT "$USER" +if [ $? != 0 ]; then + echo "Error: $USER failed to copy \"$INPUT\"" >&2 + exit 1 +fi + +echo "File \"$INPUT\" imported" + +exit 0 + +### +### +### +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/import_local_file.xml Tue Feb 28 12:36:45 2012 -0500 @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<tool id="import_local_file" name="Import local file"> + <description>from a mounted filesystem</description> + <command interpreter="sh">import_local_file.sh '$filepath' $output $userEmail</command> + <inputs> + <param name="filepath" type="text" size="100" label="Absolute file path" /> + </inputs> + <outputs> + <data format="txt" name="output" label="local import: $filepath" /> + </outputs> + <help> + +.. class:: infomark + +**Copying files** + +This tool will allow you to upload a single file that is locally available. There is no browse function, +however, so you will need to give the full path name. If you have permission to read the file, Galaxy can import the file. + +.. class:: warningmark + +**Important Notes** + +- The file path must be a file, not a directory +- You must give the fullpath to the file (/home/user/myfile.txt, not ./myfile.txt) +- You must have permission to read the file + +----- + +**Example** + +- /home/user/bamfiles/abc123.bam +- /data/anotheruser/data/good_data/very_good_data.txt + + </help> +</tool>