Loading src/rpc.cpp +44 −1 Changes for src/rpc.cpp: 44 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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}; Loading Loading @@ -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); Loading @@ -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; } Loading Loading
src/rpc.cpp +44 −1 Changes for src/rpc.cpp: 44 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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}; Loading Loading @@ -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); Loading @@ -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; } Loading