Coverage report for bus/policy.c.gcov

        -:    0:Source:policy.c
        -:    0:Graph:policy.gcno
        -:    0:Data:policy.gcda
        -:    0:Runs:10117
        -:    0:Programs:2
        -:    1:/* -*- mode: C; c-file-style: "gnu" -*- */
        -:    2:/* policy.c  Bus security policy
        -:    3: *
        -:    4: * Copyright (C) 2003, 2004  Red Hat, Inc.
        -:    5: *
        -:    6: * Licensed under the Academic Free License version 2.1
        -:    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:
        -:   24:#include "policy.h"
        -:   25:#include "services.h"
        -:   26:#include "test.h"
        -:   27:#include "utils.h"
        -:   28:#include <dbus/dbus-list.h>
        -:   29:#include <dbus/dbus-hash.h>
        -:   30:#include <dbus/dbus-internals.h>
        -:   31:
        -:   32:BusPolicyRule*
        -:   33:bus_policy_rule_new (BusPolicyRuleType type,
        -:   34:                     dbus_bool_t       allow)
function bus_policy_rule_new called 69 returned 100% blocks executed 90%
       69:   35:{
        -:   36:  BusPolicyRule *rule;
        -:   37:
       69:   38:  rule = dbus_new0 (BusPolicyRule, 1);
call    0 returned 100%
       69:   39:  if (rule == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:   40:    return NULL;
        -:   41:
       69:   42:  rule->type = type;
       69:   43:  rule->refcount = 1;
       69:   44:  rule->allow = allow;
        -:   45:
       69:   46:  switch (rule->type)
branch  0 taken 22%
branch  1 taken 3%
branch  2 taken 41%
branch  3 taken 20%
branch  4 taken 14%
        -:   47:    {
        -:   48:    case BUS_POLICY_RULE_USER:
       15:   49:      rule->d.user.uid = DBUS_UID_UNSET;
       15:   50:      break;
        -:   51:    case BUS_POLICY_RULE_GROUP:
        2:   52:      rule->d.group.gid = DBUS_GID_UNSET;
        2:   53:      break;
        -:   54:    case BUS_POLICY_RULE_SEND:
       28:   55:      rule->d.send.message_type = DBUS_MESSAGE_TYPE_INVALID;
        -:   56:
        -:   57:      /* allow rules default to TRUE (only requested replies allowed)
        -:   58:       * deny rules default to FALSE (only unrequested replies denied)
        -:   59:       */
       28:   60:      rule->d.send.requested_reply = rule->allow;
       28:   61:      break;
        -:   62:    case BUS_POLICY_RULE_RECEIVE:
       14:   63:      rule->d.receive.message_type = DBUS_MESSAGE_TYPE_INVALID;
        -:   64:      /* allow rules default to TRUE (only requested replies allowed)
        -:   65:       * deny rules default to FALSE (only unrequested replies denied)
        -:   66:       */
       14:   67:      rule->d.receive.requested_reply = rule->allow;
        -:   68:      break;
        -:   69:    case BUS_POLICY_RULE_OWN:
        -:   70:      break;
        -:   71:    }
        -:   72:  
       69:   73:  return rule;
        -:   74:}
        -:   75:
        -:   76:BusPolicyRule *
        -:   77:bus_policy_rule_ref (BusPolicyRule *rule)
function bus_policy_rule_ref called 18446 returned 100% blocks executed 100%
    18446:   78:{
    18446:   79:  _dbus_assert (rule->refcount > 0);
call    0 returned 100%
        -:   80:
    18446:   81:  rule->refcount += 1;
        -:   82:
    18446:   83:  return rule;
        -:   84:}
        -:   85:
        -:   86:void
        -:   87:bus_policy_rule_unref (BusPolicyRule *rule)
function bus_policy_rule_unref called 18515 returned 100% blocks executed 100%
    18515:   88:{
    18515:   89:  _dbus_assert (rule->refcount > 0);
call    0 returned 100%
        -:   90:
    18515:   91:  rule->refcount -= 1;
        -:   92:  
    18515:   93:  if (rule->refcount == 0)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:   94:    {
       69:   95:      switch (rule->type)
branch  0 taken 41%
branch  1 taken 20%
branch  2 taken 14%
branch  3 taken 25%
        -:   96:        {
        -:   97:        case BUS_POLICY_RULE_SEND:
       28:   98:          dbus_free (rule->d.send.path);
call    0 returned 100%
       28:   99:          dbus_free (rule->d.send.interface);
call    0 returned 100%
       28:  100:          dbus_free (rule->d.send.member);
call    0 returned 100%
       28:  101:          dbus_free (rule->d.send.error);
call    0 returned 100%
       28:  102:          dbus_free (rule->d.send.destination);
call    0 returned 100%
       28:  103:          break;
        -:  104:        case BUS_POLICY_RULE_RECEIVE:
       14:  105:          dbus_free (rule->d.receive.path);
call    0 returned 100%
       14:  106:          dbus_free (rule->d.receive.interface);
call    0 returned 100%
       14:  107:          dbus_free (rule->d.receive.member);
call    0 returned 100%
       14:  108:          dbus_free (rule->d.receive.error);
call    0 returned 100%
       14:  109:          dbus_free (rule->d.receive.origin);
call    0 returned 100%
       14:  110:          break;
        -:  111:        case BUS_POLICY_RULE_OWN:
       10:  112:          dbus_free (rule->d.own.service_name);
call    0 returned 100%
        -:  113:          break;
        -:  114:        case BUS_POLICY_RULE_USER:
        -:  115:          break;
        -:  116:        case BUS_POLICY_RULE_GROUP:
        -:  117:          break;
        -:  118:        }
        -:  119:      
       69:  120:      dbus_free (rule);
call    0 returned 100%
        -:  121:    }
    18515:  122:}
        -:  123:
        -:  124:struct BusPolicy
        -:  125:{
        -:  126:  int refcount;
        -:  127:
        -:  128:  DBusList *default_rules;         /**< Default policy rules */
        -:  129:  DBusList *mandatory_rules;       /**< Mandatory policy rules */
        -:  130:  DBusHashTable *rules_by_uid;     /**< per-UID policy rules */
        -:  131:  DBusHashTable *rules_by_gid;     /**< per-GID policy rules */
        -:  132:  DBusList *at_console_true_rules; /**< console user policy rules where at_console="true"*/
        -:  133:  DBusList *at_console_false_rules; /**< console user policy rules where at_console="false"*/
        -:  134:};
        -:  135:
        -:  136:static void
        -:  137:free_rule_func (void *data,
        -:  138:                void *user_data)
function free_rule_func called 74 returned 100% blocks executed 100%
       74:  139:{
       74:  140:  BusPolicyRule *rule = data;
        -:  141:
       74:  142:  bus_policy_rule_unref (rule);
call    0 returned 100%
       74:  143:}
        -:  144:
        -:  145:static void
        -:  146:free_rule_list_func (void *data)
function free_rule_list_func called 4 returned 100% blocks executed 100%
        4:  147:{
        4:  148:  DBusList **list = data;
        -:  149:
        4:  150:  if (list == NULL) /* DBusHashTable is on crack */
branch  0 taken 50% (fallthrough)
branch  1 taken 50%
        2:  151:    return;
        -:  152:  
        2:  153:  _dbus_list_foreach (list, free_rule_func, NULL);
call    0 returned 100%
        -:  154:  
        2:  155:  _dbus_list_clear (list);
call    0 returned 100%
        -:  156:
        2:  157:  dbus_free (list);
call    0 returned 100%
        -:  158:}
        -:  159:
        -:  160:BusPolicy*
        -:  161:bus_policy_new (void)
