This commit was manufactured by cvs2svn to create branch 'SAMBA_TNG'.
[Samba.git] / source / client / smbumount.c
blobbc8999d765e1a0880a2c1b5a9691f7710eedeeaf
1 /*
2 * smbumount.c
4 * Copyright (C) 1995-1998 by Volker Lendecke
6 */
8 #include "includes.h"
10 #include <mntent.h>
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>
18 /* This is a (hopefully) temporary hack due to the fact that
19 sizeof( uid_t ) != sizeof( __kernel_uid_t ) under glibc.
20 This may change in the future and smb.h may get fixed in the
21 future. In the mean time, it's ugly hack time - get over it.
23 #undef SMB_IOC_GETMOUNTUID
24 #define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_uid_t)
26 static char *progname;
28 static void
29 usage(void)
31 printf("usage: %s mount-point\n", progname);
34 static int
35 umount_ok(const char *mount_point)
37 int fid = open(mount_point, O_RDONLY, 0);
38 __kernel_uid_t mount_uid;
40 if (fid == -1) {
41 fprintf(stderr, "Could not open %s: %s\n",
42 mount_point, strerror(errno));
43 return -1;
46 if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid) != 0) {
47 fprintf(stderr, "%s probably not smb-filesystem\n",
48 mount_point);
49 return -1;
52 if ( (getuid() != 0)
53 && (mount_uid != getuid())) {
54 fprintf(stderr, "You are not allowed to umount %s\n",
55 mount_point);
56 return -1;
59 close(fid);
60 return 0;
63 /* Make a canonical pathname from PATH. Returns a freshly malloced string.
64 It is up the *caller* to ensure that the PATH is sensible. i.e.
65 canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
66 is not a legal pathname for ``/dev/fd0.'' Anything we cannot parse
67 we return unmodified. */
68 char *
69 canonicalize (char *path)
71 char *canonical = malloc (PATH_MAX + 1);
73 if (strlen(path) > PATH_MAX)
75 fprintf(stderr, "Mount point string too long\n");
76 return NULL;
79 if (path == NULL)
80 return NULL;
82 if (realpath (path, canonical))
83 return canonical;
85 pstrcpy (canonical, path);
86 return canonical;
90 int
91 main(int argc, char *argv[])
93 int fd;
95 char* mount_point;
97 struct mntent *mnt;
98 FILE* mtab;
99 FILE* new_mtab;
101 progname = argv[0];
103 if (argc != 2) {
104 usage();
105 exit(1);
108 if (geteuid() != 0) {
109 fprintf(stderr, "%s must be installed suid root\n", progname);
110 exit(1);
113 mount_point = canonicalize(argv[1]);
115 if (mount_point == NULL)
117 exit(1);
120 if (umount_ok(mount_point) != 0) {
121 exit(1);
124 if (umount(mount_point) != 0) {
125 fprintf(stderr, "Could not umount %s: %s\n",
126 mount_point, strerror(errno));
127 exit(1);
130 if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
132 fprintf(stderr, "Can't get "MOUNTED"~ lock file");
133 return 1;
135 close(fd);
137 if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
138 fprintf(stderr, "Can't open " MOUNTED ": %s\n",
139 strerror(errno));
140 return 1;
143 #define MOUNTED_TMP MOUNTED".tmp"
145 if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
146 fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
147 strerror(errno));
148 endmntent(mtab);
149 return 1;
152 while ((mnt = getmntent(mtab)) != NULL) {
153 if (strcmp(mnt->mnt_dir, mount_point) != 0) {
154 addmntent(new_mtab, mnt);
158 endmntent(mtab);
160 if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
161 fprintf(stderr, "Error changing mode of %s: %s\n",
162 MOUNTED_TMP, strerror(errno));
163 exit(1);
166 endmntent(new_mtab);
168 if (rename(MOUNTED_TMP, MOUNTED) < 0) {
169 fprintf(stderr, "Cannot rename %s to %s: %s\n",
170 MOUNTED, MOUNTED_TMP, strerror(errno));
171 exit(1);
174 if (unlink(MOUNTED"~") == -1)
176 fprintf(stderr, "Can't remove "MOUNTED"~");
177 return 1;
180 return 0;