Annotation of embedaddon/sudo/common/sudo_debug.c, revision 1.1.1.5

1.1       misho       1: /*
1.1.1.3   misho       2:  * Copyright (c) 2011-2013 Todd C. Miller <Todd.Miller@courtesan.com>
1.1       misho       3:  *
                      4:  * Permission to use, copy, modify, and distribute this software for any
                      5:  * purpose with or without fee is hereby granted, provided that the above
                      6:  * copyright notice and this permission notice appear in all copies.
                      7:  *
                      8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                      9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     15:  */
                     16: 
                     17: #include <config.h>
                     18: 
                     19: #include <sys/types.h>
                     20: #include <sys/stat.h>
                     21: #include <sys/uio.h>
                     22: #include <stdio.h>
                     23: #ifdef STDC_HEADERS
                     24: # include <stdlib.h>
                     25: # include <stddef.h>
                     26: #else
                     27: # ifdef HAVE_STDLIB_H
                     28: #  include <stdlib.h>
                     29: # endif
                     30: #endif /* STDC_HEADERS */
                     31: #ifdef HAVE_STDBOOL_H
                     32: # include <stdbool.h>
                     33: #else
                     34: # include "compat/stdbool.h"
                     35: #endif
                     36: #ifdef HAVE_STRING_H
                     37: # include <string.h>
                     38: #endif /* HAVE_STRING_H */
                     39: #ifdef HAVE_STRINGS_H
                     40: # include <strings.h>
                     41: #endif /* HAVE_STRINGS_H */
                     42: #ifdef HAVE_UNISTD_H
                     43: # include <unistd.h>
                     44: #endif /* HAVE_UNISTD_H */
                     45: #include <ctype.h>
                     46: #include <errno.h>
                     47: #include <fcntl.h>
                     48: #include <time.h>
                     49: 
1.1.1.5 ! misho      50: #define DEFAULT_TEXT_DOMAIN    "sudo"
        !            51: #include "gettext.h"           /* must be included before missing.h */
        !            52: 
1.1       misho      53: #include "missing.h"
                     54: #include "alloc.h"
1.1.1.4   misho      55: #include "fatal.h"
1.1       misho      56: #include "sudo_plugin.h"
                     57: #include "sudo_debug.h"
1.1.1.5 ! misho      58: #include "sudo_util.h"
1.1.1.3   misho      59: 
1.1       misho      60: /*
                     61:  * The debug priorities and subsystems are currently hard-coded.
                     62:  * In the future we might consider allowing plugins to register their
                     63:  * own subsystems and provide direct access to the debugging API.
                     64:  */
                     65: 
                     66: /* Note: this must match the order in sudo_debug.h */
                     67: const char *const sudo_debug_priorities[] = {
                     68:     "crit",
                     69:     "err",
                     70:     "warn",
                     71:     "notice",
                     72:     "diag",
                     73:     "info",
                     74:     "trace",
                     75:     "debug",
                     76:     NULL
                     77: };
                     78: 
                     79: /* Note: this must match the order in sudo_debug.h */
                     80: const char *const sudo_debug_subsystems[] = {
                     81:     "main",
                     82:     "args",
                     83:     "exec",
                     84:     "pty",
                     85:     "utmp",
                     86:     "conv",
                     87:     "pcomm",
                     88:     "util",
                     89:     "netif",
                     90:     "audit",
                     91:     "edit",
                     92:     "selinux",
                     93:     "ldap",
                     94:     "match",
                     95:     "parser",
                     96:     "alias",
                     97:     "defaults",
                     98:     "auth",
                     99:     "env",
                    100:     "logging",
                    101:     "nss",
                    102:     "rbtree",
                    103:     "perms",
                    104:     "plugin",
                    105:     "hooks",
1.1.1.2   misho     106:     "sssd",
1.1.1.5 ! misho     107:     "event",
1.1       misho     108:     NULL
                    109: };
                    110: 
                    111: #define NUM_SUBSYSTEMS (sizeof(sudo_debug_subsystems) / sizeof(sudo_debug_subsystems[0]) - 1)
                    112: 
                    113: /* Values for sudo_debug_mode */
                    114: #define SUDO_DEBUG_MODE_DISABLED       0
                    115: #define SUDO_DEBUG_MODE_FILE           1
                    116: #define SUDO_DEBUG_MODE_CONV           2
                    117: 
                    118: static int sudo_debug_settings[NUM_SUBSYSTEMS];
                    119: static int sudo_debug_fd = -1;
                    120: static int sudo_debug_mode;
                    121: static char sudo_debug_pidstr[(((sizeof(int) * 8) + 2) / 3) + 3];
                    122: static size_t sudo_debug_pidlen;
