Print this page
OS-4335 ipadm_door_call should work in a branded zone without chroot
OS-4336 ipmgmtd should work in a branded zone without chroot
Reviewed by: Robert Mustacchi <rm@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_main.c
          +++ new/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_main.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright 2015 Joyent, Inc.
  24   25   */
  25   26  
  26   27  /*
  27   28   * The ipmgmtd daemon is started by ip-interface-management SMF service. This
  28   29   * daemon is used to manage, mapping of 'address object' to 'interface name' and
  29   30   * 'logical interface number', on which the address is created. It also provides
  30   31   * a means to update the ipadm persistent data-store.
  31   32   *
  32   33   * The daemon tracks the <addrobj, lifname> mapping in-memory using a linked
  33   34   * list `aobjmap'. Access to this list is synchronized using a readers-writers
↓ open down ↓ 64 lines elided ↑ open up ↑
  98   99  } ipmgmt_pif_t;
  99  100  
 100  101  static ipmgmt_pif_t *ngz_pifs;
 101  102  
 102  103  static int
 103  104  ipmgmt_db_init()
 104  105  {
 105  106          int             fd, err, scferr;
 106  107          scf_resources_t res;
 107  108          boolean_t       upgrade = B_TRUE;
      109 +        char            aobjpath[MAXPATHLEN];
 108  110  
 109  111          /*
 110  112           * Check to see if we need to upgrade the data-store. We need to
 111  113           * upgrade, if the version of the data-store does not match with
 112  114           * IPADM_DB_VERSION. Further, if we cannot determine the current
 113  115           * version of the data-store, we always err on the side of caution
 114  116           * and upgrade the data-store to current version.
 115  117           */
 116  118          if ((scferr = ipmgmt_create_scf_resources(IPMGMTD_FMRI, &res)) == 0)
 117  119                  upgrade = ipmgmt_needs_upgrade(&res);
