~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/client/smbumount.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
32
 
static void
33
 
usage(void)
34
 
{
35
 
        printf("usage: smbumount mountpoint\n");
36
 
}
37
 
 
38
 
static int
39
 
umount_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.   */
78
 
static char *
79
 
canonicalize (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
 
 
105
 
int 
106
 
main(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
 
}