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