Beispiel #1
0
DWORD
VmDirSASLGSSAPIBind(
     LDAP**     ppLd,
     PCSTR      pszURI
     )
{
    DWORD       dwError = 0;
    int         retVal = 0;
    LDAP*       pLd = NULL;
    const int   ldapVer = LDAP_VERSION3;

    if ( ppLd == NULL || pszURI == NULL )
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    retVal = ldap_initialize( &pLd, pszURI);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    retVal = ldap_set_option(pLd, LDAP_OPT_PROTOCOL_VERSION, &ldapVer);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    retVal = ldap_sasl_interactive_bind_s( pLd,
                                            NULL,
                                            "GSSAPI",
                                            NULL,
                                            NULL,
                                            LDAP_SASL_QUIET,
                                            _VmDirSASLGSSAPIInteraction,
                                            NULL);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    *ppLd = pLd;

cleanup:

    return dwError;

ldaperror:

    VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLGSSBind failed. (%d)(%s)",
                                           retVal, ldap_err2string(retVal) );
    dwError = VmDirMapLdapError(retVal);

error:
    if (retVal == 0)
    {
        VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLGSSBind failed. (%u)", dwError);
    }

    if ( pLd )
    {
        ldap_unbind_ext_s( pLd, NULL, NULL);
    }
    goto cleanup;
}
Beispiel #2
0
int
ParseAndFreeSyncStateControl(
    LDAPControl ***pCtrls,
    int *piEntryState
    )
{
    int retVal = LDAP_SUCCESS;
    int entryState = -1;

    if (pCtrls == NULL)
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "ParseAndFreeSyncStateControl: pCtrls is NULL" );
        retVal = LDAP_OPERATIONS_ERROR;
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);
    }

    if ((*pCtrls)[0] == NULL)
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "ParseAndFreeSyncStateControl: (*pCtrls)[0] is NULL" );
        retVal = LDAP_OPERATIONS_ERROR;
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);
    }

    if (VmDirStringCompareA((*pCtrls)[0]->ldctl_oid, LDAP_CONTROL_SYNC_STATE, TRUE) != 0)
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "ParseAndFreeSyncStateControl: (*pCtrls)[0]->ldctrl_oid is not expected: %s", VDIR_SAFE_STRING((*pCtrls)[0]->ldctl_oid));
        retVal = LDAP_OPERATIONS_ERROR;
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);
    }

    retVal = ParseSyncStateControlVal(&(*pCtrls)[0]->ldctl_value, &entryState);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    ldap_controls_free(*pCtrls);
    *pCtrls = NULL;

    *piEntryState = entryState;

cleanup:
    return retVal;

