Exemple #1
0
void
sudo_debug_printf2(const char *func, const char *file, int lineno, int level,
    const char *fmt, ...)
{
    int buflen, pri, subsys, saved_errno = errno;
    va_list ap;
    char *buf;

    if (!sudo_debug_mode)
	return;

    /* Extract pri and subsystem from level. */
    pri = SUDO_DEBUG_PRI(level);
    subsys = SUDO_DEBUG_SUBSYS(level);

    /* Make sure we want debug info at this level. */
    if (subsys < NUM_SUBSYSTEMS && sudo_debug_settings[subsys] >= pri) {
	va_start(ap, fmt);
	buflen = vasprintf(&buf, fmt, ap);
	va_end(ap);
	if (buflen != -1) {
	    int errcode = ISSET(level, SUDO_DEBUG_ERRNO) ? saved_errno : 0;
	    if (ISSET(level, SUDO_DEBUG_LINENO))
		sudo_debug_write2(func, file, lineno, buf, buflen, errcode);
	    else
		sudo_debug_write2(NULL, NULL, 0, buf, buflen, errcode);
	    free(buf);
	}
    }

    errno = saved_errno;
}
Exemple #2
0
/*
 * Create a new output file for the specified debug instance.
 * Returns NULL if the file cannot be opened or memory cannot be allocated.
 */
static struct sudo_debug_output *
sudo_debug_new_output(struct sudo_debug_instance *instance,
    struct sudo_debug_file *debug_file)
{
    char *buf, *cp, *last, *subsys, *pri;
    struct sudo_debug_output *output;
    unsigned int j;
    int i;

    /* Create new output for the instance. */
    /* XXX - reuse fd for existing filename? */
    output = calloc(1, sizeof(*output));
    if (output == NULL)
	goto bad;
    output->fd = -1;
    output->settings = reallocarray(NULL, instance->max_subsystem + 1,
	sizeof(int));
    if (output->settings == NULL)
	goto bad;
    output->filename = strdup(debug_file->debug_file);
    if (output->filename == NULL)
	goto bad;
    output->fd = -1;

    /* Init per-subsystems settings to -1 since 0 is a valid priority. */
    for (j = 0; j <= instance->max_subsystem; j++)
	output->settings[j] = -1;

    /* Open debug file. */
    output->fd = open(output->filename, O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR);
    if (output->fd == -1) {
	/* Create debug file as needed and set group ownership. */
	if (errno == ENOENT) {
	    output->fd = open(output->filename, O_WRONLY|O_APPEND|O_CREAT,
		S_IRUSR|S_IWUSR);
	}
	if (output->fd == -1)
	    goto bad;
	ignore_result(fchown(output->fd, (uid_t)-1, 0));
    }
    (void)fcntl(output->fd, F_SETFD, FD_CLOEXEC);
    if (sudo_debug_fds_size < output->fd) {
	/* Bump fds size to the next multiple of 4 * NBBY. */
	const int old_size = sudo_debug_fds_size / NBBY;
	const int new_size = round_nfds(output->fd + 1) / NBBY;
	unsigned char *new_fds;

	new_fds = realloc(sudo_debug_fds, new_size);
	if (new_fds == NULL)
	    goto bad;
	memset(new_fds + old_size, 0, new_size - old_size);
	sudo_debug_fds = new_fds;
	sudo_debug_fds_size = new_size * NBBY;
    }
    sudo_setbit(sudo_debug_fds, output->fd);
    if (output->fd > sudo_debug_max_fd)
	sudo_debug_max_fd = output->fd;

    /* Parse Debug conf string. */
    buf = strdup(debug_file->debug_flags);
    if (buf == NULL)
	goto bad;
    for ((cp = strtok_r(buf, ",", &last)); cp != NULL; (cp = strtok_r(NULL, ",", &last))) {
	/* Should be in the form subsys@pri. */
	subsys = cp;
	if ((pri = strchr(cp, '@')) == NULL)
	    continue;
	*pri++ = '\0';

	/* Look up priority and subsystem, fill in sudo_debug_settings[]. */
	for (i = 0; sudo_debug_priorities[i] != NULL; i++) {
	    if (strcasecmp(pri, sudo_debug_priorities[i]) == 0) {
		for (j = 0; instance->subsystems[j] != NULL; j++) {
		    if (strcasecmp(subsys, "all") == 0) {
			const unsigned int idx = instance->subsystem_ids ?
			    SUDO_DEBUG_SUBSYS(instance->subsystem_ids[j]) : j;
			if (i > output->settings[idx])
			    output->settings[idx] = i;
			continue;
		    }
		    if (strcasecmp(subsys, instance->subsystems[j]) == 0) {
			const unsigned int idx = instance->subsystem_ids ?
			    SUDO_DEBUG_SUBSYS(instance->subsystem_ids[j]) : j;
			if (i > output->settings[idx])
			    output->settings[idx] = i;
			break;
		    }
		}
		break;
	    }
	}
    }
    free(buf);

    return output;
bad:
    sudo_warn_nodebug(NULL);
    if (output != NULL)
	sudo_debug_free_output(output);
    return NULL;
}
Exemple #3
0
void
sudo_debug_execve2(int level, const char *path, char *const argv[], char *const envp[])
{
    char * const *av;
    char *buf, *cp;
    int buflen, pri, subsys, log_envp = 0;
    size_t plen;

    if (!sudo_debug_mode)
	return;

    /* Extract pri and subsystem from level. */
    pri = SUDO_DEBUG_PRI(level);
    subsys = SUDO_DEBUG_SUBSYS(level);

    /* Make sure we want debug info at this level. */
    if (subsys >= NUM_SUBSYSTEMS || sudo_debug_settings[subsys] < pri)
	return;

    /* Log envp for debug level "debug". */
    if (sudo_debug_settings[subsys] >= SUDO_DEBUG_DEBUG - 1 && envp[0] != NULL)
	log_envp = 1;

#define EXEC_PREFIX "exec "

    /* Alloc and build up buffer. */
    plen = strlen(path);
    buflen = sizeof(EXEC_PREFIX) -1 + plen;
    if (argv[0] != NULL) {
	buflen += sizeof(" []") - 1;
	for (av = argv; *av; av++)
	    buflen += strlen(*av) + 1;
	buflen--;
    }
    if (log_envp) {
	buflen += sizeof(" []") - 1;
	for (av = envp; *av; av++)
	    buflen += strlen(*av) + 1;
	buflen--;
    }
    buf = malloc(buflen + 1);
    if (buf == NULL)
	return;

    /* Copy prefix and command. */
    memcpy(buf, EXEC_PREFIX, sizeof(EXEC_PREFIX) - 1);
    cp = buf + sizeof(EXEC_PREFIX) - 1;
    memcpy(cp, path, plen);
    cp += plen;

    /* Copy argv. */
    if (argv[0] != NULL) {
	*cp++ = ' ';
	*cp++ = '[';
	for (av = argv; *av; av++) {
	    size_t avlen = strlen(*av);
	    memcpy(cp, *av, avlen);
	    cp += avlen;
	    *cp++ = ' ';
	}
	cp[-1] = ']';
    }

    if (log_envp) {
	*cp++ = ' ';
	*cp++ = '[';
	for (av = envp; *av; av++) {
	    size_t avlen = strlen(*av);
	    memcpy(cp, *av, avlen);
	    cp += avlen;
	    *cp++ = ' ';
	}
	cp[-1] = ']';
    }

    *cp = '\0';

    sudo_debug_write(buf, buflen, 0);
    free(buf);
}