function bus_policy_new called 45 returned 100% blocks executed 62%
       45:  162:{
        -:  163:  BusPolicy *policy;
        -:  164:
       45:  165:  policy = dbus_new0 (BusPolicy, 1);
call    0 returned 100%
       45:  166:  if (policy == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  167:    return NULL;
        -:  168:
       45:  169:  policy->refcount = 1;
        -:  170:  
       45:  171:  policy->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_ULONG,
call    0 returned 100%
        -:  172:                                               NULL,
        -:  173:                                               free_rule_list_func);
       45:  174:  if (policy->rules_by_uid == NULL)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
    #####:  175:    goto failed;
        -:  176:
       45:  177:  policy->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_ULONG,
call    0 returned 100%
        -:  178:                                               NULL,
        -:  179:                                               free_rule_list_func);
       45:  180:  if (policy->rules_by_gid == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  181:    goto failed;
        -:  182:
       45:  183:  return policy;
        -:  184:  
    #####:  185: failed:
    #####:  186:  bus_policy_unref (policy);
call    0 never executed
    #####:  187:  return NULL;
        -:  188:}
        -:  189:
        -:  190:BusPolicy *
        -:  191:bus_policy_ref (BusPolicy *policy)
function bus_policy_ref called 0 returned 0% blocks executed 0%
    #####:  192:{
    #####:  193:  _dbus_assert (policy->refcount > 0);
call    0 never executed
        -:  194:
    #####:  195:  policy->refcount += 1;
        -:  196:
    #####:  197:  return policy;
        -:  198:}
        -:  199:
        -:  200:void
        -:  201:bus_policy_unref (BusPolicy *policy)
function bus_policy_unref called 45 returned 100% blocks executed 100%
       45:  202:{
       45:  203:  _dbus_assert (policy->refcount > 0);
call    0 returned 100%
        -:  204:
       45:  205:  policy->refcount -= 1;
        -:  206:
       45:  207:  if (policy->refcount == 0)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:  208:    {
       45:  209:      _dbus_list_foreach (&policy->default_rules, free_rule_func, NULL);
call    0 returned 100%
       45:  210:      _dbus_list_clear (&policy->default_rules);
call    0 returned 100%
        -:  211:
       45:  212:      _dbus_list_foreach (&policy->mandatory_rules, free_rule_func, NULL);
call    0 returned 100%
       45:  213:      _dbus_list_clear (&policy->mandatory_rules);
call    0 returned 100%
        -:  214:
       45:  215:      _dbus_list_foreach (&policy->at_console_true_rules, free_rule_func, NULL);
call    0 returned 100%
       45:  216:      _dbus_list_clear (&policy->at_console_true_rules);
call    0 returned 100%
        -:  217:
       45:  218:      _dbus_list_foreach (&policy->at_console_false_rules, free_rule_func, NULL);
call    0 returned 100%
       45:  219:      _dbus_list_clear (&policy->at_console_false_rules);
call    0 returned 100%
        -:  220:
       45:  221:      if (policy->rules_by_uid)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:  222:        {
       45:  223:          _dbus_hash_table_unref (policy->rules_by_uid);
call    0 returned 100%
       45:  224:          policy->rules_by_uid = NULL;
        -:  225:        }
        -:  226:
       45:  227:      if (policy->rules_by_gid)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:  228:        {
       45:  229:          _dbus_hash_table_unref (policy->rules_by_gid);
call    0 returned 100%
       45:  230:          policy->rules_by_gid = NULL;
        -:  231:        }
        -:  232:      
       45:  233:      dbus_free (policy);
call    0 returned 100%
        -:  234:    }
       45:  235:}
        -:  236:
        -:  237:static dbus_bool_t
        -:  238:add_list_to_client (DBusList        **list,
        -:  239:                    BusClientPolicy  *client)
function add_list_to_client called 18330 returned 100% blocks executed 100%
    18330:  240:{
        -:  241:  DBusList *link;
        -:  242:
    18330:  243:  link = _dbus_list_get_first_link (list);
call    0 returned 100%
    61148:  244:  while (link != NULL)
branch  0 taken 57%
branch  1 taken 43% (fallthrough)
        -:  245:    {
    24509:  246:      BusPolicyRule *rule = link->data;
    24509:  247:      link = _dbus_list_get_next_link (list, link);
branch  0 taken 75% (fallthrough)
branch  1 taken 25%
        -:  248:
    24509:  249:      switch (rule->type)
branch  0 taken 25%
branch  1 taken 75%
branch  2 taken 0%
        -:  250:        {
        -:  251:        case BUS_POLICY_RULE_USER:
        -:  252:        case BUS_POLICY_RULE_GROUP:
        -:  253:          /* These aren't per-connection policies */
     6116:  254:          break;
        -:  255:
        -:  256:        case BUS_POLICY_RULE_OWN:
        -:  257:        case BUS_POLICY_RULE_SEND:
        -:  258:        case BUS_POLICY_RULE_RECEIVE:
        -:  259:          /* These are per-connection */
    18393:  260:          if (!bus_client_policy_append_rule (client, rule))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
       21:  261:            return FALSE;
        -:  262:          break;
        -:  263:        }
        -:  264:    }
        -:  265:  
    18309:  266:  return TRUE;
        -:  267:}
        -:  268:
        -:  269:BusClientPolicy*
        -:  270:bus_policy_create_client_policy (BusPolicy      *policy,
        -:  271:                                 DBusConnection *connection,
        -:  272:                                 DBusError      *error)
function bus_policy_create_client_policy called 6145 returned 100% blocks executed 60%
     6145:  273:{
        -:  274:  BusClientPolicy *client;
        -:  275:  dbus_uid_t uid;
        -:  276:  dbus_bool_t at_console;
        -:  277:
     6145:  278:  _dbus_assert (dbus_connection_get_is_authenticated (connection));
call    0 returned 100%
call    1 returned 100%
     6145:  279:  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
call    2 returned 100%
branch  3 taken 100% (fallthrough)
branch  4 taken 0%
call    5 returned 100%
        -:  280:  
     6145:  281:  client = bus_client_policy_new ();
call    0 returned 100%
     6145:  282:  if (client == NULL)
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
        7:  283:    goto nomem;
        -:  284:
     6138:  285:  if (!add_list_to_client (&policy->default_rules,
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  286:                           client))
       21:  287:    goto nomem;
        -:  288:
        -:  289:  /* we avoid the overhead of looking up user's groups
        -:  290:   * if we don't have any group rules anyway
        -:  291:   */
     6117:  292:  if (_dbus_hash_table_get_n_entries (policy->rules_by_gid) > 0)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  293:    {
        -:  294:      unsigned long *groups;
        -:  295:      int n_groups;
        -:  296:      int i;
        -:  297:      
    #####:  298:      if (!bus_connection_get_groups (connection, &groups, &n_groups, error))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  299:        goto failed;
        -:  300:      
    #####:  301:      i = 0;
    #####:  302:      while (i < n_groups)
branch  0 never executed
branch  1 never executed
        -:  303:        {
        -:  304:          DBusList **list;
        -:  305:          
    #####:  306:          list = _dbus_hash_table_lookup_ulong (policy->rules_by_gid,
call    0 never executed
        -:  307:                                                groups[i]);
        -:  308:          
    #####:  309:          if (list != NULL)
branch  0 never executed
branch  1 never executed
        -:  310:            {
    #####:  311:              if (!add_list_to_client (list, client))
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  312:                {
    #####:  313:                  dbus_free (groups);
call    0 never executed
    #####:  314:                  goto nomem;
        -:  315:                }
        -:  316:            }
        -:  317:          
    #####:  318:          ++i;
        -:  319:        }
        -:  320:
    #####:  321:      dbus_free (groups);
call    0 never executed
        -:  322:    }
        -:  323:
     6117:  324:  if (!dbus_connection_get_unix_user (connection, &uid))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  325:    {
    #####:  326:      dbus_set_error (error, DBUS_ERROR_FAILED,
call    0 never executed
        -:  327:                      "No user ID known for connection, cannot determine security policy\n");
    #####:  328:      goto failed;
        -:  329:    }
        -:  330:
     6117:  331:  if (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  332:    {
        -:  333:      DBusList **list;
        -:  334:      
    #####:  335:      list = _dbus_hash_table_lookup_ulong (policy->rules_by_uid,
call    0 never executed
        -:  336:                                            uid);
        -:  337:
    #####:  338:      if (list != NULL)
branch  0 never executed
branch  1 never executed
        -:  339:        {
    #####:  340:          if (!add_list_to_client (list, client))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  341:            goto nomem;
        -:  342:        }
        -:  343:    }
        -:  344:
        -:  345:  /* Add console rules */
     6117:  346:  at_console = _dbus_is_console_user (uid, error);
