17c478bd9Sstevel@tonic-gate /*
2*9525b14bSRao Shoaib  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3*9525b14bSRao Shoaib  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate  * As of BIND 8.2.2, ISC (a) removed res_mkupdate(), res_update(), and
87c478bd9Sstevel@tonic-gate  * res_mkupdrec() from what they consider the supported interface. The
97c478bd9Sstevel@tonic-gate  * functions still exist, but their calling interface has changed, since
107c478bd9Sstevel@tonic-gate  * the ns_updrec structure has changed.
117c478bd9Sstevel@tonic-gate  *
127c478bd9Sstevel@tonic-gate  * It seems probable that res_mkupdate()  etc. will return, though possibly
137c478bd9Sstevel@tonic-gate  * with other changes, in some future BIND release. In order to avoid
147c478bd9Sstevel@tonic-gate  * going to PSARC twice (once to remove the functions, and then again to
157c478bd9Sstevel@tonic-gate  * add them back), we retain the old interface as a wrapper around the
167c478bd9Sstevel@tonic-gate  * new one.
177c478bd9Sstevel@tonic-gate  */
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate #include <port_before.h>
207c478bd9Sstevel@tonic-gate 
217c478bd9Sstevel@tonic-gate #include <malloc.h>
227c478bd9Sstevel@tonic-gate #include <strings.h>
237c478bd9Sstevel@tonic-gate #include <sys/types.h>
247c478bd9Sstevel@tonic-gate #include <netinet/in.h>
257c478bd9Sstevel@tonic-gate 
26*9525b14bSRao Shoaib /* get the Solaris ns_updrec before any renaming happens */
27*9525b14bSRao Shoaib #include <arpa/nameser.h>
28*9525b14bSRao Shoaib 
29*9525b14bSRao Shoaib /* get the __ISC_ns_updrec */
307c478bd9Sstevel@tonic-gate #include <res_update.h>
31*9525b14bSRao Shoaib 
32*9525b14bSRao Shoaib #include <port_after.h>
33*9525b14bSRao Shoaib 
34*9525b14bSRao Shoaib /* un-rename ns_updrec and res_* functions so we can wrap them */
357c478bd9Sstevel@tonic-gate #undef	ns_updrec
367c478bd9Sstevel@tonic-gate #undef	res_mkupdate
377c478bd9Sstevel@tonic-gate #undef	res_update
387c478bd9Sstevel@tonic-gate #undef	res_mkupdrec
397c478bd9Sstevel@tonic-gate #undef	res_freeupdrec
40*9525b14bSRao Shoaib #undef	res_nmkupdate
41*9525b14bSRao Shoaib #undef	res_nupdate
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate void	res_freeupdrec(ns_updrec *);
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate static int
old2new(ns_updrec * old,__ISC_ns_updrec * new)467c478bd9Sstevel@tonic-gate old2new(ns_updrec *old, __ISC_ns_updrec *new) {
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate 	if (old->r_dname != 0) {
497c478bd9Sstevel@tonic-gate 		if ((new->r_dname = strdup(old->r_dname)) == 0)
507c478bd9Sstevel@tonic-gate 			return (-1);
517c478bd9Sstevel@tonic-gate 	} else {
527c478bd9Sstevel@tonic-gate 		new->r_dname = 0;
537c478bd9Sstevel@tonic-gate 	}
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate 	new->r_glink.prev =
567c478bd9Sstevel@tonic-gate 	new->r_glink.next =
577c478bd9Sstevel@tonic-gate 	new->r_link.prev  =
587c478bd9Sstevel@tonic-gate 	new->r_link.next  = 0;
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate 	new->r_section	= old->r_section;
617c478bd9Sstevel@tonic-gate 	new->r_class	= old->r_class;
627c478bd9Sstevel@tonic-gate 	new->r_type	= old->r_type;
637c478bd9Sstevel@tonic-gate 	new->r_ttl	= old->r_ttl;
647c478bd9Sstevel@tonic-gate 	new->r_data	= old->r_data;
657c478bd9Sstevel@tonic-gate 	new->r_size	= old->r_size;
667c478bd9Sstevel@tonic-gate 	new->r_opcode	= old->r_opcode;
677c478bd9Sstevel@tonic-gate 	new->r_dp	= old->r_dp;
687c478bd9Sstevel@tonic-gate 	new->r_deldp	= old->r_deldp;
697c478bd9Sstevel@tonic-gate 	new->r_zone	= old->r_zone;
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate 	return (0);
727c478bd9Sstevel@tonic-gate }
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate static int
new2old(__ISC_ns_updrec * new,ns_updrec * old)767c478bd9Sstevel@tonic-gate new2old(__ISC_ns_updrec *new, ns_updrec *old) {
777c478bd9Sstevel@tonic-gate 	/* XXX r_prev and r_next unchanged */
787c478bd9Sstevel@tonic-gate 	if (new->r_dname != 0) {
797c478bd9Sstevel@tonic-gate 		if ((old->r_dname = strdup(new->r_dname)) == 0)
807c478bd9Sstevel@tonic-gate 			return (-1);
817c478bd9Sstevel@tonic-gate 	} else {
827c478bd9Sstevel@tonic-gate 		old->r_dname = 0;
837c478bd9Sstevel@tonic-gate 	}
847c478bd9Sstevel@tonic-gate 	old->r_section	= new->r_section;
857c478bd9Sstevel@tonic-gate 	old->r_class	= new->r_class;
867c478bd9Sstevel@tonic-gate 	old->r_type	= new->r_type;
877c478bd9Sstevel@tonic-gate 	old->r_ttl	= new->r_ttl;
887c478bd9Sstevel@tonic-gate 	old->r_data	= new->r_data;
897c478bd9Sstevel@tonic-gate 	old->r_size	= new->r_size;
907c478bd9Sstevel@tonic-gate 	old->r_opcode	= new->r_opcode;
917c478bd9Sstevel@tonic-gate 	old->r_grpnext	= 0;			/* XXX */
927c478bd9Sstevel@tonic-gate 	old->r_dp	= new->r_dp;
937c478bd9Sstevel@tonic-gate 	old->r_deldp	= new->r_deldp;
947c478bd9Sstevel@tonic-gate 	old->r_zone	= new->r_zone;
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	return (0);
977c478bd9Sstevel@tonic-gate }
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate static void
delete_list(__ISC_ns_updrec * list)1017c478bd9Sstevel@tonic-gate delete_list(__ISC_ns_updrec *list) {
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate 	__ISC_ns_updrec	*next;
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 	for (; list != 0; list = next) {
1067c478bd9Sstevel@tonic-gate 		next = list->r_link.next;
1077c478bd9Sstevel@tonic-gate 		__ISC_res_freeupdrec(list);
1087c478bd9Sstevel@tonic-gate 	}
1097c478bd9Sstevel@tonic-gate }
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate static __ISC_ns_updrec *
copy_list(ns_updrec * old,int do_glink)113*9525b14bSRao Shoaib copy_list(ns_updrec *old, int do_glink) {
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 	__ISC_ns_updrec *list = 0, *r, *p;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	if (old == 0)
1187c478bd9Sstevel@tonic-gate 		return (0);
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	for (p = 0; old != 0; old = old->r_next, p = r) {
1217c478bd9Sstevel@tonic-gate 		if ((r = calloc(1, sizeof (*r))) == 0 ||
1227c478bd9Sstevel@tonic-gate 			old2new(old, r) != 0) {
1237c478bd9Sstevel@tonic-gate 			free(r);
1247c478bd9Sstevel@tonic-gate 			delete_list(list);
1257c478bd9Sstevel@tonic-gate 			return (0);
1267c478bd9Sstevel@tonic-gate 		}
1277c478bd9Sstevel@tonic-gate 		r->r_link.prev = p;
1287c478bd9Sstevel@tonic-gate 		r->r_link.next = 0;
129*9525b14bSRao Shoaib 		/* res_update and res_nupdate want r_glink set up like this */
130*9525b14bSRao Shoaib 		if (do_glink) {
131*9525b14bSRao Shoaib 			r->r_glink.prev = p;
132*9525b14bSRao Shoaib 			r->r_glink.next = 0;
133*9525b14bSRao Shoaib 		} else {
134*9525b14bSRao Shoaib 			r->r_glink.prev = (void *)-1;
135*9525b14bSRao Shoaib 			r->r_glink.next = (void *)-1;
136*9525b14bSRao Shoaib 		}
137*9525b14bSRao Shoaib 		if (p != 0) {
1387c478bd9Sstevel@tonic-gate 			p->r_link.next = r;
139*9525b14bSRao Shoaib 			if (do_glink) {
140*9525b14bSRao Shoaib 				p->r_glink.next = r;
141*9525b14bSRao Shoaib 			}
142*9525b14bSRao Shoaib 		} else {
1437c478bd9Sstevel@tonic-gate 			list = r;
144*9525b14bSRao Shoaib 		}
1457c478bd9Sstevel@tonic-gate 	}
1467c478bd9Sstevel@tonic-gate 	return (list);
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate int
res_mkupdate(ns_updrec * rrecp_in,uchar_t * buf,int length)151*9525b14bSRao Shoaib res_mkupdate(ns_updrec  *rrecp_in, uchar_t *buf, int length) {
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	__ISC_ns_updrec	*r;
1547c478bd9Sstevel@tonic-gate 	int		ret;
1557c478bd9Sstevel@tonic-gate 
156*9525b14bSRao Shoaib 	if ((r = copy_list(rrecp_in, 1)) == 0)
1577c478bd9Sstevel@tonic-gate 		return (-1);
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	ret = __ISC_res_mkupdate(r, buf, length);
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate 	delete_list(r);
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 	return (ret);
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate 
166*9525b14bSRao Shoaib int
res_nmkupdate(res_state statp,ns_updrec * rrecp_in,uchar_t * buf,int length)167*9525b14bSRao Shoaib res_nmkupdate(res_state statp, ns_updrec  *rrecp_in, uchar_t *buf, int length) {
168*9525b14bSRao Shoaib 
169*9525b14bSRao Shoaib 	__ISC_ns_updrec	*r;
170*9525b14bSRao Shoaib 	int		ret;
171*9525b14bSRao Shoaib 
172*9525b14bSRao Shoaib 	if ((r = copy_list(rrecp_in, 1)) == 0)
173*9525b14bSRao Shoaib 		return (-1);
174*9525b14bSRao Shoaib 
175*9525b14bSRao Shoaib 	ret = __ISC_res_nmkupdate(statp, r, buf, length);
176*9525b14bSRao Shoaib 
177*9525b14bSRao Shoaib 	delete_list(r);
178*9525b14bSRao Shoaib 
179*9525b14bSRao Shoaib 	return (ret);
180*9525b14bSRao Shoaib }
181*9525b14bSRao Shoaib 
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate int
res_update(ns_updrec * rrecp_in)1847c478bd9Sstevel@tonic-gate res_update(ns_updrec *rrecp_in) {
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 	__ISC_ns_updrec	*r;
1877c478bd9Sstevel@tonic-gate 	int		ret;
1887c478bd9Sstevel@tonic-gate 
189*9525b14bSRao Shoaib 	if ((r = copy_list(rrecp_in, 0)) == 0)
1907c478bd9Sstevel@tonic-gate 		return (-1);
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	ret = __ISC_res_update(r);
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	delete_list(r);
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 	return (ret);
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate 
199*9525b14bSRao Shoaib int
res_nupdate(res_state statp,ns_updrec * rrecp_in,ns_tsig_key * key)200*9525b14bSRao Shoaib res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) {
201*9525b14bSRao Shoaib 
202*9525b14bSRao Shoaib 	__ISC_ns_updrec	*r;
203*9525b14bSRao Shoaib 	int		ret;
204*9525b14bSRao Shoaib 
205*9525b14bSRao Shoaib 	if ((r = copy_list(rrecp_in, 0)) == 0)
206*9525b14bSRao Shoaib 		return (-1);
207*9525b14bSRao Shoaib 
208*9525b14bSRao Shoaib 	ret = __ISC_res_nupdate(statp, r, key);
209*9525b14bSRao Shoaib 
210*9525b14bSRao Shoaib 	delete_list(r);
211*9525b14bSRao Shoaib 
212*9525b14bSRao Shoaib 	return (ret);
213*9525b14bSRao Shoaib }
214*9525b14bSRao Shoaib 
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate ns_updrec *
res_mkupdrec(int section,const char * dname,uint_t class,uint_t type,uint_t ttl)2187c478bd9Sstevel@tonic-gate res_mkupdrec(int section, const char *dname, uint_t class, uint_t type,
2197c478bd9Sstevel@tonic-gate 		uint_t ttl) {
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 	__ISC_ns_updrec	*n;
2227c478bd9Sstevel@tonic-gate 	ns_updrec	*o;
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	n = __ISC_res_mkupdrec(section, dname, class, type, ttl);
2257c478bd9Sstevel@tonic-gate 	if (n == 0)
2267c478bd9Sstevel@tonic-gate 		return (0);
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 	if ((o = calloc(1, sizeof (*o))) != 0) {
2297c478bd9Sstevel@tonic-gate 		if (new2old(n, o) != 0) {
2307c478bd9Sstevel@tonic-gate 			res_freeupdrec(o);
2317c478bd9Sstevel@tonic-gate 			o = 0;
2327c478bd9Sstevel@tonic-gate 		}
2337c478bd9Sstevel@tonic-gate 	}
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	__ISC_res_freeupdrec(n);
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 	return (o);
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate void
res_freeupdrec(ns_updrec * rrecp)2427c478bd9Sstevel@tonic-gate res_freeupdrec(ns_updrec *rrecp) {
2437c478bd9Sstevel@tonic-gate 	if (rrecp == 0)
2447c478bd9Sstevel@tonic-gate 		return;
2457c478bd9Sstevel@tonic-gate 	/* Note: freeing r_dp is the caller's responsibility. */
2467c478bd9Sstevel@tonic-gate 	if (rrecp->r_dname != NULL)
2477c478bd9Sstevel@tonic-gate 		free(rrecp->r_dname);
2487c478bd9Sstevel@tonic-gate 	free(rrecp);
2497c478bd9Sstevel@tonic-gate }
250