Subject: | Extended operation support |
Hi,
Please see attached patch for adding extended operations to Net::LDAPapi, including an implementation of whoami. Feedback welcomed.
Cheers,
Phillip
Subject: | Net-LDAPapi-3.0.3-extended-operations.patch |
diff -Bbur Net-LDAPapi-3.0.3/LDAPapi.pm Net-LDAPapi-3.0.3.1/LDAPapi.pm
--- Net-LDAPapi-3.0.3/LDAPapi.pm 2008-08-21 18:03:18.000000000 +1200
+++ Net-LDAPapi-3.0.3.1/LDAPapi.pm 2015-04-09 01:03:10.000000000 +1200
@@ -21,6 +21,8 @@
ldap_rename ldap_rename_s
ldap_compare_ext ldap_compare_ext_s ldap_delete_ext
ldap_delete_ext_s ldap_search_ext ldap_search_ext_s ldap_result
+ ldap_extended_operation ldap_extended_operation_s ldap_parse_extended_result
+ ldap_parse_whoami ldap_whoami ldap_whoami_s
ldap_msgfree ldap_msg_free ldap_msgid ldap_msgtype
ldap_get_lderrno ldap_set_lderrno ldap_parse_result ldap_err2string
ldap_count_entries ldap_first_entry ldap_next_entry ldap_get_dn
@@ -1114,6 +1116,31 @@
return %result;
} # end of parse_result(...)
+sub parse_extended_result {
+ my ($self, @args) = @_;
+
+ my ($msg, $freeMsg) = $self->rearrange(['MSG', 'FREEMSG'], @args);
+
+ my ($status, %result);
+
+ $freeMsg = 0 unless $freeMsg;
+ $msg = $self->{"msg"} unless $msg;
+
+ my ($retoidp, $retdatap);
+
+ $status =
+ ldap_parse_extended_result($self->{"ld"}, $msg, $retoidp, $retdatap, $freeMsg);
+
+ $self->errorize($status);
+ if( $status != $self->LDAP_SUCCESS ) {
+ return undef;
+ }
+
+ $result{"retoidp"} = $retoidp;
+ $result{"retdatap"} = $retdatap;
+
+ return %result;
+} # end of parse_extended_result(...)
# needs docs bellow in POD. XXX
sub parse_intermediate {
@@ -1147,6 +1174,29 @@
return %result;
} # end of parse_result(...)
+sub parse_whoami {
+ my ($self, @args) = @_;
+
+ my ($msg) = $self->rearrange(['MSG'], @args);
+
+ my ($status, %result);
+
+ $msg = $self->{"msg"} unless $msg;
+
+ my ($authzid);
+
+ $status =
+ ldap_parse_whoami($self->{"ld"}, $msg, $authzid);
+
+ $self->errorize($status);
+ if( $status != $self->LDAP_SUCCESS ) {
+ return undef;
+ }
+
+ #$result{"authzid"} = $authzid;
+
+ return $authzid;
+} # end of parse_whoami(...)
sub perror
{
@@ -1623,6 +1673,110 @@
return $self->search_s(@args);
} # end of search_ext_s
+sub extended_operation
+{
+ my ($self, @args) = @_;
+ my ($msgid, $status, $sctrls, $cctrls);
+
+ my ($oid, $berval, $serverctrls, $clientctrls) =
+ $self->rearrange(['OID', 'BERVAL',
+ 'SCTRLS', 'CCTRLS'],
+ @args);
+
+ $sctrls = $self->create_controls_array(@$serverctrls) if $serverctrls;
+ $cctrls = $self->create_controls_array(@$clientctrls) if $clientctrls;
+
+ $status = ldap_extended_operation($self->{"ld"}, $oid, $berval, length($berval),
+ $sctrls, $cctrls,
+ $msgid);
+
+ ldap_controls_array_free($sctrls) if $sctrls;
+ ldap_controls_array_free($cctrls) if $cctrls;
+
+ $self->errorize($status);
+ if( $status != $self->LDAP_SUCCESS ) {
+ return undef;
+ }
+
+ return $msgid;
+} # end of extended_operation
+
+sub extended_operation_s
+{
+ my ($self, @args) = @_;
+ my ($status, $retoidp, $retdatap, $sctrls, $cctrls);
+
+ my ($oid, $berval, $serverctrls, $clientctrls, $result) =
+ $self->rearrange(['OID', 'BERVAL',
+ 'SCTRLS', 'CCTRLS', 'RESULT'],
+ @args);
+
+ $sctrls = $self->create_controls_array(@$serverctrls) if $serverctrls;
+ $cctrls = $self->create_controls_array(@$clientctrls) if $clientctrls;
+
+ $status = ldap_extended_operation_s($self->{"ld"}, $oid, $berval, length($berval),
+ $sctrls, $cctrls,
+ $retoidp, $retdatap);
+
+ ldap_controls_array_free($sctrls) if $sctrls;
+ ldap_controls_array_free($cctrls) if $cctrls;
+
+ $self->errorize($status);
+
+ $result->{'retoidp'} = $retoidp;
+ $result->{'retdatap'} = $retdatap;
+
+ return $status;
+} # end of extended_operation_s
+
+sub whoami
+{
+ my ($self, @args) = @_;
+ my ($msgid, $status, $sctrls, $cctrls);
+
+ my ($serverctrls, $clientctrls) =
+ $self->rearrange(['SCTRLS', 'CCTRLS'],
+ @args);
+
+ $sctrls = $self->create_controls_array(@$serverctrls) if $serverctrls;
+ $cctrls = $self->create_controls_array(@$clientctrls) if $clientctrls;
+
+ $status = ldap_whoami($self->{"ld"}, $sctrls, $cctrls, $msgid);
+
+ ldap_controls_array_free($sctrls) if $sctrls;
+ ldap_controls_array_free($cctrls) if $cctrls;
+
+ $self->errorize($status);
+ if( $status != $self->LDAP_SUCCESS ) {
+ return undef;
+ }
+
+ return $msgid;
+} # end of whoami
+
+sub whoami_s
+{
+ my ($self, @args) = @_;
+ my ($status, $authzidOut, $sctrls, $cctrls);
+
+ my ($serverctrls, $clientctrls, $authzid) =
+ $self->rearrange(['SCTRLS', 'CCTRLS', 'AUTHZID'],
+ @args);
+
+ $sctrls = $self->create_controls_array(@$serverctrls) if $serverctrls;
+ $cctrls = $self->create_controls_array(@$clientctrls) if $clientctrls;
+
+ $status = ldap_whoami_s($self->{"ld"}, $authzidOut, $sctrls, $cctrls);
+
+ ldap_controls_array_free($sctrls) if $sctrls;
+ ldap_controls_array_free($cctrls) if $cctrls;
+
+ $self->errorize($status);
+
+ $$authzid = $authzidOut;
+
+ return $status;
+} # end of whoami_s
sub count_references
{
diff -Bbur Net-LDAPapi-3.0.3/LDAPapi.xs Net-LDAPapi-3.0.3.1/LDAPapi.xs
--- Net-LDAPapi-3.0.3/LDAPapi.xs 2008-08-21 12:18:44.000000000 +1200
+++ Net-LDAPapi-3.0.3.1/LDAPapi.xs 2015-04-09 01:07:03.000000000 +1200
@@ -704,6 +704,110 @@
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)
@@ -951,6 +1055,33 @@
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
@@ -1002,6 +1133,28 @@
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)
@@ -1629,8 +1782,14 @@
LDAPControl *ctrl = malloc(sizeof(LDAPControl));
ctrl->ldctl_oid = ber_strdup(oid);
- ctrl->ldctl_value.bv_val = ber_strdup(bv_val);
- ctrl->ldctl_value.bv_len = bv_len;
+
+ // Following fails with bv_val containing otherwise valid in-string NULL characters, as
+ // ber_strdup(str) uses strlen() to determine the bytes to copy
+
+ // ctrl->ldctl_value.bv_val = ber_strdup(bv_val);
+ // ctrl->ldctl_value.bv_len = bv_len;
+ ber_str2bv(bv_val, bv_len, 1, &ctrl->ldctl_value);
+
ctrl->ldctl_iscritical = iscritical;
ctrlp = ctrl;
diff -Bbur Net-LDAPapi-3.0.3/typemap Net-LDAPapi-3.0.3.1/typemap
--- Net-LDAPapi-3.0.3/typemap 2008-08-21 12:18:44.000000000 +1200
+++ Net-LDAPapi-3.0.3.1/typemap 2012-01-20 02:46:10.000000000 +1300
@@ -16,6 +16,7 @@
BerElement ** T_PTR
LDAPVersion * T_PTR
LDAPMod * T_PTR
+LDAPMod ** T_PTR
struct berval * T_PTR
struct berval ** T_PTR
struct timeval * T_PTR