call    0 returned 100%
        -:  347:
     6117:  348:  if (at_console)
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
        -:  349:    {
     6096:  350:      if (!add_list_to_client (&policy->at_console_true_rules, client))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  351:        goto nomem;
        -:  352:    }
       21:  353:  else if (dbus_error_is_set (error) == TRUE)
call    0 returned 100%
branch  1 taken 100% (fallthrough)
branch  2 taken 0%
        -:  354:    {
       21:  355:      goto failed;
        -:  356:    }
    #####:  357:  else if (!add_list_to_client (&policy->at_console_false_rules, client))
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  358:    {
    #####:  359:      goto nomem;
        -:  360:    }
        -:  361:
     6096:  362:  if (!add_list_to_client (&policy->mandatory_rules,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  363:                           client))
    #####:  364:    goto nomem;
        -:  365:
     6096:  366:  bus_client_policy_optimize (client);
call    0 returned 100%
        -:  367:  
     6096:  368:  return client;
        -:  369:
       28:  370: nomem:
       28:  371:  BUS_SET_OOM (error);
call    0 returned 100%
       49:  372: failed:
       49:  373:  _DBUS_ASSERT_ERROR_IS_SET (error);
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
call    2 returned 100%
branch  3 taken 100% (fallthrough)
branch  4 taken 0%
call    5 returned 100%
       49:  374:  if (client)
branch  0 taken 86% (fallthrough)
branch  1 taken 14%
       42:  375:    bus_client_policy_unref (client);
call    0 returned 100%
       49:  376:  return NULL;
        -:  377:}
        -:  378:
        -:  379:static dbus_bool_t
        -:  380:list_allows_user (dbus_bool_t           def,
        -:  381:                  DBusList            **list,
        -:  382:                  unsigned long         uid,
        -:  383:                  const unsigned long  *group_ids,
        -:  384:                  int                   n_group_ids)
function list_allows_user called 12406 returned 100% blocks executed 56%
    12406:  385:{
        -:  386:  DBusList *link;
        -:  387:  dbus_bool_t allowed;
        -:  388:  
    12406:  389:  allowed = def;
        -:  390:
    12406:  391:  link = _dbus_list_get_first_link (list);
call    0 returned 100%
    49623:  392:  while (link != NULL)
branch  0 taken 67%
branch  1 taken 33% (fallthrough)
        -:  393:    {
    24811:  394:      BusPolicyRule *rule = link->data;
    24811:  395:      link = _dbus_list_get_next_link (list, link);
branch  0 taken 75% (fallthrough)
branch  1 taken 25%
        -:  396:
    24811:  397:      if (rule->type == BUS_POLICY_RULE_USER)
branch  0 taken 25% (fallthrough)
branch  1 taken 75%
        -:  398:        {
     6202:  399:          _dbus_verbose ("List %p user rule uid="DBUS_UID_FORMAT"\n",
call    0 returned 100%
        -:  400:                         list, rule->d.user.uid);
        -:  401:          
     6202:  402:          if (rule->d.user.uid == DBUS_UID_UNSET)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  403:            ; /* '*' wildcard */
    #####:  404:          else if (rule->d.user.uid != uid)
branch  0 never executed
branch  1 never executed
    #####:  405:            continue;
        -:  406:        }
    18609:  407:      else if (rule->type == BUS_POLICY_RULE_GROUP)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:  408:        {
    #####:  409:          _dbus_verbose ("List %p group rule uid="DBUS_UID_FORMAT"\n",
call    0 never executed
        -:  410:                         list, rule->d.user.uid);
        -:  411:          
    #####:  412:          if (rule->d.group.gid == DBUS_GID_UNSET)
branch  0 never executed
branch  1 never executed
        -:  413:            ;  /* '*' wildcard */
        -:  414:          else
        -:  415:            {
        -:  416:              int i;
        -:  417:              
    #####:  418:              i = 0;
    #####:  419:              while (i < n_group_ids)
branch  0 never executed
branch  1 never executed
        -:  420:                {
    #####:  421:                  if (rule->d.group.gid == group_ids[i])
branch  0 never executed
branch  1 never executed
    #####:  422:                    break;
    #####:  423:                  ++i;
        -:  424:                }
        -:  425:              
    #####:  426:              if (i == n_group_ids)
branch  0 never executed
branch  1 never executed
    #####:  427:                continue;
        -:  428:            }
        -:  429:        }
        -:  430:      else
    18609:  431:        continue;
        -:  432:
     6202:  433:      allowed = rule->allow;
        -:  434:    }
        -:  435:  
    12406:  436:  return allowed;
        -:  437:}
        -:  438:
        -:  439:dbus_bool_t
        -:  440:bus_policy_allow_user (BusPolicy        *policy,
        -:  441:                       DBusUserDatabase *user_database,
        -:  442:                       unsigned long     uid)
function bus_policy_allow_user called 6210 returned 100% blocks executed 100%
     6210:  443:{
        -:  444:  dbus_bool_t allowed;
        -:  445:  unsigned long *group_ids;
        -:  446:  int n_group_ids;
        -:  447:
        -:  448:  /* On OOM or error we always reject the user */
     6210:  449:  if (!_dbus_user_database_get_groups (user_database,
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  450:                                       uid, &group_ids, &n_group_ids, NULL))
        -:  451:    {
        7:  452:      _dbus_verbose ("Did not get any groups for UID %lu\n",
call    0 returned 100%
        -:  453:                     uid);
        7:  454:      return FALSE;
        -:  455:    }
        -:  456:
        -:  457:  /* Default to "user owning bus" or root can connect */
     6203:  458:  allowed = uid == _dbus_getuid ();
call    0 returned 100%
        -:  459:
     6203:  460:  allowed = list_allows_user (allowed,
call    0 returned 100%
        -:  461:                              &policy->default_rules,
        -:  462:                              uid,
        -:  463:                              group_ids, n_group_ids);
        -:  464:
     6203:  465:  allowed = list_allows_user (allowed,
call    0 returned 100%
        -:  466:                              &policy->mandatory_rules,
        -:  467:                              uid,
        -:  468:                              group_ids, n_group_ids);
        -:  469:
     6203:  470:  dbus_free (group_ids);
call    0 returned 100%
        -:  471:
     6203:  472:  _dbus_verbose ("UID %lu allowed = %d\n", uid, allowed);
call    0 returned 100%
        -:  473:  
     6203:  474:  return allowed;
        -:  475:}
        -:  476:
        -:  477:dbus_bool_t
        -:  478:bus_policy_append_default_rule (BusPolicy      *policy,
        -:  479:                                BusPolicyRule  *rule)
function bus_policy_append_default_rule called 52 returned 100% blocks executed 83%
       52:  480:{
       52:  481:  if (!_dbus_list_append (&policy->default_rules, rule))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  482:    return FALSE;
        -:  483:
       52:  484:  bus_policy_rule_ref (rule);
call    0 returned 100%
        -:  485:
       52:  486:  return TRUE;
        -:  487:}
        -:  488:
        -:  489:dbus_bool_t
        -:  490:bus_policy_append_mandatory_rule (BusPolicy      *policy,
        -:  491:                                  BusPolicyRule  *rule)
function bus_policy_append_mandatory_rule called 15 returned 100% blocks executed 83%
       15:  492:{
       15:  493:  if (!_dbus_list_append (&policy->mandatory_rules, rule))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  494:    return FALSE;
        -:  495:
       15:  496:  bus_policy_rule_ref (rule);
call    0 returned 100%
        -:  497:
       15:  498:  return TRUE;
        -:  499:}
        -:  500:
        -:  501:
        -:  502:
        -:  503:static DBusList**
        -:  504:get_list (DBusHashTable *hash,
        -:  505:          unsigned long  key)
