Thread

  1. [BUG] SSPI authentication fails on Windows when server parameter is localhost or domain name

    Ahmed Shinwari <ahmed.shinwari@gmail.com> — 2011-06-15T09:53:41Z

    Hi All,
    
    I faced a bug on Windows while connecting via SSPI authentication. I was
    able to find the bug and have attached the patch. Details listed below;
    
    Postgres Installer: Version 9.0.4
    OS: Windows Server 2008 R2/Windows 7
    
    Bug Description:
    =============
    If database Server is running on Windows ('Server 2008 R2' or 'Windows 7')
    with authentication mode SSPI and one try to connect from the same machine
    via 'psql' with server parameter as 'localhost' or 'fully qualified domain
    name', the database throws error;
    
    psql: FATAL:  could not get token from SSPI security context
    DETAIL:  The function requested is not supported
     (80090302)
    
    But, if assigned IP address is supplied or 127.0.0.1 is supplied instead of
    'localhost' or 'fully qualified domain name' then connection is made
    successfully.
    
    There is another behavior related that if multiple consecutive connection
    attempts are made, with server parameter as 'localhost' or 'fully qualified
    domain name' then atleast one out of five failed attempts results in server
    process abnormal termination. For example, from command prompt issue
    'psql.exe -h localhost' five times consecutively, you should get the
    following error as well;
            psql: server closed the connection unexpectedly
                This probably means the server terminated abnormally
                before or while processing the request.
    
    
    Steps To Reproduce The Error:
    ========================
    On Windows Server 2008 R2 (or Windows 7 32-bit);
    1) Create Windows user <username>
    2) Log in as that user
    3) Install PostgreSQL 9.0.4
    4) Change pg_hba.conf to have the following top lines:
        host all <username> 0.0.0.0/0 sspi
        host all <username> ::/0 sspi
    5) In Postgres, create user <username> and make them a superuser (just for
    convenience)
    6) Using psql, try the following:
        psql -h <hostname> postgres
    
    Try variations such as: localhost, <domainname>, <fully-qualified domain
    name on network>
    
    This should produce following error;
    
        psql: FATAL:  could not get token from SSPI security context
        DETAIL:  The function requested is not supported
        (80090302)
    
    
    
    Description of Fix:
    ==============
    The 'src\backend\libpq\auth.c' has a function pg_SSPI_recvauth() that
    initializes the SSPI(NTLM) and then begin exchanging tokens with client
    (e.g., libpq). First the SSPI Credential handle is obtained, then client's
    side tokens are fed to AcceptSecurityContext() and data obtained from
    AcceptSecurityContext() is sent back to client, this keeps on going until
    the authentication is completed. Once the authentication is completed, the
    sspictx handle is disposed after taking token with its reference.
    
    I observed (server logs attached) that in case of client connecting via IP
    address, the NTLM requires only three packets exchange (1st packet from
    client, second from server, and third again from client), but in case of
    connecting via 'localhost' or 'domain name', the NTLM based packets exchange
    goes beyond count of three packets. In this particular case, the sspictx
    does not get updated as the code expects only one complete loop iteration or
    the code expects that NTLM does not change the sspictx, which it does. Now,
    even when NTLM authentication completes successfully, the server fails to
    acquire the token as it asks NTLM for token by supplying an un-updated
    sspictx.
    
    The patch fixes the issue by making sure that sspictx is updated with every
    call to AcceptSecurityContext().
    
    
    
    Regards,
    Ahmed