summaryrefslogtreecommitdiff
path: root/source3/nmbd
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2008-08-09 01:04:55 +0200
committerMichael Adam <obnox@samba.org>2008-08-09 01:15:58 +0200
commit9b9948134eb9d145f5d6610b645440e3e4dd3942 (patch)
treef48c839358f351909fb30fe425a65f3e24dbad84 /source3/nmbd
parent33e3e94e0cff075ec7d3364c4de73c154369ce06 (diff)
downloadsamba-9b9948134eb9d145f5d6610b645440e3e4dd3942.tar.gz
samba-9b9948134eb9d145f5d6610b645440e3e4dd3942.tar.bz2
samba-9b9948134eb9d145f5d6610b645440e3e4dd3942.zip
nmbd: add support for delayed initial samlogon packages.
The hosts or networks configured with "init logon delayed hosts" have their initial samlogon packages (empty username) delayed by the value configured with "init logon delay" (defaulting to 100 milliseconds). This gives the administrator some control over what clients would consider the preferred logon server: they choose the server that repsonds most quickly. Michael (This used to be commit d52b9beede1fb14e1d7e3acd9765d6cd14dfcc3d)
Diffstat (limited to 'source3/nmbd')
-rw-r--r--source3/nmbd/nmbd_processlogon.c92
1 files changed, 86 insertions, 6 deletions
diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c
index 6e110dd1ca..f7990def07 100644
--- a/source3/nmbd/nmbd_processlogon.c
+++ b/source3/nmbd/nmbd_processlogon.c
@@ -31,6 +31,40 @@ struct sam_database_info {
uint32 date_lo, date_hi;
};
+/**
+ * check whether the client belongs to the hosts
+ * for which initial logon should be delayed...
+ */
+static bool delay_logon(const char *peer_name, const char *peer_addr)
+{
+ const char **delay_list = lp_init_logon_delayed_hosts();
+ const char *peer[2];
+
+ if (delay_list == NULL) {
+ return False;
+ }
+
+ peer[0] = peer_name;
+ peer[1] = peer_addr;
+
+ return list_match(delay_list, (const char *)peer, client_match);
+}
+
+static void delayed_init_logon_handler(struct event_context *event_ctx,
+ struct timed_event *te,
+ const struct timeval *now,
+ void *private_data)
+{
+ struct packet_struct *p = (struct packet_struct *)private_data;
+
+ DEBUG(10, ("delayed_init_logon_handler (%lx): re-queuing packet.\n",
+ (unsigned long)te));
+
+ queue_packet(p);
+
+ TALLOC_FREE(te);
+}
+
/****************************************************************************
Process a domain logon packet
**************************************************************************/
@@ -280,6 +314,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
{
fstring getdc_str;
fstring source_name;
+ char *source_addr;
char *q = buf + 2;
fstring asccomp;
@@ -591,13 +626,58 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
pull_ascii_fstring(getdc_str, getdc);
pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
+ source_addr = SMB_STRDUP(inet_ntoa(dgram->header.source_ip));
+ if (source_addr == NULL) {
+ DEBUG(3, ("out of memory copying client"
+ " address string\n"));
+ return;
+ }
+
+ /*
+ * handle delay.
+ * packets requeued after delay are marked as
+ * locked.
+ */
+ if ((p->locked == False) &&
+ (strlen(ascuser) == 0) &&
+ delay_logon(source_name, source_addr))
+ {
+ struct timeval when;
+
+ DEBUG(3, ("process_logon_packet: "
+ "delaying initial logon "
+ "reply for client %s(%s) for "
+ "%u milliseconds\n",
+ source_name, source_addr,
+ lp_init_logon_delay()));
+
+ when = timeval_current_ofs(0,
+ lp_init_logon_delay() * 1000);
+ p->locked = true;
+ event_add_timed(nmbd_event_context(),
+ NULL,
+ when,
+ "delayed_init_logon",
+ delayed_init_logon_handler,
+ p);
+ } else {
+ DEBUG(3, ("process_logon_packet: "
+ "processing delayed initial "
+ "logon reply for client "
+ "%s(%s)\n",
+ source_name, source_addr));
+
+ p->locked = false;
+ send_mailslot(true, getdc,
+ outbuf,PTR_DIFF(q,outbuf),
+ global_myname(), 0x0,
+ source_name,
+ dgram->source_name.name_type,
+ p->ip, ip, p->port);
+ }
+
+ SAFE_FREE(source_addr);
- send_mailslot(True, getdc,
- outbuf,PTR_DIFF(q,outbuf),
- global_myname(), 0x0,
- source_name,
- dgram->source_name.name_type,
- p->ip, ip, p->port);
break;
}