/*
 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved
 * Use of this product is subject to license terms.
 */

/*
 * Get account status using the account status control.
 */

#include "examples.h"

int
main( int argc, char **argv )
{
    LDAPuserstatus  *status;
    int             version;
    LDAP            *ld;
    int             rc;
    LDAPControl     *status_ctrl = NULL;
    LDAPControl     *requestctrls[ 2 ];
    LDAPMessage     *result;
    char            *matched = NULL;
    char            *errmsg = NULL;
    char            **referrals;
    LDAPControl     **resultctrls = NULL;
    LDAPMessage     *msg;
    LDAPControl     **ectrls = NULL;

    /* Allocate the LDAPuserstatus structure. */
    if ( !( status = (LDAPuserstatus*)malloc(sizeof(LDAPuserstatus)) ) ) {
        perror("malloc");
        return ( 1 );
    }

    /* Use LDAPv3. */
    version = LDAP_VERSION3;
    if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version )
         != 0 ) {
            fprintf( stderr,
                "ldap_set_option protocol version to %d failed\n",
                version );
            return ( 1 );
    }

    /* Get a handle to an LDAP connection. */
    if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) {
        perror( "ldap_init" );
        return( 1 );
    }

    /* Create an account status control. */
    rc = ldap_create_userstatus_control( ld, 1, &status_ctrl);
    if ( rc != LDAP_SUCCESS ) {
        fprintf( stderr, "ldap_create_userstatus_control: %s\n",
                 ldap_err2string( rc ) );
        ldap_unbind( ld );
        return( 1 );
    }
    requestctrls[ 0 ] = status_ctrl;
    requestctrls[ 1 ] = NULL;

    /* Authenticate to the directory as a user. */
    if ( ldap_simple_bind_s( ld, USER_DN, USER_PW ) != LDAP_SUCCESS ) {
        ldap_perror( ld, "ldap_simple_bind_s" );
        return( 1 );
    }

    /* Read the account entry using the control. */
    rc = ldap_search_ext_s( ld, ENTRYDN, LDAP_SCOPE_BASE,
        "(objectclass=*)", NULL, 0, requestctrls, NULL, NULL, 0, &result );
    if ( rc != LDAP_SUCCESS ) {
        fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) );
        ldap_unbind( ld );
        return( 1 );
    }

    /* Show the account status. */
    rc = ldap_parse_result( ld, result, &rc, &matched, &errmsg,
        &referrals, &resultctrls, 0 );
    if ( rc != LDAP_SUCCESS ) {
        fprintf( stderr, "ldap_parse_result: %s\n", ldap_err2string( rc ) );
        ldap_unbind( ld );
        return( 1 );
    }

    for ( msg = ldap_first_message( ld, result );
          msg != NULL;
          msg = ldap_next_message ( ld, msg) ) {
        if ( ldap_msgtype( msg ) != LDAP_RES_SEARCH_ENTRY ) continue;
        if ( ldap_get_entry_controls( ld, msg, &ectrls ) != LDAP_SUCCESS ) {
            ldap_perror ( ld, "ldap_get_entry_controls" );
        } else {
            rc = ldap_parse_userstatus_control( ld, ectrls, status );
            if ( rc != LDAP_SUCCESS ) {
                fprintf( stderr,
                    "ldap_parse_userstatus_control: %s\n",
                    ldap_err2string( rc ) );
            } else {
                printf( "DN: %s\n", ENTRYDN );
                if ( LDAP_US_ACCOUNT_USABLE == status->us_available ) {
                    printf( " Account is usable:\tY\n" );
                } else {
                    printf( " Account is usable:\tN\n" );
                }
                printf( " Password expires in:\t%ld s\n",
                    status->us_expire );
                if ( LDAP_US_ACCOUNT_INACTIVE == status->us_inactive ) {
                    printf( " Account is locked:\tY\n" );
                } else {
                    printf( " Account is locked:\tN\n" );
                }
                if ( LDAP_US_ACCOUNT_RESET == status->us_reset ) {
                    printf( " Password was reset:\tY\n" );
                } else {
                    printf( " Password was reset:\tN\n" );
                }
                if ( LDAP_US_ACCOUNT_EXPIRED == status->us_expired ) {
                    printf( " Password has expired:\tY\n" );
                } else {
                    printf( " Password has expired:\tN\n" );
                }
                printf( " Grace logins left:\t%d\n",
                    status->us_remaining );
                printf( " Account unlocks in:\t%d s\n",
                    status->us_seconds );
            }
        }
    }
    
    ldap_msgfree( result );
    ldap_control_free( status_ctrl );
    ldap_controls_free( resultctrls );
    ldap_unbind( ld );
    return( 0 );
}
