00001
00002
00003
00004
00005
00006
00007
00008 #define SMBMOUNT_MALLOC 1
00009
00010 #include "includes.h"
00011
00012 #include <mntent.h>
00013
00014 #include <asm/types.h>
00015 #include <asm/posix_types.h>
00016 #include <linux/smb.h>
00017 #include <linux/smb_mount.h>
00018 #include <linux/smb_fs.h>
00019
00020
00021
00022
00023
00024
00025 #undef SMB_IOC_GETMOUNTUID
00026 #define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_uid_t)
00027
00028 #ifndef O_NOFOLLOW
00029 #define O_NOFOLLOW 0400000
00030 #endif
00031
00032 static void
00033 usage(void)
00034 {
00035 printf("usage: smbumount mountpoint\n\n");
00036 printf("Please be aware that smbfs is deprecated in favor of "
00037 "cifs\n");
00038 }
00039
00040 static int
00041 umount_ok(const char *mount_point)
00042 {
00043
00044
00045 int fid = open(mount_point, O_RDONLY|O_NOFOLLOW, 0);
00046 __kernel_uid32_t mount_uid;
00047
00048 if (fid == -1) {
00049 fprintf(stderr, "Could not open %s: %s\n",
00050 mount_point, strerror(errno));
00051 return -1;
00052 }
00053
00054 if (ioctl(fid, SMB_IOC_GETMOUNTUID32, &mount_uid) != 0) {
00055 __kernel_uid_t mount_uid16;
00056 if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid16) != 0) {
00057 fprintf(stderr, "%s probably not smb-filesystem\n",
00058 mount_point);
00059 return -1;
00060 }
00061 mount_uid = mount_uid16;
00062 }
00063
00064 if ((getuid() != 0)
00065 && (mount_uid != getuid())) {
00066 fprintf(stderr, "You are not allowed to umount %s\n",
00067 mount_point);
00068 return -1;
00069 }
00070
00071 close(fid);
00072 return 0;
00073 }
00074
00075
00076
00077
00078
00079
00080 static char *
00081 canonicalize (char *path)
00082 {
00083 char *canonical = malloc (PATH_MAX + 1);
00084
00085 if (!canonical) {
00086 fprintf(stderr, "Error! Not enough memory!\n");
00087 return NULL;
00088 }
00089
00090 if (strlen(path) > PATH_MAX) {
00091 fprintf(stderr, "Mount point string too long\n");
00092 return NULL;
00093 }
00094
00095 if (path == NULL)
00096 return NULL;
00097
00098 if (realpath (path, canonical))
00099 return canonical;
00100
00101 strncpy (canonical, path, PATH_MAX);
00102 canonical[PATH_MAX] = '\0';
00103 return canonical;
00104 }
00105
00106
00107 int
00108 main(int argc, char *argv[])
00109 {
00110 int fd;
00111 char* mount_point;
00112 struct mntent *mnt;
00113 FILE* mtab;
00114 FILE* new_mtab;
00115
00116 if (argc != 2) {
00117 usage();
00118 exit(1);
00119 }
00120
00121 if (geteuid() != 0) {
00122 fprintf(stderr, "smbumount must be installed suid root\n");
00123 exit(1);
00124 }
00125
00126 mount_point = canonicalize(argv[1]);
00127
00128 if (mount_point == NULL)
00129 {
00130 exit(1);
00131 }
00132
00133 if (umount_ok(mount_point) != 0) {
00134 exit(1);
00135 }
00136
00137 if (umount(mount_point) != 0) {
00138 fprintf(stderr, "Could not umount %s: %s\n",
00139 mount_point, strerror(errno));
00140 exit(1);
00141 }
00142
00143 if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
00144 {
00145 fprintf(stderr, "Can't get "MOUNTED"~ lock file");
00146 return 1;
00147 }
00148 close(fd);
00149
00150 if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
00151 fprintf(stderr, "Can't open " MOUNTED ": %s\n",
00152 strerror(errno));
00153 return 1;
00154 }
00155
00156 #define MOUNTED_TMP MOUNTED".tmp"
00157
00158 if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
00159 fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
00160 strerror(errno));
00161 endmntent(mtab);
00162 return 1;
00163 }
00164
00165 while ((mnt = getmntent(mtab)) != NULL) {
00166 if (strcmp(mnt->mnt_dir, mount_point) != 0) {
00167 addmntent(new_mtab, mnt);
00168 }
00169 }
00170
00171 endmntent(mtab);
00172
00173 if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
00174 fprintf(stderr, "Error changing mode of %s: %s\n",
00175 MOUNTED_TMP, strerror(errno));
00176 exit(1);
00177 }
00178
00179 endmntent(new_mtab);
00180
00181 if (rename(MOUNTED_TMP, MOUNTED) < 0) {
00182 fprintf(stderr, "Cannot rename %s to %s: %s\n",
00183 MOUNTED, MOUNTED_TMP, strerror(errno));
00184 exit(1);
00185 }
00186
00187 if (unlink(MOUNTED"~") == -1)
00188 {
00189 fprintf(stderr, "Can't remove "MOUNTED"~");
00190 return 1;
00191 }
00192
00193 return 0;
00194 }