http://prdownloads.sourceforge.net/lufs/lufs-0.9.6.tar.gz?download
[lufs.git] / util / lufsmnt.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <limits.h>
6 #include <errno.h>
7 #include <mntent.h>
8 #include <paths.h>
9 #include <fcntl.h>
10 #include <string.h>
11
12 #include <sys/types.h>
13 #include <sys/mount.h>
14 #include <sys/stat.h>
15
16 #define ERROR(x...)     fprintf(stderr, x)
17
18 static void
19 help(){
20     printf("\n");
21     printf("Usage: lufsmnt mount-point [options]\n");
22     printf("This is a suid wrapper called by lufsd.\n");
23
24 }
25
26 static int
27 fullpath(char *path, char *full){
28     
29     full[0] = 0;
30     
31     if(strlen(path) >= PATH_MAX - 1)
32         return -1;
33
34     if(!realpath(path, full))
35         return -1;
36     else 
37         return 0;
38 }
39
40 static int
41 mount_ok(char *mp){
42     struct stat st;
43     
44     if(chdir(mp)){
45         ERROR("cannot chdir %s\n", mp);
46         return -1;
47     }
48         
49     if(stat(".", &st)){
50         ERROR("cannot stat %s\n", mp);
51         return -1;
52     }
53         
54     if(!S_ISDIR(st.st_mode)){
55         ERROR("%s is not a directory\n", mp);
56         return -1;
57     }
58
59     if((getuid()) && ((getuid() != st.st_uid) || ((st.st_mode & S_IRWXU) != S_IRWXU))){
60         ERROR("you don't have proper permissions to mount on %s\n", mp);
61         return -1;
62     }
63
64     return 0;
65 }
66
67 void
68 hide_pass(char *opts){
69     char *c;
70
71     if((c = strstr(opts, "password="))){
72         for(c = c + 9; (*c != 0) && (*c != ','); c++)
73             *c = '*';
74     }
75 }
76
77 void
78 get_fs(char *opts, char *buf, int buflen){
79     char *begin, *end;
80
81     buf[0] = 0;
82     buf[buflen - 1] = 0;
83
84     if((begin = strstr(opts, "fs="))){
85         begin += 3;
86         
87         if(!(end = strchr(begin, ','))){
88             end = begin + strlen(begin);
89         }
90         
91         if( end - begin >= buflen)
92             end = begin + buflen - 1;
93
94         strncpy(buf, begin, end - begin);
95     }
96 }
97
98 int
99 main(int argc, char **argv){
100     char *mountpoint, *opts;
101     static char fpath[PATH_MAX];
102     static char mfs[PATH_MAX];
103     static char mopts[PATH_MAX];
104     struct mntent ment;
105     int fd;
106     FILE *mtab;
107     
108     if(argc != 3){
109         help();
110         exit(1);
111     }
112
113     if(geteuid()){
114         ERROR("%s needs to be installed suid root in order to be used by unprivileged users\n", argv[0]);
115         exit(1);
116     }
117     
118     mountpoint = argv[1];
119     opts = argv[2];
120
121     fullpath(mountpoint, fpath);
122     
123     if(mount_ok(fpath)){
124         exit(1);
125     }
126         
127     if (mount("none", fpath, "lufs", MS_NOSUID | MS_NODEV, opts) < 0){
128         ERROR("mount failed: %s\n", strerror(errno));
129         switch(errno){
130         case ENODEV:
131             ERROR("you don't have kernel lufs support (check whether the lufs module is available/loaded)\n");
132             break;
133         }
134         return errno;
135     }
136
137     sprintf(mopts, "owner=%d,", getuid());
138     hide_pass(opts);
139     if(strlen(mopts) + strlen(opts) < PATH_MAX)
140         strcat(mopts, opts);
141     get_fs(opts, mfs, PATH_MAX);
142
143     ment.mnt_fsname = mfs;
144     ment.mnt_dir = fpath;
145     ment.mnt_type = "lufs";
146     ment.mnt_opts = mopts;
147     ment.mnt_freq = 0;
148     ment.mnt_passno = 0;
149
150     if((fd = open(_PATH_MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) < 0){
151         ERROR("can't get "_PATH_MOUNTED"~ lock file\n");
152         return 1;
153     }
154     close(fd);
155     
156     if((mtab = setmntent(_PATH_MOUNTED, "a+")) == NULL){
157         ERROR("can't open "_PATH_MOUNTED"\n");
158         return 1;
159     }
160     
161     if(addmntent(mtab, &ment)){
162         ERROR("can't write mount entry\n");
163         return 1;
164     }
165     
166     if(fchmod(fileno(mtab), 0644) < 0){
167         ERROR("can't set [erms on "_PATH_MOUNTED"\n");
168         return 1;
169     }
170     
171     endmntent(mtab);
172     
173     if(unlink(_PATH_MOUNTED"~") < 0){
174         ERROR("can't remove "_PATH_MOUNTED"~\n");
175         return 1;
176     }
177     
178     return 0;
179 }
180