ldaperror:
    goto cleanup;
}
Beispiel #3
0
int
VmDirPerformBind(
    PVDIR_OPERATION   pOperation
    )
{
   BindReq *    pBindReq = &(pOperation->request.bindReq);
   int          retVal = LDAP_SUCCESS;
   ber_len_t    berLen = 0;
   ber_tag_t    berTag = 0;
   BOOLEAN      bResultAlreadySent = FALSE;

   memset( pBindReq, 0, sizeof( BindReq ));

   if (ber_scanf( pOperation->ber, "{imt", &pOperation->protocol, &(pOperation->reqDn.lberbv), &pBindReq->method ) == LBER_ERROR )
   {
      VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "PerformBind: ber_scanf failed" );

      BAIL_ON_STATIC_LDAP_ERROR( retVal, LDAP_PROTOCOL_ERROR, (pOperation->ldapResult.pszErrMsg),
                                 "Decoding error while parsing protocol version, bind DN, bind method.");
   }

   VMDIR_LOG_VERBOSE( LDAP_DEBUG_ARGS,
       "Bind Request (%s): Protocol version: %d, Bind DN: \"%s\", Method: %ld",
        pOperation->conn->szClientIP,
        pOperation->protocol,
        pOperation->reqDn.lberbv.bv_val, pBindReq->method );

   if (pOperation->protocol != LDAP_VERSION3)
   {
      VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "PerformBind: Non-ldap-v3 version." );
      BAIL_ON_STATIC_LDAP_ERROR(    retVal, LDAP_PROTOCOL_ERROR, (pOperation->ldapResult.pszErrMsg),
                                  "Currently, only LDAP V3 is supported.");
   }

   switch (pBindReq->method)
   {
       case LDAP_AUTH_SIMPLE:
               if ( ber_scanf( pOperation->ber, "m}", &(pBindReq->cred.lberbv) ) == LBER_ERROR )
               {
                   VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "PerformBind: ber_scanf failed" );
                  BAIL_ON_STATIC_LDAP_ERROR( retVal, LDAP_PROTOCOL_ERROR, (pOperation->ldapResult.pszErrMsg),
                                             "Decoding error while parsing simple credentials.");
               }

               break;

       case LDAP_AUTH_SASL:
               if ( ber_scanf( pOperation->ber, "{m" /*}*/, &(pBindReq->bvMechanism.lberbv) ) == LBER_ERROR)
               {
                   BAIL_ON_STATIC_LDAP_ERROR( retVal, LDAP_PROTOCOL_ERROR, (pOperation->ldapResult.pszErrMsg),
                                              "Decoding error while parsing sasl mechanism.");
               }

               berTag = ber_peek_tag( pOperation->ber, &berLen );
               if ( berTag == LDAP_TAG_LDAPCRED ) {
                   if ( ber_scanf( pOperation->ber, "m", &(pBindReq->cred.lberbv)) == LBER_ERROR )
                   {
                       BAIL_ON_STATIC_LDAP_ERROR( retVal, LDAP_PROTOCOL_ERROR,  (pOperation->ldapResult.pszErrMsg),
                                                  "Decoding error while parsing sasl creds.");
                   }
               }

               if ( ber_scanf( pOperation->ber, /*{{*/ "}}" ) == LBER_ERROR )
               {
                   BAIL_ON_STATIC_LDAP_ERROR( retVal, LDAP_PROTOCOL_ERROR, (pOperation->ldapResult.pszErrMsg),
                                              "Decoding error.");
               }

               break;

       default:
           BAIL_ON_STATIC_LDAP_ERROR( retVal, LDAP_UNWILLING_TO_PERFORM,  (pOperation->ldapResult.pszErrMsg),
                                      "bind method not supported.");
   }

    retVal = VmDirMLBind( pOperation );
    bResultAlreadySent = TRUE;
    if (retVal && retVal != LDAP_SASL_BIND_IN_PROGRESS)
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL,
            "Bind Request Failed (%s) error %u: Protocol version: %d, Bind DN: \"%s\", Method: %ld",
            pOperation->conn->szClientIP,
            retVal,
            pOperation->protocol,
            VDIR_SAFE_STRING(pOperation->reqDn.lberbv.bv_val),
            pBindReq->method );
    }
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

cleanup:

    return retVal;

