No empty .Rs/.Re
[netbsd-mini2440.git] / sys / netsmb / smb_subr.c
blobc265b28d17d40a81645202a9c8252f8de299d69c
1 /* $NetBSD: smb_subr.c,v 1.33 2009/03/18 17:06:53 cegger Exp $ */
3 /*
4 * Copyright (c) 2000-2001 Boris Popov
5 * All rights reserved.
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.
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.
34 * FreeBSD: src/sys/netsmb/smb_subr.c,v 1.6 2002/04/17 03:14:28 bp Exp
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: smb_subr.c,v 1.33 2009/03/18 17:06:53 cegger Exp $");
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>
54 #include <netsmb/iconv.h>
56 #include <netsmb/smb.h>
57 #include <netsmb/smb_conn.h>
58 #include <netsmb/smb_rq.h>
59 #include <netsmb/smb_subr.h>
61 const smb_unichar smb_unieol = 0;
63 static MALLOC_DEFINE(M_SMBSTR, "smbstr", "SMB strings");
64 MALLOC_DEFINE(M_SMBTEMP, "smbtemp", "Temp netsmb data");
66 void
67 smb_makescred(struct smb_cred *scred, struct lwp *l, kauth_cred_t cred)
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;
78 int
79 smb_proc_intr(struct lwp *l)
81 struct proc *p;
82 int error;
84 if (l == NULL)
85 return 0;
86 p = l->l_proc;
88 mutex_enter(p->p_lock);
89 error = sigispending(l, 0);
90 mutex_exit(p->p_lock);
92 return (error != 0 ? EINTR : 0);
95 char *
96 smb_strdup(const char *s)
98 char *p;
99 int len;
101 len = s ? strlen(s) + 1 : 1;
102 p = malloc(len, M_SMBSTR, M_WAITOK);
103 if (s)
104 memcpy(p, s, len);
105 else
106 *p = 0;
107 return p;
111 * duplicate string from a user space.
113 char *
114 smb_strdupin(char *s, int maxlen)
116 char *p, bt;
117 int len = 0;
119 for (p = s; ;p++) {
120 if (copyin(p, &bt, 1))
121 return NULL;
122 len++;
123 if (maxlen && len > maxlen)
124 return NULL;
125 if (bt == 0)
126 break;
128 p = malloc(len, M_SMBSTR, M_WAITOK);
129 copyin(s, p, len);
130 return p;
134 * duplicate memory block from a user space.
136 void *
137 smb_memdupin(void *umem, int len)
139 char *p;
141 if (len > 8 * 1024)
142 return NULL;
143 p = malloc(len, M_SMBSTR, M_WAITOK);
144 if (copyin(umem, p, len) == 0)
145 return p;
146 free(p, M_SMBSTR);
147 return NULL;
150 void
151 smb_strfree(char *s)
153 free(s, M_SMBSTR);
156 void
157 smb_memfree(void *s)
159 free(s, M_SMBSTR);
162 void *
163 smb_zmalloc(unsigned long size, struct malloc_type *type, int flags)
166 return malloc(size, type, flags | M_ZERO);
169 void
170 smb_strtouni(u_int16_t *dst, const char *src)
172 while (*src) {
173 *dst++ = htole16(*src++);
175 *dst = 0;
178 #ifdef SMB_SOCKETDATA_DEBUG
179 void
180 m_dumpm(struct mbuf *m) {
181 char *p;
182 int len;
183 printf("d=");
184 while(m) {
185 p=mtod(m,char *);
186 len=m->m_len;
187 printf("(%d)",len);
188 while(len--){
189 printf("%02x ",((int)*(p++)) & 0xff);
191 m=m->m_next;
193 printf("\n");
195 #endif
198 smb_maperror(int eclass, int eno)
200 if (eclass == 0 && eno == 0)
201 return 0;
202 switch (eclass) {
203 case ERRDOS:
204 switch (eno) {
205 case ERRbadfunc:
206 case ERRbadmcb:
207 case ERRbadenv:
208 case ERRbadformat:
209 case ERRrmuns:
210 return EINVAL;
211 case ERRnofiles:
212 case ERRbadfile:
213 case ERRbadpath:
214 case ERRremcd:
215 case ERRnoipc: /* nt returns it when share not available */
216 case ERRnosuchshare: /* observed from nt4sp6 when sharename wrong */
217 return ENOENT;
218 case ERRnofids:
219 return EMFILE;
220 case ERRnoaccess:
221 case ERRbadshare:
222 return EACCES;
223 case ERRbadfid:
224 return EBADF;
225 case ERRnomem:
226 return ENOMEM; /* actually remote no mem... */
227 case ERRbadmem:
228 return EFAULT;
229 case ERRbadaccess:
230 return EACCES;
231 case ERRbaddata:
232 return E2BIG;
233 case ERRbaddrive:
234 case ERRnotready: /* nt */
235 return ENXIO;
236 case ERRdiffdevice:
237 return EXDEV;
238 case ERRlock:
239 return EDEADLK;
240 case ERRfilexists:
241 return EEXIST;
242 case ERRinvalidname: /* dunno what is it, but samba maps as noent */
243 return ENOENT;
244 case ERRdirnempty: /* samba */
245 return ENOTEMPTY;
246 case ERRrename:
247 return EEXIST;
248 case ERRquota:
249 return EDQUOT;
250 case ERRnotlocked:
251 /* it's okay to try to unlock already unlocked file */
252 return 0;
253 case NT_STATUS_NOTIFY_ENUM_DIR:
254 return EMSGSIZE;
256 break;
257 case ERRSRV:
258 switch (eno) {
259 case ERRerror:
260 return EINVAL;
261 case ERRbadpw:
262 case ERRpasswordExpired:
263 case ERRbaduid:
264 return EAUTH;
265 case ERRaccess:
266 return EACCES;
267 case ERRinvnid:
268 return ENETRESET;
269 case ERRinvnetname:
270 SMBERROR(("NetBIOS name is invalid\n"));
271 return EAUTH;
272 case ERRbadtype: /* reserved and returned */
273 return EIO;
274 case ERRaccountExpired:
275 case ERRbadClient:
276 case ERRbadLogonTime:
277 return EPERM;
278 case ERRnosupport:
279 return EBADRPC;
281 break;
282 case ERRHRD:
283 switch (eno) {
284 case ERRnowrite:
285 return EROFS;
286 case ERRbadunit:
287 return ENODEV;
288 case ERRnotready:
289 case ERRbadcmd:
290 case ERRdata:
291 return EIO;
292 case ERRbadreq:
293 return EBADRPC;
294 case ERRbadshare:
295 return ETXTBSY;
296 case ERRlock:
297 return EDEADLK;
298 case ERRgeneral:
299 /* returned e.g. for NT CANCEL SMB by Samba */
300 return ECANCELED;
302 break;
304 SMBERROR(("Unmapped error %d:%d\n", eclass, eno));
305 return EBADRPC;
308 static int
309 smb_copy_iconv(struct mbchain *mbp, const char *src, char *dst, size_t len)
311 size_t outlen = len;
313 return iconv_conv((struct iconv_drv*)mbp->mb_udata, &src, &len, &dst, &outlen);
317 smb_put_dmem(struct mbchain *mbp, struct smb_vc *vcp, const char *src,
318 int size, int caseopt)
320 struct iconv_drv *dp = vcp->vc_toserver;
322 if (size == 0)
323 return 0;
324 if (dp == NULL) {
325 return mb_put_mem(mbp, (const void *)src, size, MB_MSYSTEM);
327 mbp->mb_copy = smb_copy_iconv;
328 mbp->mb_udata = dp;
329 return mb_put_mem(mbp, (const void *)src, size, MB_MCUSTOM);
333 smb_put_dstring(struct mbchain *mbp, struct smb_vc *vcp, const char *src,
334 int caseopt)
336 int error;
338 error = smb_put_dmem(mbp, vcp, src, strlen(src), caseopt);
339 if (error)
340 return error;
341 return mb_put_uint8(mbp, 0);
344 #if 0
346 smb_put_asunistring(struct smb_rq *rqp, const char *src)
348 struct mbchain *mbp = &rqp->sr_rq;
349 struct iconv_drv *dp = rqp->sr_vc->vc_toserver;
350 u_char c;
351 int error;
353 while (*src) {
354 iconv_convmem(dp, &c, src++, 1);
355 error = mb_put_uint16le(mbp, c);
356 if (error)
357 return error;
359 return mb_put_uint16le(mbp, 0);
361 #endif
363 struct sockaddr *
364 dup_sockaddr(struct sockaddr *sa, int canwait)
366 struct sockaddr *sa2;
368 sa2 = malloc(sa->sa_len, M_SONAME, canwait ? M_WAITOK : M_NOWAIT);
369 if (sa2)
370 memcpy(sa2, sa, sa->sa_len);
371 return sa2;