📄 smbrap2.c
字号:
#include "headers.h"typedef struct RapTableEntry RapTableEntry;struct RapTableEntry { char *name; SmbProcessResult (*procedure)(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata);};typedef int INFOSIZEFN(ushort level, void *data);typedef int INFOPUTFN(SmbBuffer *b, ushort level, void *data);typedef int INFOPUTSTRINGSFN(SmbBuffer *b, ushort level, int instance, void *data);typedef void *INFOENUMERATEFN(void *magic, int i);typedef struct InfoMethod { INFOSIZEFN *size; INFOPUTFN *put; INFOPUTSTRINGSFN *putstrings; INFOENUMERATEFN *enumerate;} InfoMethod;static intserverinfosize(ushort level, void *data){ SmbServerInfo *si = data; switch (level) { case 0: return 16; case 1: return 26 + smbstrlen(si->remark); default: return 0; }}static intserverinfoput(SmbBuffer *b, ushort level, void *data){ SmbServerInfo *si = data; if (!smbbufferputstrn(b, si->name, 16, 1)) return 0; if (level > 0) { if (!smbbufferputb(b, si->vmaj) || !smbbufferputb(b, si->vmin) || !smbbufferputl(b, si->stype) || !smbbufferputl(b, 0)) return 0; } if (level > 1) return 0; return 1;}static intserverinfoputstrings(SmbBuffer *b, ushort level, int instance, void *data){ SmbServerInfo *si = data; if (level == 1) { if (!smbbufferfixupabsolutel(b, instance * 26 + 22) || !smbbufferputstring(b, nil, SMB_STRING_ASCII, si->remark)) return 0; } return 1;}static void *serverinfoenumerate(void *magic, int i){ if (magic) { SmbServerInfo **si = magic; return si[i]; } if (i == 0) return &smbglobals.serverinfo; return nil;}InfoMethod serverinfo = { serverinfosize, serverinfoput, serverinfoputstrings, serverinfoenumerate,};static intshareinfosize(ushort level, void *data){ SmbService *serv = data; switch (level) { case 0: return 13; case 1: return 20 + smbstrlen(serv->remark); case 2: return 40 + smbstrlen(serv->remark) + smbstrlen(serv->path); default: return 0; }}static intshareinfoput(SmbBuffer *b, ushort level, void *data){ SmbService *serv = data; if (!smbbufferputstrn(b, serv->name, 13, 0)) return 0; if (level > 0) { if (!smbbufferputb(b, 0) || !smbbufferputs(b, serv->stype) || !smbbufferputl(b, 0)) return 0; } if (level > 1) { if (!smbbufferputs(b, 7) || !smbbufferputs(b, -1) || !smbbufferputs(b, serv->ref) || !smbbufferputl(b, 0) || !smbbufferfill(b, 0, 10)) return 0; } if (level > 2) return 0; return 1;}static intshareinfoputstrings(SmbBuffer *b, ushort level, int instance, void *data){ SmbService *serv = data; switch (level) { case 0: break; case 1: if (!smbbufferfixupabsolutel(b, instance * 20 + 16) || !smbbufferputstring(b, nil, SMB_STRING_ASCII, serv->remark)) return 0; break; case 2: if (!smbbufferfixupabsolutel(b, instance * 40 + 16) || !smbbufferputstring(b, nil, SMB_STRING_ASCII, serv->remark) || !smbbufferfixupabsolutel(b, instance * 40 + 26) || !smbbufferputstring(b, nil, SMB_STRING_ASCII, serv->path)) return 0; break; default: return 0; } return 1;}static void *shareinfoenumerate(void *, int i){ SmbService *serv; for (serv = smbservices; i-- > 0 && serv; serv = serv->next) ; return serv;}static InfoMethod shareinfo = { shareinfosize, shareinfoput, shareinfoputstrings, shareinfoenumerate,};static SmbProcessResultthingfill(SmbBuffer *outparam, SmbBuffer *outdata, InfoMethod *m, ushort level, void *magic){ int sentthings, totalthings; int i; int totalbytes; sentthings = 0; totalbytes = 0; for (i = 0; ; i++) { int len; void *thing = (*m->enumerate)(magic, i); if (thing == nil) break; len = (*m->size)(level, thing); if (totalbytes + len <= smbbufferspace(outdata)) { assert((*m->put)(outdata, level, thing)); sentthings++; } totalbytes += len; } totalthings = i; for (i = 0; i < sentthings; i++) { void *thing = (*m->enumerate)(magic, i); assert(thing); assert((*m->putstrings)(outdata, level, i, thing)); } if (!smbbufferputs(outparam, sentthings < totalthings ? SMB_RAP_ERROR_MORE_DATA : SMB_RAP_NERR_SUCCESS) || !smbbufferputs(outparam, 0) || !smbbufferputs(outparam, totalthings) || !smbbufferputs(outparam, sentthings)) return SmbProcessResultFormat; return SmbProcessResultReply;}static SmbProcessResultonethingfill(SmbBuffer *outparam, SmbBuffer *outdata, InfoMethod *m, ushort level, void *thing){ int moredata; int totalbytes = (*m->size)(level, thing); if (totalbytes <= smbbufferspace(outdata)) { assert((*m->put)(outdata, level, thing)); assert((*m->putstrings)(outdata, level, 0, thing)); moredata = 0; } else moredata = 1; if (!smbbufferputs(outparam, moredata ? SMB_RAP_ERROR_MORE_DATA : SMB_RAP_NERR_SUCCESS) || !smbbufferputs(outparam, 0) || !smbbufferputs(outparam, totalbytes)) return SmbProcessResultFormat; return SmbProcessResultReply;}static SmbProcessResultnetshareenum(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata){ ushort level; /* WrLeh */ /* ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ENTCOUNT pcEntriesRead, ushort *pcTotalAvail */ if (!smbbuffergets(inparam, &level)) return SmbProcessResultFormat; smblogprintif(smbglobals.log.rap2, "netshareenum(%lud, %lud)\n", level, smbbufferwritespace(outdata)); if (level != 1) return SmbProcessResultFormat; return thingfill(outparam, outdata, &shareinfo, level, nil);}static SmbProcessResultnetserverenum2(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata){ ushort level, rbl; char *domain; ulong servertype; SmbProcessResult pr; SmbServerInfo *si[3]; SmbServerInfo domainsi; int entries; /* WrLehDz * ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ENTCOUNT pcEntriesRead, ushort *pcTotalAvail, * ulong fServerType, char *pszDomain */ if (!smbbuffergets(inparam, &level) || !smbbuffergets(inparam, &rbl) || !smbbuffergetl(inparam, &servertype) || !smbbuffergetstr(inparam, 0, &domain)) { fmtfail: pr = SmbProcessResultFormat; goto done; } smblogprintif(smbglobals.log.rap2, "netserverenum2(%lud, %lud, 0x%.8lux, %s)\n", level, smbbufferwritespace(outdata), servertype, domain); if (level > 1) goto fmtfail; if (servertype == 0xffffffff) servertype &= ~(SV_TYPE_DOMAIN_ENUM | SV_TYPE_LOCAL_LIST_ONLY); if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0 && (servertype & SV_TYPE_DOMAIN_ENUM) == 0) servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM); entries = 0; if ((servertype & SV_TYPE_SERVER) != 0 && (domain[0] == 0 || cistrcmp(domain, smbglobals.primarydomain) == 0)) { si[entries++] = &smbglobals.serverinfo; } if ((servertype & SV_TYPE_DOMAIN_ENUM) != 0) { /* there's only one that I know about */ memset(&domainsi, 0, sizeof(domainsi)); domainsi.name = smbglobals.primarydomain; domainsi.stype = SV_TYPE_DOMAIN_ENUM; si[entries++] = &domainsi; } si[entries] = 0; pr = thingfill(outparam, outdata, &serverinfo, level, si); done: free(domain); return pr;}static SmbProcessResultnetsharegetinfo(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata){ char *netname; ushort level; SmbProcessResult pr; SmbService *serv; /* * zWrLh * char *pszNetName, ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ushort *pcbTotalAvail */ if (!smbbuffergetstrinline(inparam, &netname) || !smbbuffergets(inparam, &level)) { fmtfail: pr = SmbProcessResultFormat; goto done; } smblogprintif(smbglobals.log.rap2, "netsharegetinfo(%s, %lud, %lud)\n", netname, level, smbbufferwritespace(outdata)); if (level > 2) goto fmtfail; for (serv = smbservices; serv; serv = serv->next) if (cistrcmp(serv->name, netname) == 0) break; if (serv == nil) { smblogprint(-1, "netsharegetinfo: service %s unimplemented\n", netname); pr = SmbProcessResultUnimp; goto done; } pr = onethingfill(outparam, outdata, &shareinfo, level, serv);done: return pr;}static SmbProcessResultnetservergetinfo(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata){ ushort level; SmbProcessResult pr; /* WrLh * ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ushort *pcbTotalAvail */ if (!smbbuffergets(inparam, &level)) { fmtfail: pr = SmbProcessResultFormat; goto done; } smblogprintif(smbglobals.log.rap2, "netservergetinfo(%lud, %lud)\n", level, smbbufferwritespace(outdata)); if (level > 1) goto fmtfail; pr = onethingfill(outparam, outdata, &shareinfo, level, &smbglobals.serverinfo); done: return pr;}static SmbProcessResultnetwkstagetinfo(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata){ ushort level; ushort usefulbytes; SmbProcessResult pr; int moredata; /* WrLh * ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ushort *pcbTotalAvail */ if (!smbbuffergets(inparam, &level)) { fmtfail: pr = SmbProcessResultFormat; goto done; } smblogprintif(smbglobals.log.rap2, "netwkstagetinfo(%lud, %lud)\n", level, smbbufferwritespace(outdata)); if (level != 10) goto fmtfail; usefulbytes = 22 + smbstrlen(smbglobals.serverinfo.name) + smbstrlen(getuser()) + 3 * smbstrlen(smbglobals.primarydomain); moredata = usefulbytes > smbbufferwritespace(outdata); assert(smbbufferputl(outdata, 0)); assert(smbbufferputl(outdata, 0)); assert(smbbufferputl(outdata, 0)); assert(smbbufferputb(outdata, smbglobals.serverinfo.vmaj)); assert(smbbufferputb(outdata, smbglobals.serverinfo.vmin)); assert(smbbufferputl(outdata, 0)); assert(smbbufferputl(outdata, 0)); assert(smbbufferfixupabsolutel(outdata, 0)); assert(smbbufferputstring(outdata, nil, SMB_STRING_ASCII, smbglobals.serverinfo.name)); assert(smbbufferfixupabsolutel(outdata, 4)); assert(smbbufferputstring(outdata, nil, SMB_STRING_ASCII, getuser())); assert(smbbufferfixupabsolutel(outdata, 8)); assert(smbbufferputstring(outdata, nil, SMB_STRING_ASCII, smbglobals.primarydomain)); assert(smbbufferfixupabsolutel(outdata, 14)); assert(smbbufferputstring(outdata, nil, SMB_STRING_ASCII, smbglobals.primarydomain)); assert(smbbufferfixupabsolutel(outdata, 18)); assert(smbbufferputstring(outdata, nil, SMB_STRING_ASCII, smbglobals.primarydomain)); if (!smbbufferputs(outparam, moredata ? SMB_RAP_ERROR_MORE_DATA : SMB_RAP_NERR_SUCCESS) || !smbbufferputs(outparam, 0) || !smbbufferputs(outparam, usefulbytes)) { pr = SmbProcessResultFormat; goto done; } pr = SmbProcessResultReply; done: return pr;}static RapTableEntry raptable[] = {[RapNetShareGetInfo] { "NetShareGetInfo", netsharegetinfo },[RapNetShareEnum] { "NetShareEnum", netshareenum },[RapNetServerGetInfo] {"NetServerGetInfo", netservergetinfo },[RapNetWkstaGetInfo] { "NetWkstaGetInfo", netwkstagetinfo },[RapNetServerEnum2] { "NetServerEnum2", netserverenum2 },};SmbProcessResultsmbrap2(SmbSession *s){ char *pstring; char *dstring; ushort pno; RapTableEntry *e; SmbProcessResult pr; SmbBuffer *inparam; inparam = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount); if (!smbbuffergets(inparam, &pno) || !smbbuffergetstrinline(inparam, &pstring) || !smbbuffergetstrinline(inparam, &dstring)) { smblogprintif(smbglobals.log.rap2, "smbrap2: not enough parameters\n"); pr = SmbProcessResultFormat; goto done; } if (pno > nelem(raptable) || raptable[pno].name == nil) { smblogprint(-1, "smbrap2: unsupported procedure %ud\n", pno); pr = SmbProcessResultUnimp; goto done; } e = raptable + pno; pr = (*e->procedure)(inparam, s->transaction.out.parameters, s->transaction.out.data);done: smbbufferfree(&inparam); return pr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -