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;
}
/*