function get_list called 3 returned 100% blocks executed 73%
        3:  506:{
        -:  507:  DBusList **list;
        -:  508:
        3:  509:  list = _dbus_hash_table_lookup_ulong (hash, key);
call    0 returned 100%
        -:  510:
        3:  511:  if (list == NULL)
branch  0 taken 67% (fallthrough)
branch  1 taken 33%
        -:  512:    {
        2:  513:      list = dbus_new0 (DBusList*, 1);
call    0 returned 100%
        2:  514:      if (list == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  515:        return NULL;
        -:  516:
        2:  517:      if (!_dbus_hash_table_insert_ulong (hash, key, list))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  518:        {
    #####:  519:          dbus_free (list);
call    0 never executed
    #####:  520:          return NULL;
        -:  521:        }
        -:  522:    }
        -:  523:
        3:  524:  return list;
        -:  525:}
        -:  526:
        -:  527:dbus_bool_t
        -:  528:bus_policy_append_user_rule (BusPolicy      *policy,
        -:  529:                             dbus_uid_t      uid,
        -:  530:                             BusPolicyRule  *rule)
function bus_policy_append_user_rule called 2 returned 100% blocks executed 78%
        2:  531:{
        -:  532:  DBusList **list;
        -:  533:
        2:  534:  list = get_list (policy->rules_by_uid, uid);
call    0 returned 100%
        -:  535:
        2:  536:  if (list == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  537:    return FALSE;
        -:  538:
        2:  539:  if (!_dbus_list_append (list, rule))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  540:    return FALSE;
        -:  541:
        2:  542:  bus_policy_rule_ref (rule);
call    0 returned 100%
        -:  543:
        2:  544:  return TRUE;
        -:  545:}
        -:  546:
        -:  547:dbus_bool_t
        -:  548:bus_policy_append_group_rule (BusPolicy      *policy,
        -:  549:                              dbus_gid_t      gid,
        -:  550:                              BusPolicyRule  *rule)
function bus_policy_append_group_rule called 0 returned 0% blocks executed 0%
    #####:  551:{
        -:  552:  DBusList **list;
        -:  553:
    #####:  554:  list = get_list (policy->rules_by_gid, gid);
call    0 never executed
        -:  555:
    #####:  556:  if (list == NULL)
branch  0 never executed
branch  1 never executed
    #####:  557:    return FALSE;
        -:  558:
    #####:  559:  if (!_dbus_list_append (list, rule))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  560:    return FALSE;
        -:  561:
    #####:  562:  bus_policy_rule_ref (rule);
call    0 never executed
        -:  563:
    #####:  564:  return TRUE;
        -:  565:}
        -:  566:
        -:  567:dbus_bool_t
        -:  568:bus_policy_append_console_rule (BusPolicy      *policy,
        -:  569:                                dbus_bool_t     at_console,
        -:  570:                                BusPolicyRule  *rule)
function bus_policy_append_console_rule called 0 returned 0% blocks executed 0%
    #####:  571:{
    #####:  572:  if (at_console)
branch  0 never executed
branch  1 never executed
        -:  573:    {
    #####:  574:      if (!_dbus_list_append (&policy->at_console_true_rules, rule))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  575:        return FALSE;
        -:  576:    }
        -:  577:    else
        -:  578:    {
    #####:  579:      if (!_dbus_list_append (&policy->at_console_false_rules, rule))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  580:        return FALSE;
        -:  581:    }
        -:  582:
    #####:  583:  bus_policy_rule_ref (rule);
call    0 never executed
        -:  584:
    #####:  585:  return TRUE;
        -:  586:
        -:  587:}
        -:  588:
        -:  589:static dbus_bool_t
        -:  590:append_copy_of_policy_list (DBusList **list,
        -:  591:                            DBusList **to_append)
function append_copy_of_policy_list called 13 returned 100% blocks executed 89%
       13:  592:{
        -:  593:  DBusList *link;
        -:  594:  DBusList *tmp_list;
        -:  595:
       13:  596:  tmp_list = NULL;
        -:  597:
        -:  598:  /* Preallocate all our links */
       13:  599:  link = _dbus_list_get_first_link (to_append);
call    0 returned 100%
       31:  600:  while (link != NULL)
branch  0 taken 28%
branch  1 taken 72% (fallthrough)
        -:  601:    {
        5:  602:      if (!_dbus_list_append (&tmp_list, link->data))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  603:        {
    #####:  604:          _dbus_list_clear (&tmp_list);
call    0 never executed
    #####:  605:          return FALSE;
        -:  606:        }
        -:  607:      
        5:  608:      link = _dbus_list_get_next_link (to_append, link);
branch  0 taken 20% (fallthrough)
branch  1 taken 80%
        -:  609:    }
        -:  610:
        -:  611:  /* Now append them */
       31:  612:  while ((link = _dbus_list_pop_first_link (&tmp_list)))
call    0 returned 100%
branch  1 taken 28%
branch  2 taken 72% (fallthrough)
        -:  613:    {
        5:  614:      bus_policy_rule_ref (link->data);
call    0 returned 100%
        5:  615:      _dbus_list_append_link (list, link);
call    0 returned 100%
        -:  616:    }
        -:  617:
       13:  618:  return TRUE;
        -:  619:}
        -:  620:
        -:  621:static dbus_bool_t
        -:  622:merge_id_hash (DBusHashTable *dest,
        -:  623:               DBusHashTable *to_absorb)
function merge_id_hash called 6 returned 100% blocks executed 86%
        6:  624:{
        -:  625:  DBusHashIter iter;
        -:  626:  
        6:  627:  _dbus_hash_iter_init (to_absorb, &iter);
call    0 returned 100%
        6:  628:  while (_dbus_hash_iter_next (&iter))
call    0 returned 100%
branch  1 taken 14%
branch  2 taken 86% (fallthrough)
        -:  629:    {
        1:  630:      unsigned long id = _dbus_hash_iter_get_ulong_key (&iter);
call    0 returned 100%
        1:  631:      DBusList **list = _dbus_hash_iter_get_value (&iter);
call    0 returned 100%
        1:  632:      DBusList **target = get_list (dest, id);
call    0 returned 100%
        -:  633:
        1:  634:      if (target == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  635:        return FALSE;
        -:  636:
        1:  637:      if (!append_copy_of_policy_list (target, list))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  638:        return FALSE;
        -:  639:    }
        -:  640:
        6:  641:  return TRUE;
        -:  642:}
        -:  643:
        -:  644:dbus_bool_t
        -:  645:bus_policy_merge (BusPolicy *policy,
        -:  646:                  BusPolicy *to_absorb)
function bus_policy_merge called 3 returned 100% blocks executed 70%
        3:  647:{
        -:  648:  /* FIXME Not properly atomic, but as used for configuration files we
        -:  649:   * don't rely on it quite so much.
        -:  650:   */
        -:  651:  
        3:  652:  if (!append_copy_of_policy_list (&policy->default_rules,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  653:                                   &to_absorb->default_rules))
    #####:  654:    return FALSE;
        -:  655:  
        3:  656:  if (!append_copy_of_policy_list (&policy->mandatory_rules,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  657:                                   &to_absorb->mandatory_rules))
    #####:  658:    return FALSE;
        -:  659:
        3:  660:  if (!append_copy_of_policy_list (&policy->at_console_true_rules,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  661:                                   &to_absorb->at_console_true_rules))
    #####:  662:    return FALSE;
        -:  663:
        3:  664:  if (!append_copy_of_policy_list (&policy->at_console_false_rules,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  665:                                   &to_absorb->at_console_false_rules))
    #####:  666:    return FALSE;
        -:  667:
        3:  668:  if (!merge_id_hash (policy->rules_by_uid,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  669:                      to_absorb->rules_by_uid))
    #####:  670:    return FALSE;
        -:  671:  
        3:  672:  if (!merge_id_hash (policy->rules_by_gid,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  673:                      to_absorb->rules_by_gid))
    #####:  674:    return FALSE;
        -:  675:
        3:  676:  return TRUE;
        -:  677:}
        -:  678:
        -:  679:struct BusClientPolicy
        -:  680:{
        -:  681:  int refcount;
        -:  682:
        -:  683:  DBusList *rules;
        -:  684:};
        -:  685:
        -:  686:BusClientPolicy*
        -:  687:bus_client_policy_new (void)
function bus_client_policy_new called 6145 returned 100% blocks executed 100%
     6145:  688:{
        -:  689:  BusClientPolicy *policy;
        -:  690:
     6145:  691:  policy = dbus_new0 (BusClientPolicy, 1);
call    0 returned 100%
     6145:  692:  if (policy == NULL)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        7:  693:    return NULL;
        -:  694:
     6138:  695:  policy->refcount = 1;
        -:  696:
     6138:  697:  return policy;
        -:  698:}
        -:  699:
        -:  700:BusClientPolicy *
        -:  701:bus_client_policy_ref (BusClientPolicy *policy)
function bus_client_policy_ref called 0 returned 0% blocks executed 0%
    #####:  702:{
    #####:  703:  _dbus_assert (policy->refcount > 0);
call    0 never executed
        -:  704:
    #####:  705:  policy->refcount += 1;
        -:  706:
    #####:  707:  return policy;
        -:  708:}
        -:  709:
        -:  710:static void
        -:  711:rule_unref_foreach (void *data,
        -:  712:                    void *user_data)
