Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 138 lines (109 sloc) 3.526 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
/* author: klacke@hyber.org */
/* purpose, make us run under a different username */
/* as well as iface to some other idiotic syscalls */
/* FIXME replace this entirely with a proper */
/* posix interface */


#ifndef WIN32
#include <unistd.h>
#endif


#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>
#include <stdlib.h>

#include "erl_driver.h"



static ErlDrvData setuid_start(ErlDrvPort port, char *buf);
static void setuid_stop(ErlDrvData drv_data);

static ErlDrvEntry setuid_driver_entry;


/* buf is the name of the intented user */
static ErlDrvData setuid_start(ErlDrvPort port, char *buf)
{
    char *t;
    char xbuf[BUFSIZ];
    struct passwd *pe;

    if ((t = strchr(buf, ' ')) == NULL)
        return (ErlDrvData) -1;

    /* Rewind pw mapping */
    setpwent();

    t++;
    switch (*t++) {
    case 's': /* setuid */
        while ((pe = getpwent())) {
            if (strcmp(pe->pw_name , t) == 0) {
                if ((setuid(pe->pw_uid) != 0) ||
                    (setreuid(pe->pw_uid, pe->pw_uid) != 0)) {
                    return (ErlDrvData) -1;
                }
                sprintf(xbuf, "ok %d", pe->pw_uid);
                endpwent();
                driver_output(port,xbuf, strlen(xbuf));
                return (ErlDrvData) port;
            }
        }
        endpwent();
        break;
    case 'n': {
        int uid = atoi(t);
        while ((pe = getpwent())) {
            if (pe->pw_uid == uid) {
                sprintf(xbuf, "ok %s", pe->pw_name);
                endpwent();
                driver_output(port,xbuf, strlen(xbuf));
                return (ErlDrvData) port;
            }
        }
        endpwent();
        driver_output(port, "ok -", 4);
        return (ErlDrvData) port;
    }
    case 'g': /* getuid */
        sprintf(xbuf, "ok %d", getuid());
        driver_output(port,xbuf, strlen(xbuf));
        return (ErlDrvData) port;
    case 'u':
        while ((pe = getpwent())) {
            if (strcmp(pe->pw_name , t) == 0) {
                sprintf(xbuf, "ok %d", pe->pw_uid);
                endpwent();
                driver_output(port,xbuf, strlen(xbuf));
                return (ErlDrvData) port;
            }
        }
        endpwent();
        break;
    case 'h':
        while ((pe = getpwent())) {
            if (strcmp(pe->pw_name , t) == 0) {
                sprintf(xbuf, "ok %s", pe->pw_dir);
                endpwent();
                driver_output(port,xbuf, strlen(xbuf));
                return (ErlDrvData) port;
            }
        }
        endpwent();
        break;
    }
    // In any case return error(?) for non void function
    return (ErlDrvData) -1;
    
        
}


static void setuid_stop(ErlDrvData drv_data)
{
}




/*
* Initialize and return a driver entry struct
*/




DRIVER_INIT(setuid_drv)
{
    setuid_driver_entry.init = NULL; /* Not used */
    setuid_driver_entry.start = setuid_start;
    setuid_driver_entry.stop = setuid_stop;
    setuid_driver_entry.output = NULL;
    setuid_driver_entry.ready_input = NULL;
    setuid_driver_entry.ready_output = NULL;
    setuid_driver_entry.driver_name = "setuid_drv";
    setuid_driver_entry.finish = NULL;
    setuid_driver_entry.control = NULL;
    setuid_driver_entry.outputv = NULL;
    return (ErlDrvEntry*) &setuid_driver_entry;
}


Something went wrong with that request. Please try again.