Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#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;
}