JunkBox_Lib  1.10.2
ldap_tool.c
Go to the documentation of this file.
1 
14 #ifdef CPLUSPLUS
15  #undef CPLUSPLUS
16 #endif
17 
18 #include "ldap_tool.h"
19 #include "jbxl_state.h"
20 
21 
22 #ifdef ENABLE_LDAP
23 
24 #include "tlist.h"
25 
26 
37 void read_ldap_config(char* fn, JBXL_LDAP_Host* ldap_host, JBXL_LDAP_Dn* ldap_bind)
38 {
39  if (ldap_host==NULL || ldap_bind==NULL) return;
40 
41  tList* lp = NULL;
42  tList* cnfg1 = NULL;
43  tList* cnfg2 = NULL;
44  tList* cnfg3 = NULL;
45  tList* cnfg4 = NULL;
46  Buffer protocol = init_Buffer();
47 
48  //
49  cnfg1 = read_index_tList_file("/etc/ldap.conf", ' ');
50  cnfg2 = read_index_tList_file("/etc/openldap/ldap.conf", ' ');
51  cnfg3 = read_index_tList_file("/etc/nslcd.conf", ' ');
52  if (fn!=NULL) cnfg4 = read_index_tList_file(fn, ' ');
53 
54  lp = add_tList_end(cnfg1, cnfg2);
55  lp = add_tList_end(lp, cnfg3);
56  lp = add_tList_end(lp, cnfg4);
57  if (lp==NULL) return;
58 
59  //
60  Buffer uri = buffer_key_tList(lp, "uri", 1);
61  if (uri.buf!=NULL) {
62  decomp_url(uri, NULL, &protocol, &ldap_host->hostname, &ldap_host->port, NULL);
63  if (!strcmp((const char*)protocol.buf, "ldaps")) {
64  ldap_host->useSSL = TRUE;
65  }
66  free_Buffer(&protocol);
67  free_Buffer(&uri);
68  }
69 
70  ldap_bind->base = buffer_key_tList(lp, "base", 1);
71  ldap_bind->dnbind = buffer_key_tList(lp, "rootdn", 1);
72  ldap_bind->passwd = buffer_key_tList(lp, "rootpw", 1);
73 
74  if (ldap_bind->dnbind.buf==NULL || ldap_bind->passwd.buf==NULL) {
75  free_Buffer(&ldap_bind->dnbind);
76  free_Buffer(&ldap_bind->passwd);
77  ldap_bind->dnbind = buffer_key_tList(lp, "binddn", 1);
78  ldap_bind->passwd = buffer_key_tList(lp, "bindpw", 1);
79  }
80  if (ldap_bind->base.buf==NULL) {
81  ldap_bind->base = dup_Buffer(ldap_bind->dnbind);
82  }
83 
84  //
85  if (ldap_bind->dnbind.buf!=NULL) {
86  Buffer tmp = erase_sBuffer(ldap_bind->dnbind, "\"\'");
87  copy_Buffer(&tmp, &ldap_bind->dnbind);
88  free_Buffer(&tmp);
89  }
90  if (ldap_bind->base.buf!=NULL) {
91  Buffer tmp = erase_sBuffer(ldap_bind->base, "\"\'");
92  copy_Buffer(&tmp, &ldap_bind->base);
93  free_Buffer(&tmp);
94  }
95  if (ldap_host->port<=0) {
96  if (ldap_host->useSSL==TRUE) ldap_host->port = 636;
97  else ldap_host->port = 389;
98  }
99 
100  // Parameters
101  Buffer param = buffer_key_tList(lp, "TLS_REQCERT", 1);
102  if (param.buf!=NULL) {
103  if (!strcasecmp((const char*)param.buf, "never")) ldap_host->reqCert = LDAP_OPT_X_TLS_NEVER;
104  else if (!strcasecmp((const char*)param.buf, "hard")) ldap_host->reqCert = LDAP_OPT_X_TLS_HARD;
105  else if (!strcasecmp((const char*)param.buf, "demand")) ldap_host->reqCert = LDAP_OPT_X_TLS_DEMAND;
106  else if (!strcasecmp((const char*)param.buf, "allow")) ldap_host->reqCert = LDAP_OPT_X_TLS_ALLOW;
107  else if (!strcasecmp((const char*)param.buf, "try")) ldap_host->reqCert = LDAP_OPT_X_TLS_TRY;
108  free_Buffer(&param);
109  }
110 
111  //
112  //print_tList(stdout, lp);
113  del_all_tList(&lp);
114 
115  return;
116 }
117 
118 
129 LDAP* open_ldap_connection(JBXL_LDAP_Host* ldap_host, JBXL_LDAP_Dn* ldap_bind)
130 {
131  if (ldap_host==NULL) return NULL;
132  if (ldap_bind==NULL) return NULL;
133  //
134  if (ldap_bind->dnbind.buf==NULL) return NULL;
135  if (ldap_bind->passwd.buf==NULL) return NULL;
136  if (ldap_bind->passwd.buf[0]=='\0') return NULL;
137  if (ldap_host->hostname.buf==NULL) return NULL;
138  if (ldap_host->port<=0) return NULL;
139 
140  int ret;
141  LDAP* ld = NULL;
142 
143  if (ldap_host->useSSL!=TRUE || ldap_host->port==389) {
144  DEBUG_MODE PRINT_MESG("INFO LDAP NORMAL Mode\n");
145  ld = ldap_init((char*)ldap_host->hostname.buf, ldap_host->port);
146  if (ld==NULL) {
147  DEBUG_MODE PRINT_MESG("ERR LDAP Init error.\n");
148  return NULL;
149  }
150 
151  if (ldap_host->useSSL==TRUE) { // STARTTLS (動作未確認)
152  DEBUG_MODE PRINT_MESG("INFO LDAP STARTTLS Mode\n");
153  ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_host->reqCert);
154  if (ret!=LDAP_SUCCESS) {
155  DEBUG_MODE PRINT_MESG("ERR LDAP STARTTLS Require Cert = %s\n", ldap_err2string(ret));
156  ldap_unbind_s(ld);
157  return NULL;
158  }
159 
160  int ldap_vers = LDAP_VERSION3;
161  ret = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_vers);
162  if (ret!=LDAP_SUCCESS) {
163  DEBUG_MODE PRINT_MESG("ERR LDAP STARTTLS Version = %s\n", ldap_err2string(ret));
164  ldap_unbind_s(ld);
165  return NULL;
166  }
167  //
168  ret = ldap_start_tls_s(ld, NULL, NULL);
169  if (ret!=LDAP_SUCCESS) {
170  DEBUG_MODE PRINT_MESG("ERR LDAP STARTTLS Start = %s\n", ldap_err2string(ret));
171  ldap_unbind_s(ld);
172  return NULL;
173  }
174  }
175  }
176  //
177  else { // LDAP over SSL
178  DEBUG_MODE PRINT_MESG("INFO LDAP Over SSL Mode\n");
179  Buffer url = make_Buffer_bystr("ldaps://");
180  cat_Buffer(&ldap_host->hostname, &url);
181  cat_s2Buffer(":", &url);
182  char* str = itostr_ts(ldap_host->port);
183  cat_s2Buffer(str, &url);
184  freeNull(str);
185  DEBUG_MODE PRINT_MESG("INFO LDAP SSL URL = %s\n", (char*)url.buf);
186  //
187  ret = ldap_initialize(&ld, (char*)url.buf);
188  free_Buffer(&url);
189  if (ret!=LDAP_SUCCESS) {
190  DEBUG_MODE PRINT_MESG("ERR LDAP SSL Init = %s\n", ldap_err2string(ret));
191  return NULL;
192  }
193  //
194  ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_host->reqCert);
195  if (ret!=LDAP_SUCCESS) {
196  DEBUG_MODE PRINT_MESG("ERR LDAP SSL Require Cert = %s\n", ldap_err2string(ret));
197  ldap_unbind_s(ld);
198  return NULL;
199  }
200  }
201 
202  ret = ldap_simple_bind_s(ld, (char*)ldap_bind->dnbind.buf, (char*)ldap_bind->passwd.buf);
203  if (ret!=LDAP_SUCCESS) {
204  DEBUG_MODE PRINT_MESG("ERR LDAP Bind = %s\n", ldap_err2string(ret));
205  ldap_unbind_s(ld);
206  return NULL;
207  }
208 
209  return ld;
210 }
211 
212 
230 int simple_check_ldap_passwd(LDAP* ld, char* userid, char* passwd, JBXL_LDAP_Dn* ldap_bind)
231 {
232  JBXL_LDAP_Dn user;
233  init_LDAP_Dn(&user);
234 
235  if (userid!=NULL) user.dnbind = make_Buffer_bystr(userid);
236  if (passwd!=NULL) user.passwd = make_Buffer_bystr(passwd);
237  user.base = dup_Buffer(ldap_bind->base);
238 
239  int ret = check_ldap_passwd(ld, &user, ldap_bind);
240  free_LDAP_Dn(&user);
241 
242  return ret;
243 }
244 
245 
261 int check_ldap_passwd(LDAP* ld, JBXL_LDAP_Dn* user, JBXL_LDAP_Dn* ldap_bind)
262 {
263  //char* dn_attr[] = {_tochar("distinguishedName"), NULL};
264  char* dn_attr[] = {_tochar("distinguishedName"), _tochar("commonName"), NULL};
265 
266  if (ld==NULL) return JBXL_ARGS_ERROR;
267 
268  if (user->base.buf==NULL) user->base = dup_Buffer(ldap_bind->base);
269  if (user->base.buf==NULL) return JBXL_LDAP_BASE_ERROR;
270 
271  //
272  if (user->dnbind.buf==NULL) {
274  }
275  else {
276  Buffer tmp = erase_sBuffer(user->dnbind, "*");
277  copy_Buffer(&tmp, &user->dnbind);
278  free_Buffer(&tmp);
279  }
280  if (user->dnbind.buf[0]=='\0') {
282  }
283 
284  Buffer cond = make_Buffer_bystr("uid=");
285  cat_Buffer(&user->dnbind, &cond);
286 
287  LDAPMessage* res = NULL;
288  ldap_search_s(ld, (char*)user->base.buf, LDAP_SCOPE_SUBTREE, (char*)cond.buf, dn_attr, 0, &res);
289  free_Buffer(&cond);
290  if (res==NULL) {
291  return JBXL_LDAP_USER_ERROR;
292  }
293 
294  char* attr;
295  LDAPMessage* ent = NULL;
296  BerElement* ber = NULL;
297 
298 /* for debug
299  for (ent = ldap_first_entry(ld, res); ent != NULL; ent = ldap_next_entry(ld, ent)) {
300  for (attr = ldap_first_attribute(ld, ent, &ber); attr != NULL; attr = ldap_next_attribute(ld, ent, ber)) {
301  char** dn = ldap_get_values(ld, ent, attr);
302  PRINT_MESG("%s => %s\n", attr, *dn);
303  ldap_memfree(attr);
304  free(*dn);
305  }
306  ber_free(ber, 0);
307  }
308  ldap_msgfree(res);
309  return 0;
310 */
311  ent = ldap_first_entry(ld, res);
312  if (ent==NULL) {
313  ldap_msgfree(res);
315  }
316 
317  attr = ldap_first_attribute(ld, ent, &ber);
318  ber_free(ber, 0);
319  if (attr==NULL) {
320  ldap_msgfree(res);
322  }
323 
324  char** dn = ldap_get_values(ld, ent, attr);
325  if (dn==NULL || *dn==NULL) {
326  ldap_memfree(attr);
327  ldap_msgfree(res);
328  return JBXL_LDAP_NO_VAL_ERROR;
329  }
330 
331  // ユーザチェック Password "" is OK!! Ohhh GeroGero!!
332  if (user->passwd.buf==NULL || user->passwd.buf[0]=='\0') return JBXL_LDAP_PASSWD_ERROR;
333 
334  Buffer dName = make_Buffer_bystr(*dn);
335  // distinguishedName 情報がない場合に,DNを生成する.
336  if (!strncasecmp(attr, "commonName", 10)) {
337  ins_s2Buffer("cn=", &dName);
338  cat_s2Buffer(",", &dName);
339  cat_Buffer(&ldap_bind->base, &dName);
340  }
341  ldap_memfree(attr);
342  ldap_msgfree(res);
343  free(*dn);
344 
345  // パスワード確認
346  int ret = ldap_simple_bind_s(ld, (const char*)dName.buf, (char*)user->passwd.buf);
347  free_Buffer(&dName);
348  if (ret!=LDAP_SUCCESS) return JBXL_LDAP_PASSWD_ERROR;
349 
350  // 念のため,セッションを確認
351  //ret = ldap_compare_s(ld, *dn, "name", (char*)user->dnbind.buf);
352  //if (ret!=LDAP_COMPARE_TRUE) return 1;
353 
354  return 0;
355 }
356 
357 
367 void close_ldap_connection(LDAP* ld, JBXL_LDAP_Host** p_ldap_host, JBXL_LDAP_Dn** p_ldap_bind)
368 {
369  del_LDAP_Host(p_ldap_host);
370  del_LDAP_Dn (p_ldap_bind);
371 
372  ldap_unbind_s(ld);
373 }
374 
375 
377 
378 void init_LDAP_Host(JBXL_LDAP_Host* host)
379 {
380  if (host==NULL) return;
381 
382  host->hostname = init_Buffer();
383  host->port = 0;
384  host->useSSL = FALSE;
385  host->reqCert = LDAP_OPT_X_TLS_HARD;
386 }
387 
388 
389 void init_LDAP_Dn(JBXL_LDAP_Dn* dn)
390 {
391  if (dn==NULL) return;
392 
393  dn->base = init_Buffer();
394  dn->dnbind = init_Buffer();
395  dn->passwd = init_Buffer();
396 }
397 
398 
399 void free_LDAP_Host(JBXL_LDAP_Host* host)
400 {
401  if (host==NULL) return;
402 
403  free_Buffer(&(host->hostname));
404  init_LDAP_Host(host);
405 }
406 
407 
408 void free_LDAP_Dn(JBXL_LDAP_Dn* dn)
409 {
410  if (dn==NULL) return;
411 
412  free_Buffer(&(dn->base));
413  free_Buffer(&(dn->dnbind));
414  free_Buffer(&(dn->passwd));
415 }
416 
417 
418 JBXL_LDAP_Host* new_LDAP_Host(void)
419 {
420  JBXL_LDAP_Host* host = (JBXL_LDAP_Host*)malloc(sizeof(JBXL_LDAP_Host));
421  if (host!=NULL) memset(host, 0, sizeof(JBXL_LDAP_Host));
422  init_LDAP_Host(host);
423 
424  return host;
425 }
426 
427 
428 JBXL_LDAP_Dn* new_LDAP_Dn(void)
429 {
430  JBXL_LDAP_Dn* dn = (JBXL_LDAP_Dn*)malloc(sizeof(JBXL_LDAP_Dn));
431  if (dn!=NULL) memset(dn, 0, sizeof(JBXL_LDAP_Dn));
432  init_LDAP_Dn(dn);
433 
434  return dn;
435 }
436 
437 
438 void del_LDAP_Host(JBXL_LDAP_Host** p_host)
439 {
440  if (p_host==NULL) return;
441 
442  free_LDAP_Host(*p_host);
443  if (*p_host!=NULL) free(*p_host);
444  *p_host = NULL;
445 }
446 
447 
448 void del_LDAP_Dn(JBXL_LDAP_Dn** p_dn)
449 {
450  if (p_dn==NULL) return;
451 
452  free_LDAP_Dn(*p_dn);
453  if (*p_dn!=NULL) free(*p_dn);
454  *p_dn = NULL;
455 }
456 
457 
458 #endif // DISABLE_LDAP
459 
void free_Buffer(Buffer *buf)
Buffer型変数のバッファ部を解放する
Definition: buffer.c:128
Buffer init_Buffer()
初期化したBuffer型変数を返す.
Definition: buffer.c:47
Buffer dup_Buffer(Buffer buf)
Buffer型変数のコピーをつくる.
Definition: buffer.c:211
int cat_Buffer(Buffer *src, Buffer *dst)
Buffer変数 srcから dstへバッファを catする.
Definition: buffer.c:384
int copy_Buffer(Buffer *src, Buffer *dst)
Buffer型変数 srcから dstへバッファをコピーする.
Definition: buffer.c:315
#define ins_s2Buffer(src, dst)
cat_b2Buffer()
Definition: buffer.h:123
#define cat_s2Buffer(src, dst)
cat_b2Buffer()
Definition: buffer.h:122
#define erase_sBuffer(b, f)
erase_bBuffer()
Definition: buffer.h:169
#define make_Buffer_bystr(str)
set_Buffer()
Definition: buffer.h:57
#define TRUE
Definition: common.h:226
#define FALSE
Definition: common.h:223
JunkBox_Lib 状態ヘッダ
#define JBXL_ARGS_ERROR
不正な引数(NULLなど)
Definition: jbxl_state.h:42
#define JBXL_LDAP_PASSWD_ERROR
ユーザ認証失敗(ユーザは存在するが,パスワードが一致しない)
Definition: jbxl_state.h:138
#define JBXL_LDAP_NO_VAL_ERROR
エントリの属性値がない
Definition: jbxl_state.h:142
#define JBXL_LDAP_NO_ENTRY_ERROR
エントリ情報がない
Definition: jbxl_state.h:140
#define JBXL_LDAP_BASE_ERROR
LDAP のBASE名が不明
Definition: jbxl_state.h:136
#define JBXL_LDAP_NO_ATTR_ERROR
エントリの属性がない
Definition: jbxl_state.h:141
#define JBXL_LDAP_NO_USER_ERROR
ユーザ名が空白か NULL
Definition: jbxl_state.h:139
#define JBXL_LDAP_USER_ERROR
ユーザ認証失敗(ユーザが存在しない)
Definition: jbxl_state.h:137
LDAP * open_ldap_connection(JBXL_LDAP_Host *ldap_host, JBXL_LDAP_Dn *ldap_bind)
Definition: ldap_tool.c:129
void close_ldap_connection(LDAP *ld, JBXL_LDAP_Host **p_ldap_host, JBXL_LDAP_Dn **p_ldap_bind)
Definition: ldap_tool.c:367
JBXL_LDAP_Host * new_LDAP_Host(void)
Definition: ldap_tool.c:418
void del_LDAP_Dn(JBXL_LDAP_Dn **p_dn)
Definition: ldap_tool.c:448
void free_LDAP_Host(JBXL_LDAP_Host *host)
Definition: ldap_tool.c:399
void init_LDAP_Host(JBXL_LDAP_Host *host)
Definition: ldap_tool.c:378
int simple_check_ldap_passwd(LDAP *ld, char *userid, char *passwd, JBXL_LDAP_Dn *ldap_bind)
Definition: ldap_tool.c:230
JBXL_LDAP_Dn * new_LDAP_Dn(void)
Definition: ldap_tool.c:428
void init_LDAP_Dn(JBXL_LDAP_Dn *dn)
Definition: ldap_tool.c:389
int check_ldap_passwd(LDAP *ld, JBXL_LDAP_Dn *user, JBXL_LDAP_Dn *ldap_bind)
Definition: ldap_tool.c:261
void free_LDAP_Dn(JBXL_LDAP_Dn *dn)
Definition: ldap_tool.c:408
void del_LDAP_Host(JBXL_LDAP_Host **p_host)
Definition: ldap_tool.c:438
void read_ldap_config(char *fn, JBXL_LDAP_Host *ldap_host, JBXL_LDAP_Dn *ldap_bind)
Definition: ldap_tool.c:37
LDAP用ライブラリ ヘッダ
Definition: buffer.h:35
unsigned char * buf
バッファの先頭へのポインタ.str[bufsz]は必ず 0x00となる.
Definition: buffer.h:39
tList * read_index_tList_file(const char *fname, char deli)
ファイルから一行ずつ読み込んで,deliを区切り文字にしてリストのキー部とデータ部に格納.
Definition: tlist.c:2219
void del_all_tList(tList **pp)
リストの全ノードの削除.ポインタ ppのノードを含むリスト全体を削除する.
Definition: tlist.c:769
tList * add_tList_end(tList *pp, tList *pt)
リストppの最後に リストptを追加する.
Definition: tlist.c:877
Buffer buffer_key_tList(tList *list, const char *key, int no)
リストの中から no番目の keyノード(ldat.key)を探し出し,ldat.valのコピーを返す.
Definition: tlist.c:1595
Tiny List 構造ライブラリヘッダ
char * itostr_ts(int n)
int を文字に変換する.要 free()
Definition: tools.c:1532
#define _tochar(a)
Definition: tools.h:207
#define freeNull(p)
Definition: tools.h:201
#define PRINT_MESG
環境依存用の出力関数.print_message()
Definition: tools.h:475
#define DEBUG_MODE
Definition: tools.h:502
int decomp_url(Buffer url, Buffer *srvurl, Buffer *protocol, Buffer *srvfqdn, unsigned short *sport, Buffer *srvdir)
URLを分解する.
Definition: xtools.c:807