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 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 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 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 * 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; 1447c478bd9Sstevel@tonic-gate } 145*9525b14bSRao Shoaib } 1467c478bd9Sstevel@tonic-gate return (list); 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate int 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 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 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 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 * 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 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