1.1.1.5 ! misho     123: static const int num_subsystems = NUM_SUBSYSTEMS;
1.1       misho     124: 
                    125: /*
                    126:  * Parse settings string from sudo.conf and open debugfile.
                    127:  * Returns 1 on success, 0 if cannot open debugfile.
                    128:  * Unsupported subsystems and priorities are silently ignored.
                    129:  */
                    130: int sudo_debug_init(const char *debugfile, const char *settings)
                    131: {
                    132:     char *buf, *cp, *subsys, *pri;
                    133:     int i, j;
                    134: 
1.1.1.5 ! misho     135:     /* Make sure we are not already initialized. */
        !           136:     if (sudo_debug_mode != SUDO_DEBUG_MODE_DISABLED)
        !           137:        return 1;
        !           138: 
1.1       misho     139:     /* Init per-subsystems settings to -1 since 0 is a valid priority. */
1.1.1.5 ! misho     140:     for (i = 0; i < num_subsystems; i++)
1.1       misho     141:        sudo_debug_settings[i] = -1;
                    142: 
                    143:     /* Open debug file if specified. */
                    144:     if (debugfile != NULL) {
                    145:        if (sudo_debug_fd != -1)
                    146:            close(sudo_debug_fd);
1.1.1.3   misho     147:        sudo_debug_fd = open(debugfile, O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR);
                    148:        if (sudo_debug_fd == -1) {
                    149:            /* Create debug file as needed and set group ownership. */
                    150:            if (errno == ENOENT) {
                    151:                sudo_debug_fd = open(debugfile, O_WRONLY|O_APPEND|O_CREAT,
                    152:                    S_IRUSR|S_IWUSR);
                    153:            }
                    154:            if (sudo_debug_fd == -1)
                    155:                return 0;
                    156:            ignore_result(fchown(sudo_debug_fd, (uid_t)-1, 0));
                    157:        }
1.1       misho     158:        (void)fcntl(sudo_debug_fd, F_SETFD, FD_CLOEXEC);
                    159:        sudo_debug_mode = SUDO_DEBUG_MODE_FILE;
                    160:     } else {
                    161:        /* Called from the plugin, no debug file. */
                    162:        sudo_debug_mode = SUDO_DEBUG_MODE_CONV;
                    163:     }
                    164: 
1.1.1.4   misho     165:     /* Stash the pid string so we only have to format it once. */
                    166:     (void)snprintf(sudo_debug_pidstr, sizeof(sudo_debug_pidstr), "[%d] ",
                    167:        (int)getpid());
                    168:     sudo_debug_pidlen = strlen(sudo_debug_pidstr);
                    169: 
1.1       misho     170:     /* Parse settings string. */
1.1.1.4   misho     171:     if ((buf = strdup(settings)) == NULL)
                    172:        return 0;
1.1       misho     173:     for ((cp = strtok(buf, ",")); cp != NULL; (cp = strtok(NULL, ","))) {
                    174:        /* Should be in the form subsys@pri. */
                    175:        subsys = cp;
                    176:        if ((pri = strchr(cp, '@')) == NULL)
                    177:            continue;
                    178:        *pri++ = '\0';
                    179: 
                    180:        /* Look up priority and subsystem, fill in sudo_debug_settings[]. */
                    181:        for (i = 0; sudo_debug_priorities[i] != NULL; i++) {
                    182:            if (strcasecmp(pri, sudo_debug_priorities[i]) == 0) {
                    183:                for (j = 0; sudo_debug_subsystems[j] != NULL; j++) {
                    184:                    if (strcasecmp(subsys, "all") == 0) {
                    185:                        sudo_debug_settings[j] = i;
                    186:                        continue;
                    187:                    }
                    188:                    if (strcasecmp(subsys, sudo_debug_subsystems[j]) == 0) {
                    189:                        sudo_debug_settings[j] = i;
                    190:                        break;
                    191:                    }
                    192:                }
                    193:                break;
                    194:            }
                    195:        }
                    196:     }
1.1.1.4   misho     197:     free(buf);
1.1       misho     198: 
                    199:     return 1;
                    200: }
                    201: 
                    202: pid_t
                    203: sudo_debug_fork(void)
                    204: {
                    205:     pid_t pid;
                    206: 
                    207:     if ((pid = fork()) == 0) {
                    208:        (void)snprintf(sudo_debug_pidstr, sizeof(sudo_debug_pidstr), "[%d] ",
                    209:            (int)getpid());
                    210:        sudo_debug_pidlen = strlen(sudo_debug_pidstr);
                    211:     }
                    212: 
                    213:     return pid;
                    214: }
                    215: 
                    216: void
                    217: sudo_debug_enter(const char *func, const char *file, int line,
                    218:     int subsys)
                    219: {
                    220:     sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
                    221:        "-> %s @ %s:%d", func, file, line);
                    222: }
                    223: 
