aquarela.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "headers.h"
  10. #include <pool.h>
  11. static void
  12. disconnecttree(void *magic, void *arg)
  13. {
  14. smbtreedisconnect((SmbSession *)magic, (SmbTree *)arg);
  15. }
  16. static void
  17. closesearch(void *magic, void *arg)
  18. {
  19. smbsearchclose((SmbSession *)magic, (SmbSearch *)arg);
  20. }
  21. static void
  22. smbsessionfree(SmbSession *s)
  23. {
  24. if (s) {
  25. smbidmapfree(&s->tidmap, disconnecttree, s);
  26. smbidmapfree(&s->sidmap, closesearch, s);
  27. smbbufferfree(&s->response);
  28. free(s->client.accountname);
  29. free(s->client.primarydomain);
  30. free(s->client.nativeos);
  31. free(s->client.nativelanman);
  32. free(s->transaction.in.parameters);
  33. free(s->transaction.in.data);
  34. free(s->transaction.in.setup);
  35. free(s->transaction.in.name);
  36. smbbufferfree(&s->transaction.out.parameters);
  37. smbbufferfree(&s->transaction.out.data);
  38. auth_freechal(s->cs);
  39. free(s);
  40. }
  41. }
  42. int
  43. smbsessionwrite(SmbSession *smbs, void *p, int32_t n)
  44. {
  45. SmbHeader h;
  46. SmbOpTableEntry *ote;
  47. uint8_t *pdata;
  48. int rv;
  49. SmbBuffer *b = nil;
  50. uint16_t bytecount;
  51. SmbProcessResult pr;
  52. if (smbs->response == nil)
  53. smbs->response = smbbuffernew(576);
  54. else
  55. smbresponsereset(smbs);
  56. smbs->errclass = SUCCESS;
  57. smbs->error = SUCCESS;
  58. // print("received %ld bytes\n", n);
  59. if (n <= 0)
  60. goto closedown;
  61. b = smbbufferinit(p, p, n);
  62. if (!smbbuffergetheader(b, &h, &pdata, &bytecount)) {
  63. smblogprint(-1, "smb: invalid header\n");
  64. goto closedown;
  65. }
  66. smbloglock();
  67. smblogprint(h.command, "received:\n");
  68. smblogdata(h.command, smblogprint, p, n, 0x1000);
  69. smblogunlock();
  70. ote = smboptable + h.command;
  71. if (ote->name == nil) {
  72. smblogprint(-1, "smb: illegal opcode 0x%.2x\n", h.command);
  73. goto unimp;
  74. }
  75. if (ote->process == nil) {
  76. smblogprint(-1, "smb: opcode %s unimplemented\n", ote->name);
  77. goto unimp;
  78. }
  79. if (smbs->nextcommand != SMB_COM_NO_ANDX_COMMAND
  80. && smbs->nextcommand != h.command) {
  81. smblogprint(-1, "smb: wrong command - expected %.2x\n", smbs->nextcommand);
  82. goto misc;
  83. }
  84. smbs->nextcommand = SMB_COM_NO_ANDX_COMMAND;
  85. switch (h.command) {
  86. case SMB_COM_NEGOTIATE:
  87. case SMB_COM_SESSION_SETUP_ANDX:
  88. case SMB_COM_TREE_CONNECT_ANDX:
  89. case SMB_COM_ECHO:
  90. break;
  91. default:
  92. if (smbs->state != SmbSessionEstablished) {
  93. smblogprint(-1, "aquarela: command %.2x unexpected\n", h.command);
  94. goto unimp;
  95. }
  96. }
  97. pr = (*ote->process)(smbs, &h, pdata, b);
  98. switch (pr) {
  99. case SmbProcessResultUnimp:
  100. unimp:
  101. smbseterror(smbs, ERRDOS, ERRunsup);
  102. pr = SmbProcessResultError;
  103. break;
  104. case SmbProcessResultFormat:
  105. smbseterror(smbs, ERRSRV, ERRsmbcmd);
  106. pr = SmbProcessResultError;
  107. break;
  108. case SmbProcessResultMisc:
  109. misc:
  110. smbseterror(smbs, ERRSRV, ERRerror);
  111. pr = SmbProcessResultError;
  112. break;
  113. case SmbProcessResultOk:
  114. case SmbProcessResultError:
  115. case SmbProcessResultReply:
  116. case SmbProcessResultDie:
  117. break;
  118. }
  119. if (pr == SmbProcessResultError) {
  120. smblogprint(h.command, "reply: error %d/%d\n", smbs->errclass, smbs->error);
  121. if (!smbresponseputerror(smbs, &h, smbs->errclass, smbs->error))
  122. pr = SmbProcessResultDie;
  123. else
  124. pr = SmbProcessResultReply;
  125. }
  126. else
  127. smblogprint(h.command, "reply: ok\n");
  128. if (pr == SmbProcessResultReply)
  129. rv = smbresponsesend(smbs) == SmbProcessResultOk ? 0 : -1;
  130. else if (pr == SmbProcessResultDie)
  131. rv = -1;
  132. else
  133. rv = 0;
  134. goto done;
  135. closedown:
  136. rv = -1;
  137. done:
  138. if (rv < 0) {
  139. smblogprintif(smbglobals.log.sessions, "shutting down\n");
  140. smbsessionfree(smbs);
  141. }
  142. smbbufferfree(&b);
  143. if (smbglobals.log.poolparanoia)
  144. poolcheck(mainmem);
  145. return rv;
  146. }
  147. static int
  148. nbwrite(NbSession *nbss, void *p, int32_t n)
  149. {
  150. return smbsessionwrite((SmbSession *)nbss->magic, p, n);
  151. }
  152. static int
  153. cifswrite(SmbCifsSession *cifs, void *p, int32_t n)
  154. {
  155. return smbsessionwrite((SmbSession *)cifs->magic, p, n);
  156. }
  157. int
  158. nbssaccept(void *v, NbSession *s, NBSSWRITEFN **writep)
  159. {
  160. SmbSession *smbs = smbemallocz(sizeof(SmbSession), 1);
  161. smbs->nbss = s;
  162. s->magic = smbs;
  163. smbs->nextcommand = SMB_COM_NO_ANDX_COMMAND;
  164. *writep = nbwrite;
  165. smblogprintif(smbglobals.log.sessions, "netbios session started\n");
  166. return 1;
  167. }
  168. int
  169. cifsaccept(SmbCifsSession *s, SMBCIFSWRITEFN **writep)
  170. {
  171. SmbSession *smbs = smbemallocz(sizeof(SmbSession), 1);
  172. smbs->cifss = s;
  173. s->magic = smbs;
  174. smbs->nextcommand = SMB_COM_NO_ANDX_COMMAND;
  175. *writep = cifswrite;
  176. smblogprintif(smbglobals.log.sessions, "cifs session started\n");
  177. return 1;
  178. }
  179. void
  180. usage(void)
  181. {
  182. fprint(2, "usage: %s [-np] [-d debug] [-u N] [-w workgroup]\n", argv0);
  183. threadexitsall("usage");
  184. }
  185. static void
  186. logset(char *cmd)
  187. {
  188. int x;
  189. if (strcmp(cmd, "allcmds") == 0) {
  190. for (x = 0; x < 256; x++)
  191. smboptable[x].debug = 1;
  192. for (x = 0; x < smbtrans2optablesize; x++)
  193. smbtrans2optable[x].debug = 1;
  194. return;
  195. }
  196. if (strcmp(cmd, "tids") == 0) {
  197. smbglobals.log.tids = 1;
  198. return;
  199. }
  200. if (strcmp(cmd, "sids") == 0) {
  201. smbglobals.log.sids = 1;
  202. return;
  203. }
  204. if (strcmp(cmd, "fids") == 0) {
  205. smbglobals.log.fids = 1;
  206. return;
  207. }
  208. if (strcmp(cmd, "rap2") == 0) {
  209. smbglobals.log.rap2 = 1;
  210. return;
  211. }
  212. else if (strcmp(cmd, "find") == 0) {
  213. smbglobals.log.find = 1;
  214. return;
  215. }
  216. if (strcmp(cmd, "query") == 0) {
  217. smbglobals.log.query = 1;
  218. return;
  219. }
  220. if (strcmp(cmd, "sharedfiles") == 0) {
  221. smbglobals.log.sharedfiles = 1;
  222. return;
  223. }
  224. if (strcmp(cmd, "poolparanoia") == 0) {
  225. mainmem->flags |= POOL_PARANOIA;
  226. smbglobals.log.poolparanoia = 1;
  227. return;
  228. }
  229. if (strcmp(cmd, "sessions") == 0) {
  230. smbglobals.log.sessions = 1;
  231. return;
  232. }
  233. if (strcmp(cmd, "rep") == 0) {
  234. smbglobals.log.rep = 1;
  235. return;
  236. }
  237. if (strcmp(cmd, "locks") == 0) {
  238. smbglobals.log.locks = 1;
  239. return;
  240. }
  241. for (x = 0; x < 256; x++)
  242. if (smboptable[x].name && strcmp(smboptable[x].name, cmd) == 0) {
  243. smboptable[x].debug = 1;
  244. return;
  245. }
  246. for (x = 0; x < smbtrans2optablesize; x++)
  247. if (smbtrans2optable[x].name && strcmp(smbtrans2optable[x].name, cmd) == 0) {
  248. smbtrans2optable[x].debug = 1;
  249. return;
  250. }
  251. if (strlen(cmd) == 4 && cmd[0] == '0' && cmd[1] == 'x') {
  252. int c;
  253. c = strtoul(cmd + 2, 0, 16);
  254. if (c >= 0 && c <= 255) {
  255. smboptable[c].debug = 1;
  256. return;
  257. }
  258. }
  259. print("debugging command %s not recognised\n", cmd);
  260. }
  261. void
  262. threadmain(int argc, char **argv)
  263. {
  264. NbName from, to;
  265. char *e = nil;
  266. int netbios = 0;
  267. ARGBEGIN {
  268. case 'u':
  269. smbglobals.unicode = strtol(ARGF(), 0, 0) != 0;
  270. break;
  271. case 'p':
  272. smbglobals.log.print = 1;
  273. break;
  274. case 'd':
  275. logset(ARGF());
  276. break;
  277. case 'w':
  278. smbglobals.primarydomain = ARGF();
  279. break;
  280. case 'n':
  281. netbios = 1;
  282. break;
  283. default:
  284. usage();
  285. } ARGEND;
  286. smbglobalsguess(0);
  287. smblistencifs(cifsaccept);
  288. if (netbios) {
  289. nbinit();
  290. nbmknamefromstring(from, "*");
  291. nbmknamefromstring(to, "*smbserver\\x20");
  292. nbsslisten(to, from, nbssaccept, nil);
  293. nbmknamefromstringandtype(to, smbglobals.serverinfo.name, 0x20);
  294. nbsslisten(to, from, nbssaccept, nil);
  295. }
  296. smblogprint(-1, "Aquarela %d.%d running\n", smbglobals.serverinfo.vmaj, smbglobals.serverinfo.vmin);
  297. for (;;) {
  298. if (netbios&& !smbbrowsesendhostannouncement(smbglobals.serverinfo.name, 60 * 1000,
  299. SV_TYPE_SERVER,
  300. smbglobals.serverinfo.remark, &e)) {
  301. smblogprint(-1, "hostannounce failed: %s\n", e);
  302. }
  303. if (sleep(60 * 1000) < 0)
  304. break;
  305. }
  306. }