Merge branch 'dbus-1.4' rejecting commit 4ebb275ab7b6f71d5
[platform/upstream/dbus.git] / bus / services.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* services.c  Service management
3  *
4  * Copyright (C) 2003  Red Hat, Inc.
5  * Copyright (C) 2003  CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  * 
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  * 
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #include <config.h>
26 #include <dbus/dbus-hash.h>
27 #include <dbus/dbus-list.h>
28 #include <dbus/dbus-mempool.h>
29 #include <dbus/dbus-marshal-validate.h>
30
31 #include "driver.h"
32 #include "services.h"
33 #include "connection.h"
34 #include "utils.h"
35 #include "activation.h"
36 #include "policy.h"
37 #include "bus.h"
38 #include "selinux.h"
39
40 struct BusService
41 {
42   int refcount;
43
44   BusRegistry *registry;
45   char *name;
46   DBusList *owners;
47 };
48
49 struct BusOwner
50 {
51   int refcount;
52
53   BusService *service;
54   DBusConnection *conn;
55
56   unsigned int allow_replacement : 1;
57   unsigned int do_not_queue : 1;
58 };
59
60 struct BusRegistry
61 {
62   int refcount;
63
64   BusContext *context;
65   
66   DBusHashTable *service_hash;
67   DBusMemPool   *service_pool;
68   DBusMemPool   *owner_pool;
69
70   DBusHashTable *service_sid_table;
71 };
72
73 BusRegistry*
74 bus_registry_new (BusContext *context)
75 {
76   BusRegistry *registry;
77
78   registry = dbus_new0 (BusRegistry, 1);
79   if (registry == NULL)
80     return NULL;
81
82   registry->refcount = 1;
83   registry->context = context;
84   
85   registry->service_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
86                                                  NULL, NULL);
87   if (registry->service_hash == NULL)
88     goto failed;
89   
90   registry->service_pool = _dbus_mem_pool_new (sizeof (BusService),
91                                                TRUE);
92
93   if (registry->service_pool == NULL)
94     goto failed;
95
96   registry->owner_pool = _dbus_mem_pool_new (sizeof (BusOwner),
97                                              TRUE);
98
99   if (registry->owner_pool == NULL)
100     goto failed;
101
102   registry->service_sid_table = NULL;
103   
104   return registry;
105
106  failed:
107   bus_registry_unref (registry);
108   return NULL;
109 }
110
111 BusRegistry *
112 bus_registry_ref (BusRegistry *registry)
113 {
114   _dbus_assert (registry->refcount > 0);
115   registry->refcount += 1;
116
117   return registry;
118 }
119
120 void
121 bus_registry_unref  (BusRegistry *registry)
122 {
123   _dbus_assert (registry->refcount > 0);
124   registry->refcount -= 1;
125
126   if (registry->refcount == 0)
127     {
128       if (registry->service_hash)
129         _dbus_hash_table_unref (registry->service_hash);
130       if (registry->service_pool)
131         _dbus_mem_pool_free (registry->service_pool);
132       if (registry->owner_pool)
133         _dbus_mem_pool_free (registry->owner_pool);
134       if (registry->service_sid_table)
135         _dbus_hash_table_unref (registry->service_sid_table);
136       
137       dbus_free (registry);
138     }
139 }
140
141 BusService*
142 bus_registry_lookup (BusRegistry      *registry,
143                      const DBusString *service_name)
144 {
145   BusService *service;
146
147   service = _dbus_hash_table_lookup_string (registry->service_hash,
148                                             _dbus_string_get_const_data (service_name));
149
150   return service;
151 }
152
153 static DBusList *
154 _bus_service_find_owner_link (BusService *service,
155                               DBusConnection *connection)
156 {
157   DBusList *link;
158   
159   link = _dbus_list_get_first_link (&service->owners);
160
161   while (link != NULL)
162     {
163       BusOwner *bus_owner;
164
165       bus_owner = (BusOwner *) link->data;
166       if (bus_owner->conn == connection) 
167         break;
168
169       link = _dbus_list_get_next_link (&service->owners, link);
170     }
171
172   return link;
173 }
174
175 static void
176 bus_owner_set_flags (BusOwner *owner,
177                      dbus_uint32_t flags)
178 {
179    owner->allow_replacement = 
180         (flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT) != FALSE;
181
182    owner->do_not_queue =
183         (flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) != FALSE;
184 }
185
186 static BusOwner *
187 bus_owner_new (BusService *service, 
188                DBusConnection *conn, 
189                dbus_uint32_t flags)
190 {
191   BusOwner *result;
192
193   result = _dbus_mem_pool_alloc (service->registry->owner_pool);
194   if (result != NULL)
195     {
196       result->refcount = 1;
197       /* don't ref the connection because we don't want
198          to block the connection from going away.
199          transactions take care of reffing the connection
200          but we need to use refcounting on the owner
201          so that the owner does not get freed before
202          we can deref the connection in the transaction
203        */
204       result->conn = conn;
205       result->service = service;
206
207       if (!bus_connection_add_owned_service (conn, service))
208         {
209           _dbus_mem_pool_dealloc (service->registry->owner_pool, result);
210           return NULL;
211         }
212         
213       bus_owner_set_flags (result, flags);
214     }
215   return result;
216 }
217
218 static BusOwner *
219 bus_owner_ref (BusOwner *owner)
220 {
221   _dbus_assert (owner->refcount > 0);
222   owner->refcount += 1;
223
224   return owner;
225 }
226
227 static void
228 bus_owner_unref  (BusOwner *owner)
229 {
230   _dbus_assert (owner->refcount > 0);
231   owner->refcount -= 1;
232
233   if (owner->refcount == 0)
234     {
235       bus_connection_remove_owned_service (owner->conn, owner->service);
236       _dbus_mem_pool_dealloc (owner->service->registry->owner_pool, owner);
237     }
238 }
239
240 BusService*
241 bus_registry_ensure (BusRegistry               *registry,
242                      const DBusString          *service_name,
243                      DBusConnection            *owner_connection_if_created,
244                      dbus_uint32_t              flags,
245                      BusTransaction            *transaction,
246                      DBusError                 *error)
247 {
248   BusService *service;
249
250   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
251   
252   _dbus_assert (owner_connection_if_created != NULL);
253   _dbus_assert (transaction != NULL);
254
255   service = _dbus_hash_table_lookup_string (registry->service_hash,
256                                             _dbus_string_get_const_data (service_name));
257   if (service != NULL)
258     return service;
259   
260   service = _dbus_mem_pool_alloc (registry->service_pool);
261   if (service == NULL)
262     {
263       BUS_SET_OOM (error);
264       return NULL;
265     }
266
267   service->registry = registry;  
268   service->refcount = 1;
269
270   _dbus_verbose ("copying string %p '%s' to service->name\n",
271                  service_name, _dbus_string_get_const_data (service_name));
272   if (!_dbus_string_copy_data (service_name, &service->name))
273     {
274       _dbus_mem_pool_dealloc (registry->service_pool, service);
275       BUS_SET_OOM (error);
276       return NULL;
277     }
278   _dbus_verbose ("copied string %p '%s' to '%s'\n",
279                  service_name, _dbus_string_get_const_data (service_name),
280                  service->name);
281
282   if (!bus_driver_send_service_owner_changed (service->name, 
283                                               NULL,
284                                               bus_connection_get_name (owner_connection_if_created),
285                                               transaction, error))
286     {
287       bus_service_unref (service);
288       return NULL;
289     }
290
291   if (!bus_activation_service_created (bus_context_get_activation (registry->context),
292                                        service->name, transaction, error))
293     {
294       bus_service_unref (service);
295       return NULL;
296     }
297   
298   if (!bus_service_add_owner (service, owner_connection_if_created, flags,
299                                               transaction, error))
300     {
301       bus_service_unref (service);
302       return NULL;
303     }
304   
305   if (!_dbus_hash_table_insert_string (registry->service_hash,
306                                        service->name,
307                                        service))
308     {
309       /* The add_owner gets reverted on transaction cancel */
310       BUS_SET_OOM (error);
311       return NULL;
312     }
313   
314   return service;
315 }
316
317 void
318 bus_registry_foreach (BusRegistry               *registry,
319                       BusServiceForeachFunction  function,
320                       void                      *data)
321 {
322   DBusHashIter iter;
323   
324   _dbus_hash_iter_init (registry->service_hash, &iter);
325   while (_dbus_hash_iter_next (&iter))
326     {
327       BusService *service = _dbus_hash_iter_get_value (&iter);
328
329       (* function) (service, data);
330     }
331 }
332
333 dbus_bool_t
334 bus_registry_list_services (BusRegistry *registry,
335                             char      ***listp,
336                             int         *array_len)
337 {
338   int i, j, len;
339   char **retval;
340   DBusHashIter iter;
341    
342   len = _dbus_hash_table_get_n_entries (registry->service_hash);
343   retval = dbus_new (char *, len + 1);
344
345   if (retval == NULL)
346     return FALSE;
347
348   _dbus_hash_iter_init (registry->service_hash, &iter);
349   i = 0;
350   while (_dbus_hash_iter_next (&iter))
351     {
352       BusService *service = _dbus_hash_iter_get_value (&iter);
353
354       retval[i] = _dbus_strdup (service->name);
355       if (retval[i] == NULL)
356         goto error;
357
358       i++;
359     }
360
361   retval[i] = NULL;
362   
363   if (array_len)
364     *array_len = len;
365   
366   *listp = retval;
367   return TRUE;
368   
369  error:
370   for (j = 0; j < i; j++)
371     dbus_free (retval[i]);
372   dbus_free (retval);
373
374   return FALSE;
375 }
376
377 dbus_bool_t
378 bus_registry_acquire_service (BusRegistry      *registry,
379                               DBusConnection   *connection,
380                               const DBusString *service_name,
381                               dbus_uint32_t     flags,
382                               dbus_uint32_t    *result,
383                               BusTransaction   *transaction,
384                               DBusError        *error)
385 {
386   dbus_bool_t retval;
387   DBusConnection *old_owner_conn;
388   BusClientPolicy *policy;
389   BusService *service;
390   BusActivation  *activation;
391   BusSELinuxID *sid;
392   BusOwner *primary_owner;
393  
394   retval = FALSE;
395
396   if (!_dbus_validate_bus_name (service_name, 0,
397                                 _dbus_string_get_length (service_name)))
398     {
399       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
400                       "Requested bus name \"%s\" is not valid",
401                       _dbus_string_get_const_data (service_name));
402       
403       _dbus_verbose ("Attempt to acquire invalid service name\n");
404       
405       goto out;
406     }
407   
408   if (_dbus_string_get_byte (service_name, 0) == ':')
409     {
410       /* Not allowed; only base services can start with ':' */
411       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
412                       "Cannot acquire a service starting with ':' such as \"%s\"",
413                       _dbus_string_get_const_data (service_name));
414       
415       _dbus_verbose ("Attempt to acquire invalid base service name \"%s\"",
416                      _dbus_string_get_const_data (service_name));
417       
418       goto out;
419     }
420
421   if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
422     {
423       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
424                       "Connection \"%s\" is not allowed to own the service \"%s\"because "
425                       "it is reserved for D-Bus' use only",
426                       bus_connection_is_active (connection) ?
427                       bus_connection_get_name (connection) :
428                       "(inactive)",
429                       DBUS_SERVICE_DBUS);
430       goto out;
431     }
432
433   policy = bus_connection_get_policy (connection);
434   _dbus_assert (policy != NULL);
435
436   /* Note that if sid is #NULL then the bus's own context gets used
437    * in bus_connection_selinux_allows_acquire_service()
438    */
439   sid = bus_selinux_id_table_lookup (registry->service_sid_table,
440                                      service_name);
441
442   if (!bus_selinux_allows_acquire_service (connection, sid,
443                                            _dbus_string_get_const_data (service_name), error))
444     {
445
446       if (dbus_error_is_set (error) &&
447           dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY))
448         {
449           goto out;
450         }
451
452       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
453                       "Connection \"%s\" is not allowed to own the service \"%s\" due "
454                       "to SELinux policy",
455                       bus_connection_is_active (connection) ?
456                       bus_connection_get_name (connection) :
457                       "(inactive)",
458                       _dbus_string_get_const_data (service_name));
459       goto out;
460     }
461   
462   if (!bus_client_policy_check_can_own (policy, connection,
463                                         service_name))
464     {
465       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
466                       "Connection \"%s\" is not allowed to own the service \"%s\" due "
467                       "to security policies in the configuration file",
468                       bus_connection_is_active (connection) ?
469                       bus_connection_get_name (connection) :
470                       "(inactive)",
471                       _dbus_string_get_const_data (service_name));
472       goto out;
473     }
474
475   if (bus_connection_get_n_services_owned (connection) >=
476       bus_context_get_max_services_per_connection (registry->context))
477     {
478       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
479                       "Connection \"%s\" is not allowed to own more services "
480                       "(increase limits in configuration file if required)",
481                       bus_connection_is_active (connection) ?
482                       bus_connection_get_name (connection) :
483                       "(inactive)");
484       goto out;
485     }
486   
487   service = bus_registry_lookup (registry, service_name);
488
489   if (service != NULL)
490     {
491       primary_owner = bus_service_get_primary_owner (service);
492       if (primary_owner != NULL)
493         old_owner_conn = primary_owner->conn;
494       else
495         old_owner_conn = NULL;
496     }
497   else
498     old_owner_conn = NULL;
499       
500   if (service == NULL)
501     {
502       service = bus_registry_ensure (registry,
503                                      service_name, connection, flags,
504                                      transaction, error);
505       if (service == NULL)
506         goto out;
507     }
508
509   primary_owner = bus_service_get_primary_owner (service);
510   if (primary_owner == NULL)
511     goto out;
512
513   if (old_owner_conn == NULL)
514     {
515       _dbus_assert (primary_owner->conn == connection);
516
517       *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;      
518     }
519   else if (old_owner_conn == connection)
520     {
521       bus_owner_set_flags (primary_owner, flags);
522       *result = DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
523     }
524   else if (((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
525            !(bus_service_get_allow_replacement (service))) ||
526            ((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
527            !(flags & DBUS_NAME_FLAG_REPLACE_EXISTING))) 
528     {
529       DBusList *link;
530       BusOwner *temp_owner;
531     /* Since we can't be queued if we are already in the queue
532        remove us */
533
534       link = _bus_service_find_owner_link (service, connection);
535       if (link != NULL)
536         {
537           _dbus_list_unlink (&service->owners, link);
538           temp_owner = (BusOwner *)link->data;
539           bus_owner_unref (temp_owner); 
540           _dbus_list_free_link (link);
541         }
542       
543       *result = DBUS_REQUEST_NAME_REPLY_EXISTS;
544     }
545   else if (!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
546            (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) ||
547             !(bus_service_get_allow_replacement (service))))
548     {
549       /* Queue the connection */
550       if (!bus_service_add_owner (service, connection, 
551                                   flags,
552                                   transaction, error))
553         goto out;
554       
555       *result = DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
556     }
557   else
558     {
559       /* Replace the current owner */
560
561       /* We enqueue the new owner and remove the first one because
562        * that will cause NameAcquired and NameLost messages to
563        * be sent.
564        */
565       
566       if (!bus_service_add_owner (service, connection,
567                                   flags,
568                                   transaction, error))
569         goto out;
570
571       if (primary_owner->do_not_queue)
572         {
573           if (!bus_service_remove_owner (service, old_owner_conn,
574                                          transaction, error))
575             goto out;
576         }
577       else
578         {
579           if (!bus_service_swap_owner (service, old_owner_conn,
580                                        transaction, error))
581             goto out;
582         }
583         
584     
585       _dbus_assert (connection == bus_service_get_primary_owner (service)->conn);
586       *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
587     }
588
589   activation = bus_context_get_activation (registry->context);
590   retval = bus_activation_send_pending_auto_activation_messages (activation,
591                                                                  service,
592                                                                  transaction,
593                                                                  error);
594   
595  out:
596   return retval;
597 }
598
599 dbus_bool_t
600 bus_registry_release_service (BusRegistry      *registry,
601                               DBusConnection   *connection,
602                               const DBusString *service_name,
603                               dbus_uint32_t    *result,
604                               BusTransaction   *transaction,
605                               DBusError        *error)
606 {
607   dbus_bool_t retval;
608   BusService *service;
609
610   retval = FALSE;
611
612   if (!_dbus_validate_bus_name (service_name, 0,
613                                 _dbus_string_get_length (service_name)))
614     {
615       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
616                       "Given bus name \"%s\" is not valid",
617                       _dbus_string_get_const_data (service_name));
618
619       _dbus_verbose ("Attempt to release invalid service name\n");
620
621       goto out;
622     }
623
624   if (_dbus_string_get_byte (service_name, 0) == ':')
625     {
626       /* Not allowed; the base service name cannot be created or released */
627       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
628                       "Cannot release a service starting with ':' such as \"%s\"",
629                       _dbus_string_get_const_data (service_name));
630
631       _dbus_verbose ("Attempt to release invalid base service name \"%s\"",
632                      _dbus_string_get_const_data (service_name));
633
634       goto out;
635     }
636
637    if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
638     {
639       /* Not allowed; the base service name cannot be created or released */
640       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
641                       "Cannot release the %s service because it is owned by the bus",
642                      DBUS_SERVICE_DBUS);
643
644       _dbus_verbose ("Attempt to release service name \"%s\"",
645                      DBUS_SERVICE_DBUS);
646
647       goto out;
648     }
649
650   service = bus_registry_lookup (registry, service_name);
651
652   if (service == NULL)
653     {
654       *result = DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
655     }
656   else if (!bus_service_has_owner (service, connection))
657     {
658       *result = DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
659     }
660   else
661     {
662       if (!bus_service_remove_owner (service, connection,
663                                      transaction, error))
664         goto out;
665
666       _dbus_assert (!bus_service_has_owner (service, connection));
667       *result = DBUS_RELEASE_NAME_REPLY_RELEASED;
668     }
669
670   retval = TRUE;
671
672  out:
673   return retval;
674 }
675
676 dbus_bool_t
677 bus_registry_set_service_context_table (BusRegistry   *registry,
678                                         DBusHashTable *table)
679 {
680   DBusHashTable *new_table;
681   DBusHashIter iter;
682   
683   new_table = bus_selinux_id_table_new ();
684   if (!new_table)
685     return FALSE;
686
687   _dbus_hash_iter_init (table, &iter);
688   while (_dbus_hash_iter_next (&iter))
689     {
690       const char *service = _dbus_hash_iter_get_string_key (&iter);
691       const char *context = _dbus_hash_iter_get_value (&iter);
692
693       if (!bus_selinux_id_table_insert (new_table,
694                                         service,
695                                         context))
696         return FALSE;
697     }
698   
699   if (registry->service_sid_table)
700     _dbus_hash_table_unref (registry->service_sid_table);
701   registry->service_sid_table = new_table;
702   return TRUE;
703 }
704
705 static void
706 bus_service_unlink_owner (BusService      *service,
707                           BusOwner        *owner)
708 {
709   _dbus_list_remove_last (&service->owners, owner);
710   bus_owner_unref (owner);
711 }
712
713 static void
714 bus_service_unlink (BusService *service)
715 {
716   _dbus_assert (service->owners == NULL);
717
718   /* the service may not be in the hash, if
719    * the failure causing transaction cancel
720    * was in the right place, but that's OK
721    */
722   _dbus_hash_table_remove_string (service->registry->service_hash,
723                                   service->name);
724   
725   bus_service_unref (service);
726 }
727
728 static void
729 bus_service_relink (BusService           *service,
730                     DBusPreallocatedHash *preallocated)
731 {
732   _dbus_assert (service->owners == NULL);
733   _dbus_assert (preallocated != NULL);
734
735   _dbus_hash_table_insert_string_preallocated (service->registry->service_hash,
736                                                preallocated,
737                                                service->name,
738                                                service);
739   
740   bus_service_ref (service);
741 }
742
743 /**
744  * Data used to represent an ownership cancellation in
745  * a bus transaction.
746  */
747 typedef struct
748 {
749   BusOwner *owner;            /**< the owner */
750   BusService *service;        /**< service to cancel ownership of */
751 } OwnershipCancelData;
752
753 static void
754 cancel_ownership (void *data)
755 {
756   OwnershipCancelData *d = data;
757
758   /* We don't need to send messages notifying of these
759    * changes, since we're reverting something that was
760    * cancelled (effectively never really happened)
761    */
762   bus_service_unlink_owner (d->service, d->owner);
763   
764   if (d->service->owners == NULL)
765     bus_service_unlink (d->service);
766 }
767
768 static void
769 free_ownership_cancel_data (void *data)
770 {
771   OwnershipCancelData *d = data;
772
773   dbus_connection_unref (d->owner->conn);
774   bus_owner_unref (d->owner);
775   bus_service_unref (d->service);
776   
777   dbus_free (d);
778 }
779
780 static dbus_bool_t
781 add_cancel_ownership_to_transaction (BusTransaction *transaction,
782                                      BusService     *service,
783                                      BusOwner       *owner)
784 {
785   OwnershipCancelData *d;
786
787   d = dbus_new (OwnershipCancelData, 1);
788   if (d == NULL)
789     return FALSE;
790   
791   d->service = service;
792   d->owner = owner;
793
794   if (!bus_transaction_add_cancel_hook (transaction, cancel_ownership, d,
795                                         free_ownership_cancel_data))
796     {
797       dbus_free (d);
798       return FALSE;
799     }
800
801   bus_service_ref (d->service);
802   bus_owner_ref (owner);
803   dbus_connection_ref (d->owner->conn);
804  
805   return TRUE;
806 }
807
808 /* this function is self-cancelling if you cancel the transaction */
809 dbus_bool_t
810 bus_service_add_owner (BusService     *service,
811                        DBusConnection *connection,
812                        dbus_uint32_t  flags,
813                        BusTransaction *transaction,
814                        DBusError      *error)
815 {
816   BusOwner *bus_owner;
817   DBusList *bus_owner_link;
818   
819   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
820   
821  /* Send service acquired message first, OOM will result
822   * in cancelling the transaction
823   */
824   if (service->owners == NULL)
825     {
826       if (!bus_driver_send_service_acquired (connection, service->name, transaction, error))
827         return FALSE;
828     }
829   
830   bus_owner_link = _bus_service_find_owner_link (service, connection);
831   
832   if (bus_owner_link == NULL)
833     {
834       bus_owner = bus_owner_new (service, connection, flags);
835       if (bus_owner == NULL)
836         {
837           BUS_SET_OOM (error);
838           return FALSE;
839         }
840
841       bus_owner_set_flags (bus_owner, flags);
842       if (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) || service->owners == NULL)
843         {
844           if (!_dbus_list_append (&service->owners,
845                                   bus_owner))
846             {
847               bus_owner_unref (bus_owner);
848               BUS_SET_OOM (error);
849               return FALSE;
850             }
851         }
852       else
853         {
854           if (!_dbus_list_insert_after (&service->owners,
855                                          _dbus_list_get_first_link (&service->owners),
856                                          bus_owner))
857             {
858               bus_owner_unref (bus_owner);
859               BUS_SET_OOM (error);
860               return FALSE;
861             }
862         }      
863     } 
864   else 
865     {
866       /* Update the link since we are already in the queue
867        * No need for operations that can produce OOM
868        */
869
870       bus_owner = (BusOwner *) bus_owner_link->data;
871       if (flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
872         {
873           DBusList *link;
874           _dbus_list_unlink (&service->owners, bus_owner_link);
875           link = _dbus_list_get_first_link (&service->owners);
876           _dbus_assert (link != NULL);
877           
878           _dbus_list_insert_after_link (&service->owners, link, bus_owner_link);
879         }
880       
881       bus_owner_set_flags (bus_owner, flags);
882       return TRUE;
883     }
884
885   if (!add_cancel_ownership_to_transaction (transaction,
886                                             service,
887                                             bus_owner))
888     {
889       bus_service_unlink_owner (service, bus_owner);
890       BUS_SET_OOM (error);
891       return FALSE;
892     }
893
894   return TRUE;
895 }
896
897 typedef struct
898 {
899   BusOwner       *owner;
900   BusService     *service;
901   BusOwner       *before_owner; /* restore to position before this connection in owners list */
902   DBusList       *owner_link;
903   DBusList       *service_link;
904   DBusPreallocatedHash *hash_entry;
905 } OwnershipRestoreData;
906
907 static void
908 restore_ownership (void *data)
909 {
910   OwnershipRestoreData *d = data;
911   DBusList *link;
912
913   _dbus_assert (d->service_link != NULL);
914   _dbus_assert (d->owner_link != NULL);
915   
916   if (d->service->owners == NULL)
917     {
918       _dbus_assert (d->hash_entry != NULL);
919       bus_service_relink (d->service, d->hash_entry);
920     }
921   else
922     {
923       _dbus_assert (d->hash_entry == NULL);
924     }
925   
926   /* We don't need to send messages notifying of these
927    * changes, since we're reverting something that was
928    * cancelled (effectively never really happened)
929    */
930   link = _dbus_list_get_first_link (&d->service->owners);
931   while (link != NULL)
932     {
933       if (link->data == d->before_owner)
934         break;
935
936       link = _dbus_list_get_next_link (&d->service->owners, link);
937     }
938   
939   _dbus_list_insert_before_link (&d->service->owners, link, d->owner_link);
940
941   /* Note that removing then restoring this changes the order in which
942    * ServiceDeleted messages are sent on destruction of the
943    * connection.  This should be OK as the only guarantee there is
944    * that the base service is destroyed last, and we never even
945    * tentatively remove the base service.
946    */
947   bus_connection_add_owned_service_link (d->owner->conn, d->service_link);
948   
949   d->hash_entry = NULL;
950   d->service_link = NULL;
951   d->owner_link = NULL;
952 }
953
954 static void
955 free_ownership_restore_data (void *data)
956 {
957   OwnershipRestoreData *d = data;
958
959   if (d->service_link)
960     _dbus_list_free_link (d->service_link);
961   if (d->owner_link)
962     _dbus_list_free_link (d->owner_link);
963   if (d->hash_entry)
964     _dbus_hash_table_free_preallocated_entry (d->service->registry->service_hash,
965                                               d->hash_entry);
966
967   dbus_connection_unref (d->owner->conn);
968   bus_owner_unref (d->owner);
969   bus_service_unref (d->service);
970   
971   dbus_free (d);
972 }
973
974 static dbus_bool_t
975 add_restore_ownership_to_transaction (BusTransaction *transaction,
976                                       BusService     *service,
977                                       BusOwner       *owner)
978 {
979   OwnershipRestoreData *d;
980   DBusList *link;
981
982   d = dbus_new (OwnershipRestoreData, 1);
983   if (d == NULL)
984     return FALSE;
985   
986   d->service = service;
987   d->owner = owner;
988   d->service_link = _dbus_list_alloc_link (service);
989   d->owner_link = _dbus_list_alloc_link (owner);
990   d->hash_entry = _dbus_hash_table_preallocate_entry (service->registry->service_hash);
991   
992   bus_service_ref (d->service);
993   bus_owner_ref (d->owner);
994   dbus_connection_ref (d->owner->conn);
995
996   d->before_owner = NULL;
997   link = _dbus_list_get_first_link (&service->owners);
998   while (link != NULL)
999     {
1000       if (link->data == owner)
1001         {
1002           link = _dbus_list_get_next_link (&service->owners, link);
1003
1004           if (link)
1005             d->before_owner = link->data;
1006
1007           break;
1008         }
1009       
1010       link = _dbus_list_get_next_link (&service->owners, link);
1011     }
1012   
1013   if (d->service_link == NULL ||
1014       d->owner_link == NULL ||
1015       d->hash_entry == NULL ||
1016       !bus_transaction_add_cancel_hook (transaction, restore_ownership, d,
1017                                         free_ownership_restore_data))
1018     {
1019       free_ownership_restore_data (d);
1020       return FALSE;
1021     }
1022   
1023   return TRUE;
1024 }
1025
1026 dbus_bool_t
1027 bus_service_swap_owner (BusService     *service,
1028                         DBusConnection *connection,
1029                         BusTransaction *transaction,
1030                         DBusError      *error)
1031 {
1032   DBusList *swap_link;
1033   BusOwner *primary_owner;
1034
1035   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1036
1037   /* We send out notifications before we do any work we
1038    * might have to undo if the notification-sending failed
1039    */
1040   
1041   /* Send service lost message */
1042   primary_owner = bus_service_get_primary_owner (service);
1043   if (primary_owner == NULL || primary_owner->conn != connection)
1044     _dbus_assert_not_reached ("Tried to swap a non primary owner");
1045
1046     
1047   if (!bus_driver_send_service_lost (connection, service->name,
1048                                      transaction, error))
1049     return FALSE;
1050
1051   if (service->owners == NULL)
1052     {
1053       _dbus_assert_not_reached ("Tried to swap owner of a service that has no owners");
1054     }
1055   else if (_dbus_list_length_is_one (&service->owners))
1056     {
1057       _dbus_assert_not_reached ("Tried to swap owner of a service that has no other owners in the queue");
1058     }
1059   else
1060     {
1061       DBusList *link;
1062       BusOwner *new_owner;
1063       DBusConnection *new_owner_conn;
1064       link = _dbus_list_get_first_link (&service->owners);
1065       _dbus_assert (link != NULL);
1066       link = _dbus_list_get_next_link (&service->owners, link);
1067       _dbus_assert (link != NULL);
1068
1069       new_owner = (BusOwner *)link->data;
1070       new_owner_conn = new_owner->conn;
1071
1072       if (!bus_driver_send_service_owner_changed (service->name,
1073                                                   bus_connection_get_name (connection),
1074                                                   bus_connection_get_name (new_owner_conn),
1075                                                   transaction, error))
1076         return FALSE;
1077
1078       /* This will be our new owner */
1079       if (!bus_driver_send_service_acquired (new_owner_conn,
1080                                              service->name,
1081                                              transaction,
1082                                              error))
1083         return FALSE;
1084     }
1085
1086   if (!add_restore_ownership_to_transaction (transaction, service, primary_owner))
1087     {
1088       BUS_SET_OOM (error);
1089       return FALSE;
1090     }
1091
1092   /* unlink the primary and make it the second link */
1093   swap_link = _dbus_list_get_first_link (&service->owners);
1094   _dbus_list_unlink (&service->owners, swap_link);
1095
1096   _dbus_list_insert_after_link (&service->owners,
1097                                 _dbus_list_get_first_link (&service->owners),
1098                                 swap_link);
1099
1100   return TRUE;
1101 }
1102
1103 /* this function is self-cancelling if you cancel the transaction */
1104 dbus_bool_t
1105 bus_service_remove_owner (BusService     *service,
1106                           DBusConnection *connection,
1107                           BusTransaction *transaction,
1108                           DBusError      *error)
1109 {
1110   BusOwner *primary_owner;
1111   
1112   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1113   
1114   /* We send out notifications before we do any work we
1115    * might have to undo if the notification-sending failed
1116    */
1117   
1118   /* Send service lost message */
1119   primary_owner = bus_service_get_primary_owner (service);
1120   if (primary_owner != NULL && primary_owner->conn == connection)
1121     {
1122       if (!bus_driver_send_service_lost (connection, service->name,
1123                                          transaction, error))
1124         return FALSE;
1125     }
1126   else
1127     {
1128       /* if we are not the primary owner then just remove us from the queue */
1129       DBusList *link;
1130       BusOwner *temp_owner;
1131
1132       link = _bus_service_find_owner_link (service, connection);
1133       _dbus_list_unlink (&service->owners, link);
1134       temp_owner = (BusOwner *)link->data;
1135       bus_owner_unref (temp_owner); 
1136       _dbus_list_free_link (link);
1137
1138       return TRUE; 
1139     }
1140
1141   if (service->owners == NULL)
1142     {
1143       _dbus_assert_not_reached ("Tried to remove owner of a service that has no owners");
1144     }
1145   else if (_dbus_list_length_is_one (&service->owners))
1146     {
1147       if (!bus_driver_send_service_owner_changed (service->name,
1148                                                   bus_connection_get_name (connection),
1149                                                   NULL,
1150                                                   transaction, error))
1151         return FALSE;
1152     }
1153   else
1154     {
1155       DBusList *link;
1156       BusOwner *new_owner;
1157       DBusConnection *new_owner_conn;
1158       link = _dbus_list_get_first_link (&service->owners);
1159       _dbus_assert (link != NULL);
1160       link = _dbus_list_get_next_link (&service->owners, link);
1161       _dbus_assert (link != NULL);
1162
1163       new_owner = (BusOwner *)link->data;
1164       new_owner_conn = new_owner->conn;
1165
1166       if (!bus_driver_send_service_owner_changed (service->name,
1167                                                   bus_connection_get_name (connection),
1168                                                   bus_connection_get_name (new_owner_conn),
1169                                                   transaction, error))
1170         return FALSE;
1171
1172       /* This will be our new owner */
1173       if (!bus_driver_send_service_acquired (new_owner_conn,
1174                                              service->name,
1175                                              transaction,
1176                                              error))
1177         return FALSE;
1178     }
1179
1180   if (!add_restore_ownership_to_transaction (transaction, service, primary_owner))
1181     {
1182       BUS_SET_OOM (error);
1183       return FALSE;
1184     }
1185  
1186   bus_service_unlink_owner (service, primary_owner);
1187
1188   if (service->owners == NULL)
1189     bus_service_unlink (service);
1190
1191   return TRUE;
1192 }
1193
1194 BusService *
1195 bus_service_ref (BusService *service)
1196 {
1197   _dbus_assert (service->refcount > 0);
1198   
1199   service->refcount += 1;
1200
1201   return service;
1202 }
1203
1204 void
1205 bus_service_unref (BusService *service)
1206 {
1207   _dbus_assert (service->refcount > 0);
1208   
1209   service->refcount -= 1;
1210
1211   if (service->refcount == 0)
1212     {
1213       _dbus_assert (service->owners == NULL);
1214       
1215       dbus_free (service->name);
1216       _dbus_mem_pool_dealloc (service->registry->service_pool, service);
1217     }
1218 }
1219
1220 DBusConnection *
1221 bus_service_get_primary_owners_connection (BusService *service)
1222 {
1223   BusOwner *owner;
1224
1225   owner = bus_service_get_primary_owner (service);
1226
1227   if (owner != NULL)
1228     return owner->conn;
1229   else
1230     return NULL;
1231 }
1232
1233 BusOwner*
1234 bus_service_get_primary_owner (BusService *service)
1235 {
1236   return _dbus_list_get_first (&service->owners);
1237 }
1238
1239 const char*
1240 bus_service_get_name (BusService *service)
1241 {
1242   return service->name;
1243 }
1244
1245 dbus_bool_t
1246 bus_service_get_allow_replacement (BusService *service)
1247 {
1248   BusOwner *owner;
1249   DBusList *link;
1250  
1251   _dbus_assert (service->owners != NULL);
1252
1253   link = _dbus_list_get_first_link (&service->owners);
1254   owner = (BusOwner *) link->data;
1255
1256   return owner->allow_replacement;
1257 }
1258
1259 dbus_bool_t
1260 bus_service_has_owner (BusService     *service,
1261                        DBusConnection *connection)
1262 {
1263   DBusList *link;
1264
1265   link = _bus_service_find_owner_link (service, connection);
1266  
1267   if (link == NULL)
1268     return FALSE;
1269   else
1270     return TRUE;
1271 }
1272
1273 dbus_bool_t 
1274 bus_service_list_queued_owners (BusService *service,
1275                                 DBusList  **return_list,
1276                                 DBusError  *error)
1277 {
1278   DBusList *link;
1279
1280   _dbus_assert (*return_list == NULL);
1281
1282   link = _dbus_list_get_first_link (&service->owners);
1283   _dbus_assert (link != NULL);
1284   
1285   while (link != NULL)
1286     {
1287       BusOwner *owner;
1288       const char *uname;
1289
1290       owner = (BusOwner *) link->data;
1291       uname = bus_connection_get_name (owner->conn);
1292
1293       if (!_dbus_list_append (return_list, (char *)uname))
1294         goto oom;
1295
1296       link = _dbus_list_get_next_link (&service->owners, link);
1297     }
1298   
1299   return TRUE;
1300   
1301  oom:
1302   _dbus_list_clear (return_list);
1303   BUS_SET_OOM (error);
1304   return FALSE;
1305 }