123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- #include "headers.h"
- #include <mp.h>
- #include <libsec.h>
- SmbProcessResult
- smbcomsessionsetupandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
- {
- uchar andxcommand;
- ushort andxoffset;
- ulong andxfixupoffset;
- ushort vcnumber;
- ulong sessionkey;
- ushort caseinsensitivepasswordlength;
- ushort casesensitivepasswordlength;
- ushort bytecountfixup, offset;
- uchar *mschapreply;
- AuthInfo *ai;
- char *sp;
- SmbProcessResult pr;
- char *accountname = nil;
- char *primarydomain = nil;
- char *nativeos = nil;
- char *nativelanman = nil;
- if (!smbcheckwordcount("comsessionsetupandx", h, 13)) {
- fmtfail:
- pr = SmbProcessResultFormat;
- goto done;
- }
- andxcommand = *pdata++;
- switch (andxcommand) {
- case SMB_COM_TREE_CONNECT_ANDX:
- case SMB_COM_OPEN_ANDX:
- case SMB_COM_CREATE_NEW:
- case SMB_COM_DELETE:
- case SMB_COM_FIND:
- case SMB_COM_COPY:
- case SMB_COM_NT_RENAME:
- case SMB_COM_QUERY_INFORMATION:
- case SMB_COM_NO_ANDX_COMMAND:
- case SMB_COM_OPEN:
- case SMB_COM_CREATE:
- case SMB_COM_CREATE_DIRECTORY:
- case SMB_COM_DELETE_DIRECTORY:
- case SMB_COM_FIND_UNIQUE:
- case SMB_COM_RENAME:
- case SMB_COM_CHECK_DIRECTORY:
- case SMB_COM_SET_INFORMATION:
- case SMB_COM_OPEN_PRINT_FILE:
- break;
- default:
- smblogprint(h->command, "smbcomsessionsetupandx: invalid andxcommand %s (0x%.2ux)\n",
- smboptable[andxcommand].name, andxcommand);
- goto fmtfail;
- }
- pdata++;
- andxoffset = smbnhgets(pdata); pdata += 2;
- s->peerinfo.maxlen = smbnhgets(pdata); pdata += 2;
- smbresponseinit(s, s->peerinfo.maxlen);
- s->client.maxmpxcount = smbnhgets(pdata); pdata += 2;
- vcnumber = smbnhgets(pdata); pdata += 2;
- sessionkey = smbnhgetl(pdata); pdata += 4;
- caseinsensitivepasswordlength = smbnhgets(pdata); pdata += 2;
- casesensitivepasswordlength = smbnhgets(pdata); pdata += 2;
- pdata += 4;
- s->peerinfo.capabilities = smbnhgetl(pdata); /*pdata += 4;*/
- smbloglock();
- smblogprint(h->command, "andxcommand: %s offset %ud\n", smboptable[andxcommand].name, andxoffset);
- smblogprint(h->command, "client.maxbuffersize: %ud\n", s->peerinfo.maxlen);
- smblogprint(h->command, "client.maxmpxcount: %ud\n", s->client.maxmpxcount);
- smblogprint(h->command, "vcnumber: %ud\n", vcnumber);
- smblogprint(h->command, "sessionkey: 0x%.8lux\n", sessionkey);
- smblogprint(h->command, "caseinsensitivepasswordlength: %ud\n", caseinsensitivepasswordlength);
- smblogprint(h->command, "casesensitivepasswordlength: %ud\n", casesensitivepasswordlength);
- smblogprint(h->command, "clientcapabilities: 0x%.8lux\n", s->peerinfo.capabilities);
- smblogunlock();
- mschapreply = smbbufferreadpointer(b);
- if (!smbbuffergetbytes(b, nil, caseinsensitivepasswordlength + casesensitivepasswordlength)) {
- smblogprint(h->command, "smbcomsessionsetupandx: not enough bdata for passwords\n");
- goto fmtfail;
- }
- if (!smbbuffergetstring(b, h, 0, &accountname)
- || !smbbuffergetstring(b, h, 0, &primarydomain)
- || !smbbuffergetstring(b, h, 0, &nativeos)
- || !smbbuffergetstring(b, h, 0, &nativelanman)) {
- smblogprint(h->command, "smbcomsessionsetupandx: not enough bytes for strings\n");
- goto fmtfail;
- }
- for (sp = accountname; *sp; sp++)
- *sp = tolower(*sp);
- smblogprint(h->command, "account: %s\n", accountname);
- smblogprint(h->command, "primarydomain: %s\n", primarydomain);
- smblogprint(h->command, "nativeos: %s\n", nativeos);
- smblogprint(h->command, "nativelanman: %s\n", nativelanman);
- if (s->client.accountname && accountname[0] && strcmp(s->client.accountname, accountname) != 0) {
- smblogprint(h->command, "smbcomsessionsetupandx: more than one user on VC (before %s, now %s)\n",
- s->client.accountname, accountname);
- smbseterror(s, ERRSRV, ERRtoomanyuids);
- errordone:
- pr = SmbProcessResultError;
- goto done;
- }
- if (s->client.accountname == nil) {
- /* first time */
- if (accountname[0] == 0) {
- smbseterror(s, ERRSRV, ERRbaduid);
- goto errordone;
- }
- if ((casesensitivepasswordlength != 24 || caseinsensitivepasswordlength != 24)) {
- smblogprint(h->command,
- "smbcomsessionsetupandx: case sensitive/insensitive password length not 24\n");
- smbseterror(s, ERRSRV, ERRbadpw);
- goto errordone;
- }
- memcpy(&s->client.mschapreply, mschapreply, sizeof(s->client.mschapreply));
- s->cs->user = accountname;
- s->cs->resp = &s->client.mschapreply;
- s->cs->nresp = sizeof(MSchapreply);
- ai = auth_response(s->cs);
- if (ai == nil) {
- smblogprint(h->command, "authentication failed\n");
- smbseterror(s, ERRSRV, ERRbadpw);
- goto errordone;
- }
- smblogprint(h->command, "authentication succeeded\n");
- if (auth_chuid(ai, nil) < 0) {
- smblogprint(h->command, "smbcomsessionsetupandx: chuid failed: %r\n");
- auth_freeAI(ai);
- miscerror:
- pr = SmbProcessResultMisc;
- goto done;
- }
- auth_freeAI(ai);
- h->uid = 1;
- s->client.accountname = accountname;
- s->client.primarydomain = primarydomain;
- s->client.nativeos = nativeos;
- s->client.nativelanman = nativelanman;
- accountname = nil;
- primarydomain = nil;
- nativeos = nil;
- nativelanman = nil;
- }
- else {
- if (caseinsensitivepasswordlength == 24 && casesensitivepasswordlength == 24
- && memcmp(&s->client.mschapreply, mschapreply, sizeof(MSchapreply)) != 0) {
- smblogprint(h->command, "second time authentication failed\n");
- smbseterror(s, ERRSRV, ERRbadpw);
- goto errordone;
- }
- }
- /* CIFS says 4 with or without extended security, samba/ms says 3 without */
- h->wordcount = 3;
- if (!smbresponseputandxheader(s, h, andxcommand, &andxfixupoffset))
- goto miscerror;
- if (!smbresponseputs(s, 0))
- goto miscerror;
- bytecountfixup = smbresponseoffset(s);
- if (!smbresponseputs(s, 0))
- goto miscerror;
- if (!smbresponseputstring(s, 1, smbglobals.nativeos)
- || !smbresponseputstring(s, 1, smbglobals.serverinfo.nativelanman)
- || !smbresponseputstring(s, 1, smbglobals.primarydomain))
- goto miscerror;
- offset = smbresponseoffset(s);
- smbresponseoffsetputs(s, bytecountfixup, offset - bytecountfixup - 2);
- s->state = SmbSessionEstablished;
- if (andxcommand != SMB_COM_NO_ANDX_COMMAND)
- pr = smbchaincommand(s, h, andxfixupoffset, andxcommand, andxoffset, b);
- else
- pr = SmbProcessResultReply;
- done:
- free(accountname);
- free(primarydomain);
- free(nativeos);
- free(nativelanman);
- return pr;
- }
|