/* This file was modified by Howard Chu, hyc@symas.com, 2000-2003. * Most changes are #if OPENLDAP, some are not marked. */ #ifdef __cplusplus extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef __cplusplus } #endif #include #include #include /* Mozilla prototypes declare things as "const char *" while */ /* OpenLDAP uses "char *" */ #ifdef MOZILLA_LDAP #define LDAP_CHAR const char #include #else #ifndef OPENLDAP #include "ldap_compat.h" #endif #define LDAP_CHAR char #endif #ifndef LDAP_RES_INTERMEDIATE #define LDAP_RES_INTERMEDIATE 0x79U /* 121 */ #endif /* Function Prototypes for Internal Functions */ static char **av2modvals(AV *ldap_value_array_av, int ldap_isa_ber); static LDAPMod *parse1mod(SV *ldap_value_ref,char *ldap_current_attribute, int ldap_add_func,int cont); static LDAPMod **hash2mod(SV *ldap_change,int ldap_add_func, const char *func); #ifdef OPENLDAP static int internal_rebind_proc(LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *params); #endif /* The Name of the PERL function to return DN, PASSWD, AUTHTYPE on Rebind */ /* Set using 'set_rebind_proc()' */ SV *ldap_perl_rebindproc = NULL; /* Use constant.h generated from constant.gen */ /* Courtesy of h.b.furuseth@usit.uio.no */ #include "constant.h" /* Strcasecmp - Some operating systems don't have this, including NT */ int StrCaseCmp(const char *s, const char *t) { while (*s && *t && toupper(*s) == toupper(*t)) { s++; t++; } return(toupper(*s) - toupper(*t)); } /* av2modvals - Takes a single Array Reference (AV *) and returns */ /* a null terminated list of char pointers. */ static char **av2modvals(AV *ldap_value_array_av, int ldap_isa_ber) { I32 ldap_arraylen; char **ldap_ch_modvalues = NULL; char *ldap_current_value_char = NULL; struct berval **ldap_bv_modvalues = NULL; struct berval *ldap_current_bval = NULL; SV **ldap_current_value_sv; int ldap_value_count = 0,ldap_pvlen,ldap_real_valuecount = 0; ldap_arraylen = av_len(ldap_value_array_av); if (ldap_arraylen < 0) return(NULL); if (ldap_isa_ber == 1) { New(1,ldap_bv_modvalues,2+ldap_arraylen,struct berval *); } else { New(1,ldap_ch_modvalues,2+ldap_arraylen,char *); } for (ldap_value_count = 0; ldap_value_count <=ldap_arraylen; ldap_value_count++) { ldap_current_value_sv = av_fetch(ldap_value_array_av,ldap_value_count,0); ldap_current_value_char = SvPV(*ldap_current_value_sv,PL_na); ldap_pvlen = SvCUR(*ldap_current_value_sv); if (strcmp(ldap_current_value_char,"") != 0) { if (ldap_isa_ber == 1) { New(1,ldap_current_bval,1,struct berval); ldap_current_bval->bv_len = ldap_pvlen; ldap_current_bval->bv_val = ldap_current_value_char; ldap_bv_modvalues[ldap_real_valuecount] = ldap_current_bval; } else { ldap_ch_modvalues[ldap_real_valuecount] = ldap_current_value_char; } ldap_real_valuecount++; } } if (ldap_isa_ber == 1) { ldap_bv_modvalues[ldap_real_valuecount] = NULL; return ((char **)ldap_bv_modvalues); } else { ldap_ch_modvalues[ldap_real_valuecount] = NULL; return (ldap_ch_modvalues); } } /* parse1mod - Take a single reference, figure out if it is a HASH, */ /* ARRAY, or SCALAR, then extract the values and attributes and */ /* return a single LDAPMod pointer to this data. */ static LDAPMod *parse1mod(SV *ldap_value_ref,char *ldap_current_attribute, int ldap_add_func,int cont) { LDAPMod *ldap_current_mod; static HV *ldap_current_values_hv; HE *ldap_change_element; char *ldap_current_modop; SV *ldap_current_value_sv; I32 keylen; int ldap_isa_ber = 0; if (ldap_current_attribute == NULL) return(NULL); New(1,ldap_current_mod,1,LDAPMod); ldap_current_mod->mod_type = ldap_current_attribute; if (SvROK(ldap_value_ref)) { if (SvTYPE(SvRV(ldap_value_ref)) == SVt_PVHV) { if (!cont) { ldap_current_values_hv = (HV *) SvRV(ldap_value_ref); hv_iterinit(ldap_current_values_hv); } if ((ldap_change_element = hv_iternext(ldap_current_values_hv)) == NULL) return(NULL); ldap_current_modop = hv_iterkey(ldap_change_element,&keylen); ldap_current_value_sv = hv_iterval(ldap_current_values_hv, ldap_change_element); if (ldap_add_func == 1) { ldap_current_mod->mod_op = 0; } else { if (strchr(ldap_current_modop,'a') != NULL) { ldap_current_mod->mod_op = LDAP_MOD_ADD; } else if (strchr(ldap_current_modop,'r') != NULL) { ldap_current_mod->mod_op = LDAP_MOD_REPLACE; } else if (strchr(ldap_current_modop,'d') != NULL) { ldap_current_mod->mod_op = LDAP_MOD_DELETE; } else { return(NULL); } } if (strchr(ldap_current_modop,'b') != NULL) { ldap_isa_ber = 1; ldap_current_mod->mod_op = ldap_current_mod->mod_op | LDAP_MOD_BVALUES; } if (SvTYPE(SvRV(ldap_current_value_sv)) == SVt_PVAV) { if (ldap_isa_ber == 1) { ldap_current_mod->mod_values = av2modvals((AV *)SvRV(ldap_current_value_sv),ldap_isa_ber); } else { ldap_current_mod->mod_values = av2modvals((AV *)SvRV(ldap_current_value_sv),ldap_isa_ber); } } } else if (SvTYPE(SvRV(ldap_value_ref)) == SVt_PVAV) { if (cont) return NULL; if (ldap_add_func == 1) ldap_current_mod->mod_op = 0; else ldap_current_mod->mod_op = LDAP_MOD_REPLACE; ldap_current_mod->mod_values = av2modvals((AV *)SvRV(ldap_value_ref),0); if (ldap_current_mod->mod_values == NULL) { ldap_current_mod->mod_op = LDAP_MOD_DELETE; } } } else { if (cont) return NULL; if (strcmp(SvPV(ldap_value_ref,PL_na),"") == 0) { if (ldap_add_func != 1) { ldap_current_mod->mod_op = LDAP_MOD_DELETE; ldap_current_mod->mod_values = NULL; } else { return(NULL); } } else { if (ldap_add_func == 1) { ldap_current_mod->mod_op = 0; } else { ldap_current_mod->mod_op = LDAP_MOD_REPLACE; } New(1,ldap_current_mod->mod_values,2,char *); ldap_current_mod->mod_values[0] = SvPV(ldap_value_ref,PL_na); ldap_current_mod->mod_values[1] = NULL; } } return(ldap_current_mod); } /* hash2mod - Cycle through all the keys in the hash and properly call */ /* the appropriate functions to build a NULL terminated list of */ /* LDAPMod pointers. */ static LDAPMod ** hash2mod(SV *ldap_change_ref, int ldap_add_func, const char *func) { LDAPMod **ldapmod = NULL; LDAPMod *ldap_current_mod; int ldap_attribute_count = 0; HE *ldap_change_element; char *ldap_current_attribute; SV *ldap_current_value_sv; I32 keylen; HV *ldap_change; if (!SvROK(ldap_change_ref) || SvTYPE(SvRV(ldap_change_ref)) != SVt_PVHV) croak("Net::LDAPapi::%s needs Hash reference as argument 3.",func); ldap_change = (HV *)SvRV(ldap_change_ref); hv_iterinit(ldap_change); while((ldap_change_element = hv_iternext(ldap_change)) != NULL) { ldap_current_attribute = hv_iterkey(ldap_change_element,&keylen); ldap_current_value_sv = hv_iterval(ldap_change,ldap_change_element); ldap_current_mod = parse1mod(ldap_current_value_sv, ldap_current_attribute,ldap_add_func,0); while (ldap_current_mod != NULL) { ldap_attribute_count++; (ldapmod ? Renew(ldapmod,1+ldap_attribute_count,LDAPMod *) : New(1,ldapmod,1+ldap_attribute_count,LDAPMod *)); New(1,ldapmod[ldap_attribute_count -1],sizeof(LDAPMod),LDAPMod); Copy(ldap_current_mod,ldapmod[ldap_attribute_count-1], sizeof(LDAPMod),LDAPMod *); ldap_current_mod = parse1mod(ldap_current_value_sv, ldap_current_attribute,ldap_add_func,1); } } ldapmod[ldap_attribute_count] = NULL; return ldapmod; } /* internal_rebind_proc - Wrapper to call a PERL rebind process */ /* ldap_set_rebind_proc is slightly different between Mozilla and OpenLDAP */ int #ifdef OPENLDAP internal_rebind_proc(LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *params) #endif { return(LDAP_SUCCESS); } typedef struct bictx { char *authcid; char *passwd; char *realm; char *authzid; } bictx; static int ldap_b2_interact(LDAP *ld, unsigned flags, void *def, void *inter) { sasl_interact_t *in = inter; const char *p; bictx *ctx = def; for (;in->id != SASL_CB_LIST_END;in++) { p = NULL; switch(in->id) { case SASL_CB_GETREALM: p = ctx->realm; break; case SASL_CB_AUTHNAME: p = ctx->authcid; break; case SASL_CB_USER: p = ctx->authzid; break; case SASL_CB_PASS: p = ctx->passwd; break; } if (p) { in->len = strlen(p); in->result = p; } } return LDAP_SUCCESS; } static struct timeval * sv2timeval(SV *data) { struct timeval *tv = NULL; if (SvPOK(data)) { /* set the NV flag if it's readable as a double */ SvNV(data); } if (SvIOK(data) || SvNOK(data)) { Newx(tv, 1, struct timeval); tv->tv_sec = SvIV(data); tv->tv_usec = ((SvNV(data) - SvIV(data))*1000000); } return tv; } static SV * timeval2sv(struct timeval *data) { return newSVnv(data->tv_sec + ((double)data->tv_usec / 1000000)); } MODULE = Net::LDAPapi PACKAGE = Net::LDAPapi PROTOTYPES: ENABLE double constant(name,arg) char * name int arg char * constant_s(name) char * name int ldap_initialize(ldp, url) LDAP * ldp = NO_INIT LDAP_CHAR * url CODE: { RETVAL = ldap_initialize(&ldp, url); } OUTPUT: RETVAL ldp int ldap_create(ldp) LDAP ** ldp = NO_INIT CODE: { RETVAL = ldap_create(ldp); } OUTPUT: RETVAL ldp int ldap_bind_s(ldp, dn, passwd, authmethod) LDAP * ldp LDAP_CHAR * dn LDAP_CHAR * passwd int authmethod int ldap_set_option(ld,option,optdata) LDAP * ld int option SV * optdata CODE: { void *optptr = NULL; bool must_safefree = 0; int sv_i; switch(option) { #ifdef OPENLDAP case LDAP_OPT_TIMEOUT: case LDAP_OPT_NETWORK_TIMEOUT: optptr = (void *) sv2timeval(optdata); must_safefree = 1; break; #endif default: if (SvIOK(optdata)) { sv_i = SvIV(optdata); optptr = (void *) &sv_i; } break; } RETVAL = ldap_set_option(ld,option,optptr); if (must_safefree) { Safefree(optptr); } } OUTPUT: RETVAL int ldap_get_option(ld,option,optdata) LDAP * ld int option SV * optdata CODE: { void *data = NULL; RETVAL = ldap_get_option(ld, option, &data); switch(option) { #ifdef OPENLDAP case LDAP_OPT_TIMEOUT: case LDAP_OPT_NETWORK_TIMEOUT: sv_setsv(SvRV(optdata), timeval2sv(data)); break; #endif default: sv_setiv(SvRV(optdata), (long)data); break; } } OUTPUT: RETVAL optdata int ldap_unbind_ext_s(ld,sctrls,cctrls) LDAP * ld LDAPControl ** sctrls LDAPControl ** cctrls int ldap_search_s(ldp, base, scope, filter, attrs, attrsonly, res) LDAP * ldp LDAP_CHAR * base int scope LDAP_CHAR * filter LDAP_CHAR ** attrs int attrsonly LDAPMessage * res = NO_INIT CODE: { RETVAL = ldap_search_s(ldp, base, scope, filter, attrs, attrsonly, &res); } OUTPUT: RETVAL res #ifdef MOZILLA_LDAP int ldap_version(ver) LDAPVersion *ver #endif int ldap_abandon_ext(ld,msgid,sctrls,cctrls) LDAP * ld int msgid LDAPControl ** sctrls LDAPControl ** cctrls int ldap_add_ext(ld, dn, ldap_change_ref, sctrls, cctrls, msgidp) LDAP * ld LDAP_CHAR * dn SV * ldap_change_ref LDAPControl ** sctrls LDAPControl ** cctrls int msgidp = NO_INIT CODE: { LDAPMod ** attrs = hash2mod(ldap_change_ref, 1, "ldap_add_ext"); RETVAL = ldap_add_ext(ld, dn, attrs, sctrls, cctrls, &msgidp); Safefree(attrs); } OUTPUT: RETVAL msgidp int ldap_add_ext_s(ld,dn,ldap_change_ref,sctrls,cctrls) LDAP * ld LDAP_CHAR * dn LDAPMod ** ldap_change_ref = hash2mod($arg, 1, "ldap_add_ext_s"); LDAPControl ** sctrls LDAPControl ** cctrls CLEANUP: Safefree(ldap_change_ref); int ldap_sasl_bind(ld, dn, passwd, serverctrls, clientctrls, msgidp) LDAP * ld LDAP_CHAR * dn LDAP_CHAR * passwd LDAPControl ** serverctrls LDAPControl ** clientctrls int msgidp = NO_INIT CODE: { struct berval cred; if( passwd == NULL ) cred.bv_val = ""; else cred.bv_val = passwd; cred.bv_len = strlen(cred.bv_val); RETVAL = ldap_sasl_bind(ld, dn, LDAP_SASL_SIMPLE, &cred, serverctrls, clientctrls, &msgidp); } OUTPUT: RETVAL msgidp int ldap_modify_ext(ld, dn, ldap_change_ref, sctrls, cctrls, msgidp) LDAP * ld LDAP_CHAR * dn SV * ldap_change_ref LDAPControl ** sctrls LDAPControl ** cctrls int msgidp = NO_INIT CODE: { LDAPMod ** mods = hash2mod(ldap_change_ref, 0, "ldap_modify_ext"); RETVAL = ldap_modify_ext(ld, dn, mods, sctrls, cctrls, &msgidp); Safefree(mods); } OUTPUT: RETVAL msgidp int ldap_modify_ext_s(ld,dn,ldap_change_ref,sctrl,cctrl) LDAP * ld LDAP_CHAR * dn LDAPMod ** ldap_change_ref = hash2mod($arg, 0, "$func_name"); LDAPControl ** sctrl LDAPControl ** cctrl int ldap_rename(ld, dn, newrdn, newSuperior, deleteoldrdn, sctrls, cctrls, msgidp) LDAP * ld LDAP_CHAR * dn LDAP_CHAR * newrdn LDAP_CHAR * newSuperior int deleteoldrdn LDAPControl ** sctrls LDAPControl ** cctrls int msgidp = NO_INIT CODE: { RETVAL = ldap_rename(ld, dn, newrdn, newSuperior, deleteoldrdn, sctrls, cctrls, &msgidp); } OUTPUT: RETVAL msgidp int ldap_rename_s(ld, dn, newrdn, newSuperior, deleteoldrdn, sctrls, cctrls) LDAP * ld LDAP_CHAR * dn LDAP_CHAR * newrdn LDAP_CHAR * newSuperior int deleteoldrdn LDAPControl ** sctrls LDAPControl ** cctrls int ldap_compare_ext(ld,dn,attr,value,sctrls,cctrls,msgidp) LDAP * ld LDAP_CHAR * dn LDAP_CHAR * attr LDAP_CHAR * value LDAPControl ** sctrls LDAPControl ** cctrls int msgidp = NO_INIT CODE: { struct berval bvalue; bvalue.bv_len = strlen(value); bvalue.bv_val = value; RETVAL = ldap_compare_ext(ld, dn, attr, &bvalue, sctrls, cctrls, &msgidp); } OUTPUT: RETVAL msgidp int ldap_compare_ext_s(ld, dn, attr, value, sctrls, cctrls) LDAP * ld LDAP_CHAR * dn LDAP_CHAR * attr LDAP_CHAR * value LDAPControl ** sctrls LDAPControl ** cctrls CODE: { struct berval bvalue; bvalue.bv_len = strlen(value); bvalue.bv_val = value; RETVAL = ldap_compare_ext_s(ld, dn, attr, &bvalue, sctrls, cctrls); } OUTPUT: RETVAL int ldap_delete_ext(ld,dn,sctrls,cctrls,msgidp) LDAP * ld LDAP_CHAR * dn LDAPControl ** sctrls LDAPControl ** cctrls int msgidp = NO_INIT CODE: { RETVAL = ldap_delete_ext(ld, dn, sctrls, cctrls, &msgidp); } OUTPUT: RETVAL msgidp int ldap_delete_ext_s(ld,dn,sctrls,cctrls) LDAP * ld LDAP_CHAR * dn LDAPControl ** sctrls LDAPControl ** cctrls int ldap_search_ext(ld, base, scope, filter, attrs, attrsonly, sctrls, cctrls, timeout, sizelimit, msgidp) LDAP * ld LDAP_CHAR * base int scope LDAP_CHAR * filter SV * attrs int attrsonly LDAPControl ** sctrls LDAPControl ** cctrls SV * timeout int sizelimit int msgidp = NO_INIT CODE: { char **attrs_char; SV **current; int arraylen,count; struct timeval *tv_timeout = NULL; if (SvTYPE(SvRV(attrs)) != SVt_PVAV) { croak("Net::LDAPapi::ldap_search_ext needs ARRAY reference as argument 5."); XSRETURN(1); } if ((arraylen = av_len((AV *)SvRV(attrs))) < 0) { New(1,attrs_char,2,char *); attrs_char[0] = NULL; } else { New(1,attrs_char,arraylen+2,char *); for (count=0;count <= arraylen; count++) { current = av_fetch((AV *)SvRV(attrs),count,0); attrs_char[count] = SvPV(*current,PL_na); } attrs_char[arraylen+1] = NULL; } tv_timeout = sv2timeval(timeout); RETVAL = ldap_search_ext(ld, base, scope, filter, attrs_char, attrsonly, sctrls, cctrls, tv_timeout, sizelimit, &msgidp); Safefree(tv_timeout); Safefree(attrs_char); } OUTPUT: RETVAL msgidp int ldap_search_ext_s(ld, base, scope, filter, attrs, attrsonly, sctrls, cctrls, timeout, sizelimit, res) LDAP * ld LDAP_CHAR * base int scope LDAP_CHAR * filter SV * attrs int attrsonly LDAPControl ** sctrls LDAPControl ** cctrls SV * timeout int sizelimit LDAPMessage * res = NO_INIT CODE: { char **attrs_char; SV **current; int arraylen,count; struct timeval *tv_timeout = NULL; if (SvTYPE(SvRV(attrs)) == SVt_PVAV) { if ((arraylen = av_len((AV *)SvRV(attrs))) < 0) { New(1, attrs_char, 2, char *); attrs_char[0] = NULL; } else { New(1, attrs_char, arraylen+2, char *); for (count=0;count <= arraylen; count++) { current = av_fetch((AV *)SvRV(attrs),count,0); attrs_char[count] = SvPV(*current,PL_na); } attrs_char[arraylen+1] = NULL; } } else { croak("Net::LDAPapi::ldap_search_ext_s needs ARRAY reference as argument 5."); XSRETURN(1); } tv_timeout = sv2timeval(timeout); RETVAL = ldap_search_ext_s(ld,base,scope,filter,attrs_char,attrsonly,sctrls,cctrls,tv_timeout,sizelimit,&res); Safefree(tv_timeout); Safefree(attrs_char); } OUTPUT: RETVAL res int ldap_extended_operation(ld, oid, bv_val, bv_len, sctrls, cctrls, msgidp) LDAP * ld LDAP_CHAR * oid LDAP_CHAR * bv_val int bv_len LDAPControl ** sctrls LDAPControl ** cctrls int msgidp = NO_INIT CODE: { struct berval indata; if (bv_len == 0) { RETVAL = ldap_extended_operation(ld, oid, NULL, sctrls, cctrls, &msgidp); } else { indata.bv_val = bv_val; indata.bv_len = bv_len; RETVAL = ldap_extended_operation(ld, oid, &indata, sctrls, cctrls, &msgidp); } } OUTPUT: RETVAL msgidp int ldap_extended_operation_s(ld, oid, bv_val, bv_len, sctrls, cctrls, retoidp, retdatap) LDAP * ld LDAP_CHAR * oid LDAP_CHAR * bv_val int bv_len LDAPControl ** sctrls LDAPControl ** cctrls char * retoidp = NO_INIT char * retdatap = NO_INIT CODE: { struct berval indata, *retdata; if (bv_len == 0) { RETVAL = ldap_extended_operation_s(ld, oid, NULL, sctrls, cctrls, &retoidp, &retdata); } else { indata.bv_val = bv_val; indata.bv_len = bv_len; RETVAL = ldap_extended_operation_s(ld, oid, &indata, sctrls, cctrls, &retoidp, &retdata); } if (retdata != NULL) retdatap = ldap_strdup(retdata->bv_val); ber_memfree(retdata); } OUTPUT: RETVAL retoidp retdatap int ldap_whoami(ld, sctrls, cctrls, msgidp) LDAP * ld LDAPControl ** sctrls LDAPControl ** cctrls int msgidp = NO_INIT CODE: { RETVAL = ldap_whoami(ld, sctrls, cctrls, &msgidp); } OUTPUT: RETVAL msgidp int ldap_whoami_s(ld, authzid, sctrls, cctrls) LDAP * ld LDAPControl ** sctrls LDAPControl ** cctrls char * authzid = NO_INIT CODE: { struct berval *retdata; RETVAL = ldap_whoami_s(ld, &retdata, sctrls, cctrls); if (retdata != NULL) authzid = ldap_strdup(retdata->bv_val); ber_memfree(retdata); } OUTPUT: RETVAL authzid int ldap_result(ld, msgid, all, timeout, result) LDAP * ld int msgid int all SV * timeout LDAPMessage * result = NO_INIT CODE: { struct timeval *tv_timeout = NULL; tv_timeout = sv2timeval(timeout); RETVAL = ldap_result(ld, msgid, all, tv_timeout, &result); Safefree(tv_timeout); } OUTPUT: RETVAL result int ldap_msgfree(lm) LDAPMessage * lm void ber_free(ber, freebuf) BerElement * ber int freebuf #if defined(MOZILLA_LDAP) || defined(OPENLDAP) int ldap_msgid(lm) LDAPMessage * lm int ldap_msgtype(lm) LDAPMessage * lm #else int ldap_msgid(lm) LDAPMessage * lm CODE: { RETVAL = lm->lm_msgid; } OUTPUT: RETVAL int ldap_msgtype(lm) LDAPMessage * lm CODE: { RETVAL = lm->lm_msgtype; } OUTPUT: RETVAL #endif #if defined(MOZILLA_LDAP) int ldap_get_lderrno(ld,m,s) LDAP * ld char * m = NO_INIT char * s = NO_INIT CODE: { RETVAL = ldap_get_lderrno(ld,&m,&s); } OUTPUT: RETVAL m s int ldap_set_lderrno(ld,e,m,s) LDAP * ld int e char * m char * s #else int ldap_get_lderrno(ld,m,s) LDAP * ld char * m = NO_INIT char * s = NO_INIT CODE: { #ifdef OPENLDAP ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &RETVAL); ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &s); ldap_get_option(ld, LDAP_OPT_MATCHED_DN, &m); #else RETVAL = ld->ld_errno; m = ld->ld_matched; s = ld->ld_error; #endif } OUTPUT: RETVAL m s int ldap_set_lderrno(ld,e,m,s) LDAP * ld int e char * m char * s CODE: { RETVAL = 0; #ifdef OPENLDAP ldap_set_option(ld, LDAP_OPT_ERROR_NUMBER, &e); ldap_set_option(ld, LDAP_OPT_ERROR_STRING, s); ldap_set_option(ld, LDAP_OPT_MATCHED_DN, m); #else ld->ld_errno = e; ld->ld_matched = m; ld->ld_error = s; #endif } OUTPUT: RETVAL #endif int ldap_get_entry_controls(ld, entry, serverctrls_ref) LDAP * ld LDAPMessage * entry SV * serverctrls_ref CODE: { int i; if (SvTYPE(SvRV(serverctrls_ref)) != SVt_PVAV) { croak("Net::LDAPapi::ldap_get_entry_controls needs ARRAY reference as argument 3."); XSRETURN(-1); } AV *serverctrls_av = (AV *)SvRV(serverctrls_ref); LDAPControl **serverctrls = malloc(sizeof(LDAPControl **)); if( serverctrls == NULL ) { croak("In ldap_parse_result(...) failed to allocate memory for serverctrls."); XSRETURN(-1); } RETVAL = ldap_get_entry_controls( ld, entry, &serverctrls); // transfer returned controls to the perl code if( serverctrls != NULL ) { for( i = 0; serverctrls[i] != NULL; i++ ) av_push(serverctrls_av, newSViv((IV)serverctrls[i])); } free(serverctrls); SvRV( serverctrls_ref ) = (SV *)serverctrls_av; } OUTPUT: RETVAL int ldap_parse_result(ld, msg, errorcodep, matcheddnp, errmsgp, referrals_ref, serverctrls_ref, freeit) LDAP * ld LDAPMessage * msg int errorcodep = NO_INIT char * matcheddnp = NO_INIT char * errmsgp = NO_INIT SV * referrals_ref SV * serverctrls_ref int freeit CODE: { int i; if (SvTYPE(SvRV(referrals_ref)) != SVt_PVAV) { croak("Net::LDAPapi::ldap_parse_result needs ARRAY reference as argument 6."); XSRETURN(-1); } if (SvTYPE(SvRV(serverctrls_ref)) != SVt_PVAV) { croak("Net::LDAPapi::ldap_parse_result needs ARRAY reference as argument 7."); XSRETURN(-1); } AV *serverctrls_av = (AV *)SvRV(serverctrls_ref); AV *referrals_av = (AV *)SvRV(referrals_ref); LDAPControl **serverctrls = malloc(sizeof(LDAPControl **)); if( serverctrls == NULL ) { croak("In ldap_parse_result(...) failed to allocate memory for serverctrls."); XSRETURN(-1); } char **referrals = malloc(sizeof(char **)); if( referrals == NULL ) { croak("In ldap_parse_result(...) failed to allocate memory for referrals."); free(referrals); XSRETURN(-1); } RETVAL = ldap_parse_result(ld, msg, &errorcodep, &matcheddnp, &errmsgp, &referrals, &serverctrls, freeit); // transfer returned referrals to the perl code if( referrals != NULL ) { for( i = 0; referrals[i] != NULL; i++ ) av_push(referrals_av, newSViv((IV)referrals[i])); } // transfer returned controls to the perl code if( serverctrls != NULL ) { for( i = 0; serverctrls[i] != NULL; i++ ) av_push(serverctrls_av, newSViv((IV)serverctrls[i])); } free(serverctrls); free(referrals); SvRV( referrals_ref ) = (SV *)referrals_av; SvRV( serverctrls_ref ) = (SV *)serverctrls_av; } OUTPUT: RETVAL errorcodep matcheddnp errmsgp int ldap_parse_extended_result(ld, msg, retoidp, retdatap, freeit) LDAP * ld LDAPMessage * msg char * retoidp = NO_INIT char * retdatap = NO_INIT int freeit CODE: { struct berval *retdata; retdata = ber_memalloc(sizeof(struct berval *)); RETVAL = ldap_parse_extended_result(ld, msg, &retoidp, &retdata, freeit); if (retdata != NULL) retdatap = ldap_strdup(retdata->bv_val); ber_memfree(retdata); } OUTPUT: RETVAL retoidp retdatap int ldap_parse_intermediate(ld, msg, retoidp, retdatap, serverctrls_ref, freeit) LDAP * ld LDAPMessage * msg char * retoidp = NO_INIT char * retdatap = NO_INIT SV * serverctrls_ref int freeit CODE: { int i; struct berval *retdata; if (SvTYPE(SvRV(serverctrls_ref)) != SVt_PVAV) { croak("Net::LDAPapi::ldap_parse_intermediate needs ARRAY reference as argument 5."); XSRETURN(-1); } AV *serverctrls_av = (AV *)SvRV(serverctrls_ref); LDAPControl **serverctrls = malloc(sizeof(LDAPControl **)); if( serverctrls == NULL ) { croak("In ldap_parse_intermediate(...) failed to allocate memory for serverctrls."); XSRETURN(-1); } retdata = malloc(sizeof(struct berval *)); RETVAL = ldap_parse_intermediate(ld, msg, &retoidp, &retdata, &serverctrls, freeit); if( retdata != NULL ) retdatap = ldap_strdup(retdata->bv_val); // transfer returned controls to the perl code if( serverctrls != NULL ) { for( i = 0; serverctrls[i] != NULL; i++ ) av_push(serverctrls_av, newSViv((IV)serverctrls[i])); } free(serverctrls); free(retdata); SvRV( serverctrls_ref ) = (SV *)serverctrls_av; } OUTPUT: RETVAL retoidp retdatap int ldap_parse_whoami(ld, msg, authzid) LDAP * ld LDAPMessage * msg char * authzid = NO_INIT CODE: { struct berval *retdata; retdata = ber_memalloc(sizeof(struct berval *)); RETVAL = ldap_parse_whoami(ld, msg, &retdata); if (retdata != NULL) authzid = ldap_strdup(retdata->bv_val); ber_memfree(retdata); } OUTPUT: RETVAL authzid char * ldap_control_oid(control) LDAPControl * control CODE: { RETVAL = control->ldctl_oid; } OUTPUT: RETVAL SV * ldap_control_berval(control) LDAPControl * control CODE: { RETVAL = newSVpv(control->ldctl_value.bv_val, control->ldctl_value.bv_len); } OUTPUT: RETVAL int ldap_control_critical(control) LDAPControl * control CODE: { RETVAL = control->ldctl_iscritical; } OUTPUT: RETVAL char * ldap_err2string(err) int err int ldap_count_references(ld, result) LDAP *ld LDAPMessage *result int ldap_count_entries(ld,result) LDAP * ld LDAPMessage * result LDAPMessage * ldap_first_entry(ld,result) LDAP * ld LDAPMessage * result LDAPMessage * ldap_next_entry(ld,preventry) LDAP * ld LDAPMessage * preventry LDAPMessage * ldap_first_message(ld, chain) LDAP *ld LDAPMessage *chain LDAPMessage * ldap_next_message(ld, chain) LDAP *ld LDAPMessage *chain SV * ldap_get_dn(ld,entry) LDAP * ld LDAPMessage * entry PREINIT: char * dn; CODE: { dn = ldap_get_dn(ld, entry); if (dn) { RETVAL = newSVpv(dn,0); ldap_memfree(dn); } else { RETVAL = &PL_sv_undef; } } OUTPUT: RETVAL void ldap_perror(ld,s) LDAP * ld LDAP_CHAR * s char * ldap_dn2ufn(dn) LDAP_CHAR * dn #if defined(OPENLDAP) int ldap_str2dn(str,dn,flags) LDAP_CHAR * str LDAPDN * dn unsigned flags int ldap_str2rdn(str,rdn,n_in,flags) LDAP_CHAR * str LDAPRDN * rdn char ** n_in unsigned flags #endif void ldap_explode_dn(dn,notypes) char * dn int notypes PPCODE: { char ** LDAPGETVAL; int i; if ((LDAPGETVAL = ldap_explode_dn(dn,notypes)) != NULL) { for (i = 0; LDAPGETVAL[i] != NULL; i++) { EXTEND(sp,1); PUSHs(sv_2mortal(newSVpv(LDAPGETVAL[i],strlen(LDAPGETVAL[i])))); } ldap_value_free(LDAPGETVAL); } } void ldap_explode_rdn(dn,notypes) char * dn int notypes PPCODE: { char ** LDAPGETVAL; int i; if ((LDAPGETVAL = ldap_explode_rdn(dn,notypes)) != NULL) { for (i = 0; LDAPGETVAL[i] != NULL; i++) { EXTEND(sp,1); PUSHs(sv_2mortal(newSVpv(LDAPGETVAL[i],strlen(LDAPGETVAL[i])))); } ldap_value_free(LDAPGETVAL); } } SV * ldap_first_attribute(ld,entry,ber) LDAP * ld LDAPMessage * entry BerElement * ber = NO_INIT PREINIT: char * attr; CODE: { attr = ldap_first_attribute(ld, entry, &ber); if (attr) { RETVAL = newSVpv(attr,0); ldap_memfree(attr); } else { RETVAL = &PL_sv_undef; } } OUTPUT: RETVAL ber SV * ldap_next_attribute(ld,entry,ber) LDAP * ld LDAPMessage * entry BerElement * ber PREINIT: char * attr; CODE: { attr = ldap_next_attribute(ld, entry, ber); if (attr) { RETVAL = newSVpv(attr,0); ldap_memfree(attr); } else { RETVAL = &PL_sv_undef; } } OUTPUT: RETVAL ber void ldap_get_values_len(ld,entry,target) LDAP * ld LDAPMessage * entry char * target PPCODE: { struct berval ** LDAPGETVAL; int i; if ((LDAPGETVAL = ldap_get_values_len(ld,entry,target)) != NULL) { for (i = 0; LDAPGETVAL[i] != NULL; i++) { EXTEND(sp,1); PUSHs(sv_2mortal(newSVpv(LDAPGETVAL[i]->bv_val,LDAPGETVAL[i]->bv_len))); } } } #ifdef MOZILLA_LDAP int ldapssl_client_init(certdbpath,certdbhandle) char * certdbpath void * certdbhandle LDAP * ldapssl_init(defhost,defport,defsecure) char * defhost int defport int defsecure int ldapssl_install_routines(ld) LDAP * ld #endif void ldap_set_rebind_proc(ld,rebind_function,args) LDAP * ld SV * rebind_function void * args CODE: { if (SvTYPE(SvRV(rebind_function)) != SVt_PVCV) { // rebind_function is not actually a function // and we set rebind function to NULL #if defined(MOZILLA_LDAP) || defined(OPENLDAP) ldap_set_rebind_proc(ld,NULL,NULL); #else ldap_set_rebind_proc(ld,NULL); #endif } else { if (ldap_perl_rebindproc == (SV*)NULL) ldap_perl_rebindproc = newSVsv(rebind_function); else SvSetSV(ldap_perl_rebindproc, rebind_function); #if defined(OPENLDAP) ldap_set_rebind_proc(ld, internal_rebind_proc, args); #endif } } HV * ldap_get_all_entries(ld,result) LDAP * ld LDAPMessage * result CODE: { LDAPMessage *entry = NULL; char *dn = NULL, *attr = NULL; struct berval **vals = NULL; BerElement *ber = NULL; int count = 0; HV* FullHash = newHV(); for ( entry = ldap_first_entry(ld, result); entry != NULL; entry = ldap_next_entry(ld, entry) ) { HV* ResultHash = newHV(); SV* HashRef = newRV((SV*) ResultHash); if ((dn = ldap_get_dn(ld, entry)) == NULL) continue; for ( attr = ldap_first_attribute(ld, entry, &ber); attr != NULL; attr = ldap_next_attribute(ld, entry, ber) ) { AV* AttributeValsArray = newAV(); SV* ArrayRef = newRV((SV*) AttributeValsArray); if ((vals = ldap_get_values_len(ld, entry, attr)) != NULL) { for (count=0; vals[count] != NULL; count++) { SV* SVval = newSVpvn(vals[count]->bv_val, vals[count]->bv_len); av_push(AttributeValsArray, SVval); } } hv_store(ResultHash, attr, strlen(attr), ArrayRef, 0); if (vals != NULL) ldap_value_free_len(vals); } if (attr != NULL) ldap_memfree(attr); hv_store(FullHash, dn, strlen(dn), HashRef, 0); if (dn != NULL) ldap_memfree(dn); #if defined(MOZILLA_LDAP) || defined(OPENLDAP) if (ber != NULL) ber_free(ber,0); #endif } RETVAL = FullHash; } OUTPUT: RETVAL int ldap_is_ldap_url(url) LDAP_CHAR * url SV * ldap_url_parse(url) LDAP_CHAR * url CODE: { LDAPURLDesc *realcomp; int count,ret; HV* FullHash = newHV(); RETVAL = newRV((SV*)FullHash); ret = ldap_url_parse(url,&realcomp); if (ret == 0) { static char *host_key = "host"; static char *port_key = "port"; static char *dn_key = "dn"; static char *attr_key = "attr"; static char *scope_key = "scope"; static char *filter_key = "filter"; #ifdef MOZILLA_LDAP static char *options_key = "options"; SV* options = newSViv(realcomp->lud_options); #endif #ifdef OPENLDAP static char *scheme_key = "scheme"; static char *exts_key = "exts"; AV* extsarray = newAV(); SV* extsibref = newRV((SV*) extsarray); SV* scheme = newSVpv(realcomp->lud_scheme,0); #endif SV* host = newSVpv(realcomp->lud_host,0); SV* port = newSViv(realcomp->lud_port); SV* dn; /* = newSVpv(realcomp->lud_dn,0); */ SV* scope = newSViv(realcomp->lud_scope); SV* filter = newSVpv(realcomp->lud_filter,0); AV* attrarray = newAV(); SV* attribref = newRV((SV*) attrarray); if (realcomp->lud_dn) dn = newSVpv(realcomp->lud_dn,0); else dn = newSVpv("",0); if (realcomp->lud_attrs != NULL) { for (count=0; realcomp->lud_attrs[count] != NULL; count++) { SV* SVval = newSVpv(realcomp->lud_attrs[count],0); av_push(attrarray, SVval); } } #ifdef OPENLDAP if (realcomp->lud_exts != NULL) { for (count=0; realcomp->lud_exts[count] != NULL; count++) { SV* SVval = newSVpv(realcomp->lud_exts[count],0); av_push(extsarray, SVval); } } hv_store(FullHash,exts_key,strlen(exts_key),extsibref,0); hv_store(FullHash,scheme_key,strlen(scheme_key),scheme,0); #endif hv_store(FullHash,host_key,strlen(host_key),host,0); hv_store(FullHash,port_key,strlen(port_key),port,0); hv_store(FullHash,dn_key,strlen(dn_key),dn,0); hv_store(FullHash,attr_key,strlen(attr_key),attribref,0); hv_store(FullHash,scope_key,strlen(scope_key),scope,0); hv_store(FullHash,filter_key,strlen(filter_key),filter,0); #ifdef MOZILLA_LDAP hv_store(FullHash,options_key,strlen(options_key),options,0); #endif ldap_free_urldesc(realcomp); } else { RETVAL = &PL_sv_undef; } } OUTPUT: RETVAL #ifndef OPENLDAP int ldap_url_search(ld,url,attrsonly) LDAP * ld char * url int attrsonly int ldap_url_search_s(ld,url,attrsonly,result) LDAP * ld char * url int attrsonly LDAPMessage * result = NO_INIT CODE: { RETVAL = ldap_url_search_s(ld,url,attrsonly,&result); } OUTPUT: RETVAL result int ldap_url_search_st(ld,url,attrsonly,timeout,result) LDAP * ld char * url int attrsonly SV * timeout LDAPMessage * result = NO_INIT CODE: { struct timeval *tv_timeout = NULL; tv_timeout = sv2timeval(timeout); RETVAL = ldap_url_search_st(ld,url,attrsonly,tv_timeout,&result); Safefree(tv_timeout); } OUTPUT: RETVAL result #endif int ldap_sort_entries(ld,chain,attr) LDAP * ld LDAPMessage * chain char * attr CODE: { RETVAL = ldap_sort_entries(ld,&chain,attr,StrCaseCmp); } OUTPUT: RETVAL chain #ifdef MOZILLA_LDAP int ldap_multisort_entries(ld,chain,attrs) LDAP * ld LDAPMessage * chain SV * attrs CODE: { char **attrs_char; SV ** current; int count,arraylen; if (SvTYPE(SvRV(attrs)) == SVt_PVAV) { if ((arraylen = av_len((AV *)SvRV(attrs))) < 0) { New(1,attrs_char,2,char *); attrs_char[0] = NULL; } else { New(1,attrs_char,arraylen+2,char *); for (count=0;count <= arraylen; count++) { current = av_fetch((AV *)SvRV(attrs),count,0); attrs_char[count] = SvPV(*current,PL_na); } attrs_char[arraylen+1] = NULL; } } else { croak("Net::LDAPapi::ldap_multisort_entries needs ARRAY reference as argument 3."); XSRETURN(1); } RETVAL = ldap_multisort_entries(ld,&chain,attrs_char,StrCaseCmp); } OUTPUT: RETVAL chain #endif #ifdef OPENLDAP int ldap_start_tls(ld,serverctrls,clientctrls,msgidp) LDAP * ld LDAPControl ** serverctrls LDAPControl ** clientctrls int msgidp = NO_INIT CODE: { RETVAL = ldap_start_tls(ld, serverctrls, clientctrls, &msgidp); } OUTPUT: RETVAL msgidp int ldap_start_tls_s(ld,serverctrls,clientctrls) LDAP * ld LDAPControl ** serverctrls LDAPControl ** clientctrls int ldap_sasl_interactive_bind_s(ld, who, passwd, serverctrls, clientctrls, mech, realm, authzid, props, flags) LDAP * ld LDAP_CHAR * who LDAP_CHAR * passwd LDAPControl ** serverctrls LDAPControl ** clientctrls LDAP_CHAR * mech LDAP_CHAR * realm LDAP_CHAR * authzid LDAP_CHAR * props unsigned flags CODE: { bictx ctx = {who, passwd, realm, authzid}; if (props) ldap_set_option(ld, LDAP_OPT_X_SASL_SECPROPS, props); RETVAL = ldap_sasl_interactive_bind_s( ld, NULL, mech, serverctrls, clientctrls, flags, ldap_b2_interact, &ctx ); } OUTPUT: RETVAL int ldap_sasl_bind_s(ld, dn, passwd, serverctrls, clientctrls, servercredp) LDAP * ld LDAP_CHAR * dn LDAP_CHAR * passwd LDAPControl ** serverctrls LDAPControl ** clientctrls struct berval ** servercredp = NO_INIT CODE: { struct berval cred; if( passwd == NULL ) cred.bv_val = ""; else cred.bv_val = passwd; cred.bv_len = strlen(cred.bv_val); servercredp = 0; /* mdw 20070918 */ RETVAL = ldap_sasl_bind_s(ld, dn, LDAP_SASL_SIMPLE, &cred, serverctrls, clientctrls, servercredp); } OUTPUT: RETVAL servercredp #endif LDAPControl ** ldap_controls_array_init(total) int total CODE: { LDAPControl ** array; array = malloc(total * sizeof(LDAPControl *)); RETVAL = array; } OUTPUT: RETVAL void ldap_controls_array_free(ctrls) LDAPControl ** ctrls CODE: { //int i; //for( i = 0; ctrls[i] != NULL; i++ ) // free((LDAPControl *)ctrls[i]); free(ctrls); } void ldap_control_set(array, ctrl, location) LDAPControl **array LDAPControl *ctrl int location CODE: { array[location] = ctrl; } int ldap_create_control(oid, bv_val, bv_len, iscritical, ctrlp) LDAP_CHAR * oid LDAP_CHAR * bv_val int bv_len int iscritical LDAPControl * ctrlp = NO_INIT CODE: { LDAPControl *ctrl = malloc(sizeof(LDAPControl)); ctrl->ldctl_oid = ber_strdup(oid); ber_mem2bv(bv_val, bv_len, 1, &ctrl->ldctl_value); ctrl->ldctl_iscritical = iscritical; ctrlp = ctrl; RETVAL = 0; } OUTPUT: RETVAL ctrlp void ldap_control_free (ctrl) LDAPControl *ctrl BerElement * ber_alloc_t(options); int options