2003-09-06 Havoc Pennington <hp@pobox.com>
[platform/upstream/dbus.git] / bus / config-parser.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* config-parser.c  XML-library-agnostic configuration file parser
3  *
4  * Copyright (C) 2003 Red Hat, Inc.
5  *
6  * Licensed under the Academic Free License version 1.2
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23 #include "config-parser.h"
24 #include "test.h"
25 #include "utils.h"
26 #include "policy.h"
27 #include <dbus/dbus-list.h>
28 #include <dbus/dbus-internals.h>
29 #include <string.h>
30
31 typedef enum
32 {
33   ELEMENT_NONE,
34   ELEMENT_BUSCONFIG,
35   ELEMENT_INCLUDE,
36   ELEMENT_USER,
37   ELEMENT_LISTEN,
38   ELEMENT_AUTH,
39   ELEMENT_POLICY,
40   ELEMENT_LIMIT,
41   ELEMENT_ALLOW,
42   ELEMENT_DENY,
43   ELEMENT_FORK,
44   ELEMENT_PIDFILE,
45   ELEMENT_SERVICEDIR,
46   ELEMENT_INCLUDEDIR,
47   ELEMENT_TYPE
48 } ElementType;
49
50 typedef enum
51 {
52   /* we ignore policies for unknown groups/users */
53   POLICY_IGNORED,
54
55   /* non-ignored */
56   POLICY_DEFAULT,
57   POLICY_MANDATORY,
58   POLICY_USER,
59   POLICY_GROUP
60 } PolicyType;
61
62 typedef struct
63 {
64   ElementType type;
65
66   unsigned int had_content : 1;
67
68   union
69   {
70     struct
71     {
72       unsigned int ignore_missing : 1;
73     } include;
74
75     struct
76     {
77       PolicyType type;
78       unsigned long gid_or_uid;      
79     } policy;
80
81     struct
82     {
83       char *name;
84       long value;
85     } limit;
86     
87   } d;
88
89 } Element;
90
91 struct BusConfigParser
92 {
93   int refcount;
94
95   DBusString basedir;  /**< Directory we resolve paths relative to */
96   
97   DBusList *stack;     /**< stack of Element */
98
99   char *user;          /**< user to run as */
100
101   char *bus_type;          /**< Message bus type */
102   
103   DBusList *listen_on; /**< List of addresses to listen to */
104
105   DBusList *mechanisms; /**< Auth mechanisms */
106
107   DBusList *service_dirs; /**< Directories to look for services in */
108
109   BusPolicy *policy;     /**< Security policy */
110
111   BusLimits limits;      /**< Limits */
112
113   char *pidfile;         /**< PID file */
114
115   unsigned int fork : 1; /**< TRUE to fork into daemon mode */
116
117   unsigned int is_toplevel : 1; /**< FALSE if we are a sub-config-file inside another one */
118 };
119
120 static const char*
121 element_type_to_name (ElementType type)
122 {
123   switch (type)
124     {
125     case ELEMENT_NONE:
126       return NULL;
127     case ELEMENT_BUSCONFIG:
128       return "busconfig";
129     case ELEMENT_INCLUDE:
130       return "include";
131     case ELEMENT_USER:
132       return "user";
133     case ELEMENT_LISTEN:
134       return "listen";
135     case ELEMENT_AUTH:
136       return "auth";
137     case ELEMENT_POLICY:
138       return "policy";
139     case ELEMENT_LIMIT:
140       return "limit";
141     case ELEMENT_ALLOW:
142       return "allow";
143     case ELEMENT_DENY:
144       return "deny";
145     case ELEMENT_FORK:
146       return "fork";
147     case ELEMENT_PIDFILE:
148       return "pidfile";
149     case ELEMENT_SERVICEDIR:
150       return "servicedir";
151     case ELEMENT_INCLUDEDIR:
152       return "includedir";
153     case ELEMENT_TYPE:
154       return "type";
155     }
156
157   _dbus_assert_not_reached ("bad element type");
158
159   return NULL;
160 }
161
162 static Element*
163 push_element (BusConfigParser *parser,
164               ElementType      type)
165 {
166   Element *e;
167
168   _dbus_assert (type != ELEMENT_NONE);
169   
170   e = dbus_new0 (Element, 1);
171   if (e == NULL)
172     return NULL;
173
174   if (!_dbus_list_append (&parser->stack, e))
175     {
176       dbus_free (e);
177       return NULL;
178     }
179   
180   e->type = type;
181
182   return e;
183 }
184
185 static void
186 element_free (Element *e)
187 {
188   if (e->type == ELEMENT_LIMIT)
189     dbus_free (e->d.limit.name);
190   
191   dbus_free (e);
192 }
193
194 static void
195 pop_element (BusConfigParser *parser)
196 {
197   Element *e;
198
199   e = _dbus_list_pop_last (&parser->stack);
200   
201   element_free (e);
202 }
203
204 static Element*
205 peek_element (BusConfigParser *parser)
206 {
207   Element *e;
208
209   e = _dbus_list_get_last (&parser->stack);
210
211   return e;
212 }
213
214 static ElementType
215 top_element_type (BusConfigParser *parser)
216 {
217   Element *e;
218
219   e = _dbus_list_get_last (&parser->stack);
220
221   if (e)
222     return e->type;
223   else
224     return ELEMENT_NONE;
225 }
226
227 static dbus_bool_t
228 merge_included (BusConfigParser *parser,
229                 BusConfigParser *included,
230                 DBusError       *error)
231 {
232   DBusList *link;
233
234   if (!bus_policy_merge (parser->policy,
235                          included->policy))
236     {
237       BUS_SET_OOM (error);
238       return FALSE;
239     }
240   
241   if (included->user != NULL)
242     {
243       dbus_free (parser->user);
244       parser->user = included->user;
245       included->user = NULL;
246     }
247
248   if (included->bus_type != NULL)
249     {
250       dbus_free (parser->bus_type);
251       parser->bus_type = included->bus_type;
252       included->bus_type = NULL;
253     }
254   
255   if (included->fork)
256     parser->fork = TRUE;
257
258   if (included->pidfile != NULL)
259     {
260       dbus_free (parser->pidfile);
261       parser->pidfile = included->pidfile;
262       included->pidfile = NULL;
263     }
264   
265   while ((link = _dbus_list_pop_first_link (&included->listen_on)))
266     _dbus_list_append_link (&parser->listen_on, link);
267
268   while ((link = _dbus_list_pop_first_link (&included->mechanisms)))
269     _dbus_list_append_link (&parser->mechanisms, link);
270
271   while ((link = _dbus_list_pop_first_link (&included->service_dirs)))
272     _dbus_list_append_link (&parser->service_dirs, link);
273   
274   return TRUE;
275 }
276
277 BusConfigParser*
278 bus_config_parser_new (const DBusString *basedir,
279                        dbus_bool_t       is_toplevel)
280 {
281   BusConfigParser *parser;
282
283   parser = dbus_new0 (BusConfigParser, 1);
284   if (parser == NULL)
285     return NULL;
286
287   parser->is_toplevel = !!is_toplevel;
288   
289   if (!_dbus_string_init (&parser->basedir))
290     {
291       dbus_free (parser);
292       return NULL;
293     }
294
295   if (((parser->policy = bus_policy_new ()) == NULL) ||
296       !_dbus_string_copy (basedir, 0, &parser->basedir, 0))
297     {
298       if (parser->policy)
299         bus_policy_unref (parser->policy);
300       
301       _dbus_string_free (&parser->basedir);
302       dbus_free (parser);
303       return NULL;
304     }
305
306   /* Make up some numbers! woot! */
307   parser->limits.max_incoming_bytes = _DBUS_ONE_MEGABYTE * 63;
308   parser->limits.max_outgoing_bytes = _DBUS_ONE_MEGABYTE * 63;
309   parser->limits.max_message_size = _DBUS_ONE_MEGABYTE * 32;
310
311   /* Making this long means the user has to wait longer for an error
312    * message if something screws up, but making it too short means
313    * they might see a false failure.
314    */
315   parser->limits.activation_timeout = 25000; /* 25 seconds */
316
317   /* Making this long risks making a DOS attack easier, but too short
318    * and legitimate auth will fail.  If interactive auth (ask user for
319    * password) is allowed, then potentially it has to be quite long.
320    */
321   parser->limits.auth_timeout = 30000; /* 30 seconds */
322
323   parser->limits.max_incomplete_connections = 32;
324   parser->limits.max_connections_per_user = 128;
325
326   /* Note that max_completed_connections / max_connections_per_user
327    * is the number of users that would have to work together to
328    * DOS all the other users.
329    */
330   parser->limits.max_completed_connections = 1024;
331
332   parser->limits.max_pending_activations = 256;
333   parser->limits.max_services_per_connection = 256;
334   
335   parser->refcount = 1;
336
337   return parser;
338 }
339
340 void
341 bus_config_parser_ref (BusConfigParser *parser)
342 {
343   _dbus_assert (parser->refcount > 0);
344
345   parser->refcount += 1;
346 }
347
348 void
349 bus_config_parser_unref (BusConfigParser *parser)
350 {
351   _dbus_assert (parser->refcount > 0);
352
353   parser->refcount -= 1;
354
355   if (parser->refcount == 0)
356     {
357       while (parser->stack != NULL)
358         pop_element (parser);
359
360       dbus_free (parser->user);
361       dbus_free (parser->bus_type);
362       dbus_free (parser->pidfile);
363       
364       _dbus_list_foreach (&parser->listen_on,
365                           (DBusForeachFunction) dbus_free,
366                           NULL);
367
368       _dbus_list_clear (&parser->listen_on);
369
370       _dbus_list_foreach (&parser->service_dirs,
371                           (DBusForeachFunction) dbus_free,
372                           NULL);
373
374       _dbus_list_clear (&parser->service_dirs);
375
376       _dbus_list_foreach (&parser->mechanisms,
377                           (DBusForeachFunction) dbus_free,
378                           NULL);
379
380       _dbus_list_clear (&parser->mechanisms);
381       
382       _dbus_string_free (&parser->basedir);
383
384       if (parser->policy)
385         bus_policy_unref (parser->policy);
386       
387       dbus_free (parser);
388     }
389 }
390
391 dbus_bool_t
392 bus_config_parser_check_doctype (BusConfigParser   *parser,
393                                  const char        *doctype,
394                                  DBusError         *error)
395 {
396   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
397
398   if (strcmp (doctype, "busconfig") != 0)
399     {
400       dbus_set_error (error,
401                       DBUS_ERROR_FAILED,
402                       "Configuration file has the wrong document type %s",
403                       doctype);
404       return FALSE;
405     }
406   else
407     return TRUE;
408 }
409
410 typedef struct
411 {
412   const char  *name;
413   const char **retloc;
414 } LocateAttr;
415
416 static dbus_bool_t
417 locate_attributes (BusConfigParser  *parser,
418                    const char       *element_name,
419                    const char      **attribute_names,
420                    const char      **attribute_values,
421                    DBusError        *error,
422                    const char       *first_attribute_name,
423                    const char      **first_attribute_retloc,
424                    ...)
425 {
426   va_list args;
427   const char *name;
428   const char **retloc;
429   int n_attrs;
430 #define MAX_ATTRS 24
431   LocateAttr attrs[MAX_ATTRS];
432   dbus_bool_t retval;
433   int i;
434
435   _dbus_assert (first_attribute_name != NULL);
436   _dbus_assert (first_attribute_retloc != NULL);
437
438   retval = TRUE;
439
440   n_attrs = 1;
441   attrs[0].name = first_attribute_name;
442   attrs[0].retloc = first_attribute_retloc;
443   *first_attribute_retloc = NULL;
444
445   va_start (args, first_attribute_retloc);
446
447   name = va_arg (args, const char*);
448   retloc = va_arg (args, const char**);
449
450   while (name != NULL)
451     {
452       _dbus_assert (retloc != NULL);
453       _dbus_assert (n_attrs < MAX_ATTRS);
454
455       attrs[n_attrs].name = name;
456       attrs[n_attrs].retloc = retloc;
457       n_attrs += 1;
458       *retloc = NULL;
459
460       name = va_arg (args, const char*);
461       retloc = va_arg (args, const char**);
462     }
463
464   va_end (args);
465
466   if (!retval)
467     return retval;
468
469   i = 0;
470   while (attribute_names[i])
471     {
472       int j;
473       dbus_bool_t found;
474       
475       found = FALSE;
476       j = 0;
477       while (j < n_attrs)
478         {
479           if (strcmp (attrs[j].name, attribute_names[i]) == 0)
480             {
481               retloc = attrs[j].retloc;
482
483               if (*retloc != NULL)
484                 {
485                   dbus_set_error (error, DBUS_ERROR_FAILED,
486                                   "Attribute \"%s\" repeated twice on the same <%s> element",
487                                   attrs[j].name, element_name);
488                   retval = FALSE;
489                   goto out;
490                 }
491
492               *retloc = attribute_values[i];
493               found = TRUE;
494             }
495
496           ++j;
497         }
498
499       if (!found)
500         {
501           dbus_set_error (error, DBUS_ERROR_FAILED,
502                           "Attribute \"%s\" is invalid on <%s> element in this context",
503                           attribute_names[i], element_name);
504           retval = FALSE;
505           goto out;
506         }
507
508       ++i;
509     }
510
511  out:
512   return retval;
513 }
514
515 static dbus_bool_t
516 check_no_attributes (BusConfigParser  *parser,
517                      const char       *element_name,
518                      const char      **attribute_names,
519                      const char      **attribute_values,
520                      DBusError        *error)
521 {
522   if (attribute_names[0] != NULL)
523     {
524       dbus_set_error (error, DBUS_ERROR_FAILED,
525                       "Attribute \"%s\" is invalid on <%s> element in this context",
526                       attribute_names[0], element_name);
527       return FALSE;
528     }
529
530   return TRUE;
531 }
532
533 static dbus_bool_t
534 start_busconfig_child (BusConfigParser   *parser,
535                        const char        *element_name,
536                        const char       **attribute_names,
537                        const char       **attribute_values,
538                        DBusError         *error)
539 {
540   if (strcmp (element_name, "user") == 0)
541     {
542       if (!check_no_attributes (parser, "user", attribute_names, attribute_values, error))
543         return FALSE;
544
545       if (push_element (parser, ELEMENT_USER) == NULL)
546         {
547           BUS_SET_OOM (error);
548           return FALSE;
549         }
550
551       return TRUE;
552     }
553   else if (strcmp (element_name, "type") == 0)
554     {
555       if (!check_no_attributes (parser, "type", attribute_names, attribute_values, error))
556         return FALSE;
557
558       if (push_element (parser, ELEMENT_TYPE) == NULL)
559         {
560           BUS_SET_OOM (error);
561           return FALSE;
562         }
563
564       return TRUE;
565     }
566   else if (strcmp (element_name, "fork") == 0)
567     {
568       if (!check_no_attributes (parser, "fork", attribute_names, attribute_values, error))
569         return FALSE;
570
571       if (push_element (parser, ELEMENT_FORK) == NULL)
572         {
573           BUS_SET_OOM (error);
574           return FALSE;
575         }
576
577       parser->fork = TRUE;
578       
579       return TRUE;
580     }
581   else if (strcmp (element_name, "pidfile") == 0)
582     {
583       if (!check_no_attributes (parser, "pidfile", attribute_names, attribute_values, error))
584         return FALSE;
585
586       if (push_element (parser, ELEMENT_PIDFILE) == NULL)
587         {
588           BUS_SET_OOM (error);
589           return FALSE;
590         }
591
592       return TRUE;
593     }
594   else if (strcmp (element_name, "listen") == 0)
595     {
596       if (!check_no_attributes (parser, "listen", attribute_names, attribute_values, error))
597         return FALSE;
598
599       if (push_element (parser, ELEMENT_LISTEN) == NULL)
600         {
601           BUS_SET_OOM (error);
602           return FALSE;
603         }
604
605       return TRUE;
606     }
607   else if (strcmp (element_name, "auth") == 0)
608     {
609       if (!check_no_attributes (parser, "auth", attribute_names, attribute_values, error))
610         return FALSE;
611
612       if (push_element (parser, ELEMENT_AUTH) == NULL)
613         {
614           BUS_SET_OOM (error);
615           return FALSE;
616         }
617
618       return TRUE;
619     }
620   else if (strcmp (element_name, "includedir") == 0)
621     {
622       if (!check_no_attributes (parser, "includedir", attribute_names, attribute_values, error))
623         return FALSE;
624
625       if (push_element (parser, ELEMENT_INCLUDEDIR) == NULL)
626         {
627           BUS_SET_OOM (error);
628           return FALSE;
629         }
630
631       return TRUE;
632     }
633   else if (strcmp (element_name, "servicedir") == 0)
634     {
635       if (!check_no_attributes (parser, "servicedir", attribute_names, attribute_values, error))
636         return FALSE;
637
638       if (push_element (parser, ELEMENT_SERVICEDIR) == NULL)
639         {
640           BUS_SET_OOM (error);
641           return FALSE;
642         }
643
644       return TRUE;
645     }
646   else if (strcmp (element_name, "include") == 0)
647     {
648       Element *e;
649       const char *ignore_missing;
650
651       if ((e = push_element (parser, ELEMENT_INCLUDE)) == NULL)
652         {
653           BUS_SET_OOM (error);
654           return FALSE;
655         }
656
657       e->d.include.ignore_missing = FALSE;
658
659       if (!locate_attributes (parser, "include",
660                               attribute_names,
661                               attribute_values,
662                               error,
663                               "ignore_missing", &ignore_missing,
664                               NULL))
665         return FALSE;
666
667       if (ignore_missing != NULL)
668         {
669           if (strcmp (ignore_missing, "yes") == 0)
670             e->d.include.ignore_missing = TRUE;
671           else if (strcmp (ignore_missing, "no") == 0)
672             e->d.include.ignore_missing = FALSE;
673           else
674             {
675               dbus_set_error (error, DBUS_ERROR_FAILED,
676                               "ignore_missing attribute must have value \"yes\" or \"no\"");
677               return FALSE;
678             }
679         }
680
681       return TRUE;
682     }
683   else if (strcmp (element_name, "policy") == 0)
684     {
685       Element *e;
686       const char *context;
687       const char *user;
688       const char *group;
689
690       if ((e = push_element (parser, ELEMENT_POLICY)) == NULL)
691         {
692           BUS_SET_OOM (error);
693           return FALSE;
694         }
695
696       e->d.policy.type = POLICY_IGNORED;
697       
698       if (!locate_attributes (parser, "policy",
699                               attribute_names,
700                               attribute_values,
701                               error,
702                               "context", &context,
703                               "user", &user,
704                               "group", &group,
705                               NULL))
706         return FALSE;
707
708       if (((context && user) ||
709            (context && group)) ||
710           (user && group) ||
711           !(context || user || group))
712         {
713           dbus_set_error (error, DBUS_ERROR_FAILED,
714                           "<policy> element must have exactly one of (context|user|group) attributes");
715           return FALSE;
716         }
717
718       if (context != NULL)
719         {
720           if (strcmp (context, "default") == 0)
721             {
722               e->d.policy.type = POLICY_DEFAULT;
723             }
724           else if (strcmp (context, "mandatory") == 0)
725             {
726               e->d.policy.type = POLICY_MANDATORY;
727             }
728           else
729             {
730               dbus_set_error (error, DBUS_ERROR_FAILED,
731                               "context attribute on <policy> must have the value \"default\" or \"mandatory\", not \"%s\"",
732                               context);
733               return FALSE;
734             }
735         }
736       else if (user != NULL)
737         {
738           DBusString username;
739           _dbus_string_init_const (&username, user);
740
741           if (_dbus_get_user_id (&username,
742                                  &e->d.policy.gid_or_uid))
743             e->d.policy.type = POLICY_USER;
744           else
745             _dbus_warn ("Unknown username \"%s\" in message bus configuration file\n",
746                         user);
747         }
748       else if (group != NULL)
749         {
750           DBusString group_name;
751           _dbus_string_init_const (&group_name, group);
752
753           if (_dbus_get_group_id (&group_name,
754                                   &e->d.policy.gid_or_uid))
755             e->d.policy.type = POLICY_GROUP;
756           else
757             _dbus_warn ("Unknown group \"%s\" in message bus configuration file\n",
758                         group);          
759         }
760       else
761         {
762           _dbus_assert_not_reached ("all <policy> attributes null and we didn't set error");
763         }
764       
765       return TRUE;
766     }
767   else if (strcmp (element_name, "limit") == 0)
768     {
769       Element *e;
770       const char *name;
771
772       if ((e = push_element (parser, ELEMENT_LIMIT)) == NULL)
773         {
774           BUS_SET_OOM (error);
775           return FALSE;
776         }
777       
778       if (!locate_attributes (parser, "limit",
779                               attribute_names,
780                               attribute_values,
781                               error,
782                               "name", &name,
783                               NULL))
784         return FALSE;
785
786       if (name == NULL)
787         {
788           dbus_set_error (error, DBUS_ERROR_FAILED,
789                           "<limit> element must have a \"name\" attribute");
790           return FALSE;
791         }
792
793       e->d.limit.name = _dbus_strdup (name);
794       if (e->d.limit.name == NULL)
795         {
796           BUS_SET_OOM (error);
797           return FALSE;
798         }
799
800       return TRUE;
801     }
802   else
803     {
804       dbus_set_error (error, DBUS_ERROR_FAILED,
805                       "Element <%s> not allowed inside <%s> in configuration file",
806                       element_name, "busconfig");
807       return FALSE;
808     }
809 }
810
811 static int
812 message_type_from_string (const char *type_str)
813 {
814   if (strcmp (type_str, "method_call") == 0)
815     return DBUS_MESSAGE_TYPE_METHOD_CALL;
816   if (strcmp (type_str, "method_return") == 0)
817     return DBUS_MESSAGE_TYPE_METHOD_RETURN;
818   else if (strcmp (type_str, "signal") == 0)
819     return DBUS_MESSAGE_TYPE_SIGNAL;
820   else if (strcmp (type_str, "error") == 0)
821     return DBUS_MESSAGE_TYPE_ERROR;
822   else
823     return DBUS_MESSAGE_TYPE_INVALID;
824 }
825
826 static dbus_bool_t
827 append_rule_from_element (BusConfigParser   *parser,
828                           const char        *element_name,
829                           const char       **attribute_names,
830                           const char       **attribute_values,
831                           dbus_bool_t        allow,
832                           DBusError         *error)
833 {
834   const char *send_interface;
835   const char *send_member;
836   const char *send_error;
837   const char *send_service;
838   const char *send_path;
839   const char *send_type;
840   const char *receive_interface;
841   const char *receive_member;
842   const char *receive_error;
843   const char *receive_service;
844   const char *receive_path;
845   const char *receive_type;
846   const char *own;
847   const char *user;
848   const char *group;
849   BusPolicyRule *rule;
850   
851   if (!locate_attributes (parser, element_name,
852                           attribute_names,
853                           attribute_values,
854                           error,
855                           "send_interface", &send_interface,
856                           "send_member", &send_member,
857                           "send_error", &send_error,
858                           "send_service", &send_service,
859                           "send_path", &send_path,
860                           "send_type", &send_type,
861                           "receive_interface", &receive_interface,
862                           "receive_member", &receive_member,
863                           "receive_error", &receive_error,
864                           "receive_service", &receive_service,
865                           "receive_path", &receive_path,
866                           "receive_type", &receive_type,
867                           "own", &own,
868                           "user", &user,
869                           "group", &group,
870                           NULL))
871     return FALSE;
872
873   if (!(send_interface || send_member || send_error || send_service ||
874         send_type || send_path ||
875         receive_interface || receive_member || receive_error || receive_service ||
876         receive_type || receive_path ||
877         own || user || group))
878     {
879       dbus_set_error (error, DBUS_ERROR_FAILED,
880                       "Element <%s> must have one or more attributes",
881                       element_name);
882       return FALSE;
883     }
884
885   if ((send_member && (send_interface == NULL && send_path == NULL)) ||
886       (receive_member && (receive_interface == NULL && receive_path == NULL)))
887     {
888       dbus_set_error (error, DBUS_ERROR_FAILED,
889                       "On element <%s>, if you specify a member you must specify an interface or a path. Keep in mind that not all messages have an interface field.",
890                       element_name);
891       return FALSE;
892     }
893   
894   /* Allowed combinations of elements are:
895    *
896    *   base, must be all send or all receive:
897    *     nothing
898    *     interface
899    *     interface + member
900    *     error
901    * 
902    *   base send_ can combine with send_service, send_path, send_type
903    *   base receive_ with receive_service, receive_path, receive_type
904    *
905    *   user, group, own must occur alone
906    */
907
908   if (((send_interface && send_error) ||
909        (send_interface && receive_interface) ||
910        (send_interface && receive_member) ||
911        (send_interface && receive_error) ||
912        (send_interface && receive_service) ||
913        (send_interface && own) ||
914        (send_interface && user) ||
915        (send_interface && group)) ||
916
917       ((send_member && send_error) ||
918        (send_member && receive_interface) ||
919        (send_member && receive_member) ||
920        (send_member && receive_error) ||
921        (send_member && receive_service) ||
922        (send_member && own) ||
923        (send_member && user) ||
924        (send_member && group)) ||
925       
926       ((send_error && receive_interface) ||
927        (send_error && receive_member) ||
928        (send_error && receive_error) ||
929        (send_error && receive_service) ||
930        (send_error && own) ||
931        (send_error && user) ||
932        (send_error && group)) ||
933
934       ((send_service && receive_interface) ||
935        (send_service && receive_member) ||
936        (send_service && receive_error) ||
937        (send_service && receive_service) ||
938        (send_service && own) ||
939        (send_service && user) ||
940        (send_service && group)) ||
941
942       ((send_type && receive_interface) ||
943        (send_type && receive_member) ||
944        (send_type && receive_error) ||
945        (send_type && receive_service) ||
946        (send_type && own) ||
947        (send_type && user) ||
948        (send_type && group)) ||
949
950       ((send_path && receive_interface) ||
951        (send_path && receive_member) ||
952        (send_path && receive_error) ||
953        (send_path && receive_service) ||
954        (send_path && own) ||
955        (send_path && user) ||
956        (send_path && group)) ||
957       
958       ((receive_interface && receive_error) ||
959        (receive_interface && own) ||
960        (receive_interface && user) ||
961        (receive_interface && group)) ||
962
963       ((receive_member && receive_error) ||
964        (receive_member && own) ||
965        (receive_member && user) ||
966        (receive_member && group)) ||
967
968       ((receive_error && own) ||
969        (receive_error && user) ||
970        (receive_error && group)) ||
971
972       ((own && user) ||
973        (own && group)) ||
974
975       ((user && group)))
976     {
977       dbus_set_error (error, DBUS_ERROR_FAILED,
978                       "Invalid combination of attributes on element <%s>, "
979                       "only send_foo/send_service or receive_foo/receive_service may be paired",
980                       element_name);
981       return FALSE;
982     }
983   
984   rule = NULL;
985
986   /* In BusPolicyRule, NULL represents wildcard.
987    * In the config file, '*' represents it.
988    */
989 #define IS_WILDCARD(str) ((str) && ((str)[0]) == '*' && ((str)[1]) == '\0')
990
991   if (send_interface || send_member || send_error || send_service ||
992       send_path || send_type)
993     {
994       int message_type;
995       
996       if (IS_WILDCARD (send_interface))
997         send_interface = NULL;
998       if (IS_WILDCARD (send_member))
999         send_member = NULL;
1000       if (IS_WILDCARD (send_error))
1001         send_error = NULL;
1002       if (IS_WILDCARD (send_service))
1003         send_service = NULL;
1004       if (IS_WILDCARD (send_path))
1005         send_path = NULL;
1006       if (IS_WILDCARD (send_type))
1007         send_type = NULL;
1008
1009       message_type = DBUS_MESSAGE_TYPE_INVALID;
1010       if (send_type != NULL)
1011         {
1012           message_type = message_type_from_string (send_type);
1013           if (message_type == DBUS_MESSAGE_TYPE_INVALID)
1014             {
1015               dbus_set_error (error, DBUS_ERROR_FAILED,
1016                               "Bad message type \"%s\"",
1017                               send_type);
1018               return FALSE;
1019             }
1020         }
1021       
1022       rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow); 
1023       if (rule == NULL)
1024         goto nomem;
1025
1026       rule->d.send.message_type = message_type;
1027       rule->d.send.path = _dbus_strdup (send_path);
1028       rule->d.send.interface = _dbus_strdup (send_interface);
1029       rule->d.send.member = _dbus_strdup (send_member);
1030       rule->d.send.error = _dbus_strdup (send_error);
1031       rule->d.send.destination = _dbus_strdup (send_service);
1032       if (send_path && rule->d.send.path == NULL)
1033         goto nomem;
1034       if (send_interface && rule->d.send.interface == NULL)
1035         goto nomem;
1036       if (send_member && rule->d.send.member == NULL)
1037         goto nomem;
1038       if (send_error && rule->d.send.error == NULL)
1039         goto nomem;
1040       if (send_service && rule->d.send.destination == NULL)
1041         goto nomem;
1042     }
1043   else if (receive_interface || receive_member || receive_error || receive_service ||
1044            receive_path || receive_type)
1045     {
1046       int message_type;
1047       
1048       if (IS_WILDCARD (receive_interface))
1049         receive_interface = NULL;
1050       if (IS_WILDCARD (receive_member))
1051         receive_member = NULL;
1052       if (IS_WILDCARD (receive_error))
1053         receive_error = NULL;
1054       if (IS_WILDCARD (receive_service))
1055         receive_service = NULL;
1056       if (IS_WILDCARD (receive_path))
1057         receive_path = NULL;
1058       if (IS_WILDCARD (receive_type))
1059         receive_type = NULL;
1060
1061
1062       message_type = DBUS_MESSAGE_TYPE_INVALID;
1063       if (receive_type != NULL)
1064         {
1065           message_type = message_type_from_string (receive_type);
1066           if (message_type == DBUS_MESSAGE_TYPE_INVALID)
1067             {
1068               dbus_set_error (error, DBUS_ERROR_FAILED,
1069                               "Bad message type \"%s\"",
1070                               receive_type);
1071               return FALSE;
1072             }
1073         }
1074       
1075       rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, allow); 
1076       if (rule == NULL)
1077         goto nomem;
1078
1079       rule->d.receive.message_type = message_type;
1080       rule->d.receive.path = _dbus_strdup (receive_path);
1081       rule->d.receive.interface = _dbus_strdup (receive_interface);
1082       rule->d.receive.member = _dbus_strdup (receive_member);
1083       rule->d.receive.error = _dbus_strdup (receive_error);
1084       rule->d.receive.origin = _dbus_strdup (receive_service);
1085       if (receive_path && rule->d.receive.path == NULL)
1086         goto nomem;
1087       if (receive_interface && rule->d.receive.interface == NULL)
1088         goto nomem;
1089       if (receive_member && rule->d.receive.member == NULL)
1090         goto nomem;
1091       if (receive_error && rule->d.receive.error == NULL)
1092         goto nomem;
1093       if (receive_service && rule->d.receive.origin == NULL)
1094         goto nomem;
1095     }
1096   else if (own)
1097     {
1098       rule = bus_policy_rule_new (BUS_POLICY_RULE_OWN, allow); 
1099       if (rule == NULL)
1100         goto nomem;
1101
1102       if (IS_WILDCARD (own))
1103         own = NULL;
1104       
1105       rule->d.own.service_name = _dbus_strdup (own);
1106       if (own && rule->d.own.service_name == NULL)
1107         goto nomem;
1108     }
1109   else if (user)
1110     {      
1111       if (IS_WILDCARD (user))
1112         {
1113           rule = bus_policy_rule_new (BUS_POLICY_RULE_USER, allow); 
1114           if (rule == NULL)
1115             goto nomem;
1116
1117           rule->d.user.uid = DBUS_UID_UNSET;
1118         }
1119       else
1120         {
1121           DBusString username;
1122           dbus_uid_t uid;
1123           
1124           _dbus_string_init_const (&username, user);
1125       
1126           if (_dbus_get_user_id (&username, &uid))
1127             {
1128               rule = bus_policy_rule_new (BUS_POLICY_RULE_USER, allow); 
1129               if (rule == NULL)
1130                 goto nomem;
1131
1132               rule->d.user.uid = uid;
1133             }
1134           else
1135             {
1136               _dbus_warn ("Unknown username \"%s\" on element <%s>\n",
1137                           user, element_name);
1138             }
1139         }
1140     }
1141   else if (group)
1142     {
1143       if (IS_WILDCARD (group))
1144         {
1145           rule = bus_policy_rule_new (BUS_POLICY_RULE_GROUP, allow); 
1146           if (rule == NULL)
1147             goto nomem;
1148
1149           rule->d.group.gid = DBUS_GID_UNSET;
1150         }
1151       else
1152         {
1153           DBusString groupname;
1154           dbus_gid_t gid;
1155           
1156           _dbus_string_init_const (&groupname, group);
1157           
1158           if (_dbus_get_user_id (&groupname, &gid))
1159             {
1160               rule = bus_policy_rule_new (BUS_POLICY_RULE_GROUP, allow); 
1161               if (rule == NULL)
1162                 goto nomem;
1163
1164               rule->d.group.gid = gid;
1165             }
1166           else
1167             {
1168               _dbus_warn ("Unknown group \"%s\" on element <%s>\n",
1169                           group, element_name);
1170             }
1171         }
1172     }
1173   else
1174     _dbus_assert_not_reached ("Did not handle some combination of attributes on <allow> or <deny>");
1175
1176   if (rule != NULL)
1177     {
1178       Element *pe;
1179       
1180       pe = peek_element (parser);      
1181       _dbus_assert (pe != NULL);
1182       _dbus_assert (pe->type == ELEMENT_POLICY);
1183
1184       switch (pe->d.policy.type)
1185         {
1186         case POLICY_IGNORED:
1187           /* drop the rule on the floor */
1188           break;
1189           
1190         case POLICY_DEFAULT:
1191           if (!bus_policy_append_default_rule (parser->policy, rule))
1192             goto nomem;
1193           break;
1194         case POLICY_MANDATORY:
1195           if (!bus_policy_append_mandatory_rule (parser->policy, rule))
1196             goto nomem;
1197           break;
1198         case POLICY_USER:
1199           if (!BUS_POLICY_RULE_IS_PER_CLIENT (rule))
1200             {
1201               dbus_set_error (error, DBUS_ERROR_FAILED,
1202                               "<%s> rule cannot be per-user because it has bus-global semantics",
1203                               element_name);
1204               goto failed;
1205             }
1206           
1207           if (!bus_policy_append_user_rule (parser->policy, pe->d.policy.gid_or_uid,
1208                                             rule))
1209             goto nomem;
1210           break;
1211         case POLICY_GROUP:
1212           if (!BUS_POLICY_RULE_IS_PER_CLIENT (rule))
1213             {
1214               dbus_set_error (error, DBUS_ERROR_FAILED,
1215                               "<%s> rule cannot be per-group because it has bus-global semantics",
1216                               element_name);
1217               goto failed;
1218             }
1219           
1220           if (!bus_policy_append_group_rule (parser->policy, pe->d.policy.gid_or_uid,
1221                                              rule))
1222             goto nomem;
1223           break;
1224         }
1225       
1226       bus_policy_rule_unref (rule);
1227       rule = NULL;
1228     }
1229   
1230   return TRUE;
1231
1232  nomem:
1233   BUS_SET_OOM (error);
1234  failed:
1235   if (rule)
1236     bus_policy_rule_unref (rule);
1237   return FALSE;
1238 }
1239
1240 static dbus_bool_t
1241 start_policy_child (BusConfigParser   *parser,
1242                     const char        *element_name,
1243                     const char       **attribute_names,
1244                     const char       **attribute_values,
1245                     DBusError         *error)
1246 {
1247   if (strcmp (element_name, "allow") == 0)
1248     {
1249       if (!append_rule_from_element (parser, element_name,
1250                                      attribute_names, attribute_values,
1251                                      TRUE, error))
1252         return FALSE;
1253       
1254       if (push_element (parser, ELEMENT_ALLOW) == NULL)
1255         {
1256           BUS_SET_OOM (error);
1257           return FALSE;
1258         }
1259       
1260       return TRUE;
1261     }
1262   else if (strcmp (element_name, "deny") == 0)
1263     {
1264       if (!append_rule_from_element (parser, element_name,
1265                                      attribute_names, attribute_values,
1266                                      FALSE, error))
1267         return FALSE;
1268       
1269       if (push_element (parser, ELEMENT_DENY) == NULL)
1270         {
1271           BUS_SET_OOM (error);
1272           return FALSE;
1273         }
1274       
1275       return TRUE;
1276     }
1277   else
1278     {
1279       dbus_set_error (error, DBUS_ERROR_FAILED,
1280                       "Element <%s> not allowed inside <%s> in configuration file",
1281                       element_name, "policy");
1282       return FALSE;
1283     }
1284 }
1285
1286 dbus_bool_t
1287 bus_config_parser_start_element (BusConfigParser   *parser,
1288                                  const char        *element_name,
1289                                  const char       **attribute_names,
1290                                  const char       **attribute_values,
1291                                  DBusError         *error)
1292 {
1293   ElementType t;
1294
1295   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1296
1297   /* printf ("START: %s\n", element_name); */
1298   
1299   t = top_element_type (parser);
1300
1301   if (t == ELEMENT_NONE)
1302     {
1303       if (strcmp (element_name, "busconfig") == 0)
1304         {
1305           if (!check_no_attributes (parser, "busconfig", attribute_names, attribute_values, error))
1306             return FALSE;
1307           
1308           if (push_element (parser, ELEMENT_BUSCONFIG) == NULL)
1309             {
1310               BUS_SET_OOM (error);
1311               return FALSE;
1312             }
1313
1314           return TRUE;
1315         }
1316       else
1317         {
1318           dbus_set_error (error, DBUS_ERROR_FAILED,
1319                           "Unknown element <%s> at root of configuration file",
1320                           element_name);
1321           return FALSE;
1322         }
1323     }
1324   else if (t == ELEMENT_BUSCONFIG)
1325     {
1326       return start_busconfig_child (parser, element_name,
1327                                     attribute_names, attribute_values,
1328                                     error);
1329     }
1330   else if (t == ELEMENT_POLICY)
1331     {
1332       return start_policy_child (parser, element_name,
1333                                  attribute_names, attribute_values,
1334                                  error);
1335     }
1336   else
1337     {
1338       dbus_set_error (error, DBUS_ERROR_FAILED,
1339                       "Element <%s> is not allowed in this context",
1340                       element_name);
1341       return FALSE;
1342     }  
1343 }
1344
1345 static dbus_bool_t
1346 set_limit (BusConfigParser *parser,
1347            const char      *name,
1348            long             value,
1349            DBusError       *error)
1350 {
1351   dbus_bool_t must_be_positive;
1352   dbus_bool_t must_be_int;
1353
1354   must_be_int = FALSE;
1355   must_be_positive = FALSE;
1356   
1357   if (strcmp (name, "max_incoming_bytes") == 0)
1358     {
1359       must_be_positive = TRUE;
1360       parser->limits.max_incoming_bytes = value;
1361     }
1362   else if (strcmp (name, "max_outgoing_bytes") == 0)
1363     {
1364       must_be_positive = TRUE;
1365       parser->limits.max_outgoing_bytes = value;
1366     }
1367   else if (strcmp (name, "max_message_size") == 0)
1368     {
1369       must_be_positive = TRUE;
1370       parser->limits.max_message_size = value;
1371     }
1372   else if (strcmp (name, "activation_timeout") == 0)
1373     {
1374       must_be_positive = TRUE;
1375       must_be_int = TRUE;
1376       parser->limits.activation_timeout = value;
1377     }
1378   else if (strcmp (name, "auth_timeout") == 0)
1379     {
1380       must_be_positive = TRUE;
1381       must_be_int = TRUE;
1382       parser->limits.auth_timeout = value;
1383     }
1384   else if (strcmp (name, "max_completed_connections") == 0)
1385     {
1386       must_be_positive = TRUE;
1387       must_be_int = TRUE;
1388       parser->limits.max_completed_connections = value;
1389     }
1390   else if (strcmp (name, "max_incomplete_connections") == 0)
1391     {
1392       must_be_positive = TRUE;
1393       must_be_int = TRUE;
1394       parser->limits.max_incomplete_connections = value;
1395     }
1396   else if (strcmp (name, "max_connections_per_user") == 0)
1397     {
1398       must_be_positive = TRUE;
1399       must_be_int = TRUE;
1400       parser->limits.max_connections_per_user = value;
1401     }
1402   else if (strcmp (name, "max_pending_activations") == 0)
1403     {
1404       must_be_positive = TRUE;
1405       must_be_int = TRUE;
1406       parser->limits.max_pending_activations = value;
1407     }
1408   else if (strcmp (name, "max_services_per_connection") == 0)
1409     {
1410       must_be_positive = TRUE;
1411       must_be_int = TRUE;
1412       parser->limits.max_services_per_connection = value;
1413     }
1414   else
1415     {
1416       dbus_set_error (error, DBUS_ERROR_FAILED,
1417                       "There is no limit called \"%s\"\n",
1418                       name);
1419       return FALSE;
1420     }
1421   
1422   if (must_be_positive && value < 0)
1423     {
1424       dbus_set_error (error, DBUS_ERROR_FAILED,
1425                       "<limit name=\"%s\"> must be a positive number\n",
1426                       name);
1427       return FALSE;
1428     }
1429
1430   if (must_be_int &&
1431       (value < _DBUS_INT_MIN || value > _DBUS_INT_MAX))
1432     {
1433       dbus_set_error (error, DBUS_ERROR_FAILED,
1434                       "<limit name=\"%s\"> value is too large\n",
1435                       name);
1436       return FALSE;
1437     }
1438
1439   return TRUE;  
1440 }
1441
1442 dbus_bool_t
1443 bus_config_parser_end_element (BusConfigParser   *parser,
1444                                const char        *element_name,
1445                                DBusError         *error)
1446 {
1447   ElementType t;
1448   const char *n;
1449   Element *e;
1450
1451   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1452
1453   /* printf ("END: %s\n", element_name); */
1454   
1455   t = top_element_type (parser);
1456
1457   if (t == ELEMENT_NONE)
1458     {
1459       /* should probably be an assertion failure but
1460        * being paranoid about XML parsers
1461        */
1462       dbus_set_error (error, DBUS_ERROR_FAILED,
1463                       "XML parser ended element with no element on the stack");
1464       return FALSE;
1465     }
1466
1467   n = element_type_to_name (t);
1468   _dbus_assert (n != NULL);
1469   if (strcmp (n, element_name) != 0)
1470     {
1471       /* should probably be an assertion failure but
1472        * being paranoid about XML parsers
1473        */
1474       dbus_set_error (error, DBUS_ERROR_FAILED,
1475                       "XML element <%s> ended but topmost element on the stack was <%s>",
1476                       element_name, n);
1477       return FALSE;
1478     }
1479
1480   e = peek_element (parser);
1481   _dbus_assert (e != NULL);
1482
1483   switch (e->type)
1484     {
1485     case ELEMENT_NONE:
1486       _dbus_assert_not_reached ("element in stack has no type");
1487       break;
1488
1489     case ELEMENT_INCLUDE:
1490     case ELEMENT_USER:
1491     case ELEMENT_TYPE:
1492     case ELEMENT_LISTEN:
1493     case ELEMENT_PIDFILE:
1494     case ELEMENT_AUTH:
1495     case ELEMENT_SERVICEDIR:
1496     case ELEMENT_INCLUDEDIR:
1497     case ELEMENT_LIMIT:
1498       if (!e->had_content)
1499         {
1500           dbus_set_error (error, DBUS_ERROR_FAILED,
1501                           "XML element <%s> was expected to have content inside it",
1502                           element_type_to_name (e->type));
1503           return FALSE;
1504         }
1505
1506       if (e->type == ELEMENT_LIMIT)
1507         {
1508           if (!set_limit (parser, e->d.limit.name, e->d.limit.value,
1509                           error))
1510             return FALSE;
1511         }
1512       break;
1513
1514     case ELEMENT_BUSCONFIG:
1515     case ELEMENT_POLICY:
1516     case ELEMENT_ALLOW:
1517     case ELEMENT_DENY:
1518     case ELEMENT_FORK:
1519       break;
1520     }
1521
1522   pop_element (parser);
1523
1524   return TRUE;
1525 }
1526
1527 static dbus_bool_t
1528 all_whitespace (const DBusString *str)
1529 {
1530   int i;
1531
1532   _dbus_string_skip_white (str, 0, &i);
1533
1534   return i == _dbus_string_get_length (str);
1535 }
1536
1537 static dbus_bool_t
1538 make_full_path (const DBusString *basedir,
1539                 const DBusString *filename,
1540                 DBusString       *full_path)
1541 {
1542   if (_dbus_path_is_absolute (filename))
1543     {
1544       return _dbus_string_copy (filename, 0, full_path, 0);
1545     }
1546   else
1547     {
1548       if (!_dbus_string_copy (basedir, 0, full_path, 0))
1549         return FALSE;
1550       
1551       if (!_dbus_concat_dir_and_file (full_path, filename))
1552         return FALSE;
1553
1554       return TRUE;
1555     }
1556 }
1557
1558 static dbus_bool_t
1559 include_file (BusConfigParser   *parser,
1560               const DBusString  *filename,
1561               dbus_bool_t        ignore_missing,
1562               DBusError         *error)
1563 {
1564   /* FIXME good test case for this would load each config file in the
1565    * test suite both alone, and as an include, and check
1566    * that the result is the same
1567    */
1568   BusConfigParser *included;
1569   DBusError tmp_error;
1570         
1571   dbus_error_init (&tmp_error);
1572   included = bus_config_load (filename, FALSE, &tmp_error);
1573   if (included == NULL)
1574     {
1575       _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
1576
1577       if (dbus_error_has_name (&tmp_error, DBUS_ERROR_FILE_NOT_FOUND) &&
1578           ignore_missing)
1579         {
1580           dbus_error_free (&tmp_error);
1581           return TRUE;
1582         }
1583       else
1584         {
1585           dbus_move_error (&tmp_error, error);
1586           return FALSE;
1587         }
1588     }
1589   else
1590     {
1591       _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
1592
1593       if (!merge_included (parser, included, error))
1594         {
1595           bus_config_parser_unref (included);
1596           return FALSE;
1597         }
1598
1599       bus_config_parser_unref (included);
1600       return TRUE;
1601     }
1602 }
1603
1604 static dbus_bool_t
1605 include_dir (BusConfigParser   *parser,
1606              const DBusString  *dirname,
1607              DBusError         *error)
1608 {
1609   DBusString filename;
1610   dbus_bool_t retval;
1611   DBusError tmp_error;
1612   DBusDirIter *dir;
1613   
1614   if (!_dbus_string_init (&filename))
1615     {
1616       BUS_SET_OOM (error);
1617       return FALSE;
1618     }
1619
1620   retval = FALSE;
1621   
1622   dir = _dbus_directory_open (dirname, error);
1623
1624   if (dir == NULL)
1625     goto failed;
1626
1627   dbus_error_init (&tmp_error);
1628   while (_dbus_directory_get_next_file (dir, &filename, &tmp_error))
1629     {
1630       DBusString full_path;
1631
1632       if (!_dbus_string_init (&full_path))
1633         {
1634           BUS_SET_OOM (error);
1635           goto failed;
1636         }
1637
1638       if (!_dbus_string_copy (dirname, 0, &full_path, 0))
1639         {
1640           BUS_SET_OOM (error);
1641           _dbus_string_free (&full_path);
1642           goto failed;
1643         }      
1644
1645       if (!_dbus_concat_dir_and_file (&full_path, &filename))
1646         {
1647           BUS_SET_OOM (error);
1648           _dbus_string_free (&full_path);
1649           goto failed;
1650         }
1651       
1652       if (_dbus_string_ends_with_c_str (&full_path, ".conf"))
1653         {
1654           if (!include_file (parser, &full_path, TRUE, error))
1655             {
1656               _dbus_string_free (&full_path);
1657               goto failed;
1658             }
1659         }
1660
1661       _dbus_string_free (&full_path);
1662     }
1663
1664   if (dbus_error_is_set (&tmp_error))
1665     {
1666       dbus_move_error (&tmp_error, error);
1667       goto failed;
1668     }
1669   
1670   retval = TRUE;
1671   
1672  failed:
1673   _dbus_string_free (&filename);
1674   
1675   if (dir)
1676     _dbus_directory_close (dir);
1677
1678   return retval;
1679 }
1680
1681 dbus_bool_t
1682 bus_config_parser_content (BusConfigParser   *parser,
1683                            const DBusString  *content,
1684                            DBusError         *error)
1685 {
1686   Element *e;
1687
1688   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1689
1690 #if 0
1691   {
1692     const char *c_str;
1693     
1694     _dbus_string_get_const_data (content, &c_str);
1695
1696     printf ("CONTENT %d bytes: %s\n", _dbus_string_get_length (content), c_str);
1697   }
1698 #endif
1699   
1700   e = peek_element (parser);
1701   if (e == NULL)
1702     {
1703       dbus_set_error (error, DBUS_ERROR_FAILED,
1704                       "Text content outside of any XML element in configuration file");
1705       return FALSE;
1706     }
1707   else if (e->had_content)
1708     {
1709       _dbus_assert_not_reached ("Element had multiple content blocks");
1710       return FALSE;
1711     }
1712
1713   switch (top_element_type (parser))
1714     {
1715     case ELEMENT_NONE:
1716       _dbus_assert_not_reached ("element at top of stack has no type");
1717       return FALSE;
1718
1719     case ELEMENT_BUSCONFIG:
1720     case ELEMENT_POLICY:
1721     case ELEMENT_ALLOW:
1722     case ELEMENT_DENY:
1723     case ELEMENT_FORK:
1724       if (all_whitespace (content))
1725         return TRUE;
1726       else
1727         {
1728           dbus_set_error (error, DBUS_ERROR_FAILED,
1729                           "No text content expected inside XML element %s in configuration file",
1730                           element_type_to_name (top_element_type (parser)));
1731           return FALSE;
1732         }
1733
1734     case ELEMENT_PIDFILE:
1735       {
1736         char *s;
1737
1738         e->had_content = TRUE;
1739         
1740         if (!_dbus_string_copy_data (content, &s))
1741           goto nomem;
1742           
1743         dbus_free (parser->pidfile);
1744         parser->pidfile = s;
1745       }
1746       break;
1747
1748     case ELEMENT_INCLUDE:
1749       {
1750         DBusString full_path;
1751         
1752         e->had_content = TRUE;
1753
1754         if (!_dbus_string_init (&full_path))
1755           goto nomem;
1756         
1757         if (!make_full_path (&parser->basedir, content, &full_path))
1758           {
1759             _dbus_string_free (&full_path);
1760             goto nomem;
1761           }
1762         
1763         if (!include_file (parser, &full_path,
1764                            e->d.include.ignore_missing, error))
1765           {
1766             _dbus_string_free (&full_path);
1767             return FALSE;
1768           }
1769
1770         _dbus_string_free (&full_path);
1771       }
1772       break;
1773
1774     case ELEMENT_INCLUDEDIR:
1775       {
1776         DBusString full_path;
1777         
1778         e->had_content = TRUE;
1779
1780         if (!_dbus_string_init (&full_path))
1781           goto nomem;
1782         
1783         if (!make_full_path (&parser->basedir, content, &full_path))
1784           {
1785             _dbus_string_free (&full_path);
1786             goto nomem;
1787           }
1788         
1789         if (!include_dir (parser, &full_path, error))
1790           {
1791             _dbus_string_free (&full_path);
1792             return FALSE;
1793           }
1794
1795         _dbus_string_free (&full_path);
1796       }
1797       break;
1798       
1799     case ELEMENT_USER:
1800       {
1801         char *s;
1802
1803         e->had_content = TRUE;
1804         
1805         if (!_dbus_string_copy_data (content, &s))
1806           goto nomem;
1807           
1808         dbus_free (parser->user);
1809         parser->user = s;
1810       }
1811       break;
1812
1813     case ELEMENT_TYPE:
1814       {
1815         char *s;
1816
1817         e->had_content = TRUE;
1818
1819         if (!_dbus_string_copy_data (content, &s))
1820           goto nomem;
1821         
1822         dbus_free (parser->bus_type);
1823         parser->bus_type = s;
1824       }
1825       break;
1826       
1827     case ELEMENT_LISTEN:
1828       {
1829         char *s;
1830
1831         e->had_content = TRUE;
1832         
1833         if (!_dbus_string_copy_data (content, &s))
1834           goto nomem;
1835
1836         if (!_dbus_list_append (&parser->listen_on,
1837                                 s))
1838           {
1839             dbus_free (s);
1840             goto nomem;
1841           }
1842       }
1843       break;
1844
1845     case ELEMENT_AUTH:
1846       {
1847         char *s;
1848         
1849         e->had_content = TRUE;
1850
1851         if (!_dbus_string_copy_data (content, &s))
1852           goto nomem;
1853
1854         if (!_dbus_list_append (&parser->mechanisms,
1855                                 s))
1856           {
1857             dbus_free (s);
1858             goto nomem;
1859           }
1860       }
1861       break;
1862
1863     case ELEMENT_SERVICEDIR:
1864       {
1865         char *s;
1866         DBusString full_path;
1867         
1868         e->had_content = TRUE;
1869
1870         if (!_dbus_string_init (&full_path))
1871           goto nomem;
1872         
1873         if (!make_full_path (&parser->basedir, content, &full_path))
1874           {
1875             _dbus_string_free (&full_path);
1876             goto nomem;
1877           }
1878         
1879         if (!_dbus_string_copy_data (&full_path, &s))
1880           {
1881             _dbus_string_free (&full_path);
1882             goto nomem;
1883           }
1884
1885         if (!_dbus_list_append (&parser->service_dirs, s))
1886           {
1887             _dbus_string_free (&full_path);
1888             dbus_free (s);
1889             goto nomem;
1890           }
1891
1892         _dbus_string_free (&full_path);
1893       }
1894       break;
1895
1896     case ELEMENT_LIMIT:
1897       {
1898         long val;
1899
1900         e->had_content = TRUE;
1901
1902         val = 0;
1903         if (!_dbus_string_parse_int (content, 0, &val, NULL))
1904           {
1905             dbus_set_error (error, DBUS_ERROR_FAILED,
1906                             "<limit name=\"%s\"> element has invalid value (could not parse as integer)",
1907                             e->d.limit.name);
1908             return FALSE;
1909           }
1910
1911         e->d.limit.value = val;
1912
1913         _dbus_verbose ("Loaded value %ld for limit %s\n",
1914                        e->d.limit.value,
1915                        e->d.limit.name);
1916       }
1917       break;
1918     }
1919
1920   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1921   return TRUE;
1922
1923  nomem:
1924   BUS_SET_OOM (error);
1925   return FALSE;
1926 }
1927
1928 dbus_bool_t
1929 bus_config_parser_finished (BusConfigParser   *parser,
1930                             DBusError         *error)
1931 {
1932   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1933
1934   if (parser->stack != NULL)
1935     {
1936       dbus_set_error (error, DBUS_ERROR_FAILED,
1937                       "Element <%s> was not closed in configuration file",
1938                       element_type_to_name (top_element_type (parser)));
1939
1940       return FALSE;
1941     }
1942
1943   if (parser->is_toplevel && parser->listen_on == NULL)
1944     {
1945       dbus_set_error (error, DBUS_ERROR_FAILED,
1946                       "Configuration file needs one or more <listen> elements giving addresses"); 
1947       return FALSE;
1948     }
1949   
1950   return TRUE;
1951 }
1952
1953 const char*
1954 bus_config_parser_get_user (BusConfigParser *parser)
1955 {
1956   return parser->user;
1957 }
1958
1959 const char*
1960 bus_config_parser_get_type (BusConfigParser *parser)
1961 {
1962   return parser->bus_type;
1963 }
1964
1965 DBusList**
1966 bus_config_parser_get_addresses (BusConfigParser *parser)
1967 {
1968   return &parser->listen_on;
1969 }
1970
1971 DBusList**
1972 bus_config_parser_get_mechanisms (BusConfigParser *parser)
1973 {
1974   return &parser->mechanisms;
1975 }
1976
1977 DBusList**
1978 bus_config_parser_get_service_dirs (BusConfigParser *parser)
1979 {
1980   return &parser->service_dirs;
1981 }
1982
1983 dbus_bool_t
1984 bus_config_parser_get_fork (BusConfigParser   *parser)
1985 {
1986   return parser->fork;
1987 }
1988
1989 const char *
1990 bus_config_parser_get_pidfile (BusConfigParser   *parser)
1991 {
1992   return parser->pidfile;
1993 }
1994
1995 BusPolicy*
1996 bus_config_parser_steal_policy (BusConfigParser *parser)
1997 {
1998   BusPolicy *policy;
1999
2000   _dbus_assert (parser->policy != NULL); /* can only steal the policy 1 time */
2001   
2002   policy = parser->policy;
2003
2004   parser->policy = NULL;
2005
2006   return policy;
2007 }
2008
2009 /* Overwrite any limits that were set in the configuration file */
2010 void
2011 bus_config_parser_get_limits (BusConfigParser *parser,
2012                               BusLimits       *limits)
2013 {
2014   *limits = parser->limits;
2015 }
2016
2017 #ifdef DBUS_BUILD_TESTS
2018 #include <stdio.h>
2019
2020 typedef enum
2021 {
2022   VALID,
2023   INVALID,
2024   UNKNOWN
2025 } Validity;
2026
2027 static dbus_bool_t
2028 do_load (const DBusString *full_path,
2029          Validity          validity,
2030          dbus_bool_t       oom_possible)
2031 {
2032   BusConfigParser *parser;
2033   DBusError error;
2034
2035   dbus_error_init (&error);
2036
2037   parser = bus_config_load (full_path, TRUE, &error);
2038   if (parser == NULL)
2039     {
2040       _DBUS_ASSERT_ERROR_IS_SET (&error);
2041
2042       if (oom_possible &&
2043           dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
2044         {
2045           _dbus_verbose ("Failed to load valid file due to OOM\n");
2046           dbus_error_free (&error);
2047           return TRUE;
2048         }
2049       else if (validity == VALID)
2050         {
2051           _dbus_warn ("Failed to load valid file but still had memory: %s\n",
2052                       error.message);
2053
2054           dbus_error_free (&error);
2055           return FALSE;
2056         }
2057       else
2058         {
2059           dbus_error_free (&error);
2060           return TRUE;
2061         }
2062     }
2063   else
2064     {
2065       _DBUS_ASSERT_ERROR_IS_CLEAR (&error);
2066
2067       bus_config_parser_unref (parser);
2068
2069       if (validity == INVALID)
2070         {
2071           _dbus_warn ("Accepted invalid file\n");
2072           return FALSE;
2073         }
2074
2075       return TRUE;
2076     }
2077 }
2078
2079 typedef struct
2080 {
2081   const DBusString *full_path;
2082   Validity          validity;
2083 } LoaderOomData;
2084
2085 static dbus_bool_t
2086 check_loader_oom_func (void *data)
2087 {
2088   LoaderOomData *d = data;
2089
2090   return do_load (d->full_path, d->validity, TRUE);
2091 }
2092
2093 static dbus_bool_t
2094 process_test_subdir (const DBusString *test_base_dir,
2095                      const char       *subdir,
2096                      Validity          validity)
2097 {
2098   DBusString test_directory;
2099   DBusString filename;
2100   DBusDirIter *dir;
2101   dbus_bool_t retval;
2102   DBusError error;
2103
2104   retval = FALSE;
2105   dir = NULL;
2106
2107   if (!_dbus_string_init (&test_directory))
2108     _dbus_assert_not_reached ("didn't allocate test_directory\n");
2109
2110   _dbus_string_init_const (&filename, subdir);
2111
2112   if (!_dbus_string_copy (test_base_dir, 0,
2113                           &test_directory, 0))
2114     _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
2115
2116   if (!_dbus_concat_dir_and_file (&test_directory, &filename))
2117     _dbus_assert_not_reached ("couldn't allocate full path");
2118
2119   _dbus_string_free (&filename);
2120   if (!_dbus_string_init (&filename))
2121     _dbus_assert_not_reached ("didn't allocate filename string\n");
2122
2123   dbus_error_init (&error);
2124   dir = _dbus_directory_open (&test_directory, &error);
2125   if (dir == NULL)
2126     {
2127       _dbus_warn ("Could not open %s: %s\n",
2128                   _dbus_string_get_const_data (&test_directory),
2129                   error.message);
2130       dbus_error_free (&error);
2131       goto failed;
2132     }
2133
2134   printf ("Testing:\n");
2135
2136  next:
2137   while (_dbus_directory_get_next_file (dir, &filename, &error))
2138     {
2139       DBusString full_path;
2140       LoaderOomData d;
2141
2142       if (!_dbus_string_init (&full_path))
2143         _dbus_assert_not_reached ("couldn't init string");
2144
2145       if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
2146         _dbus_assert_not_reached ("couldn't copy dir to full_path");
2147
2148       if (!_dbus_concat_dir_and_file (&full_path, &filename))
2149         _dbus_assert_not_reached ("couldn't concat file to dir");
2150
2151       if (!_dbus_string_ends_with_c_str (&full_path, ".conf"))
2152         {
2153           _dbus_verbose ("Skipping non-.conf file %s\n",
2154                          _dbus_string_get_const_data (&filename));
2155           _dbus_string_free (&full_path);
2156           goto next;
2157         }
2158
2159       printf ("    %s\n", _dbus_string_get_const_data (&filename));
2160
2161       _dbus_verbose (" expecting %s\n",
2162                      validity == VALID ? "valid" :
2163                      (validity == INVALID ? "invalid" :
2164                       (validity == UNKNOWN ? "unknown" : "???")));
2165
2166       d.full_path = &full_path;
2167       d.validity = validity;
2168       if (!_dbus_test_oom_handling ("config-loader", check_loader_oom_func, &d))
2169         _dbus_assert_not_reached ("test failed");
2170
2171       _dbus_string_free (&full_path);
2172     }
2173
2174   if (dbus_error_is_set (&error))
2175     {
2176       _dbus_warn ("Could not get next file in %s: %s\n",
2177                   _dbus_string_get_const_data (&test_directory),
2178                   error.message);
2179       dbus_error_free (&error);
2180       goto failed;
2181     }
2182
2183   retval = TRUE;
2184
2185  failed:
2186
2187   if (dir)
2188     _dbus_directory_close (dir);
2189   _dbus_string_free (&test_directory);
2190   _dbus_string_free (&filename);
2191
2192   return retval;
2193 }
2194
2195 dbus_bool_t
2196 bus_config_parser_test (const DBusString *test_data_dir)
2197 {
2198   if (test_data_dir == NULL ||
2199       _dbus_string_get_length (test_data_dir) == 0)
2200     {
2201       printf ("No test data\n");
2202       return TRUE;
2203     }
2204
2205   if (!process_test_subdir (test_data_dir, "valid-config-files", VALID))
2206     return FALSE;
2207
2208   return TRUE;
2209 }
2210
2211 #endif /* DBUS_BUILD_TESTS */
2212