Commit 5a0ea224 authored by jan.koester's avatar jan.koester
Browse files

rpc fix

parent 77770b0e
Loading
Loading
Loading
Loading
+44 −1
Changes for src/rpc.cpp: 44 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ namespace {
// ksmbd's codes (fs/smb/server/ksmbd_netlink.h)
constexpr uint32_t RpcOk = 0;
constexpr uint32_t RpcNotImplemented = 0x40;
constexpr uint32_t MethodSrvsvc = 1u << 1, MethodWkssvc = 1u << 2;
constexpr uint32_t MethodSrvsvc = 1u << 1, MethodWkssvc = 1u << 2, MethodLsarpc = 1u << 11;

// DCE/RPC (C706 chapter 12, connection-oriented)
enum : uint8_t { PtypeRequest = 0, PtypeResponse = 2, PtypeFault = 3, PtypeBind = 11, PtypeBindAck = 12,
@@ -76,6 +76,8 @@ const uint8_t WkssvcTail[8] = {0x98, 0x33, 0x46, 0xc3, 0xf8, 0x7e, 0x34, 0x5a};
const uint8_t Ndr32Tail[8] = {0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60};
const Syntax Srvsvc = syntax(0x4b324fc8, 0x1670, 0x01d3, SrvsvcTail, 3);
const Syntax Wkssvc = syntax(0x6bffd098, 0xa112, 0x3610, WkssvcTail, 1);
const uint8_t LsarpcTail[8] = {0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab};
const Syntax Lsarpc = syntax(0x12345778, 0x1234, 0xabcd, LsarpcTail, 0);
const Syntax Ndr32 = syntax(0x8a885d04, 0x1ceb, 0x11c9, Ndr32Tail, 2);
// the bind-time feature negotiation "syntax" 6cb71c2c-9812-4540-xxxx-...
const uint8_t BindTimeHead[8] = {0x2c, 0x1c, 0xb7, 0x6c, 0x12, 0x98, 0x40, 0x45};
@@ -130,8 +132,30 @@ struct NdrOut {
    uint32_t referent = 0x00020000;

    void align(size_t n) { while (b.size() % n) b.push_back(0); }
    void u8(uint8_t v) { b.push_back(v); }
    void u16(uint16_t v) { align(2); put16(b, v); }
    void u32(uint32_t v) { align(4); put32(b, v); }
    void ptr(bool present) { u32(present ? (referent += 4) : 0); }
    // lsa_String(Large): Length, MaximumLength, Buffer pointer; the buffer
    // (lsaBuffer) follows deferred, conformant varying, no NUL
    void lsaString(const std::string &s, bool large) {
        uint16_t len = (uint16_t)(utf16(s).size() * 2);
        u16(len);
        u16(large ? (uint16_t)(len + 2) : len);
        ptr(true);
    }
    void lsaBuffer(const std::string &s, bool large) {
        std::vector<uint16_t> w = utf16(s);
        u32((uint32_t)w.size() + (large ? 1 : 0));
        u32(0);
        u32((uint32_t)w.size());
        for (uint16_t c : w) put16(b, c);
    }
    // dom_sid2: the sub-authority count (conformance), then the SID
    void sid(const std::vector<uint8_t> &bin) {
        u32(bin.size() >= 8 ? bin[1] : 0);
        b.insert(b.end(), bin.begin(), bin.end());
    }
    // a conformant varying string of WCHAR, with its terminating NUL
    void str(const std::string &s) {
        std::vector<uint16_t> w = utf16(s);
@@ -151,6 +175,25 @@ struct NdrIn {

    explicit NdrIn(const RpcPipes::Bytes &bytes) : b(bytes) {}
    void align(size_t n) { pos = (pos + n - 1) / n * n; }
    uint16_t u16() {
        align(2);
        if (pos + 2 > b.size()) { ok = false; return 0; }
        uint16_t v = le16(&b[pos]);
        pos += 2;
        return v;
    }
    void skip(size_t n) { if (pos + n > b.size()) ok = false; else pos += n; }
    // dom_sid2 as binary; empty if malformed
    std::vector<uint8_t> sid() {
        uint32_t count = u32();
        if (!ok || count > 15 || pos + 8 + count * 4 > b.size() || b[pos] != 1 || b[pos + 1] != count) {
            ok = false;
            return {};
        }
        std::vector<uint8_t> out(b.begin() + pos, b.begin() + pos + 8 + count * 4);
        pos += 8 + count * 4;
        return out;
    }
    uint32_t u32() {
        align(4);
        if (pos + 4 > b.size()) { ok = false; return 0; }