From ec831d9055a20b69cb9a7300990b8e4414cbd474 Mon Sep 17 00:00:00 2001 From: Cameron Katri Date: Wed, 10 Feb 2021 11:29:12 -0500 Subject: pw: fix building for iOS, completely untested --- pw/pw_user.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 157 insertions(+), 26 deletions(-) (limited to 'pw/pw_user.c') diff --git a/pw/pw_user.c b/pw/pw_user.c index 2eec317..826388d 100644 --- a/pw/pw_user.c +++ b/pw/pw_user.c @@ -55,6 +55,161 @@ static const char rcsid[] = #include "bitmap.h" #include "psdate.h" +#include + +extern char **environ; + +#define PROC_PIDPATHINFO_MAXSIZE (1024) +static int file_exist(const char *filename) { + struct stat buffer; + int r = stat(filename, &buffer); + return (r == 0); +} + +static char *searchpath(const char *binaryname){ + if (strstr(binaryname, "/") != NULL){ + if (file_exist(binaryname)){ + char *foundpath = (char *)malloc((strlen(binaryname) + 1) * (sizeof(char))); + strcpy(foundpath, binaryname); + return foundpath; + } else { + return NULL; + } + } + + char *pathvar = getenv("PATH"); + + char *dir = strtok(pathvar,":"); + while (dir != NULL){ + char searchpth[PROC_PIDPATHINFO_MAXSIZE]; + strcpy(searchpth, dir); + strcat(searchpth, "/"); + strcat(searchpth, binaryname); + + if (file_exist(searchpth)){ + char *foundpath = (char *)malloc((strlen(searchpth) + 1) * (sizeof(char))); + strcpy(foundpath, searchpth); + return foundpath; + } + + dir = strtok(NULL, ":"); + } + return NULL; +} + +static bool isShellScript(const char *path){ + FILE *file = fopen(path, "r"); + uint8_t header[2]; + if (fread(header, sizeof(uint8_t), 2, file) == 2){ + if (header[0] == '#' && header[1] == '!'){ + fclose(file); + return true; + } + } + fclose(file); + return false; +} + +static char *getInterpreter(char *path){ + FILE *file = fopen(path, "r"); + char *interpreterLine = NULL; + unsigned long lineSize = 0; + getline(&interpreterLine, &lineSize, file); + + char *rawInterpreter = (interpreterLine+2); + rawInterpreter = strtok(rawInterpreter, " "); + rawInterpreter = strtok(rawInterpreter, "\n"); + + char *interpreter = (char *)malloc((strlen(rawInterpreter)+1) * sizeof(char)); + strcpy(interpreter, rawInterpreter); + + free(interpreterLine); + fclose(file); + return interpreter; +} + +static char *fixedCmd(const char *cmdStr){ + char *cmdCpy = (char *)malloc((strlen(cmdStr)+1) * sizeof(char)); + strcpy(cmdCpy, cmdStr); + + char *cmd = strtok(cmdCpy, " "); + + uint8_t size = strlen(cmd) + 1; + + char *args = cmdCpy + size; + if ((strlen(cmdStr) - strlen(cmd)) == 0) + args = NULL; + + char *abs_path = searchpath(cmd); + if (abs_path){ + bool isScript = isShellScript(abs_path); + if (isScript){ + char *interpreter = getInterpreter(abs_path); + + uint8_t commandSize = strlen(interpreter) + 1 + strlen(abs_path); + + if (args){ + commandSize += 1 + strlen(args); + } + + char *rawCommand = (char *)malloc(sizeof(char) * (commandSize + 1)); + strcpy(rawCommand, interpreter); + strcat(rawCommand, " "); + strcat(rawCommand, abs_path); + + if (args){ + strcat(rawCommand, " "); + strcat(rawCommand, args); + } + rawCommand[(commandSize)+1] = '\0'; + + free(interpreter); + free(abs_path); + free(cmdCpy); + + return rawCommand; + } else { + uint8_t commandSize = strlen(abs_path); + + if (args){ + commandSize += 1 + strlen(args); + } + + char *rawCommand = (char *)malloc(sizeof(char) * (commandSize + 1)); + strcat(rawCommand, abs_path); + + if (args){ + strcat(rawCommand, " "); + strcat(rawCommand, args); + } + rawCommand[(commandSize)+1] = '\0'; + + free(abs_path); + free(cmdCpy); + + return rawCommand; + } + } + return cmdCpy; +} + +int RunCmd(const char *cmd) { + pid_t pid; + char *rawCmd = fixedCmd(cmd); + char *argv[] = {"sh", "-c", (char*)rawCmd, NULL}; + int status; + status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ); + if (status == 0) { + if (waitpid(pid, &status, 0) == -1) { + perror("waitpid"); + } + } else { + printf("posix_spawn: %s\n", strerror(status)); + } + free(rawCmd); + return status; +} + #define LOGNAMESIZE (MAXLOGNAME-1) static char locked_str[] = "*LOCKED*"; @@ -700,7 +855,7 @@ rmat(uid_t uid) snprintf(tmp, sizeof(tmp), "/usr/bin/atrm %s", e->d_name); - system(tmp); + RunCmd(tmp); } } closedir(d); @@ -918,18 +1073,6 @@ pw_user_del(int argc, char **argv, char *arg1) errx(EX_NOUSER, "no such user `%s'", name); } - if (PWF._altdir == PWF_REGULAR && - ((pwd->pw_fields & _PWF_SOURCE) != _PWF_FILES)) { - if ((pwd->pw_fields & _PWF_SOURCE) == _PWF_NIS) { - if (!nis && nispasswd && *nispasswd != '/') - errx(EX_NOUSER, "Cannot remove NIS user `%s'", - name); - } else { - errx(EX_NOUSER, "Cannot remove non local user `%s'", - name); - } - } - id = pwd->pw_uid; if (name == NULL) name = pwd->pw_name; @@ -947,7 +1090,7 @@ pw_user_del(int argc, char **argv, char *arg1) if (access(file, F_OK) == 0) { snprintf(file, sizeof(file), "crontab -u %s -r", pwd->pw_name); - system(file); + RunCmd(file); } } @@ -1658,18 +1801,6 @@ pw_user_mod(int argc, char **argv, char *arg1) if (nis && nispasswd == NULL) nispasswd = cnf->nispasswd; - if (PWF._altdir == PWF_REGULAR && - ((pwd->pw_fields & _PWF_SOURCE) != _PWF_FILES)) { - if ((pwd->pw_fields & _PWF_SOURCE) == _PWF_NIS) { - if (!nis && nispasswd && *nispasswd != '/') - errx(EX_NOUSER, "Cannot modify NIS user `%s'", - name); - } else { - errx(EX_NOUSER, "Cannot modify non local user `%s'", - name); - } - } - if (newname) { if (strcmp(pwd->pw_name, "root") == 0) errx(EX_DATAERR, "can't rename `root' account"); -- cgit v1.2.3-56-ge451