verify_password_function オプションを使用して、パスワード規則を実装します。
文字列
空の文字列 (パスワードが設定されていない場合、関数は呼び出されない)
DBA 権限が必要です。
verify_password_function で指定された関数は、NULL 以外のパスワードが作成されるか設定されると、自動的に呼び出されます。ユーザによって関数が上書きされないようにするには、オプション値を owner.function-name に設定します。ユーザは、データベースに接続可能なパスワードを持っている必要があります。パスワードは大文字と小文字が区別され、次に該当する値は指定できません。
作成または変更したパスワードは、UTF-8 に変換されてからハッシュされ、データベースに保存されます。データベースをアンロードし、別の文字セットを使用するデータベースに再ロードした場合でも、既存のパスワードは機能します。サーバがクライアントの文字セットを UTF-8 に変換できない場合、パスワードには 7 ビット ASCII 文字を使用することをおすすめします。それ以外の文字を使用すると、パスワードが機能しないことがあります。
パスワードの設定には、次のいずれかの文を使用します。
パスワードの作成または設定に使用する文の検証後、関数が呼び出され、指定した規則を使用してパスワードが検証されます。パスワードが規則に従っている場合、関数は成功を示す NULL を返し、呼び出し元の文が実行されます。パスワードが規則に違反している場合は、エラーが設定されるか、エラーを示す NULL 以外の文字列が返されます。NULL 以外の文字列は、パスワードが不合格となった理由として、ユーザに返されるエラーに追加されます。
パスワード検証関数は、user_name VARCHAR(128) と new_pwd VARCHAR(255) という 2 つのパラメータを取ります。戻り値のデータ型は VARCHAR(255) です。パスワード検証関数がデバッガによってステップスルーされないように、この関数で ALTER FUNCTION function-name SET HIDDEN 文を実行することをおすすめします。verify_password_function オプションを設定する場合、GRANT CONNECT 文で複数のユーザ ID とパスワードを指定することはできません。
パスワード規則の詳細については、パスワード検証の使用を参照してください。
次の例では、テーブルと関数を 1 つずつ定義し、いくつかのログイン・ポリシー・オプションを設定しています。これらは共に、パスワードに特定の種類の文字が含まれることを要求し、パスワードの再利用を禁止して、パスワード有効期限を適用するなど、詳細なパスワード規則を実装します。ユーザ ID が作成されるか、パスワードが変更されると、データベース・サーバによって verify_password_function オプションを使用して関数が呼び出されます。アプリケーションは、post_login_procedure オプションで指定されたプロシージャを呼び出して、パスワードが期限切れになる前にパスワードの変更が必要であることを通知できます。
このサンプル・コードは、samples-dir\SQLAnywhere\SQL\verify_password.sql にもあります。samples-dir の詳細については、サンプル・ディレクトリを参照してください。
-- only DBA should have permissions on this table CREATE TABLE DBA.t_pwd_history( pk INT DEFAULT AUTOINCREMENT PRIMARY KEY, user_name CHAR(128), -- the user whose password is set pwd_hash CHAR(32) ); -- hash of password value to detect -- duplicate passwords -- called whenever a non-NULL password is set -- to verify the password conforms to password rules CREATE FUNCTION DBA.f_verify_pwd( uid VARCHAR(128), new_pwd VARCHAR(255) ) RETURNS VARCHAR(255) BEGIN -- a table with one row per character in new_pwd DECLARE local temporary table pwd_chars( pos INT PRIMARY KEY, -- index of c in new_pwd c CHAR( 1 CHAR ) ); -- character -- new_pwd with non-alpha characters removed DECLARE pwd_alpha_only CHAR(255); DECLARE num_lower_chars INT; -- enforce minimum length (can also be done with -- min_password_length option) IF length( new_pwd ) < 6 THEN RETURN 'password must be at least 6 characters long'; END IF; -- break new_pwd into one row per character INSERT INTO pwd_chars SELECT row_num, substr( new_pwd, row_num, 1 ) FROM dbo.RowGenerator WHERE row_num <= length( new_pwd ); -- copy of new_pwd containing alpha-only characters SELECT list( c, '' ORDER BY pos ) INTO pwd_alpha_only FROM pwd_chars WHERE c BETWEEN 'a' AND 'z' OR c BETWEEN 'A' AND 'Z'; -- number of lower case characters IN new_pwd SELECT count(*) INTO num_lower_chars FROM pwd_chars WHERE CAST( c AS BINARY ) BETWEEN 'a' AND 'z'; -- enforce rules based on characters contained in new_pwd IF ( SELECT count(*) FROM pwd_chars WHERE c BETWEEN '0' AND '9' ) < 1 THEN RETURN 'password must contain at least one numeric digit'; ELSEIF length( pwd_alpha_only ) < 2 THEN RETURN 'password must contain at least two letters'; ELSEIF num_lower_chars = 0 OR length( pwd_alpha_only ) - num_lower_chars = 0 THEN RETURN 'password must contain both upper- and lowercase characters'; END IF; -- not the same as any user name -- (this could be modified to check against a disallowed words table) IF EXISTS( SELECT * FROM SYS.SYSUSER WHERE lower( user_name ) IN ( lower( pwd_alpha_only ), lower( new_pwd ) ) ) THEN RETURN 'password or only alphabetic characters in password ' || 'must not match any user name'; END IF; -- not the same as any previous password for this user IF EXISTS( SELECT * FROM t_pwd_history WHERE user_name = uid AND pwd_hash = hash( uid || new_pwd, 'md5' ) ) THEN RETURN 'previous passwords cannot be reused'; END IF; -- save the new password INSERT INTO t_pwd_history( user_name, pwd_hash ) VALUES( uid, hash( uid || new_pwd, 'md5' ) ); RETURN( NULL ); END; ALTER FUNCTION DBA.f_verify_pwd SET HIDDEN; GRANT EXECUTE ON DBA.f_verify_pwd TO PUBLIC; SET OPTION PUBLIC.verify_password_function = 'DBA.f_verify_pwd'; -- All passwords expire in 180 days. Expired passwords can be changed -- by the user using the NewPassword connection parameter. ALTER LOGIN POLICY DEFAULT password_life_time = 180; -- If an application calls the procedure specified by the -- post_login_procedure option, then the procedure can be used to -- warn the user that their password is about to expire. In particular, -- Interactive SQL and Sybase Central call the post_login_procedure. ALTER LOGIN POLICY DEFAULT password_grace_time = 30; -- Five consecutive failed login attempts will result in a non-DBA -- user ID being locked. ALTER LOGIN POLICY DEFAULT max_failed_login_attempts = 5; |
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |