diff --git a/src/gpupdate.c b/src/gpupdate.c index e7ce39b..8207e0c 100644 --- a/src/gpupdate.c +++ b/src/gpupdate.c @@ -50,10 +50,10 @@ #define _(_x) _x static const char *exe; -static const char *gpo_exe; +static char *gpo_exe; static struct passwd *pwd; -#define FLAG_QUIET (1 << 1) +#define FLAG_STDIN (1 << 1) #define FLAG_FORCE (1 << 2) /* @@ -69,7 +69,7 @@ get_gpo_exe(void) return gpo_exe ? gpo_exe : "/usr/sbin/gpoa"; } -static int apply_gpo(const char *user, int flags) +static int apply_gpo(const char *user, int flags, char* loglevel) { int status; pid_t pid = fork(); @@ -79,9 +79,9 @@ static int apply_gpo(const char *user, int flags) return 1; case 0: if (flags & FLAG_FORCE) { - execl(exe, exe, "--force", user, NULL); + execl(exe, exe, "--force", "--loglevel", loglevel, user, NULL); } else { - execl(exe, exe, user, NULL); + execl(exe, exe, "--loglevel", loglevel, user, NULL); } return 3; default: @@ -93,11 +93,12 @@ static int apply_gpo(const char *user, int flags) /* Apply group policies via GPO applier. */ static int -gpupdate(const char *user, int flags) +gpupdate(const char *user, int flags, char* loglevel) { int ret; struct stat st; const char *log_user = user; + int i_loglevel = atoi(loglevel); /* Now make sure that the user or computer a) no user (computer) @@ -127,7 +128,7 @@ gpupdate(const char *user, int flags) exe = get_gpo_exe(); if (exe != NULL) { /* Set the text of the result message. */ - if (!(flags & FLAG_QUIET)) { + if (!(i_loglevel < 4)) { printf(_("Apply group policies for %s."), log_user); } syslog(LOG_NOTICE, "Apply group policies for %s.", log_user); @@ -141,7 +142,7 @@ gpupdate(const char *user, int flags) return HANDLER_INVALID_INVOCATION; } } - ret = apply_gpo(user, flags); + ret = apply_gpo(user, flags, loglevel); if (ret != 0) { syslog(LOG_ERR, "error applying GPO for %s (error code %d)", log_user, ret); @@ -152,53 +153,174 @@ gpupdate(const char *user, int flags) } int -main(int argc, char **argv) +getFlags(int argc, char** argv, char** gpo_exe, char** loglevel, int *flags) { - char **oddjob_argv, *p; - int oddjob_argc, ret, flags = 0; + if (argc == 0) + { + return 0; + } + if (!argv || !gpo_exe || !gpo_exe || !loglevel || !flags) + { + return -1; + } - openlog(PACKAGE "-gpupdate", LOG_PID, LOG_DAEMON); - gpo_exe = "/usr/sbin/gpoa"; + if (*gpo_exe) + { + free(*gpo_exe); + } + (*gpo_exe) = strdup("/usr/sbin/gpoa"); + if (*loglevel) + { + free(*loglevel); + } + (*loglevel) = strdup("4"); - while ((ret = getopt(argc, argv, "qfp:")) != -1) { - switch (ret) { - case 'q': - flags |= FLAG_QUIET; - break; - case 'f': - flags |= FLAG_FORCE; - break; - case 'p': - gpo_exe = optarg; - break; + int ret; + while ((ret = getopt(argc, argv, "ifl:p:")) != -1) + { + switch (ret){ + case 'f': + (*flags) |= FLAG_FORCE; + break; + case 'p': + if (*gpo_exe) + { + free(*gpo_exe); + } + (*gpo_exe) = strdup(optarg); + break; + case 'i': { + (*flags) |= FLAG_STDIN; + break; + } + case 'l': + if (*loglevel) + { + free(*loglevel); + } + (*loglevel) = strdup(optarg); + break; default: fprintf(stderr, "Valid options:\n" "-q\tDo not print messages when applying " "a policy.\n" "-f\tForce GPT download.\n" + "-l LEVEL\tSet loglevel.\n" "-p PATH\tOverride the gpo applier " - "binary (\"%s\").\n", gpo_exe); - return 1; + "binary (\"%s\").\n", *gpo_exe); + return -1; + } + } + + return 0; +} + +int +main(int argc, char **argv) +{ + char *user = NULL, **oddjob_args, *stdin_args = NULL, *loglevel = NULL; + int flags = 0, oddjob_argc, ret = HANDLER_INVALID_INVOCATION; + + openlog(PACKAGE "-gpupdate", LOG_PID, LOG_DAEMON); + + oddjob_args = oddjob_collect_args(stdin); + for (oddjob_argc = 0; oddjob_args && oddjob_args[oddjob_argc]; ++oddjob_argc); + + if (getFlags(argc, argv, &gpo_exe, &loglevel, &flags) == -1) + { + return ret; + } + + if (flags & FLAG_STDIN) + { + // Parse args. + switch(oddjob_argc) + { + case 2: + user = oddjob_args[0]; + stdin_args = oddjob_args[1]; + break; + case 1: + stdin_args = oddjob_args[0]; + break; + default: + syslog(LOG_ERR, "invoked with wrong arguments"); + + free(loglevel); + free(gpo_exe); + + return ret; } + + if (!stdin_args || !*stdin_args) + { + syslog(LOG_ERR, "invoked with wrong arguments"); + + free(loglevel); + free(gpo_exe); + + return ret; + } + + size_t newArgc = 0; + // split stdin by ' '. + char** newArgv = make_argv(stdin_args, &newArgc, ' '); + + // flags fallback + flags = FLAG_STDIN; + + optind = 1; + // rerun getFlags with STDIN + if (getFlags(newArgc, newArgv, &gpo_exe, &loglevel, &flags) == -1) + { + return ret; + } + + for (int i = newArgc; i > 0; --i) + { + free(newArgv[i - 1]); + } + free(newArgv); } - ret = HANDLER_INVALID_INVOCATION; - oddjob_argv = oddjob_collect_args(stdin); - for (oddjob_argc = 0; (oddjob_argv != NULL) && (oddjob_argv[oddjob_argc] != NULL); oddjob_argc++) { - if (oddjob_argc > 1) + else switch(oddjob_argc) + { + case 1: + user = oddjob_args[0]; + break; + case 0: break; + + default: + syslog(LOG_ERR, "invoked with wrong arguments"); + + free(loglevel); + free(gpo_exe); + + return ret; } - switch (oddjob_argc) { - case 0: - ret = gpupdate(NULL, flags); - break; - case 1: - if (strlen(oddjob_argv[0]) > 0) - ret = gpupdate(oddjob_argv[0], flags); - break; - default: - syslog(LOG_ERR, "invoked with wrong arguments"); + + if (user) + { + if (strlen(user) == 0) + { + syslog(LOG_ERR, "invoked with wrong arguments"); + + free(loglevel); + free(gpo_exe); + + return ret; + } + ret = gpupdate(user, flags, loglevel); } - oddjob_free_args(oddjob_argv); + else + { + ret = gpupdate(NULL, flags, loglevel); + } + + free(loglevel); + free(gpo_exe); + + oddjob_free_args(oddjob_args); closelog(); return ret; } diff --git a/src/oddjob-gpupdate.conf.in b/src/oddjob-gpupdate.conf.in index 44c6e5a..4c24efd 100644 --- a/src/oddjob-gpupdate.conf.in +++ b/src/oddjob-gpupdate.conf.in @@ -55,6 +55,27 @@ send_member="gpupdate_computer"/> + + + + + + + + + + + diff --git a/src/oddjobd-gpupdate.conf.in b/src/oddjobd-gpupdate.conf.in index 45ec698..7c51305 100644 --- a/src/oddjobd-gpupdate.conf.in +++ b/src/oddjobd-gpupdate.conf.in @@ -43,6 +43,19 @@ + + + + + + + + + + diff --git a/src/util.c b/src/util.c index 729ce9c..9ccc591 100644 --- a/src/util.c +++ b/src/util.c @@ -37,6 +37,35 @@ #include #include +/* Generate argv and argc from argument string (a_str) */ +char** make_argv(char* a_str, size_t* argc_out, const char a_delim) +{ + if (!argc_out) + { + return NULL; + } + + char delim[2] = {a_delim, 0}; + char** result = NULL; + char* token = strtok(a_str, delim); + + (*argc_out) = 0; + + // getopt skip first argument........ + result = reallocarray(result, ++(*argc_out), sizeof(char*)); + result[0] = NULL; + + while(token) + { + result = reallocarray(result, ++(*argc_out), sizeof(char*)); + result[(*argc_out) - 1] = strdup(token); + token = strtok(NULL, delim); + } + + return result; +} + + /* Write to a file, handling transient errors. */ ssize_t retry_write(int fd, unsigned char *buf, size_t length) diff --git a/src/util.h b/src/util.h index f204efe..0c820b6 100644 --- a/src/util.h +++ b/src/util.h @@ -31,6 +31,7 @@ #ifndef oddjob_util_h #define oddjob_util_h +char** make_argv(char* a_str, size_t* argc_out, const char a_delim); ssize_t retry_write(int fd, unsigned char *buf, size_t length); void *oddjob_malloc(size_t size); void *oddjob_malloc0(size_t size);