示例#1
0
文件: hpux9.c 项目: rra/lbcd
/*
 * Read a value from kernel memory, given its offset, and store it in the dest
 * buffer.  That buffer has space for dest_len octets.
 */
static void
kernel_read(off_t where, void *dest, int dest_len)
{
    ssize_t status;

    if (lseek(kernel_fd, where, SEEK_SET) < 0)
        sysdie("cannot lseek in %s", C_KMEM);
    status = read(kernel_fd, dest, dest_len);
    if (status < 0)
        sysdie("kernel read of %s failed", C_KMEM);
}
示例#2
0
文件: hpux9.c 项目: rra/lbcd
/*
 * Sets up for later queries.  Open the kernel memory file and find the
 * address of the necessary variable.  Exits on error.
 */
static int
kernel_open(void)
{
    kernel_fd = open(C_KMEM, O_RDONLY);
    if (kernel_fd < 0)
        sysdie("cannot open %s", C_KMEM);
    if (nlist(C_VMUNIX, nl) < 0)
        sysdie("no namelist for %s", C_VMUNIX);
    kernel_init = 1;
    return 0;
}
示例#3
0
文件: irix.c 项目: rra/lbcd
/*
 * Sets up for later queries.  Open the kernel memory file and find the
 * address of the necessary variable.  Exits on error.
 */
static int
kernel_open(void)
{
    int ldav_off;

    kmem_fd = open("/dev/kmem", O_RDONLY);
    if (kmem_fd < 0)
        sysdie("cannot open /dev/kmem");
    ldav_off = sysmp(MP_KERNADDR, MPKA_AVENRUN);
    if (ldav_off < 0)
        sysdie("sysmp failed");
    kernel_offset = (long) ldav_off & 0x7fffffff;
    kernel_init = 1;
}
示例#4
0
文件: irix.c 项目: rra/lbcd
/*
 * Get the current load average from the kernel and return the one minute,
 * five minute, and fifteen minute averages in the given parameters.  Returns
 * 0 on success and -1 on failure.
 */
int
kernel_getload(double *load1, double *load5, double *load15)
{
    int status, load[3];
    static long offset = -1;

    if (!kernel_init)
        kernel_open();
    if (lseek(kmem_fd, offset, 0) < 0)
        sysdie("cannot lseek in /dev/kmem");
    status = read(kmem_fd, (void *) load, sizeof(load));
    if (status != sizeof(load))
        sysdie("kernel read failed");
    *load1  = (double) load[0] / 1000.0;
    *load5  = (double) load[1] / 1000.0;
    *load15 = (double) load[2] / 1000.0;
    return 0;
}
示例#5
0
文件: keytab.c 项目: Stanford/wallet
/*
 * Given a remctl object, the Kerberos context, the type for the wallet
 * interface, and a file name of a keytab, iterate through every existing
 * principal in the keytab in the local realm, get fresh keys for those
 * principals, and save the old and new keys to that file.  Returns true on
 * success and false on partial failure to retrieve all the keys.
 */
bool
rekey_keytab(struct remctl *r, krb5_context ctx, const char *type,
             const char *file)
{
    char *realm = NULL;
    char *data = NULL;
    char *tempfile;
    size_t length = 0;
    int status;
    bool error = false, rekeyed = false;
    struct principal_name *names, *current;

    xasprintf(&tempfile, "%s.new", file);
    krb5_get_default_realm(ctx, &realm);
    names = keytab_principals(ctx, file, realm);
    for (current = names; current != NULL; current = current->next) {
        status = download_keytab(r, type, current->princ, &data, &length);
        if (status != 0) {
            warn("error rekeying for principal %s", current->princ);
            error = true;
            continue;
        }
        write_file(tempfile, data, length);
        rekeyed = true;

        /*
         * Now merge the original keytab file with the one containing the new
         * keys from the rekeying of this principal.
         */
        if (access(file, F_OK) != 0) {
            if (link(tempfile, file) < 0)
                sysdie("rename of temporary keytab %s to %s failed", tempfile,
                       file);
        } else {
            merge_keytab(ctx, tempfile, file);
            if (unlink(tempfile) < 0)
                syswarn("unlink of temporary keytab file %s failed",
                        tempfile);
        }
    }

    /* If no new keytab data, then leave the keytab as-is. */
    if (!rekeyed)
        die("no rekeyable principals found");

    free(tempfile);
    return !error;
}
示例#6
0
文件: keytab.c 项目: Stanford/wallet
/*
 * Given a remctl object, the Kerberos context, the name of a keytab object,
 * and a file name, call the correct wallet commands to download a keytab and
 * write it to that file.  Returns the status or 255 on an internal error.
 */
