#include "headers.h"
static int
sendresponse(void *magic, SmbBuffer *, char **errmsgp)
{
int rv;
SmbSession *s = magic;
rv = smbresponsesend(s);
if (rv < 0) {
smbstringprint(errmsgp, "sendresponse failed");
return 0;
}
return 1;
}
SmbTransactionMethod smbtransactionmethod = {
.encoderesponse = smbtransactionencoderesponse,
.sendresponse = sendresponse,
};
SmbTransactionMethod smbtransactionmethod2 = {
.encoderesponse = smbtransactionencoderesponse2,
.sendresponse = sendresponse,
};
int
smbcomtransaction(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
{
int rv;
char *errmsg;
SmbProcessResult pr = SmbProcessResultDie;
errmsg = nil;
rv = smbtransactiondecodeprimary(&s->transaction, h, pdata, b, &errmsg);
if (rv < 0) {
pr = SmbProcessResultFormat;
goto done;
}
if (rv == 0) {
h->wordcount = 0;
if (smbbufferputack(s->response, h, &s->peerinfo)) {
pr = SmbProcessResultReply;
s->nextcommand = SMB_COM_TRANSACTION_SECONDARY;
}
goto done;
}
smblogprint(h->command, "smbcomtransaction: %s scount %ud tpcount %lud tdcount %lud maxscount %lud maxpcount %lud maxdcount %lud\n",
s->transaction.in.name, s->transaction.in.scount, s->transaction.in.tpcount, s->transaction.in.tdcount,
s->transaction.in.maxscount, s->transaction.in.maxpcount, s->transaction.in.maxdcount);
smbbufferfree(&s->transaction.out.parameters);
smbbufferfree(&s->transaction.out.data);
s->transaction.out.parameters = smbbuffernew(s->transaction.in.maxpcount);
s->transaction.out.data = smbbuffernew(s->transaction.in.maxdcount);
if (strcmp(s->transaction.in.name, smbglobals.pipelanman) == 0)
pr = smbrap2(s);
else {
smbseterror(s, ERRDOS, ERRbadpath);
pr = SmbProcessResultError;
goto done;
}
if (pr == SmbProcessResultReply) {
char *errmsg;
errmsg = nil;
rv = smbtransactionrespond(&s->transaction, h, &s->peerinfo, s->response, &smbtransactionmethod, s, &errmsg);
if (!rv) {
smblogprint(h->command, "smbcomtransaction: failed: %s\n", errmsg);
pr = SmbProcessResultMisc;
}
else
pr = SmbProcessResultOk;
}
done:
free(errmsg);
return pr;
}
int
smbcomtransaction2(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
{
int rv;
char *errmsg;
SmbProcessResult pr = SmbProcessResultDie;
ushort op;
errmsg = nil;
rv = smbtransactiondecodeprimary2(&s->transaction, h, pdata, b, &errmsg);
if (rv < 0) {
fmtfail:
pr = SmbProcessResultFormat;
goto done;
}
if (rv == 0) {
h->wordcount = 0;
if (smbbufferputack(s->response, h, &s->peerinfo)) {
pr = SmbProcessResultReply;
s->nextcommand = SMB_COM_TRANSACTION2_SECONDARY;
}
goto done;
}
smblogprint(h->command, "smbcomtransaction2: scount %ud tpcount %lud tdcount %lud maxscount %lud maxpcount %lud maxdcount %lud\n",
s->transaction.in.scount, s->transaction.in.tpcount, s->transaction.in.tdcount,
s->transaction.in.maxscount, s->transaction.in.maxpcount, s->transaction.in.maxdcount);
smbbufferfree(&s->transaction.out.parameters);
smbbufferfree(&s->transaction.out.data);
s->transaction.out.parameters = smbbuffernew(s->transaction.in.maxpcount);
s->transaction.out.data = smbbuffernew(s->transaction.in.maxdcount);
if (s->transaction.in.scount != 1)
goto fmtfail;
op = s->transaction.in.setup[0];
if (op >= smbtrans2optablesize || smbtrans2optable[op].name == nil) {
smblogprint(-1, "smbcomtransaction2: function %d unknown\n", op);
pr = SmbProcessResultUnimp;
goto done;
}
if (smbtrans2optable[op].process == nil) {
smblogprint(-1, "smbcomtransaction2: %s unimplemented\n", smbtrans2optable[op].name);
pr = SmbProcessResultUnimp;
goto done;
}
pr = (*smbtrans2optable[op].process)(s, h);
if (pr == SmbProcessResultReply) {
char *errmsg;
errmsg = nil;
rv = smbtransactionrespond(&s->transaction, h, &s->peerinfo, s->response, &smbtransactionmethod2, s, &errmsg);
if (!rv) {
smblogprint(h->command, "smbcomtransaction2: failed: %s\n", errmsg);
pr = SmbProcessResultMisc;
}
else
pr = SmbProcessResultOk;
}
done:
free(errmsg);
return pr;
}
|