summaryrefslogtreecommitdiff
path: root/usr/src/cmd/zoneadm
diff options
context:
space:
mode:
author <gerald.jelinek@sun.com>2008-10-07 09:35:01 -0600
committer <gerald.jelinek@sun.com>2008-10-07 09:35:01 -0600
commitc4a4562235be590fa8120d4e0dc367980a14112f (patch)
tree7cab98c16f7cb50f95d0b2b4c0cfc8f9d61db1ac /usr/src/cmd/zoneadm
parenta55f711916b9f7718fabc2d1822bf5719aa6140f (diff)
downloadillumos-joyent-c4a4562235be590fa8120d4e0dc367980a14112f.tar.gz
6754405 configured zonepath root validation is too restrictive
Diffstat (limited to 'usr/src/cmd/zoneadm')
-rw-r--r--usr/src/cmd/zoneadm/zoneadm.c60
1 files changed, 53 insertions, 7 deletions
diff --git a/usr/src/cmd/zoneadm/zoneadm.c b/usr/src/cmd/zoneadm/zoneadm.c
index 3ee3c3879b..12d0dd6711 100644
--- a/usr/src/cmd/zoneadm/zoneadm.c
+++ b/usr/src/cmd/zoneadm/zoneadm.c
@@ -1095,18 +1095,64 @@ validate_zonepath(char *path, int cmd_num)
return (Z_ERR);
}
if ((res = stat(rootpath, &stbuf)) == 0) {
- if (zonecfg_detached(rpath))
+ struct dirent *dp;
+ DIR *dirp;
+ boolean_t empty = B_TRUE;
+
+ if (zonecfg_detached(rpath)) {
(void) fprintf(stderr,
gettext("Cannot %s detached "
"zone.\nUse attach or remove %s "
"directory.\n"), cmd_to_str(cmd_num),
rpath);
- else
- (void) fprintf(stderr,
- gettext("Rootpath %s exists; "
- "remove or move aside prior to %s.\n"),
- rootpath, cmd_to_str(cmd_num));
- return (Z_ERR);
+ return (Z_ERR);
+ }
+
+ /* Not detached, check if it really looks ok. */
+
+ if (!S_ISDIR(stbuf.st_mode)) {
+ (void) fprintf(stderr, gettext("%s is not a "
+ "directory.\n"), rootpath);
+ return (Z_ERR);
+ }
+
+ if (stbuf.st_uid != 0) {
+ (void) fprintf(stderr, gettext("%s is not "
+ "owned by root.\n"), rootpath);
+ return (Z_ERR);
+ }
+
+ if ((stbuf.st_mode & 0777) != 0755) {
+ (void) fprintf(stderr, gettext("%s mode is not "
+ "0755.\n"), rootpath);
+ return (Z_ERR);
+ }
+
+ if ((dirp = opendir(rootpath)) == NULL) {
+ (void) fprintf(stderr, gettext("Could not "
+ "open rootpath %s\n"), rootpath);
+ return (Z_ERR);
+ }
+
+ /* Verify that the dir is empty. */
+ while ((dp = readdir(dirp)) != NULL) {
+ if (strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0)
+ continue;
+
+ empty = B_FALSE;
+ break;
+ }
+ (void) closedir(dirp);
+
+ if (!empty) {
+ (void) fprintf(stderr, gettext("Rootpath %s "
+ "exists and contains data; remove or move "
+ "aside prior to %s.\n"), rootpath,
+ cmd_to_str(cmd_num));
+ return (Z_ERR);
+ }
+
}
}