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