~ubuntu-branches/ubuntu/natty/postgresql-8.4/natty-updates

« back to all changes in this revision

Viewing changes to contrib/chkpass/chkpass.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-03-20 12:00:13 UTC
  • Revision ID: james.westby@ubuntu.com-20090320120013-hogj7egc5mjncc5g
Tags: upstream-8.4~0cvs20090328
ImportĀ upstreamĀ versionĀ 8.4~0cvs20090328

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/
 
6
 *
 
7
 * $PostgreSQL$
 
8
 * best viewed with tabs set to 4
 
9
 */
 
10
 
 
11
#include "postgres.h"
 
12
 
 
13
#include <time.h>
 
14
#include <unistd.h>
 
15
#ifdef HAVE_CRYPT_H
 
16
#include <crypt.h>
 
17
#endif
 
18
 
 
19
#include "fmgr.h"
 
20
#include "utils/builtins.h"
 
21
 
 
22
PG_MODULE_MAGIC;
 
23
 
 
24
/*
 
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.
 
29
 */
 
30
 
 
31
 
 
32
/*
 
33
 * This is the internal storage format for CHKPASSs.
 
34
 * 15 is all I need but add a little buffer
 
35
 */
 
36
 
 
37
typedef struct chkpass
 
38
{
 
39
        char            password[16];
 
40
}       chkpass;
 
41
 
 
42
/*
 
43
 * Various forward declarations:
 
44
 */
 
45
 
 
46
Datum           chkpass_in(PG_FUNCTION_ARGS);
 
47
Datum           chkpass_out(PG_FUNCTION_ARGS);
 
48
Datum           chkpass_rout(PG_FUNCTION_ARGS);
 
49
 
 
50
/* Only equal or not equal make sense */
 
51
Datum           chkpass_eq(PG_FUNCTION_ARGS);
 
52
Datum           chkpass_ne(PG_FUNCTION_ARGS);
 
53
 
 
54
 
 
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)
 
59
{
 
60
        return 0;
 
61
}
 
62
 
 
63
/*
 
64
 * CHKPASS reader.
 
65
 */
 
66
PG_FUNCTION_INFO_V1(chkpass_in);
 
67
Datum
 
68
chkpass_in(PG_FUNCTION_ARGS)
 
69
{
 
70
        char       *str = PG_GETARG_CSTRING(0);
 
71
        chkpass    *result;
 
72
        char            mysalt[4];
 
73
        static char salt_chars[] =
 
74
        "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
75
 
 
76
        /* special case to let us enter encrypted passwords */
 
77
        if (*str == ':')
 
78
        {
 
79
                result = (chkpass *) palloc(sizeof(chkpass));
 
80
                strlcpy(result->password, str + 1, 13 + 1);
 
81
                PG_RETURN_POINTER(result);
 
82
        }
 
83
 
 
84
        if (verify_pass(str) != 0)
 
85
                ereport(ERROR,
 
86
                                (errcode(ERRCODE_DATA_EXCEPTION),
 
87
                                 errmsg("password \"%s\" is weak", str)));
 
88
 
 
89
        result = (chkpass *) palloc(sizeof(chkpass));
 
90
 
 
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);
 
97
}
 
98
 
 
99
/*
 
100
 * CHKPASS output function.
 
101
 * Just like any string but we know it is max 15 (13 plus colon and terminator.)
 
102
 */
 
103
 
 
104
PG_FUNCTION_INFO_V1(chkpass_out);
 
105
Datum
 
106
chkpass_out(PG_FUNCTION_ARGS)
 
107
{
 
108
        chkpass    *password = (chkpass *) PG_GETARG_POINTER(0);
 
109
        char       *result;
 
110
 
 
111
        result = (char *) palloc(16);
 
112
        result[0] = ':';
 
113
        strcpy(result + 1, password->password);
 
114
 
 
115
        PG_RETURN_CSTRING(result);
 
116
}
 
117
 
 
118
 
 
119
/*
 
120
 * special output function that doesn't output the colon
 
121
 */
 
122
 
 
123
PG_FUNCTION_INFO_V1(chkpass_rout);
 
124
Datum
 
125
chkpass_rout(PG_FUNCTION_ARGS)
 
126
{
 
127
        chkpass    *password = (chkpass *) PG_GETARG_POINTER(0);
 
128
 
 
129
        PG_RETURN_TEXT_P(cstring_to_text(password->password));
 
130
}
 
131
 
 
132
 
 
133
/*
 
134
 * Boolean tests
 
135
 */
 
136
 
 
137
PG_FUNCTION_INFO_V1(chkpass_eq);
 
138
Datum
 
139
chkpass_eq(PG_FUNCTION_ARGS)
 
140
{
 
141
        chkpass    *a1 = (chkpass *) PG_GETARG_POINTER(0);
 
142
        text       *a2 = PG_GETARG_TEXT_PP(1);
 
143
        char            str[9];
 
144
 
 
145
        text_to_cstring_buffer(a2, str, sizeof(str));
 
146
        PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) == 0);
 
147
}
 
148
 
 
149
PG_FUNCTION_INFO_V1(chkpass_ne);
 
150
Datum
 
151
chkpass_ne(PG_FUNCTION_ARGS)
 
152
{
 
153
        chkpass    *a1 = (chkpass *) PG_GETARG_POINTER(0);
 
154
        text       *a2 = PG_GETARG_TEXT_PP(1);
 
155
        char            str[9];
 
156
 
 
157
        text_to_cstring_buffer(a2, str, sizeof(str));
 
158
        PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) != 0);
 
159
}