pure-pw.c
来自「功能强大的ftp服务器源代码」· C语言 代码 · 共 1,575 行 · 第 1/4 页
C
1,575 行
#include <config.h>#include "ftpd.h"#include "pure-pw.h"#include "../puredb/src/puredb_write.h"#ifdef HAVE_POSIX_TERMIOS# include <termios.h>#elif defined(HAVE_TERMIO_H)# include <termio.h>#elif defined(HAVE_SGTTY_H)# include <sgtty.h>#endif#ifndef HAVE_GETOPT_LONG# include "bsd-getopt_long.h"#else# include <getopt.h>#endif#ifdef WITH_DMALLOC# include <dmalloc.h>#endif#ifdef PROBE_RANDOM_AT_RUNTIMEstatic const char *random_device;#endifstatic void disable_echo(void){ if (!isatty(0)) { return; }#ifdef ECHO# ifdef HAVE_POSIX_TERMIOS { struct termios p; if (tcgetattr(0, &p) != 0) { return; } p.c_lflag &= ~ECHO;# ifndef TCSAFLUSH# define TCSAFLUSH 0# endif tcsetattr(0, TCSAFLUSH, &p); }# elif defined(HAVE_TERMIO_H) && defined(TCGETA) { struct termio tty; if (ioctl(0, TCGETA, &tty) != 0) { return; } tty.c_lflag &= ~ECHO; ioctl(0, TCSETA, &tty); }# else { struct sgttyb tty; if (ioctl(0, TIOCGETP, &tty) != 0) { return; } tty.sg_flags &= ~ECHO; ioctl(0, TIOCSETN, &tty); }# endif#endif}static void enable_echo(void){ if (!isatty(0)) { return; } #ifdef ECHO# ifdef HAVE_POSIX_TERMIOS { struct termios p; if (tcgetattr(0, &p) != 0) { return; } p.c_lflag |= ECHO;# ifndef TCSAFLUSH# define TCSAFLUSH 0# endif tcsetattr(0, TCSAFLUSH, &p); }# elif defined(HAVE_TERMIO_H) && defined(TCGETA) { struct termio tty; if (ioctl(0, TCGETA, &tty) != 0) { return; } tty.c_lflag |= ECHO; ioctl(0, TCSETA, &tty); }# else { struct sgttyb tty; if (ioctl(0, TIOCGETP, &tty) != 0) { return; } tty.sg_flags |= ECHO; ioctl(0, TIOCSETN, &tty); }# endif#endif}/* * The difference between this strtok() and the libc's one is that * this one doesn't skip empty fields, and takes a char instead of a * string as a delimiter. * This strtok2() variant leaves zeroes. */static char *my_strtok2(char *str, const char delim){ static char *s; static char save; if (str != NULL) { if (*str == 0) { return NULL; } s = str; scan: while (*s != 0 && *s != delim) { s++; } save = *s; *s = 0; return str; } if (s == NULL || save == 0) { return NULL; } s++; str = s; goto scan;}static void filter_pw_line_sep(char *str){ if (str == NULL) { return; } while (*str != 0) { if (*str == *PW_LINE_SEP) { *str = '_'; } str++; }}static void help(void){ puts("\nUsage :\n\n" "pure-pw useradd <login> [-f <passwd file>] -u <uid> [-g <gid>]\n" " -D/-d <home directory> [-c <gecos>]\n" " [-t <download bandwidth>] [-T <upload bandwidth>]\n" " [-n <max number of files>] [-N <max Mbytes>]\n" " [-q <upload ratio>] [-Q <download ratio>]\n" " [-r <allow client ip>/<mask>] [-R <deny client ip>/<mask>]\n" " [-i <allow local ip>/<mask>] [-I <deny local ip>/<mask>]\n" " [-y <max number of concurrent sessions>]\n" " [-z <hhmm>-<hhmm>] [-m]\n" "\n" "pure-pw usermod <login> -f <passwd file> -u <uid> [-g <gid>]\n" " -D/-d <home directory> -[c <gecos>]\n" " [-t <download bandwidth>] [-T <upload bandwidth>]\n" " [-n <max number of files>] [-N <max Mbytes>]\n" " [-q <upload ratio>] [-Q <download ratio>]\n" " [-r <allow client ip>/<mask>] [-R <deny client ip>/<mask>]\n" " [-i <allow local ip>/<mask>] [-I <deny local ip>/<mask>]\n" " [-y <max number of concurrent sessions>]\n" " [-z <hhmm>-<hhmm>] [-m]\n" "\n" "pure-pw userdel <login> [-f <passwd file>] [-m]\n" "\n" "pure-pw passwd <login> [-f <passwd file>] [-m]\n" "\n" "pure-pw show <login> [-f <passwd file>]\n" "\n" "pure-pw mkdb [<puredb database file> [-f <passwd file>]]\n" "\n" "pure-pw list [-f <passwd file>]\n" "\n" "-d <home directory> : chroot user (recommended)\n" "-D <home directory> : don't chroot user\n" "-<option> '' : set this option to unlimited\n" "-m : also update the " DEFAULT_PW_DB " database\n" "For a 1:10 ratio, use -q 1 -Q 10\n" "To allow access only between 9 am and 6 pm, use -z 0900-1800\n" "\n");#ifndef WITH_PUREDB puts("*WARNING* : that pure-ftpd server hasn't been compiled with puredb support\n");#endif exit(EXIT_SUCCESS); }static void no_mem(void){ fprintf(stderr, "Out of memory : [%s]\n", strerror(errno)); exit(EXIT_FAILURE);}#ifdef PROBE_RANDOM_AT_RUNTIMEstatic void pw_zrand_probe(void){ static const char * const devices[] = { "/dev/arandom", "/dev/urandom", "/dev/random", NULL }; register const char * const *device = devices; do { if (access(*device, F_OK | R_OK) == 0) { random_device = *device; break; } device++; } while (*device != NULL);}#endifstatic unsigned int pw_zrand(void){ int fd; int ret; if (#ifdef PROBE_RANDOM_AT_RUNTIME ((fd = open(random_device, O_RDONLY | O_NONBLOCK)) == -1)#elif defined(HAVE_DEV_ARANDOM) ((fd = open("/dev/arandom", O_RDONLY | O_NONBLOCK)) == -1)#elif defined(HAVE_DEV_URANDOM) ((fd = open("/dev/urandom", O_RDONLY | O_NONBLOCK)) == -1)#else ((fd = open("/dev/random", O_RDONLY | O_NONBLOCK)) == -1)#endif ) { nax:#ifdef HAVE_RANDOM return (unsigned int) random(); #else return (unsigned int) rand();#endif } if (read(fd, &ret, sizeof ret) != (ssize_t) sizeof ret) { close(fd); goto nax; } close(fd); return (unsigned int) ret;}static char *best_crypt(const char * const pwd){ static const char crcars[64] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; register const char *crypted; if ((crypted = (const char *) /* Blowfish */ crypt("test", "$2a$07$1234567890123456789012")) != NULL && strcmp(crypted, "$2a$07$123456789012345678901uKO4" "/IReKqBzRzT6YaajGvw20UBdHW7m") == 0) { char salt[] = "$2a$07$0000000000000000000000"; int c = 28; do { c--; salt[c] = crcars[pw_zrand() & 63]; } while (c > 7); return (char *) crypt(pwd, salt); } else if ((crypted = (const char *) /* MD5 */ crypt("test", "$1$12345678$")) != NULL && strcmp(crypted, "$1$12345678$oEitTZYQtRHfNGmsFvTBA/") == 0) { char salt[] = "$1$00000000"; int c = 10; do { c--; salt[c] = crcars[pw_zrand() & 63]; } while (c > 3); return (char *) crypt(pwd, salt); } else if ((crypted = (const char *) /* Extended DES */ crypt("test", "_.../1234")) != NULL && strcmp(crypted, "_.../1234PAPUVmqGzpU") == 0) { char salt[] = "_.../0000"; int c = 8; do { c--; salt[c] = crcars[pw_zrand() & 63]; } while (c > 5); return (char *) crypt(pwd, salt); } /* Simple DES */ { char salt[] = "00"; salt[0] = crcars[pw_zrand() & 63]; salt[1] = crcars[pw_zrand() & 63]; return (char *) crypt(pwd, salt); } }char *newpasswd_filename(const char * const file){ size_t sizeof_file2; char *file2; sizeof_file2 = strlen(file) + sizeof NEWPASSWD_SUFFIX; if ((file2 = malloc(sizeof_file2)) == NULL) { return NULL; } (void) snprintf(file2, sizeof_file2, "%s%s", file, NEWPASSWD_SUFFIX); return file2;}static void strip_lf(char *str){ char *f; if (str == NULL) { return; } if ((f = strchr(str, '\r')) != NULL) { *f = 0; } if ((f = strchr(str, '\n')) != NULL) { *f = 0; }}static int parse_pw_line(char *line, PWInfo * const pwinfo){ pwinfo->login = NULL; pwinfo->pwd = NULL; pwinfo->gecos = NULL; pwinfo->home = NULL; pwinfo->allow_local_ip = pwinfo->deny_local_ip = NULL; pwinfo->allow_client_ip = pwinfo->deny_client_ip = NULL; pwinfo->has_bw_dl = 0; pwinfo->has_bw_ul = 0; pwinfo->has_quota_files = 0; pwinfo->has_quota_size = 0; pwinfo->has_ul_ratio = 0; pwinfo->has_dl_ratio = 0; pwinfo->has_time = 0; pwinfo->time_begin = pwinfo->time_end = 0U; pwinfo->uid = (uid_t) 0; pwinfo->gid = (gid_t) 0; pwinfo->has_per_user_max = 0; pwinfo->per_user_max = 0U; if ((line = my_strtok2(line, *PW_LINE_SEP)) == NULL || *line == 0) { /* account */ return -1; } pwinfo->login = line; if ((line = my_strtok2(NULL, *PW_LINE_SEP)) == NULL || *line == 0) { /* pwd */ return -1; } pwinfo->pwd = line; if ((line = my_strtok2(NULL, *PW_LINE_SEP)) == NULL || *line == 0) { /* uid */ return -1; } pwinfo->uid = (uid_t) strtoul(line, NULL, 10); if ((line = my_strtok2(NULL, *PW_LINE_SEP)) == NULL || *line == 0) { /* gid */ return -1; } pwinfo->gid = (gid_t) strtoul(line, NULL, 10); if (pwinfo->uid <= (uid_t) 0 || pwinfo->gid <= (gid_t) 0) { return -1; } if ((line = my_strtok2(NULL, *PW_LINE_SEP)) == NULL) { /* gecos */ return -1; } pwinfo->gecos = line; if ((line = my_strtok2(NULL, *PW_LINE_SEP)) == NULL || *line == 0) { /* home */ return -1; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?