diff --git a/src/tools/pgmd5/pg_md5.c b/src/tools/pgmd5/pg_md5.c index cf37e89..8081553 100644 --- a/src/tools/pgmd5/pg_md5.c +++ b/src/tools/pgmd5/pg_md5.c @@ -39,6 +39,7 @@ #endif #include #include +#include /* Maximum number of characters allowed for input. */ #define MAX_INPUT_SIZE MAX_USER_NAME_LEN @@ -46,6 +47,7 @@ static void print_usage(const char prog[], int exit_code); static void set_tio_attr(int enable); static void update_pool_passwd(char *conf_file, char *username, char *password); +static void update_pool_passwd_from_file(char *conf_file, char *input_file); int main(int argc, char *argv[]) @@ -53,11 +55,13 @@ main(int argc, char *argv[]) #define PRINT_USAGE(exit_code) print_usage(argv[0], exit_code) char conf_file[POOLMAXPATHLEN + 1]; + char input_file[POOLMAXPATHLEN + 1]; char username[MAX_INPUT_SIZE + 1]; int opt; int optindex; bool md5auth = false; bool prompt = false; + bool use_input_file = false; static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, @@ -65,6 +69,7 @@ main(int argc, char *argv[]) {"md5auth", no_argument, NULL, 'm'}, {"username", required_argument, NULL, 'u'}, {"config-file", required_argument, NULL, 'f'}, + {"input-file", required_argument, NULL, 'i'}, {NULL, 0, NULL, 0} }; @@ -76,7 +81,7 @@ main(int argc, char *argv[]) */ memset(username, 0, MAX_INPUT_SIZE + 1); - while ((opt = getopt_long(argc, argv, "hpmf:u:", long_options, &optindex)) != -1) + while ((opt = getopt_long(argc, argv, "hpmfi:u:", long_options, &optindex)) != -1) { switch (opt) { @@ -96,6 +101,15 @@ main(int argc, char *argv[]) strlcpy(conf_file, optarg, sizeof(conf_file)); break; + case 'i': /* specify users password input file */ + if (!optarg) + { + PRINT_USAGE(EXIT_SUCCESS); + } + strlcpy(input_file, optarg, sizeof(input_file)); + use_input_file = true; + break; + case 'u': if (!optarg) { @@ -115,6 +129,12 @@ main(int argc, char *argv[]) break; } } + /* Use input file */ + if (use_input_file) + { + update_pool_passwd_from_file(conf_file, input_file); + return EXIT_SUCCESS; + } /* Prompt for password. */ if (prompt) @@ -189,6 +209,84 @@ main(int argc, char *argv[]) return EXIT_SUCCESS; } +static void +update_pool_passwd_from_file(char *conf_file, char *input_file) +{ + FILE *fp; + struct stat stat_buf; + + char buf[MAX_INPUT_SIZE + 1]; + char username[MAX_INPUT_SIZE + 1]; + char password[MAX_INPUT_SIZE + 1]; + char *pch; + int len; + int line_count; + + if (strlen(input_file) == 0) + { + fprintf(stderr, "input_file is emptry\n\n"); + exit(EXIT_FAILURE); + } + + if (stat(input_file, &stat_buf) != 0) + { + fprintf(stderr, "input_file \"%s\" cannot be opened. Check file permissions\n\n", input_file); + exit(EXIT_FAILURE); + } + + if (!S_ISREG(stat_buf.st_mode)) + { + fprintf(stderr, "input_file \"%s\" is not a plain file\n\n", input_file); + exit(EXIT_FAILURE); + } + + + fp = fopen(input_file, "r"); + if (fp == NULL) + { + fprintf(stderr, "input_file \"%s\" cannot be opened\n\n", input_file); + exit(EXIT_FAILURE); + } + + line_count = 0; + while (!feof(fp) && !ferror(fp)) + { + line_count++; + + memset(buf, 0, MAX_INPUT_SIZE + 1); + memset(username, 0, MAX_INPUT_SIZE + 1); + memset(password, 0, MAX_INPUT_SIZE + 1); + + if (fgets(buf, sizeof(buf), fp) == NULL) + break; + + len = strlen(buf); + if (len == 0 || *buf == '\n') + continue; + + /* Remove trailing newline */ + if (buf[len - 1] == '\n') + buf[len - 1] = 0; + + /* Split username and passwords */ + pch = buf; + while( pch && pch != buf + len && *pch != ':') + pch++; + + if (!strlen(pch)) + { + fprintf(stderr, "invalid username:password pair at line:%d\n", line_count); + continue; + } + strncpy(username, buf, pch-buf); + strncpy(password, pch+1, strlen(pch+1)); + + update_pool_passwd(conf_file, username, password); + } + + fclose(fp); +} + static void update_pool_passwd(char *conf_file, char *username, char *password) { @@ -250,6 +348,7 @@ print_usage(const char prog[], int exit_code) --username, -u USER When producing a md5 authentication password,\n\ create the pool_passwd entry for USER.\n\ --config-file, -f CONFIG-FILE Specify pgpool.conf.\n\ + --input-file, -i INPUT-FILE Specify file containing username and password pairs.\n\ --help, -h This help menu.\n\ \n\ Warning: At most %d characters are allowed for input.\n\