Only skip pages marked as clean in the visibility map, if the last 32
[PostgreSQL.git] / contrib / chkpass / chkpass.c
blobad6c1e713e95958c176fe539ad438a6c0c0f1f33
1 /*
2 * PostgreSQL type definitions for chkpass
3 * Written by D'Arcy J.M. Cain
4 * darcy@druid.net
5 * http://www.druid.net/darcy/
7 * $PostgreSQL$
8 * best viewed with tabs set to 4
9 */
11 #include "postgres.h"
13 #include <time.h>
14 #include <unistd.h>
15 #ifdef HAVE_CRYPT_H
16 #include <crypt.h>
17 #endif
19 #include "fmgr.h"
20 #include "utils/builtins.h"
22 PG_MODULE_MAGIC;
25 * This type encrypts it's input unless the first character is a colon.
26 * The output is the encrypted form with a leading colon. The output
27 * format is designed to allow dump and reload operations to work as
28 * expected without doing special tricks.
33 * This is the internal storage format for CHKPASSs.
34 * 15 is all I need but add a little buffer
37 typedef struct chkpass
39 char password[16];
40 } chkpass;
43 * Various forward declarations:
46 Datum chkpass_in(PG_FUNCTION_ARGS);
47 Datum chkpass_out(PG_FUNCTION_ARGS);
48 Datum chkpass_rout(PG_FUNCTION_ARGS);
50 /* Only equal or not equal make sense */
51 Datum chkpass_eq(PG_FUNCTION_ARGS);
52 Datum chkpass_ne(PG_FUNCTION_ARGS);
55 /* This function checks that the password is a good one
56 * It's just a placeholder for now */
57 static int
58 verify_pass(const char *str)
60 return 0;
64 * CHKPASS reader.
66 PG_FUNCTION_INFO_V1(chkpass_in);
67 Datum
68 chkpass_in(PG_FUNCTION_ARGS)
70 char *str = PG_GETARG_CSTRING(0);
71 chkpass *result;
72 char mysalt[4];
73 static char salt_chars[] =
74 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
76 /* special case to let us enter encrypted passwords */
77 if (*str == ':')
79 result = (chkpass *) palloc(sizeof(chkpass));
80 strlcpy(result->password, str + 1, 13 + 1);
81 PG_RETURN_POINTER(result);
84 if (verify_pass(str) != 0)
85 ereport(ERROR,
86 (errcode(ERRCODE_DATA_EXCEPTION),
87 errmsg("password \"%s\" is weak", str)));
89 result = (chkpass *) palloc(sizeof(chkpass));
91 mysalt[0] = salt_chars[random() & 0x3f];
92 mysalt[1] = salt_chars[random() & 0x3f];
93 mysalt[2] = 0; /* technically the terminator is not necessary
94 * but I like to play safe */
95 strcpy(result->password, crypt(str, mysalt));
96 PG_RETURN_POINTER(result);
100 * CHKPASS output function.
101 * Just like any string but we know it is max 15 (13 plus colon and terminator.)
104 PG_FUNCTION_INFO_V1(chkpass_out);
105 Datum
106 chkpass_out(PG_FUNCTION_ARGS)
108 chkpass *password = (chkpass *) PG_GETARG_POINTER(0);
109 char *result;
111 result = (char *) palloc(16);
112 result[0] = ':';
113 strcpy(result + 1, password->password);
115 PG_RETURN_CSTRING(result);
120 * special output function that doesn't output the colon
123 PG_FUNCTION_INFO_V1(chkpass_rout);
124 Datum
125 chkpass_rout(PG_FUNCTION_ARGS)
127 chkpass *password = (chkpass *) PG_GETARG_POINTER(0);
129 PG_RETURN_TEXT_P(cstring_to_text(password->password));
134 * Boolean tests
137 PG_FUNCTION_INFO_V1(chkpass_eq);
138 Datum
139 chkpass_eq(PG_FUNCTION_ARGS)
141 chkpass *a1 = (chkpass *) PG_GETARG_POINTER(0);
142 text *a2 = PG_GETARG_TEXT_PP(1);
143 char str[9];
145 text_to_cstring_buffer(a2, str, sizeof(str));
146 PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) == 0);
149 PG_FUNCTION_INFO_V1(chkpass_ne);
150 Datum
151 chkpass_ne(PG_FUNCTION_ARGS)
153 chkpass *a1 = (chkpass *) PG_GETARG_POINTER(0);
154 text *a2 = PG_GETARG_TEXT_PP(1);
155 char str[9];
157 text_to_cstring_buffer(a2, str, sizeof(str));
158 PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) != 0);