smbns_dyndns.c revision 2
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A * defines BADSIG, BADKEY and BADTIME. 2N/A * DYNDNS_TTL is the time to live in DNS caches. Note that this 2N/A * does not affect the entry in the authoritative DNS database. 2N/A/* Microsoft AD interoperability */ 2N/A/* lint-free alternatives to NS_PUT16, NS_PUT32 */ 2N/A/* add a host integer to a network short */ 2N/A * Dynamic DNS update API for kclient. 2N/A * Returns 0 upon success. Otherwise, returns -1. 2N/A * Convert IPv4 or IPv6 sockaddr to hostname. 2N/A * The value is lowercase per RFC 4120 section 6.2.1. 2N/A * Log a DNS error message 2N/A {
YXRRSET,
"RRSet should not exist but does exist" },
2N/A {
NXRRSET,
"RRSet should exist but does not exist" },
2N/A {
NOTAUTH,
"server is not authoritative for specified zone" },
2N/A {
BADSIG,
"bad transaction signature (TSIG)" },
2N/A * Log a DNS update description message 2N/A "add hostname %s %s address %s in %s zone",
2N/A "delete all %s addresses for hostname %s " 2N/A "delete all hostnames for %s address %s " 2N/A "delete %s address %s in reverse zone",
2N/A "delete hostname %s %s address %s in %s zone",
2N/A * Display GSS error message from error code. This routine is used to display 2N/A * the mechanism independent and mechanism specific error messages for GSS 2N/A * routines. The major status error code is the mechanism independent error 2N/A * code and the minor status error code is the mechanism specific error code. 2N/A * maj: GSS major status 2N/A * min: GSS minor status 2N/A * dyndns_addr_to_ptrname 2N/A * Convert a network address structure into a domain name for reverse lookup. 2N/A * IPv4 addresses are converted to in-addr.arpa names (RFC 1035 section 3.5). 2N/A * IPv6 addresses are converted to ip6.arpa names (RFC 3596 section 2.5). 2N/A * af: address family of *addr, AF_INET or AF_INET6 2N/A * addr: pointer to in_addr or in6_addr address structure 2N/A * buf: buffer to hold reverse domain name 2N/A * buf_sz: length of buffer 2N/A * 0 on error, or length of domain name written to buf 2N/A * The IPv6 reverse lookup domain name format has 2N/A * 4 chars for each address byte, followed by "ip6.arpa". 2N/A * dyndns_get_update_info 2N/A * Given a valid resolver context, update direction, and a host name and 2N/A * address pair, return the information needed to perform a DNS update. 2N/A * DNS zone and SOA nameservers are found by searching current DNS data. 2N/A * dyndns_get_update_info(statp, DYNDNS_ZONE_FWD, type, 2N/A * data_buf: "10.0.0.1" 2N/A * dyndns_get_update_info(statp, DYNDNS_ZONE_REV, type, 2N/A * zone_buf: "10.in-addr.arpa" 2N/A * name_buf: "1.0.0.10.in-addr.arpa" 2N/A * statp: resolver state 2N/A * update_zone: one of DYNDNS_ZONE_FWD or DYNDNS_ZONE_REV 2N/A * hostname: host name, as a string 2N/A * af: address family of *addr, AF_INET or AF_INET6 2N/A * addr: pointer to in_addr or in6_addr address structure 2N/A * type: type of DNS record to update 2N/A * zone_buf: buffer to receive zone owning name 2N/A * zone_sz: size of zone_buf buffer 2N/A * name_buf: buffer to receive name to update 2N/A * name_sz: size of name_buf buffer 2N/A * data_buf: buffer to receive data to update for name 2N/A * data_sz: size of data_buf buffer 2N/A * ns: buffer to receive nameservers found for zone 2N/A * ns_cnt: number of nameservers that fit in ns buffer 2N/A * -1 on error, or number of nameservers returned in ns 2N/A * Build a TKEY RDATA section according to RFC 2930 section 2. 2N/A * May be called with buf == NULL and buf_sz == 0, in which case the 2N/A * function does not actually build the TKEY RDATA, but only returns the 2N/A * space needed for TKEY RDATA as specified by the tkey parameter. 2N/A * buf: buffer to store TKEY RDATA 2N/A * buf_sz: buffer length 2N/A * tkey: pointer to DNS TKEY RDATA structure 2N/A * -1 on error, or length of data written (or that would be written) to buf 2N/A "tk_key_size > 0 && tk_key_data == NULL");
2N/A "tk_other_size > 0 && tk_other_data == NULL");
2N/A * Build a complete TSIG RR section according to RFC 2845 section 2.3, 2N/A * including either all fields, or only those fields used in computation 2N/A * of the message signature data. 2N/A * Because the TSIG RR is added to an existing DNS message for message 2N/A * digest computation, this function takes as parameters a buffer 2N/A * containing an existing message and its length. The TSIG RR is 2N/A * appended to the existing message in the same buffer. 2N/A * May be called with buf == NULL and buf_sz == 0, in which case the 2N/A * function does not actually build the TSIG RR, but only returns the 2N/A * space needed for a TSIG RR as specified by the other parameters. 2N/A * buf: buffer to store TSIG RR 2N/A * buf_sz: buffer length 2N/A * msg_len: length of existing message in buffer 2N/A * key_name: key name, in C string format 2N/A * tsig: pointer to DNS TSIG RDATA structure 2N/A * digest_data: one of DYNDNS_DIGEST_SIGNED or DYNDNS_DIGEST_UNSIGNED 2N/A * -1 on error, or length of data written (or that would be written) to buf 2N/A "ts_mac_size > 0 && ts_mac_data == NULL");
2N/A "ts_other_size > 0 && ts_other_data == NULL");
2N/A * name [type] class ttl [rdlen] 2N/A * TSIG RDATA fields: 2N/A * alg_name sign_time fudge_time [mac_size] [mac_data] [orig_id] error 2N/A * other_size other_data 2N/A * dyndns_build_tkey_msg 2N/A * This routine is used to build the TKEY message to transmit GSS tokens 2N/A * during GSS security context establishment for secure DNS update. The 2N/A * TKEY message format uses the DNS query message format. The TKEY section 2N/A * is the answer section of the query message format. 2N/A * statp: resolver state 2N/A * buf: buffer to store TKEY message 2N/A * buf_sz: size of buffer 2N/A * key_name: TKEY key name 2N/A * (this same key name must be also be used in the TSIG message) 2N/A * tkey: pointer to DNS TKEY RDATA structure 2N/A * -1 on error, or length of message written to buf 2N/A * Construct a service name for the target system (i.e. the DNS server) as 2N/A * DNS/<fqhostname>@<realm> 2N/A * and convert it to GSS-API internal format. 2N/A * Construct a service name for the GSS initiator (i.e. our dyndns client) 2N/A * <sam_account>@<realm> 2N/A * and convert it to GSS-API internal format. 2N/A * dyndns_establish_sec_ctx 2N/A * This routine is used to establish a security context with the DNS server 2N/A * by building TKEY messages and sending them to the DNS server. TKEY messages 2N/A * are also received from the DNS server for processing. The security context 2N/A * establishment is done with the GSS client on the system producing a token 2N/A * and sending the token within the TKEY message to the GSS server on the DNS 2N/A * server. The GSS server then processes the token and then send a TKEY reply 2N/A * message with a new token to be processed by the GSS client. The GSS client 2N/A * processes the new token and then generates a new token to be sent to the 2N/A * GSS server. This cycle is continued until the security establishment is 2N/A * See RFC 3645 section 3 for standards information. 2N/A * statp: : resolver state 2N/A * gss_context : handle to security context 2N/A * cred_handle : handle to credential 2N/A * target : server principal 2N/A * key_name : TKEY key name 2N/A * (this same key name must be also be used in the TSIG message) 2N/A * gss_context : handle to security context 2N/A * -1 on failure, 0 on success 2N/A "no replay attack detection available");
2N/A "remote peer did not authenticate itself");
2N/A "could not build key exchange message");
2N/A "could not send key exchange message");
2N/A "could not parse key exchange message");
2N/A "secure update error: key exchange error");
2N/A "could not parse peer key data");
2N/A /* Extract token length and value from TKEY RDATA */ 2N/A * dyndns_get_sec_context 2N/A * Get security context for secure dynamic DNS update. This routine opens 2N/A * a socket to the DNS server and establishes a security context with 2N/A * the DNS server using host principal to perform secure dynamic DNS update. 2N/A * statp: resolver state 2N/A * hostname: fully qualified hostname 2N/A * dns_srv_ip: ip address of hostname in network byte order 2N/A * 0 on failure, or gss credential context 2N/A * dyndns_build_update_msg 2N/A * This routine builds the update request message for adding and removing DNS 2N/A * entries which is used for non-secure and secure DNS update. 2N/A * statp: resolver state 2N/A * buf: buffer to build message 2N/A * buf_sz: buffer size 2N/A * zone: zone owning name 2N/A * name: name to update 2N/A * type: type of data to update for name 2N/A * data: value of data to update for name 2N/A * ttl: time to live of new DNS RR 2N/A * (if update_op == DYNDNS_UPDATE_ADD) 2N/A * update_op: one of: 2N/A * DYNDNS_UPDATE_ADD adds entries 2N/A * DYNDNS_UPDATE_DEL_ALL deletes entries of one name & type. 2N/A * DYNDNS_UPDATE_DEL_CLEAR deletes entries of one name. 2N/A * DYNDNS_UPDATE_DEL_ONE deletes one entry. 2N/A * -1 on error, or length of message written to buf 2N/A /* Add to an RRset */ 2N/A /* Delete an RRset */ 2N/A /* Delete all RRsets from a name */ 2N/A /* Delete an RR from an RRset */ 2N/A * dyndns_search_entry 2N/A * Query DNS server for entry. This routine can indicate if an entry exist 2N/A * or not during forward or reverse lookup. Also can indicate if the data 2N/A * of the entry matched. For example, for forward lookup, the entry is 2N/A * searched using the hostname and the data is the IP address. For reverse 2N/A * lookup, the entry is searched using the IP address and the data is the 2N/A * update_zone: one of DYNDNS_ZONE_FWD or DYNDNS_ZONE_REV 2N/A * hostname : fully qualified hostname 2N/A * family : address family of *addr, AF_INET or AF_INET6 2N/A * addr : address of hostname in network format 2N/A * is_match: is 1 for found matching entry, otherwise 0 2N/A * 1 : an entry exist but not necessarily match 2N/A * 0 : an entry does not exist 2N/A * -1 : an error occurred 2N/A * if both ips aren't the same family skip to 2N/A /* need compare macro here */ 2N/A /* entry does not exist */ 2N/A * dyndns_update_nameaddr 2N/A * Perform non-secure dynamic DNS update. On error, perform secure update 2N/A * on behalf of the localhost's domain machine account if the localhost is a 2N/A * Secure dynamic DNS update using host credentials requires the system to 2N/A * be configured as a Kerberos client. That configuration is done as part of the 2N/A * This routine creates a new resolver context, builds the update request 2N/A * message, and sends the message to the DNS server. The response is received 2N/A * and check for error. If there is no error then the local NSS cached is 2N/A * purged. DNS may be used to check to see if an entry already exist before 2N/A * adding or to see if an entry does exist before removing it. Adding 2N/A * duplicate entries or removing non-existing entries does not cause any 2N/A * problems. DNS is not check when doing a delete all. 2N/A * update_op: one of: 2N/A * DYNDNS_UPDATE_ADD adds entries 2N/A * DYNDNS_UPDATE_DEL_ALL deletes entries of one name & type. 2N/A * DYNDNS_UPDATE_DEL_CLEAR deletes entries of one name. 2N/A * DYNDNS_UPDATE_DEL_ONE deletes one entry. 2N/A * update_zone: one of DYNDNS_ZONE_FWD or DYNDNS_ZONE_REV 2N/A * hostname : fully qualified hostname 2N/A * af : address family of *addr, AF_INET or AF_INET6 2N/A * addr : address of hostname in network format 2N/A * ttl : cached time of this entry by others and not within DNS 2N/A * do_check : one of: 2N/A * DYNDNS_CHECK_NONE for no DNS checking before update 2N/A * DYNDNS_CHECK_EXIST to check first in DNS 2N/A * fully qualified host name; required for secure update 2N/A * may be NULL if secure update not required 2N/A "requested forward update but no hostname provided");
2N/A "requested reverse update but no address provided");
2N/A "requested update requires hostname and address");
2N/A /* don't check af if it is not used by the update */ 2N/A "address family %d not supported",
af);
2N/A "dyndns: error while checking current DNS entry");
2N/A "nothing to delete");
2N/A * TBD: read a property to set which update mode(s) to attempt 2N/A "cannot find host principal \"%s\" " 2N/A "for realm \"%s\" in local keytab file.",
2N/A "could not initialize resolver");
2N/A * 7013458 libresolv2 res_nsend is sometimes inconsistent 2N/A * for UDP vs. TCP queries 2N/A * Remove the next statement when 7013458 is fixed. 2N/A "could not setup update information");
2N/A "could not build update message");
2N/A * TBD: revise this algorithm to use the primary master nameserver 2N/A * (returned by dyndns_get_update_info above) and the authoritative 2N/A * nameservers found by searching the zone's NS RRset. 2N/A "dyndns: trying update on server at %s",
ns_addr);
2N/A /* attempt non-secure update on this server */ 2N/A /* set new message ID if needed */ 2N/A "dyndns: non-secure update completed");
2N/A * DNS servers typically return REFUSED error code when 2N/A * they allow secure updates only. If secure update 2N/A * will be attempted next, suppress the expected 2N/A * REFUSED error messages when performing 2N/A * non-secure updates. Otherwise, "REFUSED" error 2N/A * messages should be logged. 2N/A "non-secure update response code");
2N/A /* attempt secure update on this server */ 2N/A * TBD: per RFC 3645 section 3.1.2, 2N/A * the key name SHOULD be made globally unique 2N/A /* set new message ID if needed */ 2N/A /* sign update message */ 2N/A /* check here for update request is successful */ 2N/A "dyndns: secure update completed");
2N/A "secure update response code");
2N/A "both non-secure and secure updates" :
2N/A "non-secure update");
2N/A * dyndns_zone_update 2N/A * Perform dynamic update on both forward and reverse lookup zone using 2N/A * the specified hostname and IP addresses. Before updating DNS, existing 2N/A * host entries with the same hostname in the forward lookup zone are removed 2N/A * and existing pointer entries with the same IP addresses in the reverse 2N/A * lookup zone are removed. After DNS update, host entries for current 2N/A * hostname will show current IP addresses and pointer entries for current 2N/A * IP addresses will show current hostname. 2N/A * fqdn - fully-qualified domain name (in lower case) 2N/A * -1: some dynamic DNS updates errors 2N/A * 0: successful or DDNS disabled. 2N/A * To comply with RFC 4120 section 6.2.1, the fully-qualified hostname 2N/A * must be set to lower case. 2N/A * NULL IP is okay since we are removing all using the hostname. 2N/A * NULL hostname is okay since we are removing all using the IP. 2N/A * Clear the rev zone records. Must be called to clear the OLD if list 2N/A * of down records prior to updating the list with new information. 2N/A * fqdn - fully-qualified domain name (in lower case) 2N/A * -1: some dynamic DNS updates errors 2N/A * 0: successful or DDNS disabled. 2N/A * To comply with RFC 4120 section 6.2.1, the fully-qualified hostname 2N/A * must be set to lower case. 2N/A * NULL hostname is okay since we are removing all using the IP.