123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include "headers.h"
- typedef struct RapTableEntry RapTableEntry;
- struct RapTableEntry {
- char *name;
- SmbProcessResult (*procedure)(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata);
- };
- typedef int INFOSIZEFN(uint16_t level, void *data);
- typedef int INFOPUTFN(SmbBuffer *b, uint16_t level, void *data);
- typedef int INFOPUTSTRINGSFN(SmbBuffer *b, uint16_t 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 int
- serverinfosize(uint16_t level, void *data)
- {
- SmbServerInfo *si = data;
- switch (level) {
- case 0:
- return 16;
- case 1:
- return 26 + smbstrlen(si->remark);
- default:
- return 0;
- }
- }
- static int
- serverinfoput(SmbBuffer *b, uint16_t 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 int
- serverinfoputstrings(SmbBuffer *b, uint16_t 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 int
- shareinfosize(uint16_t 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 int
- shareinfoput(SmbBuffer *b, uint16_t 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 int
- shareinfoputstrings(SmbBuffer *b, uint16_t 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 SmbProcessResult
- thingfill(SmbBuffer *outparam, SmbBuffer *outdata, InfoMethod *m,
- uint16_t 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 SmbProcessResult
- onethingfill(SmbBuffer *outparam, SmbBuffer *outdata, InfoMethod *m,
- uint16_t 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 SmbProcessResult
- netshareenum(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata)
- {
- uint16_t 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 SmbProcessResult
- netserverenum2(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata)
- {
- uint16_t level, rbl;
- char *domain;
- uint32_t 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 SmbProcessResult
- netsharegetinfo(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata)
- {
- char *netname;
- uint16_t 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 SmbProcessResult
- netservergetinfo(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata)
- {
- uint16_t 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 SmbProcessResult
- netwkstagetinfo(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata)
- {
- uint16_t level;
- uint16_t 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 },
- };
- SmbProcessResult
- smbrap2(SmbSession *s)
- {
- char *pstring;
- char *dstring;
- uint16_t 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;
- }
|