smbcomsessionsetupandx.c 6.5 KB

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