smb_subr.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /*-
  2. * SPDX-License-Identifier: BSD-2-Clause
  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. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  17. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  20. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. * SUCH DAMAGE.
  27. */
  28. #include <sys/param.h>
  29. #include <sys/systm.h>
  30. #include <sys/endian.h>
  31. #include <sys/kernel.h>
  32. #include <sys/malloc.h>
  33. #include <sys/proc.h>
  34. #include <sys/lock.h>
  35. #include <sys/sysctl.h>
  36. #include <sys/socket.h>
  37. #include <sys/signalvar.h>
  38. #include <sys/mbuf.h>
  39. #include <sys/iconv.h>
  40. #include <netsmb/smb.h>
  41. #include <netsmb/smb_conn.h>
  42. #include <netsmb/smb_rq.h>
  43. #include <netsmb/smb_subr.h>
  44. static MALLOC_DEFINE(M_SMBDATA, "SMBDATA", "Misc netsmb data");
  45. static MALLOC_DEFINE(M_SMBSTR, "SMBSTR", "netsmb string data");
  46. MALLOC_DEFINE(M_SMBTEMP, "SMBTEMP", "Temp netsmb data");
  47. smb_unichar smb_unieol = 0;
  48. void
  49. smb_makescred(struct smb_cred *scred, struct thread *td, struct ucred *cred)
  50. {
  51. if (td) {
  52. scred->scr_td = td;
  53. scred->scr_cred = cred ? cred : td->td_ucred;
  54. } else {
  55. scred->scr_td = NULL;
  56. scred->scr_cred = cred ? cred : NULL;
  57. }
  58. }
  59. int
  60. smb_td_intr(struct thread *td)
  61. {
  62. struct proc *p;
  63. sigset_t tmpset;
  64. if (td == NULL)
  65. return 0;
  66. p = td->td_proc;
  67. PROC_LOCK(p);
  68. tmpset = p->p_siglist;
  69. SIGSETOR(tmpset, td->td_siglist);
  70. SIGSETNAND(tmpset, td->td_sigmask);
  71. mtx_lock(&p->p_sigacts->ps_mtx);
  72. SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore);
  73. mtx_unlock(&p->p_sigacts->ps_mtx);
  74. if (SIGNOTEMPTY(td->td_siglist) && SMB_SIGMASK(tmpset)) {
  75. PROC_UNLOCK(p);
  76. return EINTR;
  77. }
  78. PROC_UNLOCK(p);
  79. return 0;
  80. }
  81. char *
  82. smb_strdup(const char *s)
  83. {
  84. char *p;
  85. size_t len;
  86. len = s ? strlen(s) + 1 : 1;
  87. p = malloc(len, M_SMBSTR, M_WAITOK);
  88. if (s)
  89. bcopy(s, p, len);
  90. else
  91. *p = 0;
  92. return p;
  93. }
  94. /*
  95. * duplicate string from a user space.
  96. */
  97. char *
  98. smb_strdupin(char *s, size_t maxlen)
  99. {
  100. char *p;
  101. int error;
  102. p = malloc(maxlen + 1, M_SMBSTR, M_WAITOK);
  103. error = copyinstr(s, p, maxlen + 1, NULL);
  104. if (error) {
  105. free(p, M_SMBSTR);
  106. return (NULL);
  107. }
  108. return p;
  109. }
  110. /*
  111. * duplicate memory block from a user space.
  112. */
  113. void *
  114. smb_memdupin(void *umem, size_t len)
  115. {
  116. char *p;
  117. if (len > 8 * 1024)
  118. return NULL;
  119. p = malloc(len, M_SMBSTR, M_WAITOK);
  120. if (copyin(umem, p, len) == 0)
  121. return p;
  122. free(p, M_SMBSTR);
  123. return NULL;
  124. }
  125. /*
  126. * duplicate memory block in the kernel space.
  127. */
  128. void *
  129. smb_memdup(const void *umem, int len)
  130. {
  131. char *p;
  132. if (len > 8 * 1024)
  133. return NULL;
  134. p = malloc(len, M_SMBSTR, M_WAITOK);
  135. if (p == NULL)
  136. return NULL;
  137. bcopy(umem, p, len);
  138. return p;
  139. }
  140. void
  141. smb_strfree(char *s)
  142. {
  143. free(s, M_SMBSTR);
  144. }
  145. void
  146. smb_memfree(void *s)
  147. {
  148. free(s, M_SMBSTR);
  149. }
  150. void *
  151. smb_zmalloc(size_t size, struct malloc_type *type, int flags)
  152. {
  153. return malloc(size, type, flags | M_ZERO);
  154. }
  155. void
  156. smb_strtouni(u_int16_t *dst, const char *src)
  157. {
  158. while (*src) {
  159. *dst++ = htole16(*src++);
  160. }
  161. *dst = 0;
  162. }
  163. #ifdef SMB_SOCKETDATA_DEBUG
  164. void
  165. m_dumpm(struct mbuf *m) {
  166. char *p;
  167. size_t len;
  168. printf("d=");
  169. while(m) {
  170. p=mtod(m,char *);
  171. len=m->m_len;
  172. printf("(%zu)",len);
  173. while(len--){
  174. printf("%02x ",((int)*(p++)) & 0xff);
  175. }
  176. m=m->m_next;
  177. }
  178. printf("\n");
  179. }
  180. #endif
  181. int
  182. smb_maperror(int eclass, int eno)
  183. {
  184. if (eclass == 0 && eno == 0)
  185. return 0;
  186. switch (eclass) {
  187. case ERRDOS:
  188. switch (eno) {
  189. case ERRbadfunc:
  190. case ERRbadmcb:
  191. case ERRbadenv:
  192. case ERRbadformat:
  193. case ERRrmuns:
  194. return EINVAL;
  195. case ERRbadfile:
  196. case ERRbadpath:
  197. case ERRremcd:
  198. case 66: /* nt returns it when share not available */
  199. case 67: /* observed from nt4sp6 when sharename wrong */
  200. return ENOENT;
  201. case ERRnofids:
  202. return EMFILE;
  203. case ERRnoaccess:
  204. case ERRbadshare:
  205. return EACCES;
  206. case ERRbadfid:
  207. return EBADF;
  208. case ERRnomem:
  209. return ENOMEM; /* actually remote no mem... */
  210. case ERRbadmem:
  211. return EFAULT;
  212. case ERRbadaccess:
  213. return EACCES;
  214. case ERRbaddata:
  215. return E2BIG;
  216. case ERRbaddrive:
  217. case ERRnotready: /* nt */
  218. return ENXIO;
  219. case ERRdiffdevice:
  220. return EXDEV;
  221. case ERRnofiles:
  222. return 0; /* eeof ? */
  223. return ETXTBSY;
  224. case ERRlock:
  225. return EDEADLK;
  226. case ERRfilexists:
  227. return EEXIST;
  228. case 123: /* dunno what is it, but samba maps as noent */
  229. return ENOENT;
  230. case 145: /* samba */
  231. return ENOTEMPTY;
  232. case ERRnotlocked:
  233. return 0; /* file become unlocked */
  234. case 183:
  235. return EEXIST;
  236. case ERRquota:
  237. return EDQUOT;
  238. }
  239. break;
  240. case ERRSRV:
  241. switch (eno) {
  242. case ERRerror:
  243. return EINVAL;
  244. case ERRbadpw:
  245. case ERRpasswordExpired:
  246. return EAUTH;
  247. case ERRaccess:
  248. return EACCES;
  249. case ERRinvnid:
  250. return ENETRESET;
  251. case ERRinvnetname:
  252. SMBERROR("NetBIOS name is invalid\n");
  253. return EAUTH;
  254. case 3: /* reserved and returned */
  255. return EIO;
  256. case ERRaccountExpired:
  257. case ERRbadClient:
  258. case ERRbadLogonTime:
  259. return EPERM;
  260. case ERRnosupport:
  261. return EBADRPC;
  262. }
  263. break;
  264. case ERRHRD:
  265. switch (eno) {
  266. case ERRnowrite:
  267. return EROFS;
  268. case ERRbadunit:
  269. return ENODEV;
  270. case ERRnotready:
  271. case ERRbadcmd:
  272. case ERRdata:
  273. return EIO;
  274. case ERRbadreq:
  275. return EBADRPC;
  276. case ERRbadshare:
  277. return ETXTBSY;
  278. case ERRlock:
  279. return EDEADLK;
  280. }
  281. break;
  282. }
  283. SMBERROR("Unmapped error %d:%d\n", eclass, eno);
  284. return EBADRPC;
  285. }
  286. static int
  287. smb_copy_iconv(struct mbchain *mbp, c_caddr_t src, caddr_t dst,
  288. size_t *srclen, size_t *dstlen)
  289. {
  290. int error;
  291. size_t inlen = *srclen, outlen = *dstlen;
  292. error = iconv_conv((struct iconv_drv*)mbp->mb_udata, &src, &inlen,
  293. &dst, &outlen);
  294. if (inlen != *srclen || outlen != *dstlen) {
  295. *srclen -= inlen;
  296. *dstlen -= outlen;
  297. return 0;
  298. } else
  299. return error;
  300. }
  301. int
  302. smb_put_dmem(struct mbchain *mbp, struct smb_vc *vcp, const char *src,
  303. size_t size, int caseopt)
  304. {
  305. struct iconv_drv *dp = vcp->vc_toserver;
  306. if (size == 0)
  307. return 0;
  308. if (dp == NULL) {
  309. return mb_put_mem(mbp, src, size, MB_MSYSTEM);
  310. }
  311. mbp->mb_copy = smb_copy_iconv;
  312. mbp->mb_udata = dp;
  313. if (SMB_UNICODE_STRINGS(vcp))
  314. mb_put_padbyte(mbp);
  315. return mb_put_mem(mbp, src, size, MB_MCUSTOM);
  316. }
  317. int
  318. smb_put_dstring(struct mbchain *mbp, struct smb_vc *vcp, const char *src,
  319. int caseopt)
  320. {
  321. int error;
  322. error = smb_put_dmem(mbp, vcp, src, strlen(src), caseopt);
  323. if (error)
  324. return error;
  325. if (SMB_UNICODE_STRINGS(vcp))
  326. return mb_put_uint16le(mbp, 0);
  327. return mb_put_uint8(mbp, 0);
  328. }
  329. int
  330. smb_put_asunistring(struct smb_rq *rqp, const char *src)
  331. {
  332. struct mbchain *mbp = &rqp->sr_rq;
  333. struct iconv_drv *dp = rqp->sr_vc->vc_toserver;
  334. u_char c;
  335. int error;
  336. while (*src) {
  337. iconv_convmem(dp, &c, src++, 1);
  338. error = mb_put_uint16le(mbp, c);
  339. if (error)
  340. return error;
  341. }
  342. return mb_put_uint16le(mbp, 0);
  343. }