1 #include "headers.h" 2 #include <mp.h> 3 #include <libsec.h> 4 5 SmbProcessResult 6 smbcomsessionsetupandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b) 7 { 8 uchar andxcommand; 9 ushort andxoffset; 10 ulong andxfixupoffset; 11 ushort vcnumber; 12 ulong sessionkey; 13 ushort caseinsensitivepasswordlength; 14 ushort casesensitivepasswordlength; 15 ushort bytecountfixup, offset; 16 uchar *mschapreply; 17 AuthInfo *ai; 18 char *sp; 19 SmbProcessResult pr; 20 char *accountname = nil; 21 char *primarydomain = nil; 22 char *nativeos = nil; 23 char *nativelanman = nil; 24 25 if (!smbcheckwordcount("comsessionsetupandx", h, 13)) { 26 fmtfail: 27 pr = SmbProcessResultFormat; 28 goto done; 29 } 30 31 andxcommand = *pdata++; 32 switch (andxcommand) { 33 case SMB_COM_TREE_CONNECT_ANDX: 34 case SMB_COM_OPEN_ANDX: 35 case SMB_COM_CREATE_NEW: 36 case SMB_COM_DELETE: 37 case SMB_COM_FIND: 38 case SMB_COM_COPY: 39 case SMB_COM_NT_RENAME: 40 case SMB_COM_QUERY_INFORMATION: 41 case SMB_COM_NO_ANDX_COMMAND: 42 case SMB_COM_OPEN: 43 case SMB_COM_CREATE: 44 case SMB_COM_CREATE_DIRECTORY: 45 case SMB_COM_DELETE_DIRECTORY: 46 case SMB_COM_FIND_UNIQUE: 47 case SMB_COM_RENAME: 48 case SMB_COM_CHECK_DIRECTORY: 49 case SMB_COM_SET_INFORMATION: 50 case SMB_COM_OPEN_PRINT_FILE: 51 break; 52 default: 53 smblogprint(h->command, "smbcomsessionsetupandx: invalid andxcommand %s (0x%.2ux)\n", 54 smboptable[andxcommand].name, andxcommand); 55 goto fmtfail; 56 } 57 pdata++; 58 andxoffset = smbnhgets(pdata); pdata += 2; 59 s->peerinfo.maxlen = smbnhgets(pdata); pdata += 2; 60 smbresponseinit(s, s->peerinfo.maxlen); 61 s->client.maxmpxcount = smbnhgets(pdata); pdata += 2; 62 vcnumber = smbnhgets(pdata); pdata += 2; 63 sessionkey = smbnhgetl(pdata); pdata += 4; 64 caseinsensitivepasswordlength = smbnhgets(pdata); pdata += 2; 65 casesensitivepasswordlength = smbnhgets(pdata); pdata += 2; 66 pdata += 4; 67 s->peerinfo.capabilities = smbnhgetl(pdata); /*pdata += 4;*/ 68 smbloglock(); 69 smblogprint(h->command, "andxcommand: %s offset %ud\n", smboptable[andxcommand].name, andxoffset); 70 smblogprint(h->command, "client.maxbuffersize: %ud\n", s->peerinfo.maxlen); 71 smblogprint(h->command, "client.maxmpxcount: %ud\n", s->client.maxmpxcount); 72 smblogprint(h->command, "vcnumber: %ud\n", vcnumber); 73 smblogprint(h->command, "sessionkey: 0x%.8lux\n", sessionkey); 74 smblogprint(h->command, "caseinsensitivepasswordlength: %ud\n", caseinsensitivepasswordlength); 75 smblogprint(h->command, "casesensitivepasswordlength: %ud\n", casesensitivepasswordlength); 76 smblogprint(h->command, "clientcapabilities: 0x%.8lux\n", s->peerinfo.capabilities); 77 smblogunlock(); 78 79 mschapreply = smbbufferreadpointer(b); 80 81 if (!smbbuffergetbytes(b, nil, caseinsensitivepasswordlength + casesensitivepasswordlength)) { 82 smblogprint(h->command, "smbcomsessionsetupandx: not enough bdata for passwords\n"); 83 goto fmtfail; 84 } 85 if (!smbbuffergetstring(b, h, 0, &accountname) 86 || !smbbuffergetstring(b, h, 0, &primarydomain) 87 || !smbbuffergetstring(b, h, 0, &nativeos) 88 || !smbbuffergetstring(b, h, 0, &nativelanman)) { 89 smblogprint(h->command, "smbcomsessionsetupandx: not enough bytes for strings\n"); 90 goto fmtfail; 91 } 92 93 for (sp = accountname; *sp; sp++) 94 *sp = tolower(*sp); 95 96 smblogprint(h->command, "account: %s\n", accountname); 97 smblogprint(h->command, "primarydomain: %s\n", primarydomain); 98 smblogprint(h->command, "nativeos: %s\n", nativeos); 99 smblogprint(h->command, "nativelanman: %s\n", nativelanman); 100 101 if (s->client.accountname && accountname[0] && strcmp(s->client.accountname, accountname) != 0) { 102 smblogprint(h->command, "smbcomsessionsetupandx: more than one user on VC (before %s, now %s)\n", 103 s->client.accountname, accountname); 104 smbseterror(s, ERRSRV, ERRtoomanyuids); 105 errordone: 106 pr = SmbProcessResultError; 107 goto done; 108 } 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 164 /* CIFS says 4 with or without extended security, samba/ms says 3 without */ 165 h->wordcount = 3; 166 if (!smbresponseputandxheader(s, h, andxcommand, &andxfixupoffset)) 167 goto miscerror; 168 if (!smbresponseputs(s, 0)) 169 goto miscerror; 170 bytecountfixup = smbresponseoffset(s); 171 if (!smbresponseputs(s, 0)) 172 goto miscerror; 173 if (!smbresponseputstring(s, 1, smbglobals.nativeos) 174 || !smbresponseputstring(s, 1, smbglobals.serverinfo.nativelanman) 175 || !smbresponseputstring(s, 1, smbglobals.primarydomain)) 176 goto miscerror; 177 offset = smbresponseoffset(s); 178 smbresponseoffsetputs(s, bytecountfixup, offset - bytecountfixup - 2); 179 s->state = SmbSessionEstablished; 180 if (andxcommand != SMB_COM_NO_ANDX_COMMAND) 181 pr = smbchaincommand(s, h, andxfixupoffset, andxcommand, andxoffset, b); 182 else 183 pr = SmbProcessResultReply; 184 done: 185 free(accountname); 186 free(primarydomain); 187 free(nativeos); 188 free(nativelanman); 189 return pr; 190 } 191