18ccd4a63SDavid du Colombier #include "headers.h"
28ccd4a63SDavid du Colombier #include <pool.h>
38ccd4a63SDavid du Colombier
48ccd4a63SDavid du Colombier static void
disconnecttree(void * magic,void * arg)58ccd4a63SDavid du Colombier disconnecttree(void *magic, void *arg)
68ccd4a63SDavid du Colombier {
78ccd4a63SDavid du Colombier smbtreedisconnect((SmbSession *)magic, (SmbTree *)arg);
88ccd4a63SDavid du Colombier }
98ccd4a63SDavid du Colombier
108ccd4a63SDavid du Colombier static void
closesearch(void * magic,void * arg)118ccd4a63SDavid du Colombier closesearch(void *magic, void *arg)
128ccd4a63SDavid du Colombier {
138ccd4a63SDavid du Colombier smbsearchclose((SmbSession *)magic, (SmbSearch *)arg);
148ccd4a63SDavid du Colombier }
158ccd4a63SDavid du Colombier
168ccd4a63SDavid du Colombier static void
smbsessionfree(SmbSession * s)178ccd4a63SDavid du Colombier smbsessionfree(SmbSession *s)
188ccd4a63SDavid du Colombier {
198ccd4a63SDavid du Colombier if (s) {
208ccd4a63SDavid du Colombier smbidmapfree(&s->tidmap, disconnecttree, s);
218ccd4a63SDavid du Colombier smbidmapfree(&s->sidmap, closesearch, s);
228ccd4a63SDavid du Colombier smbbufferfree(&s->response);
238ccd4a63SDavid du Colombier free(s->client.accountname);
248ccd4a63SDavid du Colombier free(s->client.primarydomain);
258ccd4a63SDavid du Colombier free(s->client.nativeos);
268ccd4a63SDavid du Colombier free(s->client.nativelanman);
278ccd4a63SDavid du Colombier free(s->transaction.in.parameters);
288ccd4a63SDavid du Colombier free(s->transaction.in.data);
298ccd4a63SDavid du Colombier free(s->transaction.in.setup);
308ccd4a63SDavid du Colombier free(s->transaction.in.name);
318ccd4a63SDavid du Colombier smbbufferfree(&s->transaction.out.parameters);
328ccd4a63SDavid du Colombier smbbufferfree(&s->transaction.out.data);
338ccd4a63SDavid du Colombier auth_freechal(s->cs);
348ccd4a63SDavid du Colombier free(s);
358ccd4a63SDavid du Colombier }
368ccd4a63SDavid du Colombier }
378ccd4a63SDavid du Colombier
388ccd4a63SDavid du Colombier int
smbsessionwrite(SmbSession * smbs,void * p,long n)398ccd4a63SDavid du Colombier smbsessionwrite(SmbSession *smbs, void *p, long n)
408ccd4a63SDavid du Colombier {
418ccd4a63SDavid du Colombier SmbHeader h;
428ccd4a63SDavid du Colombier SmbOpTableEntry *ote;
438ccd4a63SDavid du Colombier uchar *pdata;
448ccd4a63SDavid du Colombier int rv;
458ccd4a63SDavid du Colombier SmbBuffer *b = nil;
468ccd4a63SDavid du Colombier ushort bytecount;
478ccd4a63SDavid du Colombier SmbProcessResult pr;
488ccd4a63SDavid du Colombier
498ccd4a63SDavid du Colombier if (smbs->response == nil)
508ccd4a63SDavid du Colombier smbs->response = smbbuffernew(576);
518ccd4a63SDavid du Colombier else
528ccd4a63SDavid du Colombier smbresponsereset(smbs);
538ccd4a63SDavid du Colombier smbs->errclass = SUCCESS;
548ccd4a63SDavid du Colombier smbs->error = SUCCESS;
558ccd4a63SDavid du Colombier // print("received %ld bytes\n", n);
568ccd4a63SDavid du Colombier if (n <= 0)
578ccd4a63SDavid du Colombier goto closedown;
588ccd4a63SDavid du Colombier b = smbbufferinit(p, p, n);
598ccd4a63SDavid du Colombier if (!smbbuffergetheader(b, &h, &pdata, &bytecount)) {
608ccd4a63SDavid du Colombier smblogprint(-1, "smb: invalid header\n");
618ccd4a63SDavid du Colombier goto closedown;
628ccd4a63SDavid du Colombier }
638ccd4a63SDavid du Colombier smbloglock();
648ccd4a63SDavid du Colombier smblogprint(h.command, "received:\n");
658ccd4a63SDavid du Colombier smblogdata(h.command, smblogprint, p, n, 0x1000);
668ccd4a63SDavid du Colombier smblogunlock();
678ccd4a63SDavid du Colombier ote = smboptable + h.command;
688ccd4a63SDavid du Colombier if (ote->name == nil) {
698ccd4a63SDavid du Colombier smblogprint(-1, "smb: illegal opcode 0x%.2ux\n", h.command);
708ccd4a63SDavid du Colombier goto unimp;
718ccd4a63SDavid du Colombier }
728ccd4a63SDavid du Colombier if (ote->process == nil) {
738ccd4a63SDavid du Colombier smblogprint(-1, "smb: opcode %s unimplemented\n", ote->name);
748ccd4a63SDavid du Colombier goto unimp;
758ccd4a63SDavid du Colombier }
768ccd4a63SDavid du Colombier if (smbs->nextcommand != SMB_COM_NO_ANDX_COMMAND
778ccd4a63SDavid du Colombier && smbs->nextcommand != h.command) {
788ccd4a63SDavid du Colombier smblogprint(-1, "smb: wrong command - expected %.2ux\n", smbs->nextcommand);
798ccd4a63SDavid du Colombier goto misc;
808ccd4a63SDavid du Colombier }
818ccd4a63SDavid du Colombier smbs->nextcommand = SMB_COM_NO_ANDX_COMMAND;
828ccd4a63SDavid du Colombier switch (h.command) {
838ccd4a63SDavid du Colombier case SMB_COM_NEGOTIATE:
848ccd4a63SDavid du Colombier case SMB_COM_SESSION_SETUP_ANDX:
858ccd4a63SDavid du Colombier case SMB_COM_TREE_CONNECT_ANDX:
868ccd4a63SDavid du Colombier case SMB_COM_ECHO:
878ccd4a63SDavid du Colombier break;
888ccd4a63SDavid du Colombier default:
898ccd4a63SDavid du Colombier if (smbs->state != SmbSessionEstablished) {
908ccd4a63SDavid du Colombier smblogprint(-1, "aquarela: command %.2ux unexpected\n", h.command);
918ccd4a63SDavid du Colombier goto unimp;
928ccd4a63SDavid du Colombier }
938ccd4a63SDavid du Colombier }
948ccd4a63SDavid du Colombier pr = (*ote->process)(smbs, &h, pdata, b);
958ccd4a63SDavid du Colombier switch (pr) {
968ccd4a63SDavid du Colombier case SmbProcessResultUnimp:
978ccd4a63SDavid du Colombier unimp:
988ccd4a63SDavid du Colombier smbseterror(smbs, ERRDOS, ERRunsup);
998ccd4a63SDavid du Colombier pr = SmbProcessResultError;
1008ccd4a63SDavid du Colombier break;
1018ccd4a63SDavid du Colombier case SmbProcessResultFormat:
1028ccd4a63SDavid du Colombier smbseterror(smbs, ERRSRV, ERRsmbcmd);
1038ccd4a63SDavid du Colombier pr = SmbProcessResultError;
1048ccd4a63SDavid du Colombier break;
1058ccd4a63SDavid du Colombier case SmbProcessResultMisc:
1068ccd4a63SDavid du Colombier misc:
1078ccd4a63SDavid du Colombier smbseterror(smbs, ERRSRV, ERRerror);
1088ccd4a63SDavid du Colombier pr = SmbProcessResultError;
1098ccd4a63SDavid du Colombier break;
1108ccd4a63SDavid du Colombier }
1118ccd4a63SDavid du Colombier if (pr == SmbProcessResultError) {
1128ccd4a63SDavid du Colombier smblogprint(h.command, "reply: error %d/%d\n", smbs->errclass, smbs->error);
1138ccd4a63SDavid du Colombier if (!smbresponseputerror(smbs, &h, smbs->errclass, smbs->error))
1148ccd4a63SDavid du Colombier pr = SmbProcessResultDie;
1158ccd4a63SDavid du Colombier else
1168ccd4a63SDavid du Colombier pr = SmbProcessResultReply;
1178ccd4a63SDavid du Colombier }
1188ccd4a63SDavid du Colombier else
1198ccd4a63SDavid du Colombier smblogprint(h.command, "reply: ok\n");
1208ccd4a63SDavid du Colombier if (pr == SmbProcessResultReply)
1218ccd4a63SDavid du Colombier rv = smbresponsesend(smbs) == SmbProcessResultOk ? 0 : -1;
1228ccd4a63SDavid du Colombier else if (pr == SmbProcessResultDie)
1238ccd4a63SDavid du Colombier rv = -1;
1248ccd4a63SDavid du Colombier else
1258ccd4a63SDavid du Colombier rv = 0;
1268ccd4a63SDavid du Colombier goto done;
1278ccd4a63SDavid du Colombier closedown:
1288ccd4a63SDavid du Colombier rv = -1;
1298ccd4a63SDavid du Colombier done:
1308ccd4a63SDavid du Colombier if (rv < 0) {
1318ccd4a63SDavid du Colombier smblogprintif(smbglobals.log.sessions, "shutting down\n");
1328ccd4a63SDavid du Colombier smbsessionfree(smbs);
1338ccd4a63SDavid du Colombier }
1348ccd4a63SDavid du Colombier smbbufferfree(&b);
1358ccd4a63SDavid du Colombier if (smbglobals.log.poolparanoia)
1368ccd4a63SDavid du Colombier poolcheck(mainmem);
1378ccd4a63SDavid du Colombier return rv;
1388ccd4a63SDavid du Colombier }
1398ccd4a63SDavid du Colombier
1408ccd4a63SDavid du Colombier static int
nbwrite(NbSession * nbss,void * p,long n)1418ccd4a63SDavid du Colombier nbwrite(NbSession *nbss, void *p, long n)
1428ccd4a63SDavid du Colombier {
1438ccd4a63SDavid du Colombier return smbsessionwrite((SmbSession *)nbss->magic, p, n);
1448ccd4a63SDavid du Colombier }
1458ccd4a63SDavid du Colombier
1468ccd4a63SDavid du Colombier static int
cifswrite(SmbCifsSession * cifs,void * p,long n)1478ccd4a63SDavid du Colombier cifswrite(SmbCifsSession *cifs, void *p, long n)
1488ccd4a63SDavid du Colombier {
1498ccd4a63SDavid du Colombier return smbsessionwrite((SmbSession *)cifs->magic, p, n);
1508ccd4a63SDavid du Colombier }
1518ccd4a63SDavid du Colombier
1528ccd4a63SDavid du Colombier int
nbssaccept(void *,NbSession * s,NBSSWRITEFN ** writep)1538ccd4a63SDavid du Colombier nbssaccept(void *, NbSession *s, NBSSWRITEFN **writep)
1548ccd4a63SDavid du Colombier {
1558ccd4a63SDavid du Colombier SmbSession *smbs = smbemallocz(sizeof(SmbSession), 1);
1568ccd4a63SDavid du Colombier smbs->nbss = s;
1578ccd4a63SDavid du Colombier s->magic = smbs;
1588ccd4a63SDavid du Colombier smbs->nextcommand = SMB_COM_NO_ANDX_COMMAND;
1598ccd4a63SDavid du Colombier *writep = nbwrite;
1608ccd4a63SDavid du Colombier smblogprintif(smbglobals.log.sessions, "netbios session started\n");
1618ccd4a63SDavid du Colombier return 1;
1628ccd4a63SDavid du Colombier }
1638ccd4a63SDavid du Colombier
1648ccd4a63SDavid du Colombier int
cifsaccept(SmbCifsSession * s,SMBCIFSWRITEFN ** writep)1658ccd4a63SDavid du Colombier cifsaccept(SmbCifsSession *s, SMBCIFSWRITEFN **writep)
1668ccd4a63SDavid du Colombier {
1678ccd4a63SDavid du Colombier SmbSession *smbs = smbemallocz(sizeof(SmbSession), 1);
1688ccd4a63SDavid du Colombier smbs->cifss = s;
1698ccd4a63SDavid du Colombier s->magic = smbs;
1708ccd4a63SDavid du Colombier smbs->nextcommand = SMB_COM_NO_ANDX_COMMAND;
1718ccd4a63SDavid du Colombier *writep = cifswrite;
1728ccd4a63SDavid du Colombier smblogprintif(smbglobals.log.sessions, "cifs session started\n");
1738ccd4a63SDavid du Colombier return 1;
1748ccd4a63SDavid du Colombier }
1758ccd4a63SDavid du Colombier
1768ccd4a63SDavid du Colombier void
usage(void)1778ccd4a63SDavid du Colombier usage(void)
1788ccd4a63SDavid du Colombier {
179*94aa1c4cSDavid du Colombier fprint(2, "usage: %s [-np] [-d debug] [-u N] [-w workgroup]\n", argv0);
18016a961bdSDavid du Colombier threadexitsall("usage");
1818ccd4a63SDavid du Colombier }
1828ccd4a63SDavid du Colombier
1838ccd4a63SDavid du Colombier static void
logset(char * cmd)1848ccd4a63SDavid du Colombier logset(char *cmd)
1858ccd4a63SDavid du Colombier {
1868ccd4a63SDavid du Colombier int x;
1878ccd4a63SDavid du Colombier if (strcmp(cmd, "allcmds") == 0) {
1888ccd4a63SDavid du Colombier for (x = 0; x < 256; x++)
1898ccd4a63SDavid du Colombier smboptable[x].debug = 1;
1908ccd4a63SDavid du Colombier for (x = 0; x < smbtrans2optablesize; x++)
1918ccd4a63SDavid du Colombier smbtrans2optable[x].debug = 1;
1928ccd4a63SDavid du Colombier return;
1938ccd4a63SDavid du Colombier }
1948ccd4a63SDavid du Colombier if (strcmp(cmd, "tids") == 0) {
1958ccd4a63SDavid du Colombier smbglobals.log.tids = 1;
1968ccd4a63SDavid du Colombier return;
1978ccd4a63SDavid du Colombier }
1988ccd4a63SDavid du Colombier if (strcmp(cmd, "sids") == 0) {
1998ccd4a63SDavid du Colombier smbglobals.log.sids = 1;
2008ccd4a63SDavid du Colombier return;
2018ccd4a63SDavid du Colombier }
2028ccd4a63SDavid du Colombier if (strcmp(cmd, "fids") == 0) {
2038ccd4a63SDavid du Colombier smbglobals.log.fids = 1;
2048ccd4a63SDavid du Colombier return;
2058ccd4a63SDavid du Colombier }
2068ccd4a63SDavid du Colombier if (strcmp(cmd, "rap2") == 0) {
2078ccd4a63SDavid du Colombier smbglobals.log.rap2 = 1;
2088ccd4a63SDavid du Colombier return;
2098ccd4a63SDavid du Colombier }
2108ccd4a63SDavid du Colombier else if (strcmp(cmd, "find") == 0) {
2118ccd4a63SDavid du Colombier smbglobals.log.find = 1;
2128ccd4a63SDavid du Colombier return;
2138ccd4a63SDavid du Colombier }
2148ccd4a63SDavid du Colombier if (strcmp(cmd, "query") == 0) {
2158ccd4a63SDavid du Colombier smbglobals.log.query = 1;
2168ccd4a63SDavid du Colombier return;
2178ccd4a63SDavid du Colombier }
2188ccd4a63SDavid du Colombier if (strcmp(cmd, "sharedfiles") == 0) {
2198ccd4a63SDavid du Colombier smbglobals.log.sharedfiles = 1;
2208ccd4a63SDavid du Colombier return;
2218ccd4a63SDavid du Colombier }
2228ccd4a63SDavid du Colombier if (strcmp(cmd, "poolparanoia") == 0) {
2238ccd4a63SDavid du Colombier mainmem->flags |= POOL_PARANOIA;
2248ccd4a63SDavid du Colombier smbglobals.log.poolparanoia = 1;
2258ccd4a63SDavid du Colombier return;
2268ccd4a63SDavid du Colombier }
2278ccd4a63SDavid du Colombier if (strcmp(cmd, "sessions") == 0) {
2288ccd4a63SDavid du Colombier smbglobals.log.sessions = 1;
2298ccd4a63SDavid du Colombier return;
2308ccd4a63SDavid du Colombier }
2318ccd4a63SDavid du Colombier if (strcmp(cmd, "rep") == 0) {
2328ccd4a63SDavid du Colombier smbglobals.log.rep = 1;
2338ccd4a63SDavid du Colombier return;
2348ccd4a63SDavid du Colombier }
2358ccd4a63SDavid du Colombier if (strcmp(cmd, "locks") == 0) {
2368ccd4a63SDavid du Colombier smbglobals.log.locks = 1;
2378ccd4a63SDavid du Colombier return;
2388ccd4a63SDavid du Colombier }
2398ccd4a63SDavid du Colombier
2408ccd4a63SDavid du Colombier for (x = 0; x < 256; x++)
2418ccd4a63SDavid du Colombier if (smboptable[x].name && strcmp(smboptable[x].name, cmd) == 0) {
2428ccd4a63SDavid du Colombier smboptable[x].debug = 1;
2438ccd4a63SDavid du Colombier return;
2448ccd4a63SDavid du Colombier }
2458ccd4a63SDavid du Colombier for (x = 0; x < smbtrans2optablesize; x++)
2468ccd4a63SDavid du Colombier if (smbtrans2optable[x].name && strcmp(smbtrans2optable[x].name, cmd) == 0) {
2478ccd4a63SDavid du Colombier smbtrans2optable[x].debug = 1;
2488ccd4a63SDavid du Colombier return;
2498ccd4a63SDavid du Colombier }
2508ccd4a63SDavid du Colombier if (strlen(cmd) == 4 && cmd[0] == '0' && cmd[1] == 'x') {
2518ccd4a63SDavid du Colombier int c;
2528ccd4a63SDavid du Colombier c = strtoul(cmd + 2, 0, 16);
2538ccd4a63SDavid du Colombier if (c >= 0 && c <= 255) {
2548ccd4a63SDavid du Colombier smboptable[c].debug = 1;
2558ccd4a63SDavid du Colombier return;
2568ccd4a63SDavid du Colombier }
2578ccd4a63SDavid du Colombier }
2588ccd4a63SDavid du Colombier print("debugging command %s not recognised\n", cmd);
2598ccd4a63SDavid du Colombier }
2608ccd4a63SDavid du Colombier
2618ccd4a63SDavid du Colombier
2628ccd4a63SDavid du Colombier void
threadmain(int argc,char ** argv)2638ccd4a63SDavid du Colombier threadmain(int argc, char **argv)
2648ccd4a63SDavid du Colombier {
2658ccd4a63SDavid du Colombier NbName from, to;
2668ccd4a63SDavid du Colombier char *e = nil;
2678ccd4a63SDavid du Colombier int netbios = 0;
2688ccd4a63SDavid du Colombier ARGBEGIN {
2698ccd4a63SDavid du Colombier case 'u':
2708ccd4a63SDavid du Colombier smbglobals.unicode = strtol(ARGF(), 0, 0) != 0;
2718ccd4a63SDavid du Colombier break;
2728ccd4a63SDavid du Colombier case 'p':
2738ccd4a63SDavid du Colombier smbglobals.log.print = 1;
2748ccd4a63SDavid du Colombier break;
2758ccd4a63SDavid du Colombier case 'd':
2768ccd4a63SDavid du Colombier logset(ARGF());
2778ccd4a63SDavid du Colombier break;
2788ccd4a63SDavid du Colombier case 'w':
2798ccd4a63SDavid du Colombier smbglobals.primarydomain = ARGF();
2808ccd4a63SDavid du Colombier break;
2818ccd4a63SDavid du Colombier case 'n':
2828ccd4a63SDavid du Colombier netbios = 1;
2838ccd4a63SDavid du Colombier break;
2848ccd4a63SDavid du Colombier default:
2858ccd4a63SDavid du Colombier usage();
2868ccd4a63SDavid du Colombier } ARGEND;
2878ccd4a63SDavid du Colombier smbglobalsguess(0);
2888ccd4a63SDavid du Colombier smblistencifs(cifsaccept);
2898ccd4a63SDavid du Colombier if (netbios) {
2908ccd4a63SDavid du Colombier nbinit();
2918ccd4a63SDavid du Colombier nbmknamefromstring(from, "*");
2928ccd4a63SDavid du Colombier nbmknamefromstring(to, "*smbserver\\x20");
2938ccd4a63SDavid du Colombier nbsslisten(to, from, nbssaccept, nil);
2948ccd4a63SDavid du Colombier nbmknamefromstringandtype(to, smbglobals.serverinfo.name, 0x20);
2958ccd4a63SDavid du Colombier nbsslisten(to, from, nbssaccept, nil);
2968ccd4a63SDavid du Colombier }
2978ccd4a63SDavid du Colombier smblogprint(-1, "Aquarela %d.%d running\n", smbglobals.serverinfo.vmaj, smbglobals.serverinfo.vmin);
2988ccd4a63SDavid du Colombier for (;;) {
2998ccd4a63SDavid du Colombier if (netbios&& !smbbrowsesendhostannouncement(smbglobals.serverinfo.name, 60 * 1000,
3008ccd4a63SDavid du Colombier SV_TYPE_SERVER,
3018ccd4a63SDavid du Colombier smbglobals.serverinfo.remark, &e)) {
3028ccd4a63SDavid du Colombier smblogprint(-1, "hostannounce failed: %s\n", e);
3038ccd4a63SDavid du Colombier }
3048ccd4a63SDavid du Colombier if (sleep(60 * 1000) < 0)
3058ccd4a63SDavid du Colombier break;
3068ccd4a63SDavid du Colombier }
3078ccd4a63SDavid du Colombier }
3088ccd4a63SDavid du Colombier
309