forked from pool/libvirt
177 lines
4.7 KiB
Diff
177 lines
4.7 KiB
Diff
|
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
||
|
index de4ec4d44..43971db67 100644
|
||
|
--- a/src/libvirt_private.syms
|
||
|
+++ b/src/libvirt_private.syms
|
||
|
@@ -2751,6 +2751,7 @@ virStrcpy;
|
||
|
virStrdup;
|
||
|
virStringBufferIsPrintable;
|
||
|
virStringEncodeBase64;
|
||
|
+virStringFilterChars;
|
||
|
virStringHasChars;
|
||
|
virStringHasControlChars;
|
||
|
virStringIsEmpty;
|
||
|
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
|
||
|
index b7216d6ee..246145fcd 100644
|
||
|
--- a/src/lxc/lxc_container.c
|
||
|
+++ b/src/lxc/lxc_container.c
|
||
|
@@ -2159,6 +2159,37 @@ static int lxcContainerSetUserGroup(virCommandPtr cmd,
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static const char hostname_validchars[] =
|
||
|
+ "abcdefghijklmnopqrstuvwxyz"
|
||
|
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||
|
+ "0123456789-";
|
||
|
+
|
||
|
+static int lxcContainerSetHostname(virDomainDefPtr def)
|
||
|
+{
|
||
|
+ int ret = -1;
|
||
|
+ char *name = NULL;
|
||
|
+ char *hostname = NULL;
|
||
|
+
|
||
|
+ /* Filter the VM name to get a valid hostname */
|
||
|
+ if (VIR_STRDUP(name, def->name) < 0)
|
||
|
+ goto cleanup;
|
||
|
+
|
||
|
+ /* RFC 1123 allows 0-9 digits as a first character in hostname */
|
||
|
+ virStringFilterChars(name, hostname_validchars);
|
||
|
+ hostname = name;
|
||
|
+ if (strlen(name) > 0 && name[0] == '-')
|
||
|
+ hostname = name + 1;
|
||
|
+
|
||
|
+ if (sethostname(hostname, strlen(hostname)) < 0) {
|
||
|
+ virReportSystemError(errno, "%s", _("Failed to set hostname"));
|
||
|
+ goto cleanup;
|
||
|
+ }
|
||
|
+ ret = 0;
|
||
|
+
|
||
|
+ cleanup:
|
||
|
+ VIR_FREE(name);
|
||
|
+ return ret;
|
||
|
+}
|
||
|
|
||
|
/**
|
||
|
* lxcContainerChild:
|
||
|
@@ -2269,6 +2300,10 @@ static int lxcContainerChild(void *data)
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
+ if (lxcContainerSetHostname(vmDef) < 0)
|
||
|
+ goto cleanup;
|
||
|
+
|
||
|
+
|
||
|
/* drop a set of root capabilities */
|
||
|
if (lxcContainerDropCapabilities(vmDef, !!hasReboot) < 0)
|
||
|
goto cleanup;
|
||
|
diff --git a/src/util/virstring.c b/src/util/virstring.c
|
||
|
index b2ebce27f..b808aff2c 100644
|
||
|
--- a/src/util/virstring.c
|
||
|
+++ b/src/util/virstring.c
|
||
|
@@ -1293,6 +1293,30 @@ virStringStripControlChars(char *str)
|
||
|
str[j] = '\0';
|
||
|
}
|
||
|
|
||
|
+/**
|
||
|
+ * virStringFilterChars:
|
||
|
+ * @str: the string to strip
|
||
|
+ * @valid: the valid characters for the string
|
||
|
+ *
|
||
|
+ * Modify the string in-place to remove the characters that aren't
|
||
|
+ * in the list of valid ones.
|
||
|
+ */
|
||
|
+void
|
||
|
+virStringFilterChars(char *str, const char *valid)
|
||
|
+{
|
||
|
+ size_t len, i, j;
|
||
|
+
|
||
|
+ if (!str)
|
||
|
+ return;
|
||
|
+
|
||
|
+ len = strlen(str);
|
||
|
+ for (i = 0, j = 0; i < len; i++) {
|
||
|
+ if (strchr(valid, str[i]))
|
||
|
+ str[j++] = str[i];
|
||
|
+ }
|
||
|
+ str[j] = '\0';
|
||
|
+}
|
||
|
+
|
||
|
/**
|
||
|
* virStringToUpper:
|
||
|
* @str: string to capitalize
|
||
|
diff --git a/src/util/virstring.h b/src/util/virstring.h
|
||
|
index b19abaf9f..8af054bce 100644
|
||
|
--- a/src/util/virstring.h
|
||
|
+++ b/src/util/virstring.h
|
||
|
@@ -293,6 +293,7 @@ bool virStringHasChars(const char *str,
|
||
|
const char *chars);
|
||
|
bool virStringHasControlChars(const char *str);
|
||
|
void virStringStripControlChars(char *str);
|
||
|
+void virStringFilterChars(char *str, const char *valid);
|
||
|
|
||
|
bool virStringIsPrintable(const char *str);
|
||
|
bool virStringBufferIsPrintable(const uint8_t *buf, size_t buflen);
|
||
|
diff --git a/tests/virstringtest.c b/tests/virstringtest.c
|
||
|
index 320f7a398..e8518ede1 100644
|
||
|
--- a/tests/virstringtest.c
|
||
|
+++ b/tests/virstringtest.c
|
||
|
@@ -767,6 +767,36 @@ static int testStripControlChars(const void *args)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
+struct testFilterData {
|
||
|
+ const char *string;
|
||
|
+ const char *valid;
|
||
|
+ const char *result;
|
||
|
+};
|
||
|
+
|
||
|
+static int testFilterChars(const void *args)
|
||
|
+{
|
||
|
+ const struct testFilterData *data = args;
|
||
|
+ int ret = -1;
|
||
|
+ char *res = NULL;
|
||
|
+
|
||
|
+ if (VIR_STRDUP(res, data->string) < 0)
|
||
|
+ goto cleanup;
|
||
|
+
|
||
|
+ virStringFilterChars(res, data->valid);
|
||
|
+
|
||
|
+ if (STRNEQ_NULLABLE(res, data->result)) {
|
||
|
+ fprintf(stderr, "Returned '%s', expected '%s'\n",
|
||
|
+ NULLSTR(res), NULLSTR(data->result));
|
||
|
+ goto cleanup;
|
||
|
+ }
|
||
|
+
|
||
|
+ ret = 0;
|
||
|
+
|
||
|
+ cleanup:
|
||
|
+ VIR_FREE(res);
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
static int
|
||
|
mymain(void)
|
||
|
{
|
||
|
@@ -1085,6 +1115,22 @@ mymain(void)
|
||
|
TEST_STRIP_CONTROL_CHARS("\x01H\x02" "E\x03L\x04L\x05O", "HELLO");
|
||
|
TEST_STRIP_CONTROL_CHARS("\x01\x02\x03\x04HELL\x05O", "HELLO");
|
||
|
TEST_STRIP_CONTROL_CHARS("\nhello \x01\x07hello\t", "\nhello hello\t");
|
||
|
+
|
||
|
+#define TEST_FILTER_CHARS(str, filter, res) \
|
||
|
+ do { \
|
||
|
+ struct testFilterData filterData = { \
|
||
|
+ .string = str, \
|
||
|
+ .valid = filter, \
|
||
|
+ .result = res, \
|
||
|
+ }; \
|
||
|
+ if (virTestRun("Filter chars from " #str, \
|
||
|
+ testFilterChars, &filterData) < 0) \
|
||
|
+ ret = -1; \
|
||
|
+ } while (0)
|
||
|
+
|
||
|
+ TEST_FILTER_CHARS(NULL, NULL, NULL);
|
||
|
+ TEST_FILTER_CHARS("hello 123 hello", "helo", "hellohello");
|
||
|
+
|
||
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||
|
}
|
||
|
|