ldaperror:
    pOperation->ldapResult.errCode = retVal;

    if (retVal != LDAP_NOTICE_OF_DISCONNECT && bResultAlreadySent == FALSE)
    {
        VmDirSendLdapResult( pOperation );
    }

    goto cleanup;
}
Beispiel #4
0
int
VmDirCreateSyncRequestControl(
    PCSTR pszInvocationId,
    USN lastLocalUsnProcessed,
    PCSTR pszUtdVector,
    LDAPControl *           syncReqCtrl
    )
{
    int                 retVal = LDAP_SUCCESS;
    BerElement *        ber = NULL;
    PSTR                pszLastLocalUsnProcessed = NULL;

    if (syncReqCtrl == NULL)
    {
        retVal = LDAP_OPERATIONS_ERROR;
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);
    }

    if ((ber = ber_alloc()) == NULL)
    {
        retVal = LDAP_OPERATIONS_ERROR;
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);
    }

    if (VmDirAllocateStringPrintf(&pszLastLocalUsnProcessed, "%lld", lastLocalUsnProcessed))
    {
        retVal = LDAP_OPERATIONS_ERROR;
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);
    }

    if ( ber_printf( ber, "{i{sss}}", LDAP_SYNC_REFRESH_ONLY,
                    pszInvocationId,
                    pszLastLocalUsnProcessed,
                    pszUtdVector ) == -1)
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "VmDirCreateSyncRequestControl: ber_printf failed." );
        retVal = LDAP_OPERATIONS_ERROR;
        BAIL_ON_SIMPLE_LDAP_ERROR( retVal );
    }

    memset( syncReqCtrl, 0, sizeof( LDAPControl ));
    syncReqCtrl->ldctl_oid = LDAP_CONTROL_SYNC;
    syncReqCtrl->ldctl_iscritical = '1';
    if (ber_flatten2(ber, &syncReqCtrl->ldctl_value, 1))
    {
        retVal = LDAP_OPERATIONS_ERROR;
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);
    }

cleanup:
    VMDIR_SAFE_FREE_STRINGA(pszLastLocalUsnProcessed);
    if (ber)
    {
        ber_free(ber, 1);
    }
    return retVal;

ldaperror:
    ber_bvfree(&syncReqCtrl->ldctl_value);
    goto cleanup;
}
Beispiel #5
0
DWORD
VmDirAnonymousLDAPBindWithTimeout(
    LDAP**      ppLd,
    PCSTR       pszLdapURI,
    int         timeout
    )
{
    DWORD       dwError = 0;
    int         retVal = 0;
    const int   ldapVer = LDAP_VERSION3;
    BerValue    ldapBindPwd = {0};
    LDAP*       pLocalLd = NULL;
    struct timeval nettimeout = {0};


    if (ppLd == NULL || pszLdapURI == NULL)
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    retVal = ldap_initialize( &pLocalLd, pszLdapURI);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    retVal = ldap_set_option( pLocalLd, LDAP_OPT_PROTOCOL_VERSION, &ldapVer);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    if (timeout > 0)
    {
        nettimeout.tv_sec = timeout;

        // timeout connect
        retVal = ldap_set_option(pLocalLd, LDAP_OPT_NETWORK_TIMEOUT, (void *)&nettimeout);
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);
    }

    ldapBindPwd.bv_val = NULL;
    ldapBindPwd.bv_len = 0;

    retVal = ldap_sasl_bind_s(
                               pLocalLd,
                               "",
                               LDAP_SASL_SIMPLE,
                               &ldapBindPwd,  // no credentials
                               NULL,
                               NULL,
                               NULL);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    *ppLd = pLocalLd;

cleanup:

    return dwError;

ldaperror:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirAnonymousLDAPBind to (%s) failed. (%d)(%s)",
                     VDIR_SAFE_STRING(pszLdapURI), retVal, ldap_err2string(retVal) );
    dwError = VmDirMapLdapError(retVal);

error:
    if (retVal == 0)
    {
        VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "VmDirAnonymousLDAPBind to (%s) failed. (%u)", VDIR_SAFE_STRING(pszLdapURI), dwError);
    }

    if (pLocalLd)
    {
        ldap_unbind_ext_s( pLocalLd, NULL, NULL);
    }

    goto cleanup;
}
Beispiel #6
0
/*
 * Bind to a LDAP server via SSL port.
 * Require server certificate verification.
 *
 * In 5.5. mix mode, replication goes through ldaps port.
 */
