ldapauth.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. #ifndef _WIN32
  6. #include <ctype.h>
  7. #endif
  8. #include "../../structures.h"
  9. #define LDAP_DEPRECATED 1
  10. #include <ldap.h>
  11. int already_loaded = 0;
  12. static struct auth myalwaysauth;
  13. static struct commands ldap_serv_auth_handler;
  14. static struct commands ldap_access_handler;
  15. static struct commands ldap_sbase_handler;
  16. static struct commands ldap_userenv_handler;
  17. static struct commands ldap_trafgroup_handler;
  18. static struct commands ldap_attrsgroup_handler;
  19. static struct commands ldap_dircount_handler;
  20. static char *attrs[] = { NULL, NULL};
  21. static char *ldap_group_attr;
  22. static char *ldap_access;
  23. static char *ldap_sbase;
  24. static char *ldap_serv;
  25. static char *ldap_user;
  26. static char *ldap_pass;
  27. static char *ldap_userenv;
  28. int ldap_userenv_size;
  29. static char *ldap_trafgroup;
  30. static char *ldap_dircount;
  31. static int usercaselow = 0;
  32. struct pluginlink * mypluginlink;
  33. struct schedule myschedule;
  34. #ifndef _WIN32
  35. void lower (char *string)
  36. {
  37. int length, i;
  38. length = strlen(string);
  39. for (i=0; i<length; i++)
  40. {
  41. string[i] = tolower(string[i]);
  42. }
  43. }
  44. #endif
  45. /* -------------------------------------------------------------------------- */
  46. int savecounters(void)
  47. {
  48. struct trafcount *tc=mypluginlink->conf->trafcounter;
  49. struct trafcount *tcd;
  50. struct counter_record wcounter;
  51. FILE *f;
  52. unsigned char *tmpbuf,pat_file[]="%s%s.lc";
  53. /* timetoexit !=0 - áóäåì çàâåðøàòüñÿ.*/
  54. while (tc != NULL)
  55. {
  56. tcd = tc;
  57. tc = tc->next;
  58. f=NULL;
  59. if(strcmp(tcd->comment,"ldapcounters")==0) {
  60. tmpbuf=malloc(strlen(pat_file)+strlen(ldap_dircount)+strlen(tcd->ace->users->user));
  61. sprintf(tmpbuf,pat_file,ldap_dircount,tcd->ace->users->user);
  62. f=fopen(tmpbuf,"w+b");
  63. fseek(f,0,SEEK_SET);
  64. fprintf(f,"%"PRINTF_INT64_MODIFIER"u %lu %lu\n",tcd->traf64,
  65. (unsigned long)tcd->cleared,(unsigned long)tcd->updated);
  66. fclose(f);
  67. free(tmpbuf);
  68. }
  69. }
  70. /*return 1 delete job , return 0 no delete job*/
  71. if (mypluginlink->conf->needreload !=0 )
  72. {
  73. return (0);
  74. }
  75. return (0);
  76. }
  77. /* --------------------------------------------------------------------------*/
  78. static int ldapfunc(struct clientparam *param)
  79. {
  80. LDAP *ld = NULL;
  81. LDAPMessage *res = NULL;
  82. int rc = -1;
  83. char tmpbuf[1024];
  84. /* test proxy user auth ------------------------*/
  85. if(!param->username || !param->password) return 4;
  86. if(strlen(param->password)==0) return 4;
  87. /* init ldap ---------------------- */
  88. ld = ldap_init( ldap_serv, 389 );
  89. if ( ld == NULL )
  90. {
  91. param->srv->logfunc(param,"Error ldap_init: No init lib ldap");
  92. /*ldap_perror( ld, "Error ldap_init" ); */
  93. return 7;
  94. }
  95. /* this code for Active Directory LDAP catalog :(
  96. detail see documentation for plugin */
  97. if (usercaselow > 0)
  98. #ifdef _WIN32
  99. { CharLower(param->username); }
  100. #else
  101. { lower(param->username); }
  102. #endif
  103. /* create user for test auth */
  104. sprintf(tmpbuf,"%.200s=%.200s,%.200s",attrs[0],param->username,ldap_userenv);
  105. rc = ldap_bind_s( ld, tmpbuf, param->password, LDAP_AUTH_SIMPLE );
  106. if ( rc != LDAP_SUCCESS )
  107. {
  108. param->srv->logfunc(param,"Error ldap_bind: No connect ldap catalog");
  109. ldap_unbind_s(ld);
  110. return 7;
  111. }
  112. ldap_unbind_s(ld);
  113. ld = ldap_init( ldap_serv, 389 );
  114. if ( ld == NULL )
  115. {
  116. param->srv->logfunc(param,"Error ldap_init: No init lib ldap");
  117. /*ldap_perror( ld, "Error ldap_init" ); */
  118. return 7;
  119. }
  120. rc = ldap_bind_s( ld, ldap_user, ldap_pass, LDAP_AUTH_SIMPLE );
  121. if ( rc != LDAP_SUCCESS )
  122. {
  123. param->srv->logfunc(param, "Error ldap_bind: Not authorize in ldap\
  124. catalog, checked option \'ldapconnect\' ");
  125. ldap_unbind_s(ld);
  126. return 7;
  127. }
  128. /* test enter user in filter ------------------------------
  129. create filter for search*/
  130. sprintf(tmpbuf,"(&(%.200s=%.200s)(%.200s=%.200s))",attrs[0],param->username,
  131. ldap_group_attr,ldap_access);
  132. /* search */
  133. rc = ldap_search_s( ld, ldap_sbase, LDAP_SCOPE_SUBTREE,
  134. tmpbuf, attrs, 0, &res );
  135. rc=ldap_count_entries(ld,res);
  136. ldap_msgfree(res);
  137. ldap_unbind_s(ld);
  138. /* user not found */
  139. if (rc == 0)
  140. { return 5; }
  141. return 0;
  142. }
  143. /* --------------------------------------------------------------------------
  144. handle command ldapserv */
  145. int h_ldapconnect(int argc, unsigned char ** argv)
  146. {
  147. LDAP *ld = NULL;
  148. if (argc < 2)
  149. {
  150. fprintf(stderr, "Error in ldapconnect: See documentation of ldapauth plugin.\n");
  151. return 1;
  152. }
  153. ldap_serv=strdup(argv[1]);
  154. ldap_user=strdup(argv[2]);
  155. ld = ldap_init( ldap_serv, 389 );
  156. ldap_unbind_s(ld);
  157. if (argc == 4)
  158. {
  159. ldap_pass= strdup(argv[3]);
  160. }
  161. else
  162. {
  163. ldap_pass=NULL;
  164. }
  165. return 0;
  166. }
  167. /* --------------------------------------------------------------------------
  168. handle command ldapaccess */
  169. int h_access(int argc, unsigned char ** argv)
  170. {
  171. if (argc < 1)
  172. {
  173. fprintf(stderr, "Error in ldapaccess: See documentation of ldapauth plugin.\n");
  174. return 1;
  175. }
  176. ldap_access=strdup(argv[1]);
  177. return 0;
  178. }
  179. /* --------------------------------------------------------------------------
  180. handle command ldapsbase
  181. searching base */
  182. int h_sbase(int argc, unsigned char ** argv)
  183. {
  184. if (argc < 1)
  185. {
  186. fprintf(stderr, "Error in ldapsbase: See documentation of ldapauth plugin.\n");
  187. return 1;
  188. }
  189. ldap_sbase=strdup(argv[1]);
  190. return 0;
  191. }
  192. /* --------------------------------------------------------------------------
  193. handle command ldapuserenv */
  194. int h_userenv(int argc, unsigned char ** argv)
  195. {
  196. if (argc < 1)
  197. {
  198. fprintf(stderr, "Error in ldapsbase: See documentation of ldapauth plugin.\n");
  199. return 1;
  200. }
  201. ldap_userenv=strdup(argv[1]);
  202. return 0;
  203. }
  204. /* --------------------------------------------------------------------------
  205. handle command ldaptrafgroup */
  206. int h_trafgroup(int argc, unsigned char ** argv)
  207. {
  208. struct trafcount *newtrafcount;
  209. struct bandlim *newbandlim;
  210. static struct ace *newace;
  211. static struct userlist *newuserlist;
  212. struct counter_record rcounter;
  213. LDAP *ld = NULL;
  214. LDAPMessage *res = NULL;
  215. LDAPMessage *msg = NULL;
  216. BerElement *ber = NULL;
  217. int rc = -1;
  218. char *tmpbuf,pat_file[]="%s%s.lc",pat_group[]="(%s=%s)";
  219. char *getattr,**vals,buf[256];
  220. ROTATION rtype;
  221. unsigned long traflimit;
  222. int bandwidth ;
  223. FILE *f;
  224. if (argc < 3)
  225. {
  226. fprintf(stderr, "Error in ldaptrafgroup: See documentation of ldapauth plugin.\n");
  227. return 1;
  228. }
  229. ld = ldap_init( ldap_serv, 389 );
  230. if ( ld == NULL )
  231. {
  232. fprintf(stderr,"Error in ldaptrafgroup: ldap_init: No init lib ldap");
  233. return 7;
  234. }
  235. rc = ldap_bind_s( ld, ldap_user, ldap_pass, LDAP_AUTH_SIMPLE );
  236. if ( rc != LDAP_SUCCESS )
  237. {
  238. fprintf(stderr, "Error in ldaptrafgroup: ldap_bind: Not authorize in ldap\
  239. catalog, checked option \'ldapconnect\' ");
  240. ldap_unbind_s(ld);
  241. return 7;
  242. }
  243. /* type traf limit */
  244. if(strcmp(argv[2],"MONTHLY")==0||strcmp(argv[2],"monthly")==0)
  245. {rtype=MONTHLY;}
  246. if(strcmp(argv[2],"DAILY")==0||strcmp(argv[2],"daily")==0)
  247. {rtype=DAILY;}
  248. if(strcmp(argv[2],"WEEKLY")==0||strcmp(argv[2],"weekly")==0)
  249. {rtype=WEEKLY;}
  250. traflimit = atol((char *)argv[3]);
  251. bandwidth = atoi((char *)argv[4]);
  252. /* name ldap group */
  253. tmpbuf=malloc(strlen(pat_group)+strlen(ldap_group_attr)+strlen(argv[1]));
  254. sprintf(tmpbuf,pat_group,ldap_group_attr,argv[1]);
  255. rc = ldap_search_s( ld, ldap_sbase, LDAP_SCOPE_SUBTREE,
  256. tmpbuf, attrs, 0, &res );
  257. free(tmpbuf);
  258. rc=ldap_count_entries(ld,res);
  259. /* users found */
  260. if (rc > 0)
  261. {
  262. msg=ldap_first_entry(ld, res);
  263. getattr=ldap_first_attribute(ld, msg, &ber);
  264. while (rc > 0)
  265. {
  266. vals=ldap_get_values(ld, msg, getattr);
  267. if (vals != NULL && vals[0] != NULL )
  268. {
  269. /* -------------bandlim----------
  270. create user list */
  271. newuserlist = (*mypluginlink->mallocfunc)(sizeof (struct userlist));
  272. if (usercaselow > 0)
  273. #ifdef _WIN32
  274. { CharLower(vals[0]); }
  275. #else
  276. { lower(vals[0]); }
  277. #endif
  278. newuserlist->user = (*mypluginlink->strdupfunc)(vals[0]);
  279. newuserlist->next = NULL;
  280. /*create user rule */
  281. newace = (*mypluginlink->mallocfunc)(sizeof (struct ace));
  282. memset(newace, 0, sizeof(struct ace));
  283. newace->users = newuserlist;
  284. newace->action = BANDLIM;
  285. /*create user bandlim */
  286. newbandlim =(*mypluginlink->mallocfunc)(sizeof (struct bandlim));
  287. memset(newbandlim, 0, sizeof(struct bandlim));
  288. newbandlim->rate = bandwidth;
  289. newbandlim->ace = newace;
  290. newbandlim->next = mypluginlink->conf->bandlimiter;
  291. mypluginlink->conf->bandlimiter = newbandlim;
  292. /* -------------counters----------
  293. create user list */
  294. newuserlist = (*mypluginlink->mallocfunc)(sizeof (struct userlist));
  295. if (usercaselow > 0)
  296. #ifdef _WIN32
  297. { CharLower(vals[0]); }
  298. #else
  299. { lower(vals[0]); }
  300. #endif
  301. newuserlist->user = (*mypluginlink->strdupfunc)(vals[0]);
  302. newuserlist->next = NULL;
  303. /*create user rule */
  304. newace = (*mypluginlink->mallocfunc)(sizeof (struct ace));
  305. memset(newace, 0, sizeof(struct ace));
  306. newace->users = newuserlist;
  307. newace->action = COUNTIN;
  308. /*create user counter */
  309. newtrafcount =(*mypluginlink->mallocfunc)(sizeof (struct trafcount));
  310. memset(newtrafcount, 0, sizeof(struct trafcount));
  311. newtrafcount->ace = newace;
  312. newtrafcount->type=rtype;
  313. newtrafcount->traflim64 = traflimit;
  314. newtrafcount->comment=(*mypluginlink->strdupfunc)("ldapcounters");
  315. newtrafcount->number=0;
  316. tmpbuf=malloc(strlen(pat_file)+strlen(ldap_dircount)+strlen(vals[0]));
  317. sprintf(tmpbuf,pat_file,ldap_dircount,vals[0]);
  318. f=NULL;
  319. f=fopen(tmpbuf,"rb");
  320. if(f!=NULL)
  321. {
  322. fseek(f,0,SEEK_SET);
  323. fgets(buf, 256, f);
  324. sscanf(buf,"%"PRINTF_INT64_MODIFIER"u %lu %lu\n",&rcounter.traf64,
  325. &rcounter.cleared, &rcounter.updated);
  326. newtrafcount->traf64=rcounter.traf64;
  327. newtrafcount->cleared=rcounter.cleared;
  328. newtrafcount->updated=rcounter.updated;
  329. fclose(f);
  330. }
  331. free(tmpbuf);
  332. newtrafcount->next = mypluginlink->conf->trafcounter;
  333. mypluginlink->conf->trafcounter = newtrafcount;
  334. ldap_value_free(vals);
  335. }
  336. msg=ldap_next_entry(ld, msg);
  337. rc--;
  338. }
  339. }/* end if (rc > 0) */
  340. ldap_unbind_s(ld);
  341. return 0;
  342. }
  343. /* --------------------------------------------------------------------------
  344. handle command ldapattrsgroup */
  345. int h_attrsgroup(int argc, unsigned char ** argv)
  346. {
  347. if (argc < 1)
  348. {
  349. fprintf(stderr, "Error in ldapattr: See documentation of ldapauth plugin.\n");
  350. return 1;
  351. }
  352. attrs[0]=strdup(argv[1]);
  353. ldap_group_attr=strdup(argv[2]);
  354. if(argc == 4)
  355. { usercaselow=atoi(argv[3]); }
  356. return 0;
  357. }
  358. /* --------------------------------------------------------------------------
  359. handle command ldapdircount */
  360. int h_dircount(int argc, unsigned char ** argv)
  361. {
  362. if (argc < 1)
  363. {
  364. fprintf(stderr, "Error in ldapdircount: See documentation of ldapauth plugin.\n");
  365. return 1;
  366. }
  367. ldap_dircount=strdup(argv[1]);
  368. return 0;
  369. }
  370. /*------------------------------- MAIN --------------------------------------
  371. start plugin init */
  372. #ifdef WATCOM
  373. #pragma aux start "*" parm caller [ ] value struct float struct routine [eax] modify [eax ecx edx]
  374. #undef PLUGINCALL
  375. #define PLUGINCALL
  376. #endif
  377. PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink,
  378. int argc, char** argv)
  379. {
  380. if (already_loaded != 0)
  381. {
  382. free(ldap_access);
  383. free(ldap_sbase);
  384. free(ldap_serv);
  385. free(ldap_user);
  386. free(ldap_pass);
  387. free(ldap_userenv);
  388. free(ldap_dircount);
  389. free(ldap_group_attr);
  390. free(attrs[0]);
  391. return (0);
  392. }
  393. already_loaded = 1;
  394. mypluginlink=pluginlink;
  395. ldap_access=NULL;
  396. ldap_sbase=NULL;
  397. ldap_serv=NULL;
  398. ldap_user=NULL;
  399. ldap_pass=NULL;
  400. ldap_userenv=NULL;
  401. ldap_trafgroup=NULL;
  402. ldap_dircount=NULL;
  403. ldap_group_attr=NULL;
  404. myalwaysauth.preauthorize = pluginlink->checkpreACL;
  405. myalwaysauth.authenticate = ldapfunc;
  406. myalwaysauth.authorize = pluginlink->checkACL;
  407. myalwaysauth.desc = "ldap";
  408. myalwaysauth.next = pluginlink->authfuncs->next;
  409. pluginlink->authfuncs->next = &myalwaysauth;
  410. /* add command: ldapconnect ipserv user_serv pass_serv */
  411. ldap_serv_auth_handler.minargs = 3;
  412. ldap_serv_auth_handler.maxargs = 4;
  413. ldap_serv_auth_handler.command = "ldapconnect";
  414. ldap_serv_auth_handler.handler = h_ldapconnect;
  415. ldap_serv_auth_handler.next = pluginlink->commandhandlers->next;
  416. pluginlink->commandhandlers->next = &ldap_serv_auth_handler;
  417. /* add command: ldapaccess cn=internet,cn=users,dc=domain,dc=ru */
  418. ldap_access_handler.minargs = 2;
  419. ldap_access_handler.maxargs = 2;
  420. ldap_access_handler.command = "ldapaccess";
  421. ldap_access_handler.handler = h_access;
  422. ldap_access_handler.next = pluginlink->commandhandlers->next;
  423. pluginlink->commandhandlers->next = &ldap_access_handler;
  424. /* add command: ldapsbase cn=users,dc=domain,dc=ru */
  425. ldap_sbase_handler.minargs = 2;
  426. ldap_sbase_handler.maxargs = 2;
  427. ldap_sbase_handler.command = "ldapsbase";
  428. ldap_sbase_handler.handler = h_sbase;
  429. ldap_sbase_handler.next = pluginlink->commandhandlers->next;
  430. pluginlink->commandhandlers->next = &ldap_sbase_handler;
  431. /* add command: ldapuserenv (cn=users,dc=domain,dc=ru) */
  432. ldap_userenv_handler.minargs = 2;
  433. ldap_userenv_handler.maxargs = 2;
  434. ldap_userenv_handler.command = "ldapuserenv";
  435. ldap_userenv_handler.handler = h_userenv;
  436. ldap_userenv_handler.next = pluginlink->commandhandlers->next;
  437. pluginlink->commandhandlers->next = &ldap_userenv_handler;
  438. /* add command: ldaptrafgroup cn=traf500,cn=users,dc=domain,dc=ru M 500 333 */
  439. ldap_trafgroup_handler.minargs = 5;
  440. ldap_trafgroup_handler.maxargs = 5;
  441. ldap_trafgroup_handler.command = "ldaptrafgroup";
  442. ldap_trafgroup_handler.handler = h_trafgroup;
  443. ldap_trafgroup_handler.next = pluginlink->commandhandlers->next;
  444. pluginlink->commandhandlers->next = &ldap_trafgroup_handler;
  445. /* add command: ldapattr cn memberOf usercaselow=1 */
  446. ldap_attrsgroup_handler.minargs = 3;
  447. ldap_attrsgroup_handler.maxargs = 4;
  448. ldap_attrsgroup_handler.command = "ldapattr";
  449. ldap_attrsgroup_handler.handler = h_attrsgroup;
  450. ldap_attrsgroup_handler.next = pluginlink->commandhandlers->next;
  451. pluginlink->commandhandlers->next = &ldap_attrsgroup_handler;
  452. /* add command: ldapdircount c:\3proxy\ */
  453. ldap_dircount_handler.minargs = 2;
  454. ldap_dircount_handler.maxargs = 2;
  455. ldap_dircount_handler.command = "ldapdircount";
  456. ldap_dircount_handler.handler = h_dircount;
  457. ldap_dircount_handler.next = pluginlink->commandhandlers->next;
  458. pluginlink->commandhandlers->next = &ldap_dircount_handler;
  459. /*create job shedule for processing reload, save counters to file */
  460. memset(&myschedule,0,sizeof(struct schedule));
  461. myschedule.type=MINUTELY;
  462. myschedule.function=savecounters;
  463. myschedule.next = *pluginlink->schedule;
  464. *pluginlink->schedule=&myschedule;
  465. return 0;
  466. }