int
get_keytab(struct remctl *r, krb5_context ctx, const char *type,
           const char *name, const char *file, const char *srvtab)
{
    const char *command[5];
    char *tempfile;
    char *data = NULL;
    size_t length = 0;
    int status;

    command[0] = type;
    command[1] = "get";
    command[2] = "keytab";
    command[3] = name;
    command[4] = NULL;
    status = run_command(r, command, &data, &length);
    if (status != 0)
        return status;
    if (data == NULL) {
        warn("no data returned by wallet server");
        return 255;
    }
    if (access(file, F_OK) == 0) {
        xasprintf(&tempfile, "%s.new", file);
        overwrite_file(tempfile, data, length);
        if (srvtab != NULL)
            write_srvtab(ctx, srvtab, name, tempfile);
        merge_keytab(ctx, tempfile, file);
        if (unlink(tempfile) < 0)
            sysdie("unlink of temporary keytab file %s failed", tempfile);
        free(tempfile);
    } else {
        write_file(file, data, length);
        if (srvtab != NULL)
            write_srvtab(ctx, srvtab, name, file);
    }
    return 0;
}
示例#7
0
/*
 * Take the amount of memory to allocate in bytes as a command-line argument
 * and call test_malloc with that amount of memory.
 */
int
main(int argc, char *argv[])
{
    size_t size, max;
    size_t limit = 0;
    int willfail = 0;
    unsigned char code;

    if (argc < 3)
        die("Usage error.  Type, size, and limit must be given.");
    errno = 0;
    size = strtol(argv[2], 0, 10);
    if (size == 0 && errno != 0)
        sysdie("Invalid size");
    errno = 0;
    limit = strtol(argv[3], 0, 10);
    if (limit == 0 && errno != 0)
        sysdie("Invalid limit");

    /* If the code is capitalized, install our customized error handler. */
    code = argv[1][0];
    if (isupper(code)) {
        xmalloc_error_handler = test_handler;
        code = tolower(code);
    }

    /*
     * Decide if the allocation should fail.  If it should, set willfail to 2,
     * so that if it unexpectedly succeeds, we exit with a status indicating
     * that the test should be skipped.
     */
    max = size;
    if (code == 's' || code == 'n' || code == 'a' || code == 'v') {
        max += size;
        if (limit > 0)
            limit += size;
    }
    if (limit > 0 && max > limit)
        willfail = 2;

    /*
     * If a memory limit was given and we can set memory limits, set it.
     * Otherwise, exit 2, signalling to the driver that the test should be
     * skipped.  We do this here rather than in the driver due to some
     * pathological problems with Linux (setting ulimit in the shell caused
     * the shell to die).
     */
    if (limit > 0) {
#if HAVE_SETRLIMIT && defined(RLIMIT_AS)
        struct rlimit rl;
        void *tmp;
        size_t test_size;

        rl.rlim_cur = limit;
        rl.rlim_max = limit;
        if (setrlimit(RLIMIT_AS, &rl) < 0) {
            syswarn("Can't set data limit to %lu", (unsigned long) limit);
            exit(2);
        }
        if (size < limit || code == 'r') {
            test_size = code == 'r' ? 10 : size;
            if (test_size == 0)
                test_size = 1;
            tmp = malloc(test_size);
            if (tmp == NULL) {
                syswarn("Can't allocate initial memory of %lu (limit %lu)",
                        (unsigned long) test_size, (unsigned long) limit);
                exit(2);
            }
            free(tmp);
        }
#else
        warn("Data limits aren't supported.");
        exit(2);
#endif
    }

    switch (code) {
    case 'c': exit(test_calloc(size) ? willfail : 1);
    case 'm': exit(test_malloc(size) ? willfail : 1);
    case 'r': exit(test_realloc(size) ? willfail : 1);
    case 's': exit(test_strdup(size) ? willfail : 1);
    case 'n': exit(test_strndup(size) ? willfail : 1);
    case 'a': exit(test_asprintf(size) ? willfail : 1);
    case 'v': exit(test_vasprintf(size) ? willfail : 1);
    default:
        die("Unknown mode %c", argv[1][0]);
        break;
    }
    exit(1);
}
示例#8
0
/*
 * Main routine.  Parse the arguments, open the remctl connection, send the
 * command, and then call process_response.
 */
