Line data Source code
1 : #include "common.h"
2 :
3 : #include <assert.h>
4 : #include <freetds/utils.h>
5 :
6 : /* change password on server */
7 :
8 : #define USER "freetds_oldpwd"
9 : #define PWD1 "TestPWD1?"
10 : #define PWD2 "OtherPWDButLonger2@"
11 :
12 : static void
13 2 : my_attrs(void)
14 : {
15 2 : SQLSetConnectAttr(odbc_conn, 1226 /* SQL_COPT_SS_OLDPWD */ ,
16 1 : (SQLPOINTER) T(PWD1), SQL_NTS);
17 2 : strcpy(common_pwd.user, USER);
18 2 : strcpy(common_pwd.password, PWD2);
19 2 : }
20 :
21 : static HENV save_env;
22 : static HDBC save_conn;
23 : static HSTMT save_stmt;
24 :
25 : static void
26 : swap_conn(void)
27 : {
28 4 : ODBC_SWAP(HENV, odbc_env, save_env);
29 4 : ODBC_SWAP(HDBC, odbc_conn, save_conn);
30 4 : ODBC_SWAP(HSTMT, odbc_stmt, save_stmt);
31 : }
32 :
33 10 : TEST_MAIN()
34 : {
35 : const char *ci;
36 : SQLRETURN rc;
37 :
38 10 : odbc_use_version3 = true;
39 :
40 : /*
41 : * Check if we are in CI.
42 : * This test is doing some administration setting on the server, avoid
43 : * to do on all machines, especially if users are trying to run tests
44 : * without knowing this.
45 : */
46 10 : ci = getenv("CI");
47 10 : if (!ci || strcasecmp(ci, "true") != 0) {
48 0 : odbc_test_skipped();
49 0 : return 0;
50 : }
51 :
52 10 : odbc_connect();
53 :
54 : /* minimum TDS 7.2 and MSSQL 2012 */
55 10 : if (odbc_tds_version() < 0x702 || odbc_db_version_int() < 0x0a000000u) {
56 6 : odbc_disconnect();
57 6 : odbc_test_skipped();
58 0 : return 0;
59 : }
60 :
61 : /* create new login for this test and disconnect */
62 4 : odbc_command_with_result(odbc_stmt, "DROP LOGIN " USER);
63 4 : rc = odbc_command2("CREATE LOGIN " USER " WITH PASSWORD='" PWD1 "' MUST_CHANGE, "
64 : "DEFAULT_DATABASE = tempdb, CHECK_EXPIRATION = ON", "SENo");
65 4 : if (rc == SQL_ERROR) {
66 2 : odbc_read_error();
67 2 : odbc_disconnect();
68 2 : if (strstr(odbc_err, "MUST_CHANGE") == NULL)
69 : return 1;
70 2 : odbc_test_skipped();
71 0 : return 0;
72 : }
73 2 : swap_conn();
74 :
75 : /* login with new password should fail */
76 2 : strcpy(common_pwd.user, USER);
77 2 : strcpy(common_pwd.password, PWD1);
78 :
79 2 : CHKAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &odbc_env, "S");
80 2 : SQLSetEnvAttr(odbc_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
81 2 : CHKAllocHandle(SQL_HANDLE_DBC, odbc_env, &odbc_conn, "S");
82 2 : CHKConnect(T(common_pwd.server), SQL_NTS, T(common_pwd.user), SQL_NTS, T(common_pwd.password), SQL_NTS, "E");
83 2 : odbc_read_error();
84 4 : if (strcmp(odbc_sqlstate, "42000") != 0 ||
85 4 : strstr(odbc_err, USER) == NULL || strstr(odbc_err, "The password of the account must be changed") == NULL) {
86 0 : fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate);
87 0 : odbc_disconnect();
88 0 : return 1;
89 : }
90 2 : odbc_disconnect();
91 :
92 : /* login and change password */
93 2 : odbc_set_conn_attr = my_attrs;
94 2 : odbc_connect();
95 2 : odbc_disconnect();
96 :
97 : /* login wiht new password */
98 2 : odbc_set_conn_attr = NULL;
99 2 : odbc_connect();
100 2 : odbc_disconnect();
101 :
102 : /* drop created login */
103 2 : tds_sleep_ms(500); /* give time for logoff */
104 2 : swap_conn();
105 2 : odbc_command("DROP LOGIN " USER);
106 2 : odbc_disconnect();
107 :
108 2 : return 0;
109 : }
|