No empty .Rs/.Re
[netbsd-mini2440.git] / external / bsd / bind / dist / contrib / dbus / dbus_mgr.c
blob6a4b55b082768b04ec6732088adc28d264539f2c
1 /* $NetBSD$ */
3 /* dbus_mgr.c
5 * named module to provide dynamic forwarding zones in
6 * response to D-BUS dhcp events or commands.
8 * Copyright(C) Jason Vas Dias, Red Hat Inc., 2005
9 * Modified by Adam Tkac, Red Hat Inc., 2007
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation at
14 * http://www.fsf.org/licensing/licenses/gpl.txt
15 * and included in this software distribution as the "LICENSE" file.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 #include <config.h>
23 #include <isc/types.h>
24 #include <isc/net.h>
25 #include <isc/mem.h>
26 #include <isc/magic.h>
27 #include <isc/list.h>
28 #include <isc/task.h>
29 #include <isc/event.h>
30 #include <isc/socket.h>
31 #include <isc/timer.h>
32 #include <isc/netaddr.h>
33 #include <isc/sockaddr.h>
34 #include <isc/buffer.h>
35 #include <isc/log.h>
37 #include <dns/name.h>
38 #include <dns/acl.h>
39 #include <dns/fixedname.h>
40 #include <dns/view.h>
41 #include <dns/forward.h>
43 #include <named/types.h>
44 #include <named/config.h>
45 #include <named/server.h>
46 #include <named/globals.h>
47 #include <named/log.h>
49 #include <named/dbus_service.h>
50 #include <named/dbus_mgr.h>
52 #include <string.h>
53 #include <search.h>
55 typedef void (*__free_fn_t) (void *__nodep);
56 extern void tdestroy (void *__root, __free_fn_t __freefct);
57 extern void free(void*);
59 #ifdef ISC_USE_INTERNAL_MALLOC
60 # if ISC_USE_INTERNAL_MALLOC
61 # error dbus_mgr cannot be used if ISC_USE_INTERNAL_MALLOC==1
62 # endif
63 #endif
65 #define DBUSMGR_DESTINATION "com.redhat.named"
66 #define DBUSMGR_OBJECT_PATH "/com/redhat/named"
67 #define DBUSMGR_INTERFACE "com.redhat.named"
69 #define DBUSMGR_MAGIC ISC_MAGIC('D', 'B', 'U', 'S')
71 struct ns_dbus_mgr
73 unsigned int magic;
74 isc_mem_t * mctx; /* Memory context. */
75 isc_taskmgr_t * taskmgr; /* Task manager. */
76 isc_socketmgr_t * socketmgr; /* Socket manager. */
77 isc_timermgr_t * timermgr; /* Timer manager. */
78 isc_task_t * task; /* task */
79 isc_timer_t * timer; /* dbus_init retry */
80 void * sockets; /* dbus fd tree */
81 void * dhc_if; /* dhcp interface tree */
82 void * ifwdt; /* initial forwarder tree */
83 char * dhcdbd_name; /* dhcdbd destination */
84 DBUS_SVC dbus; /* dbus handle */
87 typedef
88 struct dbus_mgr_sock_s
90 int fd;
91 struct ns_dbus_mgr *mgr;
92 isc_socket_t *sock;
93 isc_socketevent_t *ser;
94 isc_socketevent_t *sew;
95 isc_socketevent_t *sel;
96 } DBusMgrSocket;
98 typedef
99 enum dhc_state_e
101 DHC_NBI, /* no broadcast interfaces found */
102 DHC_PREINIT, /* configuration started */
103 DHC_BOUND, /* lease obtained */
104 DHC_RENEW, /* lease renewed */
105 DHC_REBOOT, /* have valid lease, but now obtained a different one */
106 DHC_REBIND, /* new, different lease */
107 DHC_STOP, /* remove old lease */
108 DHC_MEDIUM, /* media selection begun */
109 DHC_TIMEOUT, /* timed out contacting DHCP server */
110 DHC_FAIL, /* all attempts to contact server timed out, sleeping */
111 DHC_EXPIRE, /* lease has expired, renewing */
112 DHC_RELEASE, /* releasing lease */
113 DHC_START, /* sent when dhclient started OK */
114 DHC_ABEND, /* dhclient exited abnormally */
115 DHC_END, /* dhclient exited normally */
116 DHC_END_OPTIONS, /* last option in subscription sent */
117 DHC_INVALID=255
118 } DHC_State;
120 typedef ISC_LIST(dns_name_t) DNSNameList;
122 typedef ISC_LIST(isc_sockaddr_t) SockAddrList;
124 typedef struct dbm_fwdr_s
126 dns_fwdpolicy_t fwdpolicy;
127 dns_name_t dn;
128 SockAddrList sa;
129 ISC_LINK( struct dbm_fwdr_s ) link;
130 } DBusMgrInitialFwdr;
132 typedef
133 struct dhc_if_s
135 char *if_name;
136 DHC_State dhc_state;
137 DHC_State previous_state;
138 struct in_addr ip;
139 struct in_addr subnet_mask;
140 DNSNameList dn;
141 SockAddrList dns;
142 } DHC_IF;
144 static void
145 dbus_mgr_watch_handler( int fd, dbus_svc_WatchFlags flags, void *mgrp );
147 static
148 dbus_svc_HandlerResult
149 dbus_mgr_message_handler
151 DBusMsgHandlerArgs
154 static
155 void dbus_mgr_close_socket( const void *p, const VISIT which, const int level);
157 static
158 void dbus_mgr_destroy_socket( void *p );
160 static
161 void dbus_mgr_free_dhc( void *p );
163 static void
164 dbus_mgr_watches_selected(isc_task_t *t, isc_event_t *ev);
166 static isc_result_t
167 dbus_mgr_init_dbus(ns_dbus_mgr_t *);
169 static isc_result_t
170 dbus_mgr_record_initial_fwdtable(ns_dbus_mgr_t *);
172 static
173 dns_fwdtable_t *dbus_mgr_get_fwdtable(void);
175 static void
176 dbus_mgr_free_initial_fwdtable(ns_dbus_mgr_t *);
178 static
179 uint8_t dbus_mgr_subscribe_to_dhcdbd( ns_dbus_mgr_t * );
181 static
182 void dbus_mgr_dbus_shutdown_handler ( ns_dbus_mgr_t * );
184 static
185 int dbus_mgr_log_err( const char *fmt, ...)
187 va_list va;
188 va_start(va, fmt);
189 isc_log_vwrite(ns_g_lctx,
190 NS_LOGCATEGORY_DBUS,
191 NS_LOGMODULE_DBUS,
192 ISC_LOG_NOTICE,
193 fmt, va
195 va_end(va);
196 return 0;
199 static
200 int dbus_mgr_log_dbg( const char *fmt, ...)
202 va_list va;
203 va_start(va, fmt);
204 isc_log_vwrite(ns_g_lctx,
205 NS_LOGCATEGORY_DBUS,
206 NS_LOGMODULE_DBUS,
207 ISC_LOG_DEBUG(80),
208 fmt, va
210 va_end(va);
211 return 0;
214 static
215 int dbus_mgr_log_info( const char *fmt, ...)
217 va_list va;
218 va_start(va, fmt);
219 isc_log_vwrite(ns_g_lctx,
220 NS_LOGCATEGORY_DBUS,
221 NS_LOGMODULE_DBUS,
222 ISC_LOG_DEBUG(1),
223 fmt, va
225 va_end(va);
226 return 0;
229 isc_result_t
230 dbus_mgr_create
231 ( isc_mem_t *mctx,
232 isc_taskmgr_t *taskmgr,
233 isc_socketmgr_t *socketmgr,
234 isc_timermgr_t *timermgr,
235 ns_dbus_mgr_t **dbus_mgr
238 isc_result_t result;
239 ns_dbus_mgr_t *mgr;
241 *dbus_mgr = 0L;
243 mgr = isc_mem_get(mctx, sizeof(*mgr));
244 if (mgr == NULL)
245 return (ISC_R_NOMEMORY);
247 mgr->magic = DBUSMGR_MAGIC;
248 mgr->mctx = mctx;
249 mgr->taskmgr = taskmgr;
250 mgr->socketmgr = socketmgr;
251 mgr->timermgr = timermgr;
252 mgr->task = 0L;
253 mgr->sockets = 0L;
254 mgr->timer = 0L;
255 mgr->dhc_if = 0L;
256 mgr->ifwdt = 0L;
257 mgr->dhcdbd_name = 0L;
259 if( (result = isc_task_create( taskmgr, 100, &(mgr->task)))
260 != ISC_R_SUCCESS
261 ) goto cleanup_mgr;
263 isc_task_setname( mgr->task, "dbusmgr", mgr );
265 mgr->dbus = 0L;
267 if( (result = dbus_mgr_record_initial_fwdtable( mgr ))
268 != ISC_R_SUCCESS
269 ) goto cleanup_mgr;
271 if( (result = dbus_mgr_init_dbus( mgr ))
272 != ISC_R_SUCCESS
273 ) goto cleanup_mgr;
275 *dbus_mgr = mgr;
277 return ISC_R_SUCCESS;
279 cleanup_mgr:
280 if ( dbus_mgr_get_fwdtable() != NULL)
281 dbus_mgr_free_initial_fwdtable (mgr);
282 if( mgr->task != 0L )
283 isc_task_detach(&(mgr->task));
284 isc_mem_put(mctx, mgr, sizeof(*mgr));
285 return (result);
288 static isc_result_t
289 dbus_mgr_init_dbus(ns_dbus_mgr_t * mgr)
291 char destination[]=DBUSMGR_DESTINATION;
292 isc_result_t result;
294 if( mgr->sockets != 0L )
296 isc_task_purgerange(mgr->task, 0L, ISC_SOCKEVENT_READ_READY, ISC_SOCKEVENT_SELECTED, 0L);
297 twalk(mgr->sockets, dbus_mgr_close_socket);
298 tdestroy(mgr->sockets, dbus_mgr_destroy_socket);
299 mgr->sockets = 0L;
302 if( mgr->dbus != 0L )
304 dbus_svc_shutdown(mgr->dbus);
305 mgr->dbus = 0L;
308 result = dbus_svc_init(DBUS_PRIVATE_SYSTEM, destination, &mgr->dbus,
309 dbus_mgr_watch_handler, 0L, 0L, mgr);
311 if(result != ISC_R_SUCCESS)
312 goto cleanup;
314 if( mgr->dbus == 0L )
316 if( mgr->timer == 0L)
318 isc_task_purgerange(mgr->task, 0L, ISC_SOCKEVENT_READ_READY, ISC_SOCKEVENT_SELECTED, 0L);
319 if( mgr->sockets != 0L )
321 twalk(mgr->sockets, dbus_mgr_close_socket);
322 tdestroy(mgr->sockets, dbus_mgr_destroy_socket);
323 mgr->sockets = 0L;
325 dbus_mgr_dbus_shutdown_handler ( mgr );
326 return ISC_R_SUCCESS;
328 goto cleanup;
331 if( !dbus_svc_add_filter
332 ( mgr->dbus, dbus_mgr_message_handler, mgr, 4,
333 "type=signal,path=/org/freedesktop/DBus,member=NameOwnerChanged",
334 "type=signal,path=/org/freedesktop/DBus/Local,member=Disconnected",
335 "type=signal,interface=com.redhat.dhcp.subscribe.binary",
336 "type=method_call,destination=com.redhat.named,path=/com/redhat/named"
340 dbus_mgr_log_err( "dbus_svc_add_filter failed" );
341 goto cleanup;
344 if( mgr->timer != 0L )
346 isc_timer_reset(mgr->timer,
347 isc_timertype_inactive,
348 NULL, NULL, ISC_TRUE
352 if( !dbus_mgr_subscribe_to_dhcdbd( mgr ) )
353 dbus_mgr_log_err("D-BUS dhcdbd subscription disabled.");
355 dbus_mgr_log_err("D-BUS service enabled.");
356 return ISC_R_SUCCESS;
358 cleanup:
359 isc_task_purgerange(mgr->task, 0L, ISC_SOCKEVENT_READ_READY, ISC_SOCKEVENT_SELECTED, 0L);
360 twalk(mgr->sockets, dbus_mgr_close_socket);
361 tdestroy(mgr->sockets, dbus_mgr_destroy_socket);
362 mgr->sockets = 0L;
363 if( mgr->dbus )
365 dbus_svc_shutdown(mgr->dbus);
366 mgr->dbus = 0L;
368 return ISC_R_FAILURE;
371 static
372 uint8_t dbus_mgr_subscribe_to_dhcdbd( ns_dbus_mgr_t *mgr )
374 DBUS_SVC dbus = mgr->dbus;
375 char subs[1024], path[1024],
376 dhcdbd_destination[]="com.redhat.dhcp", *ddp[1]={ &(dhcdbd_destination[0]) },
377 *dhcdbd_name=0L;
378 const char *options[] = { "reason", "ip-address", "subnet-mask",
379 "domain-name", "domain-name-servers"
381 dbus_svc_MessageHandle msg;
382 int i, n_opts = 5;
384 if( mgr->dhcdbd_name == 0L )
386 msg = dbus_svc_call
387 ( dbus,
388 "org.freedesktop.DBus",
389 "/org/freedesktop/DBus",
390 "GetNameOwner",
391 "org.freedesktop.DBus",
392 TYPE_STRING, &ddp,
393 TYPE_INVALID
395 if( msg == 0L )
396 return 0;
398 if( !dbus_svc_get_args(dbus, msg,
399 TYPE_STRING, &(dhcdbd_name),
400 TYPE_INVALID
402 ) return 0;
404 mgr->dhcdbd_name = isc_mem_get(mgr->mctx, strlen(dhcdbd_name) + 1);
405 if( mgr->dhcdbd_name == 0L )
406 return 0;
408 strcpy(mgr->dhcdbd_name, dhcdbd_name);
412 sprintf(path,"/com/redhat/dhcp/subscribe");
413 sprintf(subs,"com.redhat.dhcp.binary");
415 for(i = 0; i < n_opts; i++)
417 msg = dbus_svc_call
418 ( dbus,
419 "com.redhat.dhcp",
420 path,
421 "binary",
422 subs,
423 TYPE_STRING, &(options[i]),
424 TYPE_INVALID
426 if(msg == 0L)
427 return 0;
428 if ( dbus_svc_message_type( msg ) == ERROR )
429 return 0;
431 dbus_mgr_log_err("D-BUS dhcdbd subscription enabled.");
432 return 1;
435 void
436 dbus_mgr_shutdown
437 ( ns_dbus_mgr_t *mgr
440 if( mgr->timer != 0L )
441 isc_timer_detach(&(mgr->timer));
442 if( mgr->dbus != 0L )
444 isc_task_purgerange(mgr->task, 0L, ISC_SOCKEVENT_READ_READY, ISC_SOCKEVENT_SELECTED, 0L);
445 if( mgr->sockets != 0L )
447 twalk(mgr->sockets, dbus_mgr_close_socket);
448 tdestroy(mgr->sockets, dbus_mgr_destroy_socket);
449 mgr->sockets = 0L;
451 dbus_svc_shutdown(mgr->dbus);
453 if( mgr->dhc_if != 0L )
454 tdestroy(mgr->dhc_if, dbus_mgr_free_dhc);
455 if( mgr->dhcdbd_name != 0L )
456 isc_mem_put(mgr->mctx, mgr->dhcdbd_name, strlen(mgr->dhcdbd_name) + 1);
457 isc_task_detach(&(mgr->task));
458 dbus_mgr_free_initial_fwdtable(mgr);
459 isc_mem_put(mgr->mctx, mgr, sizeof(ns_dbus_mgr_t));
462 static
463 void dbus_mgr_restart_dbus(isc_task_t *t, isc_event_t *ev)
465 ns_dbus_mgr_t *mgr = (ns_dbus_mgr_t*)(ev->ev_arg) ;
466 t=t;
467 isc_event_free(&ev);
468 dbus_mgr_log_dbg("attempting to connect to D-BUS");
469 dbus_mgr_init_dbus( mgr );
472 static
473 void dbus_mgr_handle_dbus_shutdown_event(isc_task_t *t, isc_event_t *ev)
475 ns_dbus_mgr_t *mgr = ev->ev_arg;
476 isc_time_t tick={10,0};
477 isc_interval_t tock={10,0};
478 DBUS_SVC dbus = mgr->dbus;
479 t = t;
481 mgr->dbus = 0L;
483 isc_event_free(&ev);
485 if ( dbus != 0L )
487 isc_task_purgerange(mgr->task, 0L, ISC_SOCKEVENT_READ_READY, ISC_SOCKEVENT_SELECTED, 0L);
488 if( mgr->sockets != 0L )
490 twalk(mgr->sockets, dbus_mgr_close_socket);
491 tdestroy(mgr->sockets, dbus_mgr_destroy_socket);
492 mgr->sockets = 0L;
494 dbus_svc_shutdown(dbus);
497 dbus_mgr_log_err( "D-BUS service disabled." );
499 if( mgr->timer != 0L )
501 isc_timer_reset(mgr->timer,
502 isc_timertype_ticker,
503 &tick, &tock, ISC_TRUE
505 }else
506 if( isc_timer_create
507 ( mgr->timermgr,
508 isc_timertype_ticker,
509 &tick, &tock,
510 mgr->task,
511 dbus_mgr_restart_dbus,
512 mgr,
513 &(mgr->timer)
514 ) != ISC_R_SUCCESS
517 dbus_mgr_log_err( "D-BUS service cannot be restored." );
521 static
522 void dbus_mgr_dbus_shutdown_handler ( ns_dbus_mgr_t *mgr )
524 isc_event_t *dbus_shutdown_event =
525 isc_event_allocate
526 ( mgr->mctx,
527 mgr->task,
529 dbus_mgr_handle_dbus_shutdown_event,
530 mgr,
531 sizeof(isc_event_t)
533 if( dbus_shutdown_event != 0L )
535 isc_task_purgerange(mgr->task, 0L, ISC_SOCKEVENT_READ_READY, ISC_SOCKEVENT_SELECTED, 0L);
536 isc_task_send( mgr->task, &dbus_shutdown_event );
537 }else
538 dbus_mgr_log_err("unable to allocate dbus shutdown event");
541 static
542 dns_view_t *dbus_mgr_get_localhost_view(void)
544 dns_view_t *view;
545 isc_netaddr_t localhost = { AF_INET, { { htonl( ( 127 << 24 ) | 1 ) } }, 0 };
546 int match;
548 for (view = ISC_LIST_HEAD(ns_g_server->viewlist);
549 view != NULL;
550 view = ISC_LIST_NEXT(view, link)
553 /* return first view matching "localhost" source and dest */
555 if(( (view->matchclients != 0L ) /* 0L: accept "any" */
556 &&(( dns_acl_match( &localhost,
557 NULL, /* unsigned queries */
558 view->matchclients,
559 &(ns_g_server->aclenv),
560 &match,
561 NULL /* no match list */
562 ) != ISC_R_SUCCESS
563 ) || (match <= 0)
566 ||( (view->matchdestinations != 0L ) /* 0L: accept "any" */
567 &&(( dns_acl_match( &localhost,
568 NULL, /* unsigned queries */
569 view->matchdestinations,
570 &(ns_g_server->aclenv),
571 &match,
572 NULL /* no match list */
573 ) != ISC_R_SUCCESS
574 ) || (match <= 0)
577 ) continue;
579 break;
581 return view;
584 static
585 dns_fwdtable_t *dbus_mgr_get_fwdtable(void)
587 dns_view_t *view = dbus_mgr_get_localhost_view();
588 if( view != 0L )
589 return view->fwdtable;
590 return 0L;
593 static
594 dns_fwdtable_t *dbus_mgr_get_view_and_fwdtable( dns_view_t **viewp )
596 *viewp = dbus_mgr_get_localhost_view();
597 if( *viewp != 0L )
598 return (*viewp)->fwdtable;
599 return 0L;
602 static int dbus_mgr_ifwdr_comparator( const void *p1, const void *p2 )
604 char n1buf[ DNS_NAME_FORMATSIZE ]="", *n1p=&(n1buf[0]),
605 n2buf[ DNS_NAME_FORMATSIZE ]="", *n2p=&(n2buf[0]);
606 dns_name_t *dn1;
607 dns_name_t *dn2;
608 DE_CONST(&(((const DBusMgrInitialFwdr*)p1)->dn), dn1);
609 DE_CONST(&(((const DBusMgrInitialFwdr*)p2)->dn), dn2);
610 dns_name_format(dn1, n1p, DNS_NAME_FORMATSIZE );
611 dns_name_format(dn2, n2p, DNS_NAME_FORMATSIZE );
612 return strcmp(n1buf, n2buf);
615 static int dbus_mgr_dhc_if_comparator( const void *p1, const void *p2 );
617 static void dbus_mgr_record_initial_forwarder( dns_name_t *name, dns_forwarders_t *fwdr, void *mp )
619 ns_dbus_mgr_t *mgr = mp;
620 isc_sockaddr_t *sa, *nsa;
621 DBusMgrInitialFwdr *ifwdr;
623 if( ISC_LIST_HEAD(fwdr->addrs) == 0L)
624 return;
626 if( (ifwdr = isc_mem_get(mgr->mctx, sizeof(DBusMgrInitialFwdr))) == 0L)
627 return;
629 ifwdr->fwdpolicy = fwdr->fwdpolicy;
631 dns_name_init(&(ifwdr->dn), NULL);
632 if( dns_name_dupwithoffsets(name, mgr->mctx, &(ifwdr->dn)) != ISC_R_SUCCESS )
633 goto namedup_err;
635 ISC_LIST_INIT(ifwdr->sa);
637 for( sa = ISC_LIST_HEAD(fwdr->addrs);
638 sa != 0L;
639 sa = ISC_LIST_NEXT(sa,link)
642 nsa = isc_mem_get(mgr->mctx, sizeof(isc_sockaddr_t));
643 if( nsa == 0L )
644 goto nsa_err;
645 *nsa = *sa;
646 ISC_LINK_INIT(nsa, link);
647 ISC_LIST_APPEND(ifwdr->sa, nsa, link);
649 ISC_LINK_INIT(ifwdr, link);
650 tsearch( ifwdr, &(mgr->ifwdt), dbus_mgr_ifwdr_comparator);
652 return;
654 nsa_err:
655 while ( (sa = ISC_LIST_HEAD (ifwdr->sa)) != NULL) {
656 ISC_LIST_UNLINK (ifwdr->sa, sa, link);
657 isc_mem_put (mgr->mctx, sa, sizeof (*sa));
660 namedup_err:
661 isc_mem_put (mgr->mctx, ifwdr, sizeof (*ifwdr));
663 return;
666 static isc_result_t
667 dbus_mgr_record_initial_fwdtable( ns_dbus_mgr_t *mgr )
669 dns_fwdtable_t *fwdtable = dbus_mgr_get_fwdtable();
671 if( fwdtable == 0L )
672 return ISC_R_SUCCESS; /* no initial fwdtable */
673 dns_fwdtable_foreach( fwdtable, dbus_mgr_record_initial_forwarder, mgr);
674 return ISC_R_SUCCESS;
677 static void
678 dbus_mgr_free_initial_forwarder( void *p )
680 DBusMgrInitialFwdr *ifwdr = p;
681 isc_sockaddr_t *sa;
683 dns_name_free(&(ifwdr->dn), ns_g_mctx);
684 for( sa = ISC_LIST_HEAD( ifwdr->sa );
685 sa != 0L;
686 sa = ISC_LIST_HEAD( ifwdr->sa )
689 if( ISC_LINK_LINKED(sa, link) )
690 ISC_LIST_UNLINK(ifwdr->sa, sa, link);
691 isc_mem_put(ns_g_mctx, sa, sizeof(isc_sockaddr_t));
693 isc_mem_put(ns_g_mctx, ifwdr, sizeof(DBusMgrInitialFwdr));
696 static void
697 dbus_mgr_free_initial_fwdtable( ns_dbus_mgr_t *mgr )
699 tdestroy(mgr->ifwdt, dbus_mgr_free_initial_forwarder);
700 mgr->ifwdt = 0L;
703 static void
704 dbus_mgr_log_forwarders( const char *pfx, dns_name_t *name, SockAddrList *saList)
706 isc_sockaddr_t *sa;
707 char nameP[DNS_NAME_FORMATSIZE], addrP[128];
708 int s=0;
709 dns_name_format(name, nameP, DNS_NAME_FORMATSIZE );
710 for( sa = ISC_LIST_HEAD(*saList);
711 sa != 0L;
712 sa = ISC_LIST_NEXT(sa,link)
715 isc_sockaddr_format(sa, addrP, 128);
716 dbus_mgr_log_info("%s zone %s server %d: %s", pfx, nameP, s++, addrP);
720 static
721 isc_result_t dbus_mgr_set_forwarders
723 ns_dbus_mgr_t *mgr,
724 DNSNameList *nameList,
725 SockAddrList *saList,
726 dns_fwdpolicy_t fwdpolicy
729 isc_result_t result = ISC_R_SUCCESS;
730 dns_fwdtable_t *fwdtable;
731 dns_view_t *view=0L;
732 dns_name_t *dnsName;
733 isc_sockaddr_t *sa, *nsa;
734 dns_forwarders_t *fwdr=0L;
736 fwdtable = dbus_mgr_get_view_and_fwdtable(&view);
738 if( fwdtable == 0L )
740 if( ISC_LIST_HEAD(*saList) == 0L )
741 return ISC_R_SUCCESS;/* deletion not required */
743 view = dbus_mgr_get_localhost_view();
744 if( view == 0L )
745 return ISC_R_NOPERM; /* if configuration does not allow localhost clients,
746 * then we really shouldn't be creating a forwarding table.
748 result = isc_task_beginexclusive(mgr->task);
750 if( result == ISC_R_SUCCESS )
752 result = dns_fwdtable_create( mgr->mctx, &(view->fwdtable) );
754 isc_task_endexclusive(mgr->task);
756 if( result != ISC_R_SUCCESS )
757 return result;
759 if( view->fwdtable == 0L )
760 return ISC_R_NOMEMORY;
762 if( isc_log_getdebuglevel(ns_g_lctx) >= 1 )
763 dbus_mgr_log_info("Created forwarder table.");
767 for( dnsName = ISC_LIST_HEAD(*nameList);
768 dnsName != NULL;
769 dnsName = ISC_LIST_NEXT(dnsName,link)
772 fwdr = 0L;
773 if( ( dns_fwdtable_find_exact( fwdtable, dnsName, &fwdr ) != ISC_R_SUCCESS )
774 ||( fwdr == 0L )
777 if( ISC_LIST_HEAD( *saList ) == 0L )
778 continue;
779 /* no forwarders for name - add forwarders */
781 result = isc_task_beginexclusive(mgr->task);
783 if( result == ISC_R_SUCCESS )
785 result = dns_fwdtable_add( fwdtable, dnsName,
786 (isc_sockaddrlist_t*)saList,
787 fwdpolicy
790 if( view != 0L )
791 dns_view_flushcache( view );
793 isc_task_endexclusive(mgr->task);
795 if( result != ISC_R_SUCCESS )
796 return result;
798 if( isc_log_getdebuglevel(ns_g_lctx) >= 1 )
799 dbus_mgr_log_forwarders("Created forwarder",dnsName, saList);
801 continue;
804 if( ISC_LIST_HEAD( *saList ) == 0L )
805 { /* empty forwarders list - delete forwarder entry */
807 if( isc_log_getdebuglevel(ns_g_lctx) >= 1 )
808 dbus_mgr_log_forwarders("Deleting forwarder", dnsName, (SockAddrList*)&(fwdr->addrs));
810 result = isc_task_beginexclusive(mgr->task);
811 if( result == ISC_R_SUCCESS )
813 result = dns_fwdtable_delete( fwdtable, dnsName );
815 if( view != 0L )
816 dns_view_flushcache( view );
818 isc_task_endexclusive(mgr->task);
820 if( result != ISC_R_SUCCESS )
821 return result;
823 continue;
826 result = isc_task_beginexclusive(mgr->task);
828 if( result == ISC_R_SUCCESS )
830 fwdr->fwdpolicy = fwdpolicy;
832 if( isc_log_getdebuglevel(ns_g_lctx) >= 1 )
833 dbus_mgr_log_forwarders("Removing forwarder", dnsName, (SockAddrList*)&(fwdr->addrs));
835 for( sa = ISC_LIST_HEAD(fwdr->addrs);
836 sa != 0L ;
837 sa = ISC_LIST_HEAD(fwdr->addrs)
840 if( ISC_LINK_LINKED(sa, link) )
841 ISC_LIST_UNLINK(fwdr->addrs, sa, link);
842 isc_mem_put(mgr->mctx, sa, sizeof(isc_sockaddr_t));
845 ISC_LIST_INIT( fwdr->addrs );
847 for( sa = ISC_LIST_HEAD(*saList);
848 sa != 0L;
849 sa = ISC_LIST_NEXT(sa,link)
852 nsa = isc_mem_get(mgr->mctx, sizeof(isc_sockaddr_t));
853 if( nsa == 0L )
855 result = ISC_R_NOMEMORY;
856 break;
858 *nsa = *sa;
859 ISC_LINK_INIT( nsa, link );
860 ISC_LIST_APPEND( fwdr->addrs, nsa, link );
863 if( view != 0L )
864 dns_view_flushcache( view );
866 isc_task_endexclusive(mgr->task);
868 if( isc_log_getdebuglevel(ns_g_lctx) >= 1 )
869 dbus_mgr_log_forwarders("Added forwarder", dnsName, (SockAddrList*)&(fwdr->addrs));
871 }else
872 return result;
875 return (result);
878 static void
879 dbus_mgr_get_name_list
881 ns_dbus_mgr_t *mgr,
882 char *domains,
883 DNSNameList *nameList,
884 char *error_name,
885 char *error_message
888 char *name, *endName, *endp;
889 dns_fixedname_t *fixedname;
890 dns_name_t *dnsName;
891 isc_buffer_t buffer;
892 isc_result_t result;
893 uint32_t total_length;
895 total_length = strlen(domains);
896 endp = domains + total_length;
898 ISC_LIST_INIT( *nameList );
900 for( name = domains + strspn(domains," \t\n"),
901 endName = name + strcspn(name," \t\n");
902 (name < endp) && (endName <= endp);
903 name = endName + 1 + strspn(endName+1," \t\n"),
904 endName = name + strcspn(name," \t\n")
906 { /* name loop */
907 *endName = '\0';
909 isc_buffer_init( &buffer, name, endName - name );
910 isc_buffer_add(&buffer, endName - name);
912 fixedname = isc_mem_get( mgr->mctx, sizeof( dns_fixedname_t ));
914 dns_fixedname_init(fixedname);
916 dnsName = dns_fixedname_name(fixedname);
918 result= dns_name_fromtext
919 ( dnsName, &buffer, ( *(endp-1) != '.') ? dns_rootname : NULL, 0, NULL
922 if( result != ISC_R_SUCCESS )
924 sprintf(error_name, "com.redhat.named.InvalidArgument");
925 sprintf(error_message,"Invalid DNS name initial argument: %s", name);
927 isc_mem_put( mgr->mctx, fixedname, sizeof( dns_fixedname_t ) );
929 for( dnsName = ISC_LIST_HEAD( *nameList );
930 (dnsName != 0L);
931 dnsName = ISC_LIST_HEAD( *nameList )
934 if( ISC_LINK_LINKED(dnsName,link) )
935 ISC_LIST_DEQUEUE( *nameList, dnsName, link );
936 isc_mem_put( mgr->mctx, dnsName, sizeof( dns_fixedname_t ) );
938 ISC_LIST_INIT(*nameList);
939 return;
941 ISC_LINK_INIT(dnsName, link);
942 ISC_LIST_ENQUEUE( *nameList, dnsName, link );
946 static isc_result_t
947 dbus_mgr_get_sa_list
949 ns_dbus_mgr_t *mgr,
950 dbus_svc_MessageIterator iter,
951 SockAddrList *saList ,
952 uint8_t *fwdpolicy,
953 char *error_name,
954 char *error_message
957 DBUS_SVC dbus = mgr->dbus;
958 isc_sockaddr_t *nsSA=0L, *nsSA_Q=0L;
959 uint32_t argType = dbus_svc_message_next_arg_type( dbus, iter ),
960 length;
961 isc_result_t result;
962 in_port_t port;
963 char *ip;
964 uint8_t *iparray=0L;
966 ISC_LIST_INIT(*saList);
968 if( argType == TYPE_INVALID )
969 return ISC_R_SUCCESS; /* address list "removal" */
973 switch( argType )
975 case TYPE_UINT32:
977 nsSA = isc_mem_get(mgr->mctx, sizeof(isc_sockaddr_t));
978 if( nsSA != 0L )
980 memset(nsSA,'\0', sizeof(isc_sockaddr_t));
981 nsSA_Q = nsSA;
982 dbus_svc_message_next_arg(dbus, iter, &(nsSA->type.sin.sin_addr.s_addr));
983 nsSA->type.sa.sa_family = AF_INET;
984 nsSA->length = sizeof( nsSA->type.sin );
986 break;
988 case TYPE_ARRAY:
990 argType = dbus_svc_message_element_type( dbus, iter );
991 if( argType == TYPE_BYTE )
993 iparray = 0L;
994 length = 0;
996 dbus_svc_message_get_elements(dbus, iter, &length, &iparray);
998 if( iparray != 0L )
1000 if (length == sizeof( struct in_addr ))
1002 nsSA = isc_mem_get(mgr->mctx, sizeof(isc_sockaddr_t));
1003 if( nsSA != 0L )
1005 memset(nsSA,'\0', sizeof(isc_sockaddr_t));
1006 nsSA_Q = nsSA;
1008 memcpy(&(nsSA->type.sin.sin_addr), iparray, sizeof( struct in_addr ));
1009 nsSA->type.sa.sa_family = AF_INET;
1010 nsSA->length = sizeof( nsSA->type.sin );
1012 }else
1013 if (length == sizeof( struct in6_addr ))
1015 nsSA = isc_mem_get(mgr->mctx, sizeof(isc_sockaddr_t));
1016 if( nsSA != 0L )
1018 memset(nsSA,'\0', sizeof(isc_sockaddr_t));
1019 nsSA_Q = nsSA;
1021 memcpy(&(nsSA->type.sin6.sin6_addr), iparray, sizeof( struct in6_addr ));
1022 nsSA->type.sa.sa_family = AF_INET6;
1023 nsSA->length = sizeof( nsSA->type.sin6 );
1028 break;
1030 case TYPE_STRING:
1032 ip = 0L;
1033 dbus_svc_message_next_arg(dbus, iter, &(ip));
1034 if( ip != 0L )
1036 length = strlen(ip);
1037 if( strspn(ip, "0123456789.") == length )
1039 nsSA = isc_mem_get(mgr->mctx, sizeof(isc_sockaddr_t));
1040 if( nsSA != 0L)
1042 memset(nsSA,'\0', sizeof(isc_sockaddr_t));
1043 if( inet_pton( AF_INET, ip, &(nsSA->type.sin.sin_addr)) )
1045 nsSA->type.sa.sa_family = AF_INET;
1046 nsSA->length = sizeof(nsSA->type.sin);
1047 nsSA_Q = nsSA;
1050 }else
1051 if( strspn(ip, "0123456789AaBbCcDdEeFf:.") == length)
1053 nsSA = isc_mem_get(mgr->mctx, sizeof(isc_sockaddr_t));
1054 if( nsSA != 0L )
1056 memset(nsSA,'\0', sizeof(isc_sockaddr_t));
1057 if( inet_pton( AF_INET6, ip, &(nsSA->type.sin6.sin6_addr)) )
1059 nsSA->type.sa.sa_family = AF_INET6;
1060 nsSA->length = sizeof(nsSA->type.sin6);
1061 nsSA_Q = nsSA;
1066 break;
1068 case TYPE_UINT16:
1070 if( (nsSA == 0L) || (nsSA->type.sa.sa_family == AF_UNSPEC) )
1071 break;
1072 else
1073 if( nsSA->type.sa.sa_family == AF_INET )
1074 dbus_svc_message_next_arg(dbus, iter, &(nsSA->type.sin.sin_port));
1075 else
1076 if( nsSA->type.sa.sa_family == AF_INET6 )
1077 dbus_svc_message_next_arg(dbus, iter, &(nsSA->type.sin6.sin6_port));
1078 break;
1080 case TYPE_BYTE:
1082 dbus_svc_message_next_arg(dbus, iter, fwdpolicy);
1083 if(*fwdpolicy > dns_fwdpolicy_only)
1084 *fwdpolicy = dns_fwdpolicy_only;
1085 break;
1087 default:
1089 if(nsSA != 0L)
1090 nsSA->type.sa.sa_family = AF_UNSPEC;
1091 sprintf(error_message,"Unhandled argument type: %c", argType);
1092 break;
1095 if( (nsSA != 0L)
1096 &&(nsSA->type.sa.sa_family == AF_UNSPEC)
1099 sprintf(error_name, "com.redhat.named.InvalidArgument");
1100 if( error_message[0]=='\0')
1102 if( nsSA == 0L )
1103 sprintf(error_message,"Missing IP Address Name Server argument");
1104 else
1105 sprintf(error_message,"Bad IP Address Name Server argument");
1107 if( nsSA != 0L )
1108 isc_mem_put(mgr->mctx, nsSA, sizeof(isc_sockaddr_t));
1109 nsSA = 0L;
1110 for( nsSA = ISC_LIST_HEAD( *saList );
1111 (nsSA != 0L);
1112 nsSA = ISC_LIST_HEAD( *saList )
1115 if(ISC_LINK_LINKED(nsSA, link))
1116 ISC_LIST_DEQUEUE( *saList, nsSA, link );
1117 isc_mem_put( mgr->mctx, nsSA, sizeof( isc_sockaddr_t ) );
1119 ISC_LIST_INIT(*saList);
1120 return ISC_R_FAILURE;
1123 if( nsSA != 0L )
1125 if( nsSA->type.sin.sin_port == 0 )
1127 if( ns_g_port != 0L )
1128 nsSA->type.sin.sin_port = htons(ns_g_port);
1129 else
1131 result = ns_config_getport(ns_g_config, &(port) );
1132 if( result != ISC_R_SUCCESS )
1133 port = 53;
1134 nsSA->type.sin.sin_port = htons( port );
1138 if( nsSA_Q != 0L )
1140 ISC_LINK_INIT(nsSA,link);
1141 ISC_LIST_ENQUEUE(*saList, nsSA, link);
1142 nsSA_Q = 0L;
1146 argType = dbus_svc_message_next_arg_type( dbus, iter );
1148 } while ( argType != TYPE_INVALID );
1150 return ISC_R_SUCCESS;
1153 static void
1154 dbus_mgr_handle_set_forwarders
1156 ns_dbus_mgr_t *mgr,
1157 DBUS_SVC dbus,
1158 uint8_t reply_expected,
1159 uint32_t serial,
1160 const char *path,
1161 const char *member,
1162 const char *interface,
1163 const char *sender,
1164 dbus_svc_MessageHandle msg
1167 dbus_svc_MessageIterator iter;
1168 char error_name[1024]="", error_message[1024]="", *domains=0L;
1169 uint32_t argType, new_serial;
1170 DNSNameList nameList;
1171 dns_name_t *dnsName;
1172 SockAddrList saList;
1173 isc_sockaddr_t *nsSA;
1174 isc_result_t result;
1175 uint8_t fwdpolicy = dns_fwdpolicy_only;
1177 iter = dbus_svc_message_iterator_new( dbus, msg );
1179 if( iter == 0L )
1181 if( reply_expected )
1183 sprintf(error_name, "com.redhat.named.InvalidArguments");
1184 sprintf(error_message,"SetForwarders requires DNS name and nameservers arguments.");
1185 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1186 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1189 return;
1192 argType = dbus_svc_message_next_arg_type( dbus, iter );
1194 if( argType != TYPE_STRING )
1196 if( reply_expected )
1198 sprintf(error_name, "com.redhat.named.InvalidArguments");
1199 sprintf(error_message,"SetForwarders requires DNS name string initial argument.");
1200 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1201 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1204 return;
1207 dbus_svc_message_next_arg( dbus, iter, &domains );
1209 if( ( domains == 0L ) || (*domains == '\0') )
1211 if( reply_expected )
1213 sprintf(error_name, "com.redhat.named.InvalidArguments");
1214 sprintf(error_message,"SetForwarders requires DNS name string initial argument.");
1215 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1216 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1219 return;
1222 dbus_mgr_get_name_list( mgr, domains, &nameList, error_name, error_message );
1224 if( error_name[0] != '\0' )
1226 if( reply_expected )
1228 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1229 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1232 return;
1235 if( ISC_LIST_HEAD( nameList ) == 0L )
1236 return;
1238 result = dbus_mgr_get_sa_list( mgr, iter, &saList , &fwdpolicy, error_name, error_message );
1240 if( result == ISC_R_SUCCESS )
1242 result = dbus_mgr_set_forwarders( mgr, &nameList, &saList, fwdpolicy );
1244 if( result != ISC_R_SUCCESS )
1246 if( reply_expected )
1248 sprintf(error_name, "com.redhat.named.Failure");
1249 sprintf(error_message, isc_result_totext(result));
1250 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1251 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1254 }else
1255 if( reply_expected )
1256 dbus_svc_send( dbus, RETURN, serial, &new_serial, sender, path, interface, member,
1257 TYPE_UINT32, &result, TYPE_INVALID
1259 }else
1261 if( reply_expected )
1263 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1264 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1269 for( dnsName = ISC_LIST_HEAD( nameList );
1270 (dnsName != 0L) ;
1271 dnsName = ISC_LIST_HEAD( nameList )
1274 if( ISC_LINK_LINKED(dnsName,link) )
1275 ISC_LIST_DEQUEUE( nameList, dnsName, link );
1276 isc_mem_put( mgr->mctx, dnsName, sizeof( dns_fixedname_t ) );
1279 for( nsSA = ISC_LIST_HEAD(saList);
1280 (nsSA != 0L) ;
1281 nsSA = ISC_LIST_HEAD(saList)
1284 if( ISC_LINK_LINKED(nsSA,link) )
1285 ISC_LIST_DEQUEUE( saList, nsSA, link );
1286 isc_mem_put(mgr->mctx, nsSA, sizeof(isc_sockaddr_t));
1290 static
1291 int dbus_mgr_msg_append_dns_name
1292 ( DBUS_SVC dbus,
1293 dbus_svc_MessageHandle msg,
1294 dns_name_t *name
1297 char nameBuf[ DNS_NAME_FORMATSIZE ]="", *nameP=&(nameBuf[0]);
1299 dns_name_format(name, nameP, DNS_NAME_FORMATSIZE );
1301 if( *nameP == '\0' )
1302 return 0;
1304 return dbus_svc_message_append_args( dbus, msg, TYPE_STRING, &nameP, TYPE_INVALID ) > 0;
1307 typedef enum dbmoi_e
1309 OUTPUT_BINARY,
1310 OUTPUT_TEXT
1311 } DBusMgrOutputInterface;
1313 static
1314 int dbus_mgr_msg_append_forwarders
1315 ( DBUS_SVC dbus,
1316 dbus_svc_MessageHandle msg,
1317 dns_forwarders_t *fwdr,
1318 DBusMgrOutputInterface outputType
1321 isc_sockaddr_t *sa;
1322 char policyBuf[16]="", *pbp[1]={&(policyBuf[0])}, addressBuf[64]="", *abp[1]={&(addressBuf[0])};
1323 uint8_t *byteArray[1];
1325 if( outputType == OUTPUT_BINARY )
1327 if(!dbus_svc_message_append_args
1328 ( dbus, msg,
1329 TYPE_BYTE, &(fwdr->fwdpolicy),
1330 TYPE_INVALID
1332 ) return 0;
1333 }else
1334 if( outputType == OUTPUT_TEXT )
1336 sprintf(policyBuf,"%s",
1337 (fwdr->fwdpolicy == dns_fwdpolicy_none)
1338 ? "none"
1339 : (fwdr->fwdpolicy == dns_fwdpolicy_first)
1340 ? "first"
1341 : "only"
1343 if(!dbus_svc_message_append_args
1344 ( dbus, msg,
1345 TYPE_STRING, pbp,
1346 TYPE_INVALID
1348 ) return 0;
1349 }else
1350 return 0;
1352 for( sa = ISC_LIST_HEAD(fwdr->addrs);
1353 sa != 0L;
1354 sa = ISC_LIST_NEXT(sa, link)
1357 if( outputType == OUTPUT_BINARY )
1359 if( sa->type.sa.sa_family == AF_INET )
1361 if(!dbus_svc_message_append_args
1362 ( dbus, msg,
1363 TYPE_UINT32, &(sa->type.sin.sin_addr.s_addr),
1364 TYPE_INVALID
1366 ) return 0;
1368 if(!dbus_svc_message_append_args
1369 ( dbus, msg,
1370 TYPE_UINT16, &(sa->type.sin.sin_port),
1371 TYPE_INVALID
1373 ) return 0;
1374 }else
1375 if( sa->type.sa.sa_family == AF_INET6 )
1377 byteArray[0] = (uint8_t*)&(sa->type.sin6.sin6_addr);
1378 if(!dbus_svc_message_append_args
1379 ( dbus, msg,
1380 TYPE_ARRAY, TYPE_BYTE, &byteArray, sizeof(struct in6_addr),
1381 TYPE_INVALID
1383 ) return 0;
1385 if(!dbus_svc_message_append_args
1386 ( dbus, msg,
1387 TYPE_UINT16, &(sa->type.sin6.sin6_port),
1388 TYPE_INVALID
1390 ) return 0;
1391 }else
1392 continue;
1393 }else
1394 if( outputType == OUTPUT_TEXT )
1396 if( sa->type.sa.sa_family == AF_INET )
1398 if( inet_ntop( AF_INET, &(sa->type.sin.sin_addr), addressBuf, sizeof(addressBuf)) == 0L )
1399 continue;
1400 if(!dbus_svc_message_append_args
1401 ( dbus, msg,
1402 TYPE_STRING, abp,
1403 TYPE_INVALID
1405 ) return 0;
1406 sprintf(addressBuf, "%hu", ntohs( sa->type.sin.sin_port ));
1407 if(!dbus_svc_message_append_args
1408 ( dbus, msg,
1409 TYPE_STRING, abp,
1410 TYPE_INVALID
1412 ) return 0;
1413 }else
1414 if( sa->type.sa.sa_family == AF_INET6 )
1416 if( inet_ntop( AF_INET6, &(sa->type.sin6.sin6_addr), addressBuf, sizeof(addressBuf)) == 0L )
1417 continue;
1418 if(!dbus_svc_message_append_args
1419 ( dbus, msg,
1420 TYPE_STRING, abp,
1421 TYPE_INVALID
1423 ) return 0;
1424 sprintf(addressBuf, "%hu", ntohs( sa->type.sin6.sin6_port ));
1425 if(!dbus_svc_message_append_args
1426 ( dbus, msg,
1427 TYPE_STRING, abp,
1428 TYPE_INVALID
1430 ) return 0;
1431 }else
1432 continue;
1433 }else
1434 return 0;
1436 return 1;
1439 typedef struct dbm_m_s
1441 DBUS_SVC dbus;
1442 dbus_svc_MessageHandle msg;
1443 DBusMgrOutputInterface outputType;
1444 } DBusMgrMsg;
1446 static
1447 void forwarders_to_msg( dns_name_t *name, dns_forwarders_t *fwdr, void *mp )
1449 DBusMgrMsg *m = mp;
1451 if( (fwdr == 0L) || (name == 0L) || (mp == 0L))
1452 return;
1453 dbus_mgr_msg_append_dns_name ( m->dbus, m->msg, name );
1454 dbus_mgr_msg_append_forwarders( m->dbus, m->msg, fwdr, m->outputType );
1457 static void
1458 dbus_mgr_handle_list_forwarders
1460 DBUS_SVC dbus,
1461 uint8_t reply_expected,
1462 uint32_t serial,
1463 const char *path,
1464 const char *member,
1465 const char *interface,
1466 const char *sender,
1467 dbus_svc_MessageHandle msg
1470 char error_name[1024], error_message[1024];
1471 DBusMgrMsg m;
1472 uint32_t new_serial;
1473 dns_fwdtable_t *fwdtable = dbus_mgr_get_fwdtable();
1474 DBusMgrOutputInterface outputType = OUTPUT_BINARY;
1475 uint32_t length = strlen(interface);
1477 if( !reply_expected )
1478 return;
1480 if( (length > 4) && (strcmp(interface + (length - 4), "text")==0))
1481 outputType = OUTPUT_TEXT;
1483 if( fwdtable == 0L )
1485 sprintf(error_name,"com.redhat.dbus.Failure");
1486 sprintf(error_message, "%s", isc_result_totext(ISC_R_NOPERM));
1487 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1488 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1490 return;
1493 msg = dbus_svc_new_message( dbus, RETURN, serial, sender, path, interface, member);
1495 m.dbus = dbus;
1496 m.msg = msg;
1497 m.outputType = outputType;
1499 if( msg == 0L )
1501 sprintf(error_name,"com.redhat.dbus.OutOfMemory");
1502 sprintf(error_message,"out of memory");
1503 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1504 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1508 dns_fwdtable_foreach( fwdtable, forwarders_to_msg, &m );
1510 dbus_svc_send_message( dbus, msg, &new_serial );
1513 static void
1514 dbus_mgr_handle_get_forwarders
1516 DBUS_SVC dbus,
1517 uint8_t reply_expected,
1518 uint32_t serial,
1519 const char *path,
1520 const char *member,
1521 const char *interface,
1522 const char *sender,
1523 dbus_svc_MessageHandle msg
1526 char error_name[1024], error_message[1024], *domain=0L;
1527 isc_result_t result;
1528 dns_fixedname_t fixedname;
1529 dns_name_t *dnsName;
1530 isc_buffer_t buffer;
1531 uint32_t length, new_serial;
1532 dns_fwdtable_t *fwdtable;
1533 dns_forwarders_t *fwdr=0L;
1534 dns_name_t *foundname;
1535 dns_fixedname_t fixedFoundName;
1536 DBusMgrOutputInterface outputType = OUTPUT_BINARY;
1538 if( !reply_expected )
1539 return;
1541 length = strlen(interface);
1543 if( (length > 4) && (strcmp(interface + (length - 4), "text")==0))
1544 outputType = OUTPUT_TEXT;
1546 if( (!dbus_svc_get_args( dbus, msg, TYPE_STRING, &domain, TYPE_INVALID))
1547 ||(domain == 0L)
1548 ||(*domain == '\0')
1552 sprintf(error_name,"com.redhat.dbus.InvalidArguments");
1553 sprintf(error_message,"domain name argument expected");
1554 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1555 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1557 return;
1560 length = strlen( domain );
1562 isc_buffer_init( &buffer, domain, length);
1564 isc_buffer_add(&buffer, length);
1566 dns_fixedname_init(&fixedname);
1568 dnsName = dns_fixedname_name(&fixedname);
1570 result = dns_name_fromtext
1571 ( dnsName, &buffer, dns_rootname, 0, NULL
1574 if( result != ISC_R_SUCCESS )
1576 sprintf(error_name,"com.redhat.dbus.InvalidArguments");
1577 sprintf(error_message,"invalid domain name argument: %s", domain);
1578 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1579 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1581 return;
1584 msg = dbus_svc_new_message( dbus, RETURN, serial, sender, path, interface, member);
1586 if( msg == 0L )
1588 sprintf(error_name,"com.redhat.dbus.OutOfMemory");
1589 sprintf(error_message,"out of memory");
1590 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1591 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1593 return;
1596 fwdtable = dbus_mgr_get_fwdtable();
1598 if( fwdtable == 0L )
1600 sprintf(error_name,"com.redhat.dbus.Failure");
1601 sprintf(error_message, "%s", isc_result_totext(ISC_R_NOPERM));
1602 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1603 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1605 return;
1608 dns_fixedname_init(&fixedFoundName);
1609 foundname = dns_fixedname_name(&fixedFoundName);
1611 if( ( dns_fwdtable_find_closest( fwdtable, dnsName, foundname, &fwdr ) == ISC_R_SUCCESS )
1612 &&( fwdr != 0L )
1615 if( (!dbus_mgr_msg_append_dns_name( dbus, msg, foundname ))
1616 ||(!dbus_mgr_msg_append_forwarders( dbus, msg, fwdr, outputType ))
1619 sprintf(error_name,"com.redhat.dbus.OutOfMemory");
1620 sprintf(error_message,"out of memory");
1621 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1622 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1624 return;
1627 }else
1629 result = ISC_R_NOTFOUND;
1630 if( outputType == OUTPUT_BINARY )
1632 dbus_svc_message_append_args( dbus, msg,
1633 TYPE_UINT32, &(result),
1634 TYPE_INVALID
1636 }else
1638 sprintf(error_name,"com.redhat.dbus.NotFound");
1639 sprintf(error_message,"Not Found");
1640 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
1641 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
1643 return;
1646 dbus_svc_send_message( dbus, msg, &new_serial );
1649 static void
1650 dbus_mgr_check_dhcdbd_state( ns_dbus_mgr_t *mgr, dbus_svc_MessageHandle msg )
1652 DBUS_SVC dbus = mgr->dbus;
1653 char *name_owned = 0L,
1654 *old_owner = 0L,
1655 *new_owner = 0L;
1657 if( !dbus_svc_get_args( dbus, msg,
1658 TYPE_STRING, &name_owned,
1659 TYPE_STRING, &old_owner,
1660 TYPE_STRING, &new_owner,
1661 TYPE_INVALID
1663 ) return;
1665 dbus_mgr_log_dbg("NameOwnerChanged: %s %s %s ( %s )", name_owned, old_owner, new_owner, mgr->dhcdbd_name);
1667 if( (name_owned == 0L) || (new_owner == 0L) || (old_owner == 0L) )
1668 return;
1670 if( strcmp( name_owned, "com.redhat.dhcp" ) == 0 )
1672 if( *new_owner == '\0' )
1674 isc_mem_put(mgr->mctx, mgr->dhcdbd_name, strlen(mgr->dhcdbd_name) + 1);
1675 mgr->dhcdbd_name = 0L;
1676 dbus_mgr_log_err("D-BUS dhcdbd subscription disabled.");
1677 return;
1679 if( (mgr->dhcdbd_name == 0L)
1680 ||( strcmp( mgr->dhcdbd_name, new_owner) != 0 )
1683 if( mgr->dhcdbd_name != 0L )
1685 isc_mem_put(mgr->mctx, mgr->dhcdbd_name, strlen(mgr->dhcdbd_name)+1);
1686 mgr->dhcdbd_name = 0L;
1688 mgr->dhcdbd_name = isc_mem_get(mgr->mctx, strlen(new_owner) + 1);
1689 if( mgr->dhcdbd_name == 0L )
1690 return;
1691 strcpy( mgr->dhcdbd_name, new_owner );
1692 dbus_mgr_subscribe_to_dhcdbd( mgr );
1694 }else
1695 if( ( mgr->dhcdbd_name != 0L )
1696 && ( strcmp(mgr->dhcdbd_name, name_owned) == 0L )
1697 && ( *new_owner == '\0' )
1700 isc_mem_put(mgr->mctx, mgr->dhcdbd_name, strlen(mgr->dhcdbd_name));
1701 mgr->dhcdbd_name = 0L;
1702 dbus_mgr_log_err("D-BUS dhcdbd subscription disabled.");
1706 static int dbus_mgr_dhc_if_comparator( const void *p1, const void *p2 )
1708 return( strcmp( ((const DHC_IF*)p1)->if_name, ((const DHC_IF*)p2)->if_name) );
1711 static
1712 dns_name_t *dbus_mgr_if_reverse_ip_name
1713 ( ns_dbus_mgr_t *mgr,
1714 struct in_addr ip_address,
1715 struct in_addr subnet_mask
1718 dns_name_t *dns_name =0L;
1719 dns_fixedname_t *fixedname=0L;
1720 char name [ DNS_NAME_FORMATSIZE ], *p;
1721 uint32_t ip = (ntohl(ip_address.s_addr) & ntohl(subnet_mask.s_addr)), i;
1722 isc_buffer_t buffer;
1723 isc_result_t result;
1725 if( (ip == 0) || (ip == 0xffffffff) )
1726 return 0L;
1728 for(i = 8, p = name; (i < 32); i += 8)
1729 if( ip & ( 0xff << i ) )
1730 p += sprintf(p, "%u.", (((ip & ( 0xff << i )) >> i ) & 0xff) );
1732 if( p > name )
1734 p += sprintf(p, "in-addr.arpa");
1735 isc_buffer_init( &buffer, name, p - name );
1736 isc_buffer_add(&buffer, p - name);
1738 fixedname = isc_mem_get( mgr->mctx, sizeof( dns_fixedname_t ));
1740 dns_fixedname_init(fixedname);
1742 dns_name = dns_fixedname_name(fixedname);
1744 result= dns_name_fromtext
1745 ( dns_name, &buffer, dns_rootname, 0, NULL
1748 ISC_LINK_INIT(dns_name, link);
1749 if( result == ISC_R_SUCCESS )
1750 return dns_name;
1752 return 0L;
1755 static void
1756 dbus_mgr_free_dhc( void *p )
1758 DHC_IF *d_if = p;
1759 dns_name_t *dn;
1760 isc_sockaddr_t *sa;
1762 isc_mem_put( ns_g_mctx, d_if->if_name, strlen(d_if->if_name) + 1);
1763 for( sa = ISC_LIST_HEAD( d_if->dns );
1764 sa != NULL;
1765 sa = ISC_LIST_HEAD( d_if->dns )
1768 if( ISC_LINK_LINKED( sa, link ) )
1769 ISC_LIST_UNLINK( d_if->dns, sa, link );
1770 isc_mem_put(ns_g_mctx, sa, sizeof(isc_sockaddr_t));
1772 for( dn = ISC_LIST_HEAD( d_if->dn );
1773 dn != NULL;
1774 dn = ISC_LIST_HEAD( d_if->dn )
1777 if( ISC_LINK_LINKED( dn, link ) )
1778 ISC_LIST_UNLINK( d_if->dn, dn, link );
1779 isc_mem_put( ns_g_mctx, dn, sizeof( dns_fixedname_t ) );
1781 isc_mem_put( ns_g_mctx, d_if, sizeof(DHC_IF));
1784 static void
1785 dbus_mgr_handle_dhcdbd_message
1787 ns_dbus_mgr_t *mgr,
1788 const char *path,
1789 const char *member,
1790 dbus_svc_MessageHandle msg
1793 DBUS_SVC dbus = mgr->dbus;
1794 DHC_IF *d_if, *const*d_ifpp, dif;
1795 DHC_State dhc_state;
1796 char *if_name, *opt_name, error_name[1024]="", error_message[1024]="";
1797 uint8_t *value=0L;
1798 uint32_t length;
1799 isc_result_t result;
1800 isc_sockaddr_t *sa = 0L;
1801 dns_name_t *dn = 0L;
1802 struct in_addr *ip;
1803 in_port_t port;
1804 char dnBuf[ DNS_NAME_FORMATSIZE ];
1805 isc_buffer_t buffer;
1806 DBusMgrInitialFwdr *ifwdr, *const*ifwdpp, ifwd;
1807 ISC_LIST(DBusMgrInitialFwdr) ifwdrList;
1808 DNSNameList nameList;
1809 dbus_mgr_log_dbg("Got dhcdbd message: %s %s %p", path, member, msg );
1811 if( ( if_name = strrchr(path,'/') ) == 0L )
1813 dbus_mgr_log_err("bad path in dhcdbd message:", path);
1814 return;
1817 ++if_name;
1818 dif.if_name = if_name;
1820 if( ((d_ifpp=tfind( &dif, &(mgr->dhc_if), dbus_mgr_dhc_if_comparator)) == 0L)
1821 ||((d_if = *d_ifpp) == 0L)
1824 d_if = isc_mem_get( mgr->mctx, sizeof(DHC_IF));
1825 if( d_if == 0L )
1827 dbus_mgr_log_err("out of memory");
1828 return;
1830 memset(d_if, '\0', sizeof(DHC_IF));
1831 if((d_if->if_name = isc_mem_get( mgr->mctx, strlen(if_name) + 1)) == 0L)
1833 dbus_mgr_log_err("out of memory");
1834 return;
1836 strcpy(d_if->if_name, if_name);
1837 d_if->dhc_state = DHC_INVALID;
1838 d_if->previous_state = DHC_INVALID;
1839 ISC_LIST_INIT( d_if->dn );
1840 ISC_LIST_INIT( d_if->dns );
1841 if( tsearch( d_if, &(mgr->dhc_if), dbus_mgr_dhc_if_comparator) == 0L )
1843 dbus_mgr_log_err("out of memory");
1844 return;
1848 if( strcmp(member, "reason") == 0 )
1850 if( (!dbus_svc_get_args( dbus, msg,
1851 TYPE_STRING, &opt_name,
1852 TYPE_ARRAY, TYPE_BYTE, &value, &length,
1853 TYPE_INVALID
1856 ||( value == 0L)
1857 ||( length != sizeof(uint32_t))
1858 ||( *((uint32_t*)value) > DHC_END_OPTIONS)
1861 dbus_mgr_log_err("Invalid DHC reason value received from dhcdbd");
1862 return;
1864 dhc_state = (DHC_State) *((uint32_t*)value);
1865 dbus_mgr_log_dbg("reason: %d %d %d", dhc_state, d_if->dhc_state, d_if->previous_state);
1866 switch( dhc_state )
1869 case DHC_END_OPTIONS:
1870 switch( d_if->dhc_state )
1872 case DHC_END_OPTIONS:
1873 break;
1875 case DHC_RENEW:
1876 case DHC_REBIND:
1877 if( ( d_if->previous_state != DHC_INVALID )
1878 &&( d_if->previous_state != DHC_RELEASE )
1879 ) break;
1880 /* DHC_RENEW means the same lease parameters were obtained.
1881 * Only do configuration if we started up with existing dhclient
1882 * which has now renewed - else we are already configured correctly.
1884 dbus_mgr_log_err("D-BUS: existing dhclient for interface %s RENEWed lease", if_name);
1886 case DHC_REBOOT:
1887 case DHC_BOUND:
1888 d_if->previous_state = d_if->dhc_state;
1889 d_if->dhc_state = DHC_BOUND;
1890 if( (dn = dbus_mgr_if_reverse_ip_name(mgr, d_if->ip, d_if->subnet_mask )) != 0L )
1892 ISC_LIST_APPEND(d_if->dn, dn, link );
1894 if( ( ISC_LIST_HEAD( d_if->dn ) != NULL )
1895 &&( ISC_LIST_HEAD( d_if->dns ) != NULL )
1898 dbus_mgr_log_err("D-BUS: dhclient for interface %s acquired new lease - creating forwarders.",
1899 if_name
1901 result = dbus_mgr_set_forwarders( mgr, &(d_if->dn), &(d_if->dns), dns_fwdpolicy_only );
1902 if( result != ISC_R_SUCCESS )
1904 dbus_mgr_log_err("D-BUS: forwarder configuration failed: %s", isc_result_totext(result));
1907 break;
1909 case DHC_STOP:
1910 case DHC_TIMEOUT:
1911 case DHC_FAIL:
1912 case DHC_EXPIRE:
1913 case DHC_RELEASE:
1914 d_if->previous_state = d_if->dhc_state;
1915 d_if->dhc_state = DHC_RELEASE;
1916 if( ISC_LIST_HEAD( d_if->dn ) != NULL )
1918 dbus_mgr_log_err("D-BUS: dhclient for interface %s released lease - removing forwarders.",
1919 if_name);
1920 for( sa = ISC_LIST_HEAD( d_if->dns );
1921 sa != 0L;
1922 sa = ISC_LIST_HEAD( d_if->dns )
1925 if( ISC_LINK_LINKED( sa, link ) )
1926 ISC_LIST_UNLINK( d_if->dns, sa, link );
1927 isc_mem_put( mgr->mctx, sa, sizeof(isc_sockaddr_t));
1929 ISC_LIST_INIT( d_if->dns );
1930 ISC_LIST_INIT( ifwdrList );
1932 for( dn = ISC_LIST_HEAD( d_if->dn );
1933 dn != 0L;
1934 dn = ISC_LIST_NEXT( dn, link )
1937 dns_name_init( &(ifwd.dn), NULL );
1938 isc_buffer_init( &buffer, dnBuf, DNS_NAME_FORMATSIZE);
1939 dns_name_setbuffer( &(ifwd.dn), &buffer);
1940 dns_name_copy(dn, &(ifwd.dn), NULL);
1941 if( ((ifwdpp = tfind(&ifwd, &(mgr->ifwdt), dbus_mgr_ifwdr_comparator)) != 0L )
1942 &&((ifwdr = *ifwdpp) != 0L)
1945 ISC_LIST_APPEND( ifwdrList, ifwdr, link );
1949 result = dbus_mgr_set_forwarders( mgr, &(d_if->dn), &(d_if->dns), dns_fwdpolicy_none );
1950 if( result != ISC_R_SUCCESS )
1952 dbus_mgr_log_err("D-BUS: removal of forwarders failed: %s", isc_result_totext(result));
1955 for( dn = ISC_LIST_HEAD( d_if->dn );
1956 dn != 0L;
1957 dn = ISC_LIST_HEAD( d_if->dn )
1960 if( ISC_LINK_LINKED( dn, link ) )
1961 ISC_LIST_UNLINK( d_if->dn, dn, link );
1962 isc_mem_put( mgr->mctx, dn, sizeof( dns_fixedname_t ) );
1964 ISC_LIST_INIT( d_if->dn );
1966 for( ifwdr = ISC_LIST_HEAD( ifwdrList );
1967 ifwdr != 0L;
1968 ifwdr = ISC_LIST_HEAD( ifwdrList )
1971 if( ISC_LINK_LINKED( ifwdr, link ) )
1972 ISC_LIST_UNLINK( ifwdrList, ifwdr, link );
1973 ISC_LINK_INIT(ifwdr, link);
1974 ISC_LIST_INIT(nameList);
1975 ISC_LINK_INIT(&(ifwdr->dn), link);
1976 ISC_LIST_APPEND( nameList, &(ifwdr->dn), link );
1977 result = dbus_mgr_set_forwarders( mgr, &nameList,
1978 &(ifwdr->sa),
1979 ifwdr->fwdpolicy
1981 if( result != ISC_R_SUCCESS )
1983 dbus_mgr_log_err("D-BUS: restore of forwarders failed: %s", isc_result_totext(result));
1988 case DHC_ABEND:
1989 case DHC_END:
1990 case DHC_NBI:
1991 case DHC_PREINIT:
1992 case DHC_MEDIUM:
1993 case DHC_START:
1994 case DHC_INVALID:
1995 default:
1996 break;
1998 break;
2000 case DHC_BOUND:
2001 case DHC_REBOOT:
2002 case DHC_REBIND:
2003 case DHC_RENEW:
2004 case DHC_STOP:
2005 case DHC_TIMEOUT:
2006 case DHC_FAIL:
2007 case DHC_EXPIRE:
2008 case DHC_RELEASE:
2009 d_if->previous_state = d_if->dhc_state;
2010 d_if->dhc_state = dhc_state;
2012 case DHC_ABEND:
2013 case DHC_END:
2014 case DHC_NBI:
2015 case DHC_PREINIT:
2016 case DHC_MEDIUM:
2017 case DHC_START:
2018 case DHC_INVALID:
2019 default:
2020 break;
2022 }else
2023 if( strcmp( member, "domain_name" ) == 0 )
2025 if( (!dbus_svc_get_args( dbus, msg,
2026 TYPE_STRING, &opt_name,
2027 TYPE_ARRAY, TYPE_BYTE, &value, &length,
2028 TYPE_INVALID
2031 ||( value == 0L)
2032 ||( length == 0)
2035 dbus_mgr_log_err("Invalid domain_name value received from dhcdbd");
2036 return;
2038 dbus_mgr_log_dbg("domain-name %s", (char*)value);
2039 dbus_mgr_get_name_list( mgr, (char*)value, &(d_if->dn), error_name, error_message );
2040 if( ( error_message[0] != '\0' ) || (ISC_LIST_HEAD(d_if->dn) == 0L ))
2042 dbus_mgr_log_err("Bad domain_name value: %s", error_message );
2044 }else
2045 if( strcmp( member, "domain_name_servers") == 0 )
2047 if( (!dbus_svc_get_args( dbus, msg,
2048 TYPE_STRING, &opt_name,
2049 TYPE_ARRAY, TYPE_BYTE, &value, &length,
2050 TYPE_INVALID
2053 ||( value == 0L)
2054 ||( length == 0)
2057 dbus_mgr_log_err("Invalid domain_name_servers value received from dhcdbd");
2058 return;
2060 for(ip = (struct in_addr*) value; ip < ((struct in_addr*)(value + length)); ip++)
2062 dbus_mgr_log_dbg("domain-name-servers: %s", inet_ntop(AF_INET, value, error_name, 16));
2063 sa = isc_mem_get(mgr->mctx, sizeof(isc_sockaddr_t));
2064 memset(sa, '\0', sizeof(isc_sockaddr_t));
2065 sa->type.sin.sin_addr = *ip;
2066 sa->type.sa.sa_family = AF_INET;
2067 sa->length = sizeof(sa->type.sin);
2068 result = ns_config_getport(ns_g_config, &(port) );
2069 if( result != ISC_R_SUCCESS )
2070 port = 53;
2071 sa->type.sin.sin_port = htons( port );
2072 ISC_LIST_APPEND(d_if->dns, sa, link);
2074 }else
2075 if( strcmp(member, "ip_address") == 0)
2077 if( (!dbus_svc_get_args( dbus, msg,
2078 TYPE_STRING, &opt_name,
2079 TYPE_ARRAY, TYPE_BYTE, &value, &length,
2080 TYPE_INVALID
2083 ||( value == 0L)
2084 ||( length != sizeof(struct in_addr) )
2087 dbus_mgr_log_err("Invalid ip_address value received from dhcdbd");
2088 return;
2090 dbus_mgr_log_dbg("ip-address: %s", inet_ntop(AF_INET, value, error_name, 16));
2091 d_if->ip = *((struct in_addr*)value);
2093 }else
2094 if( strcmp(member, "subnet_mask") == 0 )
2096 if( (!dbus_svc_get_args( dbus, msg,
2097 TYPE_STRING, &opt_name,
2098 TYPE_ARRAY, TYPE_BYTE, &value, &length,
2099 TYPE_INVALID
2102 ||( value == 0L)
2103 ||( length != sizeof(struct in_addr) )
2106 dbus_mgr_log_err("Invalid subnet_mask value received from dhcdbd");
2107 return;
2109 dbus_mgr_log_dbg("subnet-mask: %s", inet_ntop(AF_INET, value, error_name, 16));
2110 d_if->subnet_mask = *((struct in_addr*)value);
2114 static
2115 dbus_svc_HandlerResult
2116 dbus_mgr_message_handler
2118 DBusMsgHandlerArgs
2121 char error_name[1024], error_message[1024];
2122 ns_dbus_mgr_t *mgr = object;
2123 uint32_t new_serial;
2125 if_suffix = prefix = suffix = prefixObject = 0L;
2127 dbus_mgr_log_dbg("D-BUS message: %u %u %u %s %s %s %s %s %s",
2128 type, reply_expected, serial, destination, path, member, interface, sender, signature
2131 if ( ( type == SIGNAL )
2132 &&( strcmp(path,"/org/freedesktop/DBus/Local") == 0 )
2135 if( strcmp(member,"Disconnected") == 0 )
2136 dbus_mgr_dbus_shutdown_handler( mgr );
2137 }else
2138 if( ( type == SIGNAL )
2139 &&( strcmp(path,"/org/freedesktop/DBus") == 0 )
2140 &&(strcmp(member,"NameOwnerChanged") == 0)
2141 &&(strcmp(signature, "sss") == 0)
2144 dbus_mgr_check_dhcdbd_state( mgr, msg );
2145 }else
2146 if( ( type == SIGNAL )
2147 &&( (sender != 0L) && (mgr->dhcdbd_name != 0L) && (strcmp(sender,mgr->dhcdbd_name) == 0))
2148 &&( strcmp(interface,"com.redhat.dhcp.subscribe.binary") == 0 )
2151 dbus_mgr_handle_dhcdbd_message( mgr, path, member, msg );
2152 }else
2153 if( (type == CALL)
2154 &&( strcmp(destination, DBUSMGR_DESTINATION)==0)
2155 &&( strcmp(path, DBUSMGR_OBJECT_PATH)==0)
2158 if( strcmp(member, "SetForwarders") == 0 )
2159 dbus_mgr_handle_set_forwarders
2160 ( mgr, dbus, reply_expected, serial, path, member, interface, sender, msg );
2161 else
2162 if( strcmp(member, "GetForwarders") == 0 )
2164 if( *signature != '\0' )
2165 dbus_mgr_handle_get_forwarders
2166 ( dbus, reply_expected, serial, path, member, interface, sender, msg );
2167 else
2168 dbus_mgr_handle_list_forwarders
2169 ( dbus, reply_expected, serial, path, member, interface, sender, msg );
2170 }else
2171 if( reply_expected )
2173 sprintf(error_name, "InvalidOperation");
2174 sprintf(error_message, "Unrecognized path / interface / member");
2175 dbus_svc_send( dbus, ERROR, serial, &new_serial, sender, path, interface, member,
2176 TYPE_STRING, error_name, TYPE_STRING, error_message, TYPE_INVALID
2180 return HANDLED;
2183 static void
2184 dbus_mgr_read_watch_activated(isc_task_t *t, isc_event_t *ev)
2186 DBusMgrSocket *sfd = (DBusMgrSocket*)(ev->ev_arg);
2187 t = t;
2188 isc_mem_put(sfd->mgr->mctx, ev, ev->ev_size);
2189 dbus_mgr_log_dbg("watch %d READ",sfd->fd);
2190 isc_socket_fd_handle_reads( sfd->sock, sfd->ser );
2191 dbus_svc_handle_watch( sfd->mgr->dbus, sfd->fd, WATCH_ENABLE | WATCH_READ );
2194 static void
2195 dbus_mgr_write_watch_activated(isc_task_t *t, isc_event_t *ev)
2197 DBusMgrSocket *sfd = (DBusMgrSocket*)(ev->ev_arg);
2198 t = t;
2199 isc_mem_put(sfd->mgr->mctx, ev, ev->ev_size);
2200 dbus_mgr_log_dbg("watch %d WRITE",sfd->fd);
2201 isc_socket_fd_handle_writes( sfd->sock, sfd->ser );
2202 dbus_svc_handle_watch( sfd->mgr->dbus, sfd->fd, WATCH_ENABLE | WATCH_WRITE );
2205 static void
2206 dbus_mgr_watches_selected(isc_task_t *t, isc_event_t *ev)
2208 ns_dbus_mgr_t *mgr = (ns_dbus_mgr_t*)(ev->ev_arg);
2209 t = t;
2210 isc_mem_put(mgr->mctx, ev, ev->ev_size);
2211 if( ( mgr->dbus == 0L ) || (mgr->sockets == 0L))
2213 return;
2215 dbus_mgr_log_dbg("watches selected");
2216 dbus_svc_dispatch( mgr->dbus );
2217 dbus_mgr_log_dbg("dispatch complete");
2220 static int dbus_mgr_socket_comparator( const void *p1, const void *p2 )
2222 return( ( ((const DBusMgrSocket*)p1)->fd
2223 == ((const DBusMgrSocket*)p2)->fd
2224 ) ? 0
2225 : ( ((const DBusMgrSocket*)p1)->fd
2226 > ((const DBusMgrSocket*)p2)->fd
2227 ) ? 1
2228 : -1
2232 static void
2233 dbus_mgr_watch_handler( int fd, dbus_svc_WatchFlags flags, void *mgrp )
2235 ns_dbus_mgr_t *mgr = mgrp;
2236 DBusMgrSocket sockFd, *sfd=0L, *const*spp=0L;
2237 isc_result_t result=ISC_R_SUCCESS;
2238 isc_socketevent_t *sev;
2239 isc_event_t *pev[1];
2241 if(mgr == 0L)
2242 return;
2244 if( (flags & 7) == WATCH_ERROR )
2245 return;
2247 sockFd.fd = fd;
2249 dbus_mgr_log_dbg("watch handler: fd %d %d", fd, flags);
2251 if( ((spp = tfind( &sockFd, &(mgr->sockets), dbus_mgr_socket_comparator) ) == 0L )
2252 ||((sfd = *spp) == 0L )
2255 if( ( flags & WATCH_ENABLE ) == 0 )
2256 return;
2258 sfd = isc_mem_get(mgr->mctx, sizeof(DBusMgrSocket));
2259 if( sfd == 0L )
2261 dbus_mgr_log_err("dbus_mgr: out of memory" );
2262 return;
2264 sfd->fd = fd;
2265 sfd->mgr = mgr;
2266 sfd->ser = sfd->sew = sfd->sel = 0L;
2268 if( tsearch(sfd, &(mgr->sockets), dbus_mgr_socket_comparator) == 0L )
2270 dbus_mgr_log_err("dbus_mgr: out of memory" );
2271 isc_mem_put(mgr->mctx, sfd, sizeof(DBusMgrSocket));
2272 return;
2274 sfd->sock = 0L;
2275 result = isc_socket_create( mgr->socketmgr, fd, isc_sockettype_fd, &(sfd->sock) );
2276 if( result != ISC_R_SUCCESS )
2278 dbus_mgr_log_err("dbus_mgr: isc_socket_create failed: %s",
2279 isc_result_totext(result)
2281 tdelete(sfd, &(mgr->sockets), dbus_mgr_socket_comparator);
2282 isc_mem_put(mgr->mctx, sfd, sizeof(DBusMgrSocket));
2283 return;
2287 if( (flags & WATCH_ENABLE) == WATCH_ENABLE )
2289 if( (flags & WATCH_READ) == WATCH_READ )
2291 if( sfd->ser == 0L )
2293 sfd->ser = (isc_socketevent_t *)
2294 isc_event_allocate
2296 mgr->mctx, mgr->task,
2297 ISC_SOCKEVENT_READ_READY,
2298 dbus_mgr_read_watch_activated,
2299 sfd,
2300 sizeof(isc_socketevent_t)
2303 if( sfd->ser == 0L )
2305 dbus_mgr_log_err("dbus_mgr: out of memory" );
2306 tdelete(sfd, &(mgr->sockets), dbus_mgr_socket_comparator);
2307 isc_mem_put(mgr->mctx, sfd, sizeof(DBusMgrSocket));
2308 return;
2311 sev = isc_socket_fd_handle_reads(sfd->sock, sfd->ser );
2313 }else
2315 sev = isc_socket_fd_handle_reads(sfd->sock, sfd->ser );
2318 if( (flags & WATCH_WRITE) == WATCH_WRITE )
2320 if( sfd->sew == 0L )
2322 sfd->sew = (isc_socketevent_t *)
2323 isc_event_allocate
2325 mgr->mctx, mgr->task,
2326 ISC_SOCKEVENT_WRITE_READY,
2327 dbus_mgr_write_watch_activated,
2328 sfd,
2329 sizeof(isc_socketevent_t)
2331 if( sfd->sew == 0L )
2333 dbus_mgr_log_err("dbus_mgr: out of memory" );
2334 tdelete(sfd, &(mgr->sockets), dbus_mgr_socket_comparator);
2335 isc_mem_put(mgr->mctx, sfd, sizeof(DBusMgrSocket));
2336 return;
2339 sev = isc_socket_fd_handle_writes(sfd->sock, sfd->sew );
2341 }else
2343 sev = isc_socket_fd_handle_writes(sfd->sock, sfd->sew );
2346 if( (sfd->ser != 0L) || (sfd->sew != 0L) )
2348 if( sfd->sel == 0L )
2350 sfd->sel = (isc_socketevent_t *)
2351 isc_event_allocate
2353 mgr->mctx, mgr->task,
2354 ISC_SOCKEVENT_SELECTED,
2355 dbus_mgr_watches_selected,
2356 mgr,
2357 sizeof(isc_socketevent_t)
2359 if( sfd->sel == 0L )
2361 dbus_mgr_log_err("dbus_mgr: out of memory" );
2362 tdelete(sfd, &(mgr->sockets), dbus_mgr_socket_comparator);
2363 isc_mem_put(mgr->mctx, sfd, sizeof(DBusMgrSocket));
2364 return;
2367 sev = isc_socket_fd_handle_selected(sfd->sock, sfd->sel );
2369 }else
2371 sev = isc_socket_fd_handle_selected(sfd->sock, sfd->sel);
2374 }else
2376 dbus_mgr_log_dbg("watch %d disabled",fd);
2377 if(flags & WATCH_READ)
2379 sev = isc_socket_fd_handle_reads( sfd->sock, 0L );
2380 if( sev != 0L )
2382 pev[0]=(isc_event_t*)sev;
2383 isc_event_free(pev);
2385 sfd->ser = 0L;
2388 if( flags & WATCH_WRITE )
2390 sev = isc_socket_fd_handle_writes( sfd->sock, 0L );
2391 if( sev != 0L )
2393 pev[0]=(isc_event_t*)sev;
2394 isc_event_free(pev);
2396 sfd->sew = 0L;
2399 if( (sfd->ser == 0L) && (sfd->sew == 0L) )
2401 sev = isc_socket_fd_handle_selected( sfd->sock, 0L );
2402 if( sev != 0L )
2404 pev[0]=(isc_event_t*)sev;
2405 isc_event_free(pev);
2407 sfd->sel = 0L;
2409 tdelete(sfd, &(mgr->sockets), dbus_mgr_socket_comparator);
2411 isc_mem_put(mgr->mctx, sfd, sizeof(DBusMgrSocket));
2416 static
2417 void dbus_mgr_close_socket( const void *p, const VISIT which, const int level)
2419 DBusMgrSocket *const*spp=p, *sfd;
2420 isc_event_t *ev ;
2421 int i = level ? 0 :1;
2422 i &= i;
2424 if( (spp==0L) || ((sfd = *spp)==0L)
2425 ||((which != leaf) && (which != postorder))
2426 ) return;
2428 if( sfd->ser != 0L )
2430 ev = (isc_event_t *)isc_socket_fd_handle_reads(sfd->sock, 0);
2431 if( ev != 0L )
2432 isc_event_free((isc_event_t **)&ev);
2433 sfd->ser = 0L;
2436 if( sfd->sew != 0L )
2438 ev = (isc_event_t *)isc_socket_fd_handle_writes(sfd->sock, 0);
2439 if( ev != 0L )
2440 isc_event_free((isc_event_t **)&ev);
2441 sfd->sew = 0L;
2444 if( sfd->sel != 0L )
2446 ev = (isc_event_t *)isc_socket_fd_handle_selected(sfd->sock, 0);
2447 if( ev != 0L )
2448 isc_event_free((isc_event_t **)&ev);
2449 sfd->sel = 0L;
2450 dbus_mgr_log_dbg("CLOSED socket %d", sfd->fd);
2454 static
2455 void dbus_mgr_destroy_socket( void *p )
2457 DBusMgrSocket *sfd = p;
2459 isc_mem_put( sfd->mgr->mctx, sfd, sizeof(DBusMgrSocket) );