client/smbumount.c

説明を見る。
00001 /*
00002  *  smbumount.c
00003  *
00004  *  Copyright (C) 1995-1998 by Volker Lendecke
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 /* This is a (hopefully) temporary hack due to the fact that
00021         sizeof( uid_t ) != sizeof( __kernel_uid_t ) under glibc.
00022         This may change in the future and smb.h may get fixed in the
00023         future.  In the mean time, it's ugly hack time - get over it.
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         /* we set O_NOFOLLOW to prevent users playing games with symlinks to
00044            umount filesystems they don't own */
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 /* Make a canonical pathname from PATH.  Returns a freshly malloced string.
00076    It is up the *caller* to ensure that the PATH is sensible.  i.e.
00077    canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
00078    is not a legal pathname for ``/dev/fd0''  Anything we cannot parse
00079    we return unmodified.   */
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 }       

Sambaに対してSat Aug 29 21:22:53 2009に生成されました。  doxygen 1.4.7