1 Reply Latest reply: Apr 11, 2013 10:46 AM by bbrodd RSS

    OCIPasswordChange does not work when pw has expired

    bbrodd
      I am trying to implement the OCIPasswordChange function but am having an interesting problem with it. If the userid that I am trying to change the pw for is not expired, my implementation works fine and the pw for the userid is updated. Running the exact same code, but forcing the pw to be expired via the servers "Database Home Page" before running it results in an "ORA-01017: invalid username/password; logon denied" error. I am using the right userid/pw and the preceding OCISessionBegin call return code correctly indicates that the pw has expired. Any ideas on what I am doing wrong?

      I am using Oracle Express 10g with the server on one pc and the client on another ... both XP.

      Here is a C example of using OciPasswordChange that I followed for implementing in VA Smalltalk. Thought it might help identify the problem:
      OCIPassworChange
      oid main()
      {
      int     rc;

      char     errbuf[100];
      int     errcode;

      // Step 1: Initialize OCI
      rc = OCIInitialize((ub4) OCI_DEFAULT, (dvoid *)0,
      (dvoid * (*)(dvoid *, size_t)) 0,
      (dvoid * (*)(dvoid *, dvoid *, size_t))0,
      (void (*)(dvoid *, dvoid *)) 0 );

      // Step 2: Initialize the OCI evironment
      rc = OCIEnvInit( (OCIEnv **) &p_env, OCI_DEFAULT, (size_t) 0, (dvoid **) 0 );

      // Step 3: Initialize the OCI handles
      rc = OCIHandleAlloc( (dvoid *) p_env, (dvoid **) &p_err, OCI_HTYPE_ERROR,
      (size_t) 0, (dvoid **) 0);

      rc = OCIHandleAlloc( (dvoid *) p_env, (dvoid **) &p_svc, OCI_HTYPE_SVCCTX,
      (size_t) 0, (dvoid **) 0);

      rc = OCIHandleAlloc( (dvoid *) p_env, (dvoid **) &p_srv, OCI_HTYPE_SERVER,
      (size_t) 0, (dvoid **) 0);

      rc = OCIHandleAlloc((dvoid *) p_env, (dvoid **)&p_ses, (ub4) OCI_HTYPE_SESSION,
      (size_t) 0, (dvoid **) 0);

      // Step 4: Connect using a mutli-session connect
      rc = OCIServerAttach( p_srv, p_err,
      (text *)"local", 5, 0);

      // Create a server context
      rc = OCIAttrSet( (dvoid *) p_svc, OCI_HTYPE_SVCCTX,
      (dvoid *)p_srv, (ub4) 0,
      (ub4) OCI_ATTR_SERVER, (OCIError *) p_err);

      // Create a session context
      rc = OCIAttrSet((dvoid *) p_ses, (ub4) OCI_HTYPE_SESSION,
      (dvoid *) "testuser", (ub4) 8,
      (ub4) OCI_ATTR_USERNAME, p_err);
      rc = OCIAttrSet((dvoid *) p_ses, (ub4) OCI_HTYPE_SESSION,
      (dvoid *) "oldpass", (ub4) 7,
      (ub4) OCI_ATTR_PASSWORD, p_err);

      rc = OCIAttrSet((dvoid *) p_svc, (ub4) OCI_HTYPE_SVCCTX,
      (dvoid *) p_ses, (ub4) 0,
      (ub4) OCI_ATTR_SESSION, p_err);

      // Open the session on the server
      rc = OCISessionBegin ( p_svc, p_err, p_ses, OCI_CRED_RDBMS,
      (ub4) OCI_DEFAULT);

      // This is a generic error checking routine
      if (rc != 0)
      {
      OCIErrorGet((dvoid *)p_err, (ub4) 1, (text *) NULL, &errcode,
      (text*)errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
      printf("Error - %.*s\n", 512, errbuf);

      // If the error is a 28001, change the password.
      if(errcode==28001)
      {
      // You need to set the Session into the service context
      // before you can call OCIPasswordChange(), and you also need
      // to allocate both the session and service context handles
      // before hand. Then you can call OCIPasswordChange.
      rc = OCIAttrSet((dvoid *)p_svc, OCI_HTYPE_SVCCTX,
      (dvoid *)p_ses,0,OCI_ATTR_SESSION, p_err);
      rc = OCIPasswordChange(p_svc, p_err, "testuser",8,
      "oldpass",7, "newpass",8, OCI_DEFAULT);
      if(rc != 0) printf("Password change failed.\n");
      else printf("Password successfully changed.\n");
      }
      }

      // Step 10: Disconnect from the server and free the
      rc = OCIServerDetach( p_srv, p_err, OCI_DEFAULT );
      rc = OCIHandleFree((dvoid *) p_srv, OCI_HTYPE_SERVER);
      rc = OCIHandleFree((dvoid *) p_svc, OCI_HTYPE_SVCCTX);
      rc = OCIHandleFree((dvoid *) p_err, OCI_HTYPE_ERROR);
      printf("Disconnected.\n\n");

      return;
      }

      Thanks,
      Bob

      Edited by: bbrodd on Apr 10, 2013 6:44 AM
        • 1. Re: OCIPasswordChange does not work when pw has expired
          bbrodd
          I finally figured out my issue. I didn't realize that I was running with an 11.x Instant Client against my 10g Express DB. I don't remember setting up 11.x, but I have been running this way for about a year without experiencing any other problems. I don't know why the very specific event of updating an expired password fails (and updating an unexpired password succeeds), but re-installing the latest 10.x version of InstantClient resolved the issue.