ShellBanner
System:Linux MiraNet 3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686
Software:Apache. PHP/5.3.6-13ubuntu3.10
ID:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Safe Mode:OFF
Open_Basedir:OFF
Freespace:24.46 GB of 70.42 GB (34.73%)
MySQL: ON MSSQL: OFF Oracle: OFF PostgreSQL: OFF Curl: OFF Sockets: ON Fetch: OFF Wget: ON Perl: ON
Disabled Functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,

/ usr/ src/ courier-0.66.1/ courier/ - drwxrwxrwx

Directory:
Viewing file:     ldapaliasd.c (16.75 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
** Copyright 2000-2009 Double Precision, Inc.
** See COPYING for distribution information.
*/

#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include    "numlib/numlib.h"
#if TIME_WITH_SYS_TIME
#include        <sys/time.h>
#include        <time.h>
#else
#if HAVE_SYS_TIME_H
#include        <sys/time.h>
#else
#include        <time.h>
#endif
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_LBER_H
#include <lber.h>
#endif
#if HAVE_LBER_H
#include <lber.h>
#endif
#if HAVE_LDAP_H
#include <ldap.h>
#if LDAP_VENDOR_VERSION > 20000
#define OPENLDAPV2
#endif
#endif
#if HAVE_SYSLOG_H
#include <syslog.h>
#else
#define syslog(a,b)
#endif
#include <sys/socket.h>
#include <sys/un.h>

#include    <courierauth.h>
#include    "courier.h"
#include    "liblock/config.h"
#include    "liblock/liblock.h"
#include    "ldapaliasdrc.h"
#include    "sysconfdir.h"
#include    "localstatedir.h"


static LDAP *my_ldap_fp=0;
static const char *basedn;
static const char *mailfield;
static const char *maildropfield;
static const char *sourcefield;
static const char *vdomain;
static const char *vuser;
static int timeout_n;


/*
** There's a memory leak in OpenLDAP 1.2.11, presumably in earlier versions
** too.  See http://www.OpenLDAP.org/its/index.cgi?findid=864 for more
** information.  To work around the bug, the first time a connection fails
** we stop trying for 60 seconds.  After 60 seconds we kill the process,
** and let the parent process restart it.
**
** We'll control this behavior via LDAP_MEMORY_LEAK.  Set it to ZERO to turn
** off this behavior (whenever OpenLDAP gets fixed).
*/

static time_t ldapfailflag=0;

static void ldapconnfailure()
{
    const char *p=getenv("LDAP_MEMORY_LEAK");

    if (!p) p="1";

    if (atoi(p) && !ldapfailflag)
    {
        time(&ldapfailflag);
        ldapfailflag += 60;
    }
}

static int ldapconncheck()
{
    time_t t;

    if (!ldapfailflag)
        return (0);

    time(&t);

    if (t >= ldapfailflag)
        exit(0);
    return (1);
}

static void ldapclose()
{
    if (my_ldap_fp)
    {
        ldap_unbind_ext(my_ldap_fp, NULL, NULL);
        my_ldap_fp=0;
    }
}

static int ldaperror(int rc)
{
#ifdef OPENLDAPV2
    if (rc && !LDAP_NAME_ERROR(rc))
#else
    if (rc && !NAME_ERROR(rc))
#endif
    {
        /* If there was a protocol error, close the connection */
        ldapclose();
        ldapconnfailure();
    }
    return (rc);
}

static LDAP *ldapconnect()
{
    LDAP    *p;

    const char *url_s=ldapaliasd_config("LDAP_URI");

    if (!*url_s)
    {
#if    HAVE_SYSLOG_H
        syslog(LOG_DAEMON|LOG_CRIT,
               "Cannot read LDAP_URI from %s",
               LDAPALIASDCONFIGFILE);
#endif
        return (0);
    }

    if (ldapconncheck())
        return (NULL);

    if (ldap_initialize(&p, url_s) != LDAP_SUCCESS)
    {
#if    HAVE_SYSLOG_H
        syslog(LOG_DAEMON|LOG_CRIT,
            "Cannot connect to %s: %s",
            url_s, strerror(errno));
#endif
        ldapconnfailure();
    }
    return (p);
}

static int ldapopen()
{
    int     ldrc;
    const char *binddn_s=ldapaliasd_config("LDAP_BINDDN");
    const char *bindpw_s=ldapaliasd_config("LDAP_BINDPW");
    struct berval cred;

    basedn=ldapaliasd_config("LDAP_BASEDN");

    if ((timeout_n=atoi(ldapaliasd_config("LDAP_TIMEOUT"))) <= 0)
    {
#if    HAVE_SYSLOG_H
        syslog(LOG_DAEMON|LOG_CRIT,
            "Cannot read LDAP_TIMEOUT from %s",
               LDAPALIASDCONFIGFILE);
#endif
        return (-1);
    }


    my_ldap_fp=ldapconnect();

    if (!my_ldap_fp)
    {
        return (-1);
    }

    if (!*binddn_s)
    {
#if 0
#if    HAVE_SYSLOG_H
        syslog(LOG_DAEMON|LOG_CRIT,
            "Cannot read LDAP_BINDDN from %s",
               LDAPALIASDCONFIGFILE);
#endif
#endif
        return (0);
    }

    cred.bv_len=strlen(bindpw_s ? bindpw_s:"");
    cred.bv_val=bindpw_s ? (char *)bindpw_s:"";


    if (ldaperror(ldrc = ldap_sasl_bind_s(my_ldap_fp, binddn_s, NULL,
                          &cred, NULL, NULL, NULL))
        != LDAP_SUCCESS)
    {
        const char *s=ldap_err2string(ldrc);

#if    HAVE_SYSLOG_H
        syslog(LOG_DAEMON|LOG_CRIT,
               "ldap_simple_bind_s failed: %s", s);
#endif
        ldapclose();
        ldapconnfailure();
        return (-1);
    }
    return (0);
}

static LDAPMessage *search_attr_retry(const char *filter, const char *attr)
{
    char *attrlist[2];
    struct timeval timeout;
    LDAPMessage *result;

    attrlist[0]=(char *)attr;
    attrlist[1]=0;

    timeout.tv_sec=timeout_n;
    timeout.tv_usec=0;

    if (ldaperror(ldap_search_ext_s(my_ldap_fp, (char *)basedn,
                    LDAP_SCOPE_SUBTREE,
                    (char *)filter, attrlist,
                    0,
                    NULL, NULL, &timeout,
                    1000000,
                    &result))
        != LDAP_SUCCESS)
        return (NULL);
    return (result);
}

static LDAPMessage *search_attr(const char *filter, const char *attr)
{
    LDAPMessage *result=search_attr_retry(filter, attr);

    if (result == NULL && my_ldap_fp == NULL && ldapopen() == 0)
        result=search_attr_retry(filter, attr);

    return result;
}

static int search_maildrop2(const char *mail, const char *source, FILE *outfp);

static int search_maildrop(const char *mail, const char *source, FILE *outfp)
{
    int rc;
    char *escaped=courier_auth_ldap_escape(mail);

    if (!escaped)
    {
        syslog(LOG_DAEMON|LOG_CRIT, "malloc failed: %m");
        return(0);
    }

    rc=search_maildrop2(escaped, source, outfp);
    free(escaped);
    return rc;
}

static int search_maildrop2(const char *mail, const char *source, FILE *outfp)
{
    char *filter;
    char *p;
    LDAPMessage *result;
    int rc=1;

    if (my_ldap_fp == 0)
    {
        if (ldapopen())
            return(0);
    }

    filter=malloc(strlen(mail)+(source ? strlen(source):0)+
              (sourcefield ? strlen(sourcefield):0)+
              strlen(mailfield)+80);
    if (!filter)
    {
        syslog(LOG_DAEMON|LOG_CRIT, "malloc failed: %m");
        return (0);
    }

    strcpy(filter, "(&(");
    strcat(filter, mailfield);
    strcat(filter, "=");

    p=filter+strlen(filter);
    while (*mail)
    {
        if (*mail != '\\' && *mail != '(' && *mail != ')')
            *p++=*mail;
        ++mail;
    }
    strcpy(p, ")");

    if (source)
    {
        strcat(filter,"(");
        strcat(filter, sourcefield);
        strcat(filter, "=");
        p=filter+strlen(filter);
        while (*source)
        {
            if (*source != '\\' && *source != '('
                && *source != ')')
                *p++= *source;
            ++source;
        }
        strcpy(p, ")");
    }
    else if (*sourcefield) {
        strcat(filter, "(!(");
        strcat(filter, sourcefield);
        strcat(filter, "=*))");
    }
    strcat(filter, ")");

    result=search_attr(filter, maildropfield);
    free(filter);

    if (!result)
        return (0);    /* Protocol error. */

    if (ldap_count_entries(my_ldap_fp, result) == 1)
    {
        LDAPMessage *entry;
        struct berval **values;

        if ((entry=ldap_first_entry(my_ldap_fp, result)) != NULL &&
            (values=ldap_get_values_len(my_ldap_fp, entry,
                        (char *)
                        maildropfield)) != NULL)
        {
            int n=ldap_count_values_len(values);
            int i;

            for (i=0; i<n; i++)
            {
                int rc;

                fprintf(outfp, "maildrop: ");
                if ((rc=fwrite(values[i]->bv_val,
                           values[i]->bv_len,
                           1, outfp)) < 0)
                    break;
                fprintf(outfp, "\n");
                rc=0;
            }
            ldap_value_free_len(values);
        }
    }
    ldap_msgfree(result);

    if (rc == 0)
        fprintf(outfp, ".\n");
    return (rc);
}

static int search_virtual(const char *mail, const char *source, FILE *outfp)
{
    char *filter;
    char *p;
    LDAPMessage *result;
    int rc=1;
    const char *domain;

    if (*vdomain == 0 || *vuser == 0)
        return (1);

    domain=strrchr(mail, '@');

    if (domain == 0)
        return (1);

    if (my_ldap_fp == 0)
    {
        if (ldapopen())
            return(0);
    }

    filter=malloc(strlen(mail)+(source ? strlen(source):0)+
              (sourcefield ? strlen(sourcefield):0)+
              strlen(vdomain)+80);
    if (!filter)
    {
        syslog(LOG_DAEMON|LOG_CRIT, "malloc failed: %m");
        return (0);
    }

    strcpy(filter, "(&(");
    strcat(filter, vdomain);
    strcat(filter, "=");

    p=filter+strlen(filter);
    ++domain;    /* Skip past '@' */
    while (*domain)
    {
        if (*domain != '\\' && *domain != '(' && *domain != ')')
            *p++=*domain;
        ++domain;
    }
    strcpy(p, ")");

    if (source)
    {
        strcat(filter,"(");
        strcat(filter, sourcefield);
        strcat(filter, "=");
        p=filter+strlen(filter);
        while (*source)
        {
            if (*source != '\\' && *source != '('
                && *source != ')')
                *p++= *source;
            ++source;
        }
        strcpy(p, ")");
    }
    else if (*sourcefield) {
        strcat(filter, "(!(");
        strcat(filter, sourcefield);
        strcat(filter, "=*))");
    }
    strcat(filter, ")");

    result=search_attr(filter, vuser);

    if (!result)
    {
        free(filter);
        return (0);    /* Protocol error. */
    }

    strcpy(filter, mail);
    *strrchr(filter, '@')=0;

    if (ldap_count_entries(my_ldap_fp, result) == 1)
    {
        LDAPMessage *entry;
        struct berval **values;

        if ((entry=ldap_first_entry(my_ldap_fp, result)) != NULL &&
            (values=ldap_get_values_len(my_ldap_fp, entry,
                        (char *)
                        vuser)) != NULL)
        {
            int n=ldap_count_values_len(values);
            int i;

            for (i=0; i<n; i++)
            {
                int rc;

                fprintf(outfp, "maildrop: ");
                if ((rc=fwrite(values[i]->bv_val,
                           values[i]->bv_len,
                           1, outfp)) < 0)
                    break;

                fprintf(outfp, "-%s\n", filter);
                rc=0;
            }
            ldap_value_free_len(values);
        }
    }
    ldap_msgfree(result);
    free(filter);

    if (rc == 0)
        fprintf(outfp, ".\n");
    return (rc);
}

static void search_source(char *source, FILE *outfp)
{
    char *query;

    for (query=source; *query; query++)
    {
        if (isspace((int)(unsigned char)*query))
        {
            *query++=0;
            while (*query && isspace((int)(unsigned char)*query))
                ++query;
            break;
        }
    }

    if (!*query)
        return;

    if (sourcefield && *sourcefield &&
        search_maildrop(query, source, outfp) == 0)
        return;

    if (sourcefield && *sourcefield &&
        search_virtual(query, source, outfp) == 0)
        return;

    if (search_maildrop(query, NULL, outfp) &&
        search_virtual(query, NULL, outfp))
        fprintf(outfp, ".\n");
}

static int mksocket()
{
    int     fd=socket(PF_UNIX, SOCK_STREAM, 0);
    struct  sockaddr_un skun;

        if (fd < 0)     return (-1);
        skun.sun_family=AF_UNIX;
        strcpy(skun.sun_path, SOCKETFILE);
        strcat(skun.sun_path, ".tmp");
        unlink(skun.sun_path);

        if (bind(fd, (const struct sockaddr *)&skun, sizeof(skun)) ||
        listen(fd, SOMAXCONN) ||
        chmod(skun.sun_path, 0770) ||
        rename(skun.sun_path, SOCKETFILE) ||
        fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
        {
                close(fd);
                return (-1);
        }
        return (fd);
}

static int pipe_tochild;
static int pipe_fromchildren;

static void child(int fd)
{
    int afd;

    sourcefield=ldapaliasd_config("LDAP_SOURCE");
    mailfield=ldapaliasd_config("LDAP_MAIL");
    maildropfield=ldapaliasd_config("LDAP_MAILDROP");
    if (!*mailfield)
        mailfield="mail";
    if (!*maildropfield)
        maildropfield="maildrop";

    vdomain=ldapaliasd_config("LDAP_VDOMAIN");
    vuser=ldapaliasd_config("LDAP_VUSER");

    for (;;)
    {
        struct sockaddr saddr;
        socklen_t    saddr_len;
        FILE    *fp;
        char    buf[BUFSIZ];
        char    *p;
        fd_set  fds;
        struct timeval tv;

        FD_ZERO(&fds);
        FD_SET(fd, &fds);
        FD_SET(pipe_tochild, &fds);

        tv.tv_sec=300;
        tv.tv_usec=0;

        if (select((fd > pipe_tochild ? fd:pipe_tochild)+1,
               &fds, 0, 0, &tv) < 0)
        {
                        syslog(LOG_CRIT, "select() failed: %m");
            return;
        }

        if (FD_ISSET(pipe_tochild, &fds))
            return;
        if (!FD_ISSET(fd, &fds))
        {
            ldapclose();
            continue;
        }

                saddr_len=sizeof(saddr);
                if ((afd=accept(fd, &saddr, &saddr_len)) < 0)
                        continue;
                if (fcntl(afd, F_SETFL, 0) < 0)
                {
                        syslog(LOG_CRIT, "fcntl() failed: %m");
            close(afd);
            continue;
        }

        fp=fdopen(afd, "r+");
        if (!fp)
        {
                        syslog(LOG_CRIT, "fdopen() failed: %m");
            close(afd);
            continue;
        }

        if (fgets(buf, sizeof(buf), fp) == NULL)
        {
            fclose(fp);
            continue;
        }
        if ((p=strchr(buf, '\n')) != 0)
            *p=0;
        search_source(buf, fp);
        fclose(fp);
    }
}

static int sigterm_received;
static int sighup_received;
static int sigchild_received;

static RETSIGTYPE sigalarm(int signum)
{
    signal(SIGALRM, sigalarm);
    alarm(2);

#if     RETSIGTYPE != void
        return (0);
#endif
}

static RETSIGTYPE sigterm(int signum)
{
    sigterm_received=1;

#if     RETSIGTYPE != void
        return (0);
#endif
}

static RETSIGTYPE sighup(int signum)
{
    sighup_received=1;

    signal(SIGHUP, sighup);

#if     RETSIGTYPE != void
        return (0);
#endif
}

static RETSIGTYPE sigchild(int signum)
{
    sigchild_received=1;
    alarm(1);

#if     RETSIGTYPE != void
        return (0);
#endif
}

static void loop(int fd)
{
    int afd;

    int pipea[2];
    int pipeb[2];

    if (pipe(pipea) < 0)
    {
        syslog(LOG_CRIT, "pipe() failed: %m");
        sleep(5);
    }

    if (pipe(pipeb) < 0)
    {
        close(pipea[0]);
        close(pipea[1]);
        syslog(LOG_CRIT, "pipe() failed: %m");
        sleep(5);
        return;
    }

    afd=atoi(ldapaliasd_config("LDAP_NUMPROCS"));

    if (afd <= 0)
        afd=5;

    signal(SIGALRM, sigalarm);
    signal(SIGCHLD, sigchild);

    while (afd)
    {
        pid_t p=fork();

        if (p < 0)
        {
            char buf;

            syslog(LOG_CRIT, "pipe() failed: %m");
            close(pipea[0]);
            close(pipea[1]);
            close(pipeb[1]);

            if (read(pipeb[0], &buf, 1) < 0)
                ; /* suppress gcc warning */

            close(pipeb[0]);
            sleep (5);
            return;
        }

        if (p == 0)
        {
            alarm(0);
            signal(SIGCHLD, SIG_DFL);
            signal(SIGTERM, SIG_DFL);
            signal(SIGHUP, SIG_DFL);
            signal(SIGALRM, SIG_DFL);
            pipe_tochild=pipea[0];
            close(pipea[1]);
            pipe_fromchildren=pipeb[1];
            close(pipeb[0]);
            child(fd);
            exit(0);
        }
        --afd;
    }

    sighup_received=0;
    sigterm_received=0;
    sigchild_received=0;
    pipe_tochild=pipea[1];
    close(pipea[0]);
    pipe_fromchildren=pipeb[0];
    close(pipeb[1]);

    signal(SIGTERM, sigterm);
    signal(SIGHUP, sighup);

    while (!sighup_received && !sigterm_received &&
           !sigchild_received)
    {
        sigset_t ss;

        sigemptyset(&ss);
        sigaddset(&ss, SIGUSR1);

        sigsuspend(&ss);
    }

    /* should be sigpause(0), but Solaris is broken */

    alarm(0);
    signal(SIGALRM, SIG_DFL);
    signal(SIGTERM, SIG_DFL);
    signal(SIGHUP, SIG_IGN);

#if 0
#if USE_NOCLDWAIT

    {
        struct sigaction sa;

        memset(&sa, 0, sizeof(sa));
        sa.sa_handler=SIG_IGN;
        sa.sa_flags=SA_NOCLDWAIT;
        sigaction(SIGCHLD, &sa, NULL);
    }
#else
    signal(SIGCHLD, SIG_IGN);
#endif
#else
    signal(SIGCHLD, SIG_DFL);
#endif

    close(pipe_tochild);

    if (sighup_received)
        syslog(LOG_DAEMON|LOG_INFO,
               "Terminating child processes after a SIGHUP");
    if (sigterm_received)
        syslog(LOG_DAEMON|LOG_INFO,
               "Terminating child processes after a SIGTERM");
    if (sigchild_received)
        syslog(LOG_DAEMON|LOG_CRIT,
               "Terminating child processes after a SIGCHILD");
    {
        char c;
        int waitstat;

        if (read(pipe_fromchildren, &c, 1) < 0)
            ; /* suppress gcc warning */

        close(pipe_fromchildren);
        while (wait(&waitstat) >= 0)
            ;
    }
    if (sighup_received)
        syslog(LOG_DAEMON|LOG_INFO,
               "Terminated child processes after a SIGHUP");
    if (sigterm_received)
        syslog(LOG_DAEMON|LOG_INFO,
               "Terminated child processes after a SIGTERM");
    if (sigchild_received)
        syslog(LOG_DAEMON|LOG_CRIT,
               "Terminated child processes after a SIGCHILD");
    if (sigterm_received)
        exit(0);
    ldapaliasd_configchanged();
}

static void start()
{
    int lockfd;
    int sockfd;

    lockfd=ll_daemon_start(LOCKFILE);

    if (lockfd < 0)
    {
        perror("ll_daemon_start");
        exit(1);
    }

    if (atoi(ldapaliasd_config("LDAP_ALIAS")) <= 0)
    {
        ll_daemon_started(PIDFILE, lockfd);
        /* Consider this a good start */
        exit(0);
    }

    if ((sockfd=mksocket()) < 0)
    {
        perror("socket");
        exit(1);
    }

    signal(SIGPIPE, SIG_IGN);
    ll_daemon_started(PIDFILE, lockfd);
    ll_daemon_resetio();


    for (;;)
    {
        if (atoi(ldapaliasd_config("LDAP_ALIAS")) <= 0)
            exit(0);
        loop(sockfd);
    }
}

static void stop()
{
    ll_daemon_stop(LOCKFILE, PIDFILE);
}

static void restart()
{
    ll_daemon_restart(LOCKFILE, PIDFILE);
}

static const char *readline(FILE *fp)
{
    static char buf[BUFSIZ];
    char *p;

    if (fgets(buf, sizeof(buf), fp) == NULL)
    {
        fclose(fp);
        return (NULL);
    }
    if ((p=strchr(buf, '\n')) != 0)
        *p=0;
    return (buf);
}

static void check(const char *source, const char *query)
{
    FILE *fp=ldapaliasd_connect();
    int found=0;
    const char *p;

    if (!fp)
    {
        fprintf(stderr, "connect failed\n");
        exit(1);
    }

    fprintf(fp, "%s %s\n", source, query);
    fflush(fp);

    while ((p=readline(fp)) != NULL)
    {
        if (strcmp(p, ".") == 0)
        {
            if (!found)
            {
                fprintf(stderr, "%s: not found\n", query);
                exit (1);
            }
            exit (0);
        }
        printf("%s\n", p);
        found=1;
    }

    fprintf(stderr, "Error.\n");
    exit (1);
}

int main(int argc, char **argv)
{
    if (chdir(COURIER_HOME) < 0)
    {
        perror(COURIER_HOME);
        exit(1);
    }

    libmail_changeuidgid(MAILUID, MAILGID);
    
#if HAVE_SYSLOG_H
    openlog("courierldapaliasd", LOG_PID, LOG_MAIL);
#endif

    if (argc > 1)
    {
        if (strcmp(argv[1], "start") == 0)
        {
            start();
            return (0);
        }

        if (strcmp(argv[1], "stop") == 0)
        {
            stop();
            return (0);
        }

        if (strcmp(argv[1], "restart") == 0)
        {
            restart();
            return (0);
        }

        if (strcmp(argv[1], "query") == 0 && argc > 3)
        {
            check(argv[2], argv[3]);
            return (0);
        }
    }

    fprintf(stderr, "Usage: %s [start|stop|restart]\n", argv[0]);
    return (1);
}
Command:
Quick Commands:
Upload:
[OK] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [OK]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.1921 seconds