preparing for release of alpha.0.7
[Samba.git] / source / client / smbmnt.c
blobfa3cacb8640bfb3f30facb0f11b83906d2efa485
1 /*
2 * smbmount.c
4 * Copyright (C) 1995-1998 by Paal-Kr. Engstad and 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 <asm/unistd.h>
18 #ifndef MS_MGC_VAL
19 /* This may look strange but MS_MGC_VAL is what we are looking for and
20 is what we need from <linux/fs.h> under libc systems and is
21 provided in standard includes on glibc systems. So... We
22 switch on what we need... */
23 #include <linux/fs.h>
24 #endif
26 static char *progname;
29 static void
30 usage(void)
32 printf("usage: %s mount-point [options]\n", progname);
33 printf("Try `%s -h' for more information\n", progname);
36 static void
37 help(void)
39 printf("\n");
40 printf("usage: %s mount-point [options]\n", progname);
41 printf("-u uid uid the mounted files get\n"
42 "-g gid gid the mounted files get\n"
43 "-f mode permission the files get (octal notation)\n"
44 "-d mode permission the dirs get (octal notation)\n"
45 "-P pid connection handler's pid\n\n"
46 "-s share share name on server\n\n"
47 "-h print this help text\n");
50 static int
51 parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share)
53 int opt;
54 struct passwd *pwd;
55 struct group *grp;
57 while ((opt = getopt (argc, argv, "u:g:f:d:s:")) != EOF)
59 switch (opt)
61 case 'u':
62 if (isdigit(optarg[0]))
64 data->uid = atoi(optarg);
66 else
68 pwd = getpwnam(optarg);
69 if (pwd == NULL)
71 fprintf(stderr, "Unknown user: %s\n",
72 optarg);
73 return 1;
75 data->uid = pwd->pw_uid;
77 break;
78 case 'g':
79 if (isdigit(optarg[0]))
81 data->gid = atoi(optarg);
83 else
85 grp = getgrnam(optarg);
86 if (grp == NULL)
88 fprintf(stderr, "Unknown group: %s\n",
89 optarg);
90 return 1;
92 data->gid = grp->gr_gid;
94 break;
95 case 'f':
96 data->file_mode = strtol(optarg, NULL, 8);
97 break;
98 case 'd':
99 data->dir_mode = strtol(optarg, NULL, 8);
100 break;
101 case 's':
102 *share = optarg;
103 break;
104 default:
105 return -1;
108 return 0;
112 static char *
113 fullpath(const char *p)
115 char path[MAXPATHLEN];
117 if (strlen(p) > MAXPATHLEN-1)
119 return NULL;
122 if (realpath(p, path) == NULL)
124 return strdup(p);
126 return strdup(path);
129 /* Check whether user is allowed to mount on the specified mount point */
130 static int
131 mount_ok(SMB_STRUCT_STAT *st)
133 if (!S_ISDIR(st->st_mode))
135 errno = ENOTDIR;
136 return -1;
139 if ( (getuid() != 0)
140 && ( (getuid() != st->st_uid)
141 || ((st->st_mode & S_IRWXU) != S_IRWXU)))
143 errno = EPERM;
144 return -1;
147 return 0;
150 int
151 main(int argc, char *argv[])
153 char *mount_point, *share_name = NULL;
154 FILE *mtab;
155 int fd, um;
156 unsigned int flags;
157 struct smb_mount_data data;
158 SMB_STRUCT_STAT st;
159 struct mntent ment;
161 progname = argv[0];
163 memset(&data, 0, sizeof(struct smb_mount_data));
165 if ( (argc == 2)
166 && (argv[1][0] == '-')
167 && (argv[1][1] == 'h')
168 && (argv[1][2] == '\0'))
170 help();
171 return 0;
174 if (geteuid() != 0) {
175 fprintf(stderr, "%s must be installed suid root\n", progname);
176 exit(1);
179 if (argc < 2)
181 usage();
182 return 1;
185 mount_point = argv[1];
187 argv += 1;
188 argc -= 1;
190 if (sys_stat(mount_point, &st) == -1) {
191 fprintf(stderr, "could not find mount point %s: %s\n",
192 mount_point, strerror(errno));
193 exit(1);
196 if (mount_ok(&st) != 0) {
197 fprintf(stderr, "cannot mount on %s: %s\n",
198 mount_point, strerror(errno));
199 exit(1);
202 data.version = SMB_MOUNT_VERSION;
204 /* getuid() gives us the real uid, who may umount the fs */
205 data.mounted_uid = getuid();
207 data.uid = getuid();
208 data.gid = getgid();
209 um = umask(0);
210 umask(um);
211 data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & ~um;
212 data.dir_mode = 0;
214 if (parse_args(argc, argv, &data, &share_name) != 0) {
215 usage();
216 return -1;
219 if (data.dir_mode == 0) {
220 data.dir_mode = data.file_mode;
221 if ((data.dir_mode & S_IRUSR) != 0)
222 data.dir_mode |= S_IXUSR;
223 if ((data.dir_mode & S_IRGRP) != 0)
224 data.dir_mode |= S_IXGRP;
225 if ((data.dir_mode & S_IROTH) != 0)
226 data.dir_mode |= S_IXOTH;
229 flags = MS_MGC_VAL;
231 if (mount(share_name, mount_point, "smbfs", flags, (char *)&data) < 0)
233 perror("mount error");
234 printf("Please refer to the smbmnt(8) manual page\n");
235 return -1;
238 ment.mnt_fsname = share_name ? share_name : "none";
239 ment.mnt_dir = fullpath(mount_point);
240 ment.mnt_type = "smbfs";
241 ment.mnt_opts = "";
242 ment.mnt_freq = 0;
243 ment.mnt_passno= 0;
245 mount_point = ment.mnt_dir;
247 if (mount_point == NULL)
249 fprintf(stderr, "Mount point too long\n");
250 return -1;
253 if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
255 fprintf(stderr, "Can't get "MOUNTED"~ lock file");
256 return 1;
258 close(fd);
260 if ((mtab = setmntent(MOUNTED, "a+")) == NULL)
262 fprintf(stderr, "Can't open " MOUNTED);
263 return 1;
266 if (addmntent(mtab, &ment) == 1)
268 fprintf(stderr, "Can't write mount entry");
269 return 1;
271 if (fchmod(fileno(mtab), 0644) == -1)
273 fprintf(stderr, "Can't set perms on "MOUNTED);
274 return 1;
276 endmntent(mtab);
278 if (unlink(MOUNTED"~") == -1)
280 fprintf(stderr, "Can't remove "MOUNTED"~");
281 return 1;
284 return 0;