1 #include "headers.h"
2
3 static SmbTransactionMethod smbtransactionmethodrap = {
4 .encodeprimary = smbtransactionencodeprimary,
5 .sendrequest = smbtransactionclientsend,
6 .receiveresponse = smbtransactionclientreceive,
7 .decoderesponse = smbtransactiondecoderesponse,
8 };
9
10 int
smbclientrap(SmbClient * c,SmbBuffer * inparam,SmbBuffer * outparam,SmbBuffer * outdata,char ** errmsgp)11 smbclientrap(SmbClient *c, SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata, char **errmsgp)
12 {
13 SmbTransaction transaction;
14 SmbHeader h;
15 memset(&transaction, 0, sizeof(transaction));
16 transaction.in.name = smbglobals.pipelanman;
17 transaction.in.parameters = smbbufferreadpointer(inparam);
18 transaction.in.tpcount = smbbufferreadspace(inparam);
19 transaction.in.maxpcount = smbbufferwritespace(outparam);
20 transaction.in.maxdcount = smbbufferwritespace(outdata);
21 transaction.out.parameters = outparam;
22 transaction.out.data = outdata;
23 h = c->protoh;
24 h.tid = c->ipctid;
25 h.mid = 0;
26 return smbtransactionexecute(&transaction, &h, &c->peerinfo, c->b, &smbtransactionmethodrap, c, nil, errmsgp);
27 }
28
29 int
smbnetserverenum2(SmbClient * c,ulong stype,char * domain,int * entriesp,SmbRapServerInfo1 ** sip,char ** errmsgp)30 smbnetserverenum2(SmbClient *c, ulong stype, char *domain, int *entriesp, SmbRapServerInfo1 **sip, char **errmsgp)
31 {
32 int rv;
33 ushort ec, entries, total, converter;
34 SmbRapServerInfo1 *si = nil;
35 SmbBuffer *ipb = smbbuffernew(512);
36 SmbBuffer *odb = smbbuffernew(65535);
37 SmbBuffer *opb = smbbuffernew(8);
38 smbbufferputs(ipb, 104);
39 smbbufferputstring(ipb, nil, SMB_STRING_ASCII, "WrLehDz");
40 smbbufferputstring(ipb, nil, SMB_STRING_ASCII, "B16BBDz");
41 smbbufferputs(ipb, 1);
42 smbbufferputs(ipb, smbbufferwritespace(odb));
43 smbbufferputl(ipb, stype);
44 smbbufferputstring(ipb, nil, SMB_STRING_ASCII, domain);
45 rv = !smbclientrap(c, ipb, opb, odb, errmsgp);
46 smbbufferfree(&ipb);
47 if (rv == 0) {
48 char *remark, *eremark;
49 int remarkspace;
50 int i;
51 if (!smbbuffergets(opb, &ec)
52 || !smbbuffergets(opb, &converter)
53 || !smbbuffergets(opb, &entries)
54 || !smbbuffergets(opb, &total)) {
55 smbstringprint(errmsgp, "smbnetserverenum2: not enough return parameters");
56 rv = -1;
57 goto done;
58 }
59 if (ec != 0) {
60 rv = ec;
61 goto done;
62 }
63 if (smbbufferreadspace(odb) < entries * 26) {
64 smbstringprint(errmsgp, "smbnetserverenum2: not enough return data");
65 rv = -1;
66 goto done;
67 }
68 remarkspace = smbbufferreadspace(odb) - entries * 26;
69 si = smbemalloc(entries * sizeof(SmbRapServerInfo1) + remarkspace);
70 remark = (char *)&si[entries];
71 eremark = remark + remarkspace;
72 for (i = 0; i < entries; i++) {
73 ulong offset;
74 int remarklen;
75 assert(smbbuffergetbytes(odb, si[i].name, 16));
76 assert(smbbuffergetb(odb, &si[i].vmaj));
77 assert(smbbuffergetb(odb, &si[i].vmin));
78 assert(smbbuffergetl(odb, &si[i].type));
79 assert(smbbuffergetl(odb, &offset));
80 offset -= converter;
81 if (!smbbufferoffsetcopystr(odb, offset, remark, eremark - remark, &remarklen)) {
82 smbstringprint(errmsgp, "smbnetserverenum2: invalid string offset");
83 rv = -1;
84 goto done;
85 }
86 si[i].remark = remark;
87 remark += remarklen;
88 }
89 *sip = si;
90 si = nil;
91 *entriesp = entries;
92 }
93 else
94 rv = -1;
95 done:
96 free(si);
97 smbbufferfree(&opb);
98 smbbufferfree(&odb);
99 return rv;
100 }
101