function rule_unref_foreach called 18372 returned 100% blocks executed 100%
    18372:  713:{
    18372:  714:  BusPolicyRule *rule = data;
        -:  715:
    18372:  716:  bus_policy_rule_unref (rule);
call    0 returned 100%
    18372:  717:}
        -:  718:
        -:  719:void
        -:  720:bus_client_policy_unref (BusClientPolicy *policy)
function bus_client_policy_unref called 6138 returned 100% blocks executed 100%
     6138:  721:{
     6138:  722:  _dbus_assert (policy->refcount > 0);
call    0 returned 100%
        -:  723:
     6138:  724:  policy->refcount -= 1;
        -:  725:
     6138:  726:  if (policy->refcount == 0)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:  727:    {
     6138:  728:      _dbus_list_foreach (&policy->rules,
call    0 returned 100%
        -:  729:                          rule_unref_foreach,
        -:  730:                          NULL);
        -:  731:
     6138:  732:      _dbus_list_clear (&policy->rules);
call    0 returned 100%
        -:  733:
     6138:  734:      dbus_free (policy);
call    0 returned 100%
        -:  735:    }
     6138:  736:}
        -:  737:
        -:  738:static void
        -:  739:remove_rules_by_type_up_to (BusClientPolicy   *policy,
        -:  740:                            BusPolicyRuleType  type,
        -:  741:                            DBusList          *up_to)
function remove_rules_by_type_up_to called 18288 returned 100% blocks executed 73%
    18288:  742:{
        -:  743:  DBusList *link;
        -:  744:
    18288:  745:  link = _dbus_list_get_first_link (&policy->rules);
call    0 returned 100%
    54864:  746:  while (link != up_to)
branch  0 taken 50%
branch  1 taken 50% (fallthrough)
        -:  747:    {
    18288:  748:      BusPolicyRule *rule = link->data;
    18288:  749:      DBusList *next = _dbus_list_get_next_link (&policy->rules, link);
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:  750:
    18288:  751:      if (rule->type == type)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  752:        {
    #####:  753:          _dbus_list_remove_link (&policy->rules, link);
call    0 never executed
    #####:  754:          bus_policy_rule_unref (rule);
call    0 never executed
        -:  755:        }
        -:  756:      
    18288:  757:      link = next;
        -:  758:    }
    18288:  759:}
        -:  760:
        -:  761:void
        -:  762:bus_client_policy_optimize (BusClientPolicy *policy)
function bus_client_policy_optimize called 6096 returned 100% blocks executed 92%
     6096:  763:{
        -:  764:  DBusList *link;
        -:  765:
        -:  766:  /* The idea here is that if we have:
        -:  767:   * 
        -:  768:   * <allow send_interface="foo.bar"/>
        -:  769:   * <deny send_interface="*"/>
        -:  770:   *
        -:  771:   * (for example) the deny will always override the allow.  So we
        -:  772:   * delete the allow. Ditto for deny followed by allow, etc. This is
        -:  773:   * a dumb thing to put in a config file, but the <include> feature
        -:  774:   * of files allows for an "inheritance and override" pattern where
        -:  775:   * it could make sense. If an included file wants to "start over"
        -:  776:   * with a blanket deny, no point keeping the rules from the parent
        -:  777:   * file.
        -:  778:   */
        -:  779:
     6096:  780:  _dbus_verbose ("Optimizing policy with %d rules\n",
call    0 returned 100%
call    1 returned 100%
        -:  781:                 _dbus_list_get_length (&policy->rules));
        -:  782:  
     6096:  783:  link = _dbus_list_get_first_link (&policy->rules);
call    0 returned 100%
    30480:  784:  while (link != NULL)
branch  0 taken 75%
branch  1 taken 25% (fallthrough)
        -:  785:    {
        -:  786:      BusPolicyRule *rule;
        -:  787:      DBusList *next;
        -:  788:      dbus_bool_t remove_preceding;
        -:  789:
    18288:  790:      next = _dbus_list_get_next_link (&policy->rules, link);
branch  0 taken 67% (fallthrough)
branch  1 taken 33%
    18288:  791:      rule = link->data;
        -:  792:      
    18288:  793:      remove_preceding = FALSE;
        -:  794:
    18288:  795:      _dbus_assert (rule != NULL);
call    0 returned 100%
        -:  796:      
    18288:  797:      switch (rule->type)
branch  0 taken 33%
branch  1 taken 33%
branch  2 taken 33%
branch  3 taken 0%
branch  4 taken 0%
        -:  798:        {
        -:  799:        case BUS_POLICY_RULE_SEND:
     6096:  800:          remove_preceding =
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
branch  4 taken 100% (fallthrough)
branch  5 taken 0%
branch  6 taken 100% (fallthrough)
branch  7 taken 0%
branch  8 taken 100% (fallthrough)
branch  9 taken 0%
branch 10 taken 100% (fallthrough)
branch 11 taken 0%
        -:  801:            rule->d.send.message_type == DBUS_MESSAGE_TYPE_INVALID &&
        -:  802:            rule->d.send.path == NULL &&
        -:  803:            rule->d.send.interface == NULL &&
        -:  804:            rule->d.send.member == NULL &&
        -:  805:            rule->d.send.error == NULL &&
        -:  806:            rule->d.send.destination == NULL;
     6096:  807:          break;
        -:  808:        case BUS_POLICY_RULE_RECEIVE:
     6096:  809:          remove_preceding =
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
branch  4 taken 100% (fallthrough)
branch  5 taken 0%
branch  6 taken 100% (fallthrough)
branch  7 taken 0%
branch  8 taken 100% (fallthrough)
branch  9 taken 0%
branch 10 taken 100% (fallthrough)
branch 11 taken 0%
        -:  810:            rule->d.receive.message_type == DBUS_MESSAGE_TYPE_INVALID &&
        -:  811:            rule->d.receive.path == NULL &&
        -:  812:            rule->d.receive.interface == NULL &&
        -:  813:            rule->d.receive.member == NULL &&
        -:  814:            rule->d.receive.error == NULL &&
        -:  815:            rule->d.receive.origin == NULL;
     6096:  816:          break;
        -:  817:        case BUS_POLICY_RULE_OWN:
     6096:  818:          remove_preceding =
        -:  819:            rule->d.own.service_name == NULL;
     6096:  820:          break;
        -:  821:        case BUS_POLICY_RULE_USER:
        -:  822:        case BUS_POLICY_RULE_GROUP:
    #####:  823:          _dbus_assert_not_reached ("invalid rule");
call    0 never executed
        -:  824:          break;
        -:  825:        }
        -:  826:
    18288:  827:      if (remove_preceding)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
    18288:  828:        remove_rules_by_type_up_to (policy, rule->type,
call    0 returned 100%
        -:  829:                                    link);
        -:  830:      
    18288:  831:      link = next;
        -:  832:    }
        -:  833:
     6096:  834:  _dbus_verbose ("After optimization, policy has %d rules\n",
call    0 returned 100%
call    1 returned 100%
        -:  835:                 _dbus_list_get_length (&policy->rules));
     6096:  836:}
        -:  837:
        -:  838:dbus_bool_t
        -:  839:bus_client_policy_append_rule (BusClientPolicy *policy,
        -:  840:                               BusPolicyRule   *rule)
