Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "headers.h"
2
 
3
SmbProcessResult
4
smbnegotiate(SmbSession *s, SmbHeader *h, uchar *, SmbBuffer *b)
5
{
6
	ushort index;
7
	int i;
8
	uchar bufferformat;
9
 
10
	if (!smbcheckwordcount("negotiate", h, 0))
11
		return SmbProcessResultFormat;
12
	if (s->state != SmbSessionNeedNegotiate) {
13
		/* this acts as a complete session reset */
14
		smblogprint(-1, "smbnegotiate: called when already negotiated\n");
15
		return SmbProcessResultUnimp;
16
	}
17
	i = 0;
18
	index = 0xffff;
19
	while (smbbuffergetb(b, &bufferformat)) {
20
		char *s;
21
		if (bufferformat != 0x02) {
22
			smblogprint(-1, "smbnegotiate: unrecognised buffer format 0x%.2ux\n", bufferformat);
23
			return SmbProcessResultFormat;
24
		}
25
		if (!smbbuffergetstr(b, 0, &s)) {
26
			smblogprint(-1, "smbnegotiate: no null found\n");
27
			return SmbProcessResultFormat;
28
		}
29
		smblogprint(h->command, "smbnegotiate: '%s'\n", s);
30
		if (index == 0xffff && strcmp(s, "NT LM 0.12") == 0)
31
			index = i;
32
		i++;
33
		free(s);
34
	}
35
	if (index != 0xffff) {
36
		Tm *tm;
37
		ulong capabilities;
38
		ulong bytecountfixupoffset;
39
 
40
		h->wordcount = 17;
41
		if (!smbbufferputheader(s->response, h, nil)
42
			|| !smbbufferputs(s->response, index)
43
			|| !smbbufferputb(s->response, 3)			/* user security, encrypted */
44
			|| !smbbufferputs(s->response, 1)			/* max mux */
45
			|| !smbbufferputs(s->response, 1)			/* max vc */
46
			|| !smbbufferputl(s->response, smbglobals.maxreceive)		/* max buffer size */
47
			|| !smbbufferputl(s->response, 0x10000)		/* max raw */
48
			|| !smbbufferputl(s->response, threadid()))	/* session key */
49
			goto die;
50
		/* <= Win2k insist upon this being set to ensure that they observe the prototol (!) */
51
		capabilities = CAP_NT_SMBS;
52
		if (smbglobals.unicode)
53
			capabilities |= CAP_UNICODE;
54
		tm = localtime(time(nil));
55
		s->tzoff = tm->tzoff;
56
		if (!smbbufferputl(s->response, capabilities)
57
			|| !smbbufferputv(s->response, nsec() / 100 + (vlong)10000000 * 11644473600LL)
58
			|| !smbbufferputs(s->response, -s->tzoff / 60)
59
			|| !smbbufferputb(s->response, 8))	/* crypt len */
60
			goto die;
61
		bytecountfixupoffset = smbbufferwriteoffset(s->response);
62
		if (!smbbufferputs(s->response, 0))
63
			goto die;
64
		s->cs = auth_challenge("proto=mschap role=server");
65
		if (s->cs == nil) {
66
			smblogprint(h->command, "smbnegotiate: couldn't get mschap challenge\n");
67
			return SmbProcessResultMisc;
68
		}
69
		if (s->cs->nchal != 8) {
70
			smblogprint(h->command, "smbnegotiate: nchal %d\n", s->cs->nchal);
71
			return SmbProcessResultMisc;
72
		}
73
		if (!smbbufferputbytes(s->response, s->cs->chal, s->cs->nchal)
74
			|| !smbbufferputstring(s->response, nil, SMB_STRING_UNICODE, smbglobals.primarydomain)
75
			|| !smbbufferfixuprelatives(s->response, bytecountfixupoffset))
76
			goto die;
77
	}
78
	else {
79
		h->wordcount = 1;
80
		if (!smbbufferputheader(s->response, h, nil)
81
			|| !smbbufferputs(s->response, index)
82
			|| !smbbufferputs(s->response, 0))
83
			goto die;
84
	}
85
	s->state = SmbSessionNeedSetup;
86
	return SmbProcessResultReply;
87
die:
88
	return SmbProcessResultDie;
89
}