1 /* $NetBSD: mount_smbfs.c,v 1.10 2009/09/04 18:22:37 pooka Exp $ */
4 * Copyright (c) 2000-2002, Boris Popov
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Boris Popov.
18 * 4. Neither the name of the author nor the names of any co-contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * from: Id: mount_smbfs.c,v 1.17 2002/04/10 04:17:51 bp Exp
37 #include <sys/cdefs.h>
38 __RCSID("$NetBSD: mount_smbfs.c,v 1.10 2009/09/04 18:22:37 pooka Exp $");
40 #include <sys/param.h>
42 #include <sys/errno.h>
43 #include <sys/mount.h>
58 #include <netsmb/smb.h>
59 #include <netsmb/smb_conn.h>
60 #include <netsmb/smb_lib.h>
62 #include <fs/smbfs/smbfs.h>
64 #include "mount_smbfs.h"
68 static void usage(void);
70 static const struct mntopt mopts
[] = {
77 main(int argc
, char *argv
[])
81 return mount_smbfs(argc
, argv
);
87 mount_smbfs_parseargs(int argc
, char *argv
[], struct smbfs_args
*mdatap
,
88 int *mntflagsp
, char *canon_dev
, char *mount_point
)
90 struct smb_ctx
*ctx
= &sctx
;
93 int opt
, error
, caseopt
;
96 if (strcmp(argv
[1], "-h") == 0) {
98 } else if (strcmp(argv
[1], "-v") == 0) {
99 errx(EX_OK
, "version %d.%d.%d", SMBFS_VERSION
/ 100000,
100 (SMBFS_VERSION
% 10000) / 1000,
101 (SMBFS_VERSION
% 1000) / 100);
107 if (smb_lib_init() != 0)
110 *mntflagsp
= error
= 0;
111 memset(mdatap
, 0, sizeof(*mdatap
));
112 mdatap
->uid
= mdatap
->gid
= -1;
113 caseopt
= SMB_CS_NONE
;
115 if (smb_ctx_init(ctx
, argc
, argv
, SMBL_SHARE
, SMBL_SHARE
, SMB_ST_DISK
) != 0)
117 if (smb_ctx_readrc(ctx
) != 0)
122 while ((opt
= getopt(argc
, argv
, STDPARAM_OPT
"c:d:f:g:l:n:o:u:w:")) != -1) {
125 error
= smb_ctx_opt(ctx
, opt
, optarg
);
132 pwd
= isdigit((unsigned char)optarg
[0]) ?
133 getpwuid(atoi(optarg
)) : getpwnam(optarg
);
135 errx(EX_NOUSER
, "unknown user '%s'", optarg
);
136 mdatap
->uid
= pwd
->pw_uid
;
142 grp
= isdigit((unsigned char)optarg
[0]) ?
143 getgrgid(atoi(optarg
)) : getgrnam(optarg
);
145 errx(EX_NOUSER
, "unknown group '%s'", optarg
);
146 mdatap
->gid
= grp
->gr_gid
;
151 mdatap
->dir_mode
= strtol(optarg
, &next
, 8);
152 if (errno
|| *next
!= 0)
153 errx(EX_DATAERR
, "invalid value for directory mode");
157 mdatap
->file_mode
= strtol(optarg
, &next
, 8);
158 if (errno
|| *next
!= 0)
159 errx(EX_DATAERR
, "invalid value for file mode");
168 while ((nsp
= strsep(&inp
, ",;:")) != NULL
) {
169 if (strcasecmp(nsp
, "LONG") == 0)
170 mdatap
->flags
|= SMBFS_MOUNT_NO_LONG
;
172 errx(EX_DATAERR
, "unknown suboption '%s'", nsp
);
177 getmntopts(optarg
, mopts
, mntflagsp
, 0);
182 caseopt
|= SMB_CS_LOWER
;
185 caseopt
|= SMB_CS_UPPER
;
188 errx(EX_DATAERR
, "invalid suboption '%c' for -c",
197 if (optind
== argc
- 2)
200 if (optind
!= argc
- 1)
202 realpath(argv
[optind
], mount_point
);
204 if (stat(mount_point
, &st
) == -1)
205 err(EX_OSERR
, "could not find mount point %s", mount_point
);
206 if (!S_ISDIR(st
.st_mode
)) {
208 err(EX_OSERR
, "can't mount on %s", mount_point
);
211 if (smb_getextattr(mount_point, &einfo) == 0)
212 errx(EX_OSERR, "can't mount on %s twice", mount_point);
214 if (mdatap
->uid
== (uid_t
)-1)
215 mdatap
->uid
= st
.st_uid
;
216 if (mdatap
->gid
== (gid_t
)-1)
217 mdatap
->gid
= st
.st_gid
;
218 if (mdatap
->file_mode
== 0 )
219 mdatap
->file_mode
= st
.st_mode
& (S_IRWXU
| S_IRWXG
| S_IRWXO
);
220 if (mdatap
->dir_mode
== 0) {
221 mdatap
->dir_mode
= mdatap
->file_mode
;
222 if (mdatap
->dir_mode
& S_IRUSR
)
223 mdatap
->dir_mode
|= S_IXUSR
;
224 if (mdatap
->dir_mode
& S_IRGRP
)
225 mdatap
->dir_mode
|= S_IXGRP
;
226 if (mdatap
->dir_mode
& S_IROTH
)
227 mdatap
->dir_mode
|= S_IXOTH
;
230 * For now, let connection be private for this mount
232 ctx
->ct_ssn
.ioc_opt
|= SMBVOPT_PRIVATE
;
234 ctx
->ct_ssn
.ioc_owner
= ctx
->ct_sh
.ioc_owner
= 0; /* root */
236 ctx
->ct_ssn
.ioc_owner
= ctx
->ct_sh
.ioc_owner
= mdatap
->uid
;
237 ctx
->ct_ssn
.ioc_group
= ctx
->ct_sh
.ioc_group
= mdatap
->gid
;
239 if (mdatap
->dir_mode
& S_IXGRP
)
241 if (mdatap
->dir_mode
& S_IXOTH
)
243 ctx
->ct_ssn
.ioc_rights
|= opt
;
244 ctx
->ct_sh
.ioc_rights
|= opt
;
245 error
= smb_ctx_resolve(ctx
);
247 err(1, "resolve %d", error
);
248 error
= smb_ctx_lookup(ctx
, SMBL_SHARE
, SMBLK_CREATE
);
250 err(1, "lookup %d", error
);
252 mdatap
->version
= SMBFS_VERSION
;
253 mdatap
->dev_fd
= ctx
->ct_fd
;
254 mdatap
->caseopt
= caseopt
;
256 snprintf(canon_dev
, MAXPATHLEN
, "//%s@%s/%s",
257 ctx
->ct_ssn
.ioc_user
[0] ? ctx
->ct_ssn
.ioc_user
: "guest",
258 ctx
->ct_ssn
.ioc_srvname
, ctx
->ct_sh
.ioc_share
);
262 mount_smbfs(int argc
, char *argv
[])
264 char canon_dev
[MAXPATHLEN
], canon_dir
[MAXPATHLEN
];
265 struct smbfs_args mdata
;
268 mount_smbfs_parseargs(argc
, argv
, &mdata
, &mntflags
,
269 canon_dev
, canon_dir
);
271 error
= mount(SMBFS_VFSNAME
, canon_dir
, mntflags
,
272 &mdata
, sizeof mdata
);
273 smb_ctx_done(&sctx
); /* XXX */
276 smb_error("mount error for %s: %s", error
, canon_dir
,
286 fprintf(stderr
, "%s\n%s\n%s\n%s\n",
287 "usage: mount_smbfs [-E cs1:cs2] [-I host] [-L locale] [-M crights:srights]",
288 " [-N] [-O cowner:cgroup/sowner:sgroup] [-R retrycount]",
289 " [-T timeout] [-W workgroup] [-c case] [-d mode] [-f mode]",
290 " [-g gid] [-n opt] [-u uid] //user@server/share node");