krb5_error_code ipadb_simple_search(struct ipadb_context *ipactx, char *basedn, int scope, char *filter, char **attrs, LDAPMessage **res) { int ret; ret = ipadb_check_connection(ipactx); if (ret != 0) return ipadb_simple_ldap_to_kerr(ret); ret = ldap_search_ext_s(ipactx->lcontext, basedn, scope, filter, attrs, 0, NULL, NULL, &std_timeout, LDAP_NO_LIMIT, res); /* first test if we need to retry to connect */ if (ret != 0 && ipadb_need_retry(ipactx, ret)) { ldap_msgfree(*res); ret = ldap_search_ext_s(ipactx->lcontext, basedn, scope, filter, attrs, 0, NULL, NULL, &std_timeout, LDAP_NO_LIMIT, res); } return ipadb_simple_ldap_to_kerr(ret); }
krb5_error_code ipadb_multibase_search(struct ipadb_context *ipactx, char **basedns, int scope, char *filter, char **attrs, struct ipadb_multires **res, bool any) { int ret; ret = ipadb_multires_init(ipactx->lcontext, res); if (ret != 0) return ret; ret = ipadb_check_connection(ipactx); if (ret != 0) return ipadb_simple_ldap_to_kerr(ret); for (int b = 0; basedns[b]; b++) { LDAPMessage *r; ret = ldap_search_ext_s(ipactx->lcontext, basedns[b], scope, filter, attrs, 0, NULL, NULL, &std_timeout, LDAP_NO_LIMIT, &r); /* first test if we need to retry to connect */ if (ret != 0 && ipadb_need_retry(ipactx, ret)) { ldap_msgfree(r); ret = ldap_search_ext_s(ipactx->lcontext, basedns[b], scope, filter, attrs, 0, NULL, NULL, &std_timeout, LDAP_NO_LIMIT, &r); } if (ret != 0) break; if (ldap_count_entries(ipactx->lcontext, r) > 0) { void *tmp = realloc((*res)->res, (((*res)->count + 1) * sizeof(LDAPMessage *))); if (tmp == NULL) { ret = ENOMEM; break; } (*res)->res = tmp; (*res)->res[(*res)->count] = r; (*res)->count++; if (any) break; } } if (ret != 0) { ipadb_multires_free(*res); *res = NULL; } return ipadb_simple_ldap_to_kerr(ret); }
krb5_error_code ipadb_simple_delete(struct ipadb_context *ipactx, char *dn) { int ret; ret = ldap_delete_ext_s(ipactx->lcontext, dn, NULL, NULL); /* first test if we need to retry to connect */ if (ret != 0 && ipadb_need_retry(ipactx, ret)) { ret = ldap_delete_ext_s(ipactx->lcontext, dn, NULL, NULL); } return ipadb_simple_ldap_to_kerr(ret); }
krb5_error_code ipadb_simple_modify(struct ipadb_context *ipactx, char *dn, LDAPMod **mods) { int ret; ret = ldap_modify_ext_s(ipactx->lcontext, dn, mods, NULL, NULL); /* first test if we need to retry to connect */ if (ret != 0 && ipadb_need_retry(ipactx, ret)) { ret = ldap_modify_ext_s(ipactx->lcontext, dn, mods, NULL, NULL); } return ipadb_simple_ldap_to_kerr(ret); }
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; }