smbcomtransaction.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include "headers.h"
  2. static int
  3. sendresponse(void *magic, SmbBuffer *, char **errmsgp)
  4. {
  5. int rv;
  6. SmbSession *s = magic;
  7. rv = smbresponsesend(s);
  8. if (rv < 0) {
  9. smbstringprint(errmsgp, "sendresponse failed");
  10. return 0;
  11. }
  12. return 1;
  13. }
  14. SmbTransactionMethod smbtransactionmethod = {
  15. .encoderesponse = smbtransactionencoderesponse,
  16. .sendresponse = sendresponse,
  17. };
  18. SmbTransactionMethod smbtransactionmethod2 = {
  19. .encoderesponse = smbtransactionencoderesponse2,
  20. .sendresponse = sendresponse,
  21. };
  22. int
  23. smbcomtransaction(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
  24. {
  25. int rv;
  26. char *errmsg;
  27. SmbProcessResult pr = SmbProcessResultDie;
  28. errmsg = nil;
  29. rv = smbtransactiondecodeprimary(&s->transaction, h, pdata, b, &errmsg);
  30. if (rv < 0) {
  31. pr = SmbProcessResultFormat;
  32. goto done;
  33. }
  34. if (rv == 0) {
  35. h->wordcount = 0;
  36. if (smbbufferputack(s->response, h, &s->peerinfo)) {
  37. pr = SmbProcessResultReply;
  38. s->nextcommand = SMB_COM_TRANSACTION_SECONDARY;
  39. }
  40. goto done;
  41. }
  42. smblogprint(h->command, "smbcomtransaction: %s scount %ud tpcount %lud tdcount %lud maxscount %lud maxpcount %lud maxdcount %lud\n",
  43. s->transaction.in.name, s->transaction.in.scount, s->transaction.in.tpcount, s->transaction.in.tdcount,
  44. s->transaction.in.maxscount, s->transaction.in.maxpcount, s->transaction.in.maxdcount);
  45. smbbufferfree(&s->transaction.out.parameters);
  46. smbbufferfree(&s->transaction.out.data);
  47. s->transaction.out.parameters = smbbuffernew(s->transaction.in.maxpcount);
  48. s->transaction.out.data = smbbuffernew(s->transaction.in.maxdcount);
  49. if (strcmp(s->transaction.in.name, smbglobals.pipelanman) == 0)
  50. pr = smbrap2(s);
  51. else {
  52. smbseterror(s, ERRDOS, ERRbadpath);
  53. pr = SmbProcessResultError;
  54. goto done;
  55. }
  56. if (pr == SmbProcessResultReply) {
  57. char *errmsg;
  58. errmsg = nil;
  59. rv = smbtransactionrespond(&s->transaction, h, &s->peerinfo, s->response, &smbtransactionmethod, s, &errmsg);
  60. if (!rv) {
  61. smblogprint(h->command, "smbcomtransaction: failed: %s\n", errmsg);
  62. pr = SmbProcessResultMisc;
  63. }
  64. else
  65. pr = SmbProcessResultOk;
  66. }
  67. done:
  68. free(errmsg);
  69. return pr;
  70. }
  71. int
  72. smbcomtransaction2(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
  73. {
  74. int rv;
  75. char *errmsg;
  76. SmbProcessResult pr = SmbProcessResultDie;
  77. ushort op;
  78. errmsg = nil;
  79. rv = smbtransactiondecodeprimary2(&s->transaction, h, pdata, b, &errmsg);
  80. if (rv < 0) {
  81. fmtfail:
  82. pr = SmbProcessResultFormat;
  83. goto done;
  84. }
  85. if (rv == 0) {
  86. h->wordcount = 0;
  87. if (smbbufferputack(s->response, h, &s->peerinfo)) {
  88. pr = SmbProcessResultReply;
  89. s->nextcommand = SMB_COM_TRANSACTION2_SECONDARY;
  90. }
  91. goto done;
  92. }
  93. smblogprint(h->command, "smbcomtransaction2: scount %ud tpcount %lud tdcount %lud maxscount %lud maxpcount %lud maxdcount %lud\n",
  94. s->transaction.in.scount, s->transaction.in.tpcount, s->transaction.in.tdcount,
  95. s->transaction.in.maxscount, s->transaction.in.maxpcount, s->transaction.in.maxdcount);
  96. smbbufferfree(&s->transaction.out.parameters);
  97. smbbufferfree(&s->transaction.out.data);
  98. s->transaction.out.parameters = smbbuffernew(s->transaction.in.maxpcount);
  99. s->transaction.out.data = smbbuffernew(s->transaction.in.maxdcount);
  100. if (s->transaction.in.scount != 1)
  101. goto fmtfail;
  102. op = s->transaction.in.setup[0];
  103. if (op >= smbtrans2optablesize || smbtrans2optable[op].name == nil) {
  104. smblogprint(-1, "smbcomtransaction2: function %d unknown\n", op);
  105. pr = SmbProcessResultUnimp;
  106. goto done;
  107. }
  108. if (smbtrans2optable[op].process == nil) {
  109. smblogprint(-1, "smbcomtransaction2: %s unimplemented\n", smbtrans2optable[op].name);
  110. pr = SmbProcessResultUnimp;
  111. goto done;
  112. }
  113. pr = (*smbtrans2optable[op].process)(s, h);
  114. if (pr == SmbProcessResultReply) {
  115. char *errmsg;
  116. errmsg = nil;
  117. rv = smbtransactionrespond(&s->transaction, h, &s->peerinfo, s->response, &smbtransactionmethod2, s, &errmsg);
  118. if (!rv) {
  119. smblogprint(h->command, "smbcomtransaction2: failed: %s\n", errmsg);
  120. pr = SmbProcessResultMisc;
  121. }
  122. else
  123. pr = SmbProcessResultOk;
  124. }
  125. done:
  126. free(errmsg);
  127. return pr;
  128. }