Add mount.cifs as a wrapper for mount.cifs.
[Samba.git] / source / client / smbumount.c
blobe74c31299c27e49193d06ee6e87041058b3ddec1
1 /*
2 * smbumount.c
4 * Copyright (C) 1995-1998 by Volker Lendecke
6 */
8 #define SMBMOUNT_MALLOC 1
10 #include "includes.h"
12 #include <mntent.h>
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>
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.
25 #undef SMB_IOC_GETMOUNTUID
26 #define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_uid_t)
28 #ifndef O_NOFOLLOW
29 #define O_NOFOLLOW 0400000
30 #endif
32 static void
33 usage(void)
35 printf("usage: smbumount mountpoint\n\n");
36 printf("Please be aware that smbfs is deprecated in favor of "
37 "cifs\n");
40 static int
41 umount_ok(const char *mount_point)
43 /* we set O_NOFOLLOW to prevent users playing games with symlinks to
44 umount filesystems they don't own */
45 int fid = open(mount_point, O_RDONLY|O_NOFOLLOW, 0);
46 __kernel_uid32_t mount_uid;
48 if (fid == -1) {
49 fprintf(stderr, "Could not open %s: %s\n",
50 mount_point, strerror(errno));
51 return -1;
54 if (ioctl(fid, SMB_IOC_GETMOUNTUID32, &mount_uid) != 0) {
55 __kernel_uid_t mount_uid16;
56 if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid16) != 0) {
57 fprintf(stderr, "%s probably not smb-filesystem\n",
58 mount_point);
59 return -1;
61 mount_uid = mount_uid16;
64 if ((getuid() != 0)
65 && (mount_uid != getuid())) {
66 fprintf(stderr, "You are not allowed to umount %s\n",
67 mount_point);
68 return -1;
71 close(fid);
72 return 0;
75 /* Make a canonical pathname from PATH. Returns a freshly malloced string.
76 It is up the *caller* to ensure that the PATH is sensible. i.e.
77 canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
78 is not a legal pathname for ``/dev/fd0'' Anything we cannot parse
79 we return unmodified. */
80 static char *
81 canonicalize (char *path)
83 char *canonical = (char*)malloc (PATH_MAX + 1);
85 if (!canonical) {
86 fprintf(stderr, "Error! Not enough memory!\n");
87 return NULL;
90 if (strlen(path) > PATH_MAX) {
91 fprintf(stderr, "Mount point string too long\n");
92 return NULL;
95 if (path == NULL)
96 return NULL;
98 if (realpath (path, canonical))
99 return canonical;
101 strncpy (canonical, path, PATH_MAX);
102 canonical[PATH_MAX] = '\0';
103 return canonical;
108 main(int argc, char *argv[])
110 int fd;
111 char* mount_point;
112 struct mntent *mnt;
113 FILE* mtab;
114 FILE* new_mtab;
115 TALLOC_CTX *frame = talloc_stackframe();
117 if (argc != 2) {
118 usage();
119 exit(1);
122 if (geteuid() != 0) {
123 fprintf(stderr, "smbumount must be installed suid root\n");
124 exit(1);
127 mount_point = canonicalize(argv[1]);
129 if (mount_point == NULL)
131 exit(1);
134 if (umount_ok(mount_point) != 0) {
135 exit(1);
138 if (umount(mount_point) != 0) {
139 fprintf(stderr, "Could not umount %s: %s\n",
140 mount_point, strerror(errno));
141 exit(1);
144 if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
146 fprintf(stderr, "Can't get "MOUNTED"~ lock file");
147 return 1;
149 close(fd);
151 if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
152 fprintf(stderr, "Can't open " MOUNTED ": %s\n",
153 strerror(errno));
154 return 1;
157 #define MOUNTED_TMP MOUNTED".tmp"
159 if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
160 fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
161 strerror(errno));
162 endmntent(mtab);
163 return 1;
166 while ((mnt = getmntent(mtab)) != NULL) {
167 if (strcmp(mnt->mnt_dir, mount_point) != 0) {
168 addmntent(new_mtab, mnt);
172 endmntent(mtab);
174 if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
175 fprintf(stderr, "Error changing mode of %s: %s\n",
176 MOUNTED_TMP, strerror(errno));
177 exit(1);
180 endmntent(new_mtab);
182 if (rename(MOUNTED_TMP, MOUNTED) < 0) {
183 fprintf(stderr, "Cannot rename %s to %s: %s\n",
184 MOUNTED, MOUNTED_TMP, strerror(errno));
185 exit(1);
188 if (unlink(MOUNTED"~") == -1)
190 fprintf(stderr, "Can't remove "MOUNTED"~");
191 return 1;
194 TALLOC_FREE(frame);
195 return 0;