Print this page
OS-4361 libzonecfg should be aware of branded zone native root
Reviewed by: Robert Mustacchi <rm@joyent.com>
        
*** 18,27 ****
--- 18,28 ----
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+  * Copyright 2015 Joyent, Inc.
   */
  
  
  /*
   * This module contains functions used for reading and writing the index file.
*** 168,189 ****
  
          return (ze);
  }
  
  static boolean_t
! get_index_path(char *path)
  {
!         return (snprintf(path, MAXPATHLEN, "%s%s", zonecfg_root,
!             ZONE_INDEX_FILE) < MAXPATHLEN);
  }
  
  FILE *
  setzoneent(void)
  {
          char path[MAXPATHLEN];
  
!         if (!get_index_path(path)) {
                  errno = EINVAL;
                  return (NULL);
          }
          return (fopen(path, "r"));
  }
--- 169,212 ----
  
          return (ze);
  }
  
  static boolean_t
! path_common(char *path, size_t path_size, const char *stem)
  {
!         const char *native_root = zone_get_nroot();
! 
!         if (native_root == NULL || zonecfg_in_alt_root()) {
!                 /*
!                  * Do not prepend the native system root (e.g. "/native") if an
!                  * alternative configuration root has been selected.
!                  */
!                 native_root = "";
!         }
! 
!         return (snprintf(path, path_size, "%s%s%s", native_root, zonecfg_root,
!             stem) < path_size);
  }
  
+ static boolean_t
+ get_index_path(char *path, size_t path_size)
+ {
+         return (path_common(path, path_size, ZONE_INDEX_FILE));
+ }
+ 
+ static boolean_t
+ get_temp_path(char *path, size_t path_size)
+ {
+         return (path_common(path, path_size, _PATH_TMPFILE));
+ }
+ 
  FILE *
  setzoneent(void)
  {
          char path[MAXPATHLEN];
  
!         if (!get_index_path(path, sizeof (path))) {
                  errno = EINVAL;
                  return (NULL);
          }
          return (fopen(path, "r"));
  }
