Two changes in this ball...
[ira/wip.git] / source3 / client / smbumount.c
1 /*
2  *  smbumount.c
3  *
4  *  Copyright (C) 1995-1998 by Volker Lendecke
5  *
6  */
7
8 #include "includes.h"
9
10 #include <mntent.h>
11
12 #include <asm/types.h>
13 #include <asm/posix_types.h>
14 #include <linux/smb.h>
15 #include <linux/smb_mount.h>
16 #include <linux/smb_fs.h>
17
18 #include "includes.h"
19
20 static char *progname;
21
22 static void
23 usage(void)
24 {
25         printf("usage: %s mount-point\n", progname);
26 }
27
28 static int
29 umount_ok(const char *mount_point)
30 {
31         int fid = open(mount_point, O_RDONLY, 0);
32         uid_t mount_uid;
33
34         if (fid == -1) {
35                 fprintf(stderr, "Could not open %s: %s\n",
36                         mount_point, strerror(errno));
37                 return -1;
38         }
39         
40         if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid) != 0) {
41                 fprintf(stderr, "%s probably not smb-filesystem\n",
42                         mount_point);
43                 return -1;
44         }
45
46         if (   (getuid() != 0)
47             && (mount_uid != getuid())) {
48                 fprintf(stderr, "You are not allowed to umount %s\n",
49                         mount_point);
50                 return -1;
51         }
52
53         close(fid);
54         return 0;
55 }
56
57 /* Make a canonical pathname from PATH.  Returns a freshly malloced string.
58    It is up the *caller* to ensure that the PATH is sensible.  i.e.
59    canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
60    is not a legal pathname for ``/dev/fd0.''  Anything we cannot parse
61    we return unmodified.   */
62 char *
63 canonicalize (const char *path)
64 {
65         char *canonical = malloc (PATH_MAX + 1);
66
67         if (strlen(path) > PATH_MAX)
68         {
69                 fprintf(stderr, "Mount point string too long\n");
70                 return NULL;
71         }
72
73         if (path == NULL)
74                 return NULL;
75   
76         if (realpath (path, canonical))
77                 return canonical;
78
79         pstrcpy (canonical, path);
80         return canonical;
81 }
82
83
84 int 
85 main(int argc, char *argv[])
86 {
87         int fd;
88
89         char* mount_point;
90
91         struct mntent *mnt;
92         FILE* mtab;
93         FILE* new_mtab;
94
95         progname = argv[0];
96
97         if (argc != 2) {
98                 usage();
99                 exit(1);
100         }
101
102         if (geteuid() != 0) {
103                 fprintf(stderr, "%s must be installed suid root\n", progname);
104                 exit(1);
105         }
106
107         mount_point = canonicalize(argv[1]);
108
109         if (mount_point == NULL)
110         {
111                 exit(1);
112         }
113
114         if (umount_ok(mount_point) != 0) {
115                 exit(1);
116         }
117
118         if (umount(mount_point) != 0) {
119                 fprintf(stderr, "Could not umount %s: %s\n",
120                         mount_point, strerror(errno));
121                 exit(1);
122         }
123
124         if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
125         {
126                 fprintf(stderr, "Can't get "MOUNTED"~ lock file");
127                 return 1;
128         }
129         close(fd);
130         
131         if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
132                 fprintf(stderr, "Can't open " MOUNTED ": %s\n",
133                         strerror(errno));
134                 return 1;
135         }
136
137 #define MOUNTED_TMP MOUNTED".tmp"
138
139         if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
140                 fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
141                         strerror(errno));
142                 endmntent(mtab);
143                 return 1;
144         }
145
146         while ((mnt = getmntent(mtab)) != NULL) {
147                 if (strcmp(mnt->mnt_dir, mount_point) != 0) {
148                         addmntent(new_mtab, mnt);
149                 }
150         }
151
152         endmntent(mtab);
153
154         if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
155                 fprintf(stderr, "Error changing mode of %s: %s\n",
156                         MOUNTED_TMP, strerror(errno));
157                 exit(1);
158         }
159
160         endmntent(new_mtab);
161
162         if (rename(MOUNTED_TMP, MOUNTED) < 0) {
163                 fprintf(stderr, "Cannot rename %s to %s: %s\n",
164                         MOUNTED, MOUNTED_TMP, strerror(errno));
165                 exit(1);
166         }
167
168         if (unlink(MOUNTED"~") == -1)
169         {
170                 fprintf(stderr, "Can't remove "MOUNTED"~");
171                 return 1;
172         }
173
174         return 0;
175 }