1.1.1.4   misho     224: void
                    225: sudo_debug_exit(const char *func, const char *file, int line,
1.1       misho     226:     int subsys)
                    227: {
                    228:     sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
                    229:        "<- %s @ %s:%d", func, file, line);
                    230: }
                    231: 
1.1.1.4   misho     232: void
                    233: sudo_debug_exit_int(const char *func, const char *file, int line,
1.1       misho     234:     int subsys, int rval)
                    235: {
                    236:     sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
                    237:        "<- %s @ %s:%d := %d", func, file, line, rval);
                    238: }
                    239: 
1.1.1.4   misho     240: void
                    241: sudo_debug_exit_long(const char *func, const char *file, int line,
1.1       misho     242:     int subsys, long rval)
                    243: {
                    244:     sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
                    245:        "<- %s @ %s:%d := %ld", func, file, line, rval);
                    246: }
                    247: 
1.1.1.4   misho     248: void
                    249: sudo_debug_exit_size_t(const char *func, const char *file, int line,
1.1       misho     250:     int subsys, size_t rval)
                    251: {
                    252:     /* XXX - should use %zu but our snprintf.c doesn't support it */
                    253:     sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
                    254:        "<- %s @ %s:%d := %lu", func, file, line, (unsigned long)rval);
                    255: }
                    256: 
                    257: /* We use int, not bool, here for functions that return -1 on error. */
1.1.1.4   misho     258: void
                    259: sudo_debug_exit_bool(const char *func, const char *file, int line,
1.1       misho     260:     int subsys, int rval)
                    261: {
                    262:     if (rval == true || rval == false) {
                    263:        sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
                    264:            "<- %s @ %s:%d := %s", func, file, line, rval ? "true" : "false");
                    265:     } else {
                    266:        sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
                    267:            "<- %s @ %s:%d := %d", func, file, line, rval);
                    268:     }
                    269: }
                    270: 
1.1.1.4   misho     271: void
                    272: sudo_debug_exit_str(const char *func, const char *file, int line,
1.1       misho     273:     int subsys, const char *rval)
                    274: {
                    275:     sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
                    276:        "<- %s @ %s:%d := %s", func, file, line, rval ? rval : "(null)");
                    277: }
                    278: 
1.1.1.4   misho     279: void
                    280: sudo_debug_exit_str_masked(const char *func, const char *file, int line,
1.1       misho     281:     int subsys, const char *rval)
                    282: {
                    283:     static const char stars[] = "********************************************************************************";
                    284:     int len = rval ? strlen(rval) : sizeof("(null)") - 1;
                    285: 
                    286:     sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
                    287:        "<- %s @ %s:%d := %.*s", func, file, line, len, rval ? stars : "(null)");
                    288: }
                    289: 
