DWORD VMCAGetDSERootAttribute( PVMCA_LDAP_CONTEXT pContext, PSTR pszAttribute, PSTR* ppszAttrValue ) { DWORD dwError = 0; // LDAP_SUCCESS PSTR pAttribute = NULL; BerValue** ppValue = NULL; BerElement* pBer = NULL; LDAPMessage* pSearchResult = NULL; LDAPMessage* pResults = NULL; PCHAR pszFilter = "(objectClass=*)"; PCHAR ppszAttrs[] = { pszAttribute, NULL }; dwError = ldap_search_ext_s( pContext->pConnection, // Session handle "", // DN to start search LDAP_SCOPE_BASE, // Scope pszFilter, // Filter ppszAttrs, // Retrieve list of attributes 0, // Get both attributes and values NULL, NULL, NULL, 0, &pSearchResult); // [out] Search results BAIL_ON_ERROR(dwError); if (ldap_count_entries(pContext->pConnection, pSearchResult) != 1) { dwError = ERROR_INVALID_STATE; BAIL_ON_ERROR(dwError); } // There should be only one result for this type pResults = ldap_first_entry(pContext->pConnection, pSearchResult); if (pResults == NULL) { ldap_get_option(pContext->pConnection, LDAP_OPT_ERROR_NUMBER, &dwError); BAIL_ON_ERROR(dwError); } pAttribute = ldap_first_attribute(pContext->pConnection,pResults,&pBer); if(pAttribute == NULL) { ldap_get_option(pContext->pConnection, LDAP_OPT_ERROR_NUMBER, &dwError); BAIL_ON_ERROR(dwError); } ppValue = ldap_get_values_len(pContext->pConnection, pResults, pszAttribute); if(ppValue == NULL) { ldap_get_option(pContext->pConnection, LDAP_OPT_ERROR_NUMBER, &dwError); BAIL_ON_ERROR(dwError); } dwError = VMCAAllocateStringA(ppValue[0]->bv_val, ppszAttrValue); BAIL_ON_ERROR(dwError); error : if ( ppValue != NULL) { ldap_value_free_len(ppValue); } if(pAttribute != NULL) { ldap_memfree(pAttribute); } if(pBer != NULL) { ber_free(pBer,0); } if(pSearchResult != NULL) { ldap_msgfree(pSearchResult); } return dwError; }
NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, LDAPMessage ** result, const char *domain_name, bool try_add) { NTSTATUS status = NT_STATUS_UNSUCCESSFUL; char *filter = NULL; int rc; const char **attr_list; int count; char *escape_domain_name; escape_domain_name = escape_ldap_string(talloc_tos(), domain_name); if (!escape_domain_name) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; } if (asprintf(&filter, "(&(objectClass=%s)(%s=%s))", LDAP_OBJ_DOMINFO, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), escape_domain_name) < 0) { TALLOC_FREE(escape_domain_name); return NT_STATUS_NO_MEMORY; } TALLOC_FREE(escape_domain_name); DEBUG(2, ("smbldap_search_domain_info: Searching for:[%s]\n", filter)); attr_list = get_attr_list( NULL, dominfo_attr_list ); rc = smbldap_search_suffix(ldap_state, filter, attr_list , result); TALLOC_FREE( attr_list ); if (rc != LDAP_SUCCESS) { DEBUG(2,("smbldap_search_domain_info: Problem during LDAPsearch: %s\n", ldap_err2string (rc))); DEBUG(2,("smbldap_search_domain_info: Query was: %s, %s\n", lp_ldap_suffix(talloc_tos()), filter)); goto failed; } SAFE_FREE(filter); count = ldap_count_entries(ldap_state->ldap_struct, *result); if (count == 1) { return NT_STATUS_OK; } ldap_msgfree(*result); *result = NULL; if (count < 1) { DEBUG(3, ("smbldap_search_domain_info: Got no domain info entries for domain\n")); if (!try_add) goto failed; status = add_new_domain_info(ldap_state, domain_name); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("smbldap_search_domain_info: Adding domain info for %s failed with %s\n", domain_name, nt_errstr(status))); goto failed; } status = add_new_domain_account_policies(ldap_state, domain_name); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("smbldap_search_domain_info: Adding domain account policies for %s failed with %s\n", domain_name, nt_errstr(status))); goto failed; } return smbldap_search_domain_info(ldap_state, result, domain_name, False); } if (count > 1 ) { DEBUG(0, ("smbldap_search_domain_info: Got too many (%d) domain info entries for domain %s\n", count, domain_name)); goto failed; } failed: return status; }
/* * Parse LDAPResult Messages: * * LDAPResult ::= SEQUENCE { * resultCode ENUMERATED, * matchedDN LDAPDN, * errorMessage LDAPString, * referral [3] Referral OPTIONAL } * * including Bind results: * * BindResponse ::= [APPLICATION 1] SEQUENCE { * COMPONENTS OF LDAPResult, * serverSaslCreds [7] OCTET STRING OPTIONAL } * * and ExtendedOp results: * * ExtendedResponse ::= [APPLICATION 24] SEQUENCE { * COMPONENTS OF LDAPResult, * responseName [10] LDAPOID OPTIONAL, * response [11] OCTET STRING OPTIONAL } * */ int ldap_parse_result( LDAP *ld, LDAPMessage *r, int *errcodep, char **matcheddnp, char **errmsgp, char ***referralsp, LDAPControl ***serverctrls, int freeit ) { LDAPMessage *lm; ber_int_t errcode = LDAP_SUCCESS; ber_tag_t tag; BerElement *ber; Debug( LDAP_DEBUG_TRACE, "ldap_parse_result\n", 0, 0, 0 ); assert( ld != NULL ); assert( LDAP_VALID( ld ) ); assert( r != NULL ); if(errcodep != NULL) *errcodep = LDAP_SUCCESS; if(matcheddnp != NULL) *matcheddnp = NULL; if(errmsgp != NULL) *errmsgp = NULL; if(referralsp != NULL) *referralsp = NULL; if(serverctrls != NULL) *serverctrls = NULL; LDAP_MUTEX_LOCK( &ld->ld_res_mutex ); /* Find the result, last msg in chain... */ lm = r->lm_chain_tail; /* FIXME: either this is not possible (assert?) * or it should be handled */ if ( lm != NULL ) { switch ( lm->lm_msgtype ) { case LDAP_RES_SEARCH_ENTRY: case LDAP_RES_SEARCH_REFERENCE: case LDAP_RES_INTERMEDIATE: lm = NULL; break; default: break; } } if( lm == NULL ) { errcode = ld->ld_errno = LDAP_NO_RESULTS_RETURNED; LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex ); goto done; } if ( ld->ld_error ) { LDAP_FREE( ld->ld_error ); ld->ld_error = NULL; } if ( ld->ld_matched ) { LDAP_FREE( ld->ld_matched ); ld->ld_matched = NULL; } if ( ld->ld_referrals ) { LDAP_VFREE( ld->ld_referrals ); ld->ld_referrals = NULL; } /* parse results */ ber = ber_dup( lm->lm_ber ); if ( ld->ld_version < LDAP_VERSION2 ) { tag = ber_scanf( ber, "{iA}", &ld->ld_errno, &ld->ld_error ); } else { ber_len_t len; tag = ber_scanf( ber, "{iAA" /*}*/, &ld->ld_errno, &ld->ld_matched, &ld->ld_error ); if( tag != LBER_ERROR ) { /* peek for referrals */ if( ber_peek_tag(ber, &len) == LDAP_TAG_REFERRAL ) { tag = ber_scanf( ber, "v", &ld->ld_referrals ); } } /* need to clean out misc items */ if( tag != LBER_ERROR ) { if( lm->lm_msgtype == LDAP_RES_BIND ) { /* look for sasl result creditials */ if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SASL_RES_CREDS ) { /* skip 'em */ tag = ber_scanf( ber, "x" ); } } else if( lm->lm_msgtype == LDAP_RES_EXTENDED ) { /* look for exop result oid or value */ if ( ber_peek_tag( ber, &len ) == LDAP_TAG_EXOP_RES_OID ) { /* skip 'em */ tag = ber_scanf( ber, "x" ); } if ( tag != LBER_ERROR && ber_peek_tag( ber, &len ) == LDAP_TAG_EXOP_RES_VALUE ) { /* skip 'em */ tag = ber_scanf( ber, "x" ); } } } if( tag != LBER_ERROR ) { int rc = ldap_pvt_get_controls( ber, serverctrls ); if( rc != LDAP_SUCCESS ) { tag = LBER_ERROR; } } if( tag != LBER_ERROR ) { tag = ber_scanf( ber, /*{*/"}" ); } } if ( tag == LBER_ERROR ) { ld->ld_errno = errcode = LDAP_DECODING_ERROR; } if( ber != NULL ) { ber_free( ber, 0 ); } /* return */ if( errcodep != NULL ) { *errcodep = ld->ld_errno; } if ( errcode == LDAP_SUCCESS ) { if( matcheddnp != NULL ) { if ( ld->ld_matched ) { *matcheddnp = LDAP_STRDUP( ld->ld_matched ); } } if( errmsgp != NULL ) { if ( ld->ld_error ) { *errmsgp = LDAP_STRDUP( ld->ld_error ); } } if( referralsp != NULL) { *referralsp = ldap_value_dup( ld->ld_referrals ); } } LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex ); done: if ( freeit ) { ldap_msgfree( r ); } return errcode; }
static DWORD VMCACheckAttribute( PVMCA_LDAP_CONTEXT pContext, PCSTR pszObjectDN, PCSTR pszAttribute, PCSTR pszValue, ATTR_SEARCH_RESULT* pAttrStatus ) { DWORD dwError = 0; PCHAR pszFilter = "(objectClass=*)"; PSTR pszRetrievedValue = NULL; DWORD dwNumEntries = 0; LDAPMessage* pSearchResult = NULL; PCHAR ppszAttr[] = { (PSTR)pszAttribute, NULL }; dwError = ldap_search_ext_s( pContext->pConnection, (PSTR)pszObjectDN, LDAP_SCOPE_BASE, pszFilter, ppszAttr, /* attributes */ FALSE, NULL, /* server controls */ NULL, /* client controls */ NULL, /* timeout */ 0, &pSearchResult); BAIL_ON_ERROR(dwError); dwNumEntries = ldap_count_entries(pContext->pConnection, pSearchResult); if (dwNumEntries == 0) { // Caller should make sure that the ObjectDN passed in does exist // by calling DirCliLdapCheckCAObject first. dwError = ERROR_INVALID_PARAMETER; BAIL_ON_ERROR(dwError); } else if (dwNumEntries != 1) { dwError = ERROR_INVALID_STATE; BAIL_ON_ERROR(dwError); } dwError = VMCACopyQueryResultAttributeString(pContext, pSearchResult, pszAttribute, TRUE, &pszRetrievedValue); BAIL_ON_ERROR(dwError); if (!pszRetrievedValue) { *pAttrStatus = ATTR_NOT_FOUND; } else if (VMCAStringCompareA(pszValue, pszRetrievedValue, FALSE)) { *pAttrStatus = ATTR_DIFFER; } else { *pAttrStatus = ATTR_MATCH; } cleanup: if (pSearchResult) { ldap_msgfree(pSearchResult); } VMCA_SAFE_FREE_STRINGA(pszRetrievedValue); return dwError; error : *pAttrStatus = ATTR_NOT_FOUND; if (dwError == LDAP_NO_SUCH_OBJECT) { dwError = 0; } goto cleanup; }
DWORD VmAfdQueryCACerts( LDAP* pLotus, PCSTR pszCACN, BOOL bDetail, PVMAFD_CA_CERT_ARRAY* ppCACertificates ) { DWORD dwError = 0; PSTR pszClassFilter = "(objectClass=vmwCertificationAuthority)"; PSTR pszAttrEntryDN = "entryDN"; PSTR pszAttrCADN = "cACertificateDN"; PSTR pszAttrCert = "cACertificate"; PSTR pszAttrCrl = "certificateRevocationList"; PSTR pszFilter = NULL; PSTR pszComboFilter = NULL; PSTR pszSearchBaseDN= NULL; PSTR pszDomainName = NULL; LDAPMessage* pSearchResult = NULL; LDAPMessage* pCAResult = NULL; PVMAFD_CA_CERT_ARRAY pCertArray = NULL; PCHAR attrs[] = { pszAttrEntryDN, pszAttrCADN, pszAttrCert, pszAttrCrl, NULL}; struct berval** ppValues = NULL; int nCertCount = 0; int certIndex = 0; dwError = VmAfdAllocateMemory( sizeof(VMAFD_CA_CERT_ARRAY), (PVOID*)&pCertArray); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdGetDefaultDomainName( pLotus, &pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringPrintf( &pszSearchBaseDN, "cn=Configuration,%s", pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); if (pszCACN) { dwError = VmAfdAllocateStringPrintf( &pszComboFilter, "(&(CN=%s)%s)", pszCACN, pszClassFilter); BAIL_ON_VMAFD_ERROR(dwError); pszFilter = pszComboFilter; } else { pszFilter = pszClassFilter; } dwError = ldap_search_ext_s( pLotus, pszSearchBaseDN, LDAP_SCOPE_SUBTREE, pszFilter, attrs, 0, /* get values and attrs */ NULL, NULL, NULL, 0, &pSearchResult); BAIL_ON_VMAFD_ERROR(dwError); nCertCount = ldap_count_entries(pLotus, pSearchResult); if (nCertCount > 0) { pCertArray->dwCount = nCertCount; dwError = VmAfdAllocateMemory( sizeof(VMAFD_CA_CERT) * nCertCount, (PVOID*)&pCertArray->pCACerts); BAIL_ON_VMAFD_ERROR(dwError); for ( pCAResult = ldap_first_entry(pLotus, pSearchResult); pCAResult != NULL; pCAResult = ldap_next_entry(pLotus, pCAResult), ++certIndex) { // The following assumes there's only one certificate for each CA // object. In the future if the whole chain is store, we will // update accordingly. // Copy CN dwError = VmAfdCopyQueryResultAttributeString( pLotus, pCAResult, pszAttrEntryDN, FALSE, (PSTR*)&pCertArray->pCACerts[certIndex].pCN); BAIL_ON_VMAFD_ERROR(dwError); // Copy subject DN dwError = VmAfdCopyQueryResultAttributeString( pLotus, pCAResult, pszAttrCADN, FALSE, (PSTR*)&pCertArray->pCACerts[certIndex].pSubjectDN); BAIL_ON_VMAFD_ERROR(dwError); if (bDetail) { // Copy certificate dwError = VmAfdCopyQueryResultAttributeString( pLotus, pCAResult, pszAttrCert, FALSE, (PSTR*)&pCertArray->pCACerts[certIndex].pCert); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdCopyQueryResultAttributeString( pLotus, pCAResult, pszAttrCrl, TRUE, (PSTR*)&pCertArray->pCACerts[certIndex].pCrl); BAIL_ON_VMAFD_ERROR(dwError); } } } *ppCACertificates = pCertArray; cleanup: VMAFD_SAFE_FREE_MEMORY(pszSearchBaseDN); VMAFD_SAFE_FREE_MEMORY(pszDomainName); VMAFD_SAFE_FREE_MEMORY(pszComboFilter); if (ppValues != NULL) { ldap_value_free_len(ppValues); ppValues = NULL; } if(pSearchResult != NULL) { ldap_msgfree(pSearchResult); } return dwError; error: if (pCertArray ) { VecsFreeCACertArray(pCertArray); } if (ppCACertificates) { *ppCACertificates = NULL; } goto cleanup; }
int ldap_back_search( Operation *op, SlapReply *rs ) { ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; ldapconn_t *lc = NULL; struct timeval tv; time_t stoptime = (time_t)(-1); LDAPMessage *res, *e; int rc = 0, msgid; struct berval match = BER_BVNULL, filter = BER_BVNULL; int i, x; char **attrs = NULL; int freetext = 0, filter_undef = 0; int do_retry = 1, dont_retry = 0; LDAPControl **ctrls = NULL; char **references = NULL; rs_assert_ready( rs ); rs->sr_flags &= ~REP_ENTRY_MASK; /* paranoia, we can set rs = non-entry */ if ( !ldap_back_dobind( &lc, op, rs, LDAP_BACK_SENDERR ) ) { return rs->sr_err; } /* * FIXME: in case of values return filter, we might want * to map attrs and maybe rewrite value */ if ( op->ors_tlimit != SLAP_NO_LIMIT ) { tv.tv_sec = op->ors_tlimit; tv.tv_usec = 0; stoptime = op->o_time + op->ors_tlimit; } else { LDAP_BACK_TV_SET( &tv ); } i = 0; if ( op->ors_attrs ) { for ( ; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++ ) /* just count attrs */ ; } x = 0; if ( op->o_bd->be_extra_anlist ) { for ( ; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ ) /* just count attrs */ ; } if ( i > 0 || x > 0 ) { int j = 0; attrs = op->o_tmpalloc( ( i + x + 1 )*sizeof( char * ), op->o_tmpmemctx ); if ( attrs == NULL ) { rs->sr_err = LDAP_NO_MEMORY; rc = -1; goto finish; } if ( i > 0 ) { for ( i = 0; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++, j++ ) { attrs[ j ] = op->ors_attrs[i].an_name.bv_val; } } if ( x > 0 ) { for ( x = 0; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++, j++ ) { if ( op->o_bd->be_extra_anlist[x].an_desc && ad_inlist( op->o_bd->be_extra_anlist[x].an_desc, op->ors_attrs ) ) { continue; } attrs[ j ] = op->o_bd->be_extra_anlist[x].an_name.bv_val; } } attrs[ j ] = NULL; } ctrls = op->o_ctrls; rc = ldap_back_controls_add( op, rs, lc, &ctrls ); if ( rc != LDAP_SUCCESS ) { goto finish; } /* deal with <draft-zeilenga-ldap-t-f> filters */ filter = op->ors_filterstr; retry: /* this goes after retry because ldap_back_munge_filter() * optionally replaces RFC 4526 T-F filters (&) (|) * if already computed, they will be re-installed * by filter2bv_undef_x() later */ if ( !LDAP_BACK_T_F( li ) ) { ldap_back_munge_filter( op, &filter ); } rs->sr_err = ldap_pvt_search( lc->lc_ld, op->o_req_dn.bv_val, op->ors_scope, filter.bv_val, attrs, op->ors_attrsonly, ctrls, NULL, tv.tv_sec ? &tv : NULL, op->ors_slimit, op->ors_deref, &msgid ); ldap_pvt_thread_mutex_lock( &li->li_counter_mutex ); ldap_pvt_mp_add( li->li_ops_completed[ SLAP_OP_SEARCH ], 1 ); ldap_pvt_thread_mutex_unlock( &li->li_counter_mutex ); if ( rs->sr_err != LDAP_SUCCESS ) { switch ( rs->sr_err ) { case LDAP_SERVER_DOWN: if ( do_retry ) { do_retry = 0; if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_DONTSEND ) ) { goto retry; } } if ( lc == NULL ) { /* reset by ldap_back_retry ... */ rs->sr_err = slap_map_api2result( rs ); } else { rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_DONTSEND ); } goto finish; case LDAP_FILTER_ERROR: /* first try? */ if ( !filter_undef && strstr( filter.bv_val, "(?" ) && !LDAP_BACK_NOUNDEFFILTER( li ) ) { BER_BVZERO( &filter ); filter2bv_undef_x( op, op->ors_filter, 1, &filter ); filter_undef = 1; goto retry; } /* invalid filters return success with no data */ rs->sr_err = LDAP_SUCCESS; rs->sr_text = NULL; goto finish; default: rs->sr_err = slap_map_api2result( rs ); rs->sr_text = NULL; goto finish; } } /* if needed, initialize timeout */ if ( li->li_timeout[ SLAP_OP_SEARCH ] ) { if ( tv.tv_sec == 0 || tv.tv_sec > li->li_timeout[ SLAP_OP_SEARCH ] ) { tv.tv_sec = li->li_timeout[ SLAP_OP_SEARCH ]; tv.tv_usec = 0; } } /* We pull apart the ber result, stuff it into a slapd entry, and * let send_search_entry stuff it back into ber format. Slow & ugly, * but this is necessary for version matching, and for ACL processing. */ for ( rc = -2; rc != -1; rc = ldap_result( lc->lc_ld, msgid, LDAP_MSG_ONE, &tv, &res ) ) { /* check for abandon */ if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( lc ) ) { if ( rc > 0 ) { ldap_msgfree( res ); } (void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND ); rc = SLAPD_ABANDON; goto finish; } if ( rc == 0 || rc == -2 ) { ldap_pvt_thread_yield(); /* check timeout */ if ( li->li_timeout[ SLAP_OP_SEARCH ] ) { if ( rc == 0 ) { (void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND ); rs->sr_text = "Operation timed out"; rc = rs->sr_err = op->o_protocol >= LDAP_VERSION3 ? LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER; goto finish; } } else { LDAP_BACK_TV_SET( &tv ); } /* check time limit */ if ( op->ors_tlimit != SLAP_NO_LIMIT && slap_get_time() > stoptime ) { (void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND ); rc = rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; goto finish; } continue; } else { /* only touch when activity actually took place... */ if ( li->li_idle_timeout ) { lc->lc_time = op->o_time; } /* don't retry any more */ dont_retry = 1; } if ( rc == LDAP_RES_SEARCH_ENTRY ) { Entry ent = { 0 }; struct berval bdn = BER_BVNULL; do_retry = 0; e = ldap_first_entry( lc->lc_ld, res ); rc = ldap_build_entry( op, e, &ent, &bdn ); if ( rc == LDAP_SUCCESS ) { ldap_get_entry_controls( lc->lc_ld, res, &rs->sr_ctrls ); rs->sr_entry = &ent; rs->sr_attrs = op->ors_attrs; rs->sr_operational_attrs = NULL; rs->sr_flags = 0; rs->sr_err = LDAP_SUCCESS; rc = rs->sr_err = send_search_entry( op, rs ); if ( rs->sr_ctrls ) { ldap_controls_free( rs->sr_ctrls ); rs->sr_ctrls = NULL; } rs->sr_entry = NULL; rs->sr_flags = 0; if ( !BER_BVISNULL( &ent.e_name ) ) { assert( ent.e_name.bv_val != bdn.bv_val ); op->o_tmpfree( ent.e_name.bv_val, op->o_tmpmemctx ); BER_BVZERO( &ent.e_name ); } if ( !BER_BVISNULL( &ent.e_nname ) ) { op->o_tmpfree( ent.e_nname.bv_val, op->o_tmpmemctx ); BER_BVZERO( &ent.e_nname ); } entry_clean( &ent ); } ldap_msgfree( res ); switch ( rc ) { case LDAP_SUCCESS: case LDAP_INSUFFICIENT_ACCESS: break; default: if ( rc == LDAP_UNAVAILABLE ) { rc = rs->sr_err = LDAP_OTHER; } else { (void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND ); } goto finish; } } else if ( rc == LDAP_RES_SEARCH_REFERENCE ) { if ( LDAP_BACK_NOREFS( li ) ) { ldap_msgfree( res ); continue; } do_retry = 0; rc = ldap_parse_reference( lc->lc_ld, res, &references, &rs->sr_ctrls, 1 ); if ( rc != LDAP_SUCCESS ) { continue; } /* FIXME: there MUST be at least one */ if ( references && references[ 0 ] && references[ 0 ][ 0 ] ) { int cnt; for ( cnt = 0; references[ cnt ]; cnt++ ) /* NO OP */ ; /* FIXME: there MUST be at least one */ rs->sr_ref = op->o_tmpalloc( ( cnt + 1 ) * sizeof( struct berval ), op->o_tmpmemctx ); for ( cnt = 0; references[ cnt ]; cnt++ ) { ber_str2bv( references[ cnt ], 0, 0, &rs->sr_ref[ cnt ] ); } BER_BVZERO( &rs->sr_ref[ cnt ] ); /* ignore return value by now */ RS_ASSERT( !(rs->sr_flags & REP_ENTRY_MASK) ); rs->sr_entry = NULL; ( void )send_search_reference( op, rs ); } else { Debug( LDAP_DEBUG_ANY, "%s ldap_back_search: " "got SEARCH_REFERENCE " "with no referrals\n", op->o_log_prefix, 0, 0 ); } /* cleanup */ if ( references ) { ber_memvfree( (void **)references ); op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx ); rs->sr_ref = NULL; references = NULL; } if ( rs->sr_ctrls ) { ldap_controls_free( rs->sr_ctrls ); rs->sr_ctrls = NULL; } } else if ( rc == LDAP_RES_INTERMEDIATE ) { /* FIXME: response controls * are passed without checks */ rc = ldap_parse_intermediate( lc->lc_ld, res, (char **)&rs->sr_rspoid, &rs->sr_rspdata, &rs->sr_ctrls, 0 ); if ( rc != LDAP_SUCCESS ) { continue; } slap_send_ldap_intermediate( op, rs ); if ( rs->sr_rspoid != NULL ) { ber_memfree( (char *)rs->sr_rspoid ); rs->sr_rspoid = NULL; } if ( rs->sr_rspdata != NULL ) { ber_bvfree( rs->sr_rspdata ); rs->sr_rspdata = NULL; } if ( rs->sr_ctrls != NULL ) { ldap_controls_free( rs->sr_ctrls ); rs->sr_ctrls = NULL; } } else { char *err = NULL; rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err, &match.bv_val, &err, &references, &rs->sr_ctrls, 1 ); if ( rc == LDAP_SUCCESS ) { if ( err ) { rs->sr_text = err; freetext = 1; } } else { rs->sr_err = rc; } rs->sr_err = slap_map_api2result( rs ); /* RFC 4511: referrals can only appear * if result code is LDAP_REFERRAL */ if ( references && references[ 0 ] && references[ 0 ][ 0 ] ) { if ( rs->sr_err != LDAP_REFERRAL ) { Debug( LDAP_DEBUG_ANY, "%s ldap_back_search: " "got referrals with err=%d\n", op->o_log_prefix, rs->sr_err, 0 ); } else { int cnt; for ( cnt = 0; references[ cnt ]; cnt++ ) /* NO OP */ ; rs->sr_ref = op->o_tmpalloc( ( cnt + 1 ) * sizeof( struct berval ), op->o_tmpmemctx ); for ( cnt = 0; references[ cnt ]; cnt++ ) { /* duplicating ...*/ ber_str2bv( references[ cnt ], 0, 0, &rs->sr_ref[ cnt ] ); } BER_BVZERO( &rs->sr_ref[ cnt ] ); } } else if ( rs->sr_err == LDAP_REFERRAL ) { Debug( LDAP_DEBUG_ANY, "%s ldap_back_search: " "got err=%d with null " "or empty referrals\n", op->o_log_prefix, rs->sr_err, 0 ); rs->sr_err = LDAP_NO_SUCH_OBJECT; } if ( match.bv_val != NULL ) { match.bv_len = strlen( match.bv_val ); } rc = 0; break; } /* if needed, restore timeout */ if ( li->li_timeout[ SLAP_OP_SEARCH ] ) { if ( tv.tv_sec == 0 || tv.tv_sec > li->li_timeout[ SLAP_OP_SEARCH ] ) { tv.tv_sec = li->li_timeout[ SLAP_OP_SEARCH ]; tv.tv_usec = 0; } } } if ( rc == -1 ) { if ( dont_retry == 0 ) { if ( do_retry ) { do_retry = 0; if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_DONTSEND ) ) { goto retry; } } rs->sr_err = LDAP_SERVER_DOWN; rs->sr_err = slap_map_api2result( rs ); goto finish; } else if ( LDAP_BACK_ONERR_STOP( li ) ) { /* if onerr == STOP */ rs->sr_err = LDAP_SERVER_DOWN; rs->sr_err = slap_map_api2result( rs ); goto finish; } } /* * Rewrite the matched portion of the search base, if required */ if ( !BER_BVISNULL( &match ) && !BER_BVISEMPTY( &match ) ) { struct berval pmatch; if ( dnPretty( NULL, &match, &pmatch, op->o_tmpmemctx ) != LDAP_SUCCESS ) { pmatch.bv_val = match.bv_val; match.bv_val = NULL; } rs->sr_matched = pmatch.bv_val; rs->sr_flags |= REP_MATCHED_MUSTBEFREED; } finish:; if ( !BER_BVISNULL( &match ) ) { ber_memfree( match.bv_val ); } if ( rs->sr_v2ref ) { rs->sr_err = LDAP_REFERRAL; } if ( LDAP_BACK_QUARANTINE( li ) ) { ldap_back_quarantine( op, rs ); } if ( filter.bv_val != op->ors_filterstr.bv_val ) { op->o_tmpfree( filter.bv_val, op->o_tmpmemctx ); } #if 0 /* let send_ldap_result play cleanup handlers (ITS#4645) */ if ( rc != SLAPD_ABANDON ) #endif { send_ldap_result( op, rs ); } (void)ldap_back_controls_free( op, rs, &ctrls ); if ( rs->sr_ctrls ) { ldap_controls_free( rs->sr_ctrls ); rs->sr_ctrls = NULL; } if ( rs->sr_text ) { if ( freetext ) { ber_memfree( (char *)rs->sr_text ); } rs->sr_text = NULL; } if ( rs->sr_ref ) { op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx ); rs->sr_ref = NULL; } if ( references ) { ber_memvfree( (void **)references ); } if ( attrs ) { op->o_tmpfree( attrs, op->o_tmpmemctx ); } if ( lc != NULL ) { ldap_back_release_conn( li, lc ); } if ( rs->sr_err == LDAP_UNAVAILABLE && /* if we originally bound and wanted rebind-as-user, must drop * the connection now because we just discarded the credentials. * ITS#7464, #8142 */ LDAP_BACK_SAVECRED( li ) && SLAP_IS_AUTHZ_BACKEND( op ) ) rs->sr_err = SLAPD_DISCONNECT; return rs->sr_err; }
PyObject* LDAPmessage_to_python( LDAP*ld, LDAPMessage*m ) { /* we convert an LDAP message into a python structure. * It is always a list of dictionaries. * We always free m. */ PyObject* result; LDAPMessage* entry; result = PyList_New(0); if (result == NULL) { ldap_msgfree( m ); return NULL; } for(entry = ldap_first_entry(ld,m); entry != NULL; entry = ldap_next_entry(ld,entry)) { char *dn; char *attr; BerElement *ber = NULL; PyObject* entrytuple; PyObject* attrdict; dn = ldap_get_dn( ld, entry ); if (dn == NULL) { Py_DECREF(result); ldap_msgfree( m ); return LDAPerror( ld, "ldap_get_dn" ); } attrdict = PyDict_New(); if (attrdict == NULL) { Py_DECREF(result); ldap_msgfree( m ); ldap_memfree(dn); return NULL; } /* Fill attrdict with lists */ for( attr = ldap_first_attribute( ld, entry, &ber ); attr != NULL; attr = ldap_next_attribute( ld, entry, ber ) ) { PyObject* valuelist; struct berval ** bvals = ldap_get_values_len( ld, entry, attr ); /* Find which list to append to */ if ( PyMapping_HasKeyString( attrdict, attr ) ) { valuelist = PyMapping_GetItemString( attrdict, attr ); } else { valuelist = PyList_New(0); if (valuelist != NULL && PyMapping_SetItemString(attrdict, attr, valuelist) == -1) { Py_DECREF(valuelist); valuelist = NULL; /* catch error later */ } } if (valuelist == NULL) { Py_DECREF(attrdict); Py_DECREF(result); if (ber != NULL) ber_free(ber, 0); ldap_msgfree( m ); ldap_memfree(attr); ldap_memfree(dn); return NULL; } if (bvals != NULL) { Py_ssize_t i; for (i=0; bvals[i]; i++) { PyObject *valuestr; valuestr = PyBytes_FromStringAndSize( bvals[i]->bv_val, bvals[i]->bv_len ); if (PyList_Append( valuelist, valuestr ) == -1) { Py_DECREF(attrdict); Py_DECREF(result); Py_DECREF(valuestr); Py_DECREF(valuelist); if (ber != NULL) ber_free(ber, 0); ldap_msgfree( m ); ldap_memfree(attr); ldap_memfree(dn); return NULL; } Py_DECREF(valuestr); } ldap_value_free_len(bvals); } Py_DECREF( valuelist ); ldap_memfree(attr); } entrytuple = Py_BuildValue("(sO)", dn, attrdict); ldap_memfree(dn); Py_DECREF(attrdict); PyList_Append(result, entrytuple); Py_DECREF(entrytuple); if (ber != NULL) ber_free(ber, 0); } for(entry = ldap_first_reference(ld,m); entry != NULL; entry = ldap_next_reference(ld,entry)) { char **refs = NULL; PyObject* entrytuple; PyObject* reflist = PyList_New(0); if (reflist == NULL) { Py_DECREF(result); ldap_msgfree( m ); return NULL; } if (ldap_parse_reference(ld, entry, &refs, NULL, 0) != LDAP_SUCCESS) { Py_DECREF(result); ldap_msgfree( m ); return LDAPerror( ld, "ldap_parse_reference" ); } if (refs) { Py_ssize_t i; for (i=0; refs[i] != NULL; i++) { PyObject *refstr = PyBytes_FromString(refs[i]); PyList_Append(reflist, refstr); Py_DECREF(refstr); } ber_memvfree( (void **) refs ); } entrytuple = Py_BuildValue("(sO)", NULL, reflist); Py_DECREF(reflist); PyList_Append(result, entrytuple); Py_DECREF(entrytuple); } ldap_msgfree( m ); return result; }
DWORD VmAfdQueryCACertAndCrlAttributes( LDAP* pLotus, PVMAFD_CERT_ARRAY* ppCertificates, PVMAFD_CRL_FILE_CONTAINER* ppCrls ) { DWORD dwError = 0; PSTR pszFilter = "(objectClass=vmwCertificationAuthority)"; PSTR pszAttrCert = "cACertificate"; PSTR pszAttrCrl = "certificateRevocationList"; PSTR pszSearchBaseDN = NULL; PSTR pszDomainName = NULL; LDAPMessage* pSearchResult = NULL; LDAPMessage* pCAResult = NULL; PCHAR attrs[] = { pszAttrCert, pszAttrCrl, NULL}; int nCertCount = 0; int nCrlCount = 0; PVMAFD_CERT_ARRAY pCertArray = NULL; PVMAFD_CRL_FILE_CONTAINER pCrlContainer = NULL; struct berval** ppValues = NULL; if (!ppCertificates || !ppCrls) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMAFD_ERROR(dwError); } dwError = VmAfdGetDefaultDomainName( pLotus, &pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringPrintf( &pszSearchBaseDN, "cn=Configuration,%s", pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); dwError = ldap_search_ext_s( pLotus, pszSearchBaseDN, LDAP_SCOPE_SUBTREE, pszFilter, attrs, 0, /* get values and attrs */ NULL, NULL, NULL, 0, &pSearchResult); BAIL_ON_VMAFD_ERROR(dwError); for ( pCAResult = ldap_first_entry(pLotus, pSearchResult); pCAResult != NULL; pCAResult = ldap_next_entry(pLotus, pCAResult)) { nCertCount += VmAfdCountResultAttribute( pLotus, pCAResult, pszAttrCert); nCrlCount += VmAfdCountResultAttribute( pLotus, pCAResult, pszAttrCrl); } dwError = VmAfdAllocateMemory( sizeof(VMAFD_CERT_ARRAY), (PVOID*)&pCertArray); BAIL_ON_VMAFD_ERROR(dwError); pCertArray->dwCount = nCertCount; dwError = VmAfdAllocateMemory( sizeof(VMAFD_CRL_FILE_CONTAINER), (PVOID*)&pCrlContainer); BAIL_ON_VMAFD_ERROR(dwError); pCrlContainer->dwCount = nCrlCount; if (nCertCount || nCrlCount) { int certIndex = 0; int crlIndex = 0; if (nCertCount) { dwError = VmAfdAllocateMemory( sizeof(VMAFD_CERT_CONTAINER) * nCertCount, (PVOID*)&pCertArray->certificates); BAIL_ON_VMAFD_ERROR(dwError); } if (nCrlCount) { dwError = VmAfdAllocateMemory( sizeof(VMAFD_CRL_DATA) * nCrlCount, (PVOID*)&pCrlContainer->crls); BAIL_ON_VMAFD_ERROR(dwError); } for ( pCAResult = ldap_first_entry(pLotus, pSearchResult); pCAResult != NULL; pCAResult = ldap_next_entry(pLotus, pCAResult)) { // Copy certs ppValues = ldap_get_values_len( pLotus, pCAResult, pszAttrCert); if (ppValues) { int i = 0; while(ppValues[i]) { dwError = VmAfdAllocateMemory( sizeof(CHAR) * ppValues[i]->bv_len + 1, (PVOID)&pCertArray->certificates[certIndex].pCert); BAIL_ON_VMAFD_ERROR(dwError); memcpy( (PVOID) pCertArray->certificates[certIndex].pCert, (PVOID) ppValues[i]->bv_val, (size_t) ppValues[i]->bv_len); i++; certIndex++; } ldap_value_free_len(ppValues); ppValues = NULL; } // Copy CRLs ppValues = ldap_get_values_len( pLotus, pCAResult, pszAttrCrl); if (ppValues) { int i = 0; while(ppValues[i]) { dwError = VmAfdAllocateMemory( sizeof(CHAR) * ppValues[i]->bv_len + 1, (PVOID)&pCrlContainer->crls[crlIndex].buffer); BAIL_ON_VMAFD_ERROR(dwError); memcpy( (PVOID) pCrlContainer->crls[crlIndex].buffer, (PVOID) ppValues[i]->bv_val, (size_t) ppValues[i]->bv_len); i++; crlIndex++; } ldap_value_free_len(ppValues); ppValues = NULL; } } } *ppCertificates = pCertArray; *ppCrls = pCrlContainer; cleanup: VMAFD_SAFE_FREE_MEMORY(pszSearchBaseDN); VMAFD_SAFE_FREE_MEMORY(pszDomainName); if (ppValues != NULL) { ldap_value_free_len(ppValues); ppValues = NULL; } if(pSearchResult != NULL) { ldap_msgfree(pSearchResult); } return dwError; error: *ppCertificates = NULL; VMAFD_SAFE_FREE_MEMORY(pCrlContainer); if (ppCertificates) { *ppCertificates = NULL; } if(ppCrls) { *ppCrls = NULL; } if (pCertArray ) { VecsFreeCertArray(pCertArray); } goto cleanup; }
/* Parse an extended partial */ int ldap_parse_intermediate ( LDAP *ld, LDAPMessage *res, char **retoidp, struct berval **retdatap, LDAPControl ***serverctrls, int freeit ) { BerElement *ber; ber_tag_t tag; ber_len_t len; struct berval *resdata; char *resoid; assert( ld != NULL ); assert( LDAP_VALID( ld ) ); assert( res != NULL ); Debug( LDAP_DEBUG_TRACE, "ldap_parse_intermediate\n", 0, 0, 0 ); if( ld->ld_version < LDAP_VERSION3 ) { ld->ld_errno = LDAP_NOT_SUPPORTED; return ld->ld_errno; } if( res->lm_msgtype != LDAP_RES_INTERMEDIATE ) { ld->ld_errno = LDAP_PARAM_ERROR; return ld->ld_errno; } if( retoidp != NULL ) *retoidp = NULL; if( retdatap != NULL ) *retdatap = NULL; if( serverctrls != NULL ) *serverctrls = NULL; ber = ber_dup( res->lm_ber ); if ( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } tag = ber_scanf( ber, "{" /*}*/ ); if( tag == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 0 ); return ld->ld_errno; } resoid = NULL; resdata = NULL; tag = ber_peek_tag( ber, &len ); /* * NOTE: accept intermediate and extended response tag values * as older versions of slapd(8) incorrectly used extended * response tags. * Should be removed when 2.2 is moved to Historic. */ if( tag == LDAP_TAG_IM_RES_OID || tag == LDAP_TAG_EXOP_RES_OID ) { /* we have a resoid */ if( ber_scanf( ber, "a", &resoid ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 0 ); return ld->ld_errno; } assert( resoid[ 0 ] != '\0' ); tag = ber_peek_tag( ber, &len ); } if( tag == LDAP_TAG_IM_RES_VALUE || tag == LDAP_TAG_EXOP_RES_VALUE ) { /* we have a resdata */ if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 0 ); if( resoid != NULL ) LDAP_FREE( resoid ); return ld->ld_errno; } } if ( serverctrls == NULL ) { ld->ld_errno = LDAP_SUCCESS; goto free_and_return; } if ( ber_scanf( ber, /*{*/ "}" ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; goto free_and_return; } ld->ld_errno = ldap_pvt_get_controls( ber, serverctrls ); free_and_return: ber_free( ber, 0 ); if( retoidp != NULL ) { *retoidp = resoid; } else { LDAP_FREE( resoid ); } if( retdatap != NULL ) { *retdatap = resdata; } else { ber_bvfree( resdata ); } if( freeit ) { ldap_msgfree( res ); } return ld->ld_errno; }
void CWE90_LDAP_Injection__w32_char_listen_socket_10_bad() { char * data; char dataBuffer[256] = ""; data = dataBuffer; if(globalTrue) { { #ifdef _WIN32 WSADATA wsaData; int wsaDataInit = 0; #endif int recvResult; struct sockaddr_in service; char *replace; SOCKET listenSocket = INVALID_SOCKET; SOCKET acceptSocket = INVALID_SOCKET; size_t dataLen = strlen(data); do { #ifdef _WIN32 if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { break; } wsaDataInit = 1; #endif /* POTENTIAL FLAW: Read data using a listen socket */ listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listenSocket == INVALID_SOCKET) { break; } memset(&service, 0, sizeof(service)); service.sin_family = AF_INET; service.sin_addr.s_addr = INADDR_ANY; service.sin_port = htons(TCP_PORT); if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) { break; } if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) { break; } acceptSocket = accept(listenSocket, NULL, NULL); if (acceptSocket == SOCKET_ERROR) { break; } /* Abort on error or the connection was closed */ recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (256 - dataLen - 1), 0); if (recvResult == SOCKET_ERROR || recvResult == 0) { break; } /* Append null terminator */ data[dataLen + recvResult / sizeof(char)] = '\0'; /* Eliminate CRLF */ replace = strchr(data, '\r'); if (replace) { *replace = '\0'; } replace = strchr(data, '\n'); if (replace) { *replace = '\0'; } } while (0); if (listenSocket != INVALID_SOCKET) { CLOSE_SOCKET(listenSocket); } if (acceptSocket != INVALID_SOCKET) { CLOSE_SOCKET(acceptSocket); } #ifdef _WIN32 if (wsaDataInit) { WSACleanup(); } #endif } } { LDAP* pLdapConnection = NULL; ULONG connectSuccess = 0L; ULONG searchSuccess = 0L; LDAPMessage *pMessage = NULL; char filter[256]; /* POTENTIAL FLAW: data concatenated into LDAP search, which could result in LDAP Injection*/ _snprintf(filter, 256-1, "(cn=%s)", data); pLdapConnection = ldap_initA("localhost", LDAP_PORT); if (pLdapConnection == NULL) { printLine("Initialization failed"); exit(1); } connectSuccess = ldap_connect(pLdapConnection, NULL); if (connectSuccess != LDAP_SUCCESS) { printLine("Connection failed"); exit(1); } searchSuccess = ldap_search_ext_sA( pLdapConnection, "base", LDAP_SCOPE_SUBTREE, filter, NULL, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &pMessage); if (searchSuccess != LDAP_SUCCESS) { printLine("Search failed"); if (pMessage != NULL) { ldap_msgfree(pMessage); } exit(1); } /* Typically you would do something with the search results, but this is a test case and we can ignore them */ /* Free the results to avoid incidentals */ if (pMessage != NULL) { ldap_msgfree(pMessage); } /* Close the connection */ ldap_unbind(pLdapConnection); } }
/* Parse an extended result */ int ldap_parse_extended_result ( LDAP *ld, LDAPMessage *res, char **retoidp, struct berval **retdatap, int freeit ) { BerElement *ber; ber_tag_t rc; ber_tag_t tag; ber_len_t len; struct berval *resdata; ber_int_t errcode; char *resoid; assert( ld != NULL ); assert( LDAP_VALID( ld ) ); assert( res != NULL ); Debug( LDAP_DEBUG_TRACE, "ldap_parse_extended_result\n", 0, 0, 0 ); if( ld->ld_version < LDAP_VERSION3 ) { ld->ld_errno = LDAP_NOT_SUPPORTED; return ld->ld_errno; } if( res->lm_msgtype != LDAP_RES_EXTENDED ) { ld->ld_errno = LDAP_PARAM_ERROR; return ld->ld_errno; } if( retoidp != NULL ) *retoidp = NULL; if( retdatap != NULL ) *retdatap = NULL; if ( ld->ld_error ) { LDAP_FREE( ld->ld_error ); ld->ld_error = NULL; } if ( ld->ld_matched ) { LDAP_FREE( ld->ld_matched ); ld->ld_matched = NULL; } ber = ber_dup( res->lm_ber ); if ( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } rc = ber_scanf( ber, "{eAA" /*}*/, &errcode, &ld->ld_matched, &ld->ld_error ); if( rc == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 0 ); return ld->ld_errno; } resoid = NULL; resdata = NULL; tag = ber_peek_tag( ber, &len ); if( tag == LDAP_TAG_REFERRAL ) { /* skip over referral */ if( ber_scanf( ber, "x" ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 0 ); return ld->ld_errno; } tag = ber_peek_tag( ber, &len ); } if( tag == LDAP_TAG_EXOP_RES_OID ) { /* we have a resoid */ if( ber_scanf( ber, "a", &resoid ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 0 ); return ld->ld_errno; } assert( resoid[ 0 ] != '\0' ); tag = ber_peek_tag( ber, &len ); } if( tag == LDAP_TAG_EXOP_RES_VALUE ) { /* we have a resdata */ if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( ber, 0 ); if( resoid != NULL ) LDAP_FREE( resoid ); return ld->ld_errno; } } ber_free( ber, 0 ); if( retoidp != NULL ) { *retoidp = resoid; } else { LDAP_FREE( resoid ); } if( retdatap != NULL ) { *retdatap = resdata; } else { ber_bvfree( resdata ); } ld->ld_errno = errcode; if( freeit ) { ldap_msgfree( res ); } return LDAP_SUCCESS; }
void CWE90_LDAP_Injection__w32_wchar_t_console_09_bad() { wchar_t * data; wchar_t dataBuffer[256] = L""; data = dataBuffer; if(GLOBAL_CONST_TRUE) { { /* Read input from the console */ size_t dataLen = wcslen(data); /* if there is room in data, read into it from the console */ if (256-dataLen > 1) { /* POTENTIAL FLAW: Read data from the console */ if (fgetws(data+dataLen, (int)(256-dataLen), stdin) != NULL) { /* The next few lines remove the carriage return from the string that is * inserted by fgetws() */ dataLen = wcslen(data); if (dataLen > 0 && data[dataLen-1] == L'\n') { data[dataLen-1] = L'\0'; } } else { printLine("fgetws() failed"); /* Restore NUL terminator if fgetws fails */ data[dataLen] = L'\0'; } } } } { LDAP* pLdapConnection = NULL; ULONG connectSuccess = 0L; ULONG searchSuccess = 0L; LDAPMessage *pMessage = NULL; wchar_t filter[256]; /* POTENTIAL FLAW: data concatenated into LDAP search, which could result in LDAP Injection*/ _snwprintf(filter, 256-1, L"(cn=%s)", data); pLdapConnection = ldap_initW(L"localhost", LDAP_PORT); if (pLdapConnection == NULL) { printLine("Initialization failed"); exit(1); } connectSuccess = ldap_connect(pLdapConnection, NULL); if (connectSuccess != LDAP_SUCCESS) { printLine("Connection failed"); exit(1); } searchSuccess = ldap_search_ext_sW( pLdapConnection, L"base", LDAP_SCOPE_SUBTREE, filter, NULL, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &pMessage); if (searchSuccess != LDAP_SUCCESS) { printLine("Search failed"); if (pMessage != NULL) { ldap_msgfree(pMessage); } exit(1); } /* Typically you would do something with the search results, but this is a test case and we can ignore them */ /* Free the results to avoid incidentals */ if (pMessage != NULL) { ldap_msgfree(pMessage); } /* Close the connection */ ldap_unbind(pLdapConnection); } }
/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ static void goodG2B1() { wchar_t * data; wchar_t dataBuffer[256] = L""; data = dataBuffer; if(GLOBAL_CONST_FALSE) { /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ printLine("Benign, fixed string"); } else { /* FIX: Use a fixed file name */ wcscat(data, L"Doe, XXXXX"); } { LDAP* pLdapConnection = NULL; ULONG connectSuccess = 0L; ULONG searchSuccess = 0L; LDAPMessage *pMessage = NULL; wchar_t filter[256]; /* POTENTIAL FLAW: data concatenated into LDAP search, which could result in LDAP Injection*/ _snwprintf(filter, 256-1, L"(cn=%s)", data); pLdapConnection = ldap_initW(L"localhost", LDAP_PORT); if (pLdapConnection == NULL) { printLine("Initialization failed"); exit(1); } connectSuccess = ldap_connect(pLdapConnection, NULL); if (connectSuccess != LDAP_SUCCESS) { printLine("Connection failed"); exit(1); } searchSuccess = ldap_search_ext_sW( pLdapConnection, L"base", LDAP_SCOPE_SUBTREE, filter, NULL, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &pMessage); if (searchSuccess != LDAP_SUCCESS) { printLine("Search failed"); if (pMessage != NULL) { ldap_msgfree(pMessage); } exit(1); } /* Typically you would do something with the search results, but this is a test case and we can ignore them */ /* Free the results to avoid incidentals */ if (pMessage != NULL) { ldap_msgfree(pMessage); } /* Close the connection */ ldap_unbind(pLdapConnection); } }
int lds_search_async( char* _lds_name, char* _dn, int _scope, char* _filter, char** _attrs, struct timeval* _search_timeout, int* _ld_result_count, int* _ld_error, int* _msgidp) { struct ld_session* lds; struct timeval zerotime; #ifdef LDAP_PERF struct timeval before_search = { 0, 0 }, after_search = { 0, 0 }; #endif /* * get ld_handle */ if (get_connected_ldap_session(_lds_name, &lds) != 0) { LM_ERR("[%s]: couldn't get ldap session\n", _lds_name); return -1; } /* * free last_ldap_result */ if (last_ldap_result != NULL) { ldap_msgfree(last_ldap_result); last_ldap_result = NULL; } LM_DBG( "[%s]: performing LDAP search: dn [%s]," " scope [%d], filter [%s], client_timeout [%d] usecs\n", _lds_name, _dn, _scope, _filter, (int)(lds->client_search_timeout.tv_sec * 1000000 + lds->client_search_timeout.tv_usec)); #ifdef LDAP_PERF gettimeofday(&before_search, NULL); #endif /* * perform ldap search */ *_ld_error = ldap_search_ext( lds->handle, _dn, _scope, _filter, _attrs, 0, NULL, NULL, &lds->client_search_timeout, 0, _msgidp); #ifdef LDAP_PERF gettimeofday(&after_search, NULL); LM_INFO("[%s]: LDAP search took [%d] usecs\n", _lds_name, (int)((after_search.tv_sec * 1000000 + after_search.tv_usec) - (before_search.tv_sec * 1000000 + before_search.tv_usec))); #endif if (*_ld_error != LDAP_SUCCESS) { if (last_ldap_result != NULL) { ldap_msgfree(last_ldap_result); last_ldap_result = NULL; } if (LDAP_API_ERROR(*_ld_error)) { ldap_disconnect(_lds_name); } LM_DBG( "[%s]: ldap_search_ext_st failed: %s\n", _lds_name, ldap_err2string(*_ld_error)); return -1; } zerotime.tv_sec = zerotime.tv_usec = 0L; *_ld_error = ldap_result(lds->handle, *_msgidp, LDAP_MSG_ALL, &zerotime, &last_ldap_result); switch (*_ld_error) { case -1: LM_ERR("[%s]: ldap result failed\n", _lds_name); return -1; case 0: /* receive did not succeed; reactor needed */ return 0; default: /* receive successfull */ *_msgidp = -1; break; } last_ldap_handle = lds->handle; *_ld_result_count = ldap_count_entries(lds->handle, last_ldap_result); if (*_ld_result_count < 0) { LM_DBG("[%s]: ldap_count_entries failed\n", _lds_name); return -1; } return 0; }
ldap_key_t * ldap_getuserkey(ldap_opt_t *l, const char * user) { ldap_key_t * k = (ldap_key_t *) calloc (1, sizeof(ldap_key_t)); LDAPMessage *res, *e; char * filter; int i; char *attrs[] = { l->pub_key_attr, NULL }; if ((!k) || (!l)) return NULL; /* Am i still connected ? RETRY n times */ /* XXX TODO: setup some conf value for retrying */ if (!(l->flags & FLAG_CONNECTED)) for (i = 0 ; i < 2 ; i++) if (ldap_connect(l) == 0) break; /* quick check for attempts to be evil */ if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) || (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL)) return NULL; /* build filter for LDAP request */ REQUEST_USER(filter, user, l->filter); if ( ldap_search_st( l->ld, l->u_basedn, LDAP_SCOPE_SUBTREE, filter, attrs, 0, &l->s_timeout, &res ) != LDAP_SUCCESS) { ldap_perror(l->ld, "ldap_search_st()"); free(filter); free(k); /* XXX error on search, timeout etc.. close ask for reconnect */ ldap_close(l); return NULL; } /* free */ free(filter); /* check if any results */ i = ldap_count_entries(l->ld,res); if (i <= 0) { ldap_msgfree(res); free(k); return NULL; } if (i > 1) debug("[LDAP] duplicate entries, using the FIRST entry returned"); e = ldap_first_entry(l->ld, res); k->keys = ldap_get_values_len(l->ld, e, l->pub_key_attr); k->num = ldap_count_values_len(k->keys); ldap_msgfree(res); return k; }
/* * sets last_ldap_result and last_ldap_handle */ int lds_search( char* _lds_name, char* _dn, int _scope, char* _filter, char** _attrs, struct timeval* _search_timeout, int* _ld_result_count, int* _ld_error) { struct ld_session* lds; #ifdef LDAP_PERF struct timeval before_search = { 0, 0 }, after_search = { 0, 0 }; #endif /* * get ld_handle */ if (get_connected_ldap_session(_lds_name, &lds) != 0) { LM_ERR("[%s]: couldn't get ldap session\n", _lds_name); return -1; } /* * free last_ldap_result */ if (last_ldap_result != NULL) { ldap_msgfree(last_ldap_result); last_ldap_result = NULL; } LM_DBG( "[%s]: performing LDAP search: dn [%s]," " scope [%d], filter [%s], client_timeout [%d] usecs\n", _lds_name, _dn, _scope, _filter, (int)(lds->client_search_timeout.tv_sec * 1000000 + lds->client_search_timeout.tv_usec)); #ifdef LDAP_PERF gettimeofday(&before_search, NULL); #endif /* * perform ldap search */ *_ld_error = ldap_search_ext_s( lds->handle, _dn, _scope, _filter, _attrs, 0, NULL, NULL, &lds->client_search_timeout, 0, &last_ldap_result); #ifdef LDAP_PERF gettimeofday(&after_search, NULL); LM_INFO("[%s]: LDAP search took [%d] usecs\n", _lds_name, (int)((after_search.tv_sec * 1000000 + after_search.tv_usec) - (before_search.tv_sec * 1000000 + before_search.tv_usec))); #endif if (*_ld_error != LDAP_SUCCESS) { if (last_ldap_result != NULL) { ldap_msgfree(last_ldap_result); last_ldap_result = NULL; } if (LDAP_API_ERROR(*_ld_error)) { ldap_disconnect(_lds_name); } LM_DBG( "[%s]: ldap_search_ext_st failed: %s\n", _lds_name, ldap_err2string(*_ld_error)); return -1; } last_ldap_handle = lds->handle; *_ld_result_count = ldap_count_entries(lds->handle, last_ldap_result); if (*_ld_result_count < 0) { LM_DBG("[%s]: ldap_count_entries failed\n", _lds_name); return -1; } return 0; }
int ld_cmd_exec(db_res_t* res, db_cmd_t* cmd) { db_con_t* con; struct ld_res* lres; struct ld_cmd* lcmd; struct ld_con* lcon; char* filter, *err_desc; int ret, err; LDAPMessage *msg, *resmsg; int reconn_cnt; int msgid; char *oid; struct berval *data; struct timeval restimeout; filter = NULL; err_desc = NULL; resmsg = NULL; /* First things first: retrieve connection info from the currently active * connection and also mysql payload from the database command */ con = cmd->ctx->con[db_payload_idx]; lcmd = DB_GET_PAYLOAD(cmd); lcon = DB_GET_PAYLOAD(con); reconn_cnt = ld_reconnect_attempt; if (ld_prepare_ldap_filter(&filter, cmd, &lcmd->filter) < 0) { ERR("ldap: Error while building LDAP search filter\n"); goto error; } DBG("ldap: ldap_search(base:'%s', filter:'%s')\n", lcmd->base, filter); do { if (lcon->flags & LD_CONNECTED) { ldap_set_option(lcon->con, LDAP_OPT_DEREF, ((void *)&lcmd->chase_references)); /* there is alternative method using LDAP_CONTROL_REFERRALS per request but is not well documented */ ldap_set_option(lcon->con, LDAP_OPT_REFERRALS, lcmd->chase_referrals?LDAP_OPT_ON:LDAP_OPT_OFF); ret = ldap_search_ext(lcon->con, lcmd->base, lcmd->scope, filter, lcmd->result, 0, NULL, NULL, lcmd->timelimit.tv_sec ? &lcmd->timelimit : NULL, lcmd->sizelimit, &msgid); if (ret != LDAP_SUCCESS) { ERR("ldap: Error while searching: %s\n", ldap_err2string(ret)); goto error; } /* openldap v2.3 library workaround for unsolicited messages: if only unsolicited messages are available then ldap_result of v2.3 library waits forever */ memset(&restimeout, 0, sizeof(restimeout)); restimeout.tv_sec = 5; ret = ldap_result(lcon->con, LDAP_RES_ANY, LDAP_MSG_ALL, &restimeout, &resmsg); } else { /* force it to reconnect */ ret = -1; } if (ret <= 0) { ERR("ldap: Error in ldap_search: %s\n", ret < 0 ? ldap_err2string(ret) : "timeout"); if (ret == LDAP_SERVER_DOWN) { lcon->flags &= ~LD_CONNECTED; do { if (!reconn_cnt) { ERR("ldap: maximum reconnection attempt reached! giving up\n"); goto error; } reconn_cnt--; err = ld_con_connect(con); } while (err != 0); } else { goto error; } } } while (ret <= 0); /* looking for unsolicited messages */ for (msg = ldap_first_message(lcon->con, resmsg); msg != NULL; msg = ldap_next_message(lcon->con, msg)) { if (ldap_msgtype(msg) == LDAP_RES_EXTENDED) { if (ldap_parse_extended_result(lcon->con, msg, &oid, &data, 0) != LDAP_SUCCESS) { ERR("ldap: Error while parsing extended result\n"); goto error; } if (oid != NULL) { if (strcmp(oid, LDAP_NOTICE_OF_DISCONNECTION) == 0) { WARN("ldap: Notice of Disconnection (OID: %s)\n", oid); } else { WARN("ldap: Unsolicited message received. OID: %s\n", oid); } ldap_memfree(oid); } if (data != NULL) { WARN("ldap: Unsolicited message data: %.*s\n", (int)data->bv_len, data->bv_val); ber_bvfree(data); } } } ret = ldap_parse_result(lcon->con, resmsg, &err, NULL, &err_desc, NULL, NULL, 0); if (ret != LDAP_SUCCESS) { ERR("ldap: Error while reading result status: %s\n", ldap_err2string(ret)); goto error; } if (err != LDAP_SUCCESS) { ERR("ldap: LDAP server reports error: %s\n", ldap_err2string(err)); goto error; } if (res) { lres = DB_GET_PAYLOAD(res); lres->msg = resmsg; } else if (resmsg) { ldap_msgfree(resmsg); } if (filter) pkg_free(filter); if (err_desc) ldap_memfree(err_desc); return 0; error: if (filter) pkg_free(filter); if (resmsg) ldap_msgfree(resmsg); if (err_desc) ldap_memfree(err_desc); return -1; }
DWORD VmAfdGetDSERootAttribute( LDAP* pLotus, PSTR pszAttribute, PSTR* ppAttrValue ) { DWORD dwError = 0; // LDAP_SUCCESS PCHAR pDcFilter = "(objectClass=*)"; PCHAR pDcAttr[] = { pszAttribute, NULL }; PSTR pAttribute = NULL; BerElement* pBer = NULL; BerValue** ppValue = NULL; LDAPMessage* pSearchResult = NULL; LDAPMessage* pResults = NULL; dwError = ldap_search_ext_s( pLotus, "", LDAP_SCOPE_BASE, pDcFilter, pDcAttr, 0, NULL, NULL, NULL, 0, &pSearchResult); BAIL_ON_VMAFD_ERROR(dwError); if (ldap_count_entries(pLotus, pSearchResult) != 1) { dwError = ERROR_INVALID_STATE; BAIL_ON_VMAFD_ERROR(dwError); } pResults = ldap_first_entry(pLotus, pSearchResult); if (pResults == NULL) { ldap_get_option(pLotus, LDAP_OPT_ERROR_NUMBER, &dwError); BAIL_ON_VMAFD_ERROR(dwError); } pAttribute = ldap_first_attribute(pLotus,pResults,&pBer); if (pAttribute == NULL) { ldap_get_option(pLotus, LDAP_OPT_ERROR_NUMBER, &dwError); BAIL_ON_VMAFD_ERROR(dwError); } ppValue = ldap_get_values_len(pLotus, pResults, pAttribute); if (ppValue == NULL) { ldap_get_option(pLotus, LDAP_OPT_ERROR_NUMBER, &dwError); BAIL_ON_VMAFD_ERROR(dwError); } dwError = VmAfdAllocateStringA(ppValue[0]->bv_val, ppAttrValue); BAIL_ON_VMAFD_ERROR(dwError); cleanup: if (ppValue != NULL) { ldap_value_free_len(ppValue); } if (pAttribute != NULL) { ldap_memfree(pAttribute); } if (pBer != NULL) { ber_free(pBer,0); } if (pSearchResult != NULL) { ldap_msgfree(pSearchResult); } return dwError; error: *ppAttrValue = NULL; goto cleanup; }
int ldap_sasl_bind_s( LDAP *ld, LDAP_CONST char *dn, LDAP_CONST char *mechanism, struct berval *cred, LDAPControl **sctrls, LDAPControl **cctrls, struct berval **servercredp ) { int rc, msgid; LDAPMessage *result; struct berval *scredp = NULL; Debug0( LDAP_DEBUG_TRACE, "ldap_sasl_bind_s\n" ); /* do a quick !LDAPv3 check... ldap_sasl_bind will do the rest. */ if( servercredp != NULL ) { if (ld->ld_version < LDAP_VERSION3) { ld->ld_errno = LDAP_NOT_SUPPORTED; return ld->ld_errno; } *servercredp = NULL; } rc = ldap_sasl_bind( ld, dn, mechanism, cred, sctrls, cctrls, &msgid ); if ( rc != LDAP_SUCCESS ) { return( rc ); } #ifdef LDAP_CONNECTIONLESS if (LDAP_IS_UDP(ld)) { return( rc ); } #endif if ( ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &result ) == -1 || !result ) { return( ld->ld_errno ); /* ldap_result sets ld_errno */ } /* parse the results */ scredp = NULL; if( servercredp != NULL ) { rc = ldap_parse_sasl_bind_result( ld, result, &scredp, 0 ); } if ( rc != LDAP_SUCCESS ) { ldap_msgfree( result ); return( rc ); } rc = ldap_result2error( ld, result, 1 ); if ( rc == LDAP_SUCCESS || rc == LDAP_SASL_BIND_IN_PROGRESS ) { if( servercredp != NULL ) { *servercredp = scredp; scredp = NULL; } } if ( scredp != NULL ) { ber_bvfree(scredp); } return rc; }
/* Creates new LDAP Account */ int db_create(char *bid, char *username, char *first, char *last, char *pass) { /* declares local vars */ LDAP *ld; LDAPMessage *res; LDAPMod **mods; char filter[1024]; int i; int bid_len; char *dn; char *uid; /* checks for connection */ if (db_pointer) { ld = db_pointer; } else { return(1); }; /* Gets size of bid */ bid_len = strlen(bid); /* Creates filter */ strcpy(filter, "(blipsid="); strcpy(filter+9, bid); strcpy(filter+9+bid_len, ")"); if (ldap_search_s(ld, "o=acsalaska.net", LDAP_SCOPE_SUBTREE, filter, NULL, 0, &res)) { ldap_perror(ld, "ldap_search_s"); return(1); }; /* Checks for results */ if (ldap_count_entries(ld, res)) { ldap_msgfree(res); return(2); }; ldap_msgfree(res); res = NULL; /* Generates DN */ dn = (char *) db_dn(username); if (!dn) { return(1); }; /* Searches for existing username */ if (ldap_search_s(ld, dn, LDAP_SCOPE_SUBTREE, "(uid=*)", NULL, 0, &res) != LDAP_NO_SUCH_OBJECT) { ldap_perror(ld, "ldap_search_s"); free(dn); return(1); }; /* Checks for results */ if (ldap_count_entries(ld, res)) { ldap_msgfree(res); return(3); }; ldap_msgfree(res); /* gets UID of account */ uid = strtok(username, "@"); /* Creates mod pointers */ mods = (LDAPMod **) malloc (9*sizeof(LDAPMod *)); if (!mods) { return(1); }; memset(mods, 0, (8*sizeof(LDAPMod *))); for(i = 0; i < 8; i++) { mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod)); if (!mods[i]) { for(i = i; i >= 0; i--) free(mods[i]); free(mods); return(1); }; }; /* Creates mod entries */ mods[0]->mod_op = 0; mods[0]->mod_type = (char *) strdup("objectclass"); mods[0]->mod_values = (char **) malloc(sizeof(char *)*8); mods[0]->mod_values[0] = (char *) strdup("top"); mods[0]->mod_values[1] = (char *) strdup("person"); mods[0]->mod_values[2] = (char *) strdup("organizationalperson"); mods[0]->mod_values[3] = (char *) strdup("inetorgperson"); mods[0]->mod_values[4] = (char *) strdup("inetuser"); mods[0]->mod_values[5] = (char *) strdup("acsaccount"); mods[0]->mod_values[6] = (char *) strdup("acsblipsaccount"); mods[0]->mod_values[7] = NULL; mods[1]->mod_op = 0; mods[1]->mod_type = (char *) strdup("uid"); mods[1]->mod_values = (char **) malloc(sizeof(char *)*2); mods[1]->mod_values[0] = uid; mods[1]->mod_values[1] = NULL; mods[2]->mod_op = 0; mods[2]->mod_type = (char *) strdup("datasource"); mods[2]->mod_values = (char **) malloc(sizeof(char *)*2); mods[2]->mod_values[0] = (char *) strdup("Backend LDAP Internet Provisioning System Daemon"); mods[2]->mod_values[1] = NULL; mods[3]->mod_op = 0; mods[3]->mod_type = (char *) strdup("givenname"); mods[3]->mod_values = (char **) malloc(sizeof(char *)*2); mods[3]->mod_values[0] = first; mods[3]->mod_values[1] = NULL; mods[4]->mod_op = 0; mods[4]->mod_type = (char *) strdup("sn"); mods[4]->mod_values = (char **) malloc(sizeof(char *)*2); mods[4]->mod_values[0] = last; mods[4]->mod_values[1] = NULL; mods[5]->mod_op = 0; mods[5]->mod_type = (char *) strdup("cn"); mods[5]->mod_values = (char **) malloc(sizeof(char *)*2); mods[5]->mod_values[0] = (char *) strdup("First Last"); mods[5]->mod_values[1] = NULL; mods[6]->mod_op = 0; mods[6]->mod_type = (char *) strdup("clearpassword"); mods[6]->mod_values = (char **) malloc(sizeof(char *)*2); mods[6]->mod_values[0] = pass; mods[6]->mod_values[1] = NULL; mods[7]->mod_op = 0; mods[7]->mod_type = (char *) strdup("userpassword"); mods[7]->mod_values = (char **) malloc(sizeof(char *)*2); mods[7]->mod_values[0] = pass; mods[7]->mod_values[1] = NULL; mods[8] = NULL; /* Creates the account in LDAP */ if (ldap_add_s(ld, dn, mods)) { ldap_perror(ld, "ldap_add_s"); free(dn); ldap_mods_free(mods, 9); return(1); }; ldap_perror(ld, "ldap_add_s"); /* ends function */ fprintf(stderr, "got here 98\n"); free(dn); fprintf(stderr, "got here 99\n"); //ldap_mods_free(mods, 9); fprintf(stderr, "got here 100\n"); return(0); }
int ldap_parse_sasl_bind_result( LDAP *ld, LDAPMessage *res, struct berval **servercredp, int freeit ) { ber_int_t errcode; struct berval* scred; ber_tag_t tag; BerElement *ber; Debug0( LDAP_DEBUG_TRACE, "ldap_parse_sasl_bind_result\n" ); assert( ld != NULL ); assert( LDAP_VALID( ld ) ); assert( res != NULL ); if( servercredp != NULL ) { if( ld->ld_version < LDAP_VERSION2 ) { return LDAP_NOT_SUPPORTED; } *servercredp = NULL; } if( res->lm_msgtype != LDAP_RES_BIND ) { ld->ld_errno = LDAP_PARAM_ERROR; return ld->ld_errno; } scred = NULL; if ( ld->ld_error ) { LDAP_FREE( ld->ld_error ); ld->ld_error = NULL; } if ( ld->ld_matched ) { LDAP_FREE( ld->ld_matched ); ld->ld_matched = NULL; } /* parse results */ ber = ber_dup( res->lm_ber ); if( ber == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return ld->ld_errno; } if ( ld->ld_version < LDAP_VERSION2 ) { tag = ber_scanf( ber, "{iA}", &errcode, &ld->ld_error ); if( tag == LBER_ERROR ) { ber_free( ber, 0 ); ld->ld_errno = LDAP_DECODING_ERROR; return ld->ld_errno; } } else { ber_len_t len; tag = ber_scanf( ber, "{eAA" /*}*/, &errcode, &ld->ld_matched, &ld->ld_error ); if( tag == LBER_ERROR ) { ber_free( ber, 0 ); ld->ld_errno = LDAP_DECODING_ERROR; return ld->ld_errno; } tag = ber_peek_tag(ber, &len); if( tag == LDAP_TAG_REFERRAL ) { /* skip 'em */ if( ber_scanf( ber, "x" ) == LBER_ERROR ) { ber_free( ber, 0 ); ld->ld_errno = LDAP_DECODING_ERROR; return ld->ld_errno; } tag = ber_peek_tag(ber, &len); } if( tag == LDAP_TAG_SASL_RES_CREDS ) { if( ber_scanf( ber, "O", &scred ) == LBER_ERROR ) { ber_free( ber, 0 ); ld->ld_errno = LDAP_DECODING_ERROR; return ld->ld_errno; } } } ber_free( ber, 0 ); if ( servercredp != NULL ) { *servercredp = scred; } else if ( scred != NULL ) { ber_bvfree( scred ); } ld->ld_errno = errcode; if ( freeit ) { ldap_msgfree( res ); } return( LDAP_SUCCESS ); }
/* return 0 IFF we can retrieve the entry with ndn */ int ldap_back_entry_get( Operation *op, struct berval *ndn, ObjectClass *oc, AttributeDescription *at, int rw, Entry **ent ) { ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; ldapconn_t *lc = NULL; int rc; struct berval bdn; LDAPMessage *result = NULL, *e = NULL; char *attr[3], **attrp = NULL; char *filter = NULL; SlapReply rs; int do_retry = 1; LDAPControl **ctrls = NULL; Operation op2 = *op; *ent = NULL; /* Tell getconn this is a privileged op */ op2.o_do_not_cache = 1; /* use rootdn to be doubly explicit this is privileged */ op2.o_dn = op->o_bd->be_rootdn; op2.o_ndn = op->o_bd->be_rootndn; /* ldap_back_entry_get() is an entry lookup, so it does not need * to know what the entry is being looked up for */ op2.o_tag = LDAP_REQ_SEARCH; op2.o_ctrls = NULL; rc = ldap_back_dobind( &lc, &op2, &rs, LDAP_BACK_DONTSEND ); if ( !rc ) { return rs.sr_err; } if ( at ) { attrp = attr; if ( oc && at != slap_schema.si_ad_objectClass ) { attr[0] = slap_schema.si_ad_objectClass->ad_cname.bv_val; attr[1] = at->ad_cname.bv_val; attr[2] = NULL; } else { attr[0] = at->ad_cname.bv_val; attr[1] = NULL; } } if ( oc ) { char *ptr; filter = op->o_tmpalloc( STRLENOF( "(objectClass=" ")" ) + oc->soc_cname.bv_len + 1, op->o_tmpmemctx ); ptr = lutil_strcopy( filter, "(objectClass=" ); ptr = lutil_strcopy( ptr, oc->soc_cname.bv_val ); *ptr++ = ')'; *ptr++ = '\0'; } retry: ctrls = NULL; rc = ldap_back_controls_add( &op2, &rs, lc, &ctrls ); if ( rc != LDAP_SUCCESS ) { goto cleanup; } /* TODO: timeout? */ rc = ldap_pvt_search_s( lc->lc_ld, ndn->bv_val, LDAP_SCOPE_BASE, filter, attrp, LDAP_DEREF_NEVER, ctrls, NULL, NULL, LDAP_NO_LIMIT, 0, &result ); if ( rc != LDAP_SUCCESS ) { if ( rc == LDAP_SERVER_DOWN && do_retry ) { do_retry = 0; if ( ldap_back_retry( &lc, &op2, &rs, LDAP_BACK_DONTSEND ) ) { /* if the identity changed, there might be need to re-authz */ (void)ldap_back_controls_free( &op2, &rs, &ctrls ); goto retry; } } goto cleanup; } e = ldap_first_entry( lc->lc_ld, result ); if ( e == NULL ) { /* the entry exists, but it doesn't match the filter? */ goto cleanup; } *ent = entry_alloc(); if ( *ent == NULL ) { rc = LDAP_NO_MEMORY; goto cleanup; } rc = ldap_build_entry( op, e, *ent, &bdn ); if ( rc != LDAP_SUCCESS ) { entry_free( *ent ); *ent = NULL; } cleanup: (void)ldap_back_controls_free( &op2, &rs, &ctrls ); if ( result ) { ldap_msgfree( result ); } if ( filter ) { op->o_tmpfree( filter, op->o_tmpmemctx ); } if ( lc != NULL ) { ldap_back_release_conn( li, lc ); } return rc; }
static int ldaplookup_by_subject( X509_LOOKUP *ctx, int type, X509_NAME *name, X509_OBJECT *ret ) { int count = 0; ldaphost *lh; const char *attrs[2]; char *filter = NULL; if (ctx == NULL) return(0); if (name == NULL) return(0); lh = (ldaphost*) ctx->method_data; if (lh == NULL) return(0); switch(type) { case X509_LU_X509: { attrs[0] = ATTR_CACERT; } break; case X509_LU_CRL: { attrs[0] = ATTR_CACRL; } break; default: { X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_WRONG_LOOKUP_TYPE); goto done; } } attrs[1] = NULL; filter = ldaplookup_filter(name, attrs[0]); if (filter == NULL) { X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_UNABLE_TO_GET_FILTER); goto done; } #ifdef TRACE_BY_LDAP fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject: filter=%s\n", filter); #endif for (; lh != NULL; lh = lh->next) { LDAPMessage *res = NULL; int result; #ifdef TRACE_BY_LDAP { int version = -1; ldap_get_option(lh->ld, LDAP_OPT_PROTOCOL_VERSION, &version); fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject:" " bind to \"%s://%s:%d\"" " using ldap v%d protocol\n" , lh->ldapurl->lud_scheme, lh->ldapurl->lud_host, lh->ldapurl->lud_port , version ); } #endif result = ldaplookup_bind_s(lh->ld); if (result != LDAP_SUCCESS) { X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_UNABLE_TO_BIND); { char buf[1024]; snprintf(buf, sizeof(buf), " url=\"%s://%s:%d\"" " ldaperror=0x%x(%.256s)" , lh->ldapurl->lud_scheme, lh->ldapurl->lud_host, lh->ldapurl->lud_port , result, ldap_err2string(result) ); ERR_add_error_data(1, buf); } continue; } result = ldaplookup_search_s(lh->ld, lh->ldapurl->lud_dn, LDAP_SCOPE_SUBTREE, filter, (char**)attrs, 0, &res); if (result != LDAP_SUCCESS) { X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_SEARCH_FAIL); ldap_msgfree(res); continue; } result = ldaplookup_result2store(type, name, lh->ld, res, ctx->store_ctx); if (result > 0) count += result; ldap_msgfree(res); /*do not call ldap_unbind_s*/ } #ifdef TRACE_BY_LDAP fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject: count=%d\n", count); #endif if (count > 0) { /* * we have added at least one to the cache so now pull one out again */ union { struct { X509_CINF st_x509_cinf; X509 st_x509; } x509; struct { X509_CRL_INFO st_crl_info; X509_CRL st_crl; } crl; } data; X509_OBJECT stmp, *tmp; int k; memset(&data, 0, sizeof(data)); stmp.type = type; switch(type) { case X509_LU_X509: { data.x509.st_x509_cinf.subject = name; data.x509.st_x509.cert_info = &data.x509.st_x509_cinf; stmp.data.x509 = &data.x509.st_x509; } break; case X509_LU_CRL: { data.crl.st_crl_info.issuer = name; data.crl.st_crl.crl = &data.crl.st_crl_info; stmp.data.crl = &data.crl.st_crl; } break; default: count = 0; goto done; } CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); k = sk_X509_OBJECT_find(ctx->store_ctx->objs, &stmp); if (k >= 0) tmp = sk_X509_OBJECT_value(ctx->store_ctx->objs, k); else tmp = NULL; CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); #ifdef TRACE_BY_LDAP fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject: k=%d, tmp=%p\n", k, (void*)tmp); #endif if (tmp == NULL) { count = 0; goto done; } ret->type = tmp->type; memcpy(&ret->data, &tmp->data, sizeof(ret->data)); } done: if (filter != NULL) OPENSSL_free(filter); return(count > 0); }
static DWORD VMCALdapFindObject( PVMCA_LDAP_CONTEXT pContext, PCSTR pszBaseDN, ber_int_t scope, PCSTR pszAttribute, PCSTR pszValue, PSTR *ppszObjectDN ) { DWORD dwError = 0; DWORD dwNumEntries = 0; LDAPMessage* pResult = NULL; LDAPMessage* pEntry = NULL; PSTR pszFilter = NULL; PSTR pszObjectDN = NULL; if (pszAttribute && pszValue) { VMCAAllocateStringPrintfA(&pszFilter, "(%s=%s)", pszAttribute, pszValue); } dwError = ldap_search_ext_s( pContext->pConnection, (PSTR)pszBaseDN, scope, pszFilter, NULL, /* attributes */ TRUE, NULL, /* server controls */ NULL, /* client controls */ NULL, /* timeout */ 0, &pResult); BAIL_ON_ERROR(dwError); dwNumEntries = ldap_count_entries(pContext->pConnection, pResult); if (dwNumEntries > 1) { dwError = ERROR_INVALID_STATE; BAIL_ON_ERROR(dwError); } else if (dwNumEntries == 0) { dwError = ERROR_NOT_FOUND; BAIL_ON_ERROR(dwError); } else { pEntry = ldap_first_entry(pContext->pConnection, pResult); if (!pEntry) { dwError = ERROR_INVALID_STATE; BAIL_ON_ERROR(dwError); } pszObjectDN = ldap_get_dn(pContext->pConnection, pEntry); if (IsNullOrEmptyString(pszObjectDN)) { dwError = ERROR_INVALID_STATE; BAIL_ON_ERROR(dwError); } *ppszObjectDN = pszObjectDN; } cleanup: if (pResult) { ldap_msgfree(pResult); } VMCA_SAFE_FREE_STRINGA(pszFilter); return dwError; error : VMCA_SAFE_FREE_STRINGA(pszObjectDN); if (dwError == LDAP_NO_SUCH_OBJECT) { dwError = 0; } goto cleanup; }
/* goodG2B() uses the GoodSource with the BadSink */ static void goodG2B() { char * data; char * &dataRef = data; char dataBuffer[256] = ""; data = dataBuffer; /* FIX: Use a fixed file name */ strcat(data, "Doe, XXXXX"); { char * data = dataRef; { LDAP* pLdapConnection = NULL; ULONG connectSuccess = 0L; ULONG searchSuccess = 0L; LDAPMessage *pMessage = NULL; char filter[256]; /* POTENTIAL FLAW: data concatenated into LDAP search, which could result in LDAP Injection*/ _snprintf(filter, 256-1, "(cn=%s)", data); pLdapConnection = ldap_initA("localhost", LDAP_PORT); if (pLdapConnection == NULL) { printLine("Initialization failed"); exit(1); } connectSuccess = ldap_connect(pLdapConnection, NULL); if (connectSuccess != LDAP_SUCCESS) { printLine("Connection failed"); exit(1); } searchSuccess = ldap_search_ext_sA( pLdapConnection, "base", LDAP_SCOPE_SUBTREE, filter, NULL, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &pMessage); if (searchSuccess != LDAP_SUCCESS) { printLine("Search failed"); if (pMessage != NULL) { ldap_msgfree(pMessage); } exit(1); } /* Typically you would do something with the search results, but this is a test case and we can ignore them */ /* Free the results to avoid incidentals */ if (pMessage != NULL) { ldap_msgfree(pMessage); } /* Close the connection */ ldap_unbind(pLdapConnection); } } }
DWORD VMCALdapGetMemberships( PVMCA_LDAP_CONTEXT pConnection, PCSTR pszUPNName, PSTR **pppszMemberships, PDWORD pdwMemberships ) { DWORD dwError = 0; PSTR pszFilter = NULL; PSTR pszAttrMemberOf = ATTR_MEMBEROF; // memberOf PSTR ppszAttrs[] = { pszAttrMemberOf, NULL}; DWORD dwCount = 0; LDAPMessage *pResult = NULL; LDAPMessage *pEntry = NULL; struct berval** ppValues = NULL; PSTR *ppszMemberships = NULL; DWORD dwMemberships = 0; DWORD i = 0; LDAP *pLd = NULL; if (pConnection == NULL || pConnection->pConnection == NULL || IsNullOrEmptyString(pszUPNName) || pppszMemberships == NULL || pdwMemberships == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } pLd = pConnection->pConnection; dwError = VMCAAllocateStringPrintfA(&pszFilter, "(%s=%s)", ATTR_KRB_UPN, pszUPNName); // userPrincipalName BAIL_ON_VMCA_ERROR(dwError); dwError = ldap_search_ext_s( pLd, "", LDAP_SCOPE_SUBTREE, pszFilter, (PSTR*)ppszAttrs, 0, NULL, NULL, NULL, -1, &pResult); BAIL_ON_VMCA_ERROR(dwError); dwCount = ldap_count_entries(pLd, pResult); if (dwCount == 0) { dwError = LDAP_NO_SUCH_OBJECT; BAIL_ON_VMCA_ERROR(dwError); } else if (dwCount > 1) { dwError = LDAP_OPERATIONS_ERROR; BAIL_ON_VMCA_ERROR(dwError); } pEntry = ldap_first_entry(pLd, pResult); if (!pEntry) { dwError = LDAP_NO_SUCH_OBJECT; BAIL_ON_VMCA_ERROR(dwError); } ppValues = ldap_get_values_len(pLd, pEntry, pszAttrMemberOf); if (!ppValues) { dwMemberships = 0; } else { dwMemberships = ldap_count_values_len(ppValues); } if (dwMemberships) { dwError = VMCAAllocateMemory(dwMemberships * sizeof(PSTR), (PVOID*)&ppszMemberships); BAIL_ON_VMCA_ERROR(dwError); for (i = 0; ppValues[i] != NULL; i++) { PCSTR pszMemberOf = ppValues[i]->bv_val; dwError = VMCAAllocateStringA(pszMemberOf, &ppszMemberships[i]); BAIL_ON_VMCA_ERROR(dwError); } } *pppszMemberships = ppszMemberships; *pdwMemberships = dwMemberships; cleanup: if(ppValues) { ldap_value_free_len(ppValues); } if (pResult) { ldap_msgfree(pResult); } VMCA_SAFE_FREE_MEMORY(pszFilter); return dwError; error: if (ppszMemberships != NULL && dwMemberships > 0) { for (i = 0; i < dwMemberships; i++) { VMCA_SAFE_FREE_STRINGA(ppszMemberships[i]); } VMCA_SAFE_FREE_MEMORY(ppszMemberships); } goto cleanup; }
void bad() { char * data; char * &dataRef = data; char dataBuffer[256] = ""; data = dataBuffer; { /* Read input from a file */ size_t dataLen = strlen(data); FILE * pFile; /* if there is room in data, attempt to read the input from a file */ if (256-dataLen > 1) { pFile = fopen(FILENAME, "r"); if (pFile != NULL) { /* POTENTIAL FLAW: Read data from a file */ if (fgets(data+dataLen, (int)(256-dataLen), pFile) == NULL) { printLine("fgets() failed"); /* Restore NUL terminator if fgets fails */ data[dataLen] = '\0'; } fclose(pFile); } } } { char * data = dataRef; { LDAP* pLdapConnection = NULL; ULONG connectSuccess = 0L; ULONG searchSuccess = 0L; LDAPMessage *pMessage = NULL; char filter[256]; /* POTENTIAL FLAW: data concatenated into LDAP search, which could result in LDAP Injection*/ _snprintf(filter, 256-1, "(cn=%s)", data); pLdapConnection = ldap_initA("localhost", LDAP_PORT); if (pLdapConnection == NULL) { printLine("Initialization failed"); exit(1); } connectSuccess = ldap_connect(pLdapConnection, NULL); if (connectSuccess != LDAP_SUCCESS) { printLine("Connection failed"); exit(1); } searchSuccess = ldap_search_ext_sA( pLdapConnection, "base", LDAP_SCOPE_SUBTREE, filter, NULL, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &pMessage); if (searchSuccess != LDAP_SUCCESS) { printLine("Search failed"); if (pMessage != NULL) { ldap_msgfree(pMessage); } exit(1); } /* Typically you would do something with the search results, but this is a test case and we can ignore them */ /* Free the results to avoid incidentals */ if (pMessage != NULL) { ldap_msgfree(pMessage); } /* Close the connection */ ldap_unbind(pLdapConnection); } } }
static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf, size_t len, CURLcode *err) { ldapconninfo *li = conn->proto.generic; struct SessionHandle *data=conn->data; ldapreqinfo *lr = data->state.proto.generic; int rc, ret; LDAPMessage *result = NULL; LDAPMessage *ent; BerElement *ber = NULL; struct timeval tv = {0,1}; (void)len; (void)buf; (void)sockindex; rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &result); if(rc < 0) { failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc)); *err = CURLE_RECV_ERROR; return -1; } *err = CURLE_AGAIN; ret = -1; /* timed out */ if(result == NULL) return ret; for(ent = ldap_first_message(li->ld, result); ent; ent = ldap_next_message(li->ld, ent)) { struct berval bv, *bvals, **bvp = &bvals; int binary = 0, msgtype; msgtype = ldap_msgtype(ent); if(msgtype == LDAP_RES_SEARCH_RESULT) { int code; char *info = NULL; rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0); if(rc) { failf(data, "LDAP local: search ldap_parse_result %s", ldap_err2string(rc)); *err = CURLE_LDAP_SEARCH_FAILED; } else if(code && code != LDAP_SIZELIMIT_EXCEEDED) { failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc), info ? info : ""); *err = CURLE_LDAP_SEARCH_FAILED; } else { /* successful */ if(code == LDAP_SIZELIMIT_EXCEEDED) infof(data, "There are more than %d entries\n", lr->nument); data->req.size = data->req.bytecount; *err = CURLE_OK; ret = 0; } lr->msgid = 0; ldap_memfree(info); break; } else if(msgtype != LDAP_RES_SEARCH_ENTRY) continue; lr->nument++; rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv); if(rc < 0) { /* TODO: verify that this is really how this return code should be handled */ *err = CURLE_RECV_ERROR; return -1; } Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4); Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, bv.bv_len); Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); data->req.bytecount += bv.bv_len + 5; for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp); rc == LDAP_SUCCESS; rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) { int i; if(bv.bv_val == NULL) break; if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7)) binary = 1; else binary = 0; for(i=0; bvals[i].bv_val != NULL; i++) { int binval = 0; Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, bv.bv_len); Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1); data->req.bytecount += bv.bv_len + 2; if(!binary) { /* check for leading or trailing whitespace */ if(ISSPACE(bvals[i].bv_val[0]) || ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1])) binval = 1; else { /* check for unprintable characters */ unsigned int j; for(j=0; j<bvals[i].bv_len; j++) if(!ISPRINT(bvals[i].bv_val[j])) { binval = 1; break; } } } if(binary || binval) { char *val_b64 = NULL; size_t val_b64_sz = 0; /* Binary value, encode to base64. */ CURLcode error = Curl_base64_encode(data, bvals[i].bv_val, bvals[i].bv_len, &val_b64, &val_b64_sz); if(error) { ber_memfree(bvals); ber_free(ber, 0); ldap_msgfree(result); *err = error; return -1; } Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2); data->req.bytecount += 2; if(val_b64_sz > 0) { Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz); free(val_b64); data->req.bytecount += val_b64_sz; } } else { Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1); Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val, bvals[i].bv_len); data->req.bytecount += bvals[i].bv_len + 1; } Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); data->req.bytecount++; } ber_memfree(bvals); Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); data->req.bytecount++; } Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); data->req.bytecount++; ber_free(ber, 0); } ldap_msgfree(result); return ret; }
static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state, const char *domain_name) { fstring sid_string; fstring algorithmic_rid_base_string; char *filter = NULL; char *dn = NULL; LDAPMod **mods = NULL; int rc; LDAPMessage *result = NULL; int num_result; const char **attr_list; char *escape_domain_name; /* escape for filter */ escape_domain_name = escape_ldap_string(talloc_tos(), domain_name); if (!escape_domain_name) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; } if (asprintf(&filter, "(&(%s=%s)(objectclass=%s))", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), escape_domain_name, LDAP_OBJ_DOMINFO) < 0) { TALLOC_FREE(escape_domain_name); return NT_STATUS_NO_MEMORY; } TALLOC_FREE(escape_domain_name); attr_list = get_attr_list(NULL, dominfo_attr_list ); rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result); TALLOC_FREE( attr_list ); SAFE_FREE(filter); if (rc != LDAP_SUCCESS) { return NT_STATUS_UNSUCCESSFUL; } num_result = ldap_count_entries(ldap_state->ldap_struct, result); if (num_result > 1) { DEBUG (0, ("add_new_domain_info: More than domain with that name exists: bailing " "out!\n")); ldap_msgfree(result); return NT_STATUS_UNSUCCESSFUL; } /* Check if we need to add an entry */ DEBUG(3,("add_new_domain_info: Adding new domain\n")); /* this time escape for DN */ escape_domain_name = escape_rdn_val_string_alloc(domain_name); if (!escape_domain_name) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; } if (asprintf(&dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), escape_domain_name, lp_ldap_suffix(talloc_tos())) < 0) { SAFE_FREE(escape_domain_name); return NT_STATUS_NO_MEMORY; } SAFE_FREE(escape_domain_name); /* Free original search */ ldap_msgfree(result); /* make the changes - the entry *must* not already have samba * attributes */ smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), domain_name); /* If we don't have an entry, then ask secrets.tdb for what it thinks. It may choose to make it up */ sid_to_fstring(sid_string, get_global_sam_sid()); smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), sid_string); slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string) - 1, "%i", algorithmic_rid_base()); smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE), algorithmic_rid_base_string); smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO); /* add the sambaNextUserRid attributes. */ { uint32 rid = BASE_RID; fstring rid_str; fstr_sprintf( rid_str, "%i", rid ); DEBUG(10,("add_new_domain_info: setting next available user rid [%s]\n", rid_str)); smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), rid_str); } rc = smbldap_add(ldap_state, dn, mods); if (rc!=LDAP_SUCCESS) { char *ld_error = NULL; ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); DEBUG(1,("add_new_domain_info: failed to add domain dn= %s with: %s\n\t%s\n", dn, ldap_err2string(rc), ld_error?ld_error:"unknown")); SAFE_FREE(ld_error); SAFE_FREE(dn); ldap_mods_free(mods, True); return NT_STATUS_UNSUCCESSFUL; } DEBUG(2,("add_new_domain_info: added: domain = %s in the LDAP database\n", domain_name)); ldap_mods_free(mods, True); SAFE_FREE(dn); return NT_STATUS_OK; }