2 * Copyright (c) 2000-2001 Boris Popov
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Boris Popov.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * $FreeBSD: src/sys/netsmb/smb_usr.c,v 1.1.2.1 2001/05/22 08:32:34 bp Exp $
33 * $DragonFly: src/sys/netproto/smb/smb_usr.c,v 1.4 2006/11/26 19:12:25 pavalos Exp $
35 #include <sys/param.h>
36 #include <sys/malloc.h>
37 #include <sys/kernel.h>
38 #include <sys/systm.h>
41 #include <sys/fcntl.h>
42 #include <sys/socket.h>
43 #include <sys/socketvar.h>
44 #include <sys/sysctl.h>
46 #include <sys/iconv.h>
55 * helpers for nsmb device. Can be moved to the smb_dev.c file.
57 static void smb_usr_vcspec_free(struct smb_vcspec
*spec
);
60 smb_usr_vc2spec(struct smbioc_ossn
*dp
, struct smb_vcspec
*spec
)
64 bzero(spec
, sizeof(*spec
));
65 if (dp
->ioc_user
[0] == 0)
67 if (dp
->ioc_server
== NULL
)
69 if (dp
->ioc_localcs
[0] == 0) {
70 SMBERROR("no local charset ?\n");
74 spec
->sap
= smb_memdupin(dp
->ioc_server
, dp
->ioc_svlen
);
75 if (spec
->sap
== NULL
)
78 spec
->lap
= smb_memdupin(dp
->ioc_local
, dp
->ioc_lolen
);
79 if (spec
->lap
== NULL
) {
80 smb_usr_vcspec_free(spec
);
84 spec
->srvname
= dp
->ioc_srvname
;
85 spec
->pass
= dp
->ioc_password
;
86 spec
->domain
= dp
->ioc_workgroup
;
87 spec
->username
= dp
->ioc_user
;
88 spec
->mode
= dp
->ioc_mode
;
89 spec
->rights
= dp
->ioc_rights
;
90 spec
->owner
= dp
->ioc_owner
;
91 spec
->group
= dp
->ioc_group
;
92 spec
->localcs
= dp
->ioc_localcs
;
93 spec
->servercs
= dp
->ioc_servercs
;
94 if (dp
->ioc_opt
& SMBVOPT_PRIVATE
)
95 flags
|= SMBV_PRIVATE
;
96 if (dp
->ioc_opt
& SMBVOPT_SINGLESHARE
)
97 flags
|= SMBV_PRIVATE
| SMBV_SINGLESHARE
;
103 smb_usr_vcspec_free(struct smb_vcspec
*spec
)
106 smb_memfree(spec
->sap
);
108 smb_memfree(spec
->lap
);
112 smb_usr_share2spec(struct smbioc_oshare
*dp
, struct smb_sharespec
*spec
)
114 bzero(spec
, sizeof(*spec
));
115 spec
->mode
= dp
->ioc_mode
;
116 spec
->rights
= dp
->ioc_rights
;
117 spec
->owner
= dp
->ioc_owner
;
118 spec
->group
= dp
->ioc_group
;
119 spec
->name
= dp
->ioc_share
;
120 spec
->stype
= dp
->ioc_stype
;
121 spec
->pass
= dp
->ioc_password
;
126 smb_usr_lookup(struct smbioc_lookup
*dp
, struct smb_cred
*scred
,
127 struct smb_vc
**vcpp
, struct smb_share
**sspp
)
129 struct smb_vc
*vcp
= NULL
;
130 struct smb_vcspec vspec
;
131 struct smb_sharespec sspec
, *sspecp
= NULL
;
134 if (dp
->ioc_level
< SMBL_VC
|| dp
->ioc_level
> SMBL_SHARE
)
136 error
= smb_usr_vc2spec(&dp
->ioc_ssn
, &vspec
);
139 if (dp
->ioc_flags
& SMBLK_CREATE
)
140 vspec
.flags
|= SMBV_CREATE
;
142 if (dp
->ioc_level
>= SMBL_SHARE
) {
143 error
= smb_usr_share2spec(&dp
->ioc_sh
, &sspec
);
148 error
= smb_sm_lookup(&vspec
, sspecp
, scred
, &vcp
);
154 smb_usr_vcspec_free(&vspec
);
159 * Connect to the resource specified by smbioc_ossn structure.
160 * It may either find an existing connection or try to establish a new one.
161 * If no errors occured smb_vc returned locked and referenced.
164 smb_usr_opensession(struct smbioc_ossn
*dp
, struct smb_cred
*scred
,
165 struct smb_vc
**vcpp
)
167 struct smb_vc
*vcp
= NULL
;
168 struct smb_vcspec vspec
;
171 error
= smb_usr_vc2spec(dp
, &vspec
);
174 if (dp
->ioc_opt
& SMBVOPT_CREATE
)
175 vspec
.flags
|= SMBV_CREATE
;
177 error
= smb_sm_lookup(&vspec
, NULL
, scred
, &vcp
);
178 smb_usr_vcspec_free(&vspec
);
183 smb_usr_openshare(struct smb_vc
*vcp
, struct smbioc_oshare
*dp
,
184 struct smb_cred
*scred
, struct smb_share
**sspp
)
186 struct smb_share
*ssp
;
187 struct smb_sharespec shspec
;
190 error
= smb_usr_share2spec(dp
, &shspec
);
193 error
= smb_vc_lookupshare(vcp
, &shspec
, scred
, &ssp
);
198 if ((dp
->ioc_opt
& SMBSOPT_CREATE
) == 0)
200 error
= smb_share_create(vcp
, &shspec
, scred
, &ssp
);
203 error
= smb_smb_treeconnect(ssp
, scred
);
205 smb_share_put(ssp
, scred
);
212 smb_usr_simplerequest(struct smb_share
*ssp
, struct smbioc_rq
*dp
,
213 struct smb_cred
*scred
)
215 struct smb_rq rq
, *rqp
= &rq
;
222 switch (dp
->ioc_cmd
) {
223 case SMB_COM_TRANSACTION2
:
224 case SMB_COM_TRANSACTION2_SECONDARY
:
225 case SMB_COM_CLOSE_AND_TREE_DISC
:
226 case SMB_COM_TREE_CONNECT
:
227 case SMB_COM_TREE_DISCONNECT
:
228 case SMB_COM_NEGOTIATE
:
229 case SMB_COM_SESSION_SETUP_ANDX
:
230 case SMB_COM_LOGOFF_ANDX
:
231 case SMB_COM_TREE_CONNECT_ANDX
:
234 error
= smb_rq_init(rqp
, SSTOCP(ssp
), dp
->ioc_cmd
, scred
);
239 error
= mb_put_mem(mbp
, dp
->ioc_twords
, dp
->ioc_twc
* 2, MB_MUSER
);
244 error
= mb_put_mem(mbp
, dp
->ioc_tbytes
, dp
->ioc_tbc
, MB_MUSER
);
248 error
= smb_rq_simple(rqp
);
252 md_get_uint8(mdp
, &wc
);
255 if (wc
> dp
->ioc_rpbufsz
) {
259 error
= md_get_mem(mdp
, dp
->ioc_rpbuf
, wc
, MB_MUSER
);
262 md_get_uint16le(mdp
, &bc
);
263 if ((wc
+ bc
) > dp
->ioc_rpbufsz
) {
268 error
= md_get_mem(mdp
, dp
->ioc_rpbuf
+ wc
, bc
, MB_MUSER
);
270 dp
->ioc_errclass
= rqp
->sr_errclass
;
271 dp
->ioc_serror
= rqp
->sr_serror
;
272 dp
->ioc_error
= rqp
->sr_error
;
279 smb_cpdatain(struct mbchain
*mbp
, int len
, caddr_t data
)
285 error
= mb_init(mbp
);
288 return mb_put_mem(mbp
, data
, len
, MB_MUSER
);
292 smb_usr_t2request(struct smb_share
*ssp
, struct smbioc_t2rq
*dp
,
293 struct smb_cred
*scred
)
295 struct smb_t2rq t2
, *t2p
= &t2
;
299 if (dp
->ioc_setupcnt
> 3)
301 error
= smb_t2_init(t2p
, SSTOCP(ssp
), dp
->ioc_setup
[0], scred
);
304 len
= t2p
->t2_setupcount
= dp
->ioc_setupcnt
;
306 t2p
->t2_setupdata
= dp
->ioc_setup
;
308 t2p
->t_name
= smb_strdupin(dp
->ioc_name
, 128);
309 if (t2p
->t_name
== NULL
) {
314 t2p
->t2_maxscount
= 0;
315 t2p
->t2_maxpcount
= dp
->ioc_rparamcnt
;
316 t2p
->t2_maxdcount
= dp
->ioc_rdatacnt
;
317 error
= smb_cpdatain(&t2p
->t2_tparam
, dp
->ioc_tparamcnt
, dp
->ioc_tparam
);
320 error
= smb_cpdatain(&t2p
->t2_tdata
, dp
->ioc_tdatacnt
, dp
->ioc_tdata
);
323 error
= smb_t2_request(t2p
);
326 mdp
= &t2p
->t2_rparam
;
328 len
= m_fixhdr(mdp
->md_top
);
329 if (len
> dp
->ioc_rparamcnt
) {
333 dp
->ioc_rparamcnt
= len
;
334 error
= md_get_mem(mdp
, dp
->ioc_rparam
, len
, MB_MUSER
);
338 dp
->ioc_rparamcnt
= 0;
339 mdp
= &t2p
->t2_rdata
;
341 len
= m_fixhdr(mdp
->md_top
);
342 if (len
> dp
->ioc_rdatacnt
) {
346 dp
->ioc_rdatacnt
= len
;
347 error
= md_get_mem(mdp
, dp
->ioc_rdata
, len
, MB_MUSER
);
349 dp
->ioc_rdatacnt
= 0;
352 smb_strfree(t2p
->t_name
);