<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>bus.c Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.2.15 --> <center> <a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="modules.html">Modules</a> <a class="qindex" href="annotated.html">Data Structures</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Data Fields</a> <a class="qindex" href="pages.html">Related Pages</a> </center> <hr><h1>bus.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font> 00002 <font class="comment">/* bus.c message bus context object</font> 00003 <font class="comment"> *</font> 00004 <font class="comment"> * Copyright (C) 2003 Red Hat, Inc.</font> 00005 <font class="comment"> *</font> 00006 <font class="comment"> * Licensed under the Academic Free License version 1.2</font> 00007 <font class="comment"> * </font> 00008 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font> 00009 <font class="comment"> * it under the terms of the GNU General Public License as published by</font> 00010 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font> 00011 <font class="comment"> * (at your option) any later version.</font> 00012 <font class="comment"> *</font> 00013 <font class="comment"> * This program is distributed in the hope that it will be useful,</font> 00014 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font> 00015 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</font> 00016 <font class="comment"> * GNU General Public License for more details.</font> 00017 <font class="comment"> * </font> 00018 <font class="comment"> * You should have received a copy of the GNU General Public License</font> 00019 <font class="comment"> * along with this program; if not, write to the Free Software</font> 00020 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</font> 00021 <font class="comment"> *</font> 00022 <font class="comment"> */</font> 00023 00024 <font class="preprocessor">#include "bus.h"</font> 00025 <font class="preprocessor">#include "activation.h"</font> 00026 <font class="preprocessor">#include "connection.h"</font> 00027 <font class="preprocessor">#include "services.h"</font> 00028 <font class="preprocessor">#include "utils.h"</font> 00029 <font class="preprocessor">#include "policy.h"</font> 00030 <font class="preprocessor">#include "config-parser.h"</font> 00031 <font class="preprocessor">#include "signals.h"</font> 00032 <font class="preprocessor">#include <dbus/dbus-list.h></font> 00033 <font class="preprocessor">#include <dbus/dbus-hash.h></font> 00034 <font class="preprocessor">#include <dbus/dbus-internals.h></font> 00035 00036 <font class="keyword">struct </font>BusContext 00037 { 00038 <font class="keywordtype">int</font> refcount; 00039 <font class="keywordtype">char</font> *type; 00040 <font class="keywordtype">char</font> *address; 00041 <font class="keywordtype">char</font> *pidfile; 00042 DBusLoop *loop; 00043 <a class="code" href="structDBusList.html">DBusList</a> *servers; 00044 BusConnections *connections; 00045 BusActivation *activation; 00046 BusRegistry *registry; 00047 BusPolicy *policy; 00048 BusMatchmaker *matchmaker; 00049 <a class="code" href="structDBusUserDatabase.html">DBusUserDatabase</a> *user_database; 00050 BusLimits limits; 00051 }; 00052 00053 <font class="keyword">static</font> dbus_int32_t server_data_slot = -1; 00054 00055 <font class="keyword">typedef</font> <font class="keyword">struct</font> 00056 <font class="keyword"></font>{ 00057 BusContext *context; 00058 } BusServerData; 00059 00060 <font class="preprocessor">#define BUS_SERVER_DATA(server) (dbus_server_get_data ((server), server_data_slot))</font> 00061 <font class="preprocessor"></font> 00062 <font class="keyword">static</font> BusContext* 00063 server_get_context (<a class="code" href="structDBusServer.html">DBusServer</a> *server) 00064 { 00065 BusContext *context; 00066 BusServerData *bd; 00067 00068 <font class="keywordflow">if</font> (!dbus_server_allocate_data_slot (&server_data_slot)) 00069 <font class="keywordflow">return</font> NULL; 00070 00071 bd = BUS_SERVER_DATA (server); 00072 <font class="keywordflow">if</font> (bd == NULL) 00073 { 00074 dbus_server_free_data_slot (&server_data_slot); 00075 <font class="keywordflow">return</font> NULL; 00076 } 00077 00078 context = bd->context; 00079 00080 dbus_server_free_data_slot (&server_data_slot); 00081 00082 <font class="keywordflow">return</font> context; 00083 } 00084 00085 <font class="keyword">static</font> dbus_bool_t 00086 server_watch_callback (<a class="code" href="structDBusWatch.html">DBusWatch</a> *watch, 00087 <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> condition, 00088 <font class="keywordtype">void</font> *data) 00089 { 00090 <font class="comment">/* FIXME this can be done in dbus-mainloop.c</font> 00091 <font class="comment"> * if the code in activation.c for the babysitter</font> 00092 <font class="comment"> * watch handler is fixed.</font> 00093 <font class="comment"> */</font> 00094 00095 <font class="keywordflow">return</font> dbus_watch_handle (watch, condition); 00096 } 00097 00098 <font class="keyword">static</font> dbus_bool_t 00099 add_server_watch (<a class="code" href="structDBusWatch.html">DBusWatch</a> *watch, 00100 <font class="keywordtype">void</font> *data) 00101 { 00102 <a class="code" href="structDBusServer.html">DBusServer</a> *server = data; 00103 BusContext *context; 00104 00105 context = server_get_context (server); 00106 00107 <font class="keywordflow">return</font> _dbus_loop_add_watch (context->loop, 00108 watch, server_watch_callback, server, 00109 NULL); 00110 } 00111 00112 <font class="keyword">static</font> <font class="keywordtype">void</font> 00113 remove_server_watch (<a class="code" href="structDBusWatch.html">DBusWatch</a> *watch, 00114 <font class="keywordtype">void</font> *data) 00115 { 00116 <a class="code" href="structDBusServer.html">DBusServer</a> *server = data; 00117 BusContext *context; 00118 00119 context = server_get_context (server); 00120 00121 _dbus_loop_remove_watch (context->loop, 00122 watch, server_watch_callback, server); 00123 } 00124 00125 00126 <font class="keyword">static</font> <font class="keywordtype">void</font> 00127 server_timeout_callback (<a class="code" href="structDBusTimeout.html">DBusTimeout</a> *timeout, 00128 <font class="keywordtype">void</font> *data) 00129 { 00130 <font class="comment">/* can return FALSE on OOM but we just let it fire again later */</font> 00131 dbus_timeout_handle (timeout); 00132 } 00133 00134 <font class="keyword">static</font> dbus_bool_t 00135 add_server_timeout (<a class="code" href="structDBusTimeout.html">DBusTimeout</a> *timeout, 00136 <font class="keywordtype">void</font> *data) 00137 { 00138 <a class="code" href="structDBusServer.html">DBusServer</a> *server = data; 00139 BusContext *context; 00140 00141 context = server_get_context (server); 00142 00143 <font class="keywordflow">return</font> _dbus_loop_add_timeout (context->loop, 00144 timeout, server_timeout_callback, server, NULL); 00145 } 00146 00147 <font class="keyword">static</font> <font class="keywordtype">void</font> 00148 remove_server_timeout (<a class="code" href="structDBusTimeout.html">DBusTimeout</a> *timeout, 00149 <font class="keywordtype">void</font> *data) 00150 { 00151 <a class="code" href="structDBusServer.html">DBusServer</a> *server = data; 00152 BusContext *context; 00153 00154 context = server_get_context (server); 00155 00156 _dbus_loop_remove_timeout (context->loop, 00157 timeout, server_timeout_callback, server); 00158 } 00159 00160 <font class="keyword">static</font> <font class="keywordtype">void</font> 00161 new_connection_callback (<a class="code" href="structDBusServer.html">DBusServer</a> *server, 00162 <a class="code" href="structDBusConnection.html">DBusConnection</a> *new_connection, 00163 <font class="keywordtype">void</font> *data) 00164 { 00165 BusContext *context = data; 00166 00167 <font class="keywordflow">if</font> (!bus_connections_setup_connection (context->connections, new_connection)) 00168 { 00169 _dbus_verbose (<font class="stringliteral">"No memory to setup new connection\n"</font>); 00170 00171 <font class="comment">/* if we don't do this, it will get unref'd without</font> 00172 <font class="comment"> * being disconnected... kind of strange really</font> 00173 <font class="comment"> * that we have to do this, people won't get it right</font> 00174 <font class="comment"> * in general.</font> 00175 <font class="comment"> */</font> 00176 dbus_connection_disconnect (new_connection); 00177 } 00178 00179 dbus_connection_set_max_received_size (new_connection, 00180 context->limits.max_incoming_bytes); 00181 00182 dbus_connection_set_max_message_size (new_connection, 00183 context->limits.max_message_size); 00184 00185 <font class="comment">/* on OOM, we won't have ref'd the connection so it will die. */</font> 00186 } 00187 00188 <font class="keyword">static</font> <font class="keywordtype">void</font> 00189 free_server_data (<font class="keywordtype">void</font> *data) 00190 { 00191 BusServerData *bd = data; 00192 00193 dbus_free (bd); 00194 } 00195 00196 <font class="keyword">static</font> dbus_bool_t 00197 setup_server (BusContext *context, 00198 <a class="code" href="structDBusServer.html">DBusServer</a> *server, 00199 <font class="keywordtype">char</font> **auth_mechanisms, 00200 <a class="code" href="structDBusError.html">DBusError</a> *error) 00201 { 00202 BusServerData *bd; 00203 00204 bd = dbus_new0 (BusServerData, 1); 00205 <font class="keywordflow">if</font> (!dbus_server_set_data (server, 00206 server_data_slot, 00207 bd, free_server_data)) 00208 { 00209 dbus_free (bd); 00210 BUS_SET_OOM (error); 00211 <font class="keywordflow">return</font> FALSE; 00212 } 00213 00214 bd->context = context; 00215 00216 <font class="keywordflow">if</font> (!dbus_server_set_auth_mechanisms (server, (<font class="keyword">const</font> <font class="keywordtype">char</font>**) auth_mechanisms)) 00217 { 00218 BUS_SET_OOM (error); 00219 <font class="keywordflow">return</font> FALSE; 00220 } 00221 00222 dbus_server_set_new_connection_function (server, 00223 new_connection_callback, 00224 context, NULL); 00225 00226 <font class="keywordflow">if</font> (!dbus_server_set_watch_functions (server, 00227 add_server_watch, 00228 remove_server_watch, 00229 NULL, 00230 server, 00231 NULL)) 00232 { 00233 BUS_SET_OOM (error); 00234 <font class="keywordflow">return</font> FALSE; 00235 } 00236 00237 <font class="keywordflow">if</font> (!dbus_server_set_timeout_functions (server, 00238 add_server_timeout, 00239 remove_server_timeout, 00240 NULL, 00241 server, NULL)) 00242 { 00243 BUS_SET_OOM (error); 00244 <font class="keywordflow">return</font> FALSE; 00245 } 00246 00247 <font class="keywordflow">return</font> TRUE; 00248 } 00249 00250 BusContext* 00251 bus_context_new (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *config_file, 00252 dbus_bool_t force_fork, 00253 <font class="keywordtype">int</font> print_addr_fd, 00254 <font class="keywordtype">int</font> print_pid_fd, 00255 <a class="code" href="structDBusError.html">DBusError</a> *error) 00256 { 00257 BusContext *context; 00258 <a class="code" href="structDBusList.html">DBusList</a> *link; 00259 <a class="code" href="structDBusList.html">DBusList</a> **addresses; 00260 <a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser; 00261 <a class="code" href="structDBusString.html">DBusString</a> full_address; 00262 <font class="keyword">const</font> <font class="keywordtype">char</font> *user, *pidfile; 00263 <font class="keywordtype">char</font> **auth_mechanisms; 00264 <a class="code" href="structDBusList.html">DBusList</a> **auth_mechanisms_list; 00265 <font class="keywordtype">int</font> len; 00266 00267 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00268 00269 <font class="keywordflow">if</font> (!_dbus_string_init (&full_address)) 00270 { 00271 BUS_SET_OOM (error); 00272 <font class="keywordflow">return</font> NULL; 00273 } 00274 00275 <font class="keywordflow">if</font> (!dbus_server_allocate_data_slot (&server_data_slot)) 00276 { 00277 BUS_SET_OOM (error); 00278 _dbus_string_free (&full_address); 00279 <font class="keywordflow">return</font> NULL; 00280 } 00281 00282 parser = NULL; 00283 context = NULL; 00284 auth_mechanisms = NULL; 00285 00286 parser = bus_config_load (config_file, TRUE, error); 00287 <font class="keywordflow">if</font> (parser == NULL) 00288 <font class="keywordflow">goto</font> failed; 00289 00290 <font class="comment">/* Check for an existing pid file. Of course this is a race;</font> 00291 <font class="comment"> * we'd have to use fcntl() locks on the pid file to</font> 00292 <font class="comment"> * avoid that. But we want to check for the pid file</font> 00293 <font class="comment"> * before overwriting any existing sockets, etc.</font> 00294 <font class="comment"> */</font> 00295 pidfile = bus_config_parser_get_pidfile (parser); 00296 <font class="keywordflow">if</font> (pidfile != NULL) 00297 { 00298 <a class="code" href="structDBusString.html">DBusString</a> u; 00299 <a class="code" href="structDBusStat.html">DBusStat</a> stbuf; 00300 <a class="code" href="structDBusError.html">DBusError</a> tmp_error; 00301 00302 dbus_error_init (&tmp_error); 00303 _dbus_string_init_const (&u, pidfile); 00304 00305 <font class="keywordflow">if</font> (_dbus_stat (&u, &stbuf, &tmp_error)) 00306 { 00307 dbus_set_error (error, DBUS_ERROR_FAILED, 00308 <font class="stringliteral">"The pid file \"%s\" exists, if the message bus is not running, remove this file"</font>, 00309 pidfile); 00310 dbus_error_free (&tmp_error); 00311 <font class="keywordflow">goto</font> failed; 00312 } 00313 } 00314 00315 context = dbus_new0 (BusContext, 1); 00316 <font class="keywordflow">if</font> (context == NULL) 00317 { 00318 BUS_SET_OOM (error); 00319 <font class="keywordflow">goto</font> failed; 00320 } 00321 00322 context->refcount = 1; 00323 00324 <font class="comment">/* get our limits and timeout lengths */</font> 00325 bus_config_parser_get_limits (parser, &context->limits); 00326 00327 <font class="comment">/* we need another ref of the server data slot for the context</font> 00328 <font class="comment"> * to own</font> 00329 <font class="comment"> */</font> 00330 <font class="keywordflow">if</font> (!dbus_server_allocate_data_slot (&server_data_slot)) 00331 _dbus_assert_not_reached (<font class="stringliteral">"second ref of server data slot failed"</font>); 00332 00333 context->user_database = _dbus_user_database_new (); 00334 <font class="keywordflow">if</font> (context->user_database == NULL) 00335 { 00336 BUS_SET_OOM (error); 00337 <font class="keywordflow">goto</font> failed; 00338 } 00339 00340 context->loop = _dbus_loop_new (); 00341 <font class="keywordflow">if</font> (context->loop == NULL) 00342 { 00343 BUS_SET_OOM (error); 00344 <font class="keywordflow">goto</font> failed; 00345 } 00346 00347 <font class="comment">/* Build an array of auth mechanisms */</font> 00348 00349 auth_mechanisms_list = bus_config_parser_get_mechanisms (parser); 00350 len = _dbus_list_get_length (auth_mechanisms_list); 00351 00352 <font class="keywordflow">if</font> (len > 0) 00353 { 00354 <font class="keywordtype">int</font> i; 00355 00356 auth_mechanisms = dbus_new0 (<font class="keywordtype">char</font>*, len + 1); 00357 <font class="keywordflow">if</font> (auth_mechanisms == NULL) 00358 <font class="keywordflow">goto</font> failed; 00359 00360 i = 0; 00361 link = _dbus_list_get_first_link (auth_mechanisms_list); 00362 <font class="keywordflow">while</font> (link != NULL) 00363 { 00364 auth_mechanisms[i] = _dbus_strdup (link-><a class="code" href="structDBusList.html#m2">data</a>); 00365 <font class="keywordflow">if</font> (auth_mechanisms[i] == NULL) 00366 <font class="keywordflow">goto</font> failed; 00367 link = _dbus_list_get_next_link (auth_mechanisms_list, link); 00368 } 00369 } 00370 <font class="keywordflow">else</font> 00371 { 00372 auth_mechanisms = NULL; 00373 } 00374 00375 <font class="comment">/* Listen on our addresses */</font> 00376 00377 addresses = bus_config_parser_get_addresses (parser); 00378 00379 link = _dbus_list_get_first_link (addresses); 00380 <font class="keywordflow">while</font> (link != NULL) 00381 { 00382 <a class="code" href="structDBusServer.html">DBusServer</a> *server; 00383 00384 server = dbus_server_listen (link-><a class="code" href="structDBusList.html#m2">data</a>, error); 00385 <font class="keywordflow">if</font> (server == NULL) 00386 <font class="keywordflow">goto</font> failed; 00387 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (!setup_server (context, server, auth_mechanisms, error)) 00388 <font class="keywordflow">goto</font> failed; 00389 00390 <font class="keywordflow">if</font> (!_dbus_list_append (&context->servers, server)) 00391 { 00392 BUS_SET_OOM (error); 00393 <font class="keywordflow">goto</font> failed; 00394 } 00395 00396 link = _dbus_list_get_next_link (addresses, link); 00397 } 00398 00399 <font class="comment">/* note that type may be NULL */</font> 00400 context->type = _dbus_strdup (bus_config_parser_get_type (parser)); 00401 00402 <font class="comment">/* We have to build the address backward, so that</font> 00403 <font class="comment"> * <listen> later in the config file have priority</font> 00404 <font class="comment"> */</font> 00405 link = _dbus_list_get_last_link (&context->servers); 00406 <font class="keywordflow">while</font> (link != NULL) 00407 { 00408 <font class="keywordtype">char</font> *addr; 00409 00410 addr = dbus_server_get_address (link-><a class="code" href="structDBusList.html#m2">data</a>); 00411 <font class="keywordflow">if</font> (addr == NULL) 00412 { 00413 BUS_SET_OOM (error); 00414 <font class="keywordflow">goto</font> failed; 00415 } 00416 00417 <font class="keywordflow">if</font> (_dbus_string_get_length (&full_address) > 0) 00418 { 00419 <font class="keywordflow">if</font> (!_dbus_string_append (&full_address, <font class="stringliteral">";"</font>)) 00420 { 00421 BUS_SET_OOM (error); 00422 <font class="keywordflow">goto</font> failed; 00423 } 00424 } 00425 00426 <font class="keywordflow">if</font> (!_dbus_string_append (&full_address, addr)) 00427 { 00428 BUS_SET_OOM (error); 00429 <font class="keywordflow">goto</font> failed; 00430 } 00431 00432 dbus_free (addr); 00433 00434 link = _dbus_list_get_prev_link (&context->servers, link); 00435 } 00436 00437 <font class="keywordflow">if</font> (!_dbus_string_copy_data (&full_address, &context->address)) 00438 { 00439 BUS_SET_OOM (error); 00440 <font class="keywordflow">goto</font> failed; 00441 } 00442 00443 <font class="comment">/* Note that we don't know whether the print_addr_fd is</font> 00444 <font class="comment"> * one of the sockets we're using to listen on, or some</font> 00445 <font class="comment"> * other random thing. But I think the answer is "don't do</font> 00446 <font class="comment"> * that then"</font> 00447 <font class="comment"> */</font> 00448 <font class="keywordflow">if</font> (print_addr_fd >= 0) 00449 { 00450 <a class="code" href="structDBusString.html">DBusString</a> addr; 00451 <font class="keyword">const</font> <font class="keywordtype">char</font> *a = bus_context_get_address (context); 00452 <font class="keywordtype">int</font> bytes; 00453 00454 _dbus_assert (a != NULL); 00455 <font class="keywordflow">if</font> (!_dbus_string_init (&addr)) 00456 { 00457 BUS_SET_OOM (error); 00458 <font class="keywordflow">goto</font> failed; 00459 } 00460 00461 <font class="keywordflow">if</font> (!_dbus_string_append (&addr, a) || 00462 !_dbus_string_append (&addr, <font class="stringliteral">"\n"</font>)) 00463 { 00464 _dbus_string_free (&addr); 00465 BUS_SET_OOM (error); 00466 <font class="keywordflow">goto</font> failed; 00467 } 00468 00469 bytes = _dbus_string_get_length (&addr); 00470 <font class="keywordflow">if</font> (_dbus_write (print_addr_fd, &addr, 0, bytes) != bytes) 00471 { 00472 dbus_set_error (error, DBUS_ERROR_FAILED, 00473 <font class="stringliteral">"Printing message bus address: %s\n"</font>, 00474 _dbus_strerror (errno)); 00475 _dbus_string_free (&addr); 00476 <font class="keywordflow">goto</font> failed; 00477 } 00478 00479 <font class="keywordflow">if</font> (print_addr_fd > 2) 00480 _dbus_close (print_addr_fd, NULL); 00481 00482 _dbus_string_free (&addr); 00483 } 00484 00485 <font class="comment">/* Create activation subsystem */</font> 00486 00487 context->activation = bus_activation_new (context, &full_address, 00488 bus_config_parser_get_service_dirs (parser), 00489 error); 00490 <font class="keywordflow">if</font> (context->activation == NULL) 00491 { 00492 _DBUS_ASSERT_ERROR_IS_SET (error); 00493 <font class="keywordflow">goto</font> failed; 00494 } 00495 00496 context->connections = bus_connections_new (context); 00497 <font class="keywordflow">if</font> (context->connections == NULL) 00498 { 00499 BUS_SET_OOM (error); 00500 <font class="keywordflow">goto</font> failed; 00501 } 00502 00503 context->registry = bus_registry_new (context); 00504 <font class="keywordflow">if</font> (context->registry == NULL) 00505 { 00506 BUS_SET_OOM (error); 00507 <font class="keywordflow">goto</font> failed; 00508 } 00509 00510 context->matchmaker = bus_matchmaker_new (); 00511 <font class="keywordflow">if</font> (context->matchmaker == NULL) 00512 { 00513 BUS_SET_OOM (error); 00514 <font class="keywordflow">goto</font> failed; 00515 } 00516 00517 context->policy = bus_config_parser_steal_policy (parser); 00518 _dbus_assert (context->policy != NULL); 00519 00520 <font class="comment">/* Now become a daemon if appropriate */</font> 00521 <font class="keywordflow">if</font> (force_fork || bus_config_parser_get_fork (parser)) 00522 { 00523 <a class="code" href="structDBusString.html">DBusString</a> u; 00524 00525 <font class="keywordflow">if</font> (pidfile) 00526 _dbus_string_init_const (&u, pidfile); 00527 00528 <font class="keywordflow">if</font> (!_dbus_become_daemon (pidfile ? &u : NULL, error)) 00529 <font class="keywordflow">goto</font> failed; 00530 } 00531 <font class="keywordflow">else</font> 00532 { 00533 <font class="comment">/* Need to write PID file for ourselves, not for the child process */</font> 00534 <font class="keywordflow">if</font> (pidfile != NULL) 00535 { 00536 <a class="code" href="structDBusString.html">DBusString</a> u; 00537 00538 _dbus_string_init_const (&u, pidfile); 00539 00540 <font class="keywordflow">if</font> (!_dbus_write_pid_file (&u, _dbus_getpid (), error)) 00541 <font class="keywordflow">goto</font> failed; 00542 } 00543 } 00544 00545 <font class="comment">/* keep around the pid filename so we can delete it later */</font> 00546 context->pidfile = _dbus_strdup (pidfile); 00547 00548 <font class="comment">/* Write PID if requested */</font> 00549 <font class="keywordflow">if</font> (print_pid_fd >= 0) 00550 { 00551 <a class="code" href="structDBusString.html">DBusString</a> pid; 00552 <font class="keywordtype">int</font> bytes; 00553 00554 <font class="keywordflow">if</font> (!_dbus_string_init (&pid)) 00555 { 00556 BUS_SET_OOM (error); 00557 <font class="keywordflow">goto</font> failed; 00558 } 00559 00560 <font class="keywordflow">if</font> (!_dbus_string_append_int (&pid, _dbus_getpid ()) || 00561 !_dbus_string_append (&pid, <font class="stringliteral">"\n"</font>)) 00562 { 00563 _dbus_string_free (&pid); 00564 BUS_SET_OOM (error); 00565 <font class="keywordflow">goto</font> failed; 00566 } 00567 00568 bytes = _dbus_string_get_length (&pid); 00569 <font class="keywordflow">if</font> (_dbus_write (print_pid_fd, &pid, 0, bytes) != bytes) 00570 { 00571 dbus_set_error (error, DBUS_ERROR_FAILED, 00572 <font class="stringliteral">"Printing message bus PID: %s\n"</font>, 00573 _dbus_strerror (errno)); 00574 _dbus_string_free (&pid); 00575 <font class="keywordflow">goto</font> failed; 00576 } 00577 00578 <font class="keywordflow">if</font> (print_pid_fd > 2) 00579 _dbus_close (print_pid_fd, NULL); 00580 00581 _dbus_string_free (&pid); 00582 } 00583 00584 <font class="comment">/* Here we change our credentials if required,</font> 00585 <font class="comment"> * as soon as we've set up our sockets and pidfile</font> 00586 <font class="comment"> */</font> 00587 user = bus_config_parser_get_user (parser); 00588 <font class="keywordflow">if</font> (user != NULL) 00589 { 00590 <a class="code" href="structDBusCredentials.html">DBusCredentials</a> creds; 00591 <a class="code" href="structDBusString.html">DBusString</a> u; 00592 00593 _dbus_string_init_const (&u, user); 00594 00595 <font class="keywordflow">if</font> (!_dbus_credentials_from_username (&u, &creds) || 00596 creds.<a class="code" href="structDBusCredentials.html#m1">uid</a> < 0 || 00597 creds.<a class="code" href="structDBusCredentials.html#m2">gid</a> < 0) 00598 { 00599 dbus_set_error (error, DBUS_ERROR_FAILED, 00600 <font class="stringliteral">"Could not get UID and GID for username \"%s\""</font>, 00601 user); 00602 <font class="keywordflow">goto</font> failed; 00603 } 00604 00605 <font class="keywordflow">if</font> (!_dbus_change_identity (creds.<a class="code" href="structDBusCredentials.html#m1">uid</a>, creds.<a class="code" href="structDBusCredentials.html#m2">gid</a>, error)) 00606 <font class="keywordflow">goto</font> failed; 00607 } 00608 00609 bus_config_parser_unref (parser); 00610 _dbus_string_free (&full_address); 00611 dbus_free_string_array (auth_mechanisms); 00612 dbus_server_free_data_slot (&server_data_slot); 00613 00614 <font class="keywordflow">return</font> context; 00615 00616 failed: 00617 <font class="keywordflow">if</font> (parser != NULL) 00618 bus_config_parser_unref (parser); 00619 00620 <font class="keywordflow">if</font> (context != NULL) 00621 bus_context_unref (context); 00622 00623 _dbus_string_free (&full_address); 00624 dbus_free_string_array (auth_mechanisms); 00625 00626 dbus_server_free_data_slot (&server_data_slot); 00627 00628 <font class="keywordflow">return</font> NULL; 00629 } 00630 00631 <font class="keyword">static</font> <font class="keywordtype">void</font> 00632 shutdown_server (BusContext *context, 00633 <a class="code" href="structDBusServer.html">DBusServer</a> *server) 00634 { 00635 <font class="keywordflow">if</font> (server == NULL || 00636 !dbus_server_get_is_connected (server)) 00637 <font class="keywordflow">return</font>; 00638 00639 <font class="keywordflow">if</font> (!dbus_server_set_watch_functions (server, 00640 NULL, NULL, NULL, 00641 context, 00642 NULL)) 00643 _dbus_assert_not_reached (<font class="stringliteral">"setting watch functions to NULL failed"</font>); 00644 00645 <font class="keywordflow">if</font> (!dbus_server_set_timeout_functions (server, 00646 NULL, NULL, NULL, 00647 context, 00648 NULL)) 00649 _dbus_assert_not_reached (<font class="stringliteral">"setting timeout functions to NULL failed"</font>); 00650 00651 dbus_server_disconnect (server); 00652 } 00653 00654 <font class="keywordtype">void</font> 00655 bus_context_shutdown (BusContext *context) 00656 { 00657 <a class="code" href="structDBusList.html">DBusList</a> *link; 00658 00659 link = _dbus_list_get_first_link (&context->servers); 00660 <font class="keywordflow">while</font> (link != NULL) 00661 { 00662 shutdown_server (context, link-><a class="code" href="structDBusList.html#m2">data</a>); 00663 00664 link = _dbus_list_get_next_link (&context->servers, link); 00665 } 00666 } 00667 00668 <font class="keywordtype">void</font> 00669 bus_context_ref (BusContext *context) 00670 { 00671 _dbus_assert (context->refcount > 0); 00672 context->refcount += 1; 00673 } 00674 00675 <font class="keywordtype">void</font> 00676 bus_context_unref (BusContext *context) 00677 { 00678 _dbus_assert (context->refcount > 0); 00679 context->refcount -= 1; 00680 00681 <font class="keywordflow">if</font> (context->refcount == 0) 00682 { 00683 <a class="code" href="structDBusList.html">DBusList</a> *link; 00684 00685 _dbus_verbose (<font class="stringliteral">"Finalizing bus context %p\n"</font>, context); 00686 00687 bus_context_shutdown (context); 00688 00689 <font class="keywordflow">if</font> (context->connections) 00690 { 00691 bus_connections_unref (context->connections); 00692 context->connections = NULL; 00693 } 00694 00695 <font class="keywordflow">if</font> (context->registry) 00696 { 00697 bus_registry_unref (context->registry); 00698 context->registry = NULL; 00699 } 00700 00701 <font class="keywordflow">if</font> (context->activation) 00702 { 00703 bus_activation_unref (context->activation); 00704 context->activation = NULL; 00705 } 00706 00707 link = _dbus_list_get_first_link (&context->servers); 00708 <font class="keywordflow">while</font> (link != NULL) 00709 { 00710 dbus_server_unref (link-><a class="code" href="structDBusList.html#m2">data</a>); 00711 00712 link = _dbus_list_get_next_link (&context->servers, link); 00713 } 00714 _dbus_list_clear (&context->servers); 00715 00716 <font class="keywordflow">if</font> (context->policy) 00717 { 00718 bus_policy_unref (context->policy); 00719 context->policy = NULL; 00720 } 00721 00722 <font class="keywordflow">if</font> (context->loop) 00723 { 00724 _dbus_loop_unref (context->loop); 00725 context->loop = NULL; 00726 } 00727 00728 <font class="keywordflow">if</font> (context->matchmaker) 00729 { 00730 bus_matchmaker_unref (context->matchmaker); 00731 context->matchmaker = NULL; 00732 } 00733 00734 dbus_free (context->type); 00735 dbus_free (context->address); 00736 00737 <font class="keywordflow">if</font> (context->pidfile) 00738 { 00739 <a class="code" href="structDBusString.html">DBusString</a> u; 00740 _dbus_string_init_const (&u, context->pidfile); 00741 00742 <font class="comment">/* Deliberately ignore errors here, since there's not much</font> 00743 <font class="comment"> * we can do about it, and we're exiting anyways.</font> 00744 <font class="comment"> */</font> 00745 _dbus_delete_file (&u, NULL); 00746 00747 dbus_free (context->pidfile); 00748 } 00749 00750 _dbus_user_database_unref (context->user_database); 00751 00752 dbus_free (context); 00753 00754 dbus_server_free_data_slot (&server_data_slot); 00755 } 00756 } 00757 00758 <font class="comment">/* type may be NULL */</font> 00759 <font class="keyword">const</font> <font class="keywordtype">char</font>* 00760 bus_context_get_type (BusContext *context) 00761 { 00762 <font class="keywordflow">return</font> context->type; 00763 } 00764 00765 <font class="keyword">const</font> <font class="keywordtype">char</font>* 00766 bus_context_get_address (BusContext *context) 00767 { 00768 <font class="keywordflow">return</font> context->address; 00769 } 00770 00771 BusRegistry* 00772 bus_context_get_registry (BusContext *context) 00773 { 00774 <font class="keywordflow">return</font> context->registry; 00775 } 00776 00777 BusConnections* 00778 bus_context_get_connections (BusContext *context) 00779 { 00780 <font class="keywordflow">return</font> context->connections; 00781 } 00782 00783 BusActivation* 00784 bus_context_get_activation (BusContext *context) 00785 { 00786 <font class="keywordflow">return</font> context->activation; 00787 } 00788 00789 BusMatchmaker* 00790 bus_context_get_matchmaker (BusContext *context) 00791 { 00792 <font class="keywordflow">return</font> context->matchmaker; 00793 } 00794 00795 DBusLoop* 00796 bus_context_get_loop (BusContext *context) 00797 { 00798 <font class="keywordflow">return</font> context->loop; 00799 } 00800 00801 <a class="code" href="structDBusUserDatabase.html">DBusUserDatabase</a>* 00802 bus_context_get_user_database (BusContext *context) 00803 { 00804 <font class="keywordflow">return</font> context->user_database; 00805 } 00806 00807 dbus_bool_t 00808 bus_context_allow_user (BusContext *context, 00809 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> uid) 00810 { 00811 <font class="keywordflow">return</font> bus_policy_allow_user (context->policy, 00812 context->user_database, 00813 uid); 00814 } 00815 00816 BusClientPolicy* 00817 bus_context_create_client_policy (BusContext *context, 00818 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection, 00819 <a class="code" href="structDBusError.html">DBusError</a> *error) 00820 { 00821 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00822 <font class="keywordflow">return</font> bus_policy_create_client_policy (context->policy, connection, 00823 error); 00824 } 00825 00826 <font class="keywordtype">int</font> 00827 bus_context_get_activation_timeout (BusContext *context) 00828 { 00829 00830 <font class="keywordflow">return</font> context->limits.activation_timeout; 00831 } 00832 00833 <font class="keywordtype">int</font> 00834 bus_context_get_auth_timeout (BusContext *context) 00835 { 00836 <font class="keywordflow">return</font> context->limits.auth_timeout; 00837 } 00838 00839 <font class="keywordtype">int</font> 00840 bus_context_get_max_completed_connections (BusContext *context) 00841 { 00842 <font class="keywordflow">return</font> context->limits.max_completed_connections; 00843 } 00844 00845 <font class="keywordtype">int</font> 00846 bus_context_get_max_incomplete_connections (BusContext *context) 00847 { 00848 <font class="keywordflow">return</font> context->limits.max_incomplete_connections; 00849 } 00850 00851 <font class="keywordtype">int</font> 00852 bus_context_get_max_connections_per_user (BusContext *context) 00853 { 00854 <font class="keywordflow">return</font> context->limits.max_connections_per_user; 00855 } 00856 00857 <font class="keywordtype">int</font> 00858 bus_context_get_max_pending_activations (BusContext *context) 00859 { 00860 <font class="keywordflow">return</font> context->limits.max_pending_activations; 00861 } 00862 00863 <font class="keywordtype">int</font> 00864 bus_context_get_max_services_per_connection (BusContext *context) 00865 { 00866 <font class="keywordflow">return</font> context->limits.max_services_per_connection; 00867 } 00868 00869 <font class="keywordtype">int</font> 00870 bus_context_get_max_match_rules_per_connection (BusContext *context) 00871 { 00872 <font class="keywordflow">return</font> context->limits.max_match_rules_per_connection; 00873 } 00874 00875 dbus_bool_t 00876 bus_context_check_security_policy (BusContext *context, 00877 <a class="code" href="structDBusConnection.html">DBusConnection</a> *sender, 00878 <a class="code" href="structDBusConnection.html">DBusConnection</a> *addressed_recipient, 00879 <a class="code" href="structDBusConnection.html">DBusConnection</a> *proposed_recipient, 00880 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message, 00881 <a class="code" href="structDBusError.html">DBusError</a> *error) 00882 { 00883 BusClientPolicy *sender_policy; 00884 BusClientPolicy *recipient_policy; 00885 00886 <font class="comment">/* NULL sender, proposed_recipient means the bus driver. NULL</font> 00887 <font class="comment"> * addressed_recipient means the message didn't specify an explicit</font> 00888 <font class="comment"> * target. If proposed_recipient is NULL, then addressed_recipient</font> 00889 <font class="comment"> * is also NULL but is implicitly the bus driver.</font> 00890 <font class="comment"> */</font> 00891 00892 _dbus_assert (proposed_recipient == NULL || 00893 (dbus_message_get_destination (message) == NULL || 00894 addressed_recipient != NULL)); 00895 00896 <font class="keywordflow">if</font> (sender != NULL) 00897 { 00898 <font class="keywordflow">if</font> (bus_connection_is_active (sender)) 00899 { 00900 sender_policy = bus_connection_get_policy (sender); 00901 _dbus_assert (sender_policy != NULL); 00902 } 00903 <font class="keywordflow">else</font> 00904 { 00905 <font class="comment">/* Policy for inactive connections is that they can only send</font> 00906 <font class="comment"> * the hello message to the bus driver</font> 00907 <font class="comment"> */</font> 00908 <font class="keywordflow">if</font> (proposed_recipient == NULL && 00909 dbus_message_is_method_call (message, 00910 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, 00911 <font class="stringliteral">"Hello"</font>)) 00912 { 00913 _dbus_verbose (<font class="stringliteral">"security check allowing %s message\n"</font>, 00914 <font class="stringliteral">"Hello"</font>); 00915 <font class="keywordflow">return</font> TRUE; 00916 } 00917 <font class="keywordflow">else</font> 00918 { 00919 _dbus_verbose (<font class="stringliteral">"security check disallowing non-%s message\n"</font>, 00920 <font class="stringliteral">"Hello"</font>); 00921 00922 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, 00923 <font class="stringliteral">"Client tried to send a message other than %s without being registered"</font>, 00924 <font class="stringliteral">"Hello"</font>); 00925 00926 <font class="keywordflow">return</font> FALSE; 00927 } 00928 } 00929 } 00930 <font class="keywordflow">else</font> 00931 sender_policy = NULL; 00932 00933 _dbus_assert ((sender != NULL && sender_policy != NULL) || 00934 (sender == NULL && sender_policy == NULL)); 00935 00936 <font class="keywordflow">if</font> (proposed_recipient != NULL) 00937 { 00938 <font class="comment">/* only the bus driver can send to an inactive recipient (as it</font> 00939 <font class="comment"> * owns no services, so other apps can't address it). Inactive</font> 00940 <font class="comment"> * recipients can receive any message.</font> 00941 <font class="comment"> */</font> 00942 <font class="keywordflow">if</font> (bus_connection_is_active (proposed_recipient)) 00943 { 00944 recipient_policy = bus_connection_get_policy (proposed_recipient); 00945 _dbus_assert (recipient_policy != NULL); 00946 } 00947 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (sender == NULL) 00948 { 00949 _dbus_verbose (<font class="stringliteral">"security check using NULL recipient policy for message from bus\n"</font>); 00950 recipient_policy = NULL; 00951 } 00952 <font class="keywordflow">else</font> 00953 { 00954 _dbus_assert_not_reached (<font class="stringliteral">"a message was somehow sent to an inactive recipient from a source other than the message bus\n"</font>); 00955 recipient_policy = NULL; 00956 } 00957 } 00958 <font class="keywordflow">else</font> 00959 recipient_policy = NULL; 00960 00961 _dbus_assert ((proposed_recipient != NULL && recipient_policy != NULL) || 00962 (proposed_recipient != NULL && sender == NULL && recipient_policy == NULL) || 00963 (proposed_recipient == NULL && recipient_policy == NULL)); 00964 00965 <font class="keywordflow">if</font> (sender_policy && 00966 !bus_client_policy_check_can_send (sender_policy, 00967 context->registry, proposed_recipient, 00968 message)) 00969 { 00970 <font class="keyword">const</font> <font class="keywordtype">char</font> *dest = dbus_message_get_destination (message); 00971 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, 00972 <font class="stringliteral">"A security policy in place prevents this sender "</font> 00973 <font class="stringliteral">"from sending this message to this recipient, "</font> 00974 <font class="stringliteral">"see message bus configuration file (rejected message "</font> 00975 <font class="stringliteral">"had interface \"%s\" member \"%s\" error name \"%s\" destination \"%s\")"</font>, 00976 dbus_message_get_interface (message) ? 00977 dbus_message_get_interface (message) : "(unset)", 00978 dbus_message_get_member (message) ? 00979 dbus_message_get_member (message) : "(unset)", 00980 dbus_message_get_error_name (message) ? 00981 dbus_message_get_error_name (message) : "(unset)", 00982 dest ? dest : DBUS_SERVICE_ORG_FREEDESKTOP_DBUS); 00983 _dbus_verbose (<font class="stringliteral">"security policy disallowing message due to sender policy\n"</font>); 00984 <font class="keywordflow">return</font> FALSE; 00985 } 00986 00987 <font class="keywordflow">if</font> (recipient_policy && 00988 !bus_client_policy_check_can_receive (recipient_policy, 00989 context->registry, sender, 00990 addressed_recipient, proposed_recipient, 00991 message)) 00992 { 00993 <font class="keyword">const</font> <font class="keywordtype">char</font> *dest = dbus_message_get_destination (message); 00994 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, 00995 <font class="stringliteral">"A security policy in place prevents this recipient "</font> 00996 <font class="stringliteral">"from receiving this message from this sender, "</font> 00997 <font class="stringliteral">"see message bus configuration file (rejected message "</font> 00998 <font class="stringliteral">"had interface \"%s\" member \"%s\" error name \"%s\" destination \"%s\")"</font>, 00999 dbus_message_get_interface (message) ? 01000 dbus_message_get_interface (message) : "(unset)", 01001 dbus_message_get_member (message) ? 01002 dbus_message_get_member (message) : "(unset)", 01003 dbus_message_get_error_name (message) ? 01004 dbus_message_get_error_name (message) : "(unset)", 01005 dest ? dest : DBUS_SERVICE_ORG_FREEDESKTOP_DBUS); 01006 _dbus_verbose (<font class="stringliteral">"security policy disallowing message due to recipient policy\n"</font>); 01007 <font class="keywordflow">return</font> FALSE; 01008 } 01009 01010 <font class="comment">/* See if limits on size have been exceeded */</font> 01011 <font class="keywordflow">if</font> (proposed_recipient && 01012 dbus_connection_get_outgoing_size (proposed_recipient) > 01013 context->limits.max_outgoing_bytes) 01014 { 01015 <font class="keyword">const</font> <font class="keywordtype">char</font> *dest = dbus_message_get_destination (message); 01016 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED, 01017 <font class="stringliteral">"The destination service \"%s\" has a full message queue"</font>, 01018 dest ? dest : (proposed_recipient ? 01019 bus_connection_get_name (proposed_recipient) : 01020 DBUS_SERVICE_ORG_FREEDESKTOP_DBUS)); 01021 _dbus_verbose (<font class="stringliteral">"security policy disallowing message due to full message queue\n"</font>); 01022 <font class="keywordflow">return</font> FALSE; 01023 } 01024 01025 _dbus_verbose (<font class="stringliteral">"security policy allowing message\n"</font>); 01026 <font class="keywordflow">return</font> TRUE; 01027 } </pre></div><hr><address align="right"><small>Generated on Mon Sep 29 21:30:59 2003 for D-BUS by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 width=110 height=53></a>1.2.15 </small></address> </body> </html>