openldap.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                      _   _ ____  _
00003  *  Project         ___| | | |  _ \| |
00004  *                 / __| | | | |_) | |
00005  *                | (__| |_| |  _ <| |___
00006  *                 \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
00009  * Copyright (C) 2011 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
00010  *
00011  * This software is licensed as described in the file COPYING, which
00012  * you should have received as part of this distribution. The terms
00013  * are also available at https://curl.haxx.se/docs/copyright.html.
00014  *
00015  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00016  * copies of the Software, and permit persons to whom the Software is
00017  * furnished to do so, under the terms of the COPYING file.
00018  *
00019  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00020  * KIND, either express or implied.
00021  *
00022  ***************************************************************************/
00023 
00024 #include "curl_setup.h"
00025 
00026 #if !defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP)
00027 
00028 /*
00029  * Notice that USE_OPENLDAP is only a source code selection switch. When
00030  * libcurl is built with USE_OPENLDAP defined the libcurl source code that
00031  * gets compiled is the code from openldap.c, otherwise the code that gets
00032  * compiled is the code from ldap.c.
00033  *
00034  * When USE_OPENLDAP is defined a recent version of the OpenLDAP library
00035  * might be required for compilation and runtime. In order to use ancient
00036  * OpenLDAP library versions, USE_OPENLDAP shall not be defined.
00037  */
00038 
00039 #include <ldap.h>
00040 
00041 #include "urldata.h"
00042 #include <curl/curl.h>
00043 #include "sendf.h"
00044 #include "vtls/vtls.h"
00045 #include "transfer.h"
00046 #include "curl_ldap.h"
00047 #include "curl_base64.h"
00048 #include "connect.h"
00049 /* The last 3 #include files should be in this order */
00050 #include "curl_printf.h"
00051 #include "curl_memory.h"
00052 #include "memdebug.h"
00053 
00054 #ifndef _LDAP_PVT_H
00055 extern int ldap_pvt_url_scheme2proto(const char *);
00056 extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url,
00057                         LDAP **ld);
00058 #endif
00059 
00060 static CURLcode ldap_setup_connection(struct connectdata *conn);
00061 static CURLcode ldap_do(struct connectdata *conn, bool *done);
00062 static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool);
00063 static CURLcode ldap_connect(struct connectdata *conn, bool *done);
00064 static CURLcode ldap_connecting(struct connectdata *conn, bool *done);
00065 static CURLcode ldap_disconnect(struct connectdata *conn, bool dead);
00066 
00067 static Curl_recv ldap_recv;
00068 
00069 /*
00070  * LDAP protocol handler.
00071  */
00072 
00073 const struct Curl_handler Curl_handler_ldap = {
00074   "LDAP",                               /* scheme */
00075   ldap_setup_connection,                /* setup_connection */
00076   ldap_do,                              /* do_it */
00077   ldap_done,                            /* done */
00078   ZERO_NULL,                            /* do_more */
00079   ldap_connect,                         /* connect_it */
00080   ldap_connecting,                      /* connecting */
00081   ZERO_NULL,                            /* doing */
00082   ZERO_NULL,                            /* proto_getsock */
00083   ZERO_NULL,                            /* doing_getsock */
00084   ZERO_NULL,                            /* domore_getsock */
00085   ZERO_NULL,                            /* perform_getsock */
00086   ldap_disconnect,                      /* disconnect */
00087   ZERO_NULL,                            /* readwrite */
00088   PORT_LDAP,                            /* defport */
00089   CURLPROTO_LDAP,                       /* protocol */
00090   PROTOPT_NONE                          /* flags */
00091 };
00092 
00093 #ifdef USE_SSL
00094 /*
00095  * LDAPS protocol handler.
00096  */
00097 
00098 const struct Curl_handler Curl_handler_ldaps = {
00099   "LDAPS",                              /* scheme */
00100   ldap_setup_connection,                /* setup_connection */
00101   ldap_do,                              /* do_it */
00102   ldap_done,                            /* done */
00103   ZERO_NULL,                            /* do_more */
00104   ldap_connect,                         /* connect_it */
00105   ldap_connecting,                      /* connecting */
00106   ZERO_NULL,                            /* doing */
00107   ZERO_NULL,                            /* proto_getsock */
00108   ZERO_NULL,                            /* doing_getsock */
00109   ZERO_NULL,                            /* domore_getsock */
00110   ZERO_NULL,                            /* perform_getsock */
00111   ldap_disconnect,                      /* disconnect */
00112   ZERO_NULL,                            /* readwrite */
00113   PORT_LDAPS,                           /* defport */
00114   CURLPROTO_LDAP,                       /* protocol */
00115   PROTOPT_SSL                           /* flags */
00116 };
00117 #endif
00118 
00119 static const char *url_errs[] = {
00120   "success",
00121   "out of memory",
00122   "bad parameter",
00123   "unrecognized scheme",
00124   "unbalanced delimiter",
00125   "bad URL",
00126   "bad host or port",
00127   "bad or missing attributes",
00128   "bad or missing scope",
00129   "bad or missing filter",
00130   "bad or missing extensions"
00131 };
00132 
00133 typedef struct ldapconninfo {
00134   LDAP *ld;
00135   Curl_recv *recv;  /* for stacking SSL handler */
00136   Curl_send *send;
00137   int proto;
00138   int msgid;
00139   bool ssldone;
00140   bool sslinst;
00141   bool didbind;
00142 } ldapconninfo;
00143 
00144 typedef struct ldapreqinfo {
00145   int msgid;
00146   int nument;
00147 } ldapreqinfo;
00148 
00149 static CURLcode ldap_setup_connection(struct connectdata *conn)
00150 {
00151   ldapconninfo *li;
00152   LDAPURLDesc *lud;
00153   struct Curl_easy *data=conn->data;
00154   int rc, proto;
00155   CURLcode status;
00156 
00157   rc = ldap_url_parse(data->change.url, &lud);
00158   if(rc != LDAP_URL_SUCCESS) {
00159     const char *msg = "url parsing problem";
00160     status = CURLE_URL_MALFORMAT;
00161     if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
00162       if(rc == LDAP_URL_ERR_MEM)
00163         status = CURLE_OUT_OF_MEMORY;
00164       msg = url_errs[rc];
00165     }
00166     failf(conn->data, "LDAP local: %s", msg);
00167     return status;
00168   }
00169   proto = ldap_pvt_url_scheme2proto(lud->lud_scheme);
00170   ldap_free_urldesc(lud);
00171 
00172   li = calloc(1, sizeof(ldapconninfo));
00173   if(!li)
00174     return CURLE_OUT_OF_MEMORY;
00175   li->proto = proto;
00176   conn->proto.generic = li;
00177   connkeep(conn, "OpenLDAP default");
00178   /* TODO:
00179    * - provide option to choose SASL Binds instead of Simple
00180    */
00181   return CURLE_OK;
00182 }
00183 
00184 #ifdef USE_SSL
00185 static Sockbuf_IO ldapsb_tls;
00186 #endif
00187 
00188 static CURLcode ldap_connect(struct connectdata *conn, bool *done)
00189 {
00190   ldapconninfo *li = conn->proto.generic;
00191   struct Curl_easy *data = conn->data;
00192   int rc, proto = LDAP_VERSION3;
00193   char hosturl[1024];
00194   char *ptr;
00195 
00196   (void)done;
00197 
00198   strcpy(hosturl, "ldap");
00199   ptr = hosturl+4;
00200   if(conn->handler->flags & PROTOPT_SSL)
00201     *ptr++ = 's';
00202   snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
00203     conn->host.name, conn->remote_port);
00204 
00205   rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld);
00206   if(rc) {
00207     failf(data, "LDAP local: Cannot connect to %s, %s",
00208           hosturl, ldap_err2string(rc));
00209     return CURLE_COULDNT_CONNECT;
00210   }
00211 
00212   ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
00213 
00214 #ifdef USE_SSL
00215   if(conn->handler->flags & PROTOPT_SSL) {
00216     CURLcode result;
00217     result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone);
00218     if(result)
00219       return result;
00220   }
00221 #endif
00222 
00223   return CURLE_OK;
00224 }
00225 
00226 static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
00227 {
00228   ldapconninfo *li = conn->proto.generic;
00229   struct Curl_easy *data = conn->data;
00230   LDAPMessage *msg = NULL;
00231   struct timeval tv = {0, 1}, *tvp;
00232   int rc, err;
00233   char *info = NULL;
00234 
00235 #ifdef USE_SSL
00236   if(conn->handler->flags & PROTOPT_SSL) {
00237     /* Is the SSL handshake complete yet? */
00238     if(!li->ssldone) {
00239       CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
00240                                                      &li->ssldone);
00241       if(result || !li->ssldone)
00242         return result;
00243     }
00244 
00245     /* Have we installed the libcurl SSL handlers into the sockbuf yet? */
00246     if(!li->sslinst) {
00247       Sockbuf *sb;
00248       ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
00249       ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn);
00250       li->sslinst = TRUE;
00251       li->recv = conn->recv[FIRSTSOCKET];
00252       li->send = conn->send[FIRSTSOCKET];
00253     }
00254   }
00255 #endif
00256 
00257   tvp = &tv;
00258 
00259 retry:
00260   if(!li->didbind) {
00261     char *binddn;
00262     struct berval passwd;
00263 
00264     if(conn->bits.user_passwd) {
00265       binddn = conn->user;
00266       passwd.bv_val = conn->passwd;
00267       passwd.bv_len = strlen(passwd.bv_val);
00268     }
00269     else {
00270       binddn = NULL;
00271       passwd.bv_val = NULL;
00272       passwd.bv_len = 0;
00273     }
00274     rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd,
00275                         NULL, NULL, &li->msgid);
00276     if(rc)
00277       return CURLE_LDAP_CANNOT_BIND;
00278     li->didbind = TRUE;
00279     if(tvp)
00280       return CURLE_OK;
00281   }
00282 
00283   rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg);
00284   if(rc < 0) {
00285     failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc));
00286     return CURLE_LDAP_CANNOT_BIND;
00287   }
00288   if(rc == 0) {
00289     /* timed out */
00290     return CURLE_OK;
00291   }
00292 
00293   rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1);
00294   if(rc) {
00295     failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc));
00296     return CURLE_LDAP_CANNOT_BIND;
00297   }
00298 
00299   /* Try to fallback to LDAPv2? */
00300   if(err == LDAP_PROTOCOL_ERROR) {
00301     int proto;
00302     ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
00303     if(proto == LDAP_VERSION3) {
00304       if(info) {
00305         ldap_memfree(info);
00306         info = NULL;
00307       }
00308       proto = LDAP_VERSION2;
00309       ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
00310       li->didbind = FALSE;
00311       goto retry;
00312     }
00313   }
00314 
00315   if(err) {
00316     failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc),
00317           info ? info : "");
00318     if(info)
00319       ldap_memfree(info);
00320     return CURLE_LOGIN_DENIED;
00321   }
00322 
00323   if(info)
00324     ldap_memfree(info);
00325   conn->recv[FIRSTSOCKET] = ldap_recv;
00326   *done = TRUE;
00327 
00328   return CURLE_OK;
00329 }
00330 
00331 static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
00332 {
00333   ldapconninfo *li = conn->proto.generic;
00334   (void) dead_connection;
00335 
00336   if(li) {
00337     if(li->ld) {
00338       ldap_unbind_ext(li->ld, NULL, NULL);
00339       li->ld = NULL;
00340     }
00341     conn->proto.generic = NULL;
00342     free(li);
00343   }
00344   return CURLE_OK;
00345 }
00346 
00347 static CURLcode ldap_do(struct connectdata *conn, bool *done)
00348 {
00349   ldapconninfo *li = conn->proto.generic;
00350   ldapreqinfo *lr;
00351   CURLcode status = CURLE_OK;
00352   int rc = 0;
00353   LDAPURLDesc *ludp = NULL;
00354   int msgid;
00355   struct Curl_easy *data=conn->data;
00356 
00357   connkeep(conn, "OpenLDAP do");
00358 
00359   infof(data, "LDAP local: %s\n", data->change.url);
00360 
00361   rc = ldap_url_parse(data->change.url, &ludp);
00362   if(rc != LDAP_URL_SUCCESS) {
00363     const char *msg = "url parsing problem";
00364     status = CURLE_URL_MALFORMAT;
00365     if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
00366       if(rc == LDAP_URL_ERR_MEM)
00367         status = CURLE_OUT_OF_MEMORY;
00368       msg = url_errs[rc];
00369     }
00370     failf(conn->data, "LDAP local: %s", msg);
00371     return status;
00372   }
00373 
00374   rc = ldap_search_ext(li->ld, ludp->lud_dn, ludp->lud_scope,
00375                        ludp->lud_filter, ludp->lud_attrs, 0,
00376                        NULL, NULL, NULL, 0, &msgid);
00377   ldap_free_urldesc(ludp);
00378   if(rc != LDAP_SUCCESS) {
00379     failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
00380     return CURLE_LDAP_SEARCH_FAILED;
00381   }
00382   lr = calloc(1, sizeof(ldapreqinfo));
00383   if(!lr)
00384     return CURLE_OUT_OF_MEMORY;
00385   lr->msgid = msgid;
00386   data->req.protop = lr;
00387   Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
00388   *done = TRUE;
00389   return CURLE_OK;
00390 }
00391 
00392 static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
00393                           bool premature)
00394 {
00395   ldapreqinfo *lr = conn->data->req.protop;
00396 
00397   (void)res;
00398   (void)premature;
00399 
00400   if(lr) {
00401     /* if there was a search in progress, abandon it */
00402     if(lr->msgid) {
00403       ldapconninfo *li = conn->proto.generic;
00404       ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL);
00405       lr->msgid = 0;
00406     }
00407     conn->data->req.protop = NULL;
00408     free(lr);
00409   }
00410 
00411   return CURLE_OK;
00412 }
00413 
00414 static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
00415                          size_t len, CURLcode *err)
00416 {
00417   ldapconninfo *li = conn->proto.generic;
00418   struct Curl_easy *data = conn->data;
00419   ldapreqinfo *lr = data->req.protop;
00420   int rc, ret;
00421   LDAPMessage *msg = NULL;
00422   LDAPMessage *ent;
00423   BerElement *ber = NULL;
00424   struct timeval tv = {0, 1};
00425 
00426   (void)len;
00427   (void)buf;
00428   (void)sockindex;
00429 
00430   rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg);
00431   if(rc < 0) {
00432     failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc));
00433     *err = CURLE_RECV_ERROR;
00434     return -1;
00435   }
00436 
00437   *err = CURLE_AGAIN;
00438   ret = -1;
00439 
00440   /* timed out */
00441   if(!msg)
00442     return ret;
00443 
00444   for(ent = ldap_first_message(li->ld, msg); ent;
00445     ent = ldap_next_message(li->ld, ent)) {
00446     struct berval bv, *bvals, **bvp = &bvals;
00447     int binary = 0, msgtype;
00448     CURLcode writeerr;
00449 
00450     msgtype = ldap_msgtype(ent);
00451     if(msgtype == LDAP_RES_SEARCH_RESULT) {
00452       int code;
00453       char *info = NULL;
00454       rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0);
00455       if(rc) {
00456         failf(data, "LDAP local: search ldap_parse_result %s",
00457               ldap_err2string(rc));
00458         *err = CURLE_LDAP_SEARCH_FAILED;
00459       }
00460       else if(code && code != LDAP_SIZELIMIT_EXCEEDED) {
00461         failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc),
00462               info ? info : "");
00463         *err = CURLE_LDAP_SEARCH_FAILED;
00464       }
00465       else {
00466         /* successful */
00467         if(code == LDAP_SIZELIMIT_EXCEEDED)
00468           infof(data, "There are more than %d entries\n", lr->nument);
00469         data->req.size = data->req.bytecount;
00470         *err = CURLE_OK;
00471         ret = 0;
00472       }
00473       lr->msgid = 0;
00474       ldap_memfree(info);
00475       break;
00476     }
00477     else if(msgtype != LDAP_RES_SEARCH_ENTRY)
00478       continue;
00479 
00480     lr->nument++;
00481     rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
00482     if(rc < 0) {
00483       /* TODO: verify that this is really how this return code should be
00484          handled */
00485       *err = CURLE_RECV_ERROR;
00486       return -1;
00487     }
00488     writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
00489     if(writeerr) {
00490       *err = writeerr;
00491       return -1;
00492     }
00493 
00494     writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
00495                                  bv.bv_len);
00496     if(writeerr) {
00497       *err = writeerr;
00498       return -1;
00499     }
00500 
00501     writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
00502     if(writeerr) {
00503       *err = writeerr;
00504       return -1;
00505     }
00506     data->req.bytecount += bv.bv_len + 5;
00507 
00508     for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
00509       rc == LDAP_SUCCESS;
00510       rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) {
00511       int i;
00512 
00513       if(bv.bv_val == NULL) break;
00514 
00515       if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
00516         binary = 1;
00517       else
00518         binary = 0;
00519 
00520       for(i=0; bvals[i].bv_val != NULL; i++) {
00521         int binval = 0;
00522         writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
00523         if(writeerr) {
00524           *err = writeerr;
00525           return -1;
00526         }
00527 
00528        writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
00529                                     bv.bv_len);
00530        if(writeerr) {
00531          *err = writeerr;
00532          return -1;
00533        }
00534 
00535         writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
00536        if(writeerr) {
00537          *err = writeerr;
00538          return -1;
00539        }
00540         data->req.bytecount += bv.bv_len + 2;
00541 
00542         if(!binary) {
00543           /* check for leading or trailing whitespace */
00544           if(ISSPACE(bvals[i].bv_val[0]) ||
00545               ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1]))
00546             binval = 1;
00547           else {
00548             /* check for unprintable characters */
00549             unsigned int j;
00550             for(j=0; j<bvals[i].bv_len; j++)
00551               if(!ISPRINT(bvals[i].bv_val[j])) {
00552                 binval = 1;
00553                 break;
00554               }
00555           }
00556         }
00557         if(binary || binval) {
00558           char *val_b64 = NULL;
00559           size_t val_b64_sz = 0;
00560           /* Binary value, encode to base64. */
00561           CURLcode error = Curl_base64_encode(data,
00562                                               bvals[i].bv_val,
00563                                               bvals[i].bv_len,
00564                                               &val_b64,
00565                                               &val_b64_sz);
00566           if(error) {
00567             ber_memfree(bvals);
00568             ber_free(ber, 0);
00569             ldap_msgfree(msg);
00570             *err = error;
00571             return -1;
00572           }
00573           writeerr = Curl_client_write(conn, CLIENTWRITE_BODY,
00574                                        (char *)": ", 2);
00575           if(writeerr) {
00576             *err = writeerr;
00577             return -1;
00578           }
00579 
00580           data->req.bytecount += 2;
00581           if(val_b64_sz > 0) {
00582             writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
00583                                      val_b64_sz);
00584             if(writeerr) {
00585               *err = writeerr;
00586               return -1;
00587             }
00588             free(val_b64);
00589             data->req.bytecount += val_b64_sz;
00590           }
00591         }
00592         else {
00593           writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
00594           if(writeerr) {
00595             *err = writeerr;
00596             return -1;
00597           }
00598 
00599           writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
00600                                        bvals[i].bv_len);
00601           if(writeerr) {
00602             *err = writeerr;
00603             return -1;
00604           }
00605 
00606           data->req.bytecount += bvals[i].bv_len + 1;
00607         }
00608         writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
00609         if(writeerr) {
00610           *err = writeerr;
00611           return -1;
00612         }
00613 
00614         data->req.bytecount++;
00615       }
00616       ber_memfree(bvals);
00617       writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
00618       if(writeerr) {
00619         *err = writeerr;
00620         return -1;
00621       }
00622       data->req.bytecount++;
00623     }
00624     writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
00625     if(writeerr) {
00626       *err = writeerr;
00627       return -1;
00628     }
00629     data->req.bytecount++;
00630     ber_free(ber, 0);
00631   }
00632   ldap_msgfree(msg);
00633   return ret;
00634 }
00635 
00636 #ifdef USE_SSL
00637 static int
00638 ldapsb_tls_setup(Sockbuf_IO_Desc *sbiod, void *arg)
00639 {
00640   sbiod->sbiod_pvt = arg;
00641   return 0;
00642 }
00643 
00644 static int
00645 ldapsb_tls_remove(Sockbuf_IO_Desc *sbiod)
00646 {
00647   sbiod->sbiod_pvt = NULL;
00648   return 0;
00649 }
00650 
00651 /* We don't need to do anything because libcurl does it already */
00652 static int
00653 ldapsb_tls_close(Sockbuf_IO_Desc *sbiod)
00654 {
00655   (void)sbiod;
00656   return 0;
00657 }
00658 
00659 static int
00660 ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
00661 {
00662   (void)arg;
00663   if(opt == LBER_SB_OPT_DATA_READY) {
00664     struct connectdata *conn = sbiod->sbiod_pvt;
00665     return Curl_ssl_data_pending(conn, FIRSTSOCKET);
00666   }
00667   return 0;
00668 }
00669 
00670 static ber_slen_t
00671 ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
00672 {
00673   struct connectdata *conn = sbiod->sbiod_pvt;
00674   ldapconninfo *li = conn->proto.generic;
00675   ber_slen_t ret;
00676   CURLcode err = CURLE_RECV_ERROR;
00677 
00678   ret = li->recv(conn, FIRSTSOCKET, buf, len, &err);
00679   if(ret < 0 && err == CURLE_AGAIN) {
00680     SET_SOCKERRNO(EWOULDBLOCK);
00681   }
00682   return ret;
00683 }
00684 
00685 static ber_slen_t
00686 ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
00687 {
00688   struct connectdata *conn = sbiod->sbiod_pvt;
00689   ldapconninfo *li = conn->proto.generic;
00690   ber_slen_t ret;
00691   CURLcode err = CURLE_SEND_ERROR;
00692 
00693   ret = li->send(conn, FIRSTSOCKET, buf, len, &err);
00694   if(ret < 0 && err == CURLE_AGAIN) {
00695     SET_SOCKERRNO(EWOULDBLOCK);
00696   }
00697   return ret;
00698 }
00699 
00700 static Sockbuf_IO ldapsb_tls =
00701 {
00702   ldapsb_tls_setup,
00703   ldapsb_tls_remove,
00704   ldapsb_tls_ctrl,
00705   ldapsb_tls_read,
00706   ldapsb_tls_write,
00707   ldapsb_tls_close
00708 };
00709 #endif /* USE_SSL */
00710 
00711 #endif /* !CURL_DISABLE_LDAP && USE_OPENLDAP */


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:05