smbcomtreeconnectandx.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include "headers.h"
  2. static char *s9p2000 = "9p2000";
  3. SmbProcessResult
  4. smbcomtreeconnectandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
  5. {
  6. uchar andxcommand;
  7. ushort andxoffset;
  8. char *path = nil;
  9. char *service = nil;
  10. ushort flags;
  11. ushort passwordlength;
  12. // ushort bytecount;
  13. uchar errclass;
  14. ushort error;
  15. SmbService *serv;
  16. SmbTree *tree;
  17. ulong andxfixupoffset, bytecountfixup;
  18. SmbProcessResult pr;
  19. if (!smbcheckwordcount("comtreeconnectandx", h, 4)) {
  20. fmtfail:
  21. pr = SmbProcessResultFormat;
  22. goto done;
  23. }
  24. switch (s->state) {
  25. case SmbSessionNeedNegotiate:
  26. smblogprint(-1, "smbcomtreeconnectandx: called when negotiate expected\n");
  27. return SmbProcessResultUnimp;
  28. case SmbSessionNeedSetup:
  29. smbseterror(s, ERRDOS, ERRbadpw);
  30. return SmbProcessResultError;
  31. }
  32. andxcommand = *pdata++;
  33. switch (andxcommand) {
  34. case SMB_COM_OPEN:
  35. case SMB_COM_CREATE_NEW:
  36. case SMB_COM_DELETE_DIRECTORY:
  37. case SMB_COM_FIND_UNIQUE:
  38. case SMB_COM_CHECK_DIRECTORY:
  39. case SMB_COM_GET_PRINT_QUEUE:
  40. case SMB_COM_TRANSACTION:
  41. case SMB_COM_SET_INFORMATION:
  42. case SMB_COM_OPEN_ANDX:
  43. case SMB_COM_CREATE_DIRECTORY:
  44. case SMB_COM_FIND:
  45. case SMB_COM_RENAME:
  46. case SMB_COM_QUERY_INFORMATION:
  47. case SMB_COM_OPEN_PRINT_FILE:
  48. case SMB_COM_NO_ANDX_COMMAND:
  49. case SMB_COM_NT_RENAME:
  50. case SMB_COM_CREATE:
  51. case SMB_COM_DELETE:
  52. case SMB_COM_COPY:
  53. break;
  54. default:
  55. smblogprint(h->command, "smbcomtreeconnectandx: invalid andxcommand %s (0x%.2ux)\n",
  56. smboptable[andxcommand].name, andxcommand);
  57. goto fmtfail;
  58. }
  59. pdata++;
  60. andxoffset = smbnhgets(pdata); pdata += 2;
  61. flags = smbnhgets(pdata); pdata += 2;
  62. passwordlength = smbnhgets(pdata); //pdata += 2;
  63. // bytecount = smbnhgets(pdata); pdata += 2;
  64. smblogprint(h->command, "passwordlength: %ud\n", passwordlength);
  65. smblogprint(h->command, "flags: 0x%.4ux\n", flags);
  66. if (!smbbuffergetbytes(b, nil, passwordlength)) {
  67. smblogprint(h->command, "smbcomtreeconnectandx: not enough bytes for password\n");
  68. goto fmtfail;
  69. }
  70. smblogprint(h->command, "offset %lud limit %lud\n", smbbufferreadoffset(b), smbbufferwriteoffset(b));
  71. if (!smbbuffergetstring(b, h, SMB_STRING_PATH, &path)
  72. || !smbbuffergetstr(b, 0, &service)) {
  73. smblogprint(h->command, "smbcomtreeconnectandx: not enough bytes for strings\n");
  74. goto fmtfail;
  75. }
  76. smblogprint(h->command, "path: %s\n", path);
  77. smblogprint(h->command, "service: %s\n", service);
  78. if (flags & 1)
  79. smbtreedisconnectbyid(s, h->tid);
  80. serv = smbservicefind(s, path, service, &errclass, &error);
  81. if (serv == nil) {
  82. pr = SmbProcessResultError;
  83. smbseterror(s, errclass, error);
  84. goto done;
  85. }
  86. tree = smbtreeconnect(s, serv);
  87. h->tid = tree->id;
  88. h->wordcount = 3;
  89. if (!smbresponseputandxheader(s, h, andxcommand, &andxfixupoffset)
  90. || !smbresponseputs(s, 1)) {
  91. misc:
  92. pr = SmbProcessResultMisc;
  93. goto done;
  94. }
  95. bytecountfixup = smbresponseoffset(s);
  96. if (!smbresponseputs(s, 0)
  97. || !smbresponseputstr(s, serv->type)
  98. || !smbresponseputstring(s, 1, s9p2000))
  99. goto misc;
  100. if (!smbbufferfixuprelatives(s->response, bytecountfixup))
  101. goto misc;
  102. if (andxcommand != SMB_COM_NO_ANDX_COMMAND) {
  103. pr = smbchaincommand(s, h, andxfixupoffset, andxcommand, andxoffset, b);
  104. }
  105. else
  106. pr = SmbProcessResultReply;
  107. done:
  108. free(path);
  109. free(service);
  110. return pr;
  111. }