00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00033 #include "ld_uri.h"
00034 #include "ld_cfg.h"
00035
00036 #include "../../mem/mem.h"
00037 #include "../../ut.h"
00038
00039 #include <string.h>
00040
00045 #define cmpstr(s1, s2, f) \
00046 ((s1)!=(s2)) && ((s1)==0 || (s2)==0 || (f)((s1), (s2))!=0)
00047
00048
00057 static unsigned char ld_uri_cmp(db_uri_t* uri1, db_uri_t* uri2)
00058 {
00059 struct ld_uri* luri1, *luri2;
00060
00061 if (!uri1 || !uri2) return 0;
00062
00063 luri1 = DB_GET_PAYLOAD(uri1);
00064 luri2 = DB_GET_PAYLOAD(uri2);
00065
00066 if (luri1->ldap_url->lud_port != luri2->ldap_url->lud_port) return 0;
00067 if (cmpstr(luri1->ldap_url->lud_host,
00068 luri2->ldap_url->lud_host, strcasecmp))
00069 return 0;
00070 return 1;
00071 }
00072
00075 static int dupl_string(char** dst, const char* begin, const char* end)
00076 {
00077 if (*dst) pkg_free(*dst);
00078
00079 *dst = pkg_malloc(end - begin + 1);
00080 if ((*dst) == NULL) {
00081 return -1;
00082 }
00083
00084 memcpy(*dst, begin, end - begin);
00085 (*dst)[end - begin] = '\0';
00086 return 0;
00087 }
00088
00091 static char* pkgstrdup(str* s)
00092 {
00093 char* dst;
00094
00095 if (!s)
00096 return NULL;
00097
00098 dst = pkg_malloc(s->len + 1);
00099 if (dst == NULL)
00100 return NULL;
00101
00102 memcpy(dst, s->s, s->len);
00103 dst[s->len] = '\0';
00104
00105 return dst;
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115 int parse_ldap_uri(struct ld_uri* res, str* scheme, str* uri)
00116 {
00117 #define SHORTEST_DB_URL "a"
00118 #define SHORTEST_DB_URL_LEN (sizeof(SHORTEST_DB_URL) - 1)
00119
00120 enum state {
00121 ST_BEGIN,
00122 ST_SECTION_ID,
00123 ST_SLASH2,
00124 ST_USER_HOST,
00125 ST_PASS_PORT,
00126 ST_HOST_PORT
00127 };
00128 enum state st;
00129 int i, ldapurllen;
00130 const char* begin;
00131 const char* ldapbegin;
00132 char* prev_token;
00133 struct ld_con_info* cfg_conn_info;
00134 char* sport, *puri;
00135 int portlen = 0;
00136
00137 prev_token = 0;
00138
00139 if (!res || !scheme || !uri) {
00140 goto err;
00141 }
00142
00143 if (uri->len < SHORTEST_DB_URL_LEN) {
00144 goto err;
00145 }
00146
00147 st = ST_BEGIN;
00148 ldapbegin = begin = uri->s;
00149
00150 for(i = 0; i < uri->len && st != ST_SECTION_ID; i++) {
00151 switch(st) {
00152 case ST_BEGIN:
00153 switch(uri->s[i]) {
00154 case '/':
00155 st = ST_SLASH2;
00156 break;
00157
00158 default:
00159 st = ST_SECTION_ID;
00160 }
00161 break;
00162
00163 case ST_SECTION_ID:
00164 break;
00165
00166 case ST_SLASH2:
00167 switch(uri->s[i]) {
00168 case '/':
00169 st = ST_USER_HOST;
00170 ldapbegin = begin = uri->s + i + 1;
00171 break;
00172
00173 default:
00174 goto err;
00175 }
00176 break;
00177
00178 case ST_USER_HOST:
00179 switch(uri->s[i]) {
00180 case '@':
00181 st = ST_HOST_PORT;
00182 if (dupl_string(&res->username, begin, uri->s + i) < 0) goto err;
00183 ldapbegin = begin = uri->s + i + 1;
00184 break;
00185
00186 case ':':
00187 st = ST_PASS_PORT;
00188 if (dupl_string(&prev_token, begin, uri->s + i) < 0) goto err;
00189 begin = uri->s + i + 1;
00190 break;
00191 }
00192 break;
00193
00194 case ST_PASS_PORT:
00195 switch(uri->s[i]) {
00196 case '@':
00197 st = ST_HOST_PORT;
00198 res->username = prev_token;
00199 if (dupl_string(&res->password, begin, uri->s + i) < 0) goto err;
00200 ldapbegin = begin = uri->s + i + 1;
00201 break;
00202 }
00203 break;
00204
00205 case ST_HOST_PORT:
00206 break;
00207 }
00208 }
00209
00210 switch(st) {
00211 case ST_PASS_PORT:
00212 case ST_USER_HOST:
00213 case ST_HOST_PORT:
00214 ldapurllen = uri->len - (int)(ldapbegin - uri->s);
00215
00216 res->uri = pkg_malloc(scheme->len + 3 + ldapurllen + 1);
00217 if (res->uri== NULL) {
00218 ERR("ldap: No memory left\n");
00219 goto err;
00220 }
00221 memcpy(res->uri, scheme->s, scheme->len);
00222 res->uri[scheme->len] = ':';
00223 res->uri[scheme->len + 1] = '/';
00224 res->uri[scheme->len + 2] = '/';
00225 memcpy(res->uri + scheme->len + 3, ldapbegin, ldapurllen);
00226 res->uri[scheme->len + 3 + ldapurllen] = '\0';
00227
00228 if (ldap_url_parse(res->uri, &res->ldap_url) != 0) {
00229 ERR("ldap: Error while parsing URL '%s'\n", res->uri);
00230 goto err;
00231 }
00232 break;
00233 case ST_SECTION_ID:
00234
00235
00236 cfg_conn_info = ld_find_conn_info(uri);
00237 if (!cfg_conn_info) {
00238 ERR("ldap: connection id '%.*s' not found in ldap config\n", uri->len, uri->s);
00239 goto err;
00240 }
00241
00242 ldapurllen = cfg_conn_info->host.len;
00243 sport = NULL;
00244 if (cfg_conn_info->port) {
00245 sport = int2str(cfg_conn_info->port, &portlen);
00246
00247 ldapurllen += portlen + 1;
00248 }
00249
00250
00251 puri = res->uri = pkg_malloc(scheme->len + 3 + ldapurllen + 1);
00252 if (res->uri== NULL) {
00253 ERR("ldap: No memory left\n");
00254 goto err;
00255 }
00256 memcpy(puri, scheme->s, scheme->len);
00257 puri += scheme->len;
00258 memcpy(puri, "://", strlen("://"));
00259 puri+= strlen("://");
00260 memcpy(puri, cfg_conn_info->host.s, cfg_conn_info->host.len);
00261 puri+=cfg_conn_info->host.len;
00262 if (sport) {
00263 *puri++ = ':';
00264 memcpy(puri, sport, portlen);
00265 }
00266 res->uri[scheme->len + 3 + ldapurllen] = '\0';
00267
00268 if (ldap_url_parse(res->uri, &res->ldap_url) != 0) {
00269 ERR("ldap: Error while parsing URL '%s'\n", res->uri);
00270 goto err;
00271 }
00272
00273 if (cfg_conn_info->username.s) {
00274 if (!(res->username = pkgstrdup(&cfg_conn_info->username))) {
00275 ERR("ldap: No memory left\n");
00276 goto err;
00277 }
00278 }
00279
00280 if (cfg_conn_info->password.s) {
00281 if (!(res->password = pkgstrdup(&cfg_conn_info->password))) {
00282 ERR("ldap: No memory left\n");
00283 goto err;
00284 }
00285 }
00286
00287 res->authmech = cfg_conn_info->authmech;
00288 res->tls = cfg_conn_info->tls;
00289 if (cfg_conn_info->ca_list.s) {
00290 if (!(res->ca_list = pkgstrdup(&cfg_conn_info->ca_list))) {
00291 ERR("ldap: No memory left\n");
00292 goto err;
00293 }
00294 }
00295 if (cfg_conn_info->req_cert.s) {
00296 if (!(res->req_cert = pkgstrdup(&cfg_conn_info->req_cert))) {
00297 ERR("ldap: No memory left\n");
00298 goto err;
00299 }
00300 }
00301
00302 break;
00303 default:
00304 goto err;
00305 }
00306
00307 return 0;
00308
00309 err:
00310 if (prev_token) pkg_free(prev_token);
00311 if (res == NULL) return -1;
00312 if (res->username) {
00313 pkg_free(res->username);
00314 res->username = NULL;
00315 }
00316 if (res->password) {
00317 pkg_free(res->password);
00318 res->password = NULL;
00319 }
00320 if (res->ca_list) {
00321 pkg_free(res->ca_list);
00322 res->ca_list = NULL;
00323 }
00324 if (res->req_cert) {
00325 pkg_free(res->req_cert);
00326 res->req_cert = NULL;
00327 }
00328 return -1;
00329 }
00330
00331 static void ld_uri_free(db_uri_t* uri, struct ld_uri* payload)
00332 {
00333 if (payload == NULL) return;
00334 if (payload->ldap_url) ldap_free_urldesc(payload->ldap_url);
00335 if (payload->uri) pkg_free(payload->uri);
00336 if (payload->username) pkg_free(payload->username);
00337 if (payload->password) pkg_free(payload->password);
00338 if (payload->ca_list) pkg_free(payload->ca_list);
00339 if (payload->req_cert) pkg_free(payload->req_cert);
00340 db_drv_free(&payload->drv);
00341 pkg_free(payload);
00342 }
00343
00344
00345 int ld_uri(db_uri_t* uri)
00346 {
00347 struct ld_uri* luri;
00348
00349 luri = (struct ld_uri*)pkg_malloc(sizeof(struct ld_uri));
00350 if (luri == NULL) {
00351 ERR("ldap: No memory left\n");
00352 goto error;
00353 }
00354 memset(luri, '\0', sizeof(struct ld_uri));
00355 if (db_drv_init(&luri->drv, ld_uri_free) < 0) goto error;
00356 if (parse_ldap_uri(luri, &uri->scheme, &uri->body) < 0) goto error;
00357
00358 DB_SET_PAYLOAD(uri, luri);
00359 uri->cmp = ld_uri_cmp;
00360 return 0;
00361
00362 error:
00363 if (luri) {
00364 if (luri->uri) pkg_free(luri->uri);
00365 if (luri->ldap_url) ldap_free_urldesc(luri->ldap_url);
00366 db_drv_free(&luri->drv);
00367 pkg_free(luri);
00368 }
00369 return -1;
00370 }
00371
00372