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>
        
*** 19,28 ****
--- 19,29 ----
   * CDDL HEADER END
   */
  
  /*
   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+  * Copyright 2015 Joyent, Inc.
   */
  
  /*
   * The ipmgmtd daemon is started by ip-interface-management SMF service. This
   * daemon is used to manage, mapping of 'address object' to 'interface name' and
*** 103,112 ****
--- 104,114 ----
  ipmgmt_db_init()
  {
          int             fd, err, scferr;
          scf_resources_t res;
          boolean_t       upgrade = B_TRUE;
+         char            aobjpath[MAXPATHLEN];
  
          /*
           * Check to see if we need to upgrade the data-store. We need to
           * upgrade, if the version of the data-store does not match with
           * IPADM_DB_VERSION. Further, if we cannot determine the current
*** 132,146 ****
          }
          if (scferr == 0)
                  ipmgmt_release_scf_resources(&res);
  
          /* creates the address object data store, if it doesn't exist */
!         if ((fd = open(ADDROBJ_MAPPING_DB_FILE, O_CREAT|O_RDONLY,
!             IPADM_FILE_MODE)) == -1) {
                  err = errno;
!                 ipmgmt_log(LOG_ERR, "could not open %s: %s",
!                     ADDROBJ_MAPPING_DB_FILE, strerror(err));
                  return (err);
          }
          (void) close(fd);
  
          aobjmap.aobjmap_head = NULL;
--- 134,148 ----
          }
          if (scferr == 0)
                  ipmgmt_release_scf_resources(&res);
  
          /* creates the address object data store, if it doesn't exist */
!         ipmgmt_path(IPADM_PATH_ADDROBJ_MAP_DB, aobjpath, sizeof (aobjpath));
!         if ((fd = open(aobjpath, O_CREAT|O_RDONLY, IPADM_FILE_MODE)) == -1) {
                  err = errno;
!                 ipmgmt_log(LOG_ERR, "could not open %s: %s", aobjpath,
!                     strerror(err));
                  return (err);
          }
          (void) close(fd);
  
          aobjmap.aobjmap_head = NULL;
*** 150,161 ****
           * If the daemon is recovering from a crash or restart, read the
           * address object to logical interface mapping and build an in-memory
           * representation of the mapping. That is, build `aobjmap' structure
           * from address object data store.
           */
!         if ((err = ipadm_rw_db(ipmgmt_aobjmap_init, NULL,
!             ADDROBJ_MAPPING_DB_FILE, 0, IPADM_DB_READ)) != 0) {
                  /* if there was nothing to initialize, it's fine */
                  if (err != ENOENT)
                          return (err);
                  err = 0;
          }
--- 152,163 ----
           * If the daemon is recovering from a crash or restart, read the
           * address object to logical interface mapping and build an in-memory
           * representation of the mapping. That is, build `aobjmap' structure
           * from address object data store.
           */
!         if ((err = ipadm_rw_db(ipmgmt_aobjmap_init, NULL, aobjpath, 0,
!             IPADM_DB_READ)) != 0) {
                  /* if there was nothing to initialize, it's fine */
                  if (err != ENOENT)
                          return (err);
                  err = 0;
          }
