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,10 +19,11 @@
  * 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,10 +104,11 @@
 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,15 +134,15 @@
         }
         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) {
+        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",
-                    ADDROBJ_MAPPING_DB_FILE, strerror(err));
+                ipmgmt_log(LOG_ERR, "could not open %s: %s", aobjpath,
+                    strerror(err));
                 return (err);
         }
         (void) close(fd);
 
         aobjmap.aobjmap_head = NULL;
@@ -150,12 +152,12 @@
          * 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 ((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,21 +165,46 @@
         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(IPMGMT_DOOR, O_CREAT|O_RDONLY, IPADM_FILE_MODE)) == -1) {
+        /*
+         * 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",
-                    IPMGMT_DOOR, strerror(err));
+                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,19 +211,20 @@
             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) {
+        (void) fdetach(door);
+        if (fattach(ipmgmt_door_fd, door) != 0) {
                 err = errno;
-                ipmgmt_log(LOG_ERR, "failed to attach door to %s: %s",
-                    IPMGMT_DOOR, strerror(err));
+                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,17 +233,19 @@
 }
 
 static void
 ipmgmt_door_fini()
 {
+        const char *door = ipmgmt_door_path();
+
         if (ipmgmt_door_fd == -1)
                 return;
 
-        (void) fdetach(IPMGMT_DOOR);
+        (void) fdetach(door);
         if (door_revoke(ipmgmt_door_fd) == -1) {
                 ipmgmt_log(LOG_ERR, "failed to revoke access to door %s: %s",
-                    IPMGMT_DOOR, strerror(errno));
+                    door, strerror(errno));
         }
 }
 
 static int
 ipmgmt_init()
@@ -348,14 +378,18 @@
 static int
 ipmgmt_init_privileges()
 {
         struct stat     statbuf;
         int             err;
+        char            tmpfsdir[MAXPATHLEN];
 
-        /* create the IPADM_TMPFS_DIR directory */
-        if (stat(IPADM_TMPFS_DIR, &statbuf) < 0) {
-                if (mkdir(IPADM_TMPFS_DIR, (mode_t)0755) < 0) {
+        /*
+         * 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,12 +396,12 @@
                         err = ENOTDIR;
                         goto fail;
                 }
         }
 
-        if ((chmod(IPADM_TMPFS_DIR, 0755) < 0) ||
-            (chown(IPADM_TMPFS_DIR, UID_NETADM, GID_NETADM) < 0)) {
+        if ((chmod(tmpfsdir, 0755) < 0) ||
+            (chown(tmpfsdir, UID_NETADM, GID_NETADM) < 0)) {
                 err = errno;
                 goto fail;
         }
 
         /*