DWORD
VmDirSSLBind(
     LDAP**     ppLd,
     PCSTR      pszURI,
     PCSTR      pszDN,
     PCSTR      pszPassword
     )
{
    DWORD     dwError = 0;
    int       retVal = 0;
    LDAP*     pLd = NULL;
    BerValue  ldapBindPwd = {0};
    const int ldapVer = LDAP_VERSION3;
    int       iTLSDEMAND = LDAP_OPT_X_TLS_DEMAND;
    int       iTLSMin =  LDAP_OPT_X_TLS_PROTOCOL_TLS1_0;
    PSTR      pszTrustCertFile = NULL;
    SSL_CTX*  pSslCtx = NULL;

    if ( ppLd == NULL || pszURI == NULL )
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // only allow ldaps traffic over SSL port
    if ( VmDirStringNCompareA( pszURI, VMDIR_LDAPS_PROTOCOL, 5, FALSE) != 0 )
    {
        dwError = VMDIR_ERROR_ACCESS_DENIED;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirPrepareOpensslClientCtx( &pSslCtx, &pszTrustCertFile, pszURI );
    BAIL_ON_VMDIR_ERROR(dwError);

    retVal = ldap_set_option( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &iTLSDEMAND);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    retVal = ldap_set_option(NULL, LDAP_OPT_X_TLS_PROTOCOL_MIN, &iTLSMin);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    retVal = ldap_initialize(&pLd, pszURI);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    retVal = ldap_set_option(pLd, LDAP_OPT_PROTOCOL_VERSION, &ldapVer);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    retVal = ldap_set_option( pLd, LDAP_OPT_X_TLS_CTX, pSslCtx);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    ldapBindPwd.bv_val = 0;
    ldapBindPwd.bv_len = 0;
    if (pszPassword)
    {
        ldapBindPwd.bv_val = (PSTR) pszPassword;
        ldapBindPwd.bv_len = (ULONG) VmDirStringLenA(pszPassword);
    }
    retVal = ldap_sasl_bind_s( pLd,
                                pszDN,
                                LDAP_SASL_SIMPLE,
                                &ldapBindPwd,      // ldaps with credentials
                                NULL,
                                NULL,
                                NULL);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    *ppLd = pLd;

cleanup:

    if (pSslCtx)
    {
        SSL_CTX_free(pSslCtx);
    }
    VMDIR_SAFE_FREE_MEMORY(pszTrustCertFile);

    return dwError;

ldaperror:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirSSLBind failed for %s %s. (%d)(%s)",
                                         pszURI, pszDN,
                                         retVal, ldap_err2string(retVal));
    dwError = VmDirMapLdapError(retVal);

error:
    if (retVal == 0)
    {
        VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSSLBind failed. (%u)", dwError);
    }

    if ( pLd )
    {
        ldap_unbind_ext_s( pLd, NULL, NULL);
    }
    goto cleanup;
}
Beispiel #7
0
DWORD
VmDirSASLSRPBindExt1(
     LDAP**     ppLd,
     PCSTR      pszURI,
     PCSTR      pszUPN,
     PCSTR      pszPass,
     int        iTimeout
     )
{
    DWORD       dwError = 0;
    int         retVal = 0;
    PSTR        pszLowerCaseUPN = NULL;
    LDAP*       pLd = NULL;
    const int   ldapVer = LDAP_VERSION3;
    const int   iSaslNoCanon = 1;
    VMDIR_SASL_INTERACTIVE_DEFAULT srpDefault = {0};
    int         iCnt = 0;
    struct timeval  optTimeout={0};

    optTimeout.tv_usec = 0;
    optTimeout.tv_sec = iTimeout;

    if ( ppLd == NULL || pszURI == NULL || pszUPN == NULL || pszPass == NULL )
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirAllocASCIIUpperToLower( pszUPN, &pszLowerCaseUPN );
    BAIL_ON_VMDIR_ERROR(dwError);

    srpDefault.pszAuthName = pszLowerCaseUPN;
    srpDefault.pszPass     = pszPass;

    for (iCnt=0; iCnt<2; iCnt++)
    {
        retVal = ldap_initialize( &pLd, pszURI);
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

        retVal = ldap_set_option(pLd, LDAP_OPT_PROTOCOL_VERSION, &ldapVer);
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

        // turn off SASL hostname canonicalization for SRP mech
        retVal = ldap_set_option(pLd, LDAP_OPT_X_SASL_NOCANON, &iSaslNoCanon);
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

        if (iTimeout > 0)
        {
            // timeout connect
            retVal = ldap_set_option(pLd, LDAP_OPT_NETWORK_TIMEOUT, (void *)&optTimeout);
            BAIL_ON_SIMPLE_LDAP_ERROR(retVal);
        }

        retVal = ldap_sasl_interactive_bind_s( pLd,
                                                NULL,
                                                "SRP",
                                                NULL,
                                                NULL,
                                                LDAP_SASL_QUIET,
                                                _VmDirSASLSRPInteraction,
                                                &srpDefault);
        if (retVal == LDAP_SERVER_DOWN || retVal == LDAP_TIMEOUT)
        {
            VmDirSleep(50); // pause 50 ms
            if ( pLd )
            {
                ldap_unbind_ext_s(pLd, NULL, NULL);
                pLd = NULL;
            }
            continue;   // if transient network error, retry once.
        }
        else
        {
            break;
        }
    }
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);  // bail ldap_sasl_interactive_bind_s failure.

    *ppLd = pLd;

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pszLowerCaseUPN);

    return dwError;