*** 163,183 ****
          ipmgmt_ngz_persist_if(); /* create persistent interface info for NGZ */
  
          return (err);
  }
  
  static int
  ipmgmt_door_init()
  {
          int fd;
          int err;
  
!         /* create the door file for ipmgmtd */
!         if ((fd = open(IPMGMT_DOOR, O_CREAT|O_RDONLY, IPADM_FILE_MODE)) == -1) {
                  err = errno;
!                 ipmgmt_log(LOG_ERR, "could not open %s: %s",
!                     IPMGMT_DOOR, strerror(err));
                  return (err);
          }
          (void) close(fd);
  
          if ((ipmgmt_door_fd = door_create(ipmgmt_handler, NULL,
--- 165,210 ----
          ipmgmt_ngz_persist_if(); /* create persistent interface info for NGZ */
  
          return (err);
  }
  
+ static const char *
+ ipmgmt_door_path()
+ {
+         static char door[MAXPATHLEN];
+         static boolean_t init_done = B_FALSE;
+ 
+         if (!init_done) {
+                 const char *zroot = zone_get_nroot();
+ 
+                 /*
+                  * If this is a branded zone, make sure we use the "/native"
+                  * prefix for the door path:
+                  */
+                 (void) snprintf(door, sizeof (door), "%s%s", zroot != NULL ?
+                     zroot : "", IPMGMT_DOOR);
+ 
+                 init_done = B_TRUE;
+         }
+ 
+         return (door);
+ }
+ 
  static int
  ipmgmt_door_init()
  {
          int fd;
          int err;
+         const char *door = ipmgmt_door_path();
  
!         /*
!          * Create the door file for ipmgmtd.
!          */
!         if ((fd = open(door, O_CREAT | O_RDONLY, IPADM_FILE_MODE)) == -1) {
                  err = errno;
!                 ipmgmt_log(LOG_ERR, "could not open %s: %s", door,
!                     strerror(err));
                  return (err);
          }
          (void) close(fd);
  
          if ((ipmgmt_door_fd = door_create(ipmgmt_handler, NULL,
*** 184,202 ****
              DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) == -1) {
                  err = errno;
                  ipmgmt_log(LOG_ERR, "failed to create door: %s", strerror(err));
                  return (err);
          }
          /*
           * fdetach first in case a previous daemon instance exited
           * ungracefully.
           */
!         (void) fdetach(IPMGMT_DOOR);
!         if (fattach(ipmgmt_door_fd, IPMGMT_DOOR) != 0) {
                  err = errno;
!                 ipmgmt_log(LOG_ERR, "failed to attach door to %s: %s",
!                     IPMGMT_DOOR, strerror(err));
                  goto fail;
          }
          return (0);
  fail:
          (void) door_revoke(ipmgmt_door_fd);
--- 211,230 ----
              DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) == -1) {
                  err = errno;
                  ipmgmt_log(LOG_ERR, "failed to create door: %s", strerror(err));
                  return (err);
          }
+ 
          /*
           * fdetach first in case a previous daemon instance exited
           * ungracefully.
           */
!         (void) fdetach(door);
!         if (fattach(ipmgmt_door_fd, door) != 0) {
                  err = errno;
!                 ipmgmt_log(LOG_ERR, "failed to attach door to %s: %s", door,
!                     strerror(err));
                  goto fail;
          }
          return (0);
  fail:
          (void) door_revoke(ipmgmt_door_fd);
*** 205,221 ****
  }
  
  static void
  ipmgmt_door_fini()
  {
          if (ipmgmt_door_fd == -1)
                  return;
  
!         (void) fdetach(IPMGMT_DOOR);
          if (door_revoke(ipmgmt_door_fd) == -1) {
                  ipmgmt_log(LOG_ERR, "failed to revoke access to door %s: %s",
!                     IPMGMT_DOOR, strerror(errno));
          }
  }
  
  static int
  ipmgmt_init()
--- 233,251 ----
  }
  
  static void
  ipmgmt_door_fini()
  {
+         const char *door = ipmgmt_door_path();
+ 
          if (ipmgmt_door_fd == -1)
                  return;
  
!         (void) fdetach(door);
          if (door_revoke(ipmgmt_door_fd) == -1) {
                  ipmgmt_log(LOG_ERR, "failed to revoke access to door %s: %s",
!                     door, strerror(errno));
          }
  }
  
  static int
  ipmgmt_init()
*** 348,361 ****
  static int
  ipmgmt_init_privileges()
  {
          struct stat     statbuf;
          int             err;
  
!         /* create the IPADM_TMPFS_DIR directory */
!         if (stat(IPADM_TMPFS_DIR, &statbuf) < 0) {
!                 if (mkdir(IPADM_TMPFS_DIR, (mode_t)0755) < 0) {
                          err = errno;
                          goto fail;
                  }
          } else {
                  if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
--- 378,395 ----
  static int
  ipmgmt_init_privileges()
  {
          struct stat     statbuf;
          int             err;
+         char            tmpfsdir[MAXPATHLEN];
  
!         /*
!          * Create the volatile storage directory:
!          */
!         ipmgmt_path(IPADM_PATH_TMPFS_DIR, tmpfsdir, sizeof (tmpfsdir));
!         if (stat(tmpfsdir, &statbuf) < 0) {
!                 if (mkdir(tmpfsdir, (mode_t)0755) < 0) {
                          err = errno;
                          goto fail;
                  }
          } else {
                  if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
*** 362,373 ****
                          err = ENOTDIR;
                          goto fail;
                  }
          }
  
!         if ((chmod(IPADM_TMPFS_DIR, 0755) < 0) ||
!             (chown(IPADM_TMPFS_DIR, UID_NETADM, GID_NETADM) < 0)) {
                  err = errno;
                  goto fail;
          }
  
          /*
--- 396,407 ----
                          err = ENOTDIR;
                          goto fail;
                  }
          }
  
!         if ((chmod(tmpfsdir, 0755) < 0) ||
!             (chown(tmpfsdir, UID_NETADM, GID_NETADM) < 0)) {
                  err = errno;
                  goto fail;
          }
  
          /*