function bus_client_policy_append_rule called 18393 returned 100% blocks executed 100%
    18393:  841:{
    18393:  842:  _dbus_verbose ("Appending rule %p with type %d to policy %p\n",
call    0 returned 100%
        -:  843:                 rule, rule->type, policy);
        -:  844:  
    18393:  845:  if (!_dbus_list_append (&policy->rules, rule))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
       21:  846:    return FALSE;
        -:  847:
    18372:  848:  bus_policy_rule_ref (rule);
call    0 returned 100%
        -:  849:
    18372:  850:  return TRUE;
        -:  851:}
        -:  852:
        -:  853:dbus_bool_t
        -:  854:bus_client_policy_check_can_send (BusClientPolicy *policy,
        -:  855:                                  BusRegistry     *registry,
        -:  856:                                  dbus_bool_t      requested_reply,
        -:  857:                                  DBusConnection  *receiver,
        -:  858:                                  DBusMessage     *message)
function bus_client_policy_check_can_send called 47849 returned 100% blocks executed 35%
    47849:  859:{
        -:  860:  DBusList *link;
        -:  861:  dbus_bool_t allowed;
        -:  862:  
        -:  863:  /* policy->rules is in the order the rules appeared
        -:  864:   * in the config file, i.e. last rule that applies wins
        -:  865:   */
        -:  866:
    47849:  867:  _dbus_verbose ("  (policy) checking send rules\n");
call    0 returned 100%
        -:  868:  
    47849:  869:  allowed = FALSE;
    47849:  870:  link = _dbus_list_get_first_link (&policy->rules);
call    0 returned 100%
   239245:  871:  while (link != NULL)
branch  0 taken 75%
branch  1 taken 25% (fallthrough)
        -:  872:    {
   143547:  873:      BusPolicyRule *rule = link->data;
        -:  874:
   143547:  875:      link = _dbus_list_get_next_link (&policy->rules, link);
branch  0 taken 67% (fallthrough)
branch  1 taken 33%
        -:  876:      
        -:  877:      /* Rule is skipped if it specifies a different
        -:  878:       * message name from the message, or a different
        -:  879:       * destination from the message
        -:  880:       */
        -:  881:      
   143547:  882:      if (rule->type != BUS_POLICY_RULE_SEND)
branch  0 taken 67% (fallthrough)
branch  1 taken 33%
        -:  883:        {
    95698:  884:          _dbus_verbose ("  (policy) skipping non-send rule\n");
call    0 returned 100%
    95698:  885:          continue;
        -:  886:        }
        -:  887:
    47849:  888:      if (rule->d.send.message_type != DBUS_MESSAGE_TYPE_INVALID)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  889:        {
    #####:  890:          if (dbus_message_get_type (message) != rule->d.send.message_type)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  891:            {
    #####:  892:              _dbus_verbose ("  (policy) skipping rule for different message type\n");
call    0 never executed
    #####:  893:              continue;
        -:  894:            }
        -:  895:        }
        -:  896:
        -:  897:      /* If it's a reply, the requested_reply flag kicks in */
    47849:  898:      if (dbus_message_get_reply_serial (message) != 0)
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  899:        {
        -:  900:          /* for allow, requested_reply=true means the rule applies
        -:  901:           * only when reply was requested. requested_reply=false means
        -:  902:           * always allow.
        -:  903:           */
       13:  904:          if (!requested_reply && rule->allow && rule->d.send.requested_reply)
branch  0 taken 69% (fallthrough)
branch  1 taken 31%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
branch  4 taken 100% (fallthrough)
branch  5 taken 0%
        -:  905:            {
        9:  906:              _dbus_verbose ("  (policy) skipping allow rule since it only applies to requested replies\n");
call    0 returned 100%
        9:  907:              continue;
        -:  908:            }
        -:  909:
        -:  910:          /* for deny, requested_reply=false means the rule applies only
        -:  911:           * when the reply was not requested. requested_reply=true means the
        -:  912:           * rule always applies.
        -:  913:           */
        4:  914:          if (requested_reply && !rule->allow && !rule->d.send.requested_reply)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
branch  4 never executed
branch  5 never executed
        -:  915:            {
    #####:  916:              _dbus_verbose ("  (policy) skipping deny rule since it only applies to unrequested replies\n");
call    0 never executed
    #####:  917:              continue;
        -:  918:            }
        -:  919:        }
        -:  920:      
    47840:  921:      if (rule->d.send.path != NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  922:        {
    #####:  923:          if (dbus_message_get_path (message) != NULL &&
call    0 never executed
branch  1 never executed
branch  2 never executed
call    3 never executed
call    4 never executed
branch  5 never executed
branch  6 never executed
        -:  924:              strcmp (dbus_message_get_path (message),
        -:  925:                      rule->d.send.path) != 0)
        -:  926:            {
    #####:  927:              _dbus_verbose ("  (policy) skipping rule for different path\n");
call    0 never executed
    #####:  928:              continue;
        -:  929:            }
        -:  930:        }
        -:  931:      
    47840:  932:      if (rule->d.send.interface != NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  933:        {
    #####:  934:          if (dbus_message_get_interface (message) != NULL &&
call    0 never executed
branch  1 never executed
branch  2 never executed
call    3 never executed
call    4 never executed
branch  5 never executed
branch  6 never executed
        -:  935:              strcmp (dbus_message_get_interface (message),
        -:  936:                      rule->d.send.interface) != 0)
        -:  937:            {
    #####:  938:              _dbus_verbose ("  (policy) skipping rule for different interface\n");
call    0 never executed
    #####:  939:              continue;
        -:  940:            }
        -:  941:        }
        -:  942:
    47840:  943:      if (rule->d.send.member != NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  944:        {
    #####:  945:          if (dbus_message_get_member (message) != NULL &&
call    0 never executed
branch  1 never executed
branch  2 never executed
call    3 never executed
call    4 never executed
branch  5 never executed
branch  6 never executed
        -:  946:              strcmp (dbus_message_get_member (message),
        -:  947:                      rule->d.send.member) != 0)
        -:  948:            {
    #####:  949:              _dbus_verbose ("  (policy) skipping rule for different member\n");
call    0 never executed
    #####:  950:              continue;
        -:  951:            }
        -:  952:        }
        -:  953:
    47840:  954:      if (rule->d.send.error != NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  955:        {
    #####:  956:          if (dbus_message_get_error_name (message) != NULL &&
call    0 never executed
branch  1 never executed
branch  2 never executed
call    3 never executed
call    4 never executed
branch  5 never executed
branch  6 never executed
        -:  957:              strcmp (dbus_message_get_error_name (message),
        -:  958:                      rule->d.send.error) != 0)
        -:  959:            {
    #####:  960:              _dbus_verbose ("  (policy) skipping rule for different error name\n");
call    0 never executed
    #####:  961:              continue;
        -:  962:            }
        -:  963:        }
        -:  964:      
    47840:  965:      if (rule->d.send.destination != NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  966:        {
        -:  967:          /* receiver can be NULL for messages that are sent to the
        -:  968:           * message bus itself, we check the strings in that case as
        -:  969:           * built-in services don't have a DBusConnection but messages
        -:  970:           * to them have a destination service name.
        -:  971:           */
    #####:  972:          if (receiver == NULL)
branch  0 never executed
branch  1 never executed
        -:  973:            {
    #####:  974:              if (!dbus_message_has_destination (message,
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  975:                                                 rule->d.send.destination))
        -:  976:                {
    #####:  977:                  _dbus_verbose ("  (policy) skipping rule because message dest is not %s\n",
call    0 never executed
        -:  978:                                 rule->d.send.destination);
    #####:  979:                  continue;
        -:  980:                }
        -:  981:            }
        -:  982:          else
        -:  983:            {
        -:  984:              DBusString str;
        -:  985:              BusService *service;
        -:  986:              
    #####:  987:              _dbus_string_init_const (&str, rule->d.send.destination);
call    0 never executed
        -:  988:              
    #####:  989:              service = bus_registry_lookup (registry, &str);
call    0 never executed
    #####:  990:              if (service == NULL)
branch  0 never executed
branch  1 never executed
        -:  991:                {
    #####:  992:                  _dbus_verbose ("  (policy) skipping rule because dest %s doesn't exist\n",
call    0 never executed
        -:  993:                                 rule->d.send.destination);
    #####:  994:                  continue;
        -:  995:                }
        -:  996:
    #####:  997:              if (!bus_service_has_owner (service, receiver))
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  998:                {
    #####:  999:                  _dbus_verbose ("  (policy) skipping rule because dest %s isn't owned by receiver\n",
call    0 never executed
        -: 1000:                                 rule->d.send.destination);
    #####: 1001:                  continue;
        -: 1002:                }
        -: 1003:            }
        -: 1004:        }
        -: 1005:
        -: 1006:      /* Use this rule */
    47840: 1007:      allowed = rule->allow;
        -: 1008:
    47840: 1009:      _dbus_verbose ("  (policy) used rule, allow now = %d\n",
call    0 returned 100%
        -: 1010:                     allowed);
        -: 1011:    }
        -: 1012:
    47849: 1013:  return allowed;
        -: 1014:}
        -: 1015:
        -: 1016:/* See docs on what the args mean on bus_context_check_security_policy()
        -: 1017: * comment
        -: 1018: */
        -: 1019:dbus_bool_t
        -: 1020:bus_client_policy_check_can_receive (BusClientPolicy *policy,
        -: 1021:                                     BusRegistry     *registry,
        -: 1022:                                     dbus_bool_t      requested_reply,
        -: 1023:                                     DBusConnection  *sender,
        -: 1024:                                     DBusConnection  *addressed_recipient,
        -: 1025:                                     DBusConnection  *proposed_recipient,
        -: 1026:                                     DBusMessage     *message)
