From: jlnance@eos.ncsu.edu (JAMES LEWIS NANCE) Subject: ANNOUNCE Normal user floppy file systems Date: Fri, 18 Dec 1992 20:09:18 GMT
I read some requests last week for information about allowing a normal user to
mount floppys. I have written a program which will do this. I do not think
that it adds any security risk to have it on your system. If anyone can think
of a way to use it to breach security, send me some mail and I will modify the
program to try to make it more secure.
Read the comments for more doccumentation.
Jim Nance
/*
* This program provides a safe way for normal users to create, mount, and
* unmount floppy file systems. When the floppy is mounted, this program
* executes the command chmod -f -R a-s to unset all of the suid/sgid bits.
* a better way would probably be to mount the floppy with an option to ignore
* set uid bits, but I don't know how to do this.
*
* The executable produced by the program must be owned by root, and have
* the suid bit set. Ie:
* gcc -O -s -o floppy floppy.c
* chown root floppy
* chmod 4755 floppy
*
* If you have a 3.5" drive, you should change the #define FlopBlocks to
* 2880, or you will have to use the -b2880 flag when you run the program.
* By default the program mounts the floppy on /tmp/floppy. You can over ride
* this with the -m flag or you can change #define MntPoint to be something
* else. If you mount the floppy on a nonexistant mount point, the program
* will create the mount point, and remove it when you unmount the floppy. If
* the mount point exists before the program is run, it is not removed by the
* program when the floppy is unmounted.
*
* Summary of commands. Assume the executable is called floppy.
*
* floppy format # low level formats the floppy
* floppy new # high level formats the floppy
* floppy mount # mounts the floppy
* floppy unmount # unmounts the floppy
*/
#include "stdlib.h"
#include "string.h"
#include "stdarg.h"
#include "stdio.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "sys/wait.h"
#include "unistd.h"
#define MntPoint "/tmp/floppy"
#define FlopBlocks "2400"
#define Ssiz 256
/*VARARGS1*/
void err_exit(char *fmt, ...) {
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fputs("\n", stderr);
exit(1);
}
/*VARARGS1*/
void new_sys(char *fmt, ...) {
char cmd[1024];
va_list args;
va_start(args, fmt);
vsprintf(cmd, fmt, args);
va_end(args);
printf("system: %s\n", cmd);
system(cmd);
}
void print_help(char **argv) {
int i;
static char *cp[] = {
"\n",
"options are :\n",
" -dX -> use device X as the floppy drive. Default is /dev/fd0\n",
" -eX -> use program X in place of mkfs Default is mkfs -c\n",
" -bX -> append X to mkfs command Default is ",
FlopBlocks,
"\n",
" -mX -> mount floppy on directory X Default is ",
MntPoint,
" \n",
" \n",
"cmd is one of:\n",
" format -> format the floppy\n",
" new -> create a file system on the floppy\n",
" mount -> mount the floppy on /tmp/floppy\n",
" unmount -> unmount the floppy\n",
NULL};
printf("USAGE: %s {options} cmd", argv[0]);
for(i=0; cp[i]; fputs(cp[i++],stdout));
}
int main(int argc, char **argv, char **envp) {
char dev[Ssiz+1];
char mfs[Ssiz+1];
char blk[Ssiz+1];
char pth[Ssiz+1+20];
char *place;
int i;
int action=0;
uid_t uid = getuid();
gid_t gid = getgid();
pid_t pid;
struct stat buf;
if(setenv("PATH","/bin:/usr/bin:/usr/local/bin:/etc:/usr/ucb", 1))
err_exit("Can not set PATH environment variable");
strcpy(dev,"/dev/fd0");
strcpy(pth,MntPoint);
strcpy(blk,FlopBlocks);
strcpy(mfs,"mkfs -c");
for(i=1; i<argc; i++) {
if(!strncmp(argv[i], "-d", 2)) strncpy(dev,argv[i]+2,Ssiz)[Ssiz]='0'; else
if(!strncmp(argv[i], "-b", 2)) strncpy(blk,argv[i]+2,Ssiz)[Ssiz]='0'; else
if(!strncmp(argv[i], "-e", 2)) strncpy(mfs,argv[i]+2,Ssiz)[Ssiz]='0'; else
if(!strncmp(argv[i], "-m", 2)) strncpy(pth,argv[i]+2,Ssiz)[Ssiz]='0'; else
if(!strcmp(argv[i],"format" )) action=1; else
if(!strcmp(argv[i],"new" )) action=2; else
if(!strcmp(argv[i],"mount" )) action=3; else
if(!strcmp(argv[i],"unmount")) action=4; else
if(!strcmp(argv[i],"help" )) {print_help(argv); exit(0);}
}
switch (action) {
case 1:
new_sys("fdformat %s", dev);
break;
case 2:
new_sys("%s %s %s",mfs, dev, blk);
break;
case 3:
if(stat(pth, &buf)) if(pid=fork()) wait(pid); else {
setuid(uid);
setgid(gid);
new_sys("mkdir -p %s/floppy.tmp.dir", pth);
new_sys("chmod 700 %s", pth);
exit(0);
}
if(stat(pth, &buf)) err_exit("Unable to create %s",pth);
if(buf.st_uid!=uid) err_exit("You do not own %s", pth);
if(!(buf.st_mode&S_IFDIR)) err_exit("%s is not a directory",pth);
new_sys("mount %s %s", dev, pth);
new_sys("chmod -f -R a-s %s", pth);
chown(pth, uid, gid);
break;
case 4:
if(stat(pth, &buf)) err_exit("can not stat %s", pth);
if(buf.st_uid!=uid) err_exit("You do not own %s", pth);
if(!(buf.st_mode&S_IFDIR)) err_exit("%s is not a directory",pth);
new_sys("umount %s", dev);
for(place=pth; *place; place++);
strcpy(place,"/floppy.tmp.dir");
if(!stat(pth, &buf)) {
*place='\0';
new_sys("rm -rf %s", pth);
}
else *place='\0';
break;
default: print_help(argv);
}
return 0;
}