2 * PostgreSQL type definitions for chkpass
3 * Written by D'Arcy J.M. Cain
5 * http://www.druid.net/darcy/
8 * best viewed with tabs set to 4
20 #include "utils/builtins.h"
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
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 */
58 verify_pass(const char *str
)
66 PG_FUNCTION_INFO_V1(chkpass_in
);
68 chkpass_in(PG_FUNCTION_ARGS
)
70 char *str
= PG_GETARG_CSTRING(0);
73 static char salt_chars
[] =
74 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
76 /* special case to let us enter encrypted passwords */
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)
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
);
106 chkpass_out(PG_FUNCTION_ARGS
)
108 chkpass
*password
= (chkpass
*) PG_GETARG_POINTER(0);
111 result
= (char *) palloc(16);
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
);
125 chkpass_rout(PG_FUNCTION_ARGS
)
127 chkpass
*password
= (chkpass
*) PG_GETARG_POINTER(0);
129 PG_RETURN_TEXT_P(cstring_to_text(password
->password
));
137 PG_FUNCTION_INFO_V1(chkpass_eq
);
139 chkpass_eq(PG_FUNCTION_ARGS
)
141 chkpass
*a1
= (chkpass
*) PG_GETARG_POINTER(0);
142 text
*a2
= PG_GETARG_TEXT_PP(1);
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
);
151 chkpass_ne(PG_FUNCTION_ARGS
)
153 chkpass
*a1
= (chkpass
*) PG_GETARG_POINTER(0);
154 text
*a2
= PG_GETARG_TEXT_PP(1);
157 text_to_cstring_buffer(a2
, str
, sizeof(str
));
158 PG_RETURN_BOOL(strcmp(a1
->password
, crypt(str
, a1
->password
)) != 0);