#include #include #include #include #include #include #include #include #include #include #include #include #include #define ERROR(x...) fprintf(stderr, x) static void help(){ printf("\n"); printf("Usage: lufsmnt mount-point [options]\n"); printf("This is a suid wrapper called by lufsd.\n"); } static int fullpath(char *path, char *full){ full[0] = 0; if(strlen(path) >= PATH_MAX - 1) return -1; if(!realpath(path, full)) return -1; else return 0; } static int mount_ok(char *mp){ struct stat st; if(chdir(mp)){ ERROR("cannot chdir %s\n", mp); return -1; } if(stat(".", &st)){ ERROR("cannot stat %s\n", mp); return -1; } if(!S_ISDIR(st.st_mode)){ ERROR("%s is not a directory\n", mp); return -1; } if((getuid()) && ((getuid() != st.st_uid) || ((st.st_mode & S_IRWXU) != S_IRWXU))){ ERROR("you don't have proper permissions to mount on %s\n", mp); return -1; } return 0; } void hide_pass(char *opts){ char *c; if((c = strstr(opts, "password="))){ for(c = c + 9; (*c != 0) && (*c != ','); c++) *c = '*'; } } void get_fs(char *opts, char *buf, int buflen){ char *begin, *end; buf[0] = 0; buf[buflen - 1] = 0; if((begin = strstr(opts, "fs="))){ begin += 3; if(!(end = strchr(begin, ','))){ end = begin + strlen(begin); } if( end - begin >= buflen) end = begin + buflen - 1; strncpy(buf, begin, end - begin); } } int main(int argc, char **argv){ char *mountpoint, *opts; static char fpath[PATH_MAX]; static char mfs[PATH_MAX]; static char mopts[PATH_MAX]; struct mntent ment; int fd; FILE *mtab; if(argc != 3){ help(); exit(1); } if(geteuid()){ ERROR("%s needs to be installed suid root in order to be used by unprivileged users\n", argv[0]); exit(1); } mountpoint = argv[1]; opts = argv[2]; fullpath(mountpoint, fpath); if(mount_ok(fpath)){ exit(1); } if (mount("none", fpath, "lufs", MS_NOSUID | MS_NODEV, opts) < 0){ ERROR("mount failed: %s\n", strerror(errno)); switch(errno){ case ENODEV: ERROR("you don't have kernel lufs support (check whether the lufs module is available/loaded)\n"); break; } return errno; } sprintf(mopts, "owner=%d,", getuid()); hide_pass(opts); if(strlen(mopts) + strlen(opts) < PATH_MAX) strcat(mopts, opts); get_fs(opts, mfs, PATH_MAX); ment.mnt_fsname = mfs; ment.mnt_dir = fpath; ment.mnt_type = "lufs"; ment.mnt_opts = mopts; ment.mnt_freq = 0; ment.mnt_passno = 0; if((fd = open(_PATH_MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) < 0){ ERROR("can't get "_PATH_MOUNTED"~ lock file\n"); return 1; } close(fd); if((mtab = setmntent(_PATH_MOUNTED, "a+")) == NULL){ ERROR("can't open "_PATH_MOUNTED"\n"); return 1; } if(addmntent(mtab, &ment)){ ERROR("can't write mount entry\n"); return 1; } if(fchmod(fileno(mtab), 0644) < 0){ ERROR("can't set [erms on "_PATH_MOUNTED"\n"); return 1; } endmntent(mtab); if(unlink(_PATH_MOUNTED"~") < 0){ ERROR("can't remove "_PATH_MOUNTED"~\n"); return 1; } return 0; }