1 #include "headers.h"
2
3 static int
sendresponse(void * magic,SmbBuffer *,char ** errmsgp)4 sendresponse(void *magic, SmbBuffer *, char **errmsgp)
5 {
6 int rv;
7 SmbSession *s = magic;
8 rv = smbresponsesend(s);
9 if (rv < 0) {
10 smbstringprint(errmsgp, "sendresponse failed");
11 return 0;
12 }
13 return 1;
14 }
15
16 SmbTransactionMethod smbtransactionmethod = {
17 .encoderesponse = smbtransactionencoderesponse,
18 .sendresponse = sendresponse,
19 };
20
21 SmbTransactionMethod smbtransactionmethod2 = {
22 .encoderesponse = smbtransactionencoderesponse2,
23 .sendresponse = sendresponse,
24 };
25
26 int
smbcomtransaction(SmbSession * s,SmbHeader * h,uchar * pdata,SmbBuffer * b)27 smbcomtransaction(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
28 {
29 int rv;
30 char *errmsg;
31 SmbProcessResult pr = SmbProcessResultDie;
32 errmsg = nil;
33 rv = smbtransactiondecodeprimary(&s->transaction, h, pdata, b, &errmsg);
34 if (rv < 0) {
35 pr = SmbProcessResultFormat;
36 goto done;
37 }
38 if (rv == 0) {
39 h->wordcount = 0;
40 if (smbbufferputack(s->response, h, &s->peerinfo)) {
41 pr = SmbProcessResultReply;
42 s->nextcommand = SMB_COM_TRANSACTION_SECONDARY;
43 }
44 goto done;
45 }
46 smblogprint(h->command, "smbcomtransaction: %s scount %ud tpcount %lud tdcount %lud maxscount %lud maxpcount %lud maxdcount %lud\n",
47 s->transaction.in.name, s->transaction.in.scount, s->transaction.in.tpcount, s->transaction.in.tdcount,
48 s->transaction.in.maxscount, s->transaction.in.maxpcount, s->transaction.in.maxdcount);
49 smbbufferfree(&s->transaction.out.parameters);
50 smbbufferfree(&s->transaction.out.data);
51 s->transaction.out.parameters = smbbuffernew(s->transaction.in.maxpcount);
52 s->transaction.out.data = smbbuffernew(s->transaction.in.maxdcount);
53 if (strcmp(s->transaction.in.name, smbglobals.pipelanman) == 0)
54 pr = smbrap2(s);
55 else {
56 smbseterror(s, ERRDOS, ERRbadpath);
57 pr = SmbProcessResultError;
58 goto done;
59 }
60 if (pr == SmbProcessResultReply) {
61 char *errmsg;
62 errmsg = nil;
63 rv = smbtransactionrespond(&s->transaction, h, &s->peerinfo, s->response, &smbtransactionmethod, s, &errmsg);
64 if (!rv) {
65 smblogprint(h->command, "smbcomtransaction: failed: %s\n", errmsg);
66 pr = SmbProcessResultMisc;
67 }
68 else
69 pr = SmbProcessResultOk;
70 }
71 done:
72 free(errmsg);
73 return pr;
74 }
75
76 int
smbcomtransaction2(SmbSession * s,SmbHeader * h,uchar * pdata,SmbBuffer * b)77 smbcomtransaction2(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
78 {
79 int rv;
80 char *errmsg;
81 SmbProcessResult pr = SmbProcessResultDie;
82 ushort op;
83
84 errmsg = nil;
85 rv = smbtransactiondecodeprimary2(&s->transaction, h, pdata, b, &errmsg);
86 if (rv < 0) {
87 fmtfail:
88 pr = SmbProcessResultFormat;
89 goto done;
90 }
91 if (rv == 0) {
92 h->wordcount = 0;
93 if (smbbufferputack(s->response, h, &s->peerinfo)) {
94 pr = SmbProcessResultReply;
95 s->nextcommand = SMB_COM_TRANSACTION2_SECONDARY;
96 }
97 goto done;
98 }
99 smblogprint(h->command, "smbcomtransaction2: scount %ud tpcount %lud tdcount %lud maxscount %lud maxpcount %lud maxdcount %lud\n",
100 s->transaction.in.scount, s->transaction.in.tpcount, s->transaction.in.tdcount,
101 s->transaction.in.maxscount, s->transaction.in.maxpcount, s->transaction.in.maxdcount);
102 smbbufferfree(&s->transaction.out.parameters);
103 smbbufferfree(&s->transaction.out.data);
104 s->transaction.out.parameters = smbbuffernew(s->transaction.in.maxpcount);
105 s->transaction.out.data = smbbuffernew(s->transaction.in.maxdcount);
106 if (s->transaction.in.scount != 1)
107 goto fmtfail;
108 op = s->transaction.in.setup[0];
109 if (op >= smbtrans2optablesize || smbtrans2optable[op].name == nil) {
110 smblogprint(-1, "smbcomtransaction2: function %d unknown\n", op);
111 pr = SmbProcessResultUnimp;
112 goto done;
113 }
114 if (smbtrans2optable[op].process == nil) {
115 smblogprint(-1, "smbcomtransaction2: %s unimplemented\n", smbtrans2optable[op].name);
116 pr = SmbProcessResultUnimp;
117 goto done;
118 }
119 pr = (*smbtrans2optable[op].process)(s, h);
120 if (pr == SmbProcessResultReply) {
121 char *errmsg;
122 errmsg = nil;
123 rv = smbtransactionrespond(&s->transaction, h, &s->peerinfo, s->response, &smbtransactionmethod2, s, &errmsg);
124 if (!rv) {
125 smblogprint(h->command, "smbcomtransaction2: failed: %s\n", errmsg);
126 pr = SmbProcessResultMisc;
127 }
128 else
129 pr = SmbProcessResultOk;
130 }
131 done:
132 free(errmsg);
133 return pr;
134 }
135
136
137
138