da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This module handles the primary domain controller location protocol.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The document claims to be version 1.15 of the browsing protocol. It also
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * claims to specify the mailslot protocol.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The NETLOGON protocol uses \MAILSLOT\NET mailslots. The protocol
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * specification is incomplete, contains errors and is out-of-date but
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * it does provide some useful background information. The document
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * doesn't mention the NETLOGON_SAMLOGON version of the protocol.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <stdlib.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <syslog.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <alloca.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <arpa/inet.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <resolv.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/mailslot.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/libsmbns.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbns_browser.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbns_netbios.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void smb_netlogon_query(struct name_entry *server, char *mailbox,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *domain);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic void smb_netlogon_samlogon(struct name_entry *, char *,
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright char *, smb_sid_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void smb_netlogon_send(struct name_entry *name, char *domain,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char *buffer, int count);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void smb_netlogon_rdc_rsp(char *src_name, uint32_t src_ipaddr);
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic int smb_better_dc(uint32_t cur_ip, uint32_t new_ip);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego/*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * ntdomain_info
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Temporary. It should be removed once NBTD is integrated.
8d7e41661dc4633488e93b13363137523ce59977jose borrego */
8d7e41661dc4633488e93b13363137523ce59977jose borregoextern smb_ntdomain_t ntdomain_info;
8d7e41661dc4633488e93b13363137523ce59977jose borregoextern mutex_t ntdomain_mtx;
8d7e41661dc4633488e93b13363137523ce59977jose borregoextern cond_t ntdomain_cv;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_netlogon_request
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This is the entry point locating the resource domain PDC. A netlogon
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * request is sent using the specified protocol on the specified network.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Note that we need to know the domain SID in order to use the samlogon
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * format.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Netlogon responses are received asynchronously and eventually handled
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * in smb_netlogon_receive.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_netlogon_request(struct name_entry *server, char *domain)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright smb_domain_t di;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_sid_t *sid = NULL;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright int protocol = NETLOGON_PROTO_NETLOGON;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
7b59d02d2a384be9a08087b14defadd214b3c1ddjb if (domain == NULL || *domain == '\0')
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) mutex_lock(&ntdomain_mtx);
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) strlcpy(ntdomain_info.n_domain, domain,
8d7e41661dc4633488e93b13363137523ce59977jose borrego sizeof (ntdomain_info.n_domain));
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) mutex_unlock(&ntdomain_mtx);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_config_getdomaininfo(di.di_nbname, NULL, di.di_sid, NULL, NULL);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (smb_strcasecmp(di.di_nbname, domain, 0) == 0) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if ((sid = smb_sid_fromstr(di.di_sid)) != NULL)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright protocol = NETLOGON_PROTO_SAMLOGON;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright }
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright if (protocol == NETLOGON_PROTO_SAMLOGON)
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_netlogon_samlogon(server, MAILSLOT_NETLOGON_SAMLOGON_RDC,
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright domain, sid);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb else
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_netlogon_query(server, MAILSLOT_NETLOGON_RDC, domain);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_sid_free(sid);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_netlogon_receive
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This is where we handle all incoming NetLogon messages. Currently, we
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * ignore requests from anyone else. We are only interested in responses
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to our own requests. The NetLogonResponse provides the name of the PDC.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If we don't already have a controller name, we use the name provided
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * in the message. Otherwise we use the name already in the environment.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_netlogon_receive(struct datagram *datagram,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *mailbox,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char *data,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int datalen)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct netlogon_opt {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *mailslot;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw void (*handler)();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } netlogon_opt[] = {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw { MAILSLOT_NETLOGON_RDC, smb_netlogon_rdc_rsp },
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw { MAILSLOT_NETLOGON_SAMLOGON_RDC, smb_netlogon_rdc_rsp },
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw };
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_t mb;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned short opcode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char src_name[SMB_PI_MAX_HOST];
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_wchar_t unicode_src_name[SMB_PI_MAX_HOST];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t src_ipaddr;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *junk;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *primary;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *domain;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int i;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char ipstr[16];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw src_ipaddr = datagram->src.addr_list.sin.sin_addr.s_addr;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The datagram->src.name is in oem codepage format.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Therefore, we need to convert it to unicode and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * store it in multi-bytes format.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown (void) oemtoucs(unicode_src_name, (char *)datagram->src.name,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown SMB_PI_MAX_HOST, OEM_CPG_850);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown (void) smb_wcstombs(src_name, unicode_src_name, SMB_PI_MAX_HOST);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) trim_whitespace(src_name);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) inet_ntop(AF_INET, (const void *)(&src_ipaddr), ipstr,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sizeof (ipstr));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_DEBUG, "NetLogonReceive: src=%s [%s], mbx=%s",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw src_name, ipstr, mailbox);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_init(&mb, data, datalen, 0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (smb_msgbuf_decode(&mb, "w", &opcode) < 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_ERR, "NetLogonReceive: decode error");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_term(&mb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (opcode) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case LOGON_PRIMARY_RESPONSE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Message contains:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * PDC name (MBS), PDC name (Unicode), Domain name (unicode)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_msgbuf_decode(&mb, "sUU", &junk, &primary, &domain);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc < 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_ERR,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "NetLogonResponse: opcode %d decode error",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw opcode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_term(&mb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case LOGON_SAM_LOGON_RESPONSE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case LOGON_SAM_USER_UNKNOWN:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Message contains:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * PDC name, User name, Domain name (all unicode)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_msgbuf_decode(&mb, "UUU", &primary, &junk, &domain);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc < 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_ERR,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "NetLogonResponse: opcode %d decode error",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw opcode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_term(&mb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * skip past the "\\" prefix
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw primary += strspn(primary, "\\");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * We don't respond to PDC discovery requests.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_DEBUG, "NetLogonReceive: opcode 0x%04x", opcode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_term(&mb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright if (domain == NULL || primary == NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_ERR, "NetLogonResponse: malformed packet");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_term(&mb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright syslog(LOG_DEBUG, "DC Offer Domain=%s PDC=%s From=%s",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw domain, primary, src_name);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) mutex_lock(&ntdomain_mtx);
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (strcasecmp(domain, ntdomain_info.n_domain)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_DEBUG, "NetLogonResponse: other domain "
8d7e41661dc4633488e93b13363137523ce59977jose borrego "%s, requested %s", domain, ntdomain_info.n_domain);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_term(&mb);
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) mutex_unlock(&ntdomain_mtx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) mutex_unlock(&ntdomain_mtx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (i = 0; i < sizeof (netlogon_opt)/sizeof (netlogon_opt[0]); ++i) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (strcasecmp(netlogon_opt[i].mailslot, mailbox) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_DEBUG, "NetLogonReceive: %s", mailbox);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (*netlogon_opt[i].handler)(primary, src_ipaddr);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_term(&mb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_DEBUG, "NetLogonReceive[%s]: unknown mailslot", mailbox);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_term(&mb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_netlogon_query
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Build and send a LOGON_PRIMARY_QUERY to the MAILSLOT_NETLOGON. At some
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * point we should receive a LOGON_PRIMARY_RESPONSE in the mailslot we
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * specify in the request.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * struct NETLOGON_QUERY {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * unsigned short Opcode; # LOGON_PRIMARY_QUERY
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * char ComputerName[]; # ASCII hostname. The response
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * # is sent to <ComputerName>(00).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * char MailslotName[]; # MAILSLOT_NETLOGON
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * char Pad[]; # Pad to short
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * wchar_t ComputerName[] # UNICODE hostname
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * DWORD NT_Version; # 0x00000001
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * WORD LmNTToken; # 0xffff
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * WORD Lm20Token; # 0xffff
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * };
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_netlogon_query(struct name_entry *server,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *mailbox,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *domain)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_t mb;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int offset, announce_len, data_length, name_lengths;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char buffer[MAX_DATAGRAM_LENGTH];
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States char hostname[NETBIOS_NAME_SZ];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States if (smb_getnetbiosname(hostname, sizeof (hostname)) != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw name_lengths = strlen(mailbox)+1+strlen(hostname)+1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The (name_lengths & 1) part is to word align the name_lengths
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * before the wc equiv strlen and the "+ 2" is to cover the two
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * zero bytes that terminate the wchar string.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw data_length = sizeof (short) + name_lengths + (name_lengths & 1) +
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_wcequiv_strlen(hostname) + 2 + sizeof (long) + sizeof (short) +
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sizeof (short);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw offset = smb_browser_load_transact_header(buffer,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sizeof (buffer), data_length, ONE_WAY_TRANSACTION,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw MAILSLOT_NETLOGON);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (offset < 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_init(&mb, buffer + offset, sizeof (buffer) - offset, 0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw announce_len = smb_msgbuf_encode(&mb, "wssUlww",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (short)LOGON_PRIMARY_QUERY,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw hostname,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mailbox,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw hostname,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x1,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0xffff,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0xffff);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (announce_len <= 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_term(&mb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_ERR, "NetLogonQuery: encode error");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_netlogon_send(server, domain, buffer, offset + announce_len);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_term(&mb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_netlogon_samlogon
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The SamLogon version of the NetLogon request uses the workstation trust
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * account and, I think, may be a prerequisite to the challenge/response
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * netr authentication. The trust account username is the hostname with a
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * $ appended. The mailslot for this request is MAILSLOT_NTLOGON. At some
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * we should receive a LOGON_SAM_LOGON_RESPONSE in the mailslot we
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * specify in the request.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * struct NETLOGON_SAM_LOGON {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * unsigned short Opcode; # LOGON_SAM_LOGON_REQUEST
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * unsigned short RequestCount; # 0
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * wchar_t UnicodeComputerName; # hostname
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * wchar_t UnicodeUserName; # hostname$
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * char *MailslotName; # response mailslot
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * DWORD AllowableAccountControlBits; # 0x80 = WorkstationTrustAccount
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * DWORD DomainSidSize; # domain sid length in bytes
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * BYTE *DomainSid; # domain sid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * uint32_t NT_Version; # 0x00000001
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * unsigned short LmNTToken; # 0xffff
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * unsigned short Lm20Token; # 0xffff
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * };
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_netlogon_samlogon(struct name_entry *server,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *mailbox,
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright char *domain,
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright smb_sid_t *domain_sid)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_t mb;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned domain_sid_len;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *username;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char buffer[MAX_DATAGRAM_LENGTH];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int offset;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int announce_len;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int data_length;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int name_length;
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States char hostname[NETBIOS_NAME_SZ];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_DEBUG, "NetLogonSamLogonReq: %s", domain);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States if (smb_getnetbiosname(hostname, sizeof (hostname)) != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The username will be the trust account name on the PDC.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw name_length = strlen(hostname) + 2;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw username = alloca(name_length);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) snprintf(username, name_length, "%s$", hostname);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright domain_sid_len = smb_sid_len(domain_sid);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Add 2 to wide-char equivalent strlen to cover the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * two zero bytes that terminate the wchar string.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw name_length = strlen(mailbox)+1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw data_length = sizeof (short)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw + sizeof (short)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown + smb_wcequiv_strlen(hostname) + 2
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown + smb_wcequiv_strlen(username) + 2
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw + name_length
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw + sizeof (long)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw + sizeof (long)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw + domain_sid_len + 3 /* padding */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw + sizeof (long)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw + sizeof (short)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw + sizeof (short);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw offset = smb_browser_load_transact_header(buffer,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sizeof (buffer), data_length, ONE_WAY_TRANSACTION,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw MAILSLOT_NTLOGON);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (offset < 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_ERR, "NetLogonSamLogonReq: header error");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The domain SID is padded with 3 leading zeros.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_init(&mb, buffer + offset, sizeof (buffer) - offset, 0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw announce_len = smb_msgbuf_encode(&mb, "wwUUsll3.#clww",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (short)LOGON_SAM_LOGON_REQUEST,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, /* RequestCount */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw hostname, /* UnicodeComputerName */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw username, /* UnicodeUserName */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mailbox, /* MailslotName */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00000080, /* AllowableAccountControlBits */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw domain_sid_len, /* DomainSidSize */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw domain_sid_len, domain_sid, /* DomainSid */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00000001, /* NT_Version */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0xffff, /* LmNTToken */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0xffff); /* Lm20Token */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (announce_len <= 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_ERR, "NetLogonSamLogonReq: encode error");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_term(&mb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_netlogon_send(server, domain, buffer, offset + announce_len);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_msgbuf_term(&mb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Send a query for each version of the protocol.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_netlogon_send(struct name_entry *name,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *domain,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char *buffer,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int count)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw static char suffix[] = { 0x1B, 0x1C };
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct name_entry dname;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct name_entry *dest;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct name_entry *dest_dup;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int i;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (i = 0; i < sizeof (suffix)/sizeof (suffix[0]); i++) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_init_name_struct((unsigned char *)domain, suffix[i],
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, 0, 0, 0, 0, &dname);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright syslog(LOG_DEBUG, "SmbNetlogonSend");
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright smb_netbios_name_logf(&dname);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((dest = smb_name_find_name(&dname)) != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw dest_dup = smb_netbios_name_dup(dest, 1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_name_unlock_name(dest);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (dest_dup) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) smb_netbios_datagram_send(name,
8d7e41661dc4633488e93b13363137523ce59977jose borrego dest_dup, buffer, count);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw free(dest_dup);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright syslog(LOG_DEBUG,
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright "SmbNetlogonSend: could not find %s<0x%X>",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw domain, suffix[i]);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_netlogon_rdc_rsp
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This is where we process netlogon responses for the resource domain.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The src_name is the real name of the remote machine.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_netlogon_rdc_rsp(char *src_name, uint32_t src_ipaddr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw static int initialized = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t ipaddr;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego uint32_t prefer_ipaddr;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego char ipstr[INET_ADDRSTRLEN];
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego char srcip[INET_ADDRSTRLEN];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego (void) inet_ntop(AF_INET, &src_ipaddr, srcip, INET_ADDRSTRLEN);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego rc = smb_config_getstr(SMB_CI_DOMAIN_SRV, ipstr, INET_ADDRSTRLEN);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if (rc == SMBD_SMF_OK) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rc = inet_pton(AF_INET, ipstr, &prefer_ipaddr);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc == 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw prefer_ipaddr = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!initialized) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_DEBUG, "SMB DC Preference: %s", ipstr);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw initialized = 1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) mutex_lock(&ntdomain_mtx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_DEBUG, "DC Offer [%s]: %s [%s]",
8d7e41661dc4633488e93b13363137523ce59977jose borrego ntdomain_info.n_domain, src_name, srcip);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (ntdomain_info.n_ipaddr != 0) {
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego if (prefer_ipaddr != 0 &&
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego prefer_ipaddr == ntdomain_info.n_ipaddr) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_DEBUG, "DC for %s: %s [%s]",
8d7e41661dc4633488e93b13363137523ce59977jose borrego ntdomain_info.n_domain, src_name, srcip);
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) mutex_unlock(&ntdomain_mtx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego ipaddr = ntdomain_info.n_ipaddr;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ipaddr = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if (smb_better_dc(ipaddr, src_ipaddr) ||
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (prefer_ipaddr != 0 && prefer_ipaddr == src_ipaddr)) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego /* set nbtd cache */
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) strlcpy(ntdomain_info.n_name, src_name,
8d7e41661dc4633488e93b13363137523ce59977jose borrego SMB_PI_MAX_DOMAIN);
8d7e41661dc4633488e93b13363137523ce59977jose borrego ntdomain_info.n_ipaddr = src_ipaddr;
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) cond_broadcast(&ntdomain_cv);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syslog(LOG_DEBUG, "DC discovered for %s: %s [%s]",
8d7e41661dc4633488e93b13363137523ce59977jose borrego ntdomain_info.n_domain, src_name, srcip);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) mutex_unlock(&ntdomain_mtx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_better_dc(uint32_t cur_ip, uint32_t new_ip)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_inaddr_t ipaddr;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If we don't have any current DC,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * then use the new one of course.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (cur_ip == 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (1);
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright /*
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * see if there is a DC in the
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * same subnet
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ipaddr.a_family = AF_INET;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ipaddr.a_ipv4 = cur_ip;
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright if (smb_nic_is_same_subnet(&ipaddr))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ipaddr.a_family = AF_INET;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ipaddr.a_ipv4 = new_ip;
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright if (smb_nic_is_same_subnet(&ipaddr))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Otherwise, just keep the old one.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}