From a844c4b0e56a288b1949461570ef07f3544ccaa2 Mon Sep 17 00:00:00 2001 From: Rolf Neugebauer Date: Tue, 9 Aug 2016 17:26:17 +0100 Subject: [PATCH] win: fix the CIFS mount extension of the KVP daemon Change the format of the registry value, create a credentials file from the new value, and use that for the CIFS mount. This should fix issues with password and usernames with un-usual characters in them. Note this requires a matching change in the host app Signed-off-by: Rolf Neugebauer --- alpine/packages/hvtools/src/hv_kvp_daemon.c | 97 +++++++++++++++------ 1 file changed, 69 insertions(+), 28 deletions(-) diff --git a/alpine/packages/hvtools/src/hv_kvp_daemon.c b/alpine/packages/hvtools/src/hv_kvp_daemon.c index 4ae991118..f07d88788 100644 --- a/alpine/packages/hvtools/src/hv_kvp_daemon.c +++ b/alpine/packages/hvtools/src/hv_kvp_daemon.c @@ -360,12 +360,10 @@ static int kvp_key_delete(int pool, const __u8 *key, int key_size) /* * CFIS/SMB mount a directory from the host. * - * The format of the value is ";;", - * where options are either "username=,password=" - * or "username=,password=,domain=". - * - * and example value is: - * "/c;/C;username=foo,password=bar" + * The format of the value is "\n\n\n\n", where options are either + * "" or + * "domain=,". */ static int kvp_cifs_mount(const char *value) { @@ -373,13 +371,18 @@ static int kvp_cifs_mount(const char *value) char mntcmd[2048]; char *mntpoint; char *bindpoint; + char *username; + char *password; char *options; char *t; char gw[256]; char gwcmd[] = "ip route show | grep 'eth0' | awk '/default/ {print $3 }'"; + char credname[] = "/tmp/credXXXXXX"; + int fd; + FILE *fp; - int i, count; + int ret, i, count; if (strlen(value) >= sizeof(val)) { syslog(LOG_ERR, "mount: value is too long"); @@ -393,21 +396,20 @@ static int kvp_cifs_mount(const char *value) /* The above adds a ';' at the end, whack it */ gw[strlen(gw) - 1] = '\0'; - /* - * Parse the value - */ - /* Make sure we have the right number of ';' */ + /* Parse the value */ + + /* Make sure we have the right number of '\n' */ for (i = 0, count = 0; value[i]; i++) - count += (value[i] == ';'); - if (count != 2) { - syslog(LOG_ERR, "mount: Malformed value"); + count += (value[i] == '\n'); + if (count != 4) { + syslog(LOG_ERR, "mount: Malformed value. %d lines", count); return -1; } (void)strncpy(val, value, sizeof(val)); mntpoint = val; - t = strchr(mntpoint, ';'); + t = strchr(mntpoint, '\n'); if ((unsigned int)(t - mntpoint) >= sizeof(mntpoint) - 1) { syslog(LOG_ERR, "mount: Mount point too long"); return -1; @@ -415,43 +417,82 @@ static int kvp_cifs_mount(const char *value) *t = '\0'; bindpoint = t + 1; - t = strchr(bindpoint, ';'); + t = strchr(bindpoint, '\n'); if ((unsigned int)(t - bindpoint) >= sizeof(bindpoint) - 1) { syslog(LOG_ERR, "mount: Bind mount point too long"); return -1; } *t = '\0'; + /* No need to check for length here as we check above for the + * right number of new-lines */ + username = t + 1; + t = strchr(username, '\n'); + *t = '\0'; + + password = t + 1; + t = strchr(password, '\n'); + *t = '\0'; + options = t + 1; - /* - * Execute the mount - */ + /* Write credentials file */ + fd = mkstemp(credname); + if (fd < 0) { + syslog(LOG_ERR, "mount: failed to create cred file. %d %s", + errno, strerror(errno)); + return -1; + } + fp = fdopen(fd, "w"); + if (!fp) { + syslog(LOG_ERR, "mount: failed to open cred stream. %d %s", + errno, strerror(errno)); + ret = -1; + close(fd); + goto err_unlink; + } + ret = fprintf(fp, "username=%s\n", username); + if (ret < 0) { + syslog(LOG_ERR, "mount: failed to add username. %d %s", + errno, strerror(errno)); + fclose(fp); + goto err_unlink; + } + fprintf(fp, "password=%s\n", password); + if (ret < 0) { + syslog(LOG_ERR, "mount: failed to add password. %d %s", + errno, strerror(errno)); + fclose(fp); + goto err_unlink; + } + fclose(fp); + + /* Execute the mount */ syslog(LOG_INFO, "mount: cifs //%s%s to %s and %s", gw, mntpoint, mntpoint, bindpoint); snprintf(mntcmd, sizeof(mntcmd), "mkdir -p %s && " "mkdir -p %s && " - "mount.cifs //%s%s %s -o %s && " + "mount.cifs //%s%s %s -o %s,credentials=%s && " "mount --bind %s %s", mntpoint, bindpoint, - gw, mntpoint, mntpoint, options, + gw, mntpoint, mntpoint, options, credname, mntpoint, bindpoint); - if (system(mntcmd)) { + ret = system(mntcmd); + if (ret) syslog(LOG_ERR, "mount: error: %d %s", errno, strerror(errno)); - return 1; - } - return 0; +err_unlink: + unlink(credname); + return ret; } /* * CFIS/SMB un-mount a directory from the host. * - * Value has the format: ";". - * Example: "/c;/C" + * Value has the format: "\n". */ static int kvp_cifs_umount(const char *value) { @@ -467,7 +508,7 @@ static int kvp_cifs_umount(const char *value) (void)strncpy(val, value, sizeof(val)); - bindpoint = strchr(val, ';'); + bindpoint = strchr(val, '\n'); if (!bindpoint) { syslog(LOG_ERR, "umount: Malformed value. %s", value); return -1;