smbcomtreeconnectandx.c 3.6 KB

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