Ok - this is the 64 bit widening check in. It changes the configure
[kai/samba-autobuild/.git] / source / client / smbmnt.c
1 /*
2  *  smbmount.c
3  *
4  *  Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke
5  *
6  */
7
8 #include <stdio.h>
9 #include <string.h>
10 #include <signal.h>
11 #include <pwd.h>
12 #include <grp.h>
13 #include <sys/socket.h>
14 #include <sys/param.h>
15 #include <netinet/in.h>
16 #include <netdb.h>
17 #include <sys/stat.h>
18 #include <sys/types.h>
19 /* #include <sys/wait.h> */  /* generates a warning here */
20 extern pid_t waitpid(pid_t, int *, int);
21 #include <sys/errno.h>
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <ctype.h>
26 #include <stdlib.h>
27 #include <sys/mount.h>
28 #include <mntent.h>
29
30 #include <linux/fs.h>
31 #include <linux/smb.h>
32 #include <linux/smb_mount.h>
33
34 #include <asm/unistd.h>
35
36 static char *progname;
37
38
39 static void
40 usage(void)
41 {
42         printf("usage: %s mount-point [options]\n", progname);
43         printf("Try `%s -h' for more information\n", progname);
44 }
45
46 static void
47 help(void)
48 {
49         printf("\n");
50         printf("usage: %s mount-point [options]\n", progname);
51         printf("-u uid         uid the mounted files get\n"
52                "-g gid         gid the mounted files get\n"
53                "-f mode        permission the files get (octal notation)\n"
54                "-d mode        permission the dirs get (octal notation)\n"
55                "-P pid         connection handler's pid\n\n"
56                "-s share       share name on server\n\n"
57                "-h             print this help text\n");
58 }
59
60 static int
61 parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share)
62 {
63         int opt;
64         struct passwd *pwd;
65         struct group  *grp;
66
67         while ((opt = getopt (argc, argv, "u:g:f:d:s:")) != EOF)
68         {
69                 switch (opt)
70                 {
71                 case 'u':
72                         if (isdigit(optarg[0]))
73                         {
74                                 data->uid = atoi(optarg);
75                         }
76                         else
77                         {
78                                 pwd = getpwnam(optarg);
79                                 if (pwd == NULL)
80                                 {
81                                         fprintf(stderr, "Unknown user: %s\n",
82                                                 optarg);
83                                         return 1;
84                                 }
85                                 data->uid = pwd->pw_uid;
86                         }
87                         break;
88                 case 'g':
89                         if (isdigit(optarg[0]))
90                         {
91                                 data->gid = atoi(optarg);
92                         }
93                         else
94                         {
95                                 grp = getgrnam(optarg);
96                                 if (grp == NULL)
97                                 {
98                                         fprintf(stderr, "Unknown group: %s\n",
99                                                 optarg);
100                                         return 1;
101                                 }
102                                 data->gid = grp->gr_gid;
103                         }
104                         break;
105                 case 'f':
106                         data->file_mode = strtol(optarg, NULL, 8);
107                         break;
108                 case 'd':
109                         data->dir_mode = strtol(optarg, NULL, 8);
110                         break;
111                 case 's':
112                         *share = optarg;
113                         break;
114                 default:
115                         return -1;
116                 }
117         }
118         return 0;
119         
120 }
121
122 static char *
123 fullpath(const char *p)
124 {
125         char path[MAXPATHLEN];
126
127         if (strlen(p) > MAXPATHLEN-1)
128         {
129                 return NULL;
130         }
131
132         if (realpath(p, path) == NULL)
133         {
134                 return strdup(p);
135         }
136         return strdup(path);
137 }
138
139 /* Check whether user is allowed to mount on the specified mount point */
140 static int
141 mount_ok(SMB_STRUCT_STAT *st)
142 {
143         if (!S_ISDIR(st->st_mode))
144         {
145                 errno = ENOTDIR;
146                 return -1;
147         }
148         
149         if (   (getuid() != 0)
150             && (   (getuid() != st->st_uid)
151                 || ((st->st_mode & S_IRWXU) != S_IRWXU)))
152         {
153                 errno = EPERM;
154                 return -1;
155         }
156
157         return 0;
158 }
159
160 int 
161 main(int argc, char *argv[])
162 {
163         char *mount_point, *share_name = NULL;
164         FILE *mtab;
165         int fd, um;
166         unsigned int flags;
167         struct smb_mount_data data;
168         SMB_STRUCT_STAT st;
169         struct mntent ment;
170
171         progname = argv[0];
172
173         memset(&data, 0, sizeof(struct smb_mount_data));
174
175         if (   (argc == 2)
176                && (argv[1][0] == '-')
177                && (argv[1][1] == 'h')
178                && (argv[1][2] == '\0'))
179         {
180                 help();
181                 return 0;
182         }
183
184         if (geteuid() != 0) {
185                 fprintf(stderr, "%s must be installed suid root\n", progname);
186                 exit(1);
187         }
188
189         if (argc < 2)
190         {
191                 usage();
192                 return 1;
193         }
194
195         mount_point = argv[1];
196
197         argv += 1;
198         argc -= 1;
199
200         if (sys_stat(mount_point, &st) == -1) {
201                 fprintf(stderr, "could not find mount point %s: %s\n",
202                         mount_point, strerror(errno));
203                 exit(1);
204         }
205
206         if (mount_ok(&st) != 0) {
207                 fprintf(stderr, "cannot mount on %s: %s\n",
208                         mount_point, strerror(errno));
209                 exit(1);
210         }
211
212         data.version = SMB_MOUNT_VERSION;
213
214         /* getuid() gives us the real uid, who may umount the fs */
215         data.mounted_uid = getuid();
216
217         data.uid = getuid();
218         data.gid = getgid();
219         um = umask(0);
220         umask(um);
221         data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & ~um;
222         data.dir_mode  = 0;
223
224         if (parse_args(argc, argv, &data, &share_name) != 0) {
225                 usage();
226                 return -1;
227         }
228
229         if (data.dir_mode == 0) {
230                 data.dir_mode = data.file_mode;
231                 if ((data.dir_mode & S_IRUSR) != 0)
232                         data.dir_mode |= S_IXUSR;
233                 if ((data.dir_mode & S_IRGRP) != 0)
234                         data.dir_mode |= S_IXGRP;
235                 if ((data.dir_mode & S_IROTH) != 0)
236                         data.dir_mode |= S_IXOTH;
237         }
238
239         flags = MS_MGC_VAL;
240
241         if (mount(share_name, mount_point, "smbfs", flags, (char *)&data) < 0)
242         {
243                 perror("mount error");
244                 printf("Please refer to the smbmnt(8) manual page\n");
245                 return -1;
246         }
247
248         ment.mnt_fsname = share_name ? share_name : "none";
249         ment.mnt_dir = fullpath(mount_point);
250         ment.mnt_type = "smbfs";
251         ment.mnt_opts = "";
252         ment.mnt_freq = 0;
253         ment.mnt_passno= 0;
254
255         mount_point = ment.mnt_dir;
256
257         if (mount_point == NULL)
258         {
259                 fprintf(stderr, "Mount point too long\n");
260                 return -1;
261         }
262         
263         if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
264         {
265                 fprintf(stderr, "Can't get "MOUNTED"~ lock file");
266                 return 1;
267         }
268         close(fd);
269         
270         if ((mtab = setmntent(MOUNTED, "a+")) == NULL)
271         {
272                 fprintf(stderr, "Can't open " MOUNTED);
273                 return 1;
274         }
275
276         if (addmntent(mtab, &ment) == 1)
277         {
278                 fprintf(stderr, "Can't write mount entry");
279                 return 1;
280         }
281         if (fchmod(fileno(mtab), 0644) == -1)
282         {
283                 fprintf(stderr, "Can't set perms on "MOUNTED);
284                 return 1;
285         }
286         endmntent(mtab);
287
288         if (unlink(MOUNTED"~") == -1)
289         {
290                 fprintf(stderr, "Can't remove "MOUNTED"~");
291                 return 1;
292         }
293
294         return 0;
295 }