function bus_client_policy_check_can_receive called 103436 returned 100% blocks executed 38%
   103436: 1027:{
        -: 1028:  DBusList *link;
        -: 1029:  dbus_bool_t allowed;
        -: 1030:  dbus_bool_t eavesdropping;
        -: 1031:
   103436: 1032:  eavesdropping =
branch  0 taken 69% (fallthrough)
branch  1 taken 31%
call    2 returned 100%
branch  3 taken 52% (fallthrough)
branch  4 taken 48%
        -: 1033:    addressed_recipient != proposed_recipient &&
        -: 1034:    dbus_message_get_destination (message) != NULL;
        -: 1035:  
        -: 1036:  /* policy->rules is in the order the rules appeared
        -: 1037:   * in the config file, i.e. last rule that applies wins
        -: 1038:   */
        -: 1039:
   103436: 1040:  _dbus_verbose ("  (policy) checking receive rules, eavesdropping = %d\n", eavesdropping);
call    0 returned 100%
        -: 1041:  
   103436: 1042:  allowed = FALSE;
   103436: 1043:  link = _dbus_list_get_first_link (&policy->rules);
call    0 returned 100%
   517180: 1044:  while (link != NULL)
branch  0 taken 75%
branch  1 taken 25% (fallthrough)
        -: 1045:    {
   310308: 1046:      BusPolicyRule *rule = link->data;
        -: 1047:
   310308: 1048:      link = _dbus_list_get_next_link (&policy->rules, link);      
branch  0 taken 67% (fallthrough)
branch  1 taken 33%
        -: 1049:      
   310308: 1050:      if (rule->type != BUS_POLICY_RULE_RECEIVE)
branch  0 taken 67% (fallthrough)
branch  1 taken 33%
        -: 1051:        {
   206872: 1052:          _dbus_verbose ("  (policy) skipping non-receive rule\n");
call    0 returned 100%
   206872: 1053:          continue;
        -: 1054:        }
        -: 1055:
   103436: 1056:      if (rule->d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1057:        {
    #####: 1058:          if (dbus_message_get_type (message) != rule->d.receive.message_type)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -: 1059:            {
    #####: 1060:              _dbus_verbose ("  (policy) skipping rule for different message type\n");
call    0 never executed
    #####: 1061:              continue;
        -: 1062:            }
        -: 1063:        }
        -: 1064:
        -: 1065:      /* for allow, eavesdrop=false means the rule doesn't apply when
        -: 1066:       * eavesdropping. eavesdrop=true means always allow.
        -: 1067:       */
   103436: 1068:      if (eavesdropping && rule->allow && !rule->d.receive.eavesdrop)
branch  0 taken 36% (fallthrough)
branch  1 taken 64%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
branch  4 taken 100% (fallthrough)
branch  5 taken 0%
        -: 1069:        {
    37171: 1070:          _dbus_verbose ("  (policy) skipping allow rule since it doesn't apply to eavesdropping\n");
call    0 returned 100%
    37171: 1071:          continue;
        -: 1072:        }
        -: 1073:
        -: 1074:      /* for deny, eavesdrop=true means the rule applies only when
        -: 1075:       * eavesdropping; eavesdrop=false means always deny.
        -: 1076:       */
    66265: 1077:      if (!eavesdropping && !rule->allow && rule->d.receive.eavesdrop)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
branch  4 never executed
branch  5 never executed
        -: 1078:        {
    #####: 1079:          _dbus_verbose ("  (policy) skipping deny rule since it only applies to eavesdropping\n");
call    0 never executed
    #####: 1080:          continue;
        -: 1081:        }
        -: 1082:
        -: 1083:      /* If it's a reply, the requested_reply flag kicks in */
    66265: 1084:      if (dbus_message_get_reply_serial (message) != 0)
call    0 returned 100%
branch  1 taken 24% (fallthrough)
branch  2 taken 76%
        -: 1085:        {
        -: 1086:          /* for allow, requested_reply=true means the rule applies
        -: 1087:           * only when reply was requested. requested_reply=false means
        -: 1088:           * always allow.
        -: 1089:           */
    15952: 1090:          if (!requested_reply && rule->allow && rule->d.receive.requested_reply)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 never executed
branch  3 never executed
branch  4 never executed
branch  5 never executed
        -: 1091:            {
    #####: 1092:              _dbus_verbose ("  (policy) skipping allow rule since it only applies to requested replies\n");
call    0 never executed
    #####: 1093:              continue;
        -: 1094:            }
        -: 1095:
        -: 1096:          /* for deny, requested_reply=false means the rule applies only
        -: 1097:           * when the reply was not requested. requested_reply=true means the
        -: 1098:           * rule always applies.
        -: 1099:           */
    15952: 1100:          if (requested_reply && !rule->allow && !rule->d.receive.requested_reply)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
branch  4 never executed
branch  5 never executed
        -: 1101:            {
    #####: 1102:              _dbus_verbose ("  (policy) skipping deny rule since it only applies to unrequested replies\n");
call    0 never executed
    #####: 1103:              continue;
        -: 1104:            }
        -: 1105:        }
        -: 1106:      
    66265: 1107:      if (rule->d.receive.path != NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1108:        {
    #####: 1109:          if (dbus_message_get_path (message) != NULL &&
call    0 never executed
branch  1 never executed
branch  2 never executed
call    3 never executed
call    4 never executed
branch  5 never executed
branch  6 never executed
        -: 1110:              strcmp (dbus_message_get_path (message),
        -: 1111:                      rule->d.receive.path) != 0)
        -: 1112:            {
    #####: 1113:              _dbus_verbose ("  (policy) skipping rule for different path\n");
call    0 never executed
    #####: 1114:              continue;
        -: 1115:            }
        -: 1116:        }
        -: 1117:      
    66265: 1118:      if (rule->d.receive.interface != NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1119:        {
    #####: 1120:          if (dbus_message_get_interface (message) != NULL &&
call    0 never executed
branch  1 never executed
branch  2 never executed
call    3 never executed
call    4 never executed
branch  5 never executed
branch  6 never executed
        -: 1121:              strcmp (dbus_message_get_interface (message),
        -: 1122:                      rule->d.receive.interface) != 0)
        -: 1123:            {
    #####: 1124:              _dbus_verbose ("  (policy) skipping rule for different interface\n");
call    0 never executed
    #####: 1125:              continue;
        -: 1126:            }
        -: 1127:        }      
        -: 1128:
    66265: 1129:      if (rule->d.receive.member != NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1130:        {
    #####: 1131:          if (dbus_message_get_member (message) != NULL &&
call    0 never executed
branch  1 never executed
branch  2 never executed
call    3 never executed
call    4 never executed
branch  5 never executed
branch  6 never executed
        -: 1132:              strcmp (dbus_message_get_member (message),
        -: 1133:                      rule->d.receive.member) != 0)
        -: 1134:            {
    #####: 1135:              _dbus_verbose ("  (policy) skipping rule for different member\n");
call    0 never executed
    #####: 1136:              continue;
        -: 1137:            }
        -: 1138:        }
        -: 1139:
    66265: 1140:      if (rule->d.receive.error != NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1141:        {
    #####: 1142:          if (dbus_message_get_error_name (message) != NULL &&
call    0 never executed
branch  1 never executed
branch  2 never executed
call    3 never executed
call    4 never executed
branch  5 never executed
branch  6 never executed
        -: 1143:              strcmp (dbus_message_get_error_name (message),
        -: 1144:                      rule->d.receive.error) != 0)
        -: 1145:            {
    #####: 1146:              _dbus_verbose ("  (policy) skipping rule for different error name\n");
call    0 never executed
    #####: 1147:              continue;
        -: 1148:            }
        -: 1149:        }
        -: 1150:      
    66265: 1151:      if (rule->d.receive.origin != NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1152:        {          
        -: 1153:          /* sender can be NULL for messages that originate from the
        -: 1154:           * message bus itself, we check the strings in that case as
        -: 1155:           * built-in services don't have a DBusConnection but will
        -: 1156:           * still set the sender on their messages.
        -: 1157:           */
    #####: 1158:          if (sender == NULL)
branch  0 never executed
branch  1 never executed
        -: 1159:            {
    #####: 1160:              if (!dbus_message_has_sender (message,
call    0 never executed
branch  1 never executed
branch  2 never executed
        -: 1161:                                            rule->d.receive.origin))
        -: 1162:                {
    #####: 1163:                  _dbus_verbose ("  (policy) skipping rule because message sender is not %s\n",
call    0 never executed
        -: 1164:                                 rule->d.receive.origin);
    #####: 1165:                  continue;
        -: 1166:                }
        -: 1167:            }
        -: 1168:          else
        -: 1169:            {
        -: 1170:              BusService *service;
        -: 1171:              DBusString str;
        -: 1172:
    #####: 1173:              _dbus_string_init_const (&str, rule->d.receive.origin);
call    0 never executed
        -: 1174:              
    #####: 1175:              service = bus_registry_lookup (registry, &str);
call    0 never executed
        -: 1176:              
    #####: 1177:              if (service == NULL)
branch  0 never executed
branch  1 never executed
        -: 1178:                {
    #####: 1179:                  _dbus_verbose ("  (policy) skipping rule because origin %s doesn't exist\n",
call    0 never executed
        -: 1180:                                 rule->d.receive.origin);
    #####: 1181:                  continue;
        -: 1182:                }
        -: 1183:
    #####: 1184:              if (!bus_service_has_owner (service, sender))
call    0 never executed
branch  1 never executed
branch  2 never executed
        -: 1185:                {
    #####: 1186:                  _dbus_verbose ("  (policy) skipping rule because origin %s isn't owned by sender\n",
call    0 never executed
        -: 1187:                                 rule->d.receive.origin);
    #####: 1188:                  continue;
        -: 1189:                }
        -: 1190:            }
        -: 1191:        }
        -: 1192:      
        -: 1193:      /* Use this rule */
    66265: 1194:      allowed = rule->allow;
        -: 1195:
    66265: 1196:      _dbus_verbose ("  (policy) used rule, allow now = %d\n",
call    0 returned 100%
        -: 1197:                     allowed);
        -: 1198:    }
        -: 1199:
   103436: 1200:  return allowed;
        -: 1201:}
        -: 1202:
        -: 1203:dbus_bool_t
        -: 1204:bus_client_policy_check_can_own (BusClientPolicy  *policy,
        -: 1205:                                 DBusConnection   *connection,
        -: 1206:                                 const DBusString *service_name)
