LDAPConn * nsldapi_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb, int connect, int bind ) { int rc; LDAPConn *lc; LDAPServer *prevsrv, *srv; Sockbuf *sb = NULL; /* * make a new LDAP server connection */ if (( lc = (LDAPConn *)NSLDAPI_CALLOC( 1, sizeof( LDAPConn ))) == NULL || ( !use_ldsb && ( sb = ber_sockbuf_alloc()) == NULL )) { if ( lc != NULL ) { NSLDAPI_FREE( (char *)lc ); } LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL ); return( NULL ); } LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK ); if ( !use_ldsb ) { /* * we have allocated a new sockbuf * set I/O routines to match those in default LDAP sockbuf */ IFP sb_fn; struct lber_x_ext_io_fns extiofns; extiofns.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE; if ( ber_sockbuf_get_option( ld->ld_sbp, LBER_SOCKBUF_OPT_EXT_IO_FNS, &extiofns ) == 0 ) { ber_sockbuf_set_option( sb, LBER_SOCKBUF_OPT_EXT_IO_FNS, &extiofns ); } if ( ber_sockbuf_get_option( ld->ld_sbp, LBER_SOCKBUF_OPT_READ_FN, (void *)&sb_fn ) == 0 && sb_fn != NULL ) { ber_sockbuf_set_option( sb, LBER_SOCKBUF_OPT_READ_FN, (void *)sb_fn ); } if ( ber_sockbuf_get_option( ld->ld_sbp, LBER_SOCKBUF_OPT_WRITE_FN, (void *)&sb_fn ) == 0 && sb_fn != NULL ) { ber_sockbuf_set_option( sb, LBER_SOCKBUF_OPT_WRITE_FN, (void *)sb_fn ); } } lc->lconn_sb = ( use_ldsb ) ? ld->ld_sbp : sb; lc->lconn_version = ld->ld_version; /* inherited */ LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK ); if ( connect ) { prevsrv = NULL; /* * save the return code for later */ for ( srv = *srvlistp; srv != NULL; srv = srv->lsrv_next ) { rc = nsldapi_connect_to_host( ld, lc->lconn_sb, srv->lsrv_host, srv->lsrv_port, ( srv->lsrv_options & LDAP_SRV_OPT_SECURE ) != 0, &lc->lconn_krbinstance ); if (rc != -1) { break; } prevsrv = srv; } if ( srv == NULL ) { if ( !use_ldsb ) { NSLDAPI_FREE( (char *)lc->lconn_sb ); } NSLDAPI_FREE( (char *)lc ); /* nsldapi_open_ldap_connection has already set ld_errno */ return( NULL ); } if ( prevsrv == NULL ) { *srvlistp = srv->lsrv_next; } else { prevsrv->lsrv_next = srv->lsrv_next; } lc->lconn_server = srv; } if (ld->ld_options & LDAP_BITOPT_ASYNC && rc == -2) { lc->lconn_status = LDAP_CONNST_CONNECTING; } else { lc->lconn_status = LDAP_CONNST_CONNECTED; } lc->lconn_next = ld->ld_conns; ld->ld_conns = lc; /* * XXX for now, we always do a synchronous bind. This will have * to change in the long run... */ if ( bind ) { int err, lderr, freepasswd, authmethod; char *binddn, *passwd; LDAPConn *savedefconn; freepasswd = err = 0; if ( ld->ld_rebind_fn == NULL ) { binddn = passwd = ""; authmethod = LDAP_AUTH_SIMPLE; } else { if (( lderr = (*ld->ld_rebind_fn)( ld, &binddn, &passwd, &authmethod, 0, ld->ld_rebind_arg )) == LDAP_SUCCESS ) { freepasswd = 1; } else { LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); err = -1; } } if ( err == 0 ) { savedefconn = ld->ld_defconn; ld->ld_defconn = lc; ++lc->lconn_refcnt; /* avoid premature free */ /* * when binding, we will back down as low as LDAPv2 * if we get back "protocol error" from bind attempts */ for ( ;; ) { /* LDAP_MUTEX_UNLOCK(ld, LDAP_CONN_LOCK); */ if (( lderr = ldap_bind_s( ld, binddn, passwd, authmethod )) == LDAP_SUCCESS ) { /* LDAP_MUTEX_LOCK(ld, LDAP_CONN_LOCK); */ break; } /* LDAP_MUTEX_LOCK(ld, LDAP_CONN_LOCK); */ if ( lc->lconn_version <= LDAP_VERSION2 || lderr != LDAP_PROTOCOL_ERROR ) { err = -1; break; } --lc->lconn_version; /* try lower version */ } --lc->lconn_refcnt; ld->ld_defconn = savedefconn; } if ( freepasswd ) { (*ld->ld_rebind_fn)( ld, &binddn, &passwd, &authmethod, 1, ld->ld_rebind_arg ); } if ( err != 0 ) { nsldapi_free_connection( ld, lc, NULL, NULL, 1, 0 ); lc = NULL; } } return( lc ); }
/* * always protected by conn_mutex * optionally protected by req_mutex and res_mutex */ LDAPConn * ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb, int connect, LDAPreqinfo *bind, int m_req, int m_res ) { LDAPConn *lc; int async = 0; LDAP_ASSERT_MUTEX_OWNER( &ld->ld_conn_mutex ); Debug( LDAP_DEBUG_TRACE, "ldap_new_connection %d %d %d\n", use_ldsb, connect, (bind != NULL) ); /* * make a new LDAP server connection * XXX open connection synchronously for now */ lc = (LDAPConn *)LDAP_CALLOC( 1, sizeof( LDAPConn ) ); if ( lc == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return( NULL ); } if ( use_ldsb ) { assert( ld->ld_sb != NULL ); lc->lconn_sb = ld->ld_sb; } else { lc->lconn_sb = ber_sockbuf_alloc(); if ( lc->lconn_sb == NULL ) { LDAP_FREE( (char *)lc ); ld->ld_errno = LDAP_NO_MEMORY; return( NULL ); } } if ( connect ) { LDAPURLDesc **srvp, *srv = NULL; async = LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_CONNECT_ASYNC ); for ( srvp = srvlist; *srvp != NULL; srvp = &(*srvp)->lud_next ) { int rc; rc = ldap_int_open_connection( ld, lc, *srvp, async ); if ( rc != -1 ) { srv = *srvp; if ( ld->ld_urllist_proc && ( !async || rc != -2 ) ) { ld->ld_urllist_proc( ld, srvlist, srvp, ld->ld_urllist_params ); } break; } } if ( srv == NULL ) { if ( !use_ldsb ) { ber_sockbuf_free( lc->lconn_sb ); } LDAP_FREE( (char *)lc ); ld->ld_errno = LDAP_SERVER_DOWN; return( NULL ); } lc->lconn_server = ldap_url_dup( srv ); } lc->lconn_status = async ? LDAP_CONNST_CONNECTING : LDAP_CONNST_CONNECTED; lc->lconn_next = ld->ld_conns; ld->ld_conns = lc; if ( connect ) { #ifdef HAVE_TLS if ( lc->lconn_server->lud_exts ) { int rc, ext = find_tls_ext( lc->lconn_server ); if ( ext ) { LDAPConn *savedefconn; savedefconn = ld->ld_defconn; ++lc->lconn_refcnt; /* avoid premature free */ ld->ld_defconn = lc; LDAP_REQ_UNLOCK_IF(m_req); LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); LDAP_RES_UNLOCK_IF(m_res); rc = ldap_start_tls_s( ld, NULL, NULL ); LDAP_RES_LOCK_IF(m_res); LDAP_MUTEX_LOCK( &ld->ld_conn_mutex ); LDAP_REQ_LOCK_IF(m_req); ld->ld_defconn = savedefconn; --lc->lconn_refcnt; if ( rc != LDAP_SUCCESS && ext == 2 ) { ldap_free_connection( ld, lc, 1, 0 ); return NULL; } } } #endif } if ( bind != NULL ) { int err = 0; LDAPConn *savedefconn; /* Set flag to prevent additional referrals * from being processed on this * connection until the bind has completed */ lc->lconn_rebind_inprogress = 1; /* V3 rebind function */ if ( ld->ld_rebind_proc != NULL) { LDAPURLDesc *srvfunc; srvfunc = ldap_url_dup( *srvlist ); if ( srvfunc == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; err = -1; } else { savedefconn = ld->ld_defconn; ++lc->lconn_refcnt; /* avoid premature free */ ld->ld_defconn = lc; Debug( LDAP_DEBUG_TRACE, "Call application rebind_proc\n", 0, 0, 0); LDAP_REQ_UNLOCK_IF(m_req); LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); LDAP_RES_UNLOCK_IF(m_res); err = (*ld->ld_rebind_proc)( ld, bind->ri_url, bind->ri_request, bind->ri_msgid, ld->ld_rebind_params ); LDAP_RES_LOCK_IF(m_res); LDAP_MUTEX_LOCK( &ld->ld_conn_mutex ); LDAP_REQ_LOCK_IF(m_req); ld->ld_defconn = savedefconn; --lc->lconn_refcnt; if ( err != 0 ) { err = -1; ldap_free_connection( ld, lc, 1, 0 ); lc = NULL; } ldap_free_urldesc( srvfunc ); } } else { int msgid, rc; struct berval passwd = BER_BVNULL; savedefconn = ld->ld_defconn; ++lc->lconn_refcnt; /* avoid premature free */ ld->ld_defconn = lc; Debug( LDAP_DEBUG_TRACE, "anonymous rebind via ldap_sasl_bind(\"\")\n", 0, 0, 0); LDAP_REQ_UNLOCK_IF(m_req); LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); LDAP_RES_UNLOCK_IF(m_res); rc = ldap_sasl_bind( ld, "", LDAP_SASL_SIMPLE, &passwd, NULL, NULL, &msgid ); if ( rc != LDAP_SUCCESS ) { err = -1; } else { for ( err = 1; err > 0; ) { struct timeval tv = { 0, 100000 }; LDAPMessage *res = NULL; switch ( ldap_result( ld, msgid, LDAP_MSG_ALL, &tv, &res ) ) { case -1: err = -1; break; case 0: #ifdef LDAP_R_COMPILE ldap_pvt_thread_yield(); #endif break; case LDAP_RES_BIND: rc = ldap_parse_result( ld, res, &err, NULL, NULL, NULL, NULL, 1 ); if ( rc != LDAP_SUCCESS ) { err = -1; } else if ( err != LDAP_SUCCESS ) { err = -1; } /* else err == LDAP_SUCCESS == 0 */ break; default: Debug( LDAP_DEBUG_TRACE, "ldap_new_connection %p: " "unexpected response %d " "from BIND request id=%d\n", (void *) ld, ldap_msgtype( res ), msgid ); err = -1; break; } } } LDAP_RES_LOCK_IF(m_res); LDAP_MUTEX_LOCK( &ld->ld_conn_mutex ); LDAP_REQ_LOCK_IF(m_req); ld->ld_defconn = savedefconn; --lc->lconn_refcnt; if ( err != 0 ) { ldap_free_connection( ld, lc, 1, 0 ); lc = NULL; } } if ( lc != NULL ) lc->lconn_rebind_inprogress = 0; } return( lc ); }
void slapi_int_connection_init_pb( Slapi_PBlock *pb, ber_tag_t tag ) { Connection *conn; Operation *op; ber_len_t max = sockbuf_max_incoming; conn = (Connection *) slapi_ch_calloc( 1, sizeof(Connection) ); LDAP_STAILQ_INIT( &conn->c_pending_ops ); op = (Operation *) slapi_ch_calloc( 1, sizeof(OperationBuffer) ); op->o_hdr = &((OperationBuffer *) op)->ob_hdr; op->o_controls = ((OperationBuffer *) op)->ob_controls; op->o_callback = (slap_callback *) slapi_ch_calloc( 1, sizeof(slap_callback) ); op->o_callback->sc_response = slapi_int_response; op->o_callback->sc_cleanup = NULL; op->o_callback->sc_private = pb; op->o_callback->sc_next = NULL; conn->c_pending_ops.stqh_first = op; /* connection object authorization information */ conn->c_authtype = LDAP_AUTH_NONE; BER_BVZERO( &conn->c_authmech ); BER_BVZERO( &conn->c_dn ); BER_BVZERO( &conn->c_ndn ); conn->c_listener = &slapi_listener; ber_dupbv( &conn->c_peer_domain, (struct berval *)&slap_unknown_bv ); ber_dupbv( &conn->c_peer_name, (struct berval *)&slap_unknown_bv ); LDAP_STAILQ_INIT( &conn->c_ops ); BER_BVZERO( &conn->c_sasl_bind_mech ); conn->c_sasl_authctx = NULL; conn->c_sasl_sockctx = NULL; conn->c_sasl_extra = NULL; conn->c_sb = ber_sockbuf_alloc(); ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max ); conn->c_currentber = NULL; /* should check status of thread calls */ ldap_pvt_thread_mutex_init( &conn->c_mutex ); ldap_pvt_thread_mutex_init( &conn->c_write1_mutex ); ldap_pvt_thread_mutex_init( &conn->c_write2_mutex ); ldap_pvt_thread_cond_init( &conn->c_write1_cv ); ldap_pvt_thread_cond_init( &conn->c_write2_cv ); ldap_pvt_thread_mutex_lock( &conn->c_mutex ); conn->c_n_ops_received = 0; conn->c_n_ops_executing = 0; conn->c_n_ops_pending = 0; conn->c_n_ops_completed = 0; conn->c_n_get = 0; conn->c_n_read = 0; conn->c_n_write = 0; conn->c_protocol = LDAP_VERSION3; conn->c_activitytime = conn->c_starttime = slap_get_time(); /* * A real connection ID is required, because syncrepl associates * pending CSNs with unique ( connection, operation ) tuples. * Setting a fake connection ID will cause slap_get_commit_csn() * to return a stale value. */ connection_assign_nextid( conn ); conn->c_conn_state = 0x01; /* SLAP_C_ACTIVE */ conn->c_struct_state = 0x02; /* SLAP_C_USED */ conn->c_ssf = conn->c_transport_ssf = local_ssf; conn->c_tls_ssf = 0; backend_connection_init( conn ); conn->c_send_ldap_result = slap_send_ldap_result; conn->c_send_search_entry = slap_send_search_entry; conn->c_send_ldap_extended = slap_send_ldap_extended; conn->c_send_search_reference = slap_send_search_reference; /* operation object */ op->o_tag = tag; op->o_protocol = LDAP_VERSION3; BER_BVZERO( &op->o_authmech ); op->o_time = slap_get_time(); op->o_do_not_cache = 1; op->o_threadctx = ldap_pvt_thread_pool_context(); op->o_tmpmemctx = NULL; op->o_tmpmfuncs = &ch_mfuncs; op->o_conn = conn; op->o_connid = conn->c_connid; op->o_bd = frontendDB; /* extensions */ slapi_int_create_object_extensions( SLAPI_X_EXT_OPERATION, op ); slapi_int_create_object_extensions( SLAPI_X_EXT_CONNECTION, conn ); pb->pb_rs = (SlapReply *)slapi_ch_calloc( 1, sizeof(SlapReply) ); pb->pb_op = op; pb->pb_conn = conn; pb->pb_intop = 1; ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); }
int ldap_create( LDAP **ldp ) { LDAP *ld; struct ldapoptions *gopts; *ldp = NULL; /* Get pointer to global option structure */ if ( (gopts = LDAP_INT_GLOBAL_OPT()) == NULL) { return LDAP_NO_MEMORY; } /* Initialize the global options, if not already done. */ if( gopts->ldo_valid != LDAP_INITIALIZED ) { ldap_int_initialize(gopts, NULL); if ( gopts->ldo_valid != LDAP_INITIALIZED ) return LDAP_LOCAL_ERROR; } Debug( LDAP_DEBUG_TRACE, "ldap_create\n", 0, 0, 0 ); if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) { return( LDAP_NO_MEMORY ); } /* copy the global options */ AC_MEMCPY(&ld->ld_options, gopts, sizeof(ld->ld_options)); ld->ld_valid = LDAP_VALID_SESSION; /* but not pointers to malloc'ed items */ ld->ld_options.ldo_sctrls = NULL; ld->ld_options.ldo_cctrls = NULL; ld->ld_options.ldo_defludp = NULL; #ifdef HAVE_CYRUS_SASL ld->ld_options.ldo_def_sasl_mech = gopts->ldo_def_sasl_mech ? LDAP_STRDUP( gopts->ldo_def_sasl_mech ) : NULL; ld->ld_options.ldo_def_sasl_realm = gopts->ldo_def_sasl_realm ? LDAP_STRDUP( gopts->ldo_def_sasl_realm ) : NULL; ld->ld_options.ldo_def_sasl_authcid = gopts->ldo_def_sasl_authcid ? LDAP_STRDUP( gopts->ldo_def_sasl_authcid ) : NULL; ld->ld_options.ldo_def_sasl_authzid = gopts->ldo_def_sasl_authzid ? LDAP_STRDUP( gopts->ldo_def_sasl_authzid ) : NULL; #endif #ifdef HAVE_TLS /* We explicitly inherit the SSL_CTX, don't need the names/paths. Leave * them empty to allow new SSL_CTX's to be created from scratch. */ memset( &ld->ld_options.ldo_tls_info, 0, sizeof( ld->ld_options.ldo_tls_info )); ld->ld_options.ldo_tls_ctx = NULL; #endif if ( gopts->ldo_defludp ) { ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp); if ( ld->ld_options.ldo_defludp == NULL ) goto nomem; } if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) goto nomem; ld->ld_lberoptions = LBER_USE_DER; ld->ld_sb = ber_sockbuf_alloc( ); if ( ld->ld_sb == NULL ) goto nomem; #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_init( &ld->ld_req_mutex ); ldap_pvt_thread_mutex_init( &ld->ld_res_mutex ); ldap_pvt_thread_mutex_init( &ld->ld_conn_mutex ); #endif *ldp = ld; return LDAP_SUCCESS; nomem: ldap_free_select_info( ld->ld_selectinfo ); ldap_free_urllist( ld->ld_options.ldo_defludp ); #ifdef HAVE_CYRUS_SASL LDAP_FREE( ld->ld_options.ldo_def_sasl_authzid ); LDAP_FREE( ld->ld_options.ldo_def_sasl_authcid ); LDAP_FREE( ld->ld_options.ldo_def_sasl_realm ); LDAP_FREE( ld->ld_options.ldo_def_sasl_mech ); #endif LDAP_FREE( (char *)ld ); return LDAP_NO_MEMORY; }
int newthread_start(PeerClient *client_info) { ber_tag_t tag; ber_int_t msgid; ber_int_t msgid_before; ber_len_t len; BerElement *ber; Sockbuf *sb; ber_len_t max = 409600; ber_tag_t LdapOpt; int rc; TcpHeadInfo socketTcpHead; int client_conn = client_info->client_conn; int loop=0; PrintCap capInfor; capInfor.peer = *client_info; #ifdef DEBUG /* enable debugging */ int ival = -1; ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &ival ); #endif sb = ber_sockbuf_alloc(); ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_MAX_INCOMING, &max ); while(1){ loop ++; //printf(">>>>>>>>>>>>>>>>>While Loop the %d Packet<<<<<<<<<<<<<<<<<<<<<<\n", loop); /*--------------------------------------------------------------------- Recieve the data from Socket, Function of "recv" is a standard func of getting data from socket, the purpose of "recv" is getting the TCP head related infor that sent from client, and put into a struct. This struct must be exactly aligned with client side,otherwis the data may not readable ----------------------------------------------------------------------*/ //printf("\n\nDebug:-------Recv Data of TCP head\n"); rc = recv(client_conn, (char *)&socketTcpHead, sizeof(socketTcpHead),0); if(rc < 0){ printf("TCP Head Recv failed!\n"); exit (0); } capInfor.PackageHead = socketTcpHead; #ifdef DEBUGA printf("TCP Head info len: %d\n", rc); printf("Time tag: %u:%u\n", PCAP.TimeStmap.tv_sec,PCAP.TimeStmap.tv_usec ); printf("Pkt number: %d\n", capInfor.PackageHead.GetPackageNumber); printf("IP layer len: %d\n", capInfor.PackageHead.size_ip); printf("TCP layer len: %d\n", capInfor.PackageHead.size_tcp); printf("Protocol: %d\n", capInfor.PackageHead.Prctl); printf("Src IP: %s\n", capInfor.PackageHead.ipSrc); printf("Dst IP: %s\n", capInfor.PackageHead.ipDst); printf("Payload len %d\n", capInfor.PackageHead.Payload_size); #endif /*---------------------------------------------------------------------- "ber_sockbuf_add_io" is a function that supplied by "liblber" , it can get the socket information like "recv", that means here no need to call recv agian. Why here use the "ber_sockbuf_add_io" instead of recv? this time the payload, actually there is ldap protocol data streams are sent by client, and LDAP protocol use BER(ASN.1) encode method,if use this function, handy for decode the ldap information. Like recv, it also is stuck before any data coming. sb : socket buff, storing the data gather from socket. -------------------------------------------------------------------------*/ //printf("Debug:-------Recv Data of Payload infor\n"); ber_sockbuf_add_io( sb, &ber_sockbuf_io_tcp, LBER_SBIOD_LEVEL_PROVIDER, (void *)&client_conn ); //printf("Debug:-------Decode BER starting\n"); //Create and allocate memory for BER struct, BER struct can store the infor which was parsed by above function ber = ber_alloc_t(LBER_USE_DER); if( ber == NULL ) { perror( "ber_alloc_t" ); return( EXIT_FAILURE ); } /*---------------------------------------------------------------------- "ber_get_next", it links the socket buff and BER struct. now all ldap data has been transfer to the struct of ber. lib of lber and ldap can use it for ldap layer decoding. -------------------------------------------------------------------------*/ for (;;) { tag = ber_get_next( sb, &len, ber); if( tag != LBER_ERROR ) break; if( errno == EWOULDBLOCK ) continue; if( errno == EAGAIN ) continue; //perror( "ber_get_next" ); return( EXIT_FAILURE ); } //determine the Ldap option kind LdapOpt=checkLDAPoption(ber, &msgid); if(LdapOpt==LBER_ERROR){ printf("|-Error:LDAP option decode failed.\n"); } /* -1 Sem: Sync the displaying in STDOUT. Only 1 thread is able to throw the information to screen in same time, othre thread is waiting for the bin_sem become a non-zero(1) value to take the charge in output */ //printf("Debug:------Sem Wait!\n"); /*-----------------Sync-Area--BEGIN---Semaphore-Control-------------------------------*/ /*---Below function displays decoded information of PDU to screen inside each thread--*/ /*---Screen resource would be used by different threads, in order to make a complete--*/ /*---LDAP packet output,I use semaphore to sync each thread. the below command lines--*/ /*---realize a packet decode and display.---------------------------------------------*/ /*-*/ sem_wait(&bin_sem); /*-*/ //printf("Debug:------Sem OK go ahead!\n"); /*-*/ msgid_before = msgid; /*-*/ /*-*/ //printf("Debug:------Format output infor\n"); /*-*/ FormatPrintLdap(LdapOpt, msgid, ber, capInfor); /*-*/ /*-*/ /* +1 Sem: After this time the LDAP PDU Decoding&Outputing completed, /*-*/ // plus 1 to set the bin_sem, then other thread will be able to use the /*-*/ // STDOUT. /*-*/ /*-*/ sem_post(&bin_sem);// +1 Sem /*-----------------Sync-Area---END----Semaphore-Control--------------------------------*/ } //close(client_conn); }
LDAP_CALL ldap_init( const char *defhost, int defport ) { LDAP *ld; if ( !nsldapi_initialized ) { nsldapi_initialize_defaults(); } if ( defport < 0 || defport > LDAP_PORT_MAX ) { LDAPDebug( LDAP_DEBUG_ANY, "ldap_init: port %d is invalid (port numbers must range from 1 to %d)\n", defport, LDAP_PORT_MAX, 0 ); #if !defined( macintosh ) && !defined( DOS ) errno = EINVAL; #endif return( NULL ); } LDAPDebug( LDAP_DEBUG_TRACE, "ldap_init\n", 0, 0, 0 ); if ( (ld = (LDAP*)NSLDAPI_MALLOC( sizeof(struct ldap) )) == NULL ) { return( NULL ); } /* copy defaults */ SAFEMEMCPY( ld, &nsldapi_ld_defaults, sizeof( struct ldap )); if ( nsldapi_ld_defaults.ld_io_fns_ptr != NULL ) { if (( ld->ld_io_fns_ptr = (struct ldap_io_fns *)NSLDAPI_MALLOC( sizeof( struct ldap_io_fns ))) == NULL ) { NSLDAPI_FREE( (char *)ld ); return( NULL ); } /* struct copy */ *(ld->ld_io_fns_ptr) = *(nsldapi_ld_defaults.ld_io_fns_ptr); } /* call the new handle I/O callback if one is defined */ if ( ld->ld_extnewhandle_fn != NULL ) { /* * We always pass the session extended I/O argument to * the new handle callback. */ if ( ld->ld_extnewhandle_fn( ld, ld->ld_ext_session_arg ) != LDAP_SUCCESS ) { NSLDAPI_FREE( (char*)ld ); return( NULL ); } } /* allocate session-specific resources */ if (( ld->ld_sbp = ber_sockbuf_alloc()) == NULL || ( defhost != NULL && ( ld->ld_defhost = nsldapi_strdup( defhost )) == NULL ) || ((ld->ld_mutex = (void **) NSLDAPI_CALLOC( LDAP_MAX_LOCK, sizeof(void *))) == NULL )) { if ( ld->ld_sbp != NULL ) { ber_sockbuf_free( ld->ld_sbp ); } if( ld->ld_mutex != NULL ) { NSLDAPI_FREE( ld->ld_mutex ); } NSLDAPI_FREE( (char*)ld ); return( NULL ); } /* install Sockbuf I/O functions if set in LDAP * */ if ( ld->ld_extread_fn != NULL || ld->ld_extwrite_fn != NULL ) { struct lber_x_ext_io_fns lberiofns; memset( &lberiofns, 0, sizeof( lberiofns )); lberiofns.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE; lberiofns.lbextiofn_read = ld->ld_extread_fn; lberiofns.lbextiofn_write = ld->ld_extwrite_fn; lberiofns.lbextiofn_writev = ld->ld_extwritev_fn; lberiofns.lbextiofn_socket_arg = NULL; ber_sockbuf_set_option( ld->ld_sbp, LBER_SOCKBUF_OPT_EXT_IO_FNS, (void *)&lberiofns ); } #ifdef _SOLARIS_SDK /* Install the functions for IPv6 support */ /* code sequencing is critical from here to nsldapi_mutex_alloc_all */ if ( prldap_install_thread_functions( ld, 1 ) != 0 || prldap_install_io_functions( ld, 1 ) != 0 || prldap_install_dns_functions( ld ) != 0 ) { /* go through ld and free resources */ ldap_unbind( ld ); ld = NULL; return( NULL ); } #else /* allocate mutexes */ nsldapi_mutex_alloc_all( ld ); #endif /* set default port */ ld->ld_defport = ( defport == 0 ) ? LDAP_PORT : defport; return( ld ); }
static int NewConnection( ber_socket_t sfd, VDIR_CONNECTION **ppConnection, Sockbuf_IO *pSockbuf_IO ) { int retVal = LDAP_SUCCESS; ber_len_t max = SOCK_BUF_MAX_INCOMING; PVDIR_CONNECTION pConn; PSTR pszLocalErrMsg = NULL; if (VmDirAllocateMemory(sizeof(VDIR_CONNECTION), (PVOID *)&pConn) != 0) { retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, pszLocalErrMsg, "NewConnection: VmDirAllocateMemory call failed"); } pConn->bIsAnonymousBind = TRUE; // default to anonymous bind pConn->sd = sfd; retVal = VmDirGetNetworkInfoFromSocket(pConn->sd, pConn->szClientIP, sizeof(pConn->szClientIP), &pConn->dwClientPort, true); BAIL_ON_VMDIR_ERROR(retVal); retVal = VmDirGetNetworkInfoFromSocket(pConn->sd, pConn->szServerIP, sizeof(pConn->szServerIP), &pConn->dwServerPort, false); BAIL_ON_VMDIR_ERROR(retVal); VMDIR_LOG_DEBUG(VMDIR_LOG_MASK_ALL, "New connection (%s)", pConn->szClientIP); if ((pConn->sb = ber_sockbuf_alloc()) == NULL) { retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, pszLocalErrMsg, "New Connection (%s): ber_sockbuf_alloc() call failed with errno: %d", pConn->szClientIP, errno); } if (ber_sockbuf_ctrl(pConn->sb, LBER_SB_OPT_SET_MAX_INCOMING, &max) < 0) { retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, pszLocalErrMsg, "NewConnection (%s): ber_sockbuf_ctrl() failed while setting MAX_INCOMING", pConn->szClientIP); } if (ber_sockbuf_add_io(pConn->sb, pSockbuf_IO, LBER_SBIOD_LEVEL_PROVIDER, (void *)&sfd) != 0) { retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, pszLocalErrMsg, "NewConnection (%s): ber_sockbuf_addd_io() failed while setting LEVEL_PROVIDER", pConn->szClientIP); } //This is to disable NONBLOCK mode (when NULL passed in) if (ber_sockbuf_ctrl(pConn->sb, LBER_SB_OPT_SET_NONBLOCK, NULL) < 0) { retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, pszLocalErrMsg, "NewConnection (%s): ber_sockbuf_ctrl failed while setting NONBLOCK", pConn->szClientIP); } *ppConnection = pConn; cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg); return retVal; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "NewConnection failing with error %d", retVal); goto cleanup; }
int probe_main(probe_ctx *ctx, void *mutex) { LDAP *ldp; LDAPMessage *ldpres, *entry; SEXP_t *se_ldap_behaviors = NULL, *se_relative_dn = NULL; SEXP_t *se_suffix = NULL, *se_attribute = NULL; SEXP_t *sa_scope, *sv_op; SEXP_t *item; SEXP_t *probe_in; char *relative_dn = NULL; char *suffix = NULL, *xattribute = NULL; char *uri_list, *uri, *uri_save, *attr; int scope; char base[2048]; char *attrs[3]; bool a_pattern_match = false, rdn_pattern_match = false; /* runtime */ #if defined(PROBE_LDAP_MUTEX) assume_r(mutex != NULL, PROBE_EINIT); #endif probe_in = probe_ctx_getobject(ctx); se_ldap_behaviors = probe_obj_getent(probe_in, "behaviors", 1); if (se_ldap_behaviors != NULL) { sa_scope = probe_ent_getattrval(se_ldap_behaviors, "scope"); SEXP_free(se_ldap_behaviors); if (sa_scope == NULL) { dE("Atrribute `scope' is missing!"); return (PROBE_ENOATTR); } if (!SEXP_stringp(sa_scope)) { dE("Invalid value type of the `scope' attribute."); SEXP_free(sa_scope); return (PROBE_EINVAL); } if (SEXP_strcmp(sa_scope, "ONE") == 0) scope = LDAP_SCOPE_ONELEVEL; else if (SEXP_strcmp(sa_scope, "BASE") == 0) scope = LDAP_SCOPE_BASE; else if (SEXP_strcmp(sa_scope, "SUBTREE") == 0) scope = LDAP_SCOPE_SUBTREE; else { dE("Invalid value of the `scope' attribute."); SEXP_free(sa_scope); return (PROBE_EINVAL); } SEXP_free(sa_scope); } else scope = LDAP_SCOPE_BASE; #define get_string(dst, se_dst, obj, ent_name) \ do { \ SEXP_t *__sval; \ \ __sval = probe_obj_getentval (obj, ent_name, 1); \ \ if (__sval != NULL) { \ (dst) = SEXP_string_cstr (__sval); \ \ if ((dst) == NULL) { \ SEXP_free(__sval); \ return (PROBE_EINVAL); \ } \ \ (se_dst) = __sval; \ } else { \ return (PROBE_ENOATTR); \ } \ } while (0) get_string(suffix, se_suffix, probe_in, "suffix"); get_string(relative_dn, se_relative_dn, probe_in, "relative_dn"); get_string(xattribute, se_attribute, probe_in, "attribute"); if ((sv_op = probe_ent_getattrval(se_relative_dn, "operation")) != NULL) { if (SEXP_number_geti_32(sv_op) == OVAL_OPERATION_PATTERN_MATCH) rdn_pattern_match = true; SEXP_free(sv_op); } if ((sv_op = probe_ent_getattrval(se_attribute, "operation")) != NULL) { if (SEXP_number_geti_32(sv_op) == OVAL_OPERATION_PATTERN_MATCH) a_pattern_match = true; SEXP_free(sv_op); } /* * Construct the attribute array for ldap_search_* * * nil -> "1.1" * .* -> "*" * "foo" -> "foo" */ attrs[0] = "objectClass"; if (xattribute == NULL) attrs[1] = strdup("1.1"); /* no attibutes */ else if (a_pattern_match) attrs[1] = strdup("*"); /* collect all, we'll filter them afterwards */ else attrs[1] = xattribute; /* no pattern match, use the string directly */ attrs[2] = NULL; /* * Construct `base' */ assume_r(((relative_dn ? strlen(relative_dn) : 0) + ( suffix ? strlen(suffix) : 0) + 2) < (sizeof base/sizeof(char)), PROBE_ERANGE); if (relative_dn != NULL) { strcpy(base, relative_dn); strcat(base, ","); strcat(base, suffix); } else strcpy(base, suffix); /* * Get URIs */ if (ldap_get_option(NULL, LDAP_OPT_URI, &uri_list) != LDAP_OPT_SUCCESS) { item = probe_item_creat("ldap57_item", NULL, NULL); probe_item_setstatus(item, SYSCHAR_STATUS_ERROR); probe_item_collect(ctx, item); dE("ldap_get_option failed"); goto fail0; } /* * Query each URI */ for (;;) { char *entry_dn = NULL; if ((uri = strtok_r(uri_list, " ,", &uri_save)) == NULL) break; ldp = NULL; if (ldap_initialize(&ldp, uri) != LDAP_SUCCESS) continue; if (ldap_search_ext_s(ldp, base, scope, NULL, attrs, 0, NULL /* serverctrls */, NULL /* clientctrls */, NULL /* timeout */, 0, &ldpres) != LDAP_SUCCESS) { item = probe_item_creat("ldap57_item", NULL, NULL); probe_item_setstatus(item, SYSCHAR_STATUS_ERROR); probe_item_collect(ctx, item); dE("ldap_search_ext_s failed"); goto fail0; } entry = ldap_first_entry(ldp, ldpres); entry_dn = ldap_get_dn(ldp, entry); while (entry != NULL) { BerElement *berelm = NULL; attr = ldap_first_attribute(ldp, entry, &berelm); /* XXX: pattern match filter */ while (attr != NULL) { SEXP_t *se_value = NULL; ber_tag_t bertag = LBER_DEFAULT; ber_len_t berlen = 0; Sockbuf *berbuf = NULL; SEXP_t se_tmp_mem; berbuf = ber_sockbuf_alloc(); /* * Prepare the value (record) entity. Collect only * primitive (i.e. simple) types. */ se_value = probe_ent_creat1("value", NULL, NULL); probe_ent_setdatatype(se_value, OVAL_DATATYPE_RECORD); /* * XXX: does ber_get_next() return LBER_ERROR after the last value? */ while ((bertag = ber_get_next(berbuf, &berlen, berelm)) != LBER_ERROR) { SEXP_t *field = NULL; oval_datatype_t field_type = OVAL_DATATYPE_UNKNOWN; switch(bertag & LBER_ENCODING_MASK) { case LBER_PRIMITIVE: dI("Found primitive value, bertag = %u", bertag); break; case LBER_CONSTRUCTED: dW("Don't know how to handle LBER_CONSTRUCTED values"); /* FALLTHROUGH */ default: dW("Skipping attribute value, bertag = %u", bertag); continue; } assume_d(bertag & LBER_PRIMITIVE, NULL); switch(bertag & LBER_BIG_TAG_MASK) { case LBER_BOOLEAN: { /* LDAPTYPE_BOOLEAN */ ber_int_t val = -1; if (ber_get_boolean(berelm, &val) == LBER_ERROR) { dW("ber_get_boolean: LBER_ERROR"); /* XXX: set error status on field */ continue; } assume_d(val != -1, NULL); field = probe_ent_creat1("field", NULL, SEXP_number_newb_r(&se_tmp_mem, (bool)val)); field_type = OVAL_DATATYPE_BOOLEAN; SEXP_free_r(&se_tmp_mem); } break; case LBER_INTEGER: { /* LDAPTYPE_INTEGER */ ber_int_t val = -1; if (ber_get_int(berelm, &val) == LBER_ERROR) { dW("ber_get_int: LBER_ERROR"); /* XXX: set error status on field */ continue; } field = probe_ent_creat1("field", NULL, SEXP_number_newi_r(&se_tmp_mem, (int)val)); field_type = OVAL_DATATYPE_INTEGER; SEXP_free_r(&se_tmp_mem); } break; case LBER_BITSTRING: /* LDAPTYPE_BIT_STRING */ dW("LBER_BITSTRING: not implemented"); continue; case LBER_OCTETSTRING: { /* * LDAPTYPE_PRINTABLE_STRING * LDAPTYPE_NUMERIC_STRING * LDAPTYPE_DN_STRING * LDAPTYPE_BINARY (?) */ char *val = NULL; if (ber_get_stringa(berelm, &val) == LBER_ERROR) { dW("ber_get_stringa: LBER_ERROR"); /* XXX: set error status on field */ continue; } assume_d(val != NULL, NULL); field = probe_ent_creat1("field", NULL, SEXP_string_new_r(&se_tmp_mem, val, strlen(val))); field_type = OVAL_DATATYPE_STRING; SEXP_free_r(&se_tmp_mem); ber_memfree(val); } break; case LBER_NULL: /* XXX: no equivalent LDAPTYPE_? or empty */ dI("LBER_NULL: skipped"); continue; case LBER_ENUMERATED: /* XXX: no equivalent LDAPTYPE_? */ dW("Don't know how to handle LBER_ENUMERATED type"); continue; default: dW("Unknown attribute value type, bertag = %u", bertag); continue; } if (field != NULL) { assume_d(field_type != OVAL_DATATYPE_UNKNOWN, NULL); probe_ent_setdatatype(field, field_type); probe_ent_attr_add(field, "name", SEXP_string_new_r(&se_tmp_mem, attr, strlen(attr))); SEXP_list_add(se_value, field); SEXP_free_r(&se_tmp_mem); SEXP_free(field); } } ber_sockbuf_free(berbuf); /* * Create the item */ item = probe_item_create(OVAL_INDEPENDENT_LDAP57, NULL, "suffix", OVAL_DATATYPE_STRING, suffix, "relative_dn", OVAL_DATATYPE_STRING, relative_dn, /* XXX: pattern match */ "attribute", OVAL_DATATYPE_STRING, attr, "object_class", OVAL_DATATYPE_STRING, "", "ldaptype", OVAL_DATATYPE_STRING, "", NULL); SEXP_list_add(item, se_value); SEXP_free(se_value); probe_item_collect(ctx, item); attr = ldap_next_attribute(ldp, entry, berelm); } ber_free(berelm, 0); ldap_memfree(entry_dn); entry = ldap_next_entry(ldp, entry); entry_dn = ldap_get_dn(ldp, entry); } /* * Close the LDAP connection and free resources */ ldap_unbind_ext_s(ldp, NULL, NULL); } ldap_memfree(uri_list); fail0: SEXP_free(se_suffix); SEXP_free(se_relative_dn); SEXP_free(se_attribute); free(suffix); free(relative_dn); free(attrs[1]); /* attribute */ return (0); }
int ldap_create( LDAP **ldp ) { LDAP *ld; struct ldapoptions *gopts; #if defined(__APPLE__) && defined(LDAP_R_COMPILE) /* Init the global options in a nice thread-safe manner. */ dispatch_once_f(&ldap_global_opts_initialized, NULL, ldap_int_init_global_opts); #endif *ldp = NULL; /* Get pointer to global option structure */ if ( (gopts = LDAP_INT_GLOBAL_OPT()) == NULL) { return LDAP_NO_MEMORY; } #if defined(__APPLE__) && defined(LDAP_R_COMPILE) /* Global options should have been initialized by pthread_once() */ if( gopts->ldo_valid != LDAP_INITIALIZED ) { return LDAP_LOCAL_ERROR; } #else /* Initialize the global options, if not already done. */ if( gopts->ldo_valid != LDAP_INITIALIZED ) { ldap_int_initialize(gopts, NULL); if ( gopts->ldo_valid != LDAP_INITIALIZED ) return LDAP_LOCAL_ERROR; } #endif Debug( LDAP_DEBUG_TRACE, "ldap_create\n", 0, 0, 0 ); if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) { return( LDAP_NO_MEMORY ); } if ( (ld->ldc = (struct ldap_common *) LDAP_CALLOC( 1, sizeof(struct ldap_common) )) == NULL ) { LDAP_FREE( (char *)ld ); return( LDAP_NO_MEMORY ); } /* copy the global options */ LDAP_MUTEX_LOCK( &gopts->ldo_mutex ); AC_MEMCPY(&ld->ld_options, gopts, sizeof(ld->ld_options)); #ifdef LDAP_R_COMPILE /* Properly initialize the structs mutex */ ldap_pvt_thread_mutex_init( &(ld->ld_ldopts_mutex) ); #endif LDAP_MUTEX_UNLOCK( &gopts->ldo_mutex ); ld->ld_valid = LDAP_VALID_SESSION; /* but not pointers to malloc'ed items */ ld->ld_options.ldo_sctrls = NULL; ld->ld_options.ldo_cctrls = NULL; ld->ld_options.ldo_defludp = NULL; ld->ld_options.ldo_conn_cbs = NULL; ld->ld_options.ldo_noaddr_option = 0; ld->ld_options.ldo_sasl_fqdn = NULL; #ifdef HAVE_CYRUS_SASL ld->ld_options.ldo_def_sasl_mech = gopts->ldo_def_sasl_mech ? LDAP_STRDUP( gopts->ldo_def_sasl_mech ) : NULL; ld->ld_options.ldo_def_sasl_realm = gopts->ldo_def_sasl_realm ? LDAP_STRDUP( gopts->ldo_def_sasl_realm ) : NULL; ld->ld_options.ldo_def_sasl_authcid = gopts->ldo_def_sasl_authcid ? LDAP_STRDUP( gopts->ldo_def_sasl_authcid ) : NULL; ld->ld_options.ldo_def_sasl_authzid = gopts->ldo_def_sasl_authzid ? LDAP_STRDUP( gopts->ldo_def_sasl_authzid ) : NULL; #endif #ifdef HAVE_TLS /* We explicitly inherit the SSL_CTX, don't need the names/paths. Leave * them empty to allow new SSL_CTX's to be created from scratch. */ memset( &ld->ld_options.ldo_tls_info, 0, sizeof( ld->ld_options.ldo_tls_info )); ld->ld_options.ldo_tls_ctx = NULL; #endif if ( gopts->ldo_defludp ) { ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp); if ( ld->ld_options.ldo_defludp == NULL ) goto nomem; } if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) goto nomem; ld->ld_lberoptions = LBER_USE_DER; ld->ld_sb = ber_sockbuf_alloc( ); if ( ld->ld_sb == NULL ) goto nomem; #ifdef LDAP_RESPONSE_RB_TREE ldap_resp_rbt_create( ld ); if ( ld->ld_rbt_responses == NULL ) { goto nomem; } #endif #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_init( &ld->ld_msgid_mutex ); ldap_pvt_thread_mutex_init( &ld->ld_conn_mutex ); ldap_pvt_thread_mutex_init( &ld->ld_req_mutex ); ldap_pvt_thread_mutex_init( &ld->ld_res_mutex ); ldap_pvt_thread_mutex_init( &ld->ld_abandon_mutex ); ldap_pvt_thread_mutex_init( &ld->ld_ldcmutex ); #endif ld->ld_ldcrefcnt = 1; *ldp = ld; return LDAP_SUCCESS; nomem: ldap_free_select_info( ld->ld_selectinfo ); ldap_free_urllist( ld->ld_options.ldo_defludp ); #ifdef HAVE_CYRUS_SASL LDAP_FREE( ld->ld_options.ldo_def_sasl_authzid ); LDAP_FREE( ld->ld_options.ldo_def_sasl_authcid ); LDAP_FREE( ld->ld_options.ldo_def_sasl_realm ); LDAP_FREE( ld->ld_options.ldo_def_sasl_mech ); #endif LDAP_FREE( (char *)ld ); return LDAP_NO_MEMORY; }
int main( int argc, char **argv ) { char *s; int fd, rc; BerElement *ber; Sockbuf *sb; /* enable debugging */ int ival = -1; ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &ival ); if ( argc < 2 ) { usage( argv[0] ); return( EXIT_FAILURE ); } #ifdef HAVE_CONSOLE_H ccommand( &argv ); cshow( stdout ); if (( fd = open( "lber-test", O_WRONLY|O_CREAT|O_TRUNC|O_BINARY )) < 0 ) { perror( "open" ); return( EXIT_FAILURE ); } #else fd = fileno(stdout); #endif sb = ber_sockbuf_alloc(); ber_sockbuf_add_io( sb, &ber_sockbuf_io_fd, LBER_SBIOD_LEVEL_PROVIDER, (void *)&fd ); if( sb == NULL ) { perror( "ber_sockbuf_alloc_fd" ); return( EXIT_FAILURE ); } if ( (ber = ber_alloc_t( LBER_USE_DER )) == NULL ) { perror( "ber_alloc" ); return( EXIT_FAILURE ); } fprintf(stderr, "encode: start\n" ); if( ber_printf( ber, "{" /*}*/ ) ) { perror( "ber_printf {" /*}*/ ); return( EXIT_FAILURE ); } for ( s = argv[1]; *s; s++ ) { char *buf; char fmt[2]; fmt[0] = *s; fmt[1] = '\0'; fprintf(stderr, "encode: %s\n", fmt ); switch ( *s ) { case 'i': /* int */ case 'b': /* boolean */ case 'e': /* enumeration */ buf = getbuf(); rc = ber_printf( ber, fmt, atoi(buf) ); break; case 'n': /* null */ case '{': /* begin sequence */ case '}': /* end sequence */ case '[': /* begin set */ case ']': /* end set */ rc = ber_printf( ber, fmt ); break; case 'o': /* octet string (non-null terminated) */ case 'B': /* bit string */ buf = getbuf(); rc = ber_printf( ber, fmt, buf, strlen(buf) ); break; case 's': /* string */ case 't': /* tag for the next element */ buf = getbuf(); rc = ber_printf( ber, fmt, buf ); break; default: fprintf( stderr, "encode: unknown fmt %c\n", *fmt ); rc = -1; break; } if( rc == -1 ) { perror( "ber_printf" ); return( EXIT_FAILURE ); } } fprintf(stderr, "encode: end\n" ); if( ber_printf( ber, /*{*/ "N}" ) == -1 ) { perror( /*{*/ "ber_printf }" ); return( EXIT_FAILURE ); } if ( ber_flush( sb, ber, 1 ) == -1 ) { perror( "ber_flush" ); return( EXIT_FAILURE ); } ber_sockbuf_free( sb ); return( EXIT_SUCCESS ); }
int main( int argc, char **argv ) { char *s; ber_tag_t tag; ber_len_t len; BerElement *ber; Sockbuf *sb; int fd; /* enable debugging */ int ival = -1; ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &ival ); if ( argc < 2 ) { usage( argv[0] ); return( EXIT_FAILURE ); } #ifdef HAVE_CONSOLE_H ccommand( &argv ); cshow( stdout ); #endif sb = ber_sockbuf_alloc(); fd = fileno( stdin ); ber_sockbuf_add_io( sb, &ber_sockbuf_io_fd, LBER_SBIOD_LEVEL_PROVIDER, (void *)&fd ); ber = ber_alloc_t(LBER_USE_DER); if( ber == NULL ) { perror( "ber_alloc_t" ); return( EXIT_FAILURE ); } for (;;) { tag = ber_get_next( sb, &len, ber); if( tag != LBER_ERROR ) break; if( errno == EWOULDBLOCK ) continue; if( errno == EAGAIN ) continue; perror( "ber_get_next" ); return( EXIT_FAILURE ); } printf("decode: message tag 0x%lx and length %ld\n", (unsigned long) tag, (long) len ); for( s = argv[1]; *s; s++ ) { char buf[128]; char fmt[2]; fmt[0] = *s; fmt[1] = '\0'; printf("decode: format %s\n", fmt ); len = sizeof(buf); tag = ber_scanf( ber, fmt, &buf[0], &len ); if( tag == LBER_ERROR ) { perror( "ber_scanf" ); return( EXIT_FAILURE ); } } ber_sockbuf_free( sb ); return( EXIT_SUCCESS ); }