1*8ccd4a63SDavid du Colombier #include "headers.h"
2*8ccd4a63SDavid du Colombier
3*8ccd4a63SDavid du Colombier static char *s9p2000 = "9p2000";
4*8ccd4a63SDavid du Colombier
5*8ccd4a63SDavid du Colombier SmbProcessResult
smbcomtreeconnectandx(SmbSession * s,SmbHeader * h,uchar * pdata,SmbBuffer * b)6*8ccd4a63SDavid du Colombier smbcomtreeconnectandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
7*8ccd4a63SDavid du Colombier {
8*8ccd4a63SDavid du Colombier uchar andxcommand;
9*8ccd4a63SDavid du Colombier ushort andxoffset;
10*8ccd4a63SDavid du Colombier char *path = nil;
11*8ccd4a63SDavid du Colombier char *service = nil;
12*8ccd4a63SDavid du Colombier ushort flags;
13*8ccd4a63SDavid du Colombier ushort passwordlength;
14*8ccd4a63SDavid du Colombier // ushort bytecount;
15*8ccd4a63SDavid du Colombier uchar errclass;
16*8ccd4a63SDavid du Colombier ushort error;
17*8ccd4a63SDavid du Colombier SmbService *serv;
18*8ccd4a63SDavid du Colombier SmbTree *tree;
19*8ccd4a63SDavid du Colombier ulong andxfixupoffset, bytecountfixup;
20*8ccd4a63SDavid du Colombier SmbProcessResult pr;
21*8ccd4a63SDavid du Colombier
22*8ccd4a63SDavid du Colombier if (!smbcheckwordcount("comtreeconnectandx", h, 4)) {
23*8ccd4a63SDavid du Colombier fmtfail:
24*8ccd4a63SDavid du Colombier pr = SmbProcessResultFormat;
25*8ccd4a63SDavid du Colombier goto done;
26*8ccd4a63SDavid du Colombier }
27*8ccd4a63SDavid du Colombier
28*8ccd4a63SDavid du Colombier switch (s->state) {
29*8ccd4a63SDavid du Colombier case SmbSessionNeedNegotiate:
30*8ccd4a63SDavid du Colombier smblogprint(-1, "smbcomtreeconnectandx: called when negotiate expected\n");
31*8ccd4a63SDavid du Colombier return SmbProcessResultUnimp;
32*8ccd4a63SDavid du Colombier case SmbSessionNeedSetup:
33*8ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRbadpw);
34*8ccd4a63SDavid du Colombier return SmbProcessResultError;
35*8ccd4a63SDavid du Colombier }
36*8ccd4a63SDavid du Colombier
37*8ccd4a63SDavid du Colombier andxcommand = *pdata++;
38*8ccd4a63SDavid du Colombier switch (andxcommand) {
39*8ccd4a63SDavid du Colombier case SMB_COM_OPEN:
40*8ccd4a63SDavid du Colombier case SMB_COM_CREATE_NEW:
41*8ccd4a63SDavid du Colombier case SMB_COM_DELETE_DIRECTORY:
42*8ccd4a63SDavid du Colombier case SMB_COM_FIND_UNIQUE:
43*8ccd4a63SDavid du Colombier case SMB_COM_CHECK_DIRECTORY:
44*8ccd4a63SDavid du Colombier case SMB_COM_GET_PRINT_QUEUE:
45*8ccd4a63SDavid du Colombier case SMB_COM_TRANSACTION:
46*8ccd4a63SDavid du Colombier case SMB_COM_SET_INFORMATION:
47*8ccd4a63SDavid du Colombier case SMB_COM_OPEN_ANDX:
48*8ccd4a63SDavid du Colombier case SMB_COM_CREATE_DIRECTORY:
49*8ccd4a63SDavid du Colombier case SMB_COM_FIND:
50*8ccd4a63SDavid du Colombier case SMB_COM_RENAME:
51*8ccd4a63SDavid du Colombier case SMB_COM_QUERY_INFORMATION:
52*8ccd4a63SDavid du Colombier case SMB_COM_OPEN_PRINT_FILE:
53*8ccd4a63SDavid du Colombier case SMB_COM_NO_ANDX_COMMAND:
54*8ccd4a63SDavid du Colombier case SMB_COM_NT_RENAME:
55*8ccd4a63SDavid du Colombier case SMB_COM_CREATE:
56*8ccd4a63SDavid du Colombier case SMB_COM_DELETE:
57*8ccd4a63SDavid du Colombier case SMB_COM_COPY:
58*8ccd4a63SDavid du Colombier break;
59*8ccd4a63SDavid du Colombier default:
60*8ccd4a63SDavid du Colombier smblogprint(h->command, "smbcomtreeconnectandx: invalid andxcommand %s (0x%.2ux)\n",
61*8ccd4a63SDavid du Colombier smboptable[andxcommand].name, andxcommand);
62*8ccd4a63SDavid du Colombier goto fmtfail;
63*8ccd4a63SDavid du Colombier }
64*8ccd4a63SDavid du Colombier pdata++;
65*8ccd4a63SDavid du Colombier andxoffset = smbnhgets(pdata); pdata += 2;
66*8ccd4a63SDavid du Colombier flags = smbnhgets(pdata); pdata += 2;
67*8ccd4a63SDavid du Colombier passwordlength = smbnhgets(pdata); //pdata += 2;
68*8ccd4a63SDavid du Colombier // bytecount = smbnhgets(pdata); pdata += 2;
69*8ccd4a63SDavid du Colombier smblogprint(h->command, "passwordlength: %ud\n", passwordlength);
70*8ccd4a63SDavid du Colombier smblogprint(h->command, "flags: 0x%.4ux\n", flags);
71*8ccd4a63SDavid du Colombier if (!smbbuffergetbytes(b, nil, passwordlength)) {
72*8ccd4a63SDavid du Colombier smblogprint(h->command, "smbcomtreeconnectandx: not enough bytes for password\n");
73*8ccd4a63SDavid du Colombier goto fmtfail;
74*8ccd4a63SDavid du Colombier }
75*8ccd4a63SDavid du Colombier smblogprint(h->command, "offset %lud limit %lud\n", smbbufferreadoffset(b), smbbufferwriteoffset(b));
76*8ccd4a63SDavid du Colombier if (!smbbuffergetstring(b, h, SMB_STRING_PATH, &path)
77*8ccd4a63SDavid du Colombier || !smbbuffergetstr(b, 0, &service)) {
78*8ccd4a63SDavid du Colombier smblogprint(h->command, "smbcomtreeconnectandx: not enough bytes for strings\n");
79*8ccd4a63SDavid du Colombier goto fmtfail;
80*8ccd4a63SDavid du Colombier }
81*8ccd4a63SDavid du Colombier smblogprint(h->command, "path: %s\n", path);
82*8ccd4a63SDavid du Colombier smblogprint(h->command, "service: %s\n", service);
83*8ccd4a63SDavid du Colombier if (flags & 1)
84*8ccd4a63SDavid du Colombier smbtreedisconnectbyid(s, h->tid);
85*8ccd4a63SDavid du Colombier serv = smbservicefind(s, path, service, &errclass, &error);
86*8ccd4a63SDavid du Colombier if (serv == nil) {
87*8ccd4a63SDavid du Colombier pr = SmbProcessResultError;
88*8ccd4a63SDavid du Colombier smbseterror(s, errclass, error);
89*8ccd4a63SDavid du Colombier goto done;
90*8ccd4a63SDavid du Colombier }
91*8ccd4a63SDavid du Colombier tree = smbtreeconnect(s, serv);
92*8ccd4a63SDavid du Colombier h->tid = tree->id;
93*8ccd4a63SDavid du Colombier h->wordcount = 3;
94*8ccd4a63SDavid du Colombier if (!smbresponseputandxheader(s, h, andxcommand, &andxfixupoffset)
95*8ccd4a63SDavid du Colombier || !smbresponseputs(s, 1)) {
96*8ccd4a63SDavid du Colombier misc:
97*8ccd4a63SDavid du Colombier pr = SmbProcessResultMisc;
98*8ccd4a63SDavid du Colombier goto done;
99*8ccd4a63SDavid du Colombier }
100*8ccd4a63SDavid du Colombier bytecountfixup = smbresponseoffset(s);
101*8ccd4a63SDavid du Colombier if (!smbresponseputs(s, 0)
102*8ccd4a63SDavid du Colombier || !smbresponseputstr(s, serv->type)
103*8ccd4a63SDavid du Colombier || !smbresponseputstring(s, 1, s9p2000))
104*8ccd4a63SDavid du Colombier goto misc;
105*8ccd4a63SDavid du Colombier if (!smbbufferfixuprelatives(s->response, bytecountfixup))
106*8ccd4a63SDavid du Colombier goto misc;
107*8ccd4a63SDavid du Colombier if (andxcommand != SMB_COM_NO_ANDX_COMMAND) {
108*8ccd4a63SDavid du Colombier pr = smbchaincommand(s, h, andxfixupoffset, andxcommand, andxoffset, b);
109*8ccd4a63SDavid du Colombier }
110*8ccd4a63SDavid du Colombier else
111*8ccd4a63SDavid du Colombier pr = SmbProcessResultReply;
112*8ccd4a63SDavid du Colombier done:
113*8ccd4a63SDavid du Colombier free(path);
114*8ccd4a63SDavid du Colombier free(service);
115*8ccd4a63SDavid du Colombier return pr;
116*8ccd4a63SDavid du Colombier }
117