1.1.1.4   misho     290: void
                    291: sudo_debug_exit_ptr(const char *func, const char *file, int line,
1.1       misho     292:     int subsys, const void *rval)
                    293: {
                    294:     sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
                    295:        "<- %s @ %s:%d := %p", func, file, line, rval);
                    296: }
                    297: 
                    298: static void
                    299: sudo_debug_write_conv(const char *func, const char *file, int lineno,
                    300:     const char *str, int len, int errno_val)
                    301: {
1.1.1.4   misho     302:     /* Remove trailing newlines. */
                    303:     while (len > 0 && str[len - 1] == '\n')
1.1.1.3   misho     304:        len--;
                    305: 
1.1.1.4   misho     306:     if (len > 0) {
                    307:        if (func != NULL && file != NULL) {
                    308:            if (errno_val) {
                    309:                sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s: %s @ %s() %s:%d",
                    310:                    len, str, strerror(errno_val), func, file, lineno);
                    311:            } else {
                    312:                sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s @ %s() %s:%d",
                    313:                    len, str, func, file, lineno);
                    314:            }
1.1.1.3   misho     315:        } else {
1.1.1.4   misho     316:            if (errno_val) {
                    317:                sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s: %s",
                    318:                    len, str, strerror(errno_val));
                    319:            } else {
                    320:                sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s", len, str);
                    321:            }
1.1.1.3   misho     322:        }
1.1.1.4   misho     323:     } else if (errno_val) {
                    324:        /* Only print error string. */
                    325:        if (func != NULL && file != NULL) {
                    326:            sudo_printf(SUDO_CONV_DEBUG_MSG, "%s @ %s() %s:%d",
                    327:                strerror(errno_val), func, file, lineno);
1.1.1.3   misho     328:        } else {
1.1.1.4   misho     329:            sudo_printf(SUDO_CONV_DEBUG_MSG, "%s", strerror(errno_val));
1.1       misho     330:        }
                    331:     }
                    332: }
                    333: 
                    334: static void
                    335: sudo_debug_write_file(const char *func, const char *file, int lineno,
                    336:     const char *str, int len, int errno_val)
                    337: {
                    338:     char *timestr, numbuf[(((sizeof(int) * 8) + 2) / 3) + 2];
                    339:     time_t now;
                    340:     struct iovec iov[12];
1.1.1.4   misho     341:     int iovcnt = 3;
1.1       misho     342: 
                    343:     /* Prepend program name and pid with a trailing space. */
                    344:     iov[1].iov_base = (char *)getprogname();
                    345:     iov[1].iov_len = strlen(iov[1].iov_base);
                    346:     iov[2].iov_base = sudo_debug_pidstr;
                    347:     iov[2].iov_len = sudo_debug_pidlen;
                    348: 
1.1.1.5 ! misho     349:     /* Add string, trimming any trailing newlines. */
        !           350:     while (len > 0 && str[len - 1] == '\n')
        !           351:        len--;
1.1.1.4   misho     352:     if (len > 0) {
                    353:        iov[iovcnt].iov_base = (char *)str;
                    354:        iov[iovcnt].iov_len = len;
                    355:        iovcnt++;
                    356:     }
1.1       misho     357: 
                    358:     /* Append error string if errno is specified. */
                    359:     if (errno_val) {
1.1.1.4   misho     360:        if (len > 0) {
                    361:            iov[iovcnt].iov_base = ": ";
                    362:            iov[iovcnt].iov_len = 2;
                    363:            iovcnt++;
                    364:        }
1.1       misho     365:        iov[iovcnt].iov_base = strerror(errno_val);
                    366:        iov[iovcnt].iov_len = strlen(iov[iovcnt].iov_base);
                    367:        iovcnt++;
                    368:     }
                    369: 
                    370:     /* If function, file and lineno are specified, append them. */
                    371:     if (func != NULL && file != NULL && lineno != 0) {
                    372:        iov[iovcnt].iov_base = " @ ";
                    373:        iov[iovcnt].iov_len = 3;
                    374:        iovcnt++;
                    375: 
                    376:        iov[iovcnt].iov_base = (char *)func;
                    377:        iov[iovcnt].iov_len = strlen(func);
                    378:        iovcnt++;
                    379: 
                    380:        iov[iovcnt].iov_base = "() ";
                    381:        iov[iovcnt].iov_len = 3;
                    382:        iovcnt++;
                    383: 
                    384:        iov[iovcnt].iov_base = (char *)file;
                    385:        iov[iovcnt].iov_len = strlen(file);
                    386:        iovcnt++;
                    387: 
                    388:        (void)snprintf(numbuf, sizeof(numbuf), ":%d", lineno);
                    389:        iov[iovcnt].iov_base = numbuf;
                    390:        iov[iovcnt].iov_len = strlen(numbuf);
                    391:        iovcnt++;
                    392:     }
                    393: 
1.1.1.4   misho     394:     /* Append newline. */
                    395:     iov[iovcnt].iov_base = "\n";
                    396:     iov[iovcnt].iov_len = 1;
                    397:     iovcnt++;
1.1       misho     398: 
                    399:     /* Do timestamp last due to ctime's static buffer. */
1.1.1.3   misho     400:     time(&now);
1.1       misho     401:     timestr = ctime(&now) + 4;
                    402:     timestr[15] = ' '; /* replace year with a space */
                    403:     timestr[16] = '\0';
                    404:     iov[0].iov_base = timestr;
                    405:     iov[0].iov_len = 16;
                    406: 
                    407:     /* Write message in a single syscall */
                    408:     ignore_result(writev(sudo_debug_fd, iov, iovcnt));
                    409: }
                    410: 
                    411: void
                    412: sudo_debug_write2(const char *func, const char *file, int lineno,
                    413:     const char *str, int len, int errno_val)
                    414: {
                    415:     switch (sudo_debug_mode) {
                    416:     case SUDO_DEBUG_MODE_CONV:
                    417:        sudo_debug_write_conv(func, file, lineno, str, len, errno_val);
                    418:        break;
                    419:     case SUDO_DEBUG_MODE_FILE:
                    420:        sudo_debug_write_file(func, file, lineno, str, len, errno_val);
                    421:        break;
                    422:     }
                    423: }
                    424: 
                    425: /* XXX - turn into a macro */
                    426: void
                    427: sudo_debug_write(const char *str, int len, int errno_val)
                    428: {
                    429:     sudo_debug_write2(NULL, NULL, 0, str, len, errno_val);
                    430: }
                    431: 
                    432: void
