mirror of
https://github.com/3proxy/3proxy.git
synced 2025-04-22 04:02:08 +08:00
576 lines
16 KiB
C
576 lines
16 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <ldap.h>
|
|
|
|
#ifndef _WIN32
|
|
|
|
#include <ctype.h>
|
|
#endif
|
|
|
|
#include "../../proxy.h"
|
|
#include "../../structures.h"
|
|
|
|
struct counter_record
|
|
{
|
|
unsigned long traf;
|
|
unsigned long trafgb;
|
|
time_t cleared;
|
|
time_t updated;
|
|
};
|
|
|
|
|
|
int already_loaded = 0;
|
|
|
|
static struct auth myalwaysauth;
|
|
static struct commands ldap_serv_auth_handler;
|
|
static struct commands ldap_access_handler;
|
|
static struct commands ldap_sbase_handler;
|
|
static struct commands ldap_userenv_handler;
|
|
static struct commands ldap_trafgroup_handler;
|
|
static struct commands ldap_attrsgroup_handler;
|
|
static struct commands ldap_dircount_handler;
|
|
|
|
static char *attrs[] = { NULL, NULL};
|
|
static char *ldap_group_attr;
|
|
static char *ldap_access;
|
|
static char *ldap_sbase;
|
|
static char *ldap_serv;
|
|
static char *ldap_user;
|
|
static char *ldap_pass;
|
|
static char *ldap_userenv;
|
|
int ldap_userenv_size;
|
|
static char *ldap_trafgroup;
|
|
static char *ldap_dircount;
|
|
static int usercaselow = 0;
|
|
|
|
struct pluginlink * mypluginlink;
|
|
struct schedule myschedule;
|
|
|
|
#ifndef _WIN32
|
|
void lower (char *string)
|
|
{
|
|
int length, i;
|
|
|
|
length = strlen(string);
|
|
for (i=0; i<length; i++)
|
|
{
|
|
string[i] = tolower(string[i]);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
int savecouters(void)
|
|
{
|
|
struct trafcount *tc=mypluginlink->conf->trafcounter;
|
|
struct trafcount *tcd;
|
|
struct counter_record wcounter;
|
|
FILE *f;
|
|
unsigned char *tmpbuf,pat_file[]="%s%s.lc";
|
|
|
|
|
|
/* timetoexit !=0 - áóäåì çàâåðøàòüñÿ.*/
|
|
while (tc != NULL)
|
|
{
|
|
tcd = tc;
|
|
tc = tc->next;
|
|
f=NULL;
|
|
if(strcmp(tcd->comment,"ldapcounters")==0) {
|
|
tmpbuf=mypluginlink->myalloc(strlen(pat_file)+strlen(ldap_dircount)+strlen(tcd->ace->users->user));
|
|
sprintf(tmpbuf,pat_file,ldap_dircount,tcd->ace->users->user);
|
|
f=fopen(tmpbuf,"w+b");
|
|
fseek(f,0,SEEK_SET);
|
|
fprintf(f,"%10lu %10lu %lu %lu\n",tcd->trafgb,tcd->traf,
|
|
tcd->cleared,tcd->updated);
|
|
|
|
fclose(f);
|
|
mypluginlink->myfree(tmpbuf);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*return 1 delete job , return 0 no delete job*/
|
|
if (mypluginlink->conf->needreload !=0 )
|
|
{
|
|
return (0);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
#ifdef _WIN32
|
|
__declspec(dllexport) int start(struct pluginlink * pluginlink,
|
|
int argc, char** argv);
|
|
BOOL APIENTRY DllMain( HMODULE hModule,
|
|
DWORD ul_reason_for_call,
|
|
LPVOID lpReserved
|
|
)
|
|
{
|
|
return TRUE;
|
|
}
|
|
#else
|
|
|
|
int start(struct pluginlink * pluginlink,
|
|
int argc, char** argv);
|
|
|
|
#endif
|
|
|
|
/* --------------------------------------------------------------------------*/
|
|
static int ldapfunc(struct clientparam *param)
|
|
{
|
|
|
|
LDAP *ld = NULL;
|
|
LDAPMessage *res = NULL;
|
|
int rc = -1;
|
|
char tmpbuf[1024];
|
|
|
|
|
|
/* init ldap ---------------------- */
|
|
ld = ldap_init( ldap_serv, 389 );
|
|
if ( ld == NULL )
|
|
{
|
|
param->srv->logfunc(param,"Error ldap_init: No init lib ldap");
|
|
/*ldap_perror( ld, "Error ldap_init" ); */
|
|
return 7;
|
|
}
|
|
|
|
/* test proxy user auth ------------------------*/
|
|
if(!param->username || !param->password) return 4;
|
|
if(strlen(param->password)==0) return 4;
|
|
|
|
/* this code for Active Directory LDAP catalog :(
|
|
detail see documentation for plugin */
|
|
if (usercaselow > 0)
|
|
#ifdef _WIN32
|
|
{ CharLower(param->username); }
|
|
#else
|
|
{ lower(param->username); }
|
|
#endif
|
|
|
|
|
|
/* create user for test auth */
|
|
sprintf(tmpbuf,"%.200s=%.200s,%.200s",attrs[0],param->username,ldap_userenv);
|
|
|
|
rc = ldap_bind_s( ld, tmpbuf, param->password, LDAP_AUTH_SIMPLE );
|
|
|
|
|
|
if ( rc != LDAP_SUCCESS )
|
|
{
|
|
param->srv->logfunc(param,"Error ldap_bind: No connect ldap catalog");
|
|
ldap_unbind_s(ld);
|
|
return 7;
|
|
}
|
|
|
|
ldap_unbind_s(ld);
|
|
|
|
ld = ldap_init( ldap_serv, 389 );
|
|
rc = ldap_bind_s( ld, ldap_user, ldap_pass, LDAP_AUTH_SIMPLE );
|
|
|
|
if ( rc != LDAP_SUCCESS )
|
|
{
|
|
param->srv->logfunc(param, "Error ldap_bind: Not authorize in ldap\
|
|
catalog, checked option \'ldapconnect\' ");
|
|
ldap_unbind_s(ld);
|
|
return 7;
|
|
}
|
|
|
|
/* test enter user in filter ------------------------------
|
|
create filter for search*/
|
|
|
|
sprintf(tmpbuf,"(&(%.200s=%.200s)(%.200s=%.200s))",attrs[0],param->username,
|
|
ldap_group_attr,ldap_access);
|
|
|
|
|
|
/* search */
|
|
rc = ldap_search_s( ld, ldap_sbase, LDAP_SCOPE_SUBTREE,
|
|
tmpbuf, attrs, 0, &res );
|
|
|
|
rc=ldap_count_entries(ld,res);
|
|
|
|
ldap_msgfree(res);
|
|
ldap_unbind_s(ld);
|
|
|
|
/* user not found */
|
|
if (rc == 0)
|
|
{ return 5; }
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------
|
|
handle command ldapserv */
|
|
int h_ldapconnect(int argc, unsigned char ** argv)
|
|
{
|
|
LDAP *ld = NULL;
|
|
|
|
if (argc < 2)
|
|
{
|
|
fprintf(stderr, "Error in ldapconnect: See documentation of ldapauth plugin.\n");
|
|
return 1;
|
|
}
|
|
|
|
ldap_serv=mypluginlink->mystrdup(argv[1]);
|
|
ldap_user=mypluginlink->mystrdup(argv[2]);
|
|
|
|
ld = ldap_init( ldap_serv, 389 );
|
|
ldap_unbind_s(ld);
|
|
|
|
if (argc == 4)
|
|
{
|
|
ldap_pass= mypluginlink->mystrdup(argv[3]);
|
|
}
|
|
else
|
|
{
|
|
ldap_pass=NULL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
/* --------------------------------------------------------------------------
|
|
handle command ldapaccess */
|
|
int h_access(int argc, unsigned char ** argv)
|
|
{
|
|
if (argc < 1)
|
|
{
|
|
fprintf(stderr, "Error in ldapaccess: See documentation of ldapauth plugin.\n");
|
|
return 1;
|
|
}
|
|
ldap_access=mypluginlink->mystrdup(argv[1]);
|
|
return 0;
|
|
}
|
|
/* --------------------------------------------------------------------------
|
|
handle command ldapsbase
|
|
searching base */
|
|
int h_sbase(int argc, unsigned char ** argv)
|
|
{
|
|
if (argc < 1)
|
|
{
|
|
fprintf(stderr, "Error in ldapsbase: See documentation of ldapauth plugin.\n");
|
|
return 1;
|
|
}
|
|
ldap_sbase=mypluginlink->mystrdup(argv[1]);
|
|
return 0;
|
|
}
|
|
/* --------------------------------------------------------------------------
|
|
handle command ldapuserenv */
|
|
int h_userenv(int argc, unsigned char ** argv)
|
|
{
|
|
if (argc < 1)
|
|
{
|
|
fprintf(stderr, "Error in ldapsbase: See documentation of ldapauth plugin.\n");
|
|
return 1;
|
|
}
|
|
ldap_userenv=mypluginlink->mystrdup(argv[1]);
|
|
return 0;
|
|
}
|
|
/* --------------------------------------------------------------------------
|
|
handle command ldaptrafgroup */
|
|
int h_trafgroup(int argc, unsigned char ** argv)
|
|
{
|
|
struct trafcount *newtrafcount;
|
|
struct bandlim *newbandlim;
|
|
static struct ace *newace;
|
|
static struct userlist *newuserlist;
|
|
struct counter_record rcounter;
|
|
|
|
LDAP *ld = NULL;
|
|
LDAPMessage *res = NULL;
|
|
LDAPMessage *msg = NULL;
|
|
BerElement *ber = NULL;
|
|
int rc = -1;
|
|
char *tmpbuf,pat_file[]="%s%s.lc",pat_group[]="(%s=%s)";
|
|
char *getattr,**vals,buf[256];
|
|
ROTATION rtype;
|
|
unsigned long traflimit;
|
|
int bandwidth ;
|
|
|
|
FILE *f;
|
|
|
|
if (argc < 3)
|
|
{
|
|
fprintf(stderr, "Error in ldaptrafgroup: See documentation of ldapauth plugin.\n");
|
|
return 1;
|
|
}
|
|
|
|
ld = ldap_init( ldap_serv, 389 );
|
|
|
|
if ( ld == NULL )
|
|
{
|
|
fprintf(stderr,"Error in ldaptrafgroup: ldap_init: No init lib ldap");
|
|
return 7;
|
|
}
|
|
|
|
rc = ldap_bind_s( ld, ldap_user, ldap_pass, LDAP_AUTH_SIMPLE );
|
|
|
|
if ( rc != LDAP_SUCCESS )
|
|
{
|
|
fprintf(stderr, "Error in ldaptrafgroup: ldap_bind: Not authorize in ldap\
|
|
catalog, checked option \'ldapconnect\' ");
|
|
ldap_unbind_s(ld);
|
|
return 7;
|
|
}
|
|
|
|
/* type traf limit */
|
|
if(strcmp(argv[2],"MONTHLY")==0||strcmp(argv[2],"monthly")==0)
|
|
{rtype=MONTHLY;}
|
|
|
|
if(strcmp(argv[2],"DAILY")==0||strcmp(argv[2],"daily")==0)
|
|
{rtype=DAILY;}
|
|
|
|
if(strcmp(argv[2],"WEEKLY")==0||strcmp(argv[2],"weekly")==0)
|
|
{rtype=WEEKLY;}
|
|
|
|
traflimit = atol((char *)argv[3]);
|
|
bandwidth = atoi((char *)argv[4]);
|
|
|
|
/* name ldap group */
|
|
tmpbuf=mypluginlink->myalloc(strlen(pat_group)+strlen(ldap_group_attr)+strlen(argv[1]));
|
|
sprintf(tmpbuf,pat_group,ldap_group_attr,argv[1]);
|
|
rc = ldap_search_s( ld, ldap_sbase, LDAP_SCOPE_SUBTREE,
|
|
tmpbuf, attrs, 0, &res );
|
|
mypluginlink->myfree(tmpbuf);
|
|
|
|
rc=ldap_count_entries(ld,res);
|
|
|
|
/* users found */
|
|
if (rc > 0)
|
|
{
|
|
msg=ldap_first_entry(ld, res);
|
|
getattr=ldap_first_attribute(ld, msg, &ber);
|
|
|
|
while (rc > 0)
|
|
{
|
|
vals=ldap_get_values(ld, msg, getattr);
|
|
if (vals != NULL && vals[0] != NULL )
|
|
{
|
|
|
|
/* -------------bandlim----------
|
|
create user list */
|
|
newuserlist = (*mypluginlink->myalloc)(sizeof (struct userlist));
|
|
if (usercaselow > 0)
|
|
#ifdef _WIN32
|
|
{ CharLower(vals[0]); }
|
|
#else
|
|
{ lower(vals[0]); }
|
|
#endif
|
|
|
|
newuserlist->user = (*mypluginlink->mystrdup)(vals[0]);
|
|
newuserlist->next = NULL;
|
|
/*create user rule */
|
|
newace = (*mypluginlink->myalloc)(sizeof (struct ace));
|
|
memset(newace, 0, sizeof(struct ace));
|
|
newace->users = newuserlist;
|
|
newace->action = BANDLIM;
|
|
/*create user bandlim */
|
|
newbandlim =(*mypluginlink->myalloc)(sizeof (struct bandlim));
|
|
memset(newbandlim, 0, sizeof(struct bandlim));
|
|
newbandlim->rate = bandwidth;
|
|
newbandlim->ace = newace;
|
|
newbandlim->next = mypluginlink->conf->bandlimiter;
|
|
mypluginlink->conf->bandlimiter = newbandlim;
|
|
|
|
/* -------------counters----------
|
|
create user list */
|
|
newuserlist = (*mypluginlink->myalloc)(sizeof (struct userlist));
|
|
if (usercaselow > 0)
|
|
#ifdef _WIN32
|
|
{ CharLower(vals[0]); }
|
|
#else
|
|
{ lower(vals[0]); }
|
|
#endif
|
|
newuserlist->user = (*mypluginlink->mystrdup)(vals[0]);
|
|
newuserlist->next = NULL;
|
|
/*create user rule */
|
|
newace = (*mypluginlink->myalloc)(sizeof (struct ace));
|
|
memset(newace, 0, sizeof(struct ace));
|
|
newace->users = newuserlist;
|
|
newace->action = COUNTIN;
|
|
/*create user counter */
|
|
newtrafcount =(*mypluginlink->myalloc)(sizeof (struct trafcount));
|
|
memset(newtrafcount, 0, sizeof(struct trafcount));
|
|
newtrafcount->ace = newace;
|
|
newtrafcount->type=rtype;
|
|
newtrafcount->traflimgb =(traflimit/(1024*4));
|
|
newtrafcount->traflim = ((traflimit - (newtrafcount->traflimgb*(1024*4)))*(1024*1024));
|
|
newtrafcount->comment=(*mypluginlink->mystrdup)("ldapcounters");
|
|
newtrafcount->number=0;
|
|
tmpbuf=(*mypluginlink->myalloc)(strlen(pat_file)+strlen(ldap_dircount)+strlen(vals[0]));
|
|
sprintf(tmpbuf,pat_file,ldap_dircount,vals[0]);
|
|
f=NULL;
|
|
f=fopen(tmpbuf,"rb");
|
|
if(f!=NULL)
|
|
{
|
|
|
|
fseek(f,0,SEEK_SET);
|
|
fgets(buf, 256, f);
|
|
sscanf(buf,"%10lu %10lu %lu %lu\n",&rcounter.trafgb, &rcounter.traf,
|
|
&rcounter.cleared, &rcounter.updated);
|
|
|
|
|
|
newtrafcount->trafgb=rcounter.trafgb;
|
|
newtrafcount->traf=rcounter.traf;
|
|
newtrafcount->cleared=rcounter.cleared;
|
|
newtrafcount->updated=rcounter.updated;
|
|
fclose(f);
|
|
}
|
|
mypluginlink->myfree(tmpbuf);
|
|
|
|
newtrafcount->next = mypluginlink->conf->trafcounter;
|
|
mypluginlink->conf->trafcounter = newtrafcount;
|
|
|
|
ldap_value_free(vals);
|
|
}
|
|
msg=ldap_next_entry(ld, msg);
|
|
rc--;
|
|
}
|
|
|
|
}/* end if (rc > 0) */
|
|
|
|
ldap_unbind_s(ld);
|
|
|
|
return 0;
|
|
}
|
|
/* --------------------------------------------------------------------------
|
|
handle command ldapattrsgroup */
|
|
int h_attrsgroup(int argc, unsigned char ** argv)
|
|
{
|
|
if (argc < 1)
|
|
{
|
|
fprintf(stderr, "Error in ldapattr: See documentation of ldapauth plugin.\n");
|
|
return 1;
|
|
}
|
|
attrs[0]=mypluginlink->mystrdup(argv[1]);
|
|
ldap_group_attr=mypluginlink->mystrdup(argv[2]);
|
|
|
|
if(argc == 4)
|
|
{ usercaselow=atoi(argv[3]); }
|
|
|
|
return 0;
|
|
}
|
|
/* --------------------------------------------------------------------------
|
|
handle command ldapdircount */
|
|
int h_dircount(int argc, unsigned char ** argv)
|
|
{
|
|
if (argc < 1)
|
|
{
|
|
fprintf(stderr, "Error in ldapdircount: See documentation of ldapauth plugin.\n");
|
|
return 1;
|
|
}
|
|
ldap_dircount=mypluginlink->mystrdup(argv[1]);
|
|
return 0;
|
|
}
|
|
|
|
/*------------------------------- MAIN --------------------------------------
|
|
start plugin init */
|
|
int start(struct pluginlink * pluginlink, int argc, char** argv)
|
|
{
|
|
|
|
|
|
if (already_loaded != 0)
|
|
{
|
|
pluginlink->myfree(ldap_access);
|
|
pluginlink->myfree(ldap_sbase);
|
|
pluginlink->myfree(ldap_serv);
|
|
pluginlink->myfree(ldap_user);
|
|
pluginlink->myfree(ldap_pass);
|
|
pluginlink->myfree(ldap_userenv);
|
|
pluginlink->myfree(ldap_dircount);
|
|
pluginlink->myfree(ldap_group_attr);
|
|
pluginlink->myfree(attrs[0]);
|
|
return (0);
|
|
}
|
|
|
|
already_loaded = 1;
|
|
|
|
mypluginlink=pluginlink;
|
|
|
|
ldap_access=NULL;
|
|
ldap_sbase=NULL;
|
|
ldap_serv=NULL;
|
|
ldap_user=NULL;
|
|
ldap_pass=NULL;
|
|
ldap_userenv=NULL;
|
|
ldap_trafgroup=NULL;
|
|
ldap_dircount=NULL;
|
|
ldap_group_attr=NULL;
|
|
|
|
|
|
|
|
myalwaysauth.authenticate = ldapfunc;
|
|
myalwaysauth.authorize = pluginlink->checkACL;
|
|
myalwaysauth.desc = "ldap";
|
|
myalwaysauth.next = pluginlink->authfuncs->next;
|
|
pluginlink->authfuncs->next = &myalwaysauth;
|
|
|
|
/* add command: ldapconnect ipserv user_serv pass_serv */
|
|
ldap_serv_auth_handler.minargs = 3;
|
|
ldap_serv_auth_handler.maxargs = 4;
|
|
ldap_serv_auth_handler.command = "ldapconnect";
|
|
ldap_serv_auth_handler.handler = h_ldapconnect;
|
|
ldap_serv_auth_handler.next = pluginlink->commandhandlers->next;
|
|
pluginlink->commandhandlers->next = &ldap_serv_auth_handler;
|
|
|
|
/* add command: ldapaccess cn=internet,cn=users,dc=domain,dc=ru */
|
|
ldap_access_handler.minargs = 2;
|
|
ldap_access_handler.maxargs = 2;
|
|
ldap_access_handler.command = "ldapaccess";
|
|
ldap_access_handler.handler = h_access;
|
|
ldap_access_handler.next = pluginlink->commandhandlers->next;
|
|
pluginlink->commandhandlers->next = &ldap_access_handler;
|
|
|
|
/* add command: ldapsbase cn=users,dc=domain,dc=ru */
|
|
ldap_sbase_handler.minargs = 2;
|
|
ldap_sbase_handler.maxargs = 2;
|
|
ldap_sbase_handler.command = "ldapsbase";
|
|
ldap_sbase_handler.handler = h_sbase;
|
|
ldap_sbase_handler.next = pluginlink->commandhandlers->next;
|
|
pluginlink->commandhandlers->next = &ldap_sbase_handler;
|
|
|
|
/* add command: ldapuserenv (cn=users,dc=domain,dc=ru) */
|
|
ldap_userenv_handler.minargs = 2;
|
|
ldap_userenv_handler.maxargs = 2;
|
|
ldap_userenv_handler.command = "ldapuserenv";
|
|
ldap_userenv_handler.handler = h_userenv;
|
|
ldap_userenv_handler.next = pluginlink->commandhandlers->next;
|
|
pluginlink->commandhandlers->next = &ldap_userenv_handler;
|
|
|
|
/* add command: ldaptrafgroup cn=traf500,cn=users,dc=domain,dc=ru M 500 333 */
|
|
ldap_trafgroup_handler.minargs = 5;
|
|
ldap_trafgroup_handler.maxargs = 5;
|
|
ldap_trafgroup_handler.command = "ldaptrafgroup";
|
|
ldap_trafgroup_handler.handler = h_trafgroup;
|
|
ldap_trafgroup_handler.next = pluginlink->commandhandlers->next;
|
|
pluginlink->commandhandlers->next = &ldap_trafgroup_handler;
|
|
|
|
/* add command: ldapattr cn memberOf usercaselow=1 */
|
|
ldap_attrsgroup_handler.minargs = 3;
|
|
ldap_attrsgroup_handler.maxargs = 4;
|
|
ldap_attrsgroup_handler.command = "ldapattr";
|
|
ldap_attrsgroup_handler.handler = h_attrsgroup;
|
|
ldap_attrsgroup_handler.next = pluginlink->commandhandlers->next;
|
|
pluginlink->commandhandlers->next = &ldap_attrsgroup_handler;
|
|
|
|
/* add command: ldapdircount c:\3proxy\ */
|
|
ldap_dircount_handler.minargs = 2;
|
|
ldap_dircount_handler.maxargs = 2;
|
|
ldap_dircount_handler.command = "ldapdircount";
|
|
ldap_dircount_handler.handler = h_dircount;
|
|
ldap_dircount_handler.next = pluginlink->commandhandlers->next;
|
|
pluginlink->commandhandlers->next = &ldap_dircount_handler;
|
|
|
|
/*create job shedule for processing reload, save counters to file */
|
|
memset(&myschedule,0,sizeof(struct schedule));
|
|
myschedule.type=MINUTELY;
|
|
myschedule.function=savecouters;
|
|
myschedule.next = *pluginlink->schedule;
|
|
*pluginlink->schedule=&myschedule;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|