1 /* $NetBSD: smb_usr.c,v 1.15 2008/06/24 10:37:19 gmcgarry Exp $ */
4 * Copyright (c) 2000-2001 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 * FreeBSD: src/sys/netsmb/smb_usr.c,v 1.1 2001/04/10 07:59:06 bp Exp
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: smb_usr.c,v 1.15 2008/06/24 10:37:19 gmcgarry Exp $");
40 #include <sys/param.h>
41 #include <sys/malloc.h>
42 #include <sys/kernel.h>
43 #include <sys/systm.h>
46 #include <sys/fcntl.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
49 #include <sys/sysctl.h>
51 #include <netsmb/iconv.h>
53 #include <netsmb/smb.h>
54 #include <netsmb/smb_conn.h>
55 #include <netsmb/smb_rq.h>
56 #include <netsmb/smb_subr.h>
57 #include <netsmb/smb_dev.h>
60 * helpers for nsmb device. Can be moved to the smb_dev.c file.
62 static void smb_usr_vcspec_free(struct smb_vcspec
*spec
);
65 smb_usr_vc2spec(struct smbioc_ossn
*dp
, struct smb_vcspec
*spec
)
69 memset(spec
, 0, sizeof(*spec
));
70 if (dp
->ioc_user
[0] == 0)
72 if (dp
->ioc_server
== NULL
)
74 if (dp
->ioc_localcs
[0] == 0) {
75 SMBERROR(("no local charset ?\n"));
79 spec
->sap
= smb_memdupin(dp
->ioc_server
, dp
->ioc_svlen
);
80 if (spec
->sap
== NULL
)
83 spec
->lap
= smb_memdupin(dp
->ioc_local
, dp
->ioc_lolen
);
84 if (spec
->lap
== NULL
) {
85 smb_usr_vcspec_free(spec
);
89 spec
->srvname
= dp
->ioc_srvname
;
90 spec
->pass
= dp
->ioc_password
;
91 spec
->domain
= dp
->ioc_workgroup
;
92 spec
->username
= dp
->ioc_user
;
93 spec
->mode
= dp
->ioc_mode
;
94 spec
->rights
= dp
->ioc_rights
;
95 spec
->owner
= dp
->ioc_owner
;
96 spec
->group
= dp
->ioc_group
;
97 spec
->localcs
= dp
->ioc_localcs
;
98 spec
->servercs
= dp
->ioc_servercs
;
99 if (dp
->ioc_opt
& SMBVOPT_PRIVATE
)
100 flags
|= SMBV_PRIVATE
;
101 if (dp
->ioc_opt
& SMBVOPT_SINGLESHARE
)
102 flags
|= SMBV_PRIVATE
| SMBV_SINGLESHARE
;
108 smb_usr_vcspec_free(struct smb_vcspec
*spec
)
111 smb_memfree(spec
->sap
);
113 smb_memfree(spec
->lap
);
117 smb_usr_share2spec(struct smbioc_oshare
*dp
, struct smb_sharespec
*spec
)
119 memset(spec
, 0, sizeof(*spec
));
120 spec
->mode
= dp
->ioc_mode
;
121 spec
->rights
= dp
->ioc_rights
;
122 spec
->owner
= dp
->ioc_owner
;
123 spec
->group
= dp
->ioc_group
;
124 spec
->name
= dp
->ioc_share
;
125 spec
->stype
= dp
->ioc_stype
;
126 spec
->pass
= dp
->ioc_password
;
131 smb_usr_lookup(struct smbioc_lookup
*dp
, struct smb_cred
*scred
,
132 struct smb_vc
**vcpp
, struct smb_share
**sspp
)
134 struct smb_vc
*vcp
= NULL
;
135 struct smb_vcspec vspec
;
136 struct smb_sharespec sspec
, *sspecp
= NULL
;
139 if (dp
->ioc_level
< SMBL_VC
|| dp
->ioc_level
> SMBL_SHARE
)
141 error
= smb_usr_vc2spec(&dp
->ioc_ssn
, &vspec
);
144 if (dp
->ioc_flags
& SMBLK_CREATE
)
145 vspec
.flags
|= SMBV_CREATE
;
147 if (dp
->ioc_level
>= SMBL_SHARE
) {
148 error
= smb_usr_share2spec(&dp
->ioc_sh
, &sspec
);
153 error
= smb_sm_lookup(&vspec
, sspecp
, scred
, &vcp
);
159 smb_usr_vcspec_free(&vspec
);
164 * Connect to the resource specified by smbioc_ossn structure.
165 * It may either find an existing connection or try to establish a new one.
166 * If no errors occurred smb_vc returned locked and referenced.
169 smb_usr_opensession(struct smbioc_ossn
*dp
, struct smb_cred
*scred
,
170 struct smb_vc
**vcpp
)
172 struct smb_vc
*vcp
= NULL
;
173 struct smb_vcspec vspec
;
176 error
= smb_usr_vc2spec(dp
, &vspec
);
179 if (dp
->ioc_opt
& SMBVOPT_CREATE
)
180 vspec
.flags
|= SMBV_CREATE
;
182 error
= smb_sm_lookup(&vspec
, NULL
, scred
, &vcp
);
183 smb_usr_vcspec_free(&vspec
);
188 smb_usr_openshare(struct smb_vc
*vcp
, struct smbioc_oshare
*dp
,
189 struct smb_cred
*scred
, struct smb_share
**sspp
)
191 struct smb_share
*ssp
;
192 struct smb_sharespec shspec
;
195 error
= smb_usr_share2spec(dp
, &shspec
);
198 error
= smb_vc_lookupshare(vcp
, &shspec
, scred
, &ssp
);
203 if ((dp
->ioc_opt
& SMBSOPT_CREATE
) == 0)
205 error
= smb_share_create(vcp
, &shspec
, scred
, &ssp
);
208 error
= smb_smb_treeconnect(ssp
, scred
);
210 smb_share_put(ssp
, scred
);
217 smb_usr_simplerequest(struct smb_share
*ssp
, struct smbioc_rq
*dp
,
218 struct smb_cred
*scred
)
227 switch (dp
->ioc_cmd
) {
228 case SMB_COM_TRANSACTION2
:
229 case SMB_COM_TRANSACTION2_SECONDARY
:
230 case SMB_COM_CLOSE_AND_TREE_DISC
:
231 case SMB_COM_TREE_CONNECT
:
232 case SMB_COM_TREE_DISCONNECT
:
233 case SMB_COM_NEGOTIATE
:
234 case SMB_COM_SESSION_SETUP_ANDX
:
235 case SMB_COM_LOGOFF_ANDX
:
236 case SMB_COM_TREE_CONNECT_ANDX
:
239 error
= smb_rq_alloc(SSTOCP(ssp
), dp
->ioc_cmd
, scred
, &rqp
);
244 error
= mb_put_mem(mbp
, dp
->ioc_twords
, dp
->ioc_twc
* 2, MB_MUSER
);
249 error
= mb_put_mem(mbp
, dp
->ioc_tbytes
, dp
->ioc_tbc
, MB_MUSER
);
253 error
= smb_rq_simple(rqp
);
257 md_get_uint8(mdp
, &wc
);
260 if (wc
> dp
->ioc_rpbufsz
) {
264 error
= md_get_mem(mdp
, dp
->ioc_rpbuf
, wc
, MB_MUSER
);
267 md_get_uint16le(mdp
, &bc
);
268 if ((wc
+ bc
) > dp
->ioc_rpbufsz
) {
273 error
= md_get_mem(mdp
, dp
->ioc_rpbuf
+ wc
, bc
, MB_MUSER
);
281 smb_cpdatain(struct mbchain
*mbp
, int len
, void *data
)
287 error
= mb_init(mbp
);
290 return mb_put_mem(mbp
, data
, len
, MB_MUSER
);
294 smb_usr_t2request(struct smb_share
*ssp
, struct smbioc_t2rq
*dp
,
295 struct smb_cred
*scred
)
297 struct smb_t2rq
*t2p
;
301 if (dp
->ioc_setupcnt
> 3)
303 error
= smb_t2_alloc(SSTOCP(ssp
), dp
->ioc_setup
[0], scred
, &t2p
);
306 len
= t2p
->t2_setupcount
= dp
->ioc_setupcnt
;
308 t2p
->t2_setupdata
= dp
->ioc_setup
;
310 t2p
->t_name
= smb_strdupin(dp
->ioc_name
, 128);
311 if (t2p
->t_name
== NULL
) {
316 t2p
->t2_maxscount
= 0;
317 t2p
->t2_maxpcount
= dp
->ioc_rparamcnt
;
318 t2p
->t2_maxdcount
= dp
->ioc_rdatacnt
;
319 error
= smb_cpdatain(&t2p
->t2_tparam
, dp
->ioc_tparamcnt
, dp
->ioc_tparam
);
322 error
= smb_cpdatain(&t2p
->t2_tdata
, dp
->ioc_tdatacnt
, dp
->ioc_tdata
);
325 error
= smb_t2_request(t2p
);
328 mdp
= &t2p
->t2_rparam
;
330 len
= m_fixhdr(mdp
->md_top
);
331 if (len
> dp
->ioc_rparamcnt
) {
335 dp
->ioc_rparamcnt
= len
;
336 error
= md_get_mem(mdp
, dp
->ioc_rparam
, len
, MB_MUSER
);
340 dp
->ioc_rparamcnt
= 0;
341 mdp
= &t2p
->t2_rdata
;
343 len
= m_fixhdr(mdp
->md_top
);
344 if (len
> dp
->ioc_rdatacnt
) {
348 dp
->ioc_rdatacnt
= len
;
349 error
= md_get_mem(mdp
, dp
->ioc_rdata
, len
, MB_MUSER
);
351 dp
->ioc_rdatacnt
= 0;
354 smb_strfree(t2p
->t_name
);