LCOV - code coverage report
Current view: top level - src/odbc/unittests - oldpwd.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 45 52 86.5 %
Date: 2025-12-03 08:48:55 Functions: 2 2 100.0 %

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

Generated by: LCOV version 1.13