LCOV - code coverage report
Current view: top level - src/odbc/unittests - oldpwd.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 46 53 86.8 %
Date: 2026-01-01 15:30:10 Functions: 2 2 100.0 %

          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             : }

Generated by: LCOV version 1.13