2 Unix SMB/CIFS implementation.
3 NBT netbios routines and daemon - version 2
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Luke Kenneth Casson Leighton 1994-1998
6 Copyright (C) Jeremy Allison 1994-2003
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include "../libcli/netlogon/netlogon.h"
28 #include "../libcli/cldap/cldap.h"
29 #include "../lib/tsocket/tsocket.h"
30 #include "../libcli/security/security.h"
32 #include "nmbd/nmbd.h"
34 struct sam_database_info
{
36 uint32_t serial_lo
, serial_hi
;
37 uint32_t date_lo
, date_hi
;
41 * check whether the client belongs to the hosts
42 * for which initial logon should be delayed...
44 static bool delay_logon(const char *peer_name
, const char *peer_addr
)
46 const char **delay_list
= lp_init_logon_delayed_hosts();
49 if (delay_list
== NULL
) {
56 return list_match(delay_list
, (const char *)peer
, client_match
);
59 static void delayed_init_logon_handler(struct tevent_context
*event_ctx
,
60 struct tevent_timer
*te
,
64 struct packet_struct
*p
= (struct packet_struct
*)private_data
;
66 DEBUG(10, ("delayed_init_logon_handler (%lx): re-queuing packet.\n",
74 /****************************************************************************
75 Process a domain logon packet
76 **************************************************************************/
78 void process_logon_packet(struct packet_struct
*p
, const char *buf
,int len
,
82 struct dgram_packet
*dgram
= &p
->packet
.dgram
;
83 struct sockaddr_storage ss
;
84 const struct sockaddr_storage
*pss
;
87 DATA_BLOB blob_in
, blob_out
;
88 enum ndr_err_code ndr_err
;
89 struct nbt_netlogon_packet request
;
90 struct nbt_netlogon_response response
;
94 in_addr_to_sockaddr_storage(&ss
, p
->ip
);
95 pss
= iface_ip((struct sockaddr
*)&ss
);
97 DEBUG(5,("process_logon_packet:can't find outgoing interface "
98 "for packet from IP %s\n",
102 ip
= ((const struct sockaddr_in
*)pss
)->sin_addr
;
105 DEBUG(5,("process_logon_packet: Logon packet received from IP %s and domain \
106 logons are not enabled.\n", inet_ntoa(p
->ip
) ));
110 pull_ascii_nstring(source_name
, sizeof(source_name
), dgram
->source_name
.name
);
112 pdc_name
= talloc_asprintf(talloc_tos(), "\\\\%s", lp_netbios_name());
117 ZERO_STRUCT(request
);
119 blob_in
= data_blob_const(buf
, len
);
121 ndr_err
= ndr_pull_struct_blob(&blob_in
, talloc_tos(), &request
,
122 (ndr_pull_flags_fn_t
)ndr_pull_nbt_netlogon_packet
);
123 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
124 DEBUG(1,("process_logon_packet: Failed to pull logon packet\n"));
128 if (DEBUGLEVEL
>= 10) {
129 NDR_PRINT_DEBUG(nbt_netlogon_packet
, &request
);
132 DEBUG(4,("process_logon_packet: Logon from %s: code = 0x%x\n",
133 inet_ntoa(p
->ip
), request
.command
));
135 switch (request
.command
) {
136 case LOGON_REQUEST
: {
138 struct nbt_netlogon_response2 response2
;
140 DEBUG(5,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n",
141 request
.req
.logon0
.computer_name
, inet_ntoa(p
->ip
),
142 request
.req
.logon0
.user_name
,
143 request
.req
.logon0
.lm20_token
));
145 response2
.command
= LOGON_RESPONSE2
;
146 response2
.pdc_name
= pdc_name
;
147 response2
.lm20_token
= 0xffff;
149 response
.response_type
= NETLOGON_RESPONSE2
;
150 response
.data
.response2
= response2
;
152 status
= push_nbt_netlogon_response(&blob_out
, talloc_tos(), &response
);
153 if (!NT_STATUS_IS_OK(status
)) {
154 DEBUG(0,("process_logon_packet: failed to push packet\n"));
158 if (DEBUGLEVEL
>= 10) {
159 NDR_PRINT_DEBUG(nbt_netlogon_response2
, &response
.data
.response2
);
162 send_mailslot(True
, request
.req
.logon0
.mailslot_name
,
163 (char *)blob_out
.data
,
165 lp_netbios_name(), 0x0,
167 dgram
->source_name
.name_type
,
172 case LOGON_PRIMARY_QUERY
: {
174 struct nbt_netlogon_response_from_pdc get_pdc
;
176 if (!lp_domain_master()) {
177 /* We're not Primary Domain Controller -- ignore this */
181 DEBUG(5,("process_logon_packet: GETDC request from %s at IP %s, "
182 "reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
183 request
.req
.pdc
.computer_name
,
187 NETLOGON_RESPONSE_FROM_PDC
,
188 request
.req
.pdc
.nt_version
,
189 request
.req
.pdc
.lmnt_token
,
190 request
.req
.pdc
.lm20_token
));
192 get_pdc
.command
= NETLOGON_RESPONSE_FROM_PDC
;
193 get_pdc
.pdc_name
= lp_netbios_name();
194 get_pdc
._pad
= data_blob_null
;
195 get_pdc
.unicode_pdc_name
= lp_netbios_name();
196 get_pdc
.domain_name
= lp_workgroup();
197 get_pdc
.nt_version
= NETLOGON_NT_VERSION_1
;
198 get_pdc
.lmnt_token
= 0xffff;
199 get_pdc
.lm20_token
= 0xffff;
201 response
.response_type
= NETLOGON_GET_PDC
;
202 response
.data
.get_pdc
= get_pdc
;
204 status
= push_nbt_netlogon_response(&blob_out
, talloc_tos(), &response
);
205 if (!NT_STATUS_IS_OK(status
)) {
206 DEBUG(0,("process_logon_packet: failed to push packet\n"));
210 if (DEBUGLEVEL
>= 10) {
211 NDR_PRINT_DEBUG(nbt_netlogon_response_from_pdc
, &response
.data
.get_pdc
);
214 send_mailslot(True
, request
.req
.pdc
.mailslot_name
,
215 (char *)blob_out
.data
,
217 lp_netbios_name(), 0x0,
219 dgram
->source_name
.name_type
,
225 case LOGON_SAM_LOGON_REQUEST
: {
227 bool user_unknown
= false;
229 struct netlogon_samlogon_response samlogon
;
230 struct NETLOGON_SAM_LOGON_RESPONSE_NT40 nt4
;
232 source_addr
= SMB_STRDUP(inet_ntoa(dgram
->header
.source_ip
));
233 if (source_addr
== NULL
) {
234 DEBUG(3, ("out of memory copying client"
235 " address string\n"));
239 DEBUG(5,("process_logon_packet: LOGON_SAM_LOGON_REQUEST request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
240 request
.req
.logon
.computer_name
,
242 request
.req
.logon
.user_name
,
245 LOGON_SAM_LOGON_RESPONSE
,
246 request
.req
.logon
.lmnt_token
));
248 if (!request
.req
.logon
.user_name
) {
252 nt4
.command
= user_unknown
? LOGON_SAM_LOGON_USER_UNKNOWN
:
253 LOGON_SAM_LOGON_RESPONSE
;
254 nt4
.pdc_name
= pdc_name
;
255 nt4
.user_name
= request
.req
.logon
.user_name
;
256 nt4
.domain_name
= lp_workgroup();
257 nt4
.nt_version
= NETLOGON_NT_VERSION_1
;
258 nt4
.lmnt_token
= 0xffff;
259 nt4
.lm20_token
= 0xffff;
261 samlogon
.ntver
= NETLOGON_NT_VERSION_1
;
262 samlogon
.data
.nt4
= nt4
;
264 if (DEBUGLEVEL
>= 10) {
265 NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_NT40
, &nt4
);
268 response
.response_type
= NETLOGON_SAMLOGON
;
269 response
.data
.samlogon
= samlogon
;
271 status
= push_nbt_netlogon_response(&blob_out
, talloc_tos(), &response
);
272 if (!NT_STATUS_IS_OK(status
)) {
273 DEBUG(0,("process_logon_packet: failed to push packet\n"));
274 SAFE_FREE(source_addr
);
280 * packets requeued after delay are marked as
283 if ((p
->locked
== False
) &&
284 (strlen(request
.req
.logon
.user_name
) == 0) &&
285 delay_logon(source_name
, source_addr
))
289 DEBUG(3, ("process_logon_packet: "
290 "delaying initial logon "
291 "reply for client %s(%s) for "
293 source_name
, source_addr
,
294 lp_init_logon_delay()));
296 when
= timeval_current_ofs_msec(lp_init_logon_delay());
298 tevent_add_timer(nmbd_event_context(),
301 delayed_init_logon_handler
,
304 DEBUG(3, ("process_logon_packet: "
305 "processing delayed initial "
306 "logon reply for client "
308 source_name
, source_addr
));
310 send_mailslot(true, request
.req
.logon
.mailslot_name
,
311 (char *)blob_out
.data
,
313 lp_netbios_name(), 0x0,
315 dgram
->source_name
.name_type
,
319 SAFE_FREE(source_addr
);
324 /* Announce change to UAS or SAM. Send by the domain controller when a
325 replication event is required. */
327 case NETLOGON_ANNOUNCE_UAS
:
328 DEBUG(5, ("Got NETLOGON_ANNOUNCE_UAS\n"));
332 DEBUG(3,("process_logon_packet: Unknown domain request %d\n",