int
main(int argc, char *argv[])
{
    int option, status;
    char *server_host;
    struct addrinfo hints, *ai;
    const char *source = NULL;
    const char *service_name = NULL;
    unsigned short port = 0;
    struct remctl *r;
    int errorcode = 0;

    /* Set up logging and identity. */
    message_program_name = "remctl";
    if (!socket_init())
        die("failed to initialize socket library");

    /*
     * Parse options.  The + tells GNU getopt to stop option parsing at the
     * first non-argument rather than proceeding on to find options anywhere.
     * Without this, it's hard to call remote programs that take options.
     * Non-GNU getopt will treat the + as a supported option, which is handled
     * below.
     */
    while ((option = getopt(argc, argv, "+b:dhp:s:v")) != EOF) {
        switch (option) {
        case 'b':
            source = optarg;
            break;
        case 'd':
            message_handlers_debug(1, message_log_stderr);
            break;
        case 'h':
            usage(0);
            break;
        case 'p':
            port = atoi(optarg);
            break;
        case 's':
            service_name = optarg;
            break;
        case 'v':
            printf("%s\n", PACKAGE_STRING);
            exit(0);
            break;
        case '+':
            fprintf(stderr, "%s: invalid option -- +\n", argv[0]);
        default:
            usage(1);
            break;
        }
    }
    argc -= optind;
    argv += optind;
    if (argc < 2)
        usage(1);
    server_host = *argv++;
    argc--;

    /*
     * If service_name isn't set, the remctl library uses host/<server>
     * (host@<server> in GSS-API parlance).  However, if the server to which
     * we're connecting is a DNS-load-balanced name, we have to be careful
     * what principal name we use.
     *
     * Ideally, we would let the GSS-API library handle this and choose
     * whether to canonicalize the <server> in the principal name based on the
     * krb5.conf rdns setting and similar configuration.  However, with DNS
     * load balancing, this still may fail.  At the time of network
     * connection, we will connect to whatever the name resolves to then.
     * After we connect, we authenticate, and the GSS-API library will then
     * separately canonicalize the hostname.  It could get a different answer
     * than we got for our network connection, leading to an authentication
     * failure.
     *
     * Therefore, if the principal isn't specified, we canonicalize the
     * hostname to which we're connecting before we connect.  Then, the
     * additional canonicalization possibly done by the GSS-API library should
     * return the same results and be consistent.
     *
     * Note that this opens the possibility of a subtle attack through DNS
     * spoofing, since both the principal used and the host to which we're
     * connecting can be changed by varying the DNS response.
     *
     * If the principal is specified explicitly, assume the user knows what
     * they're doing and don't do any of this.
     */
    if (service_name == NULL) {
        memset(&hints, 0, sizeof(hints));
        hints.ai_flags = AI_CANONNAME;
        status = getaddrinfo(server_host, NULL, &hints, &ai);
        if (status != 0)
            die("cannot resolve host %s: %s", server_host,
                gai_strerror(status));
        server_host = xstrdup(ai->ai_canonname);
        freeaddrinfo(ai);
    }

    /* Open connection. */
    r = remctl_new();
    if (r == NULL)
        sysdie("cannot initialize remctl connection");
    if (source != NULL)
        if (!remctl_set_source_ip(r, source))
            die("%s", remctl_error(r));
    if (!remctl_open(r, server_host, port, service_name))
        die("%s", remctl_error(r));

    /* Do the work. */
    if (!remctl_command(r, (const char **) argv))
        die("%s", remctl_error(r));
    if (!process_response(r, &errorcode))
        die("%s", remctl_error(r));

    /* Shut down cleanly. */
    remctl_close(r);
    socket_shutdown();
    return errorcode;
}