1.1.1.3   misho     433: sudo_debug_vprintf2(const char *func, const char *file, int lineno, int level,
                    434:     const char *fmt, va_list ap)
1.1       misho     435: {
                    436:     int buflen, pri, subsys, saved_errno = errno;
1.1.1.4   misho     437:     char *buf = NULL;
1.1       misho     438: 
                    439:     if (!sudo_debug_mode)
                    440:        return;
                    441: 
                    442:     /* Extract pri and subsystem from level. */
                    443:     pri = SUDO_DEBUG_PRI(level);
                    444:     subsys = SUDO_DEBUG_SUBSYS(level);
                    445: 
                    446:     /* Make sure we want debug info at this level. */
1.1.1.5 ! misho     447:     if (subsys < num_subsystems && sudo_debug_settings[subsys] >= pri) {
1.1.1.4   misho     448:        buflen = fmt ? vasprintf(&buf, fmt, ap) : 0;
1.1       misho     449:        if (buflen != -1) {
                    450:            int errcode = ISSET(level, SUDO_DEBUG_ERRNO) ? saved_errno : 0;
                    451:            if (ISSET(level, SUDO_DEBUG_LINENO))
                    452:                sudo_debug_write2(func, file, lineno, buf, buflen, errcode);
                    453:            else
                    454:                sudo_debug_write2(NULL, NULL, 0, buf, buflen, errcode);
                    455:            free(buf);
                    456:        }
                    457:     }
                    458: 
                    459:     errno = saved_errno;
                    460: }
                    461: 
1.1.1.5 ! misho     462: #ifdef NO_VARIADIC_MACROS
        !           463: void
        !           464: sudo_debug_printf_nvm(int pri, const char *fmt, ...)
        !           465: {
        !           466:     va_list ap;
        !           467: 
        !           468:     va_start(ap, fmt);
        !           469:     sudo_debug_vprintf2(NULL, NULL, 0, pri, fmt, ap);
        !           470:     va_end(ap);
        !           471: }
        !           472: #endif /* NO_VARIADIC_MACROS */
        !           473: 
1.1       misho     474: void
1.1.1.3   misho     475: sudo_debug_printf2(const char *func, const char *file, int lineno, int level,
                    476:     const char *fmt, ...)
                    477: {
                    478:     va_list ap;
                    479: 
                    480:     va_start(ap, fmt);
                    481:     sudo_debug_vprintf2(func, file, lineno, level, fmt, ap);
                    482:     va_end(ap);
                    483: }
                    484: 
                    485: void
