FreeBSD/Linux Kernel Cross Reference
sys/netsmb/smb_subr.c
1 /* $NetBSD: smb_subr.c,v 1.20 2003/09/27 12:24:25 jdolecek Exp $ */
2
3 /*
4 * Copyright (c) 2000-2001 Boris Popov
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
21 *
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
32 * SUCH DAMAGE.
33 *
34 * FreeBSD: src/sys/netsmb/smb_subr.c,v 1.6 2002/04/17 03:14:28 bp Exp
35 */
36
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: smb_subr.c,v 1.20 2003/09/27 12:24:25 jdolecek Exp $");
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/proc.h>
45 #include <sys/lock.h>
46 #include <sys/sysctl.h>
47 #include <sys/socket.h>
48 #include <sys/signal.h>
49 #include <sys/signalvar.h>
50 #include <sys/mbuf.h>
51 #include <sys/socketvar.h> /* for M_SONAME */
52
53 #include <netsmb/iconv.h>
54
55 #include <netsmb/smb.h>
56 #include <netsmb/smb_conn.h>
57 #include <netsmb/smb_rq.h>
58 #include <netsmb/smb_subr.h>
59
60 const smb_unichar smb_unieol = 0;
61
62 static MALLOC_DEFINE(M_SMBSTR, "smbstr", "SMB strings");
63 MALLOC_DEFINE(M_SMBTEMP, "smbtemp", "Temp netsmb data");
64
65 void
66 smb_makescred(struct smb_cred *scred, struct proc *p, struct ucred *cred)
67 {
68 if (p) {
69 scred->scr_p = p;
70 scred->scr_cred = cred ? cred : p->p_ucred;
71 } else {
72 scred->scr_p = NULL;
73 scred->scr_cred = cred ? cred : NULL;
74 }
75 }
76
77 int
78 smb_proc_intr(struct proc *p)
79 {
80 if (p == NULL)
81 return 0;
82 if (!sigemptyset(&p->p_sigctx.ps_siglist)
83 && SMB_SIGMASK(p->p_sigctx.ps_siglist))
84 return EINTR;
85 return 0;
86 }
87
88 char *
89 smb_strdup(const char *s)
90 {
91 char *p;
92 int len;
93
94 len = s ? strlen(s) + 1 : 1;
95 p = malloc(len, M_SMBSTR, M_WAITOK);
96 if (s)
97 bcopy(s, p, len);
98 else
99 *p = 0;
100 return p;
101 }
102
103 /*
104 * duplicate string from a user space.
105 */
106 char *
107 smb_strdupin(char *s, int maxlen)
108 {
109 char *p, bt;
110 int len = 0;
111
112 for (p = s; ;p++) {
113 if (copyin(p, &bt, 1))
114 return NULL;
115 len++;
116 if (maxlen && len > maxlen)
117 return NULL;
118 if (bt == 0)
119 break;
120 }
121 p = malloc(len, M_SMBSTR, M_WAITOK);
122 copyin(s, p, len);
123 return p;
124 }
125
126 /*
127 * duplicate memory block from a user space.
128 */
129 void *
130 smb_memdupin(void *umem, int len)
131 {
132 char *p;
133
134 if (len > 8 * 1024)
135 return NULL;
136 p = malloc(len, M_SMBSTR, M_WAITOK);
137 if (copyin(umem, p, len) == 0)
138 return p;
139 free(p, M_SMBSTR);
140 return NULL;
141 }
142
143 void
144 smb_strfree(char *s)
145 {
146 free(s, M_SMBSTR);
147 }
148
149 void
150 smb_memfree(void *s)
151 {
152 free(s, M_SMBSTR);
153 }
154
155 void *
156 smb_zmalloc(unsigned long size, struct malloc_type *type, int flags)
157 {
158
159 return malloc(size, type, flags | M_ZERO);
160 }
161
162 void
163 smb_strtouni(u_int16_t *dst, const char *src)
164 {
165 while (*src) {
166 *dst++ = htole16(*src++);
167 }
168 *dst = 0;
169 }
170
171 #ifdef SMB_SOCKETDATA_DEBUG
172 void
173 m_dumpm(struct mbuf *m) {
174 char *p;
175 int len;
176 printf("d=");
177 while(m) {
178 p=mtod(m,char *);
179 len=m->m_len;
180 printf("(%d)",len);
181 while(len--){
182 printf("%02x ",((int)*(p++)) & 0xff);
183 }
184 m=m->m_next;
185 };
186 printf("\n");
187 }
188 #endif
189
190 int
191 smb_maperror(int eclass, int eno)
192 {
193 if (eclass == 0 && eno == 0)
194 return 0;
195 switch (eclass) {
196 case ERRDOS:
197 switch (eno) {
198 case ERRbadfunc:
199 case ERRbadmcb:
200 case ERRbadenv:
201 case ERRbadformat:
202 case ERRrmuns:
203 return EINVAL;
204 case ERRnofiles:
205 case ERRbadfile:
206 case ERRbadpath:
207 case ERRremcd:
208 case ERRnoipc: /* nt returns it when share not available */
209 case ERRnosuchshare: /* observed from nt4sp6 when sharename wrong */
210 return ENOENT;
211 case ERRnofids:
212 return EMFILE;
213 case ERRnoaccess:
214 case ERRbadshare:
215 return EACCES;
216 case ERRbadfid:
217 return EBADF;
218 case ERRnomem:
219 return ENOMEM; /* actually remote no mem... */
220 case ERRbadmem:
221 return EFAULT;
222 case ERRbadaccess:
223 return EACCES;
224 case ERRbaddata:
225 return E2BIG;
226 case ERRbaddrive:
227 case ERRnotready: /* nt */
228 return ENXIO;
229 case ERRdiffdevice:
230 return EXDEV;
231 case ERRlock:
232 return EDEADLK;
233 case ERRfilexists:
234 return EEXIST;
235 case ERRinvalidname: /* dunno what is it, but samba maps as noent */
236 return ENOENT;
237 case ERRdirnempty: /* samba */
238 return ENOTEMPTY;
239 case ERRrename:
240 return EEXIST;
241 case ERRquota:
242 return EDQUOT;
243 case ERRnotlocked:
244 return EBUSY;
245 case NT_STATUS_NOTIFY_ENUM_DIR:
246 return EMSGSIZE;
247 }
248 break;
249 case ERRSRV:
250 switch (eno) {
251 case ERRerror:
252 return EINVAL;
253 case ERRbadpw:
254 case ERRpasswordExpired:
255 case ERRbaduid:
256 return EAUTH;
257 case ERRaccess:
258 return EACCES;
259 case ERRinvnid:
260 return ENETRESET;
261 case ERRinvnetname:
262 SMBERROR("NetBIOS name is invalid\n");
263 return EAUTH;
264 case ERRbadtype: /* reserved and returned */
265 return EIO;
266 case ERRaccountExpired:
267 case ERRbadClient:
268 case ERRbadLogonTime:
269 return EPERM;
270 case ERRnosupport:
271 return EBADRPC;
272 }
273 break;
274 case ERRHRD:
275 switch (eno) {
276 case ERRnowrite:
277 return EROFS;
278 case ERRbadunit:
279 return ENODEV;
280 case ERRnotready:
281 case ERRbadcmd:
282 case ERRdata:
283 return EIO;
284 case ERRbadreq:
285 return EBADRPC;
286 case ERRbadshare:
287 return ETXTBSY;
288 case ERRlock:
289 return EDEADLK;
290 case ERRgeneral:
291 /* returned e.g. for NT CANCEL SMB by Samba */
292 return ECANCELED;
293 }
294 break;
295 }
296 SMBERROR("Unmapped error %d:%d\n", eclass, eno);
297 return EBADRPC;
298 }
299
300 static int
301 smb_copy_iconv(struct mbchain *mbp, const caddr_t src, caddr_t dst, size_t len)
302 {
303 size_t outlen = len;
304
305 return iconv_conv((struct iconv_drv*)mbp->mb_udata, (const char **)(&src), &len, &dst, &outlen);
306 }
307
308 int
309 smb_put_dmem(struct mbchain *mbp, struct smb_vc *vcp, const char *src,
310 int size, int caseopt)
311 {
312 struct iconv_drv *dp = vcp->vc_toserver;
313
314 if (size == 0)
315 return 0;
316 if (dp == NULL) {
317 return mb_put_mem(mbp, (caddr_t)src, size, MB_MSYSTEM);
318 }
319 mbp->mb_copy = smb_copy_iconv;
320 mbp->mb_udata = dp;
321 return mb_put_mem(mbp, (caddr_t)src, size, MB_MCUSTOM);
322 }
323
324 int
325 smb_put_dstring(struct mbchain *mbp, struct smb_vc *vcp, const char *src,
326 int caseopt)
327 {
328 int error;
329
330 error = smb_put_dmem(mbp, vcp, src, strlen(src), caseopt);
331 if (error)
332 return error;
333 return mb_put_uint8(mbp, 0);
334 }
335
336 #if 0
337 int
338 smb_put_asunistring(struct smb_rq *rqp, const char *src)
339 {
340 struct mbchain *mbp = &rqp->sr_rq;
341 struct iconv_drv *dp = rqp->sr_vc->vc_toserver;
342 u_char c;
343 int error;
344
345 while (*src) {
346 iconv_convmem(dp, &c, src++, 1);
347 error = mb_put_uint16le(mbp, c);
348 if (error)
349 return error;
350 }
351 return mb_put_uint16le(mbp, 0);
352 }
353 #endif
354
355 struct sockaddr *
356 dup_sockaddr(struct sockaddr *sa, int canwait)
357 {
358 struct sockaddr *sa2;
359
360 sa2 = malloc(sa->sa_len, M_SONAME, canwait ? M_WAITOK : M_NOWAIT);
361 if (sa2)
362 memcpy(sa2, sa, sa->sa_len);
363 return sa2;
364 }
Cache object: dac195f13e50c6f010825ac541d06cee
|