123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /*
- * 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"
- #include <pool.h>
- static void
- disconnecttree(void *magic, void *arg)
- {
- smbtreedisconnect((SmbSession *)magic, (SmbTree *)arg);
- }
- static void
- closesearch(void *magic, void *arg)
- {
- smbsearchclose((SmbSession *)magic, (SmbSearch *)arg);
- }
- static void
- smbsessionfree(SmbSession *s)
- {
- if (s) {
- smbidmapfree(&s->tidmap, disconnecttree, s);
- smbidmapfree(&s->sidmap, closesearch, s);
- smbbufferfree(&s->response);
- free(s->client.accountname);
- free(s->client.primarydomain);
- free(s->client.nativeos);
- free(s->client.nativelanman);
- free(s->transaction.in.parameters);
- free(s->transaction.in.data);
- free(s->transaction.in.setup);
- free(s->transaction.in.name);
- smbbufferfree(&s->transaction.out.parameters);
- smbbufferfree(&s->transaction.out.data);
- auth_freechal(s->cs);
- free(s);
- }
- }
- int
- smbsessionwrite(SmbSession *smbs, void *p, int32_t n)
- {
- SmbHeader h;
- SmbOpTableEntry *ote;
- uint8_t *pdata;
- int rv;
- SmbBuffer *b = nil;
- uint16_t bytecount;
- SmbProcessResult pr;
- if (smbs->response == nil)
- smbs->response = smbbuffernew(576);
- else
- smbresponsereset(smbs);
- smbs->errclass = SUCCESS;
- smbs->error = SUCCESS;
- // print("received %ld bytes\n", n);
- if (n <= 0)
- goto closedown;
- b = smbbufferinit(p, p, n);
- if (!smbbuffergetheader(b, &h, &pdata, &bytecount)) {
- smblogprint(-1, "smb: invalid header\n");
- goto closedown;
- }
- smbloglock();
- smblogprint(h.command, "received:\n");
- smblogdata(h.command, smblogprint, p, n, 0x1000);
- smblogunlock();
- ote = smboptable + h.command;
- if (ote->name == nil) {
- smblogprint(-1, "smb: illegal opcode 0x%.2x\n", h.command);
- goto unimp;
- }
- if (ote->process == nil) {
- smblogprint(-1, "smb: opcode %s unimplemented\n", ote->name);
- goto unimp;
- }
- if (smbs->nextcommand != SMB_COM_NO_ANDX_COMMAND
- && smbs->nextcommand != h.command) {
- smblogprint(-1, "smb: wrong command - expected %.2x\n", smbs->nextcommand);
- goto misc;
- }
- smbs->nextcommand = SMB_COM_NO_ANDX_COMMAND;
- switch (h.command) {
- case SMB_COM_NEGOTIATE:
- case SMB_COM_SESSION_SETUP_ANDX:
- case SMB_COM_TREE_CONNECT_ANDX:
- case SMB_COM_ECHO:
- break;
- default:
- if (smbs->state != SmbSessionEstablished) {
- smblogprint(-1, "aquarela: command %.2x unexpected\n", h.command);
- goto unimp;
- }
- }
- pr = (*ote->process)(smbs, &h, pdata, b);
- switch (pr) {
- case SmbProcessResultUnimp:
- unimp:
- smbseterror(smbs, ERRDOS, ERRunsup);
- pr = SmbProcessResultError;
- break;
- case SmbProcessResultFormat:
- smbseterror(smbs, ERRSRV, ERRsmbcmd);
- pr = SmbProcessResultError;
- break;
- case SmbProcessResultMisc:
- misc:
- smbseterror(smbs, ERRSRV, ERRerror);
- pr = SmbProcessResultError;
- break;
- case SmbProcessResultOk:
- case SmbProcessResultError:
- case SmbProcessResultReply:
- case SmbProcessResultDie:
- break;
- }
- if (pr == SmbProcessResultError) {
- smblogprint(h.command, "reply: error %d/%d\n", smbs->errclass, smbs->error);
- if (!smbresponseputerror(smbs, &h, smbs->errclass, smbs->error))
- pr = SmbProcessResultDie;
- else
- pr = SmbProcessResultReply;
- }
- else
- smblogprint(h.command, "reply: ok\n");
- if (pr == SmbProcessResultReply)
- rv = smbresponsesend(smbs) == SmbProcessResultOk ? 0 : -1;
- else if (pr == SmbProcessResultDie)
- rv = -1;
- else
- rv = 0;
- goto done;
- closedown:
- rv = -1;
- done:
- if (rv < 0) {
- smblogprintif(smbglobals.log.sessions, "shutting down\n");
- smbsessionfree(smbs);
- }
- smbbufferfree(&b);
- if (smbglobals.log.poolparanoia)
- poolcheck(mainmem);
- return rv;
- }
- static int
- nbwrite(NbSession *nbss, void *p, int32_t n)
- {
- return smbsessionwrite((SmbSession *)nbss->magic, p, n);
- }
- static int
- cifswrite(SmbCifsSession *cifs, void *p, int32_t n)
- {
- return smbsessionwrite((SmbSession *)cifs->magic, p, n);
- }
- int
- nbssaccept(void *v, NbSession *s, NBSSWRITEFN **writep)
- {
- SmbSession *smbs = smbemallocz(sizeof(SmbSession), 1);
- smbs->nbss = s;
- s->magic = smbs;
- smbs->nextcommand = SMB_COM_NO_ANDX_COMMAND;
- *writep = nbwrite;
- smblogprintif(smbglobals.log.sessions, "netbios session started\n");
- return 1;
- }
- int
- cifsaccept(SmbCifsSession *s, SMBCIFSWRITEFN **writep)
- {
- SmbSession *smbs = smbemallocz(sizeof(SmbSession), 1);
- smbs->cifss = s;
- s->magic = smbs;
- smbs->nextcommand = SMB_COM_NO_ANDX_COMMAND;
- *writep = cifswrite;
- smblogprintif(smbglobals.log.sessions, "cifs session started\n");
- return 1;
- }
- void
- usage(void)
- {
- fprint(2, "usage: %s [-np] [-d debug] [-u N] [-w workgroup]\n", argv0);
- threadexitsall("usage");
- }
- static void
- logset(char *cmd)
- {
- int x;
- if (strcmp(cmd, "allcmds") == 0) {
- for (x = 0; x < 256; x++)
- smboptable[x].debug = 1;
- for (x = 0; x < smbtrans2optablesize; x++)
- smbtrans2optable[x].debug = 1;
- return;
- }
- if (strcmp(cmd, "tids") == 0) {
- smbglobals.log.tids = 1;
- return;
- }
- if (strcmp(cmd, "sids") == 0) {
- smbglobals.log.sids = 1;
- return;
- }
- if (strcmp(cmd, "fids") == 0) {
- smbglobals.log.fids = 1;
- return;
- }
- if (strcmp(cmd, "rap2") == 0) {
- smbglobals.log.rap2 = 1;
- return;
- }
- else if (strcmp(cmd, "find") == 0) {
- smbglobals.log.find = 1;
- return;
- }
- if (strcmp(cmd, "query") == 0) {
- smbglobals.log.query = 1;
- return;
- }
- if (strcmp(cmd, "sharedfiles") == 0) {
- smbglobals.log.sharedfiles = 1;
- return;
- }
- if (strcmp(cmd, "poolparanoia") == 0) {
- mainmem->flags |= POOL_PARANOIA;
- smbglobals.log.poolparanoia = 1;
- return;
- }
- if (strcmp(cmd, "sessions") == 0) {
- smbglobals.log.sessions = 1;
- return;
- }
- if (strcmp(cmd, "rep") == 0) {
- smbglobals.log.rep = 1;
- return;
- }
- if (strcmp(cmd, "locks") == 0) {
- smbglobals.log.locks = 1;
- return;
- }
- for (x = 0; x < 256; x++)
- if (smboptable[x].name && strcmp(smboptable[x].name, cmd) == 0) {
- smboptable[x].debug = 1;
- return;
- }
- for (x = 0; x < smbtrans2optablesize; x++)
- if (smbtrans2optable[x].name && strcmp(smbtrans2optable[x].name, cmd) == 0) {
- smbtrans2optable[x].debug = 1;
- return;
- }
- if (strlen(cmd) == 4 && cmd[0] == '0' && cmd[1] == 'x') {
- int c;
- c = strtoul(cmd + 2, 0, 16);
- if (c >= 0 && c <= 255) {
- smboptable[c].debug = 1;
- return;
- }
- }
- print("debugging command %s not recognised\n", cmd);
- }
- void
- threadmain(int argc, char **argv)
- {
- NbName from, to;
- char *e = nil;
- int netbios = 0;
- ARGBEGIN {
- case 'u':
- smbglobals.unicode = strtol(ARGF(), 0, 0) != 0;
- break;
- case 'p':
- smbglobals.log.print = 1;
- break;
- case 'd':
- logset(ARGF());
- break;
- case 'w':
- smbglobals.primarydomain = ARGF();
- break;
- case 'n':
- netbios = 1;
- break;
- default:
- usage();
- } ARGEND;
- smbglobalsguess(0);
- smblistencifs(cifsaccept);
- if (netbios) {
- nbinit();
- nbmknamefromstring(from, "*");
- nbmknamefromstring(to, "*smbserver\\x20");
- nbsslisten(to, from, nbssaccept, nil);
- nbmknamefromstringandtype(to, smbglobals.serverinfo.name, 0x20);
- nbsslisten(to, from, nbssaccept, nil);
- }
- smblogprint(-1, "Aquarela %d.%d running\n", smbglobals.serverinfo.vmaj, smbglobals.serverinfo.vmin);
- for (;;) {
- if (netbios&& !smbbrowsesendhostannouncement(smbglobals.serverinfo.name, 60 * 1000,
- SV_TYPE_SERVER,
- smbglobals.serverinfo.remark, &e)) {
- smblogprint(-1, "hostannounce failed: %s\n", e);
- }
- if (sleep(60 * 1000) < 0)
- break;
- }
- }
|