function bus_client_policy_check_can_own called 1950 returned 100% blocks executed 79%
     1950: 1207:{
        -: 1208:  DBusList *link;
        -: 1209:  dbus_bool_t allowed;
        -: 1210:  
        -: 1211:  /* policy->rules is in the order the rules appeared
        -: 1212:   * in the config file, i.e. last rule that applies wins
        -: 1213:   */
        -: 1214:
     1950: 1215:  allowed = FALSE;
     1950: 1216:  link = _dbus_list_get_first_link (&policy->rules);
call    0 returned 100%
     9750: 1217:  while (link != NULL)
branch  0 taken 75%
branch  1 taken 25% (fallthrough)
        -: 1218:    {
     5850: 1219:      BusPolicyRule *rule = link->data;
        -: 1220:
     5850: 1221:      link = _dbus_list_get_next_link (&policy->rules, link);
branch  0 taken 67% (fallthrough)
branch  1 taken 33%
        -: 1222:      
        -: 1223:      /* Rule is skipped if it specifies a different service name from
        -: 1224:       * the desired one.
        -: 1225:       */
        -: 1226:      
     5850: 1227:      if (rule->type != BUS_POLICY_RULE_OWN)
branch  0 taken 67% (fallthrough)
branch  1 taken 33%
     3900: 1228:        continue;
        -: 1229:
     1950: 1230:      if (rule->d.own.service_name != NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1231:        {
    #####: 1232:          if (!_dbus_string_equal_c_str (service_name,
call    0 never executed
branch  1 never executed
branch  2 never executed
        -: 1233:                                         rule->d.own.service_name))
    #####: 1234:            continue;
        -: 1235:        }
        -: 1236:
        -: 1237:      /* Use this rule */
     1950: 1238:      allowed = rule->allow;
        -: 1239:    }
        -: 1240:
     1950: 1241:  return allowed;
        -: 1242:}
        -: 1243:
        -: 1244:#ifdef DBUS_BUILD_TESTS
        -: 1245:
        -: 1246:dbus_bool_t
        -: 1247:bus_policy_test (const DBusString *test_data_dir)
function bus_policy_test called 1 returned 100% blocks executed 100%
        1: 1248:{
        -: 1249:  /* This doesn't do anything for now because I decided to do it in
        -: 1250:   * dispatch.c instead by having some of the clients in dispatch.c
        -: 1251:   * have particular policies applied to them.
        -: 1252:   */
        -: 1253:  
        1: 1254:  return TRUE;
        -: 1255:}
        -: 1256:
        -: 1257:#endif /* DBUS_BUILD_TESTS */