xref: /plan9/sys/src/cmd/aquarela/smbcomtransaction.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
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