18ccd4a63SDavid du Colombier #include "headers.h"
28ccd4a63SDavid du Colombier #include <mp.h>
38ccd4a63SDavid du Colombier #include <libsec.h>
48ccd4a63SDavid du Colombier
58ccd4a63SDavid du Colombier SmbProcessResult
smbcomsessionsetupandx(SmbSession * s,SmbHeader * h,uchar * pdata,SmbBuffer * b)68ccd4a63SDavid du Colombier smbcomsessionsetupandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
78ccd4a63SDavid du Colombier {
88ccd4a63SDavid du Colombier uchar andxcommand;
98ccd4a63SDavid du Colombier ushort andxoffset;
108ccd4a63SDavid du Colombier ulong andxfixupoffset;
118ccd4a63SDavid du Colombier ushort vcnumber;
128ccd4a63SDavid du Colombier ulong sessionkey;
138ccd4a63SDavid du Colombier ushort caseinsensitivepasswordlength;
148ccd4a63SDavid du Colombier ushort casesensitivepasswordlength;
158ccd4a63SDavid du Colombier ushort bytecountfixup, offset;
168ccd4a63SDavid du Colombier uchar *mschapreply;
178ccd4a63SDavid du Colombier AuthInfo *ai;
188ccd4a63SDavid du Colombier char *sp;
198ccd4a63SDavid du Colombier SmbProcessResult pr;
208ccd4a63SDavid du Colombier char *accountname = nil;
218ccd4a63SDavid du Colombier char *primarydomain = nil;
228ccd4a63SDavid du Colombier char *nativeos = nil;
238ccd4a63SDavid du Colombier char *nativelanman = nil;
248ccd4a63SDavid du Colombier
258ccd4a63SDavid du Colombier if (!smbcheckwordcount("comsessionsetupandx", h, 13)) {
268ccd4a63SDavid du Colombier fmtfail:
278ccd4a63SDavid du Colombier pr = SmbProcessResultFormat;
288ccd4a63SDavid du Colombier goto done;
298ccd4a63SDavid du Colombier }
308ccd4a63SDavid du Colombier
318ccd4a63SDavid du Colombier andxcommand = *pdata++;
328ccd4a63SDavid du Colombier switch (andxcommand) {
338ccd4a63SDavid du Colombier case SMB_COM_TREE_CONNECT_ANDX:
348ccd4a63SDavid du Colombier case SMB_COM_OPEN_ANDX:
358ccd4a63SDavid du Colombier case SMB_COM_CREATE_NEW:
368ccd4a63SDavid du Colombier case SMB_COM_DELETE:
378ccd4a63SDavid du Colombier case SMB_COM_FIND:
388ccd4a63SDavid du Colombier case SMB_COM_COPY:
398ccd4a63SDavid du Colombier case SMB_COM_NT_RENAME:
408ccd4a63SDavid du Colombier case SMB_COM_QUERY_INFORMATION:
418ccd4a63SDavid du Colombier case SMB_COM_NO_ANDX_COMMAND:
428ccd4a63SDavid du Colombier case SMB_COM_OPEN:
438ccd4a63SDavid du Colombier case SMB_COM_CREATE:
448ccd4a63SDavid du Colombier case SMB_COM_CREATE_DIRECTORY:
458ccd4a63SDavid du Colombier case SMB_COM_DELETE_DIRECTORY:
468ccd4a63SDavid du Colombier case SMB_COM_FIND_UNIQUE:
478ccd4a63SDavid du Colombier case SMB_COM_RENAME:
488ccd4a63SDavid du Colombier case SMB_COM_CHECK_DIRECTORY:
498ccd4a63SDavid du Colombier case SMB_COM_SET_INFORMATION:
508ccd4a63SDavid du Colombier case SMB_COM_OPEN_PRINT_FILE:
518ccd4a63SDavid du Colombier break;
528ccd4a63SDavid du Colombier default:
538ccd4a63SDavid du Colombier smblogprint(h->command, "smbcomsessionsetupandx: invalid andxcommand %s (0x%.2ux)\n",
548ccd4a63SDavid du Colombier smboptable[andxcommand].name, andxcommand);
558ccd4a63SDavid du Colombier goto fmtfail;
568ccd4a63SDavid du Colombier }
578ccd4a63SDavid du Colombier pdata++;
588ccd4a63SDavid du Colombier andxoffset = smbnhgets(pdata); pdata += 2;
598ccd4a63SDavid du Colombier s->peerinfo.maxlen = smbnhgets(pdata); pdata += 2;
608ccd4a63SDavid du Colombier smbresponseinit(s, s->peerinfo.maxlen);
618ccd4a63SDavid du Colombier s->client.maxmpxcount = smbnhgets(pdata); pdata += 2;
628ccd4a63SDavid du Colombier vcnumber = smbnhgets(pdata); pdata += 2;
638ccd4a63SDavid du Colombier sessionkey = smbnhgetl(pdata); pdata += 4;
648ccd4a63SDavid du Colombier caseinsensitivepasswordlength = smbnhgets(pdata); pdata += 2;
658ccd4a63SDavid du Colombier casesensitivepasswordlength = smbnhgets(pdata); pdata += 2;
668ccd4a63SDavid du Colombier pdata += 4;
678ccd4a63SDavid du Colombier s->peerinfo.capabilities = smbnhgetl(pdata); /*pdata += 4;*/
688ccd4a63SDavid du Colombier smbloglock();
698ccd4a63SDavid du Colombier smblogprint(h->command, "andxcommand: %s offset %ud\n", smboptable[andxcommand].name, andxoffset);
708ccd4a63SDavid du Colombier smblogprint(h->command, "client.maxbuffersize: %ud\n", s->peerinfo.maxlen);
718ccd4a63SDavid du Colombier smblogprint(h->command, "client.maxmpxcount: %ud\n", s->client.maxmpxcount);
728ccd4a63SDavid du Colombier smblogprint(h->command, "vcnumber: %ud\n", vcnumber);
738ccd4a63SDavid du Colombier smblogprint(h->command, "sessionkey: 0x%.8lux\n", sessionkey);
748ccd4a63SDavid du Colombier smblogprint(h->command, "caseinsensitivepasswordlength: %ud\n", caseinsensitivepasswordlength);
758ccd4a63SDavid du Colombier smblogprint(h->command, "casesensitivepasswordlength: %ud\n", casesensitivepasswordlength);
768ccd4a63SDavid du Colombier smblogprint(h->command, "clientcapabilities: 0x%.8lux\n", s->peerinfo.capabilities);
778ccd4a63SDavid du Colombier smblogunlock();
788ccd4a63SDavid du Colombier
798ccd4a63SDavid du Colombier mschapreply = smbbufferreadpointer(b);
808ccd4a63SDavid du Colombier
818ccd4a63SDavid du Colombier if (!smbbuffergetbytes(b, nil, caseinsensitivepasswordlength + casesensitivepasswordlength)) {
828ccd4a63SDavid du Colombier smblogprint(h->command, "smbcomsessionsetupandx: not enough bdata for passwords\n");
838ccd4a63SDavid du Colombier goto fmtfail;
848ccd4a63SDavid du Colombier }
858ccd4a63SDavid du Colombier if (!smbbuffergetstring(b, h, 0, &accountname)
868ccd4a63SDavid du Colombier || !smbbuffergetstring(b, h, 0, &primarydomain)
878ccd4a63SDavid du Colombier || !smbbuffergetstring(b, h, 0, &nativeos)
888ccd4a63SDavid du Colombier || !smbbuffergetstring(b, h, 0, &nativelanman)) {
898ccd4a63SDavid du Colombier smblogprint(h->command, "smbcomsessionsetupandx: not enough bytes for strings\n");
908ccd4a63SDavid du Colombier goto fmtfail;
918ccd4a63SDavid du Colombier }
928ccd4a63SDavid du Colombier
938ccd4a63SDavid du Colombier for (sp = accountname; *sp; sp++)
948ccd4a63SDavid du Colombier *sp = tolower(*sp);
958ccd4a63SDavid du Colombier
968ccd4a63SDavid du Colombier smblogprint(h->command, "account: %s\n", accountname);
978ccd4a63SDavid du Colombier smblogprint(h->command, "primarydomain: %s\n", primarydomain);
988ccd4a63SDavid du Colombier smblogprint(h->command, "nativeos: %s\n", nativeos);
998ccd4a63SDavid du Colombier smblogprint(h->command, "nativelanman: %s\n", nativelanman);
1008ccd4a63SDavid du Colombier
1018ccd4a63SDavid du Colombier if (s->client.accountname && accountname[0] && strcmp(s->client.accountname, accountname) != 0) {
1028ccd4a63SDavid du Colombier smblogprint(h->command, "smbcomsessionsetupandx: more than one user on VC (before %s, now %s)\n",
1038ccd4a63SDavid du Colombier s->client.accountname, accountname);
1048ccd4a63SDavid du Colombier smbseterror(s, ERRSRV, ERRtoomanyuids);
1058ccd4a63SDavid du Colombier errordone:
1068ccd4a63SDavid du Colombier pr = SmbProcessResultError;
1078ccd4a63SDavid du Colombier goto done;
1088ccd4a63SDavid du Colombier }
1098ccd4a63SDavid du Colombier
1108ccd4a63SDavid du Colombier if (s->client.accountname == nil) {
1118ccd4a63SDavid du Colombier /* first time */
1128ccd4a63SDavid du Colombier if (accountname[0] == 0) {
1138ccd4a63SDavid du Colombier smbseterror(s, ERRSRV, ERRbaduid);
1148ccd4a63SDavid du Colombier goto errordone;
1158ccd4a63SDavid du Colombier }
1168ccd4a63SDavid du Colombier if ((casesensitivepasswordlength != 24 || caseinsensitivepasswordlength != 24)) {
1178ccd4a63SDavid du Colombier smblogprint(h->command,
1188ccd4a63SDavid du Colombier "smbcomsessionsetupandx: case sensitive/insensitive password length not 24\n");
1198ccd4a63SDavid du Colombier smbseterror(s, ERRSRV, ERRbadpw);
1208ccd4a63SDavid du Colombier goto errordone;
1218ccd4a63SDavid du Colombier }
1228ccd4a63SDavid du Colombier memcpy(&s->client.mschapreply, mschapreply, sizeof(s->client.mschapreply));
123*08d9be5dSDavid du Colombier if(s->cs == nil){
124*08d9be5dSDavid du Colombier smbseterror(s, ERRSRV, ERRerror);
125*08d9be5dSDavid du Colombier goto errordone;
126*08d9be5dSDavid du Colombier }
1278ccd4a63SDavid du Colombier s->cs->user = accountname;
1288ccd4a63SDavid du Colombier s->cs->resp = &s->client.mschapreply;
1298ccd4a63SDavid du Colombier s->cs->nresp = sizeof(MSchapreply);
1308ccd4a63SDavid du Colombier ai = auth_response(s->cs);
1318ccd4a63SDavid du Colombier if (ai == nil) {
1328ccd4a63SDavid du Colombier smblogprint(h->command, "authentication failed\n");
1338ccd4a63SDavid du Colombier smbseterror(s, ERRSRV, ERRbadpw);
1348ccd4a63SDavid du Colombier goto errordone;
1358ccd4a63SDavid du Colombier }
1368ccd4a63SDavid du Colombier smblogprint(h->command, "authentication succeeded\n");
1378ccd4a63SDavid du Colombier if (auth_chuid(ai, nil) < 0) {
1388ccd4a63SDavid du Colombier smblogprint(h->command, "smbcomsessionsetupandx: chuid failed: %r\n");
1398ccd4a63SDavid du Colombier auth_freeAI(ai);
1408ccd4a63SDavid du Colombier miscerror:
1418ccd4a63SDavid du Colombier pr = SmbProcessResultMisc;
1428ccd4a63SDavid du Colombier goto done;
1438ccd4a63SDavid du Colombier }
1448ccd4a63SDavid du Colombier auth_freeAI(ai);
1458ccd4a63SDavid du Colombier h->uid = 1;
1468ccd4a63SDavid du Colombier s->client.accountname = accountname;
1478ccd4a63SDavid du Colombier s->client.primarydomain = primarydomain;
1488ccd4a63SDavid du Colombier s->client.nativeos = nativeos;
1498ccd4a63SDavid du Colombier s->client.nativelanman = nativelanman;
1508ccd4a63SDavid du Colombier accountname = nil;
1518ccd4a63SDavid du Colombier primarydomain = nil;
1528ccd4a63SDavid du Colombier nativeos = nil;
1538ccd4a63SDavid du Colombier nativelanman = nil;
1548ccd4a63SDavid du Colombier }
1558ccd4a63SDavid du Colombier else {
1568ccd4a63SDavid du Colombier if (caseinsensitivepasswordlength == 24 && casesensitivepasswordlength == 24
1578ccd4a63SDavid du Colombier && memcmp(&s->client.mschapreply, mschapreply, sizeof(MSchapreply)) != 0) {
1588ccd4a63SDavid du Colombier smblogprint(h->command, "second time authentication failed\n");
1598ccd4a63SDavid du Colombier smbseterror(s, ERRSRV, ERRbadpw);
1608ccd4a63SDavid du Colombier goto errordone;
1618ccd4a63SDavid du Colombier }
1628ccd4a63SDavid du Colombier }
1638ccd4a63SDavid du Colombier
1648ccd4a63SDavid du Colombier /* CIFS says 4 with or without extended security, samba/ms says 3 without */
1658ccd4a63SDavid du Colombier h->wordcount = 3;
1668ccd4a63SDavid du Colombier if (!smbresponseputandxheader(s, h, andxcommand, &andxfixupoffset))
1678ccd4a63SDavid du Colombier goto miscerror;
1688ccd4a63SDavid du Colombier if (!smbresponseputs(s, 0))
1698ccd4a63SDavid du Colombier goto miscerror;
1708ccd4a63SDavid du Colombier bytecountfixup = smbresponseoffset(s);
1718ccd4a63SDavid du Colombier if (!smbresponseputs(s, 0))
1728ccd4a63SDavid du Colombier goto miscerror;
1738ccd4a63SDavid du Colombier if (!smbresponseputstring(s, 1, smbglobals.nativeos)
1748ccd4a63SDavid du Colombier || !smbresponseputstring(s, 1, smbglobals.serverinfo.nativelanman)
1758ccd4a63SDavid du Colombier || !smbresponseputstring(s, 1, smbglobals.primarydomain))
1768ccd4a63SDavid du Colombier goto miscerror;
1778ccd4a63SDavid du Colombier offset = smbresponseoffset(s);
1788ccd4a63SDavid du Colombier smbresponseoffsetputs(s, bytecountfixup, offset - bytecountfixup - 2);
1798ccd4a63SDavid du Colombier s->state = SmbSessionEstablished;
1808ccd4a63SDavid du Colombier if (andxcommand != SMB_COM_NO_ANDX_COMMAND)
1818ccd4a63SDavid du Colombier pr = smbchaincommand(s, h, andxfixupoffset, andxcommand, andxoffset, b);
1828ccd4a63SDavid du Colombier else
1838ccd4a63SDavid du Colombier pr = SmbProcessResultReply;
1848ccd4a63SDavid du Colombier done:
1858ccd4a63SDavid du Colombier free(accountname);
1868ccd4a63SDavid du Colombier free(primarydomain);
1878ccd4a63SDavid du Colombier free(nativeos);
1888ccd4a63SDavid du Colombier free(nativelanman);
1898ccd4a63SDavid du Colombier return pr;
1908ccd4a63SDavid du Colombier }
191