*** 200,211 ****
  {
          int lock_fd;
          struct flock lock;
          char path[MAXPATHLEN];
  
!         if (snprintf(path, sizeof (path), "%s%s", zonecfg_root,
!             ZONE_INDEX_LOCK_DIR) >= sizeof (path))
                  return (-1);
          if ((mkdir(path, S_IRWXU) == -1) && errno != EEXIST)
                  return (-1);
          if (strlcat(path, ZONE_INDEX_LOCK_FILE, sizeof (path)) >=
              sizeof (path))
--- 223,233 ----
  {
          int lock_fd;
          struct flock lock;
          char path[MAXPATHLEN];
  
!         if (!path_common(path, sizeof (path), ZONE_INDEX_LOCK_DIR))
                  return (-1);
          if ((mkdir(path, S_IRWXU) == -1) && errno != EEXIST)
                  return (-1);
          if (strlcat(path, ZONE_INDEX_LOCK_FILE, sizeof (path)) >=
              sizeof (path))
*** 267,283 ****
   */
  int
  putzoneent(struct zoneent *ze, zoneent_op_t operation)
  {
          FILE *index_file, *tmp_file;
!         char *tmp_file_name, buf[MAX_INDEX_LEN];
          int tmp_file_desc, lock_fd, err;
          boolean_t exist, need_quotes;
          char *cp;
          char path[MAXPATHLEN];
          char uuidstr[UUID_PRINTABLE_STRING_LENGTH];
!         size_t tlen, namelen;
          const char *zone_name, *zone_state, *zone_path, *zone_uuid;
  
          assert(ze != NULL);
  
          /*
--- 289,306 ----
   */
  int
  putzoneent(struct zoneent *ze, zoneent_op_t operation)
  {
          FILE *index_file, *tmp_file;
!         char buf[MAX_INDEX_LEN];
          int tmp_file_desc, lock_fd, err;
          boolean_t exist, need_quotes;
          char *cp;
+         char tmp_path[MAXPATHLEN];
          char path[MAXPATHLEN];
          char uuidstr[UUID_PRINTABLE_STRING_LENGTH];
!         size_t namelen;
          const char *zone_name, *zone_state, *zone_path, *zone_uuid;
  
          assert(ze != NULL);
  
          /*
*** 297,320 ****
                  return (Z_INVAL);
  
          if ((lock_fd = lock_index_file()) == -1)
                  return (Z_LOCKING_FILE);
  
!         /* using sizeof gives us room for the terminating NUL byte as well */
!         tlen = sizeof (_PATH_TMPFILE) + strlen(zonecfg_root);
!         tmp_file_name = malloc(tlen);
!         if (tmp_file_name == NULL) {
                  (void) unlock_index_file(lock_fd);
                  return (Z_NOMEM);
          }
-         (void) snprintf(tmp_file_name, tlen, "%s%s", zonecfg_root,
-             _PATH_TMPFILE);
  
!         tmp_file_desc = mkstemp(tmp_file_name);
          if (tmp_file_desc == -1) {
!                 (void) unlink(tmp_file_name);
!                 free(tmp_file_name);
                  (void) unlock_index_file(lock_fd);
                  return (Z_TEMP_FILE);
          }
          (void) fchmod(tmp_file_desc, ZONE_INDEX_MODE);
          (void) fchown(tmp_file_desc, ZONE_INDEX_UID, ZONE_INDEX_GID);
--- 320,337 ----
                  return (Z_INVAL);
  
          if ((lock_fd = lock_index_file()) == -1)
                  return (Z_LOCKING_FILE);
  
!         if (!get_temp_path(tmp_path, sizeof (tmp_path))) {
                  (void) unlock_index_file(lock_fd);
                  return (Z_NOMEM);
          }
  
!         tmp_file_desc = mkstemp(tmp_path);
          if (tmp_file_desc == -1) {
!                 (void) unlink(tmp_path);
                  (void) unlock_index_file(lock_fd);
                  return (Z_TEMP_FILE);
          }
          (void) fchmod(tmp_file_desc, ZONE_INDEX_MODE);
          (void) fchown(tmp_file_desc, ZONE_INDEX_UID, ZONE_INDEX_GID);
*** 321,331 ****
          if ((tmp_file = fdopen(tmp_file_desc, "w")) == NULL) {
                  (void) close(tmp_file_desc);
                  err = Z_MISC_FS;
                  goto error;
          }
!         if (!get_index_path(path)) {
                  err = Z_MISC_FS;
                  goto error;
          }
          if ((index_file = fopen(path, "r")) == NULL) {
                  err = Z_MISC_FS;
--- 338,348 ----
          if ((tmp_file = fdopen(tmp_file_desc, "w")) == NULL) {
                  (void) close(tmp_file_desc);
                  err = Z_MISC_FS;
                  goto error;
          }
!         if (!get_index_path(path, sizeof (path))) {
                  err = Z_MISC_FS;
                  goto error;
          }
          if ((index_file = fopen(path, "r")) == NULL) {
                  err = Z_MISC_FS;
*** 462,485 ****
                  tmp_file = NULL;
                  err = Z_MISC_FS;
                  goto error;
          }
          tmp_file = NULL;
!         if (rename(tmp_file_name, path) == -1) {
                  err = errno == EACCES ? Z_ACCES : Z_MISC_FS;
                  goto error;
          }
-         free(tmp_file_name);
          if (unlock_index_file(lock_fd) != Z_OK)
                  return (Z_UNLOCKING_FILE);
          return (Z_OK);
  
  error:
          if (index_file != NULL)
                  (void) fclose(index_file);
          if (tmp_file != NULL)
                  (void) fclose(tmp_file);
!         (void) unlink(tmp_file_name);
!         free(tmp_file_name);
          (void) unlock_index_file(lock_fd);
          return (err);
  }
--- 479,500 ----
                  tmp_file = NULL;
                  err = Z_MISC_FS;
                  goto error;
          }
          tmp_file = NULL;
!         if (rename(tmp_path, path) == -1) {
                  err = errno == EACCES ? Z_ACCES : Z_MISC_FS;
                  goto error;
          }
          if (unlock_index_file(lock_fd) != Z_OK)
                  return (Z_UNLOCKING_FILE);
          return (Z_OK);
  
  error:
          if (index_file != NULL)
                  (void) fclose(index_file);
          if (tmp_file != NULL)
                  (void) fclose(tmp_file);
!         (void) unlink(tmp_path);
          (void) unlock_index_file(lock_fd);
          return (err);
  }