/*********************************************************************** * ldap_create_sort_controlW (WLDAP32.@) * * Create a control for server sorted search results. * * PARAMS * ld [I] Pointer to an LDAP context. * sortkey [I] Array of LDAPSortKey structures, each specifying an * attribute to use as a sort key, a matching rule and * the sort order (ascending or descending). * critical [I] Tells the server this control is critical to the * search operation. * control [O] LDAPControl created. * * RETURNS * Success: LDAP_SUCCESS * Failure: An LDAP error code. * * NOTES * Pass the created control as a server control in subsequent calls * to ldap_search_ext(_s) to obtain sorted search results. */ ULONG CDECL ldap_create_sort_controlW( WLDAP32_LDAP *ld, PLDAPSortKeyW *sortkey, UCHAR critical, PLDAPControlW *control ) { ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; #ifdef HAVE_LDAP LDAPSortKey **sortkeyU = NULL; LDAPControl *controlU = NULL; TRACE( "(%p, %p, 0x%02x, %p)\n", ld, sortkey, critical, control ); if (!ld || !sortkey || !control) return WLDAP32_LDAP_PARAM_ERROR; sortkeyU = sortkeyarrayWtoU( sortkey ); if (!sortkeyU) return WLDAP32_LDAP_NO_MEMORY; ret = map_error( ldap_create_sort_control( ld, sortkeyU, critical, &controlU )); *control = controlUtoW( controlU ); if (!*control) ret = WLDAP32_LDAP_NO_MEMORY; ldap_control_free( controlU ); sortkeyarrayfreeU( sortkeyU ); #endif return ret; }
/** Clear and free any controls associated with a connection * * @param conn to clear controls from. */ void fr_ldap_control_clear(fr_ldap_connection_t *conn) { int i; for (i = 0; i < conn->serverctrls_cnt; i++) { if (conn->serverctrls[i].freeit) ldap_control_free(conn->serverctrls[i].control); conn->serverctrls[i].freeit = false; conn->serverctrls[i].control = NULL; } conn->serverctrls_cnt = 0; for (i = 0; i < conn->clientctrls_cnt; i++) { if (conn->clientctrls[i].freeit) ldap_control_free(conn->clientctrls[i].control); conn->clientctrls[i].freeit = false; conn->clientctrls[i].control = NULL; } conn->clientctrls_cnt = 0; }
/* * controlType = LDAP_CONTROL_GET_EFFECTIVE_RIGHTS; * criticality = n/a; * controlValue = OCTET STRING of BER encoding of the SEQUENCE of * ENUMERATED LDAP code */ void _ger_set_response_control ( Slapi_PBlock *pb, int iscritical, int rc ) { LDAPControl **resultctrls = NULL; LDAPControl gerrespctrl; BerElement *ber = NULL; struct berval *berval = NULL; int found = 0; int i; if ( (ber = der_alloc ()) == NULL ) { goto bailout; } /* begin sequence, enumeration, end sequence */ ber_printf ( ber, "{e}", rc ); if ( ber_flatten ( ber, &berval ) != LDAP_SUCCESS ) { goto bailout; } gerrespctrl.ldctl_oid = LDAP_CONTROL_GET_EFFECTIVE_RIGHTS; gerrespctrl.ldctl_iscritical = iscritical; gerrespctrl.ldctl_value.bv_val = berval->bv_val; gerrespctrl.ldctl_value.bv_len = berval->bv_len; slapi_pblock_get ( pb, SLAPI_RESCONTROLS, &resultctrls ); for (i = 0; resultctrls && resultctrls[i]; i++) { if (strcmp(resultctrls[i]->ldctl_oid, LDAP_CONTROL_GET_EFFECTIVE_RIGHTS) == 0) { /* * We get here if search returns more than one entry * and this is not the first entry. */ ldap_control_free ( resultctrls[i] ); resultctrls[i] = slapi_dup_control (&gerrespctrl); found = 1; break; } } if ( !found ) { /* slapi_pblock_set() will dup the control */ slapi_pblock_set ( pb, SLAPI_ADD_RESCONTROL, &gerrespctrl ); } bailout: ber_free ( ber, 1 ); /* ber_free() checks for NULL param */ ber_bvfree ( berval ); /* ber_bvfree() checks for NULL param */ }
void ldap_controls_free (LDAPControl **ctrls) { int i; if (ctrls == NULL) return; for (i = 0; ctrls[i] != NULL; i++){ ldap_control_free(ctrls[i]); } free((char *)ctrls); }
void LDAP_CALL ldap_controls_free( LDAPControl **ctrls ) { int i; if ( ctrls != NULL ) { for ( i = 0; ctrls[i] != NULL; i++ ) { ldap_control_free( ctrls[i] ); } NSLDAPI_FREE( (char *)ctrls ); } }
/* * Free an array of LDAPControl's */ void ldap_controls_free( LDAPControl **controls ) { LDAP_MEMORY_DEBUG_ASSERT( controls != NULL ); if ( controls != NULL ) { int i; for( i=0; controls[i] != NULL; i++) { ldap_control_free( controls[i] ); } LDAP_FREE( controls ); } }
/* * Free an array of LDAPControl's */ void ldap_controls_free( LDAPControl **controls ) { #ifdef LDAP_MEMORY_DEBUG assert( controls != NULL ); #endif if ( controls != NULL ) { int i; for( i=0; controls[i] != NULL; i++) { ldap_control_free( controls[i] ); } LDAP_FREE( controls ); } }
/* * Free a persistent search node (and everything it holds). */ static void pe_ch_free( PSEQNode **pe ) { if ( pe != NULL && *pe != NULL ) { if ( (*pe)->pe_entry != NULL ) { slapi_entry_free( (*pe)->pe_entry ); (*pe)->pe_entry = NULL; } if ( (*pe)->pe_ctrls[0] != NULL ) { ldap_control_free( (*pe)->pe_ctrls[0] ); (*pe)->pe_ctrls[0] = NULL; } slapi_ch_free( (void **)pe ); } }
int _ldap_bind(LDAP *ld, ldap_conndata_t *info, char ppolicy, LDAPMessage *result, int *msgid) { int rc; LDAPControl **server_ctrls = NULL; LDAPControl *ppolicy_ctrl = NULL; struct berval passwd; DEBUG("_ldap_bind (ld:%p, info:%p, ppolicy:%d, result:%p, msgid:%d)", ld, info, ppolicy, result, *msgid); if (ppolicy == 1) { rc = ldap_create_passwordpolicy_control(ld, &ppolicy_ctrl); if (rc != LDAP_SUCCESS) return rc; server_ctrls = (LDAPControl **)malloc(sizeof(LDAPControl *) * (1 + 1)); if (server_ctrls == NULL) return LDAP_NO_MEMORY; server_ctrls[0] = ppolicy_ctrl; server_ctrls[1] = NULL; } /* Mechanism is set, use SASL interactive bind. */ if (strcmp(info->mech, "SIMPLE") != 0) { if (info->passwd == NULL) info->passwd = ""; rc = ldap_sasl_interactive_bind(ld, info->binddn, info->mech, server_ctrls, NULL, LDAP_SASL_QUIET, sasl_interact, info, result, &(info->rmech), msgid); } else { if (info->passwd == NULL) { passwd.bv_len = 0; } else { passwd.bv_len = strlen(info->passwd); } passwd.bv_val = info->passwd; rc = ldap_sasl_bind(ld, info->binddn, LDAP_SASL_SIMPLE, &passwd, server_ctrls, NULL, msgid); } if (ppolicy_ctrl != NULL) ldap_control_free(ppolicy_ctrl); free(server_ctrls); ldap_msgfree(result); return rc; }
/*********************************************************************** * ldap_create_vlv_controlW (WLDAP32.@) * * Create a virtual list view control. * * PARAMS * ld [I] Pointer to an LDAP context. * info [I] LDAPVLVInfo structure specifying a list view window. * critical [I] Tells the server this control is critical to the * search operation. * control [O] LDAPControl created. * * RETURNS * Success: LDAP_SUCCESS * Failure: An LDAP error code. * * NOTES * Pass the created control in conjunction with a sort control as * server controls in subsequent calls to ldap_search_ext(_s). The * server will then return a sorted, contiguous subset of results * that meets the criteria specified in the LDAPVLVInfo structure. */ INT CDECL ldap_create_vlv_controlW( WLDAP32_LDAP *ld, WLDAP32_LDAPVLVInfo *info, UCHAR critical, LDAPControlW **control ) { INT ret = WLDAP32_LDAP_NOT_SUPPORTED; #ifdef HAVE_LDAP LDAPControl *controlU = NULL; TRACE( "(%p, %p, 0x%02x, %p)\n", ld, info, critical, control ); if (!ld || !control) return ~0u; ret = map_error( ldap_create_vlv_control( ld, (LDAPVLVInfo *)info, &controlU )); if (ret == WLDAP32_LDAP_SUCCESS) { *control = controlUtoW( controlU ); if (!*control) ret = WLDAP32_LDAP_NO_MEMORY; ldap_control_free( controlU ); } #endif return ret; }
int main( int argc, char **argv ) { LDAP *ld; LDAPMessage *result, *e; char *attrfail, *matched = NULL, *errmsg = NULL; char **vals, **referrals; int rc, parse_rc, version; unsigned long sortrc; LDAPControl *sortctrl = NULL; LDAPControl *requestctrls[ 2 ]; LDAPControl **resultctrls = NULL; LDAPsortkey **sortkeylist; /* Arrange for all connections to use LDAPv3 */ version = LDAP_VERSION3; if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version ) != 0 ) { fprintf( stderr, "ldap_set_option protocol version to %d failed\n", version ); return( 1 ); } /* Get a handle to an LDAP connection */ if ( (ld = ldap_init( MY_HOST, MY_PORT ) ) == NULL ) { perror( "ldap_init" ); return( 1 ); } /* Authenticate as Directory Manager */ if ( ldap_simple_bind_s( ld, MGR_DN, MGR_PW ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_simple_bind_s" ); ldap_unbind( ld ); return( 1 ); } /* * Create a sort key list that specifies the sort order of the results. * Sort the results by last name first, then by first name. */ ldap_create_sort_keylist( &sortkeylist, "description -givenname" ); /* Create the sort control. */ rc = ldap_create_sort_control( ld, sortkeylist, 1, &sortctrl ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_create_sort_control: %s\n", ldap_err2string( rc ) ); ldap_unbind( ld ); return( 1 ); } requestctrls[ 0 ] = sortctrl; requestctrls[ 1 ] = NULL; /* Search for all entries in Sunnyvale */ rc = ldap_search_ext_s( ld, PEOPLE_BASE, LDAP_SCOPE_SUBTREE, "(objectclass=person)", NULL, 0, requestctrls, NULL, NULL, 0, &result ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) ); ldap_unbind( ld ); return( 1 ); } parse_rc = ldap_parse_result( ld, result, &rc, &matched, &errmsg, &referrals, &resultctrls, 0 ); if ( parse_rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_parse_result: %s\n", ldap_err2string( parse_rc ) ); ldap_unbind( ld ); return( 1 ); } if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) ); if ( errmsg != NULL && *errmsg != '\0' ) { fprintf( stderr, "%s\n", errmsg ); } ldap_unbind( ld ); return( 1 ); } parse_rc = ldap_parse_sort_control( ld, resultctrls, &sortrc, &attrfail ); if ( parse_rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_parse_sort_control: %s\n", ldap_err2string( parse_rc ) ); ldap_unbind( ld ); return( 1 ); } if ( sortrc != LDAP_SUCCESS ) { fprintf( stderr, "Sort error: %s\n", ldap_err2string( sortrc )); if ( attrfail != NULL && *attrfail != '\0' ) { fprintf( stderr, "Bad attribute: %s\n", attrfail); } ldap_unbind( ld ); return( 1 ); } /* for each entry print out name + all attrs and values */ for ( e = ldap_first_entry( ld, result ); e != NULL; e = ldap_next_entry( ld, e ) ) { if ((vals = ldap_get_values( ld, e, "sn")) != NULL ) { if ( vals[0] != NULL ) { printf( "%s", vals[0] ); } ldap_value_free( vals ); } if ((vals = ldap_get_values( ld, e, "givenname")) != NULL ) { if ( vals[0] != NULL ) { printf( "\t%s", vals[0] ); } ldap_value_free( vals ); } putchar( '\n' ); } ldap_msgfree( result ); ldap_free_sort_keylist( sortkeylist ); ldap_control_free( sortctrl ); ldap_controls_free( resultctrls ); ldap_unbind( ld ); return( 0 ); }
DWORD LwLdapDirectoryExtendedDNSearch( IN HANDLE hDirectory, IN PCSTR pszObjectDN, IN PCSTR pszQuery, IN PSTR* ppszAttributeList, IN int scope, OUT LDAPMessage** ppMessage ) { DWORD dwError = LW_ERROR_SUCCESS; CHAR ExtDNCriticality = 'T'; LDAPControl *pExtDNControl = NULL; LDAPControl *ppInputControls[2] = { NULL, NULL }; LDAPMessage* pMessage = NULL; struct berval value = {0}; // Setup the extended DN control, in order to be windows 2000 compatible, // Do not specify control value, hence, the return result will always be in hexadecimal string format. value.bv_len = 0; value.bv_val = NULL; dwError = ldap_control_create(LDAP_CONTROL_X_EXTENDED_DN, ExtDNCriticality, &value, 0, &pExtDNControl); BAIL_ON_LDAP_ERROR(dwError); ppInputControls[0] = pExtDNControl; dwError = LwLdapDirectorySearchEx( hDirectory, pszObjectDN, scope, pszQuery, ppszAttributeList, ppInputControls, 0, &pMessage); BAIL_ON_LW_ERROR(dwError); LW_ASSERT(pMessage != NULL); *ppMessage = pMessage; cleanup: ppInputControls[0] = NULL; if (pExtDNControl) { ldap_control_free(pExtDNControl); } return (dwError); error: if (pMessage) { ldap_msgfree(pMessage); } *ppMessage = NULL; goto cleanup; }
/* * controlType = LDAP_CONTROL_PAGEDRESULTS; * criticality = n/a; * controlValue: * realSearchControlValue ::= SEQUENCE { * size INTEGER (0..maxInt), * -- requested page size from client * -- result set size estimate from server * cookie OCTET STRING * } */ void pagedresults_set_response_control( Slapi_PBlock *pb, int iscritical, ber_int_t estimate, int current_search_count, int index ) { LDAPControl **resultctrls = NULL; LDAPControl pr_respctrl; BerElement *ber = NULL; struct berval *berval = NULL; char *cookie_str = NULL; int found = 0; int i; LDAPDebug1Arg(LDAP_DEBUG_TRACE, "--> pagedresults_set_response_control: idx=%d\n", index); if ( (ber = der_alloc()) == NULL ) { goto bailout; } /* begin sequence, payload, end sequence */ if (current_search_count < 0) { cookie_str = slapi_ch_strdup(""); } else { cookie_str = slapi_ch_smprintf("%d", index); } ber_printf ( ber, "{io}", estimate, cookie_str, strlen(cookie_str) ); if ( ber_flatten ( ber, &berval ) != LDAP_SUCCESS ) { goto bailout; } pr_respctrl.ldctl_oid = LDAP_CONTROL_PAGEDRESULTS; pr_respctrl.ldctl_iscritical = iscritical; pr_respctrl.ldctl_value.bv_val = berval->bv_val; pr_respctrl.ldctl_value.bv_len = berval->bv_len; slapi_pblock_get ( pb, SLAPI_RESCONTROLS, &resultctrls ); for (i = 0; resultctrls && resultctrls[i]; i++) { if (strcmp(resultctrls[i]->ldctl_oid, LDAP_CONTROL_PAGEDRESULTS) == 0) { /* * We get here if search returns more than one entry * and this is not the first entry. */ ldap_control_free ( resultctrls[i] ); resultctrls[i] = slapi_dup_control (&pr_respctrl); found = 1; break; } } if ( !found ) { /* slapi_pblock_set() will dup the control */ slapi_pblock_set ( pb, SLAPI_ADD_RESCONTROL, &pr_respctrl ); } bailout: slapi_ch_free_string(&cookie_str); ber_free ( ber, 1 ); /* ber_free() checks for NULL param */ ber_bvfree ( berval ); /* ber_bvfree() checks for NULL param */ LDAPDebug1Arg(LDAP_DEBUG_TRACE, "<-- pagedresults_set_response_control: idx=%d\n", index); }
krb5_error_code ipadb_deref_search(struct ipadb_context *ipactx, char *base_dn, int scope, char *filter, char **entry_attrs, char **deref_attr_names, char **deref_attrs, LDAPMessage **res) { struct berval derefval = { 0, NULL }; LDAPControl *ctrl[2] = { NULL, NULL }; LDAPDerefSpec *ds; krb5_error_code kerr; int times; int ret; int c, i; bool retry; for (c = 0; deref_attr_names[c]; c++) { /* count */ ; } ds = calloc(c+1, sizeof(LDAPDerefSpec)); if (!ds) { return ENOMEM; } for (i = 0; deref_attr_names[i]; i++) { ds[i].derefAttr = deref_attr_names[i]; ds[i].attributes = deref_attrs; } ds[c].derefAttr = NULL; ret = ldap_create_deref_control_value(ipactx->lcontext, ds, &derefval); if (ret != LDAP_SUCCESS) { kerr = ENOMEM; goto done; } ret = ldap_control_create(LDAP_CONTROL_X_DEREF, 1, &derefval, 1, &ctrl[0]); if (ret != LDAP_SUCCESS) { kerr = ENOMEM; goto done; } /* retry once if connection errors (tot. max. 2 tries) */ times = 2; ret = LDAP_SUCCESS; retry = true; while (retry) { times--; ret = ipadb_check_connection(ipactx); if (ret != 0) break; ret = ldap_search_ext_s(ipactx->lcontext, base_dn, scope, filter, entry_attrs, 0, ctrl, NULL, &std_timeout, LDAP_NO_LIMIT, res); retry = ipadb_need_retry(ipactx, ret) && times > 0; if (retry) { /* Free result before next try */ ldap_msgfree(*res); } } kerr = ipadb_simple_ldap_to_kerr(ret); done: ldap_control_free(ctrl[0]); ldap_memfree(derefval.bv_val); free(ds); return kerr; }
DWORD LwLdapDirectoryOnePagedSearch( HANDLE hDirectory, PCSTR pszObjectDN, PCSTR pszQuery, PSTR* ppszAttributeList, DWORD dwPageSize, PLW_SEARCH_COOKIE pCookie, int scope, LDAPMessage** ppMessage ) { DWORD dwError = LW_ERROR_SUCCESS; PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL; ber_int_t pageCount = 0; CHAR pagingCriticality = 'T'; LDAPControl *pPageControl = NULL; LDAPControl *ppInputControls[2] = { NULL, NULL }; LDAPControl **ppReturnedControls = NULL; int errorcodep = 0; LDAPMessage* pMessage = NULL; BOOLEAN bSearchFinished = FALSE; struct berval * pBerCookie = (struct berval *)pCookie->pvData; LW_ASSERT(pCookie->pfnFree == NULL || pCookie->pfnFree == LwLdapFreeCookie); pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory; // dwError = ADEnablePageControlOption(hDirectory); // BAIL_ON_LW_ERROR(dwError); dwError = ldap_create_page_control(pDirectory->ld, dwPageSize, pBerCookie, pagingCriticality, &pPageControl); BAIL_ON_LDAP_ERROR(dwError); ppInputControls[0] = pPageControl; dwError = LwLdapDirectorySearchEx( hDirectory, pszObjectDN, scope, pszQuery, ppszAttributeList, ppInputControls, 0, &pMessage); BAIL_ON_LW_ERROR(dwError); dwError = ldap_parse_result(pDirectory->ld, pMessage, &errorcodep, NULL, NULL, NULL, &ppReturnedControls, 0); BAIL_ON_LDAP_ERROR(dwError); if (pBerCookie != NULL) { ber_bvfree(pBerCookie); pBerCookie = NULL; } dwError = ldap_parse_page_control(pDirectory->ld, ppReturnedControls, &pageCount, &pBerCookie); BAIL_ON_LDAP_ERROR(dwError); if (pBerCookie == NULL || pBerCookie->bv_len < 1) { bSearchFinished = TRUE; } if (ppReturnedControls) { ldap_controls_free(ppReturnedControls); ppReturnedControls = NULL; } ppInputControls[0] = NULL; ldap_control_free(pPageControl); pPageControl = NULL; pCookie->bSearchFinished = bSearchFinished; *ppMessage = pMessage; pCookie->pvData = pBerCookie; pCookie->pfnFree = LwLdapFreeCookie; cleanup: /* dwError_disable = ADDisablePageControlOption(hDirectory); if (dwError_disable) LW_RTL_LOG_ERROR("Error: LDAP Disable PageControl Info: failed");*/ if (ppReturnedControls) { ldap_controls_free(ppReturnedControls); } ppInputControls[0] = NULL; if (pPageControl) { ldap_control_free(pPageControl); } return (dwError); error: *ppMessage = NULL; pCookie->pvData = NULL; pCookie->pfnFree = NULL; pCookie->bSearchFinished = TRUE; if (pBerCookie != NULL) { ber_bvfree(pBerCookie); pBerCookie = NULL; } goto cleanup; }
/* * Check if there are any persistent searches. If so, * the check to see if the chgtype is one of those the * client is interested in. If so, then check to see if * the entry matches any of the filters the searches. * If so, then enqueue the entry on that persistent search's * ps_entryqueue and signal it to wake up and send the entry. * * Note that if eprev is NULL we assume that the entry's DN * was not changed by the op. that called this function. If * chgnum is 0 it is unknown so we won't ever send it to a * client in the EntryChangeNotification control. */ void ps_service_persistent_searches( Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype, ber_int_t chgnum ) { LDAPControl *ctrl = NULL; PSearch *ps = NULL; PSEQNode *pe = NULL; int matched = 0; const char *edn; if ( !PS_IS_INITIALIZED()) { return; } if ( NULL == e ) { /* For now, some backends such as the chaining backend do not provide a post-op entry */ return; } PSL_LOCK_READ(); edn = slapi_entry_get_dn_const(e); for ( ps = psearch_list ? psearch_list->pl_head : NULL; NULL != ps; ps = ps->ps_next ) { char *origbase = NULL; Slapi_DN *base = NULL; Slapi_Filter *f; int scope; /* Skip the node that doesn't meet the changetype, * or is unable to use the change in ps_send_results() */ if (( ps->ps_changetypes & chgtype ) == 0 || ps->ps_pblock->pb_op == NULL || slapi_op_abandoned( ps->ps_pblock ) ) { continue; } slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search", "conn=%" NSPRIu64 " op=%d entry %s with chgtype %d " "matches the ps changetype %d\n", ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid, edn, chgtype, ps->ps_changetypes); slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_FILTER, &f ); slapi_pblock_get( ps->ps_pblock, SLAPI_ORIGINAL_TARGET_DN, &origbase ); slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_TARGET_SDN, &base ); slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_SCOPE, &scope ); if (NULL == base) { base = slapi_sdn_new_dn_byref(origbase); slapi_pblock_set(ps->ps_pblock, SLAPI_SEARCH_TARGET_SDN, base); } /* * See if the entry meets the scope and filter criteria. * We cannot do the acl check here as this thread * would then potentially clash with the ps_send_results() * thread on the aclpb in ps->ps_pblock. * By avoiding the acl check in this thread, and leaving all the acl * checking to the ps_send_results() thread we avoid * the ps_pblock contention problem. * The lesson here is "Do not give multiple threads arbitary access * to the same pblock" this kind of muti-threaded access * to the same pblock must be done carefully--there is currently no * generic satisfactory way to do this. */ if ( slapi_sdn_scope_test( slapi_entry_get_sdn_const(e), base, scope ) && slapi_vattr_filter_test( ps->ps_pblock, e, f, 0 /* verify_access */ ) == 0 ) { PSEQNode *pOldtail; /* The scope and the filter match - enqueue it */ matched++; pe = (PSEQNode *)slapi_ch_calloc( 1, sizeof( PSEQNode )); pe->pe_entry = slapi_entry_dup( e ); if ( ps->ps_send_entchg_controls ) { /* create_entrychange_control() is more * expensive than slapi_dup_control() */ if ( ctrl == NULL ) { int rc; rc = create_entrychange_control( chgtype, chgnum, eprev ? slapi_entry_get_dn_const(eprev) : NULL, &ctrl ); if ( rc != LDAP_SUCCESS ) { LDAPDebug( LDAP_DEBUG_ANY, "ps_service_persistent_searches:" " unable to create EntryChangeNotification control for" " entry \"%s\" -- control won't be sent.\n", slapi_entry_get_dn_const(e), 0, 0 ); } } if ( ctrl ) { pe->pe_ctrls[0] = slapi_dup_control( ctrl ); } } /* Put it on the end of the list for this pers search */ PR_Lock( ps->ps_lock ); pOldtail = ps->ps_eq_tail; ps->ps_eq_tail = pe; if ( NULL == ps->ps_eq_head ) { ps->ps_eq_head = ps->ps_eq_tail; } else { pOldtail->pe_next = ps->ps_eq_tail; } PR_Unlock( ps->ps_lock ); } } PSL_UNLOCK_READ(); /* Were there any matches? */ if ( matched ) { ldap_control_free( ctrl ); /* Turn 'em loose */ ps_wakeup_all(); LDAPDebug( LDAP_DEBUG_TRACE, "ps_service_persistent_searches: enqueued entry " "\"%s\" on %d persistent search lists\n", slapi_entry_get_dn_const(e), matched, 0 ); } else { LDAPDebug( LDAP_DEBUG_TRACE, "ps_service_persistent_searches: entry " "\"%s\" not enqueued on any persistent search lists\n", slapi_entry_get_dn_const(e), 0, 0 ); } }
int main( int argc, char **argv ) { LDAP *ld; LDAPMessage *result, *e; BerElement *ber; char *a, *dn; char **vals; int i; int rc; int finished; int msgid; int num_entries = 0; int version = LDAP_VERSION3; LDAPControl *ctrls[2], *psctrl, **ectrls; /* arrange to use LDAP version 3 */ if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version ) != 0 ) { perror( "ldap_set_option" ); return( 1 ); } /* get a handle to an LDAP connection */ if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) { perror( "ldap_init" ); return( 1 ); } /* authenticate to the directory as nobody */ if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_simple_bind_s" ); ldap_unbind( ld ); return( 1 ); } /* construct the Persistent Search control */ if ( ldap_create_persistentsearch_control( ld, LDAP_CHANGETYPE_ANY, 1 /* changesOnly */, 1 /* request entry change controls */, 1 /* critical */, &psctrl ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_create_persistentsearch_control" ); ldap_unbind( ld ); return( 1 ); } ctrls[0] = psctrl; ctrls[1] = NULL; /* issue a persistent search for all entries with surname of Jensen */ if ( LDAP_SUCCESS != ldap_search_ext( ld, MY_SEARCHBASE, LDAP_SCOPE_SUBTREE, MY_FILTER, NULL /* all attrs */, 0 /* get attrs and values */, ctrls, NULL /* no client ctrls */, NULL /* no timeout */, 0 /* no sizelimit */, &msgid )) { ldap_perror( ld, "ldap_search_ext" ); ldap_unbind( ld ); return( 1 ); } ldap_control_free( psctrl ); /* no longer needed */ /* * Loop, polling for results until finished. * Since this is a persistent search, this loop won't end until the * server shuts down or we lose the connection for some other reason. * We could abandon the persistent search or close the connection of * course, but we don't in this example. */ finished = 0; while ( !finished ) { /* * Poll for results. We call ldap_result with the "all" argument * set to LDAP_MSG_ONE. This causes ldap_result() to return exactly one * entry if at least one entry is available. This allows us to * display the entries as they are received. */ result = NULL; rc = ldap_result( ld, msgid, LDAP_MSG_ONE, NULL /* no timeout */, &result ); switch ( rc ) { case -1: /* some error occurred */ ldap_perror( ld, "ldap_result" ); ldap_unbind( ld ); return( 1 ); case 0: /* Timeout was exceeded. No entries are ready for retrieval. */ if ( result != NULL ) { ldap_msgfree( result ); } break; default: /* * Either an entry is ready for retrieval, or all entries have * been retrieved. */ if (( e = ldap_first_entry( ld, result )) == NULL ) { /* All done */ finished = 1; if ( result != NULL ) { ldap_msgfree( result ); } continue; } num_entries++; /* for each entry print out name */ if (( dn = ldap_get_dn( ld, e )) != NULL ) { printf( "dn: %s\n", dn ); ldap_memfree( dn ); } /* print entry change info. if it was returned */ if ( LDAP_SUCCESS == ldap_get_entry_controls( ld, e, &ectrls )) { int chgnumpresent; ber_int_t chgtype; ber_int_t chgnum; char *prevdn; if ( LDAP_SUCCESS == ldap_parse_entrychange_control( ld, ectrls, &chgtype, &prevdn, &chgnumpresent, &chgnum )) { printf( "changeType: %s\n", changetype_num2string( chgtype )); if ( prevdn != NULL ) { printf( "previousDN: %s\n", prevdn ); ldap_memfree( prevdn ); } if ( chgnumpresent ) { printf( "changeNumber: %d\n", chgnum ); } ldap_controls_free( ectrls ); } } /* print out all attrs and values */ for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL; a = ldap_next_attribute( ld, e, ber ) ) { if (( vals = ldap_get_values( ld, e, a )) != NULL ) { for ( i = 0; vals[ i ] != NULL; i++ ) { printf( "%s: %s\n", a, vals[ i ] ); } ldap_value_free( vals ); } ldap_memfree( a ); } if ( ber != NULL ) { ber_free( ber, 0 ); } printf( "\n" ); ldap_msgfree( result ); } } /* All done. Print a summary. */ printf( "%d entries retrieved.\n", num_entries ); ldap_unbind( ld ); return( 0 ); }
int main( int argc, char **argv ) { int version; LDAP *ld; int rc; LDAPControl *gerctrl = NULL; LDAPControl *requestctrls[ 2 ]; char *authzid; char **attrlist; LDAPMessage *result; LDAPMessage *entry; char *attr; BerElement *ber; char **vals; int i; /* Use LDAPv3. */ version = LDAP_VERSION3; if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version ) != 0 ) { fprintf( stderr, "ldap_set_option protocol version to %d failed\n", version ); return ( 1 ); } /* Get a handle to an LDAP connection. */ if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) { perror( "ldap_init" ); return( 1 ); } /* Authenticate to the directory as a user. */ if ( ldap_simple_bind_s( ld, USER_DN, USER_PW ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_simple_bind_s" ); return( 1 ); } /* Create a get effective rights control. */ authzid = "dn: uid=kvaughan,ou=people,dc=example,dc=com"; if ( !( attrlist = (char**)malloc(sizeof(char * [ 2 ]) ) ) ) { perror( "malloc" ); ldap_unbind( ld ); return ( 1 ); } attrlist[ 0 ] = "aclRights"; attrlist[ 1 ] = NULL; rc = ldap_create_geteffectiveRights_control( ld, authzid, (const char **)&attrlist, 1, &gerctrl ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_create_geteffectiveRights_control: %s\n", ldap_err2string( rc ) ); ldap_unbind( ld ); return( 1 ); } requestctrls[ 0 ] = gerctrl; requestctrls[ 1 ] = NULL; /* Read an entry using the control. */ rc = ldap_search_ext_s( ld, ENTRYDN, LDAP_SCOPE_BASE, "(objectclass=*)", attrlist, 0, requestctrls, NULL, NULL, 0, &result ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) ); ldap_unbind( ld ); return( 1 ); } /* Examine the entry for effective rights. */ printf( "Bind DN: %s\n", ENTRYDN ); printf( "Authz ID: %s\n", authzid ); printf( "***Rights***\n" ); for ( entry = ldap_first_entry( ld, result ); entry != NULL; entry = ldap_next_entry( ld, entry ) ) { for ( attr = ldap_first_attribute( ld, entry, &ber ); attr != NULL; attr = ldap_next_attribute ( ld, entry, ber) ) { if ( (vals = ldap_get_values( ld, entry, attr ) ) != NULL) { for ( i = 0; vals[i] != NULL; ++i ) { printf( "%s: %s\n", attr, vals[i] ); } ldap_value_free( vals ); } ldap_memfree( attr ); } if ( ber != NULL ) { ber_free( ber, 0 ); } } printf( "\n" ); ldap_msgfree( result ); ldap_control_free( gerctrl ); ldap_unbind( ld ); return( 0 ); }
/* LDAP search function for internal use. Returns a Python list of LDAPEntries. The `basestr` is the base DN of the searching, `scope` is the search scope (BASE|ONELEVEL|SUB), `filterstr` is the LDAP search filter string, `attrs` is a null-terminated string list of attributes' names to get only the selected attributes. If `attrsonly` is 1 get only attributes' name without values. If `firstonly` is 1, get only the first LDAP entry of the messages. The `timeout` is an integer of seconds for timelimit, `sizelimit` is a limit for size. */ PyObject * LDAPConnection_Searching(LDAPConnection *self, PyObject *iterator) { int rc; int num_of_ctrls = 0; LDAPMessage *res, *entry; PyObject *entrylist = NULL; LDAPEntry *entryobj = NULL; LDAPControl *page_ctrl = NULL; LDAPControl *sort_ctrl = NULL; LDAPControl **server_ctrls = NULL; LDAPControl **returned_ctrls = NULL; LDAPSearchIter *search_iter = (LDAPSearchIter *)iterator; entrylist = PyList_New(0); if (entrylist == NULL) { return PyErr_NoMemory(); } /* Check the number of server controls and allocate it. */ if (self->page_size > 1) num_of_ctrls++; if (self->sort_list != NULL) num_of_ctrls++; if (num_of_ctrls > 0) { server_ctrls = (LDAPControl **)malloc(sizeof(LDAPControl *) * (num_of_ctrls + 1)); if (server_ctrls == NULL) return PyErr_NoMemory(); num_of_ctrls = 0; } if (self->page_size > 1) { /* Create page control and add to the server controls. */ rc = ldap_create_page_control(self->ld, (ber_int_t)(self->page_size), search_iter->cookie, 0, &page_ctrl); if (rc != LDAP_SUCCESS) { PyErr_BadInternalCall(); return NULL; } server_ctrls[num_of_ctrls++] = page_ctrl; server_ctrls[num_of_ctrls] = NULL; } if (self->sort_list != NULL) { rc = ldap_create_sort_control(self->ld, self->sort_list, 0, &sort_ctrl); if (rc != LDAP_SUCCESS) { PyErr_BadInternalCall(); return NULL; } server_ctrls[num_of_ctrls++] = sort_ctrl; server_ctrls[num_of_ctrls] = NULL; } rc = ldap_search_ext_s(self->ld, search_iter->base, search_iter->scope, search_iter->filter, search_iter->attrs, search_iter->attrsonly, server_ctrls, NULL, search_iter->timeout, search_iter->sizelimit, &res); if (rc == LDAP_NO_SUCH_OBJECT) { return entrylist; } if (rc != LDAP_SUCCESS && rc != LDAP_PARTIAL_RESULTS) { Py_DECREF(entrylist); PyObject *ldaperror = get_error_by_code(rc); PyErr_SetString(ldaperror, ldap_err2string(rc)); Py_DECREF(ldaperror); return NULL; } rc = ldap_parse_result(self->ld, res, NULL, NULL, NULL, NULL, &returned_ctrls, 0); #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) if (search_iter->cookie != NULL && search_iter->cookie->bv_val != NULL) { ber_bvfree(search_iter->cookie); search_iter->cookie = NULL; } rc = ldap_parse_page_control(self->ld, returned_ctrls, NULL, &(search_iter->cookie)); #else rc = ldap_parse_pageresponse_control(self->ld, ldap_control_find(LDAP_CONTROL_PAGEDRESULTS, returned_ctrls, NULL), NULL, search_iter->cookie); #endif /* Iterate over the response LDAP messages. */ for (entry = ldap_first_entry(self->ld, res); entry != NULL; entry = ldap_next_entry(self->ld, entry)) { entryobj = LDAPEntry_FromLDAPMessage(entry, self); if (entryobj == NULL) { Py_DECREF(entrylist); return NULL; } if ((entryobj == NULL) || (PyList_Append(entrylist, (PyObject *)entryobj)) != 0) { Py_XDECREF(entryobj); Py_DECREF(entrylist); return PyErr_NoMemory(); } Py_DECREF(entryobj); } /* Cleanup. */ if (returned_ctrls != NULL) ldap_controls_free(returned_ctrls); if (page_ctrl != NULL) ldap_control_free(page_ctrl); if (sort_ctrl != NULL) ldap_control_free(sort_ctrl); if (server_ctrls != NULL) free(server_ctrls); ldap_msgfree(res); return entrylist; }
void _ldap_control_free(LDAPControl *ctrl) { ldap_control_free(ctrl); }
/** Add session controls to a connection as per draft-wahl-ldap-session * * @note the RFC states that the username identifier, must be the authenticated * user id, not the purported one. As order of operations is configurable, * we're going to leave that up to the server admin to satisfy that * requirement * * For once the RFC is pretty helpful about what should be inserted into the * various values, and maps out RADIUS attributes to formatOIDs, so none of * this is configurable. * * @param conn to add controls to. * @param request to draw attributes from. */ int fr_ldap_control_add_session_tracking(fr_ldap_connection_t *conn, REQUEST *request) { /* * The OpenLDAP guys didn't declare the formatOID parameter to * ldap_create_session_tracking_control as const *sigh*. */ static char username_oid[] = LDAP_CONTROL_X_SESSION_TRACKING_USERNAME; static char acctsessionid_oid[] = LDAP_CONTROL_X_SESSION_TRACKING_RADIUS_ACCT_SESSION_ID; static char acctmultisessionid_oid[] = LDAP_CONTROL_X_SESSION_TRACKING_RADIUS_ACCT_MULTI_SESSION_ID; int ret; char ipaddress[INET6_ADDRSTRLEN]; char *username = NULL; char *acctsessionid = NULL; char *acctmultisessionid = NULL; char *hostname; LDAPControl *username_control = NULL; LDAPControl *acctsessionid_control = NULL; LDAPControl *acctmultisessionid_control = NULL; struct berval tracking_id; fr_cursor_t cursor; VALUE_PAIR const *vp; memcpy(&hostname, main_config->name, sizeof(hostname)); /* const / non-const issues */ for (vp = fr_cursor_init(&cursor, &request->packet->vps); vp; vp = fr_cursor_next(&cursor)) { if (fr_dict_attr_is_top_level(vp->da)) switch (vp->da->attr) { case FR_NAS_IP_ADDRESS: case FR_NAS_IPV6_ADDRESS: fr_pair_value_snprint(ipaddress, sizeof(ipaddress), vp, '\0'); break; case FR_USER_NAME: memcpy(&username, &vp->vp_strvalue, sizeof(username)); break; case FR_ACCT_SESSION_ID: memcpy(&acctsessionid, &vp->vp_strvalue, sizeof(acctsessionid)); break; case FR_ACCT_MULTI_SESSION_ID: memcpy(&acctmultisessionid, &vp->vp_strvalue, sizeof(acctmultisessionid)); break; } } if (username) { tracking_id.bv_val = username; tracking_id.bv_len = talloc_array_length(username) - 1; ret = ldap_create_session_tracking_control(conn->handle, ipaddress, hostname, username_oid, &tracking_id, &username_control); if (ret != LDAP_SUCCESS) { REDEBUG("Failed creating username session tracking control: %s", ldap_err2string(ret)); error: if (username_control) ldap_control_free(username_control); if (acctsessionid_control) ldap_control_free(acctsessionid_control); if (acctmultisessionid_control) ldap_control_free(acctmultisessionid_control); return -1; } } if (acctsessionid) { tracking_id.bv_val = acctsessionid; tracking_id.bv_len = talloc_array_length(acctsessionid) - 1; ret = ldap_create_session_tracking_control(conn->handle, ipaddress, hostname, acctsessionid_oid, &tracking_id, &acctsessionid_control); if (ret != LDAP_SUCCESS) { REDEBUG("Failed creating acctsessionid session tracking control: %s", ldap_err2string(ret)); goto error; } } if (acctmultisessionid) { tracking_id.bv_val = acctmultisessionid; tracking_id.bv_len = talloc_array_length(acctmultisessionid) - 1; ret = ldap_create_session_tracking_control(conn->handle, ipaddress, hostname, acctmultisessionid_oid, &tracking_id, &acctmultisessionid_control); if (ret != LDAP_SUCCESS) { REDEBUG("Failed creating acctmultisessionid session tracking control: %s", ldap_err2string(ret)); goto error; } } if ((conn->serverctrls_cnt + 3) >= LDAP_MAX_CONTROLS) { REDEBUG("Insufficient space to add session tracking controls"); goto error; } if (username_control && (fr_ldap_control_add_server(conn, username_control, true) < 0)) goto error; if (acctsessionid_control && (fr_ldap_control_add_server(conn, acctsessionid_control, true) < 0)) { conn->serverctrls_cnt--; conn->serverctrls[conn->serverctrls_cnt].control = NULL; goto error; } if (acctmultisessionid_control && (fr_ldap_control_add_server(conn, acctmultisessionid_control, true) < 0)) { conn->serverctrls_cnt--; conn->serverctrls[conn->serverctrls_cnt].control = NULL; conn->serverctrls_cnt--; conn->serverctrls[conn->serverctrls_cnt].control = NULL; goto error; } return 0; }
/* This function scans the array of controls and updates the Repl_Agmt's Dirsync_Private if the dirsync control is found. */ void windows_private_update_dirsync_control(const Repl_Agmt *ra,LDAPControl **controls ) { Dirsync_Private *dp; int foundDirsyncControl; int i; LDAPControl *dirsync = NULL; BerElement *ber = NULL; ber_int_t hasMoreData; ber_int_t maxAttributeCount; BerValue *serverCookie = NULL; #ifdef FOR_DEBUGGING int return_value = LDAP_SUCCESS; #endif LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_update_dirsync_control\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); if (NULL != controls ) { foundDirsyncControl = 0; for ( i = 0; (( controls[i] != NULL ) && ( !foundDirsyncControl )); i++ ) { foundDirsyncControl = !strcmp( controls[i]->ldctl_oid, REPL_DIRSYNC_CONTROL_OID ); } if ( !foundDirsyncControl ) { #ifdef FOR_DEBUGGING return_value = LDAP_CONTROL_NOT_FOUND; #endif goto choke; } else if (!controls[i-1]->ldctl_value.bv_val) { #ifdef FOR_DEBUGGING return_value = LDAP_CONTROL_NOT_FOUND; #endif goto choke; } else { dirsync = slapi_dup_control( controls[i-1]); } ber = ber_init( &dirsync->ldctl_value ) ; if (ber_scanf( ber, "{iiO}", &hasMoreData, &maxAttributeCount, &serverCookie) == LBER_ERROR) { #ifdef FOR_DEBUGGING return_value = LDAP_CONTROL_NOT_FOUND; #endif goto choke; } slapi_ch_free_string(&dp->dirsync_cookie); dp->dirsync_cookie = ( char* ) slapi_ch_malloc(serverCookie->bv_len + 1); memcpy(dp->dirsync_cookie, serverCookie->bv_val, serverCookie->bv_len); dp->dirsync_cookie_len = (int) serverCookie->bv_len; /* XXX shouldn't cast? */ /* dp->dirsync_maxattributecount = maxAttributeCount; We don't need to keep this */ dp->dirsync_cookie_has_more = hasMoreData; choke: ber_bvfree(serverCookie); ber_free(ber,1); ldap_control_free(dirsync); } else { #ifdef FOR_DEBUGGING return_value = LDAP_CONTROL_NOT_FOUND; #endif } #ifdef FOR_DEBUGGING LDAPDebug1Arg( LDAP_DEBUG_TRACE, "<= windows_private_update_dirsync_control: rc=%d\n", return_value); #else LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_update_dirsync_control\n" ); #endif }