# Don't fork a shell when executing htpasswd commands --- a/web/useradm.c +++ b/web/useradm.c @@ -14,6 +14,7 @@ static char rcsid[] = "$Id: useradm.c 65 #include <string.h> #include <stdlib.h> #include <sys/wait.h> +#include <unistd.h> #include "libxymon.h" @@ -124,44 +125,78 @@ int main(int argc, char *argv[]) case ACT_CREATE: /* Add a user */ { - char *cmd; + pid_t childpid; int n, ret; - cmd = (char *)malloc(1024 + strlen(passfile) + strlen(adduser_name) + strlen(adduser_password)); - sprintf(cmd, "htpasswd -b '%s' '%s' '%s'", - passfile, adduser_name, adduser_password); - n = system(cmd); ret = WEXITSTATUS(n); - if ((n == -1) || (ret != 0)) { - infomsg = "<SCRIPT LANGUAGE=\"Javascript\" type=\"text/javascript\"> alert('Update FAILED'); </SCRIPT>\n"; + childpid = fork(); + if (childpid < 0) { + /* Fork failed */ + errprintf("Could not fork child\n"); + exit(1); + } + else if (childpid == 0) { + /* child */ + char *cmd; + char **cmdargs; + + cmdargs = (char **) calloc(4 + 2, sizeof(char *)); + cmdargs[0] = cmd = strdup("htpasswd"); + cmdargs[1] = "-b"; + cmdargs[2] = strdup(passfile); + cmdargs[3] = strdup(adduser_name); + cmdargs[4] = strdup(adduser_password); + cmdargs[5] = '\0'; + + execvp(cmd, cmdargs); + exit(127); + } + /* parent waits for htpasswd to finish */ + if ((waitpid(childpid, &n, 0) == -1) || (WEXITSTATUS(n) != 0)) { + infomsg = "Update FAILED"; } else { - infomsg = "<SCRIPT LANGUAGE=\"Javascript\" type=\"text/javascript\"> alert('User added/updated'); </SCRIPT>\n"; + infomsg = "User added/updated"; } - - xfree(cmd); } break; case ACT_DELETE: /* Delete a user */ { - char *cmd; + pid_t childpid; int n, ret; - cmd = (char *)malloc(1024 + strlen(passfile) + strlen(deluser_name)); - snprintf(cmd, sizeof(cmd), "htpasswd -D '%s' '%s'", - passfile, deluser_name); - n = system(cmd); ret = WEXITSTATUS(n); - if ((n == -1) || (ret != 0)) { - infomsg = "<SCRIPT LANGUAGE=\"Javascript\" type=\"text/javascript\"> alert('Update delete FAILED'); </SCRIPT>\n"; + childpid = fork(); + if (childpid < 0) { + /* Fork failed */ + errprintf("Could not fork child\n"); + exit(1); + } + else if (childpid == 0) { + /* child */ + char *cmd; + char **cmdargs; + + cmdargs = (char **) calloc(3 + 2, sizeof(char *)); + cmdargs[0] = cmd = strdup("htpasswd"); + cmdargs[1] = "-D"; + cmdargs[2] = strdup(passfile); + cmdargs[3] = strdup(deluser_name); + cmdargs[4] = '\0'; + + execvp(cmd, cmdargs); + exit(127); + } + + /* parent waits for htpasswd to finish */ + if ((waitpid(childpid, &n, 0) == -1) || (WEXITSTATUS(n) != 0)) { + infomsg = "Update delete FAILED"; } else { - infomsg = "<SCRIPT LANGUAGE=\"Javascript\" type=\"text/javascript\"> alert('User deleted'); </SCRIPT>\n"; + infomsg = "User deleted"; } - - xfree(cmd); } break; }