summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>2000-03-17 18:30:10 +0000
committerLuke Leighton <lkcl@samba.org>2000-03-17 18:30:10 +0000
commite999698318f89484b76cd56db4a16fcde7bcdd6a (patch)
treedeea36393cd505235fe688e3a5f9db720c86002e
parentca079cdbdc0a8bf681ded1651cb320a7e3e6bbfb (diff)
downloadsamba-e999698318f89484b76cd56db4a16fcde7bcdd6a.tar.gz
when a GETDC datagram is received, if the dgram type is UNIQUE instead of
GROUP, it is processed *differently*, there is a domain-name string in it, so i skip 22 bytes and _then_ read the version number etc. this must go in 2.0.x and cvs main (oh, and i'm not going to do it, i'm not "trusted" enough to do the job "correctly"). this will be the only notification that this is needed in 2.0.x and cvs main branches.
-rw-r--r--source/include/nameserv.h3
-rw-r--r--source/nmbd/nmbd_processlogon.c460
2 files changed, 249 insertions, 214 deletions
diff --git a/source/include/nameserv.h b/source/include/nameserv.h
index 0de00f36368..0f09682249d 100644
--- a/source/include/nameserv.h
+++ b/source/include/nameserv.h
@@ -456,6 +456,9 @@ struct nmb_packet
/* A datagram - this normally contains SMB data in the data[] array. */
+#define DGRAM_GROUP 0x11
+#define DGRAM_UNIQUE 0x10
+
struct dgram_packet {
struct {
int msg_type;
diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c
index 939e5b88bbf..338674d8aad 100644
--- a/source/nmbd/nmbd_processlogon.c
+++ b/source/nmbd/nmbd_processlogon.c
@@ -35,252 +35,284 @@ extern fstring global_myworkgroup;
Process a domain logon packet
**************************************************************************/
-void process_logon_packet(struct packet_struct *p,char *buf,int len,
- char *mailslot)
+void process_logon_packet(struct packet_struct *p, char *buf, int len,
+ char *mailslot)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- pstring my_name;
- fstring reply_name;
- pstring outbuf;
- int code;
- uint16 token = 0;
- uint32 ntversion = 0;
- uint16 lmnttoken = 0;
- uint16 lm20token = 0;
- uint32 domainsidsize;
- BOOL short_request = 0;
- char *getdc;
- char *uniuser; /* Unicode user name. */
- char *unicomp; /* Unicode computer name. */
+ struct dgram_packet *dgram = &p->packet.dgram;
+ pstring my_name;
+ fstring reply_name;
+ pstring outbuf;
+ int code;
+ uint16 token = 0;
+ uint32 ntversion = 0;
+ uint16 lmnttoken = 0;
+ uint16 lm20token = 0;
+ uint32 domainsidsize;
+ BOOL short_request = 0;
+ char *getdc;
+ char *uniuser; /* Unicode user name. */
+ char *unicomp; /* Unicode computer name. */
+ BOOL dgram_unique = (dgram->header.msg_type == DGRAM_UNIQUE);
+
+ memset(outbuf, 0, sizeof(outbuf));
+
+ if (!lp_domain_logons())
+ {
+ DEBUG(3,
+ ("process_logon_packet: Logon packet received from IP %s and domain \
+logons are not enabled.\n",
+ inet_ntoa(p->ip)));
+ return;
+ }
- memset(outbuf, 0, sizeof(outbuf));
+ pstrcpy(my_name, global_myname);
+ strupper(my_name);
- if (!lp_domain_logons())
- {
- DEBUG(3,("process_logon_packet: Logon packet received from IP %s and domain \
-logons are not enabled.\n", inet_ntoa(p->ip) ));
- return;
- }
-
- pstrcpy(my_name, global_myname);
- strupper(my_name);
+ code = SVAL(buf, 0);
+ DEBUG(1,
+ ("process_logon_packet: %s-packet Logon from %s: code = %x\n",
+ dgram_unique ? "Unique" : "Group", inet_ntoa(p->ip), code));
- code = SVAL(buf,0);
- DEBUG(1,("process_logon_packet: Logon from %s: code = %x\n", inet_ntoa(p->ip), code));
+ switch (code)
+ {
+ case 0:
+ {
+ char *q = buf + 2;
+ char *machine = q;
+ char *user = skip_string(machine, 1);
- switch (code)
- {
- case 0:
- {
- char *q = buf + 2;
- char *machine = q;
- char *user = skip_string(machine,1);
+ getdc = skip_string(user, 1);
+ q = skip_string(getdc, 1);
+ token = SVAL(q, 3);
- getdc = skip_string(user,1);
- q = skip_string(getdc,1);
- token = SVAL(q,3);
+ fstrcpy(reply_name, my_name);
- fstrcpy(reply_name,my_name);
+ DEBUG(3,
+ ("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n",
+ machine, inet_ntoa(p->ip), user, token));
- DEBUG(3,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n",
- machine,inet_ntoa(p->ip),user,token));
+ q = outbuf;
+ SSVAL(q, 0, 6);
+ q += 2;
- q = outbuf;
- SSVAL(q, 0, 6);
- q += 2;
+ fstrcpy(reply_name, "\\\\");
+ fstrcat(reply_name, my_name);
+ fstrcpy(q, reply_name);
+ q = skip_string(q, 1); /* PDC name */
- fstrcpy(reply_name, "\\\\");
- fstrcat(reply_name, my_name);
- fstrcpy(q, reply_name); q = skip_string(q, 1); /* PDC name */
+ SSVAL(q, 0, token);
+ q += 2;
- SSVAL(q, 0, token);
- q += 2;
+ dump_data(4, outbuf, PTR_DIFF(q, outbuf));
- dump_data(4, outbuf, PTR_DIFF(q, outbuf));
+ send_mailslot(True, getdc,
+ outbuf, PTR_DIFF(q, outbuf),
+ dgram->dest_name.name,
+ dgram->dest_name.name_type,
+ dgram->source_name.name,
+ dgram->source_name.name_type,
+ p->ip, *iface_ip(p->ip), p->port);
+ break;
+ }
- send_mailslot(True, getdc,
- outbuf,PTR_DIFF(q,outbuf),
- dgram->dest_name.name,
- dgram->dest_name.name_type,
- dgram->source_name.name,
- dgram->source_name.name_type,
- p->ip, *iface_ip(p->ip), p->port);
- break;
- }
+ case QUERYFORPDC:
+ {
+ char *q = buf + 2;
+ char *machine = q;
- case QUERYFORPDC:
- {
- char *q = buf + 2;
- char *machine = q;
+ getdc = skip_string(machine, 1);
+ unicomp = skip_string(getdc, 1);
- getdc = skip_string(machine,1);
- unicomp = skip_string(getdc,1);
+ q = align2(unicomp, buf);
- q = align2(unicomp, buf);
+ q = skip_unibuf(q, buf + len - q);
- q = skip_unibuf(q, buf+len-q);
+ if ((buf - q) >= len)
+ { /* Check for a short request */
- if ((buf - q) >= len) { /* Check for a short request */
+ short_request = 1;
- short_request = 1;
+ }
+ else
+ { /* A full length request */
- }
- else { /* A full length request */
+ if (dgram_unique)
+ {
+ /* skip domain name */
+ q += 22;
+ }
- ntversion = IVAL(q, 0);
- q += 4;
- lmnttoken = SVAL(q, 0);
- q += 2;
- lm20token = SVAL(q, 0);
- q += 2;
+ ntversion = IVAL(q, 0);
+ q += 4;
+ lmnttoken = SVAL(q, 0);
+ q += 2;
+ lm20token = SVAL(q, 0);
+ q += 2;
- }
+ }
- /* Construct reply. */
+ /* Construct reply. */
- q = outbuf;
- SSVAL(q, 0, QUERYFORPDC_R);
- q += 2;
+ q = outbuf;
+ SSVAL(q, 0, QUERYFORPDC_R);
+ q += 2;
- fstrcpy(reply_name,my_name);
- fstrcpy(q, reply_name);
- q = skip_string(q, 1); /* PDC name */
+ fstrcpy(reply_name, my_name);
+ fstrcpy(q, reply_name);
+ q = skip_string(q, 1); /* PDC name */
- /* PDC and domain name */
+ /* PDC and domain name */
- if (!short_request) /* Make a full reply */
- {
- q = align2(q, buf);
+ if (!short_request) /* Make a full reply */
+ {
+ q = align2(q, buf);
- q = ascii_to_unibuf(q, my_name, outbuf+sizeof(outbuf)-q-2);
- q = ascii_to_unibuf(q, global_myworkgroup, outbuf+sizeof(outbuf)-q-2);
+ q = ascii_to_unibuf(q, my_name,
+ outbuf +
+ sizeof(outbuf) - q - 2);
+ q = ascii_to_unibuf(q, global_myworkgroup,
+ outbuf +
+ sizeof(outbuf) - q - 2);
- ntversion = 0x01;
+ ntversion = 0x01;
- SIVAL(q, 0, ntversion);
- q += 4;
- SSVAL(q, 0, lmnttoken);
- q += 2;
- SSVAL(q, 0, lm20token);
- q += 2;
- }
+ SIVAL(q, 0, ntversion);
+ q += 4;
+ SSVAL(q, 0, lmnttoken);
+ q += 2;
+ SSVAL(q, 0, lm20token);
+ q += 2;
+ }
- /* RJS, 21-Feb-2000, we send a short reply if the request was short */
+ /* RJS, 21-Feb-2000, we send a short reply if the request was short */
- DEBUG(3,("process_logon_packet: GETDC request from %s at IP %s, \
+ DEBUG(3,
+ ("process_logon_packet: GETDC request from %s at IP %s, \
reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
- machine,inet_ntoa(p->ip), reply_name, lp_workgroup(),
- QUERYFORPDC_R, (uint32)ntversion, (uint32)lmnttoken,
- (uint32)lm20token ));
-
- dump_data(4, outbuf, PTR_DIFF(q, outbuf));
-
- send_mailslot(True, getdc,
- outbuf,PTR_DIFF(q,outbuf),
- my_name,
- 0x0,
- dgram->source_name.name,
- dgram->source_name.name_type,
- p->ip, *iface_ip(p->ip), p->port);
- return;
- }
-
- case SAMLOGON:
- {
- char *q = buf + 2;
-
- q += 2;
- unicomp = q;
- uniuser = skip_unibuf(unicomp, buf+len-q);
- getdc = skip_unibuf(uniuser, buf+len-q);
- q = skip_string(getdc,1);
- q += 4; /* skip Account Control Bits */
- domainsidsize = IVAL(q, 0);
- q += 4;
-
- if (domainsidsize != 0)
- {
- q += domainsidsize;
- q += 2;
- q = align4(q, buf);
- }
-
- ntversion = IVAL(q, 0);
- q += 4;
- lmnttoken = SVAL(q, 0);
- q += 2;
- lm20token = SVAL(q, 0);
- q += 2;
-
- DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d ntv %x\n", domainsidsize, ntversion));
-
- /*
- * we respond regadless of whether the machine is in our password
- * database. If it isn't then we let smbd send an appropriate error.
- * Let's ignore the SID.
- */
-
- fstrcpy(reply_name,"\\\\"); /* Here it wants \\LOGONSERVER. */
- fstrcpy(reply_name+2,my_name);
-
- ntversion = 0x01;
- lmnttoken = 0xffff;
- lm20token = 0xffff;
-
- if (DEBUGLVL(3))
- {
- fstring ascuser;
- fstring asccomp;
-
- unibuf_to_ascii(ascuser, uniuser, sizeof(ascuser)-1);
- unibuf_to_ascii(asccomp, unicomp, sizeof(asccomp)-1);
-
- DEBUGADD(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
- asccomp,inet_ntoa(p->ip), ascuser, reply_name,
- global_myworkgroup, SAMLOGON_R, lmnttoken));
- }
-
- /* Construct reply. */
-
- q = outbuf;
- if (uniuser[0] == 0)
- {
- SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
- }
- else
- {
- SSVAL(q, 0, SAMLOGON_R);
+ machine, inet_ntoa(p->ip), reply_name,
+ lp_workgroup(), QUERYFORPDC_R,
+ (uint32)ntversion, (uint32)lmnttoken,
+ (uint32)lm20token));
+
+ dump_data(4, outbuf, PTR_DIFF(q, outbuf));
+
+ send_mailslot(True, getdc,
+ outbuf, PTR_DIFF(q, outbuf),
+ my_name,
+ 0x0,
+ dgram->source_name.name,
+ dgram->source_name.name_type,
+ p->ip, *iface_ip(p->ip), p->port);
+ return;
+ }
+
+ case SAMLOGON:
+ {
+ char *q = buf + 2;
+
+ q += 2;
+ unicomp = q;
+ uniuser = skip_unibuf(unicomp, buf + len - q);
+ getdc = skip_unibuf(uniuser, buf + len - q);
+ q = skip_string(getdc, 1);
+ q += 4; /* skip Account Control Bits */
+ domainsidsize = IVAL(q, 0);
+ q += 4;
+
+ if (domainsidsize != 0)
+ {
+ q += domainsidsize;
+ q += 2;
+ q = align4(q, buf);
+ }
+
+ ntversion = IVAL(q, 0);
+ q += 4;
+ lmnttoken = SVAL(q, 0);
+ q += 2;
+ lm20token = SVAL(q, 0);
+ q += 2;
+
+ DEBUG(3,
+ ("process_logon_packet: SAMLOGON sidsize %d ntv %x\n",
+ domainsidsize, ntversion));
+
+ /*
+ * we respond regadless of whether the machine is in our password
+ * database. If it isn't then we let smbd send an appropriate error.
+ * Let's ignore the SID.
+ */
+
+ fstrcpy(reply_name, "\\\\"); /* Here it wants \\LOGONSERVER. */
+ fstrcpy(reply_name + 2, my_name);
+
+ ntversion = 0x01;
+ lmnttoken = 0xffff;
+ lm20token = 0xffff;
+
+ if (DEBUGLVL(3))
+ {
+ fstring ascuser;
+ fstring asccomp;
+
+ unibuf_to_ascii(ascuser, uniuser,
+ sizeof(ascuser) - 1);
+ unibuf_to_ascii(asccomp, unicomp,
+ sizeof(asccomp) - 1);
+
+ DEBUGADD(3,
+ ("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
+ asccomp, inet_ntoa(p->ip), ascuser,
+ reply_name, global_myworkgroup,
+ SAMLOGON_R, lmnttoken));
+ }
+
+ /* Construct reply. */
+
+ q = outbuf;
+ if (uniuser[0] == 0)
+ {
+ SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
+ }
+ else
+ {
+ SSVAL(q, 0, SAMLOGON_R);
+ }
+ q += 2;
+
+ /* Logon server, trust account, domain */
+ q = ascii_to_unibuf(q, reply_name,
+ outbuf + sizeof(outbuf) - q - 2);
+ q = uni_strncpy(q, uniuser,
+ outbuf + sizeof(outbuf) - q - 2);
+ q = ascii_to_unibuf(q, lp_workgroup(),
+ outbuf + sizeof(outbuf) - q - 2);
+
+ SIVAL(q, 0, ntversion);
+ q += 4;
+ SSVAL(q, 0, lmnttoken);
+ q += 2;
+ SSVAL(q, 0, lm20token);
+ q += 2;
+
+ dump_data(4, outbuf, PTR_DIFF(q, outbuf));
+
+ send_mailslot(True, getdc,
+ outbuf, PTR_DIFF(q, outbuf),
+ my_name,
+ 0x0,
+ dgram->source_name.name,
+ dgram->source_name.name_type,
+ p->ip, *iface_ip(p->ip), p->port);
+ break;
+ }
+
+ default:
+ {
+ DEBUG(3,
+ ("process_logon_packet: Unknown domain request %d\n",
+ code));
+ return;
+ }
}
- q += 2;
-
- /* Logon server, trust account, domain */
- q = ascii_to_unibuf(q, reply_name, outbuf+sizeof(outbuf)-q-2);
- q = uni_strncpy(q, uniuser, outbuf+sizeof(outbuf)-q-2);
- q = ascii_to_unibuf(q, lp_workgroup(), outbuf+sizeof(outbuf)-q-2);
-
- SIVAL(q, 0, ntversion);
- q += 4;
- SSVAL(q, 0, lmnttoken);
- q += 2;
- SSVAL(q, 0, lm20token);
- q += 2;
-
- dump_data(4, outbuf, PTR_DIFF(q, outbuf));
-
- send_mailslot(True, getdc,
- outbuf,PTR_DIFF(q,outbuf),
- my_name,
- 0x0,
- dgram->source_name.name,
- dgram->source_name.name_type,
- p->ip, *iface_ip(p->ip), p->port);
- break;
- }
-
- default:
- {
- DEBUG(3,("process_logon_packet: Unknown domain request %d\n",code));
- return;
- }
- }
}