1.1       misho     486: sudo_debug_execve2(int level, const char *path, char *const argv[], char *const envp[])
                    487: {
                    488:     char * const *av;
                    489:     char *buf, *cp;
                    490:     int buflen, pri, subsys, log_envp = 0;
                    491:     size_t plen;
                    492: 
                    493:     if (!sudo_debug_mode)
                    494:        return;
                    495: 
                    496:     /* Extract pri and subsystem from level. */
                    497:     pri = SUDO_DEBUG_PRI(level);
                    498:     subsys = SUDO_DEBUG_SUBSYS(level);
                    499: 
                    500:     /* Make sure we want debug info at this level. */
1.1.1.5 ! misho     501:     if (subsys >= num_subsystems || sudo_debug_settings[subsys] < pri)
1.1       misho     502:        return;
                    503: 
                    504:     /* Log envp for debug level "debug". */
                    505:     if (sudo_debug_settings[subsys] >= SUDO_DEBUG_DEBUG - 1 && envp[0] != NULL)
                    506:        log_envp = 1;
                    507: 
                    508: #define EXEC_PREFIX "exec "
                    509: 
                    510:     /* Alloc and build up buffer. */
                    511:     plen = strlen(path);
                    512:     buflen = sizeof(EXEC_PREFIX) -1 + plen;
                    513:     if (argv[0] != NULL) {
                    514:        buflen += sizeof(" []") - 1;
                    515:        for (av = argv; *av; av++)
                    516:            buflen += strlen(*av) + 1;
                    517:        buflen--;
                    518:     }
                    519:     if (log_envp) {
                    520:        buflen += sizeof(" []") - 1;
                    521:        for (av = envp; *av; av++)
                    522:            buflen += strlen(*av) + 1;
                    523:        buflen--;
                    524:     }
                    525:     buf = malloc(buflen + 1);
                    526:     if (buf == NULL)
                    527:        return;
                    528: 
                    529:     /* Copy prefix and command. */
                    530:     memcpy(buf, EXEC_PREFIX, sizeof(EXEC_PREFIX) - 1);
                    531:     cp = buf + sizeof(EXEC_PREFIX) - 1;
                    532:     memcpy(cp, path, plen);
                    533:     cp += plen;
                    534: 
                    535:     /* Copy argv. */
                    536:     if (argv[0] != NULL) {
                    537:        *cp++ = ' ';
                    538:        *cp++ = '[';
                    539:        for (av = argv; *av; av++) {
                    540:            size_t avlen = strlen(*av);
                    541:            memcpy(cp, *av, avlen);
                    542:            cp += avlen;
                    543:            *cp++ = ' ';
                    544:        }
                    545:        cp[-1] = ']';
                    546:     }
                    547: 
                    548:     if (log_envp) {
                    549:        *cp++ = ' ';
                    550:        *cp++ = '[';
                    551:        for (av = envp; *av; av++) {
                    552:            size_t avlen = strlen(*av);
                    553:            memcpy(cp, *av, avlen);
                    554:            cp += avlen;
                    555:            *cp++ = ' ';
                    556:        }
                    557:        cp[-1] = ']';
                    558:     }
                    559: 
                    560:     *cp = '\0';
                    561: 
                    562:     sudo_debug_write(buf, buflen, 0);
                    563:     free(buf);
                    564: }
                    565: 
                    566: /*
1.1.1.5 ! misho     567:  * Getter for the debug descriptor.
        !           568:  */
        !           569: int
        !           570: sudo_debug_fd_get(void)
        !           571: {
        !           572:     return sudo_debug_fd;
        !           573: }
        !           574: 
        !           575: /*
        !           576:  * Setter for the debug descriptor.
1.1       misho     577:  */
                    578: int
                    579: sudo_debug_fd_set(int fd)
                    580: {
                    581:     if (sudo_debug_fd != -1 && fd != sudo_debug_fd) {
                    582:        if (dup2(sudo_debug_fd, fd) == -1)
                    583:            return -1;
                    584:        (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
                    585:        close(sudo_debug_fd);
                    586:        sudo_debug_fd = fd;
                    587:     }
                    588:     return sudo_debug_fd;
                    589: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>