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