smbcomsessionsetupandx.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include "headers.h"
  2. #include <mp.h>
  3. #include <libsec.h>
  4. SmbProcessResult
  5. smbcomsessionsetupandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
  6. {
  7. uchar andxcommand;
  8. ushort andxoffset;
  9. ulong andxfixupoffset;
  10. ushort vcnumber;
  11. ulong sessionkey;
  12. ushort caseinsensitivepasswordlength;
  13. ushort casesensitivepasswordlength;
  14. ushort bytecountfixup, offset;
  15. uchar *mschapreply;
  16. AuthInfo *ai;
  17. char *sp;
  18. SmbProcessResult pr;
  19. char *accountname = nil;
  20. char *primarydomain = nil;
  21. char *nativeos = nil;
  22. char *nativelanman = nil;
  23. if (!smbcheckwordcount("comsessionsetupandx", h, 13)) {
  24. fmtfail:
  25. pr = SmbProcessResultFormat;
  26. goto done;
  27. }
  28. andxcommand = *pdata++;
  29. switch (andxcommand) {
  30. case SMB_COM_TREE_CONNECT_ANDX:
  31. case SMB_COM_OPEN_ANDX:
  32. case SMB_COM_CREATE_NEW:
  33. case SMB_COM_DELETE:
  34. case SMB_COM_FIND:
  35. case SMB_COM_COPY:
  36. case SMB_COM_NT_RENAME:
  37. case SMB_COM_QUERY_INFORMATION:
  38. case SMB_COM_NO_ANDX_COMMAND:
  39. case SMB_COM_OPEN:
  40. case SMB_COM_CREATE:
  41. case SMB_COM_CREATE_DIRECTORY:
  42. case SMB_COM_DELETE_DIRECTORY:
  43. case SMB_COM_FIND_UNIQUE:
  44. case SMB_COM_RENAME:
  45. case SMB_COM_CHECK_DIRECTORY:
  46. case SMB_COM_SET_INFORMATION:
  47. case SMB_COM_OPEN_PRINT_FILE:
  48. break;
  49. default:
  50. smblogprint(h->command, "smbcomsessionsetupandx: invalid andxcommand %s (0x%.2ux)\n",
  51. smboptable[andxcommand].name, andxcommand);
  52. goto fmtfail;
  53. }
  54. pdata++;
  55. andxoffset = smbnhgets(pdata); pdata += 2;
  56. s->peerinfo.maxlen = smbnhgets(pdata); pdata += 2;
  57. smbresponseinit(s, s->peerinfo.maxlen);
  58. s->client.maxmpxcount = smbnhgets(pdata); pdata += 2;
  59. vcnumber = smbnhgets(pdata); pdata += 2;
  60. sessionkey = smbnhgetl(pdata); pdata += 4;
  61. caseinsensitivepasswordlength = smbnhgets(pdata); pdata += 2;
  62. casesensitivepasswordlength = smbnhgets(pdata); pdata += 2;
  63. pdata += 4;
  64. s->peerinfo.capabilities = smbnhgetl(pdata); /*pdata += 4;*/
  65. smbloglock();
  66. smblogprint(h->command, "andxcommand: %s offset %ud\n", smboptable[andxcommand].name, andxoffset);
  67. smblogprint(h->command, "client.maxbuffersize: %ud\n", s->peerinfo.maxlen);
  68. smblogprint(h->command, "client.maxmpxcount: %ud\n", s->client.maxmpxcount);
  69. smblogprint(h->command, "vcnumber: %ud\n", vcnumber);
  70. smblogprint(h->command, "sessionkey: 0x%.8lux\n", sessionkey);
  71. smblogprint(h->command, "caseinsensitivepasswordlength: %ud\n", caseinsensitivepasswordlength);
  72. smblogprint(h->command, "casesensitivepasswordlength: %ud\n", casesensitivepasswordlength);
  73. smblogprint(h->command, "clientcapabilities: 0x%.8lux\n", s->peerinfo.capabilities);
  74. smblogunlock();
  75. mschapreply = smbbufferreadpointer(b);
  76. if (!smbbuffergetbytes(b, nil, caseinsensitivepasswordlength + casesensitivepasswordlength)) {
  77. smblogprint(h->command, "smbcomsessionsetupandx: not enough bdata for passwords\n");
  78. goto fmtfail;
  79. }
  80. if (!smbbuffergetstring(b, h, 0, &accountname)
  81. || !smbbuffergetstring(b, h, 0, &primarydomain)
  82. || !smbbuffergetstring(b, h, 0, &nativeos)
  83. || !smbbuffergetstring(b, h, 0, &nativelanman)) {
  84. smblogprint(h->command, "smbcomsessionsetupandx: not enough bytes for strings\n");
  85. goto fmtfail;
  86. }
  87. for (sp = accountname; *sp; sp++)
  88. *sp = tolower(*sp);
  89. smblogprint(h->command, "account: %s\n", accountname);
  90. smblogprint(h->command, "primarydomain: %s\n", primarydomain);
  91. smblogprint(h->command, "nativeos: %s\n", nativeos);
  92. smblogprint(h->command, "nativelanman: %s\n", nativelanman);
  93. if (s->client.accountname && accountname[0] && strcmp(s->client.accountname, accountname) != 0) {
  94. smblogprint(h->command, "smbcomsessionsetupandx: more than one user on VC (before %s, now %s)\n",
  95. s->client.accountname, accountname);
  96. smbseterror(s, ERRSRV, ERRtoomanyuids);
  97. errordone:
  98. pr = SmbProcessResultError;
  99. goto done;
  100. }
  101. if (s->client.accountname == nil) {
  102. /* first time */
  103. if (accountname[0] == 0) {
  104. smbseterror(s, ERRSRV, ERRbaduid);
  105. goto errordone;
  106. }
  107. if ((casesensitivepasswordlength != 24 || caseinsensitivepasswordlength != 24)) {
  108. smblogprint(h->command,
  109. "smbcomsessionsetupandx: case sensitive/insensitive password length not 24\n");
  110. smbseterror(s, ERRSRV, ERRbadpw);
  111. goto errordone;
  112. }
  113. memcpy(&s->client.mschapreply, mschapreply, sizeof(s->client.mschapreply));
  114. s->cs->user = accountname;
  115. s->cs->resp = &s->client.mschapreply;
  116. s->cs->nresp = sizeof(MSchapreply);
  117. ai = auth_response(s->cs);
  118. if (ai == nil) {
  119. smblogprint(h->command, "authentication failed\n");
  120. smbseterror(s, ERRSRV, ERRbadpw);
  121. goto errordone;
  122. }
  123. smblogprint(h->command, "authentication succeeded\n");
  124. if (auth_chuid(ai, nil) < 0) {
  125. smblogprint(h->command, "smbcomsessionsetupandx: chuid failed: %r\n");
  126. auth_freeAI(ai);
  127. miscerror:
  128. pr = SmbProcessResultMisc;
  129. goto done;
  130. }
  131. auth_freeAI(ai);
  132. h->uid = 1;
  133. s->client.accountname = accountname;
  134. s->client.primarydomain = primarydomain;
  135. s->client.nativeos = nativeos;
  136. s->client.nativelanman = nativelanman;
  137. accountname = nil;
  138. primarydomain = nil;
  139. nativeos = nil;
  140. nativelanman = nil;
  141. }
  142. else {
  143. if (caseinsensitivepasswordlength == 24 && casesensitivepasswordlength == 24
  144. && memcmp(&s->client.mschapreply, mschapreply, sizeof(MSchapreply)) != 0) {
  145. smblogprint(h->command, "second time authentication failed\n");
  146. smbseterror(s, ERRSRV, ERRbadpw);
  147. goto errordone;
  148. }
  149. }
  150. /* CIFS says 4 with or without extended security, samba/ms says 3 without */
  151. h->wordcount = 3;
  152. if (!smbresponseputandxheader(s, h, andxcommand, &andxfixupoffset))
  153. goto miscerror;
  154. if (!smbresponseputs(s, 0))
  155. goto miscerror;
  156. bytecountfixup = smbresponseoffset(s);
  157. if (!smbresponseputs(s, 0))
  158. goto miscerror;
  159. if (!smbresponseputstring(s, 1, smbglobals.nativeos)
  160. || !smbresponseputstring(s, 1, smbglobals.serverinfo.nativelanman)
  161. || !smbresponseputstring(s, 1, smbglobals.primarydomain))
  162. goto miscerror;
  163. offset = smbresponseoffset(s);
  164. smbresponseoffsetputs(s, bytecountfixup, offset - bytecountfixup - 2);
  165. s->state = SmbSessionEstablished;
  166. if (andxcommand != SMB_COM_NO_ANDX_COMMAND)
  167. pr = smbchaincommand(s, h, andxfixupoffset, andxcommand, andxoffset, b);
  168. else
  169. pr = SmbProcessResultReply;
  170. done:
  171. free(accountname);
  172. free(primarydomain);
  173. free(nativeos);
  174. free(nativelanman);
  175. return pr;
  176. }