smbns_dyndns.c revision da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0
"within specified zone\n");
* Display GSS error message from error code. This routine is used to display * the mechanism independent and mechanism specific error messages for GSS * routines. The major status error code is the mechanism independent error * code and the minor status error code is the mechanism specific error code. * Converts a domain string by removing periods and replacing with a byte value * of how many characters following period. A byte value is placed in front * to indicate how many characters before first period. A NULL character is * Buffer space checking is done by caller. * ptr : address of pointer to buffer to store converted string * zone: domain name string * ptr: address of pointer to next available buffer space * Build the header for DNS query and DNS update request message. * ptr : address of pointer to buffer to store header * buf_len : buffer length * query_req : use REQ_QUERY for query message or REQ_UPDATE for * quest_zone_cnt : number of question record for query message or * number of zone record for update message * ans_prereq_cnt : number of answer record for query message or * number of prerequisite record for update message * nameser_update_cnt: number of name server for query message or * number of update record for update message * addit_cnt : number of additional record * flags : query flags word * ptr: address of pointer to next available buffer space /* prerequiste record count */ /* update record count */ /* additional record count */ * dyndns_build_quest_zone * Build the question section for query message or zone section for * ptr : address of pointer to buffer to store question or zone section * name : question or zone name * type : type of question or zone * class : class of question or zone * ptr: address of pointer to next available buffer space * Build update section of update message for adding and removing a record. * If the ttl value is 0 then this message is for record deletion. * ptr : address of pointer to buffer to store update section * buf_len : buffer length * name : resource name of this record * type : type of this record * class : class of this record * ttl : time-to-live, cached time of this entry by others and not * within DNS database, a zero value for record(s) deletion * data : data of this resource record * forw_rev: UPDATE_FORW for forward zone, UPDATE_REV for reverse zone * add_del : UPDATE_ADD for adding entry, UPDATE_DEL for removing zone * del_type: DEL_ONE for deleting one entry, DEL_ALL for deleting all * entries of the same resource name. Only valid for UPDATE_DEL. * ptr: address of pointer to next available buffer space * Build TKEY section to establish security context for secure dynamic DNS * update. DNS header and question sections need to be build before this * section. The TKEY data are the tokens generated during security context * establishment and the TKEY message is used to transmit those tokens, one * at a time, to the DNS server. * ptr : address of pointer to buffer to store TKEY * buf_len : buffer length * name : key name, must be unique and same as for TSIG record * key_expire: expiration time of this key in second * ptr: address of the pointer to the next available buffer space /* 19 + 14 + data_size + 2 */ * Build TSIG section for secure dynamic DNS update. This routine will be * called twice. First called with TSIG_UNSIGNED, and second with TSIG_SIGNED. * The TSIG data is NULL and ignored for TSIG_UNSIGNED and is the update request * message encrypted for TSIG_SIGNED. The message id must be the same id as the * one in the update request before it is encrypted. * ptr : address of pointer to buffer to store TSIG * buf_len : buffer length * name : key name, must be the same as in TKEY record * fudge_time : amount of error time allow in seconds * data : TSIG data if TSIG_SIGNED, otherwise NULL * data_size : size of data, otherwise 0 if data is NULL * data_signed: TSIG_SIGNED to indicate data is signed and encrypted, * otherwise TSIG_UNSIGNED * ptr: address of pointer to next available buffer space /* 19 + 10 + data_size + 6 */ * dyndns_open_init_socket * This routine creates a SOCK_STREAM or SOCK_DGRAM socket and initializes it * by doing bind() and setting linger option to off. * sock_type: SOCK_STREAM for TCP or SOCK_DGRAM for UDP * dest_addr: destination address in network byte order * port : destination port number * descriptor: descriptor referencing the created socket (
char *)&l,
sizeof (l)) == -
1) {
* This routine is used to acquire a GSS credential handle to a user's Kerberos * ticket-granting ticket (TGT) stored locally on the system. If getting a * handle fails, then a new TGT will be obtained again before trying to get a * The user's password is taken from the environment variable * lookup.dns.dynamic.passwd and is encrypted. * kinit_retry: if 0 then a new TGT can be obtained before second attempt to * get a handle to TGT if first attempt fails * user_name : name of user to get credential handle from * credHandle : handle to user's credential (TGT) * oid : contains Kerberos 5 object identifier * kinit_retry: 1 if a new TGT has been acquired in this routine, otherwise 0 if (p ==
NULL || *p == 0) {
"secure dynamic DNS update.\n");
if (p ==
NULL || *p == 0) {
"secure dynamic DNS update.\n");
* This routine is used to build the TKEY message to transmit GSS tokens * during GSS security context establishment for secure DNS update. The * TKEY message format uses the DNS query message format. The TKEY section * is the answer section of the query message format. * Microsoft uses a value of 86400 seconds (24 hours) for key expiration time. * buf : buffer to build and store TKEY message * key_name: a unique key name, this same key name must be also be used in * out_tok : TKEY message data (GSS tokens) * id : message id of this TKEY message * message size: the size of the TKEY message /* query section of query request */ /* answer section of query request */ /* add TCP length info that follows this field */ * dyndns_establish_sec_ctx * This routine is used to establish a security context with the DNS server * by building TKEY messages and sending them to the DNS server. TKEY messages * are also received from the DNS server for processing. The security context * establishment is done with the GSS client on the system producing a token * and sending the token within the TKEY message to the GSS server on the DNS * server. The GSS server then processes the token and then send a TKEY reply * message with a new token to be processed by the GSS client. The GSS client * processes the new token and then generates a new token to be sent to the * GSS server. This cycle is continued until the security establishment is * done. TCP is used to send and receive TKEY messages. * If gss_init_sec_context fails then a new TGT will be acquired so that * security establishment can be retry once more by the caller after getting * a handle to the new TGT (credential). * credHandle : handle to credential * s : socket descriptor to DNS server * key_name : TKEY key name * dns_hostname: fully qualified DNS hostname * oid : contains Kerberos 5 object identifier * user_name : name of user to perform DNS update * kinit_retry : if 0 and gss_init_sec_context fails then get new TGT so * the caller can restart doing security context establishment * gss_context : handle to security context * kinit_retry : 1 if a new TGT has been acquired in this routine, * do_acquire_cred: if 1 then caller will restart security context if (p ==
NULL || *p == 0) {
"secure dynamic DNS update.\n");
ret =
buf2[
5] &
0xf;
/* error field in TCP */ "TKEY reply: %d: ",
ret);
* Get security context for secure dynamic DNS update. This routine opens * a TCP socket to the DNS server and calls routines to get a handle to a * locally cached user's credential and establish a security context with * the DNS server to perform secure dynamic DNS update. If getting security * context fails then a retry may be done after reobtaining new credential and * getting a new credential handle. If obtaining new credential has been * done earlier during getting a handle to credential then there is no need to * do a retry for security context. * hostname: fully qualified hostname * dns_ip : ip address of hostname in network byte order * gss_handle: gss credential handle * gss_context: gss security context "hostname from DNS ip.\n");
* dyndns_build_add_remove_msg * This routine builds the update request message for adding and removing DNS * entries which is used for non-secure and secure DNS update. * This routine builds an UDP message. * buf : buffer to build message * update_zone: the type of zone to update, use UPDATE_FORW for forward * lookup zone, use UPDATE_REV for reverse lookup zone * hostname : fully qualified hostname to update DNS with * ip_addr : IP address of hostname * life_time : cached time of this entry by others and not within DNS * update_type: UPDATE_ADD to add entry, UPDATE_DEL to remove entry * del_type : DEL_ONE for deleting one entry, DEL_ALL for deleting all * entries of the same resource name. Only valid for UPDATE_DEL. * addit_cnt : Indicate how many record is in the additional section of * the DNS message. A value of zero is always used with * non-secure update message. For secure update message, * the value will be one because the signed TSIG message * is added as the additional record of the DNS update message. * id : DNS message ID. If a positive value then this ID value is * used, otherwise the next incremented value is used * level : This is the domain level which we send the request to, level * zero is the default level, it can go upto 2 in reverse zone * and virtually to any level in forward zone. * buf : buffer containing update message * int : size of update message * This function is changed to handle dynamic DNS update retires to higher /* Try higher domains according to the level requested */ /* Try higher domains according to the level requested */ * dyndns_build_unsigned_tsig_msg * This routine is used to build the unsigned TSIG message for signing. The * unsigned TSIG message contains the update request message with certain TSIG * fields included. An error time of 300 seconds is used for fudge time. This * is the number used by Microsoft clients. * This routine builds a UDP message. * buf : buffer to build message * update_zone: the type of zone to update, use UPDATE_FORW for forward * lookup zone, use UPDATE_REV for reverse lookup zone * hostname : fully qualified hostname to update DNS with * ip_addr : IP address of hostname * life_time : cached time of this entry by others and not within DNS * update_type: UPDATE_ADD to add entry, UPDATE_DEL to remove entry * del_type : DEL_ONE for deleting one entry, DEL_ALL for deleting all * entries of the same resource name. Only valid for UPDATE_DEL. * key_name : same key name used in TKEY message * id : DNS message ID. If a positive value then this ID value is * used, otherwise the next incremented value is used * level : This is the domain level which we send the request to, level * zero is the default level, it can go upto 2 in reverse zone * and virtually to any level in forward zone. * buf : buffer containing update message * int : size of update message * dyndns_build_signed_tsig_msg * This routine build the signed TSIG message which contains the update * request message encrypted. An error time of 300 seconds is used for fudge * time. This is the number used by Microsoft clients. * This routine builds a UDP message. * buf : buffer to build message * update_zone: the type of zone to update, use UPDATE_FORW for forward * lookup zone, use UPDATE_REV for reverse lookup zone * hostname : fully qualified hostname to update DNS with * ip_addr : IP address of hostname * life_time : cached time of this entry by others and not within DNS * update_type: UPDATE_ADD to add entry, UPDATE_DEL to remove entry * del_type : DEL_ONE for deleting one entry, DEL_ALL for deleting all * entries of the same resource name. Only valid for UPDATE_DEL. * key_name : same key name used in TKEY message * id : DNS message ID. If a positive value then this ID value is * used, otherwise the next incremented value is used * in_mic : the update request message encrypted * level : This is the domain level which we send the request to, level * zero is the default level, it can go upto 2 in reverse zone * and virtually to any level in forward zone. * buf : buffer containing update message * int : size of update message * This routine sends and receives UDP DNS request and reply messages. Time * out value and retry count is indicated by two environment variables: * If either of these two variables are undefined or their value exceed the * value of 10 then a default value of 3 retry and/or a default value of 3 * Pre-condition: Caller must call dyndns_open_init_socket() before calling * buf : buffer containing data to send * buf_sz : size of data to send if (p ==
NULL || *p == 0) {
if (p ==
NULL || *p == 0) {
/* required by recvfrom */ if (i == (
max_retries +
1)) {
/* did not receive anything */ * dyndns_sec_add_remove_entry * Perform secure dynamic DNS update after getting security context. * This routine opens a UDP socket to the DNS sever, gets the security context, * builds the unsigned TSIG message and signed TSIG message. The signed TSIG * message containing the encrypted update request message is sent to the DNS * server. The response is received and check for error. If there is no * error then credential handle and security context are released and the local * update_zone : UPDATE_FORW for forward zone, UPDATE_REV for reverse zone * hostname : fully qualified hostname * ip_addr : ip address of hostname in string format * life_time : cached time of this entry by others and not within DNS * max_retries : maximum retries for sending DNS update request * recv_timeout: receive timeout * update_type : UPDATE_ADD for adding entry, UPDATE_DEL for removing entry * del_type : DEL_ONE for deleting one entry, DEL_ALL for deleting all * entries of the same resource name. Only valid for UPDATE_DEL * dns_str : DNS IP address in string format * This function is enhanced to handle the case of NOTAUTH error when DNS server * is not authoritative for specified zone. In this case we need to resend the * same request to the higher authoritative domains. * This is true for both secure and unsecure dynamic DNS updates. /* sign update message */ ret =
buf2[
3] &
0xf;
/* error field in UDP */ * If it is a NOTAUTH error we should retry with higher domains * until we get a successful reply or the maximum retries is met. /* check here for update request is successful */ * Query DNS server for entry. This routine can indicate if an entry exist * or not during forward or reverse lookup. Also can indicate if the data * of the entry matched. For example, for forward lookup, the entry is * searched using the hostname and the data is the IP address. For reverse * lookup, the entry is searched using the IP address and the data is the * update_zone: UPDATE_FORW for forward zone, UPDATE_REV for reverse zone * hostname : fully qualified hostname * ip_addr : ip address of hostname in string format * update_type: UPDATE_ADD for adding entry, UPDATE_DEL for removing entry * is_match: is 1 for found matching entry, otherwise 0 * 1 : an entry exist but not necessarily match * 0 : an entry does not exist /* entry does not exist */ * dyndns_add_remove_entry * Perform non-secure dynamic DNS update. If fail then tries secure update. * This routine opens a UDP socket to the DNS sever, build the update request * message, and sends the message to the DNS server. The response is received * and check for error. If there is no error then the local NSS cached is * purged. DNS may be used to check to see if an entry already exist before * adding or to see if an entry does exist before removing it. Adding * duplicate entries or removing non-existing entries does not cause any * problems. DNS is not check when doing a delete all. * update_zone: UPDATE_FORW for forward zone, UPDATE_REV for reverse zone * hostname : fully qualified hostname * ip_addr : ip address of hostname in string format * life_time : cached time of this entry by others and not within DNS * update_type: UPDATE_ADD to add entry, UPDATE_DEL to remove entry * do_check : DNS_CHECK to check first in DNS, DNS_NOCHECK for no DNS * del_type : DEL_ONE for deleting one entry, DEL_ALL for deleting all * entries of the same resource name. Only valid for UPDATE_DEL. * dns_str : DNS IP address in string format * This function is enhanced to handle the case of NOTAUTH error when DNS server * is not authoritative for specified zone. In this case we need to resend the * same request to the higher authoritative domains. * This is true for both secure and unsecure dynamic DNS updates. ret =
buf2[
3] &
0xf;
/* error field in UDP */ * If it is a NOTAUTH error we should retry with higher domains * until we get a successful reply /* check here for update request is successful */ "support dynamic update\n");
"zone name in zone section\n");
* Main routine to add an entry into DNS. The attempt will be made on the * the servers returned by smb_get_nameserver(). Upon a successful * attempt on any one of the server, the function will exit with 0. * Otherwise, -1 is retuned to indicate the update attempt on all the * nameservers has failed. * update_zone: the type of zone to update, use UPDATE_FORW for forward * lookup zone, use UPDATE_REV for reverse lookup zone * hostname : fully qualified hostname * ip_addr : ip address of hostname in string format * life_time : cached time of this entry by others and not within DNS for (i = 0; i <
cnt; i++) {
* Main routine to remove an entry or all entries of the same resource name * from DNS. The update attempt will be made on the primary DNS server. If * there is a failure then another attempt will be made on the secondary DNS * update_zone: the type of zone to update, use UPDATE_FORW for forward * lookup zone, use UPDATE_REV for reverse lookup zone * hostname : fully qualified hostname * ip_addr : ip address of hostname in string format * del_type : DEL_ONE for deleting one entry, DEL_ALL for deleting all * entries of the same resource name. Only valid for UPDATE_DEL for (i = 0; i <
cnt; i++) {
"in forward lookup zone...\n",
hostname);
"in reverse lookup zone...\n",
ip_addr);
* Perform dynamic update on both forward and reverse lookup zone using * current hostname and IP addresses. Before updating DNS, existing host * entries with the same hostname in the forward lookup zone are removed * and existing pointer entries with the same IP addresses in the reverse * lookup zone are removed. After DNS update, host entries for current * hostname will show current IP addresses and pointer entries for current * IP addresses will show current hostname. * -1: some dynamic DNS updates errors * Dummy IP is okay since we are removing all using the hostname. for (i = 0; i <
nc_cnt; i++) {
return ((
error == 0) ? 0 : -
1);
* Clear the rev zone records. Must be called to clear the OLD if list * of down records prior to updating the list with new information. * -1: some dynamic DNS updates errors for (i = 0; i <
nc_cnt; i++) {
return ((
error == 0) ? 0 : -
1);