↓ open down ↓ 9 lines elided ↑ open up ↑
 127  129                           * current data-store version number.
 128  130                           */
 129  131                          if (scferr == 0)
 130  132                                  ipmgmt_update_dbver(&res);
 131  133                  }
 132  134          }
 133  135          if (scferr == 0)
 134  136                  ipmgmt_release_scf_resources(&res);
 135  137  
 136  138          /* creates the address object data store, if it doesn't exist */
 137      -        if ((fd = open(ADDROBJ_MAPPING_DB_FILE, O_CREAT|O_RDONLY,
 138      -            IPADM_FILE_MODE)) == -1) {
      139 +        ipmgmt_path(IPADM_PATH_ADDROBJ_MAP_DB, aobjpath, sizeof (aobjpath));
      140 +        if ((fd = open(aobjpath, O_CREAT|O_RDONLY, IPADM_FILE_MODE)) == -1) {
 139  141                  err = errno;
 140      -                ipmgmt_log(LOG_ERR, "could not open %s: %s",
 141      -                    ADDROBJ_MAPPING_DB_FILE, strerror(err));
      142 +                ipmgmt_log(LOG_ERR, "could not open %s: %s", aobjpath,
      143 +                    strerror(err));
 142  144                  return (err);
 143  145          }
 144  146          (void) close(fd);
 145  147  
 146  148          aobjmap.aobjmap_head = NULL;
 147  149          (void) pthread_rwlock_init(&aobjmap.aobjmap_rwlock, NULL);
 148  150  
 149  151          /*
 150  152           * If the daemon is recovering from a crash or restart, read the
 151  153           * address object to logical interface mapping and build an in-memory
 152  154           * representation of the mapping. That is, build `aobjmap' structure
 153  155           * from address object data store.
 154  156           */
 155      -        if ((err = ipadm_rw_db(ipmgmt_aobjmap_init, NULL,
 156      -            ADDROBJ_MAPPING_DB_FILE, 0, IPADM_DB_READ)) != 0) {
      157 +        if ((err = ipadm_rw_db(ipmgmt_aobjmap_init, NULL, aobjpath, 0,
      158 +            IPADM_DB_READ)) != 0) {
 157  159                  /* if there was nothing to initialize, it's fine */
 158  160                  if (err != ENOENT)
 159  161                          return (err);
 160  162                  err = 0;
 161  163          }
 162  164  
 163  165          ipmgmt_ngz_persist_if(); /* create persistent interface info for NGZ */
 164  166  
 165  167          return (err);
 166  168  }
 167  169  
      170 +static const char *
      171 +ipmgmt_door_path()
      172 +{
      173 +        static char door[MAXPATHLEN];
      174 +        static boolean_t init_done = B_FALSE;
      175 +
      176 +        if (!init_done) {
      177 +                const char *zroot = zone_get_nroot();
      178 +
      179 +                /*
      180 +                 * If this is a branded zone, make sure we use the "/native"
      181 +                 * prefix for the door path:
      182 +                 */
      183 +                (void) snprintf(door, sizeof (door), "%s%s", zroot != NULL ?
      184 +                    zroot : "", IPMGMT_DOOR);
      185 +
      186 +                init_done = B_TRUE;
      187 +        }
      188 +
      189 +        return (door);
      190 +}
      191 +
 168  192  static int
 169  193  ipmgmt_door_init()
 170  194  {
 171  195          int fd;
 172  196          int err;
      197 +        const char *door = ipmgmt_door_path();
 173  198  
 174      -        /* create the door file for ipmgmtd */
 175      -        if ((fd = open(IPMGMT_DOOR, O_CREAT|O_RDONLY, IPADM_FILE_MODE)) == -1) {
      199 +        /*
      200 +         * Create the door file for ipmgmtd.
      201 +         */
      202 +        if ((fd = open(door, O_CREAT | O_RDONLY, IPADM_FILE_MODE)) == -1) {
 176  203                  err = errno;
 177      -                ipmgmt_log(LOG_ERR, "could not open %s: %s",
 178      -                    IPMGMT_DOOR, strerror(err));
      204 +                ipmgmt_log(LOG_ERR, "could not open %s: %s", door,
      205 +                    strerror(err));
 179  206                  return (err);
 180  207          }
 181  208          (void) close(fd);
 182  209  
 183  210          if ((ipmgmt_door_fd = door_create(ipmgmt_handler, NULL,
 184  211              DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) == -1) {
 185  212                  err = errno;
 186  213                  ipmgmt_log(LOG_ERR, "failed to create door: %s", strerror(err));
 187  214                  return (err);
 188  215          }
      216 +
 189  217          /*
 190  218           * fdetach first in case a previous daemon instance exited
 191  219           * ungracefully.
 192  220           */
 193      -        (void) fdetach(IPMGMT_DOOR);
 194      -        if (fattach(ipmgmt_door_fd, IPMGMT_DOOR) != 0) {
      221 +        (void) fdetach(door);
      222 +        if (fattach(ipmgmt_door_fd, door) != 0) {
 195  223                  err = errno;
 196      -                ipmgmt_log(LOG_ERR, "failed to attach door to %s: %s",
 197      -                    IPMGMT_DOOR, strerror(err));
      224 +                ipmgmt_log(LOG_ERR, "failed to attach door to %s: %s", door,
      225 +                    strerror(err));
 198  226                  goto fail;
 199  227          }
 200  228          return (0);
 201  229  fail:
 202  230          (void) door_revoke(ipmgmt_door_fd);
 203  231          ipmgmt_door_fd = -1;
 204  232          return (err);
 205  233  }
 206  234  
 207  235  static void
 208  236  ipmgmt_door_fini()
 209  237  {
      238 +        const char *door = ipmgmt_door_path();
      239 +
 210  240          if (ipmgmt_door_fd == -1)
 211  241                  return;
 212  242  
 213      -        (void) fdetach(IPMGMT_DOOR);
      243 +        (void) fdetach(door);
 214  244          if (door_revoke(ipmgmt_door_fd) == -1) {
 215  245                  ipmgmt_log(LOG_ERR, "failed to revoke access to door %s: %s",
 216      -                    IPMGMT_DOOR, strerror(errno));
      246 +                    door, strerror(errno));
 217  247          }
 218  248  }
 219  249  
 220  250  static int
 221  251  ipmgmt_init()
 222  252  {
 223  253          int err;
 224  254  
 225  255          if (signal(SIGTERM, ipmgmt_exit) == SIG_ERR ||
 226  256              signal(SIGINT, ipmgmt_exit) == SIG_ERR) {
↓ open down ↓ 116 lines elided ↑ open up ↑
 343  373   * operations before setuid() because they need root privileges:
 344  374   *
 345  375   *    - create the /etc/svc/volatile/ipadm directory;
 346  376   *    - change its uid/gid to "netadm"/"netadm";
 347  377   */
 348  378  static int
 349  379  ipmgmt_init_privileges()
 350  380  {
 351  381          struct stat     statbuf;
 352  382          int             err;
      383 +        char            tmpfsdir[MAXPATHLEN];
 353  384  
 354      -        /* create the IPADM_TMPFS_DIR directory */
 355      -        if (stat(IPADM_TMPFS_DIR, &statbuf) < 0) {
 356      -                if (mkdir(IPADM_TMPFS_DIR, (mode_t)0755) < 0) {
      385 +        /*
      386 +         * Create the volatile storage directory:
      387 +         */
      388 +        ipmgmt_path(IPADM_PATH_TMPFS_DIR, tmpfsdir, sizeof (tmpfsdir));
      389 +        if (stat(tmpfsdir, &statbuf) < 0) {
      390 +                if (mkdir(tmpfsdir, (mode_t)0755) < 0) {
 357  391                          err = errno;
 358  392                          goto fail;
 359  393                  }
 360  394          } else {
 361  395                  if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
 362  396                          err = ENOTDIR;
 363  397                          goto fail;
 364  398                  }
 365  399          }
 366  400  
 367      -        if ((chmod(IPADM_TMPFS_DIR, 0755) < 0) ||
 368      -            (chown(IPADM_TMPFS_DIR, UID_NETADM, GID_NETADM) < 0)) {
      401 +        if ((chmod(tmpfsdir, 0755) < 0) ||
      402 +            (chown(tmpfsdir, UID_NETADM, GID_NETADM) < 0)) {
 369  403                  err = errno;
 370  404                  goto fail;
 371  405          }
 372  406  
 373  407          /*
 374  408           * initialize any NGZ specific network information before dropping
 375  409           * privileges. We need these privileges to plumb IP interfaces handed
 376  410           * down from the GZ (for dlpi_open() etc.) and also to configure the
 377  411           * address itself (for any IPI_PRIV ioctls like SLIFADDR)
 378  412           */
↓ open down ↓ 201 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX