source: trunk/samba-3.0.25pre1/source/client/smbumount.c@ 5

Last change on this file since 5 was 1, checked in by Paul Smedley, 18 years ago

Initial code import

File size: 4.8 KB
Line 
1/*
2 * smbumount.c
3 *
4 * Copyright (C) 1995-1998 by Volker Lendecke
5 *
6 */
7
8#define SMBMOUNT_MALLOC 1
9
10#include "includes.h"
11
12#include <mntent.h>
13
14#include <asm/types.h>
15#include <asm/posix_types.h>
16#include <linux/smb.h>
17#include <linux/smb_mount.h>
18#include <linux/smb_fs.h>
19
20/* This is a (hopefully) temporary hack due to the fact that
21 sizeof( uid_t ) != sizeof( __kernel_uid_t ) under glibc.
22 This may change in the future and smb.h may get fixed in the
23 future. In the mean time, it's ugly hack time - get over it.
24*/
25#undef SMB_IOC_GETMOUNTUID
26#define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_uid_t)
27
28#ifndef O_NOFOLLOW
29#define O_NOFOLLOW 0400000
30#endif
31
32static void
33usage(void)
34{
35 printf("usage: smbumount mountpoint\n");
36}
37
38static int
39umount_ok(const char *mount_point)
40{
41 /* we set O_NOFOLLOW to prevent users playing games with symlinks to
42 umount filesystems they don't own */
43 int fid = open(mount_point, O_RDONLY|O_NOFOLLOW, 0);
44 __kernel_uid32_t mount_uid;
45
46 if (fid == -1) {
47 fprintf(stderr, "Could not open %s: %s\n",
48 mount_point, strerror(errno));
49 return -1;
50 }
51
52 if (ioctl(fid, SMB_IOC_GETMOUNTUID32, &mount_uid) != 0) {
53 __kernel_uid_t mount_uid16;
54 if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid16) != 0) {
55 fprintf(stderr, "%s probably not smb-filesystem\n",
56 mount_point);
57 return -1;
58 }
59 mount_uid = mount_uid16;
60 }
61
62 if ((getuid() != 0)
63 && (mount_uid != getuid())) {
64 fprintf(stderr, "You are not allowed to umount %s\n",
65 mount_point);
66 return -1;
67 }
68
69 close(fid);
70 return 0;
71}
72
73/* Make a canonical pathname from PATH. Returns a freshly malloced string.
74 It is up the *caller* to ensure that the PATH is sensible. i.e.
75 canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
76 is not a legal pathname for ``/dev/fd0'' Anything we cannot parse
77 we return unmodified. */
78static char *
79canonicalize (char *path)
80{
81 char *canonical = malloc (PATH_MAX + 1);
82
83 if (!canonical) {
84 fprintf(stderr, "Error! Not enough memory!\n");
85 return NULL;
86 }
87
88 if (strlen(path) > PATH_MAX) {
89 fprintf(stderr, "Mount point string too long\n");
90 return NULL;
91 }
92
93 if (path == NULL)
94 return NULL;
95
96 if (realpath (path, canonical))
97 return canonical;
98
99 strncpy (canonical, path, PATH_MAX);
100 canonical[PATH_MAX] = '\0';
101 return canonical;
102}
103
104
105int
106main(int argc, char *argv[])
107{
108 int fd;
109 char* mount_point;
110 struct mntent *mnt;
111 FILE* mtab;
112 FILE* new_mtab;
113
114 if (argc != 2) {
115 usage();
116 exit(1);
117 }
118
119 if (geteuid() != 0) {
120 fprintf(stderr, "smbumount must be installed suid root\n");
121 exit(1);
122 }
123
124 mount_point = canonicalize(argv[1]);
125
126 if (mount_point == NULL)
127 {
128 exit(1);
129 }
130
131 if (umount_ok(mount_point) != 0) {
132 exit(1);
133 }
134
135 if (umount(mount_point) != 0) {
136 fprintf(stderr, "Could not umount %s: %s\n",
137 mount_point, strerror(errno));
138 exit(1);
139 }
140
141 if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
142 {
143 fprintf(stderr, "Can't get "MOUNTED"~ lock file");
144 return 1;
145 }
146 close(fd);
147
148 if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
149 fprintf(stderr, "Can't open " MOUNTED ": %s\n",
150 strerror(errno));
151 return 1;
152 }
153
154#define MOUNTED_TMP MOUNTED".tmp"
155
156 if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
157 fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
158 strerror(errno));
159 endmntent(mtab);
160 return 1;
161 }
162
163 while ((mnt = getmntent(mtab)) != NULL) {
164 if (strcmp(mnt->mnt_dir, mount_point) != 0) {
165 addmntent(new_mtab, mnt);
166 }
167 }
168
169 endmntent(mtab);
170
171 if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
172 fprintf(stderr, "Error changing mode of %s: %s\n",
173 MOUNTED_TMP, strerror(errno));
174 exit(1);
175 }
176
177 endmntent(new_mtab);
178
179 if (rename(MOUNTED_TMP, MOUNTED) < 0) {
180 fprintf(stderr, "Cannot rename %s to %s: %s\n",
181 MOUNTED, MOUNTED_TMP, strerror(errno));
182 exit(1);
183 }
184
185 if (unlink(MOUNTED"~") == -1)
186 {
187 fprintf(stderr, "Can't remove "MOUNTED"~");
188 return 1;
189 }
190
191 return 0;
192}
Note: See TracBrowser for help on using the repository browser.