Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "postgres.h"
00016
00017 #include <ctype.h>
00018
00019 #ifdef USE_CRACKLIB
00020 #include <crack.h>
00021 #endif
00022
00023 #include "commands/user.h"
00024 #include "fmgr.h"
00025 #include "libpq/md5.h"
00026
00027
00028 PG_MODULE_MAGIC;
00029
00030
00031 #define MIN_PWD_LENGTH 8
00032
00033 extern void _PG_init(void);
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 static void
00053 check_password(const char *username,
00054 const char *password,
00055 int password_type,
00056 Datum validuntil_time,
00057 bool validuntil_null)
00058 {
00059 int namelen = strlen(username);
00060 int pwdlen = strlen(password);
00061 char encrypted[MD5_PASSWD_LEN + 1];
00062 int i;
00063 bool pwd_has_letter,
00064 pwd_has_nonletter;
00065
00066 switch (password_type)
00067 {
00068 case PASSWORD_TYPE_MD5:
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 if (!pg_md5_encrypt(username, username, namelen, encrypted))
00079 elog(ERROR, "password encryption failed");
00080 if (strcmp(password, encrypted) == 0)
00081 ereport(ERROR,
00082 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00083 errmsg("password must not contain user name")));
00084 break;
00085
00086 case PASSWORD_TYPE_PLAINTEXT:
00087
00088
00089
00090
00091
00092
00093 if (pwdlen < MIN_PWD_LENGTH)
00094 ereport(ERROR,
00095 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00096 errmsg("password is too short")));
00097
00098
00099 if (strstr(password, username))
00100 ereport(ERROR,
00101 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00102 errmsg("password must not contain user name")));
00103
00104
00105 pwd_has_letter = false;
00106 pwd_has_nonletter = false;
00107 for (i = 0; i < pwdlen; i++)
00108 {
00109
00110
00111
00112
00113 if (isalpha((unsigned char) password[i]))
00114 pwd_has_letter = true;
00115 else
00116 pwd_has_nonletter = true;
00117 }
00118 if (!pwd_has_letter || !pwd_has_nonletter)
00119 ereport(ERROR,
00120 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00121 errmsg("password must contain both letters and nonletters")));
00122
00123 #ifdef USE_CRACKLIB
00124
00125 if (FascistCheck(password, CRACKLIB_DICTPATH))
00126 ereport(ERROR,
00127 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00128 errmsg("password is easily cracked")));
00129 #endif
00130 break;
00131
00132 default:
00133 elog(ERROR, "unrecognized password type: %d", password_type);
00134 break;
00135 }
00136
00137
00138 }
00139
00140
00141
00142
00143 void
00144 _PG_init(void)
00145 {
00146
00147 check_password_hook = check_password;
00148 }