~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/client/smbumount.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

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
#include "includes.h"
 
9
 
 
10
#include <mntent.h>
 
11
 
 
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>
 
17
 
 
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.
 
22
*/
 
23
#undef SMB_IOC_GETMOUNTUID
 
24
#define SMB_IOC_GETMOUNTUID             _IOR('u', 1, __kernel_uid_t)
 
25
 
 
26
#ifndef O_NOFOLLOW
 
27
#define O_NOFOLLOW     0400000
 
28
#endif
 
29
 
 
30
static void
 
31
usage(void)
 
32
{
 
33
        printf("usage: smbumount mountpoint\n");
 
34
}
 
35
 
 
36
static int
 
37
umount_ok(const char *mount_point)
 
38
{
 
39
        /* we set O_NOFOLLOW to prevent users playing games with symlinks to
 
40
           umount filesystems they don't own */
 
41
        int fid = open(mount_point, O_RDONLY|O_NOFOLLOW, 0);
 
42
        __kernel_uid_t mount_uid;
 
43
        
 
44
        if (fid == -1) {
 
45
                fprintf(stderr, "Could not open %s: %s\n",
 
46
                        mount_point, strerror(errno));
 
47
                return -1;
 
48
        }
 
49
        
 
50
        if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid) != 0) {
 
51
                fprintf(stderr, "%s probably not smb-filesystem\n",
 
52
                        mount_point);
 
53
                return -1;
 
54
        }
 
55
 
 
56
        if ((getuid() != 0)
 
57
            && (mount_uid != getuid())) {
 
58
                fprintf(stderr, "You are not allowed to umount %s\n",
 
59
                        mount_point);
 
60
                return -1;
 
61
        }
 
62
 
 
63
        close(fid);
 
64
        return 0;
 
65
}
 
66
 
 
67
/* Make a canonical pathname from PATH.  Returns a freshly malloced string.
 
68
   It is up the *caller* to ensure that the PATH is sensible.  i.e.
 
69
   canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
 
70
   is not a legal pathname for ``/dev/fd0''  Anything we cannot parse
 
71
   we return unmodified.   */
 
72
static char *
 
73
canonicalize (char *path)
 
74
{
 
75
        char *canonical = malloc (PATH_MAX + 1);
 
76
 
 
77
        if (!canonical) {
 
78
                fprintf(stderr, "Error! Not enough memory!\n");
 
79
                return NULL;
 
80
        }
 
81
 
 
82
        if (strlen(path) > PATH_MAX) {
 
83
                fprintf(stderr, "Mount point string too long\n");
 
84
                return NULL;
 
85
        }
 
86
 
 
87
        if (path == NULL)
 
88
                return NULL;
 
89
  
 
90
        if (realpath (path, canonical))
 
91
                return canonical;
 
92
 
 
93
        strncpy (canonical, path, PATH_MAX);
 
94
        canonical[PATH_MAX] = '\0';
 
95
        return canonical;
 
96
}
 
97
 
 
98
 
 
99
int 
 
100
main(int argc, char *argv[])
 
101
{
 
102
        int fd;
 
103
        char* mount_point;
 
104
        struct mntent *mnt;
 
105
        FILE* mtab;
 
106
        FILE* new_mtab;
 
107
 
 
108
        if (argc != 2) {
 
109
                usage();
 
110
                exit(1);
 
111
        }
 
112
 
 
113
        if (geteuid() != 0) {
 
114
                fprintf(stderr, "smbumount must be installed suid root\n");
 
115
                exit(1);
 
116
        }
 
117
 
 
118
        mount_point = canonicalize(argv[1]);
 
119
 
 
120
        if (mount_point == NULL)
 
121
        {
 
122
                exit(1);
 
123
        }
 
124
 
 
125
        if (umount_ok(mount_point) != 0) {
 
126
                exit(1);
 
127
        }
 
128
 
 
129
        if (umount(mount_point) != 0) {
 
130
                fprintf(stderr, "Could not umount %s: %s\n",
 
131
                        mount_point, strerror(errno));
 
132
                exit(1);
 
133
        }
 
134
 
 
135
        if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
 
136
        {
 
137
                fprintf(stderr, "Can't get "MOUNTED"~ lock file");
 
138
                return 1;
 
139
        }
 
140
        close(fd);
 
141
        
 
142
        if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
 
143
                fprintf(stderr, "Can't open " MOUNTED ": %s\n",
 
144
                        strerror(errno));
 
145
                return 1;
 
146
        }
 
147
 
 
148
#define MOUNTED_TMP MOUNTED".tmp"
 
149
 
 
150
        if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
 
151
                fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
 
152
                        strerror(errno));
 
153
                endmntent(mtab);
 
154
                return 1;
 
155
        }
 
156
 
 
157
        while ((mnt = getmntent(mtab)) != NULL) {
 
158
                if (strcmp(mnt->mnt_dir, mount_point) != 0) {
 
159
                        addmntent(new_mtab, mnt);
 
160
                }
 
161
        }
 
162
 
 
163
        endmntent(mtab);
 
164
 
 
165
        if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
 
166
                fprintf(stderr, "Error changing mode of %s: %s\n",
 
167
                        MOUNTED_TMP, strerror(errno));
 
168
                exit(1);
 
169
        }
 
170
 
 
171
        endmntent(new_mtab);
 
172
 
 
173
        if (rename(MOUNTED_TMP, MOUNTED) < 0) {
 
174
                fprintf(stderr, "Cannot rename %s to %s: %s\n",
 
175
                        MOUNTED, MOUNTED_TMP, strerror(errno));
 
176
                exit(1);
 
177
        }
 
178
 
 
179
        if (unlink(MOUNTED"~") == -1)
 
180
        {
 
181
                fprintf(stderr, "Can't remove "MOUNTED"~");
 
182
                return 1;
 
183
        }
 
184
 
 
185
        return 0;
 
186
}