Example #1
0
/*
    4.2.2. Bind Response
    The Bind response is defined as follows.
    BindResponse ::= [APPLICATION 1] SEQUENCE {
    COMPONENTS OF LDAPResult,
    serverSaslCreds [7] OCTET STRING OPTIONAL }
 */
VOID
VmDirSendSASLBindResponse(
    PVDIR_OPERATION     pOperation
    )
{
    DWORD               dwError = 0;
    BerElementBuffer    berbuf;
    BerElement *        ber = (BerElement *) &berbuf;
    PVDIR_LDAP_RESULT   pResult = &(pOperation->ldapResult);
    ber_tag_t           respType = GetResultTag(pOperation->reqCode);

    (void) memset( (char *)&berbuf, '\0', sizeof( BerElementBuffer ));

    ber_init2( ber, NULL, LBER_USE_DER );

    VMDIR_LOG_INFO( LDAP_DEBUG_ARGS, "VmDirSendLdapResponse: code (%d), Error (%d)(%s)",
                    respType, pResult->errCode, VDIR_SAFE_STRING(pResult->pszErrMsg));

    dwError = ber_printf( ber, "{it{ess" /*"}}"*/,
                        pOperation->msgId,                  // message sequence id
                        GetResultTag(pOperation->reqCode),  // ldap response type
                        pResult->errCode,                   // ldap return code e.g. LDAP_SASL_CONNTINUE
                        pResult->matchedDn.lberbv.bv_len > 0 ? pResult->matchedDn.lberbv.bv_val : "",
                        VDIR_SAFE_STRING(pResult->pszErrMsg));   // error text detail
    BAIL_ON_LBER_ERROR(dwError);

    // Send back TAG and SASL reply blob
    // NOTE, not exactly sure if we ever need to send Tag but WITHOUT blob reply if blob is empty.
    //       but this should NOT happen in GSSAPI scenario.
    if ( pResult->replyInfo.type == REP_SASL
         &&
         pResult->replyInfo.replyData.bvSaslReply.lberbv.bv_len > 0
       )
    {
        dwError = ber_printf( ber, "tO",
                              LDAP_TAG_SASL_RES_CREDS,
                              &pResult->replyInfo.replyData.bvSaslReply.lberbv );
        BAIL_ON_LBER_ERROR(dwError);
    }

    dwError = ber_printf( ber, "N}N}" );
    BAIL_ON_LBER_ERROR(dwError);

    dwError = WriteBerOnSocket( pOperation->conn, ber );
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:

    ber_free_buf( ber );

    return;

error:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "lber error (%d)", dwError);
    goto cleanup;
}
Example #2
0
void
VmDirSendLdapReferralResult(
   VDIR_OPERATION * op,
   PCSTR pszRefSuffix,
   PBOOLEAN pbRefSent
   )
{
   DWORD dwError = 0;
   BerElementBuffer berbuf;
   BerElement *     ber = (BerElement *) &berbuf;
   ber_int_t        msgId = 0;
   PCSTR            pszSocketInfo = NULL;
   PSTR             pszLeader = NULL;
   PSTR             pszRef = NULL;
   PVDIR_BERVALUE   pBerv = NULL;
   BOOLEAN          bIsLdaps = FALSE;

   *pbRefSent = FALSE;
   (void) memset( (char *)&berbuf, '\0', sizeof( BerElementBuffer ));

   msgId = op->msgId;

   ber_init2( ber, NULL, LBER_USE_DER );

   if (op->conn)
   {
      pszSocketInfo = op->conn->szClientIP;
   }

   dwError = VmDirRaftGetLeader(&pszLeader);
   BAIL_ON_VMDIR_ERROR(dwError);
   
   if (pszLeader == NULL)
   {
       //server self is a raft leader or leader cannot determined (e.g. in voting stage).
       goto done;
   }

   if (op->conn->dwServerPort == VmDirGetLdapsPort())
   {
       bIsLdaps = TRUE;
   }

   dwError = VmDirAllocateStringPrintf(&pszRef, "%s://%s/%s",
               bIsLdaps ? "ldaps":"ldap",
               pszLeader,
               pszRefSuffix );
   BAIL_ON_VMDIR_ERROR(dwError);

   op->ldapResult.errCode = 0;
   if ((op->reqCode == LDAP_REQ_SEARCH && gVmdirGlobals.dwEnableRaftReferral & VMDIR_RAFT_SEARCH_REFERRAL_ERROR_CODE) ||
       ((op->reqCode == LDAP_REQ_ADD || op->reqCode == LDAP_REQ_DELETE ||
         op->reqCode == LDAP_REQ_MODIFY || op->reqCode == LDAP_REQ_MODDN) &&
         gVmdirGlobals.dwEnableRaftReferral & VMDIR_RAFT_ENABLE_UPDATE_ERROR_CODE))
   {
       op->ldapResult.errCode = LDAP_REFERRAL;
   }

   dwError = VmDirAllocateMemory( sizeof(VDIR_BERVALUE) * 2, (PVOID*)&pBerv);
   BAIL_ON_VMDIR_ERROR(dwError);

   pBerv[0].lberbv_len = VmDirStringLenA(pszRef);
   pBerv[0].lberbv_val = pszRef;
   pBerv[0].bOwnBvVal = TRUE;
   pBerv[1].lberbv_val = NULL;
   pBerv[1].lberbv_len = 0;

   dwError = ber_printf(ber, "{it{W}N}{it{ess}N}", msgId, LDAP_RES_SEARCH_REFERENCE, pBerv,
                        msgId, GetResultTag(op->reqCode), op->ldapResult.errCode, "", "");
   BAIL_ON_LBER_ERROR(dwError);

   dwError = WriteBerOnSocket( op->conn, ber );
   BAIL_ON_VMDIR_ERROR(dwError);

   *pbRefSent = TRUE;

   VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "VmDirSendLdapReferralResult: sent with referral %s", pszRef);

done:
   ber_free_buf( ber );
   VmDirFreeBervalArrayContent(pBerv, 1);
   VMDIR_SAFE_FREE_MEMORY(pBerv);
   VMDIR_SAFE_FREE_MEMORY(pszLeader);
   return;

error:
   goto done;
}