📄 scldap.c
字号:
ctx->entry[i].base = NULL; for (j = 0; j < ctx->entry[i].numattrs; j++) { free(ctx->entry[i].attributes[j]); ctx->entry[i].attributes[j] = NULL; } if (ctx->entry[i].attributes) { free(ctx->entry[i].attributes); } ctx->entry[i].attributes = NULL; ctx->entry[i].numattrs = 0; if (ctx->entry[i].filter) { free(ctx->entry[i].filter); } ctx->entry[i].filter = NULL; break; } } } }}int scldap_is_valid_url(const char *url){ if (!url) return 0; return ldap_is_ldap_url((char *) url);}int scldap_url_to_entry(scldap_context * ctx, const char *entry, const char *url){ LDAPURLDesc *ldapurl = NULL; int rv, i, j; if (!ctx || !entry || !url) { return -1; } rv = ldap_url_parse((char *) url, &ldapurl); if (rv) { switch (rv) {#ifdef LDAP_URL_ERR_BADSCHEME case LDAP_URL_ERR_BADSCHEME: fprintf(stderr, "Not an LDAP URL: %s", url); break;#endif#ifdef LDAP_URL_ERR_BADENCLOSURE case LDAP_URL_ERR_BADENCLOSURE: fprintf(stderr, "Bad enclosure in URL: %s", url); break;#endif#ifdef LDAP_URL_ERR_BADURL case LDAP_URL_ERR_BADURL: fprintf(stderr, "Bad URL: %s", url); break;#endif#ifdef LDAP_URL_ERR_BADHOST case LDAP_URL_ERR_BADHOST: fprintf(stderr, "Host is invalid in URL: %s", url); break;#endif#ifdef LDAP_URL_ERR_BADATTRS case LDAP_URL_ERR_BADATTRS: fprintf(stderr, "Attributes are invalid in URL: %s", url); break;#endif#ifdef LDAP_URL_ERR_BADSCOPE case LDAP_URL_ERR_BADSCOPE: fprintf(stderr, "Scope is invalid in URL: %s", url); break;#endif#ifdef LDAP_URL_ERR_BADFILTER case LDAP_URL_ERR_BADFILTER: fprintf(stderr, "Filter is invalid in URL: %s", url); break;#endif#ifdef LDAP_URL_ERR_BADEXTS case LDAP_URL_ERR_BADEXTS: fprintf(stderr, "Extensions are invalid in URL: %s", url); break;#endif#ifdef LDAP_URL_ERR_MEM case LDAP_URL_ERR_MEM: fprintf(stderr, "Out of memory parsing URL: %s", url); break;#endif#ifdef LDAP_URL_ERR_PARAM case LDAP_URL_ERR_PARAM: fprintf(stderr, "Bad parameter parsing URL: %s", url); break;#endif default: fprintf(stderr, "Unknown error %d parsing URL: %s", rv, url); break; } return -1; } if (ldapurl) { scldap_remove_entry(ctx, entry); scldap_add_entry(ctx, entry); i = scldap_get_entry(ctx, entry);#define ADD(val) ((val) ? strdup(val) : NULL) ctx->entry[i].ldaphost = ADD(ldapurl->lud_host); ctx->entry[i].ldapport = ldapurl->lud_port; ctx->entry[i].scope = ldapurl->lud_scope; ctx->entry[i].base = ADD(ldapurl->lud_dn); for (j = 0; ldapurl->lud_attrs[j]; j++) { if (ctx->entry[i].numattrs >= SCLDAP_MAX_ATTRIBUTES) { break; } ctx->entry[i].attributes = (char **) realloc(ctx->entry[i].attributes, (ctx->entry[i].numattrs + 2) * sizeof(char *)); if (!ctx->entry[i].attributes) break; memset(&ctx->entry[i].attributes[ctx->entry[i].numattrs], 0, sizeof(char *)); ctx->entry[i].attributes[ctx->entry[i].numattrs] = strdup(ldapurl->lud_attrs[j]); ctx->entry[i].numattrs++; ctx->entry[i].attributes[ctx->entry[i].numattrs] = NULL; } ctx->entry[i].filter = ADD(ldapurl->lud_filter);#undef ADD ldap_free_urldesc(ldapurl); ldapurl = NULL; return 0; } return -1;}int scldap_approx_base_by_dn(scldap_context * ctx, const char *entry, const char *dn, char **base){ scldap_result *splitdn = NULL; unsigned int i = 0, j = 0, numdns = 0; char **founddns = NULL; if (!ctx || !entry || !dn) { return -1; } if (scldap_dn_to_result(dn, &splitdn, 0) < 0) { return -1; } for (i = 0; i < splitdn->results; i++) { scldap_result *result = NULL;#if 0 printf("%02i. %s [%li]\n", i + 1, splitdn->result[i].data, splitdn->result[i].datalen);#endif if (scldap_search(ctx, entry, &result, 0, (const char *) splitdn->result[i].data) < 0) { continue; } if (result) { for (j = 0; j < result->results; j++) { founddns = (char **) realloc(founddns, (numdns + 2) * sizeof(char *)); founddns[numdns] = strdup(result->result[j].dn); numdns++; founddns[numdns] = NULL; } scldap_free_result(result); } } scldap_free_result(splitdn); if (!numdns) { return -1; }#if 0 for (i = 0; i < numdns; i++) { printf("%02i. %s\n", i + 1, founddns[i]); }#endif if (*base) { free(*base); *base = NULL; } /* FIXME: Add proper logic to this */ *base = strdup(founddns[0]); for (i = 0; i < numdns; i++) { free(founddns[i]); } free(founddns); return 1;}int scldap_dn_to_result(const char *dn, scldap_result ** result, int notypes){ scldap_result *_result = NULL; char *buf = NULL, **tmp = NULL; unsigned int i; if (!dn || *result) return -1; _result = (scldap_result *) malloc(sizeof(scldap_result)); if (!_result) { return -1; } memset(_result, 0, sizeof(scldap_result));#if 0 printf("dn: %s\n", dn);#endif buf = (char *) malloc((strlen(dn) + 1) * 2); if (!buf) { free(_result); return -1; } memset(buf, 0, (strlen(dn) + 1) * 2); if (dn[0] == '/') { unsigned int c = 0; for (i = 1; i < strlen(dn); i++) { if (dn[i] == '/') { buf[c++] = ','; buf[c++] = ' '; } else { buf[c++] = dn[i]; } } } else { memcpy(buf, dn, strlen(dn)); }#if 0 printf("buf: %s\n", buf);#endif tmp = ldap_explode_dn(buf, notypes); for (i = 0; tmp[i]; i++) { _result->result = (scldap_result_entry *) realloc(_result->result, (_result->results + 2) * sizeof(scldap_result_entry)); if (!_result->result) continue; memset(&_result->result[_result->results], 0, sizeof(scldap_result_entry)); _result->result[_result->results].dn = strdup(buf); _result->result[_result->results].data = (unsigned char *) strdup(tmp[i]); _result->result[_result->results].datalen = strlen(tmp[i]); _result->results++; free(tmp[i]); } free(buf); free(tmp); if (!_result->results) { scldap_free_result(_result); return -1; } *result = _result; return 0;}static void scldap_get_result(LDAP * ld, LDAPMessage * res, scldap_param_entry * param, scldap_result * result, int attrsonly){ struct berval **bvals = NULL; BerElement *ber = NULL; char *name = NULL; unsigned int i = 0, j, o; for (name = ldap_first_attribute(ld, res, &ber); name; name = ldap_next_attribute(ld, res, ber)) {#define ADD() \{ \ if (result->results < SCLDAP_MAX_RESULTS) { \ result->result[result->results].name = strdup(name); \ result->result[result->results].dn = ldap_get_dn(ld, res); \ if (!attrsonly) { \ result->result[result->results].datalen = bvals[i]->bv_len; \ result->result[result->results].data = (unsigned char *) malloc(result->result[result->results].datalen + 1); \ memset(result->result[result->results].data, 0, result->result[result->results].datalen + 1); \ memcpy(result->result[result->results].data, bvals[i]->bv_val, result->result[result->results].datalen); \ for (o = 0; o < bvals[i]->bv_len; o++) { \ int k = bvals[i]->bv_val[o]; \ if (!isascii(k)) { \ result->result[result->results].binary = 1; \ break; \ } \ } \ } \ result->results++; \ result->result = (scldap_result_entry *) realloc(result->result, (result->results + 2) * sizeof(scldap_result_entry)); \ memset(&result->result[result->results], 0, sizeof(scldap_result_entry)); \ } \} if (attrsonly) { if (param->numattrs) { for (j = 0; j < param->numattrs; j++) { if (!strncasecmp(param->attributes[j], name, strlen(param->attributes[j]))) { ADD(); } } } else { ADD(); } } else if ((bvals = ldap_get_values_len(ld, res, name))) { for (i = 0; bvals[i]; i++) { if (param->numattrs) { for (j = 0; j < param->numattrs; j++) { if (!strncasecmp(param->attributes[j], name, strlen(param->attributes[j]))) { ADD(); } } } else { ADD();#undef ADD } } ber_bvecfree(bvals); } }}static char *combinestr(char *str,...){#define MAX_BUF_LEN 4096 va_list ap; char *buf = NULL; if (!str) { return NULL; } buf = (char *) malloc(MAX_BUF_LEN); if (!buf) { return NULL; } memset(buf, 0, MAX_BUF_LEN); va_start(ap, str); vsnprintf(buf, MAX_BUF_LEN, str, ap); va_end(ap); return buf;#undef MAX_BUF_LEN}int scldap_search(scldap_context * ctx, const char *entry, scldap_result ** result, unsigned int numwantedresults, const char *searchpattern){ LDAPMessage *res, *e; LDAP *ld = NULL; scldap_result *_result = *result; int rc, entrynum = -1; char *pattern = NULL; char **keepenv = NULL; if (_result || !ctx) { return -1; } entrynum = scldap_get_entry(ctx, entry); if (entrynum < 0) { return -1; } if (!ctx->entry[entrynum].ldaphost) { return -1; } keepenv = environ; environ = NULL; if ((ld = ldap_init(ctx->entry[entrynum].ldaphost, ctx->entry[entrynum].ldapport)) == NULL) { environ = keepenv; perror("ldap_init"); return -1; } environ = keepenv; if (ldap_bind_s(ld, ctx->entry[entrynum].binddn, ctx->entry[entrynum].passwd, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) { ldap_perror(ld, "ldap_bind"); ldap_unbind(ld); return -1; } if (searchpattern && ctx->entry[entrynum].filter) { pattern = combinestr(ctx->entry[entrynum].filter, searchpattern); } else if (searchpattern && !ctx->entry[entrynum].filter) { pattern = strdup(searchpattern); } else if (!searchpattern && ctx->entry[entrynum].filter) { pattern = strdup(ctx->entry[entrynum].filter); } /* This ifdef is currently not actually used or probed in any way, * older versions of OpenLDAP, eg. <=1.2.12.1 seem to need this * sanity check. This check cannot be enabled at least for newer * versions of OpenLDAP, otherwise it'll block certificate CRL * fetches. scldap used to work at least with solaris built-in * ldap library, nowadays untested, so beware. -aet */#ifdef HAVE_OLD_OPENLDAP /* Note: pattern *can* be empty but NOT NULL! Therefore, this is illegal. */ if (!pattern) { ldap_unbind(ld); return -1; }#endif#if 0 if (pattern) fprintf(stderr, "pattern: %s\n", pattern);#endif if (ldap_search(ld, ctx->entry[entrynum].base, ctx->entry[entrynum].scope, pattern, ctx->entry[entrynum].attributes, ctx->entry[entrynum].attrsonly) == -1) { ldap_perror(ld, "ldap_search"); if (pattern) free(pattern); ldap_unbind(ld); return -1; } if (pattern) free(pattern); _result = (scldap_result *) malloc(sizeof(scldap_result)); if (!_result) { ldap_unbind(ld); return -1; } memset(_result, 0, sizeof(scldap_result)); while ((rc = ldap_result(ld, LDAP_RES_ANY, 0, NULL, &res)) == LDAP_RES_SEARCH_ENTRY) { e = ldap_first_entry(ld, res); if (_result->results < SCLDAP_MAX_RESULTS) { _result->result = (scldap_result_entry *) realloc(_result->result, (_result->results + 2) * sizeof(scldap_result_entry)); if (!_result->result) break; memset(&_result->result[_result->results], 0, sizeof(scldap_result_entry)); scldap_get_result(ld, e, &ctx->entry[entrynum], _result, ctx->entry[entrynum].attrsonly); } ldap_msgfree(res); } if (rc == -1) { ldap_perror(ld, "ldap_result"); ldap_msgfree(res); ldap_unbind(ld); scldap_free_result(_result); return rc; } if ((rc = ldap_result2error(ld, res, 0)) != LDAP_SUCCESS) { ldap_perror(ld, "ldap_search"); } ldap_msgfree(res); ldap_unbind(ld); if (numwantedresults) { if (numwantedresults != _result->results) { scldap_free_result(_result); _result = NULL; rc = -1; } } *result = _result; return rc;}void scldap_free_result(scldap_result * result){ unsigned int i; if (result) { for (i = 0; i < result->results; i++) { if (result->result[i].name) { free(result->result[i].name); } result->result[i].name = NULL; if (result->result[i].dn) { free(result->result[i].dn); } result->result[i].dn = NULL; if (result->result[i].data) { free(result->result[i].data); } result->result[i].data = NULL; result->result[i].datalen = 0; } if (result->result) { free(result->result); } result->result = NULL; result->results = 0; free(result); result = NULL; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -