+ if ( op->o_tag != LDAP_REQ_EXTENDED
+ || strcmp( (const char *) opdata, LDAP_EXOP_START_TLS ) )
+ {
+ /* these checks don't apply to StartTLS */
+
+ if( op->o_tag == LDAP_REQ_EXTENDED ) {
+ /* threat other extended operations as update ops */
+ updateop++;
+ }
+
+ if( op->o_transport_ssf < ssf->sss_transport ) {
+ *text = "transport confidentiality required";
+ return LDAP_CONFIDENTIALITY_REQUIRED;
+ }
+
+ if( op->o_tls_ssf < ssf->sss_tls ) {
+ *text = "TLS confidentiality required";
+ return LDAP_CONFIDENTIALITY_REQUIRED;
+ }
+
+ if( op->o_tag != LDAP_REQ_BIND || opdata == NULL ) {
+ /* these checks don't apply to SASL bind */
+
+ if( op->o_sasl_ssf < ssf->sss_sasl ) {
+ *text = "SASL confidentiality required";
+ return LDAP_CONFIDENTIALITY_REQUIRED;
+ }
+
+ if( op->o_ssf < ssf->sss_ssf ) {
+ *text = "confidentiality required";
+ return LDAP_CONFIDENTIALITY_REQUIRED;
+ }
+ }
+
+ if( updateop ) {
+ if( op->o_transport_ssf < ssf->sss_update_transport ) {
+ *text = "transport update confidentiality required";
+ return LDAP_CONFIDENTIALITY_REQUIRED;
+ }
+
+ if( op->o_tls_ssf < ssf->sss_update_tls ) {
+ *text = "TLS update confidentiality required";
+ return LDAP_CONFIDENTIALITY_REQUIRED;
+ }
+
+ if( op->o_sasl_ssf < ssf->sss_update_sasl ) {
+ *text = "SASL update confidentiality required";
+ return LDAP_CONFIDENTIALITY_REQUIRED;
+ }
+
+ if( op->o_ssf < ssf->sss_update_ssf ) {
+ *text = "update confidentiality required";
+ return LDAP_CONFIDENTIALITY_REQUIRED;
+ }
+
+ if( op->o_ndn.bv_len == 0 ) {
+ *text = "modifications require authentication";
+ return LDAP_OPERATIONS_ERROR;
+ }
+ }
+ }
+
+ if ( op->o_tag != LDAP_REQ_BIND && ( op->o_tag != LDAP_REQ_EXTENDED ||
+ strcmp( (const char *) opdata, LDAP_EXOP_START_TLS ) ) )
+ {
+ /* these checks don't apply to Bind or StartTLS */
+
+ if( requires & SLAP_REQUIRE_STRONG ) {
+ /* should check mechanism */
+ if( op->o_authmech.bv_len == 0 || op->o_dn.bv_len == 0 )
+ {
+ *text = "strong authentication required";
+ return LDAP_STRONG_AUTH_REQUIRED;
+ }
+ }
+
+ if( requires & SLAP_REQUIRE_SASL ) {
+ if( op->o_authmech.bv_len == 0 || op->o_dn.bv_len == 0 )
+ {
+ *text = "SASL authentication required";
+ return LDAP_STRONG_AUTH_REQUIRED;
+ }
+ }
+
+ if( requires & SLAP_REQUIRE_AUTHC ) {
+ if( op->o_dn.bv_len == 0 ) {
+ *text = "authentication required";
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
+ }
+
+ if( requires & SLAP_REQUIRE_BIND ) {
+ int version;
+ ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+ version = conn->c_protocol;
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+
+ if( !version ) {
+ /* no bind has occurred */
+ *text = "BIND required";
+ return LDAP_OPERATIONS_ERROR;
+ }
+ }
+
+ if( requires & SLAP_REQUIRE_LDAP_V3 ) {
+ if( op->o_protocol < LDAP_VERSION3 ) {
+ /* no bind has occurred */
+ *text = "operation restricted to LDAPv3 clients";
+ return LDAP_OPERATIONS_ERROR;
+ }
+ }
+ }
+
+ if( restrictops & opflag ) {
+ if( restrictops == SLAP_RESTRICT_OP_READS ) {
+ *text = "read operations restricted";
+ } else {
+ *text = "operation restricted";
+ }
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
+