mirror of https://github.com/postgres/postgres
A new pg_hba.conf column, USER Allow specifiction of lists of users separated by commas Allow group names specified by + Allow include files containing lists of users specified by @ Allow lists of databases, and database files Allow samegroup in database column to match group name matching dbname Removal of secondary password files Remove pg_passwd utility Lots of code cleanup in user.c and hba.c New data/global/pg_pwd format New data/global/pg_group fileecpg_big_bison
parent
af10378ab0
commit
43a3543a4e
@ -1,123 +0,0 @@ |
|||||||
<!-- |
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/Attic/pg_passwd.sgml,v 1.10 2001/12/08 03:24:38 thomas Exp $ |
|
||||||
PostgreSQL documentation |
|
||||||
--> |
|
||||||
|
|
||||||
<refentry id="APP-PG-PASSWD"> |
|
||||||
<docinfo> |
|
||||||
<date>2000-11-18</date> |
|
||||||
</docinfo> |
|
||||||
|
|
||||||
<refmeta> |
|
||||||
<refentrytitle id="APP-PG-PASSWD-TITLE"><application>pg_passwd</application></refentrytitle> |
|
||||||
<manvolnum>1</manvolnum> |
|
||||||
<refmiscinfo>Application</refmiscinfo> |
|
||||||
</refmeta> |
|
||||||
|
|
||||||
<refnamediv> |
|
||||||
<refname>pg_passwd</refname> |
|
||||||
<refpurpose>change a secondary <productname>PostgreSQL</> password file</refpurpose> |
|
||||||
</refnamediv> |
|
||||||
|
|
||||||
<refsynopsisdiv> |
|
||||||
<cmdsynopsis> |
|
||||||
<command>pg_passwd</command> |
|
||||||
<arg choice="plain"><replaceable>filename</replaceable></arg> |
|
||||||
</cmdsynopsis> |
|
||||||
</refsynopsisdiv> |
|
||||||
|
|
||||||
<refsect1 id="app-pg-passwd-description"> |
|
||||||
<title>Description</title> |
|
||||||
<para> |
|
||||||
<application>pg_passwd</application> is a tool for manipulating flat |
|
||||||
text password files. These files can control client authentication of |
|
||||||
the <productname>PostgreSQL</productname> server. More information |
|
||||||
about setting up this authentication mechanism can be found in the |
|
||||||
<citetitle>Administrator's Guide</citetitle>. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
The format of a text password file is one entry per line; the fields |
|
||||||
of each entry are separated by colons. The first field is the user |
|
||||||
name, the second field is the encrypted password. Other fields are |
|
||||||
ignored (to allow password files to be shared between applications |
|
||||||
that use similar formats). <application>pg_passwd</application> |
|
||||||
enables users to interactively add entries to such a file, to alter |
|
||||||
passwords of existing entries, and to encrypt such passwords. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
Supply the name of the password file as argument to the |
|
||||||
<application>pg_passwd</application> command. To be used by |
|
||||||
PostgreSQL, the file needs to be located in the server's data |
|
||||||
directory, and the base name of the file needs to be specified in the |
|
||||||
<filename>pg_hba.conf</filename> access control file. |
|
||||||
|
|
||||||
<screen> |
|
||||||
<prompt>$</prompt> <userinput>pg_passwd /usr/local/pgsql/data/passwords</userinput> |
|
||||||
<computeroutput>File "/usr/local/pgsql/data/passwords" does not exist. Create? (y/n):</computeroutput> <userinput>y</userinput> |
|
||||||
<prompt>Username:</prompt> <userinput>guest</userinput> |
|
||||||
<prompt>Password:</prompt> |
|
||||||
<prompt>Re-enter password:</prompt> |
|
||||||
</screen> |
|
||||||
|
|
||||||
where the <literal>Password:</literal> and <literal>Re-enter |
|
||||||
password:</literal> prompts require the same password input which |
|
||||||
is not displayed on the terminal. Note that the password is limited |
|
||||||
to eight useful characters by restrictions of the standard crypt(3) |
|
||||||
library routine. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
The original password file is renamed to |
|
||||||
<filename>passwords.bk</filename>. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
To make use of this password file, put a line like the following in |
|
||||||
<filename>pg_hba.conf</filename>: |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
host mydb 133.65.96.250 255.255.255.255 password passwords |
|
||||||
</programlisting> |
|
||||||
|
|
||||||
which would allow access to database mydb from host 133.65.96.250 using |
|
||||||
the passwords listed in the <filename>passwords</filename> file (and |
|
||||||
only to the users listed in that file). |
|
||||||
</para> |
|
||||||
|
|
||||||
<note> |
|
||||||
<para> |
|
||||||
It is also useful to have entries in a password file with empty |
|
||||||
password fields. (This is different from an empty password.) Such |
|
||||||
entries allow you to restrict users who can access the system. These |
|
||||||
entries cannot be managed by <application>pg_passwd</application>, |
|
||||||
but you can edit password files manually. |
|
||||||
</para> |
|
||||||
</note> |
|
||||||
</refsect1> |
|
||||||
|
|
||||||
<refsect1 id="app-pg-passwd-seealso"> |
|
||||||
<title>See also</title> |
|
||||||
<para> |
|
||||||
<citetitle>PostgreSQL Administrator's Guide</citetitle> |
|
||||||
</para> |
|
||||||
</refsect1> |
|
||||||
</refentry> |
|
||||||
|
|
||||||
<!-- Keep this comment at the end of the file |
|
||||||
Local variables: |
|
||||||
mode: sgml |
|
||||||
sgml-omittag:nil |
|
||||||
sgml-shorttag:t |
|
||||||
sgml-minimize-attributes:nil |
|
||||||
sgml-always-quote-attributes:t |
|
||||||
sgml-indent-step:1 |
|
||||||
sgml-indent-data:t |
|
||||||
sgml-parent-document:nil |
|
||||||
sgml-default-dtd-file:"../reference.ced" |
|
||||||
sgml-exposed-tags:nil |
|
||||||
sgml-local-catalogs:"/usr/lib/sgml/catalog" |
|
||||||
sgml-local-ecat-files:nil |
|
||||||
End: |
|
||||||
--> |
|
File diff suppressed because it is too large
Load Diff
@ -1,109 +0,0 @@ |
|||||||
/*
|
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group |
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California |
|
||||||
* |
|
||||||
* $Id: password.c,v 1.41 2002/03/04 01:46:03 tgl Exp $ |
|
||||||
* |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <errno.h> |
|
||||||
#include <unistd.h> |
|
||||||
|
|
||||||
#include "postgres.h" |
|
||||||
|
|
||||||
#ifdef HAVE_CRYPT_H |
|
||||||
#include <crypt.h> |
|
||||||
#endif |
|
||||||
|
|
||||||
#include "libpq/libpq.h" |
|
||||||
#include "libpq/password.h" |
|
||||||
#include "libpq/crypt.h" |
|
||||||
#include "miscadmin.h" |
|
||||||
#include "storage/fd.h" |
|
||||||
|
|
||||||
|
|
||||||
int |
|
||||||
verify_password(const Port *port, const char *user, const char *password) |
|
||||||
{ |
|
||||||
char *pw_file_fullname; |
|
||||||
FILE *pw_file; |
|
||||||
|
|
||||||
pw_file_fullname = (char *) palloc(strlen(DataDir) + strlen(port->auth_arg) + 2); |
|
||||||
strcpy(pw_file_fullname, DataDir); |
|
||||||
strcat(pw_file_fullname, "/"); |
|
||||||
strcat(pw_file_fullname, port->auth_arg); |
|
||||||
|
|
||||||
pw_file = AllocateFile(pw_file_fullname, PG_BINARY_R); |
|
||||||
if (!pw_file) |
|
||||||
{ |
|
||||||
elog(LOG, "verify_password: Unable to open password file \"%s\": %m", |
|
||||||
pw_file_fullname); |
|
||||||
|
|
||||||
pfree(pw_file_fullname); |
|
||||||
|
|
||||||
return STATUS_ERROR; |
|
||||||
} |
|
||||||
|
|
||||||
pfree(pw_file_fullname); |
|
||||||
|
|
||||||
while (!feof(pw_file)) |
|
||||||
{ |
|
||||||
char pw_file_line[255], |
|
||||||
*p, |
|
||||||
*test_user, |
|
||||||
*test_pw; |
|
||||||
|
|
||||||
if (fgets(pw_file_line, sizeof(pw_file_line), pw_file) == NULL) |
|
||||||
pw_file_line[0] = '\0'; |
|
||||||
/* kill the newline */ |
|
||||||
if (strlen(pw_file_line) > 0 && |
|
||||||
pw_file_line[strlen(pw_file_line) - 1] == '\n') |
|
||||||
pw_file_line[strlen(pw_file_line) - 1] = '\0'; |
|
||||||
|
|
||||||
p = pw_file_line; |
|
||||||
|
|
||||||
test_user = strtok(p, ":"); |
|
||||||
if (!test_user || test_user[0] == '\0') |
|
||||||
continue; |
|
||||||
test_pw = strtok(NULL, ":"); |
|
||||||
|
|
||||||
if (strcmp(user, test_user) == 0) |
|
||||||
{ |
|
||||||
/* we're outta here one way or the other, so close file */ |
|
||||||
FreeFile(pw_file); |
|
||||||
|
|
||||||
/*
|
|
||||||
* If the password is empty or "+" then we use the regular |
|
||||||
* pg_shadow passwords. If we use crypt then we have to use |
|
||||||
* pg_shadow passwords no matter what. This is because the |
|
||||||
* current code needs non-encrypted passwords to encrypt with |
|
||||||
* a random salt. |
|
||||||
*/ |
|
||||||
if (port->auth_method == uaMD5 || |
|
||||||
port->auth_method == uaCrypt || |
|
||||||
test_pw == NULL || |
|
||||||
test_pw[0] == '\0' || |
|
||||||
strcmp(test_pw, "+") == 0) |
|
||||||
return md5_crypt_verify(port, user, password); |
|
||||||
|
|
||||||
/* external password file is crypt-only */ |
|
||||||
if (strcmp(crypt(password, test_pw), test_pw) == 0) |
|
||||||
{ |
|
||||||
/* it matched. */ |
|
||||||
return STATUS_OK; |
|
||||||
} |
|
||||||
|
|
||||||
elog(LOG, "verify_password: password mismatch for '%s'", |
|
||||||
user); |
|
||||||
|
|
||||||
return STATUS_ERROR; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
FreeFile(pw_file); |
|
||||||
|
|
||||||
elog(LOG, "verify_password: user '%s' not found in password file", |
|
||||||
user); |
|
||||||
|
|
||||||
return STATUS_ERROR; |
|
||||||
} |
|
@ -1,37 +0,0 @@ |
|||||||
# $Header: /cvsroot/pgsql/src/bin/pg_passwd/Attic/Makefile,v 1.14 2001/05/12 19:49:47 petere Exp $
|
|
||||||
|
|
||||||
subdir = src/bin/pg_passwd
|
|
||||||
top_builddir = ../../..
|
|
||||||
include $(top_builddir)/src/Makefile.global |
|
||||||
|
|
||||||
OBJS = pg_passwd.o
|
|
||||||
ifdef STRDUP |
|
||||||
OBJS += $(top_builddir)/src/utils/strdup.o
|
|
||||||
endif |
|
||||||
|
|
||||||
all: pg_passwd |
|
||||||
|
|
||||||
pg_passwd: $(OBJS) |
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
|
|
||||||
|
|
||||||
$(top_builddir)/src/utils/strdup.o: |
|
||||||
$(MAKE) -C $(top_builddir)/src/utils strdup.o
|
|
||||||
|
|
||||||
install: all installdirs |
|
||||||
$(INSTALL_PROGRAM) pg_passwd$(X) $(DESTDIR)$(bindir)/pg_passwd$(X)
|
|
||||||
|
|
||||||
installdirs: |
|
||||||
$(mkinstalldirs) $(DESTDIR)$(bindir)
|
|
||||||
|
|
||||||
uninstall: |
|
||||||
rm -f $(DESTDIR)$(bindir)/pg_passwd$(X)
|
|
||||||
|
|
||||||
depend dep: |
|
||||||
$(CC) -MM $(CFLAGS) *.c >depend
|
|
||||||
|
|
||||||
clean distclean maintainer-clean: |
|
||||||
rm -f pg_passwd$(X) pg_passwd.o
|
|
||||||
|
|
||||||
ifeq (depend,$(wildcard depend)) |
|
||||||
include depend |
|
||||||
endif |
|
@ -1,412 +0,0 @@ |
|||||||
/*
|
|
||||||
* @(#) pg_passwd.c 1.8 09:13:16 97/07/02 Y. Ichikawa |
|
||||||
*/ |
|
||||||
#include "postgres_fe.h" |
|
||||||
|
|
||||||
#include <unistd.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <time.h> |
|
||||||
#include <ctype.h> |
|
||||||
#define issaltchar(c) (isalnum((unsigned char) (c)) || (c) == '.' || (c) == '/') |
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS_H |
|
||||||
#include <termios.h> |
|
||||||
#endif |
|
||||||
#ifdef HAVE_CRYPT_H |
|
||||||
#include <crypt.h> |
|
||||||
#else |
|
||||||
extern char *crypt(const char *, const char *); |
|
||||||
#endif |
|
||||||
|
|
||||||
/*
|
|
||||||
* We assume that the output of crypt(3) is always 13 characters, |
|
||||||
* and that at most 8 characters can usefully be sent to it. |
|
||||||
* |
|
||||||
* Postgres usernames are assumed to be less than NAMEDATALEN chars long. |
|
||||||
*/ |
|
||||||
#define CLEAR_PASSWD_LEN 8 /* not including null */ |
|
||||||
#define CRYPTED_PASSWD_LEN 13 /* not including null */ |
|
||||||
|
|
||||||
const char *progname; |
|
||||||
|
|
||||||
static void usage(void); |
|
||||||
static void read_pwd_file(char *filename); |
|
||||||
static void write_pwd_file(char *filename, char *bkname); |
|
||||||
static void encrypt_pwd(char key[CLEAR_PASSWD_LEN + 1], |
|
||||||
char salt[3], |
|
||||||
char passwd[CRYPTED_PASSWD_LEN + 1]); |
|
||||||
static void prompt_for_username(char *username); |
|
||||||
static void prompt_for_password(char *prompt, char *password); |
|
||||||
|
|
||||||
static void |
|
||||||
usage(void) |
|
||||||
{ |
|
||||||
printf("%s manipulates flat text password files for PostgreSQL.\n\n", progname); |
|
||||||
printf("Usage:\n %s PASSWORD-FILE\n\n", progname); |
|
||||||
printf("Report bugs to <pgsql-bugs@postgresql.org>.\n"); |
|
||||||
} |
|
||||||
|
|
||||||
typedef struct |
|
||||||
{ |
|
||||||
char *uname; |
|
||||||
char *pwd; |
|
||||||
char *rest; |
|
||||||
} pg_pwd; |
|
||||||
|
|
||||||
#define MAXPWDS 1024 |
|
||||||
|
|
||||||
pg_pwd pwds[MAXPWDS]; |
|
||||||
int npwds = 0; |
|
||||||
|
|
||||||
|
|
||||||
static void |
|
||||||
read_pwd_file(char *filename) |
|
||||||
{ |
|
||||||
FILE *fp; |
|
||||||
static char line[512]; |
|
||||||
static char ans[128]; |
|
||||||
int i; |
|
||||||
|
|
||||||
try_again: |
|
||||||
fp = fopen(filename, PG_BINARY_R); |
|
||||||
if (fp == NULL) |
|
||||||
{ |
|
||||||
if (errno == ENOENT) |
|
||||||
{ |
|
||||||
printf("File \"%s\" does not exist. Create? (y/n): ", filename); |
|
||||||
fflush(stdout); |
|
||||||
if (fgets(ans, sizeof(ans), stdin) == NULL) |
|
||||||
exit(1); |
|
||||||
switch (ans[0]) |
|
||||||
{ |
|
||||||
case 'y': |
|
||||||
case 'Y': |
|
||||||
fp = fopen(filename, PG_BINARY_W); |
|
||||||
if (fp == NULL) |
|
||||||
{ |
|
||||||
perror(filename); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
fclose(fp); |
|
||||||
goto try_again; |
|
||||||
default: |
|
||||||
/* cannot continue */ |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
perror(filename); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/* read all the entries */ |
|
||||||
for (npwds = 0; |
|
||||||
npwds < MAXPWDS && fgets(line, sizeof(line), fp) != NULL; |
|
||||||
++npwds) |
|
||||||
{ |
|
||||||
int l; |
|
||||||
char *p, |
|
||||||
*q; |
|
||||||
|
|
||||||
l = strlen(line); |
|
||||||
if (line[l - 1] == '\n') |
|
||||||
line[l - 1] = '\0'; |
|
||||||
else |
|
||||||
{ |
|
||||||
fprintf(stderr, "%s:%d: line too long\n", |
|
||||||
filename, npwds + 1); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
|
|
||||||
/* get user name */ |
|
||||||
p = line; |
|
||||||
if ((q = strchr(p, ':')) != NULL) |
|
||||||
*q = '\0'; |
|
||||||
|
|
||||||
if (strlen(p) == 0) |
|
||||||
{ |
|
||||||
fprintf(stderr, "%s:%d: null user name\n", |
|
||||||
filename, npwds + 1); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
pwds[npwds].uname = strdup(p); |
|
||||||
|
|
||||||
/* check for duplicate user name */ |
|
||||||
for (i = 0; i < npwds; ++i) |
|
||||||
{ |
|
||||||
if (strcmp(pwds[i].uname, pwds[npwds].uname) == 0) |
|
||||||
{ |
|
||||||
fprintf(stderr, "Duplicate username %s in entry %d\n", |
|
||||||
pwds[npwds].uname, npwds + 1); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/* get password field */ |
|
||||||
if (q) |
|
||||||
{ |
|
||||||
p = q + 1; |
|
||||||
q = strchr(p, ':'); |
|
||||||
|
|
||||||
if (q != NULL) |
|
||||||
*(q++) = '\0'; |
|
||||||
|
|
||||||
if (strlen(p) != CRYPTED_PASSWD_LEN && strcmp(p, "+") != 0) |
|
||||||
{ |
|
||||||
fprintf(stderr, "%s:%d: warning: invalid password length\n", |
|
||||||
filename, npwds + 1); |
|
||||||
} |
|
||||||
pwds[npwds].pwd = strdup(p); |
|
||||||
} |
|
||||||
else |
|
||||||
pwds[npwds].pwd = NULL; |
|
||||||
|
|
||||||
/* rest of the line is treated as is */ |
|
||||||
if (q == NULL) |
|
||||||
pwds[npwds].rest = NULL; |
|
||||||
else |
|
||||||
pwds[npwds].rest = strdup(q); |
|
||||||
} |
|
||||||
|
|
||||||
fclose(fp); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
write_pwd_file(char *filename, char *bkname) |
|
||||||
{ |
|
||||||
FILE *fp; |
|
||||||
int i; |
|
||||||
|
|
||||||
/* make the backup file */ |
|
||||||
link_again: |
|
||||||
if (link(filename, bkname)) |
|
||||||
{ |
|
||||||
if (errno == EEXIST) |
|
||||||
{ |
|
||||||
unlink(bkname); |
|
||||||
goto link_again; |
|
||||||
} |
|
||||||
perror(bkname); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
if (unlink(filename)) |
|
||||||
{ |
|
||||||
perror(filename); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
|
|
||||||
/* open file */ |
|
||||||
if ((fp = fopen(filename, PG_BINARY_W)) == NULL) |
|
||||||
{ |
|
||||||
perror(filename); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
|
|
||||||
/* write file */ |
|
||||||
for (i = 0; i < npwds; ++i) |
|
||||||
{ |
|
||||||
fprintf(fp, "%s", pwds[i].uname); |
|
||||||
if (pwds[i].pwd) |
|
||||||
fprintf(fp, ":%s", pwds[i].pwd); |
|
||||||
if (pwds[i].rest) |
|
||||||
fprintf(fp, ":%s", pwds[i].rest); |
|
||||||
fprintf(fp, "\n"); |
|
||||||
} |
|
||||||
|
|
||||||
fclose(fp); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
encrypt_pwd(char key[CLEAR_PASSWD_LEN + 1], |
|
||||||
char salt[3], |
|
||||||
char passwd[CRYPTED_PASSWD_LEN + 1]) |
|
||||||
{ |
|
||||||
int n; |
|
||||||
|
|
||||||
/* select a salt, if not already given */ |
|
||||||
if (salt[0] == '\0') |
|
||||||
{ |
|
||||||
srand(time(NULL)); |
|
||||||
do |
|
||||||
{ |
|
||||||
n = rand() % 256; |
|
||||||
} while (!issaltchar(n)); |
|
||||||
salt[0] = n; |
|
||||||
do |
|
||||||
{ |
|
||||||
n = rand() % 256; |
|
||||||
} while (!issaltchar(n)); |
|
||||||
salt[1] = n; |
|
||||||
salt[2] = '\0'; |
|
||||||
} |
|
||||||
|
|
||||||
/* get encrypted password */ |
|
||||||
strcpy(passwd, crypt(key, salt)); |
|
||||||
|
|
||||||
#ifdef PG_PASSWD_DEBUG |
|
||||||
/* show it */ |
|
||||||
fprintf(stderr, "key = %s, salt = %s, password = %s\n", |
|
||||||
key, salt, passwd); |
|
||||||
#endif |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
prompt_for_username(char *username) |
|
||||||
{ |
|
||||||
int length; |
|
||||||
|
|
||||||
printf("Username: "); |
|
||||||
fflush(stdout); |
|
||||||
if (fgets(username, NAMEDATALEN, stdin) == NULL) |
|
||||||
username[0] = '\0'; |
|
||||||
|
|
||||||
length = strlen(username); |
|
||||||
if (length > 0 && username[length - 1] != '\n') |
|
||||||
{ |
|
||||||
/* eat rest of the line */ |
|
||||||
char buf[128]; |
|
||||||
int buflen; |
|
||||||
|
|
||||||
do |
|
||||||
{ |
|
||||||
if (fgets(buf, sizeof(buf), stdin) == NULL) |
|
||||||
break; |
|
||||||
buflen = strlen(buf); |
|
||||||
} while (buflen > 0 && buf[buflen - 1] != '\n'); |
|
||||||
} |
|
||||||
if (length > 0 && username[length - 1] == '\n') |
|
||||||
username[length - 1] = '\0'; |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
prompt_for_password(char *prompt, char *password) |
|
||||||
{ |
|
||||||
int length; |
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS_H |
|
||||||
struct termios t_orig, |
|
||||||
t; |
|
||||||
#endif |
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS_H |
|
||||||
tcgetattr(0, &t); |
|
||||||
t_orig = t; |
|
||||||
t.c_lflag &= ~ECHO; |
|
||||||
tcsetattr(0, TCSADRAIN, &t); |
|
||||||
#endif |
|
||||||
|
|
||||||
printf(prompt); |
|
||||||
fflush(stdout); |
|
||||||
|
|
||||||
if (fgets(password, CLEAR_PASSWD_LEN + 1, stdin) == NULL) |
|
||||||
password[0] = '\0'; |
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS_H |
|
||||||
tcsetattr(0, TCSADRAIN, &t_orig); |
|
||||||
#endif |
|
||||||
|
|
||||||
length = strlen(password); |
|
||||||
if (length > 0 && password[length - 1] != '\n') |
|
||||||
{ |
|
||||||
/* eat rest of the line */ |
|
||||||
char buf[128]; |
|
||||||
int buflen; |
|
||||||
|
|
||||||
do |
|
||||||
{ |
|
||||||
if (fgets(buf, sizeof(buf), stdin) == NULL) |
|
||||||
break; |
|
||||||
buflen = strlen(buf); |
|
||||||
} while (buflen > 0 && buf[buflen - 1] != '\n'); |
|
||||||
} |
|
||||||
if (length > 0 && password[length - 1] == '\n') |
|
||||||
password[length - 1] = '\0'; |
|
||||||
printf("\n"); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
int |
|
||||||
main(int argc, char *argv[]) |
|
||||||
{ |
|
||||||
char *filename; |
|
||||||
char bkname[MAXPGPATH]; |
|
||||||
char username[NAMEDATALEN]; |
|
||||||
char salt[3]; |
|
||||||
char key[CLEAR_PASSWD_LEN + 1], |
|
||||||
key2[CLEAR_PASSWD_LEN + 1]; |
|
||||||
char e_passwd[CRYPTED_PASSWD_LEN + 1]; |
|
||||||
int i; |
|
||||||
|
|
||||||
progname = argv[0]; |
|
||||||
|
|
||||||
if (argc != 2) |
|
||||||
{ |
|
||||||
fprintf(stderr, "%s: too %s arguments\nTry '%s --help' for more information.\n", |
|
||||||
progname, argc > 2 ? "many" : "few", progname); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
|
|
||||||
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) |
|
||||||
{ |
|
||||||
usage(); |
|
||||||
exit(0); |
|
||||||
} |
|
||||||
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) |
|
||||||
{ |
|
||||||
puts("pg_passwd (PostgreSQL) " PG_VERSION); |
|
||||||
exit(0); |
|
||||||
} |
|
||||||
if (argv[1][0] == '-') |
|
||||||
{ |
|
||||||
fprintf(stderr, "%s: invalid option: %s\nTry '%s --help' for more information.\n", |
|
||||||
progname, argv[1], progname); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
|
|
||||||
filename = argv[1]; |
|
||||||
|
|
||||||
/* open file */ |
|
||||||
read_pwd_file(filename); |
|
||||||
|
|
||||||
/* ask for the user name and the password */ |
|
||||||
prompt_for_username(username); |
|
||||||
prompt_for_password("New password: ", key); |
|
||||||
prompt_for_password("Re-enter new password: ", key2); |
|
||||||
if (strcmp(key, key2) != 0) |
|
||||||
{ |
|
||||||
fprintf(stderr, "Password mismatch\n"); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
salt[0] = '\0'; |
|
||||||
encrypt_pwd(key, salt, e_passwd); |
|
||||||
|
|
||||||
/* check password entry */ |
|
||||||
for (i = 0; i < npwds; ++i) |
|
||||||
{ |
|
||||||
if (strcmp(pwds[i].uname, username) == 0) |
|
||||||
{ /* found */ |
|
||||||
pwds[i].pwd = strdup(e_passwd); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
if (i == npwds) |
|
||||||
{ /* did not exist */ |
|
||||||
if (npwds == MAXPWDS) |
|
||||||
{ |
|
||||||
fprintf(stderr, "Cannot handle so many entries\n"); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
pwds[npwds].uname = strdup(username); |
|
||||||
pwds[npwds].pwd = strdup(e_passwd); |
|
||||||
pwds[npwds].rest = NULL; |
|
||||||
++npwds; |
|
||||||
} |
|
||||||
|
|
||||||
/* write back the file */ |
|
||||||
sprintf(bkname, "%s.bk", filename); |
|
||||||
write_pwd_file(filename, bkname); |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
Loading…
Reference in new issue