ldaperror:

    VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLSRPBind failed. (%d)(%s)",
                                           retVal, ldap_err2string(retVal) );
    dwError = VmDirMapLdapError(retVal);

error:
    if (retVal == 0)
    {
        VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLSRPBind failed. (%u)", dwError);
    }

    if ( pLd )
    {
        ldap_unbind_ext_s( pLd, NULL, NULL);
    }
    goto cleanup;
}
Beispiel #8
0
DWORD
VmDirSASLSRPBind(
     LDAP**     ppLd,
     PCSTR      pszURI,
     PCSTR      pszUPN,
     PCSTR      pszPass
     )
{
    DWORD       dwError = 0;
    int         retVal = 0;
    PSTR        pszLowerCaseUPN = NULL;
    LDAP*       pLd = NULL;
    const int   ldapVer = LDAP_VERSION3;
    VMDIR_SASL_INTERACTIVE_DEFAULT srpDefault = {0};
    int         iCnt = 0;

    if ( ppLd == NULL || pszURI == NULL || pszUPN == NULL || pszPass == NULL )
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirAllocASCIIUpperToLower( pszUPN, &pszLowerCaseUPN );
    BAIL_ON_VMDIR_ERROR(dwError);

    srpDefault.pszAuthName = pszLowerCaseUPN;
    srpDefault.pszPass     = pszPass;

    for (iCnt=0; iCnt<2; iCnt++)
    {
        retVal = ldap_initialize( &pLd, pszURI);
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

        retVal = ldap_set_option(pLd, LDAP_OPT_PROTOCOL_VERSION, &ldapVer);
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

        retVal = ldap_sasl_interactive_bind_s( pLd,
                                                NULL,
                                                "SRP",
                                                NULL,
                                                NULL,
                                                LDAP_SASL_QUIET,
                                                _VmDirSASLSRPInteraction,
                                                &srpDefault);
        if (retVal == LDAP_SERVER_DOWN)
        {
            VmDirSleep(50); // pause 50 ms
            if ( pLd )
            {
                ldap_unbind_ext_s(pLd, NULL, NULL);
                pLd = NULL;
            }
            continue;   // if transient network error, retry once.
        }
        else
        {
            break;
        }
    }
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);  // bail ldap_sasl_interactive_bind_s failure.

    *ppLd = pLd;

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pszLowerCaseUPN);

    return dwError;

ldaperror:

    VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLSRPBind failed. (%d)(%s)",
                                           retVal, ldap_err2string(retVal) );
    dwError = VmDirMapLdapError(retVal);

error:
    if (retVal == 0)
    {
        VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLSRPBind failed. (%u)", dwError);
    }

    if ( pLd )
    {
        ldap_unbind_ext_s( pLd, NULL, NULL);
    }
    goto cleanup;
}