2 * Copyright (c) 1994-1996, 1998-2013 Todd C. Miller <Todd.Miller@courtesan.com>
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.
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.
16 * Sponsored in part by the Defense Advanced Research Projects
17 * Agency (DARPA) and Air Force Research Laboratory, Air Force
18 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
27 #include <sys/types.h>
29 #include <sys/ioctl.h>
39 #endif /* STDC_HEADERS */
42 #endif /* HAVE_STRING_H */
45 #endif /* HAVE_STRINGS_H */
48 #endif /* HAVE_UNISTD_H */
49 #ifdef HAVE_NL_LANGINFO
50 # include <langinfo.h>
51 #endif /* HAVE_NL_LANGINFO */
63 # define va_copy(d, s) memcpy(&(d), &(s), sizeof(d));
66 /* Special message for log_warning() so we know to use ngettext() */
67 #define INCORRECT_PASSWORD_ATTEMPT ((char *)0x01)
69 static void do_syslog(int, char *);
70 static void do_logfile(char *);
71 static void send_mail(const char *fmt, ...);
72 static int should_mail(int);
73 static void mysyslog(int, const char *, ...);
74 static char *new_logline(const char *, int);
76 extern char **NewArgv; /* XXX - for auditing */
78 #define MAXSYSLOGTRIES 16 /* num of retries for broken syslogs */
81 * We do an openlog(3)/closelog(3) for each message because some
82 * authentication methods (notably PAM) use syslog(3) for their
83 * own nefarious purposes and may call openlog(3) and closelog(3).
84 * Note that because we don't want to assume that all systems have
85 * vsyslog(3) (HP-UX doesn't) "%m" will not be expanded.
86 * Sadly this is a maze of #ifdefs.
89 mysyslog(int pri, const char *fmt, ...)
94 char buf[MAXSYSLOGLEN+1];
96 debug_decl(mysyslog, SUDO_DEBUG_LOGGING)
99 #ifdef LOG_NFACILITIES
100 openlog("sudo", 0, def_syslog);
104 vsnprintf(buf, sizeof(buf), fmt, ap);
107 * Some versions of syslog(3) don't guarantee success and return
108 * an int (notably HP-UX < 10.0). So, if at first we don't succeed,
111 for (i = 0; i < MAXSYSLOGTRIES; i++)
112 if (syslog(pri, "%s", buf) == 0)
115 syslog(pri, "%s", buf);
116 #endif /* BROKEN_SYSLOG */
123 * Log a message to syslog, pre-pending the username and splitting the
124 * message into parts if it is longer than MAXSYSLOGLEN.
127 do_syslog(int pri, char *msg)
133 debug_decl(do_syslog, SUDO_DEBUG_LOGGING)
135 sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
138 * Log the full line, breaking into multiple syslog(3) calls if necessary
141 maxlen = MAXSYSLOGLEN - (strlen(fmt) - 5 + strlen(user_name));
142 for (p = msg; *p != '\0'; ) {
146 * Break up the line into what will fit on one syslog(3) line
147 * Try to avoid breaking words into several lines if possible.
149 tmp = memrchr(p, ' ', maxlen);
153 /* NULL terminate line, but save the char to restore later */
157 mysyslog(pri, fmt, user_name, p);
159 *tmp = save; /* restore saved character */
161 /* Advance p and eliminate leading whitespace */
162 for (p = tmp; *p == ' '; p++)
165 mysyslog(pri, fmt, user_name, p);
168 fmt = _("%8s : (command continued) %s");
169 maxlen = MAXSYSLOGLEN - (strlen(fmt) - 5 + strlen(user_name));
172 sudoers_setlocale(oldlocale, NULL);
178 do_logfile(char *msg)
186 debug_decl(do_logfile, SUDO_DEBUG_LOGGING)
188 sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
190 oldmask = umask(077);
191 fp = fopen(def_logfile, "a");
192 (void) umask(oldmask);
194 send_mail(_("unable to open log file: %s: %s"),
195 def_logfile, strerror(errno));
196 } else if (!lock_file(fileno(fp), SUDO_LOCK)) {
197 send_mail(_("unable to lock log file: %s: %s"),
198 def_logfile, strerror(errno));
201 if (def_loglinelen < sizeof(LOG_INDENT)) {
202 /* Don't pretty-print long log file lines (hard to grep) */
204 (void) fprintf(fp, "%s : %s : HOST=%s : %s\n",
205 get_timestr(now, def_log_year), user_name, user_shost, msg);
207 (void) fprintf(fp, "%s : %s : %s\n",
208 get_timestr(now, def_log_year), user_name, msg);
211 len = easprintf(&full_line, "%s : %s : HOST=%s : %s",
212 get_timestr(now, def_log_year), user_name, user_shost, msg);
214 len = easprintf(&full_line, "%s : %s : %s",
215 get_timestr(now, def_log_year), user_name, msg);
218 * Print out full_line with word wrap around def_loglinelen chars.
220 writeln_wrap(fp, full_line, len, def_loglinelen);
224 (void) lock_file(fileno(fp), SUDO_UNLOCK);
227 sudoers_setlocale(oldlocale, NULL);
233 * Log, audit and mail the denial message, optionally informing the user.
236 log_denial(int status, bool inform_user)
241 debug_decl(log_denial, SUDO_DEBUG_LOGGING)
243 /* Handle auditing first (audit_failure() handles the locale itself). */
244 if (ISSET(status, FLAG_NO_USER | FLAG_NO_HOST))
245 audit_failure(NewArgv, N_("No user or host"));
247 audit_failure(NewArgv, N_("validation failure"));
249 /* Log and mail messages should be in the sudoers locale. */
250 sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
252 /* Set error message. */
253 if (ISSET(status, FLAG_NO_USER))
254 message = _("user NOT in sudoers");
255 else if (ISSET(status, FLAG_NO_HOST))
256 message = _("user NOT authorized on host");
258 message = _("command not allowed");
260 logline = new_logline(message, 0);
262 /* Become root if we are not already. */
263 set_perms(PERM_ROOT|PERM_NOEXIT);
265 if (should_mail(status))
266 send_mail("%s", logline); /* send mail based on status */
269 * Log via syslog and/or a file.
272 do_syslog(def_syslog_badpri, logline);
280 /* Restore locale. */
281 sudoers_setlocale(oldlocale, NULL);
283 /* Inform the user if they failed to authenticate (in their locale). */
285 sudoers_setlocale(SUDOERS_LOCALE_USER, &oldlocale);
287 if (ISSET(status, FLAG_NO_USER)) {
288 sudo_printf(SUDO_CONV_ERROR_MSG, _("%s is not in the sudoers "
289 "file. This incident will be reported.\n"), user_name);
290 } else if (ISSET(status, FLAG_NO_HOST)) {
291 sudo_printf(SUDO_CONV_ERROR_MSG, _("%s is not allowed to run sudo "
292 "on %s. This incident will be reported.\n"),
293 user_name, user_shost);
294 } else if (ISSET(status, FLAG_NO_CHECK)) {
295 sudo_printf(SUDO_CONV_ERROR_MSG, _("Sorry, user %s may not run "
296 "sudo on %s.\n"), user_name, user_shost);
298 sudo_printf(SUDO_CONV_ERROR_MSG, _("Sorry, user %s is not allowed "
299 "to execute '%s%s%s' as %s%s%s on %s.\n"),
300 user_name, user_cmnd, user_args ? " " : "",
301 user_args ? user_args : "",
302 list_pw ? list_pw->pw_name : runas_pw ?
303 runas_pw->pw_name : user_name, runas_gr ? ":" : "",
304 runas_gr ? runas_gr->gr_name : "", user_host);
306 sudoers_setlocale(oldlocale, NULL);
312 * Log and audit that user was not allowed to run the command.
315 log_failure(int status, int flags)
317 bool inform_user = true;
318 debug_decl(log_failure, SUDO_DEBUG_LOGGING)
320 /* The user doesn't always get to see the log message (path info). */
321 if (!ISSET(status, FLAG_NO_USER | FLAG_NO_HOST) && def_path_info &&
322 (flags == NOT_FOUND_DOT || flags == NOT_FOUND))
324 log_denial(status, inform_user);
328 * We'd like to not leak path info at all here, but that can
329 * *really* confuse the users. To really close the leak we'd
330 * have to say "not allowed to run foo" even when the problem
331 * is just "no foo in path" since the user can trivially set
332 * their path to just contain a single dir.
334 if (flags == NOT_FOUND)
335 warningx(_("%s: command not found"), user_cmnd);
336 else if (flags == NOT_FOUND_DOT)
337 warningx(_("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run."), user_cmnd, user_cmnd, user_cmnd);
344 * Log and audit that user was not able to authenticate themselves.
347 log_auth_failure(int status, int tries)
350 debug_decl(log_auth_failure, SUDO_DEBUG_LOGGING)
352 /* Handle auditing first. */
353 audit_failure(NewArgv, N_("authentication failure"));
356 * Do we need to send mail?
357 * We want to avoid sending multiple messages for the same command
358 * so if we are going to send an email about the denial, that takes
361 if (ISSET(status, VALIDATE_OK)) {
362 /* Command allowed, auth failed; do we need to send mail? */
363 if (def_mail_badpass || def_mail_always)
366 /* Command denied, auth failed; make sure we don't send mail twice. */
367 if (def_mail_badpass && !should_mail(status))
369 /* Don't log the bad password message, we'll log a denial instead. */
374 * If sudoers denied the command we'll log that separately.
376 if (ISSET(status, FLAG_BAD_PASSWORD))
377 log_warning(flags, INCORRECT_PASSWORD_ATTEMPT, tries);
378 else if (ISSET(status, FLAG_NON_INTERACTIVE))
379 log_warning(flags, N_("a password is required"));
385 * Log and potentially mail the allowed command.
388 log_allowed(int status)
392 debug_decl(log_allowed, SUDO_DEBUG_LOGGING)
394 /* Log and mail messages should be in the sudoers locale. */
395 sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
397 logline = new_logline(NULL, 0);
399 /* Become root if we are not already. */
400 set_perms(PERM_ROOT|PERM_NOEXIT);
402 if (should_mail(status))
403 send_mail("%s", logline); /* send mail based on status */
406 * Log via syslog and/or a file.
409 do_syslog(def_syslog_goodpri, logline);
417 sudoers_setlocale(oldlocale, NULL);
423 * Perform logging for log_warning()/log_fatal()
426 vlog_warning(int flags, const char *fmt, va_list ap)
428 int oldlocale, serrno = errno;
429 char *logline, *message;
431 debug_decl(vlog_error, SUDO_DEBUG_LOGGING)
433 /* Need extra copy of ap for warning() below. */
434 if (!ISSET(flags, NO_STDERR))
437 /* Log messages should be in the sudoers locale. */
438 sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
440 /* Expand printf-style format + args (with a special case). */
441 if (fmt == INCORRECT_PASSWORD_ATTEMPT) {
442 int tries = va_arg(ap, int);
443 easprintf(&message, ngettext("%d incorrect password attempt",
444 "%d incorrect password attempts", tries), tries);
446 evasprintf(&message, _(fmt), ap);
449 if (ISSET(flags, MSG_ONLY)) {
452 logline = new_logline(message, ISSET(flags, USE_ERRNO) ? serrno : 0);
456 /* Become root if we are not already. */
457 set_perms(PERM_ROOT|PERM_NOEXIT);
460 * Send a copy of the error via mail.
462 if (!ISSET(flags, NO_MAIL))
463 send_mail("%s", logline);
466 * Log to syslog and/or a file.
468 if (!ISSET(flags, NO_LOG)) {
470 do_syslog(def_syslog_badpri, logline);
479 sudoers_setlocale(oldlocale, NULL);
482 * Tell the user (in their locale).
484 if (!ISSET(flags, NO_STDERR)) {
485 if (fmt == INCORRECT_PASSWORD_ATTEMPT) {
486 int tries = va_arg(ap2, int);
487 warningx(ngettext("%d incorrect password attempt",
488 "%d incorrect password attempts", tries), tries);
490 if (ISSET(flags, USE_ERRNO))
502 log_warning(int flags, const char *fmt, ...)
505 debug_decl(log_error, SUDO_DEBUG_LOGGING)
509 vlog_warning(flags, fmt, ap);
516 log_fatal(int flags, const char *fmt, ...)
519 debug_decl(log_error, SUDO_DEBUG_LOGGING)
523 vlog_warning(flags, fmt, ap);
526 /* Exit the plugin. */
528 sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
532 #define MAX_MAILFLAGS 63
535 * Send a message to MAILTO user
538 send_mail(const char *fmt, ...)
542 int fd, pfd[2], status;
546 #ifndef NO_ROOT_MAILER
547 static char *root_envp[] = {
549 "PATH=/usr/bin:/bin:/usr/sbin:/sbin",
555 #endif /* NO_ROOT_MAILER */
556 debug_decl(send_mail, SUDO_DEBUG_LOGGING)
558 /* Just return if mailer is disabled. */
559 if (!def_mailerpath || !def_mailto)
562 /* Fork and return, child will daemonize. */
563 switch (pid = sudo_debug_fork()) {
566 fatal(_("unable to fork"));
570 switch (pid = fork()) {
573 mysyslog(LOG_ERR, _("unable to fork: %m"));
574 sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to fork: %s",
578 /* Grandchild continues below. */
581 /* Parent will wait for us. */
588 rv = waitpid(pid, &status, 0);
589 } while (rv == -1 && errno == EINTR);
590 return; /* not debug */
593 /* Daemonize - disassociate from session/tty. */
596 if (chdir("/") == -1)
598 if ((fd = open(_PATH_DEVNULL, O_RDWR, 0644)) != -1) {
599 (void) dup2(fd, STDIN_FILENO);
600 (void) dup2(fd, STDOUT_FILENO);
601 (void) dup2(fd, STDERR_FILENO);
604 sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, NULL);
606 /* Close password, group and other fds so we don't leak. */
609 closefrom(STDERR_FILENO + 1);
611 /* Ignore SIGPIPE in case mailer exits prematurely (or is missing). */
612 zero_bytes(&sa, sizeof(sa));
613 sigemptyset(&sa.sa_mask);
614 sa.sa_flags = SA_INTERRUPT;
615 sa.sa_handler = SIG_IGN;
616 (void) sigaction(SIGPIPE, &sa, NULL);
618 if (pipe(pfd) == -1) {
619 mysyslog(LOG_ERR, _("unable to open pipe: %m"));
620 sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to open pipe: %s",
622 sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
626 switch (pid = sudo_debug_fork()) {
629 mysyslog(LOG_ERR, _("unable to fork: %m"));
630 sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to fork: %s",
632 sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
637 char *argv[MAX_MAILFLAGS + 1];
638 char *mpath, *mflags;
641 /* Child, set stdin to output side of the pipe */
642 if (pfd[0] != STDIN_FILENO) {
643 if (dup2(pfd[0], STDIN_FILENO) == -1) {
644 mysyslog(LOG_ERR, _("unable to dup stdin: %m"));
645 sudo_debug_printf(SUDO_DEBUG_ERROR,
646 "unable to dup stdin: %s", strerror(errno));
649 (void) close(pfd[0]);
651 (void) close(pfd[1]);
653 /* Build up an argv based on the mailer path and flags */
654 mflags = estrdup(def_mailerflags);
655 mpath = estrdup(def_mailerpath);
656 if ((argv[0] = strrchr(mpath, ' ')))
662 if ((p = strtok(mflags, " \t"))) {
665 } while (++i < MAX_MAILFLAGS && (p = strtok(NULL, " \t")));
670 * Depending on the config, either run the mailer as root
671 * (so user cannot kill it) or as the user (for the paranoid).
673 #ifndef NO_ROOT_MAILER
674 set_perms(PERM_ROOT|PERM_NOEXIT);
675 execve(mpath, argv, root_envp);
677 set_perms(PERM_FULL_USER|PERM_NOEXIT);
679 #endif /* NO_ROOT_MAILER */
680 mysyslog(LOG_ERR, _("unable to execute %s: %m"), mpath);
681 sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to execute %s: %s",
682 mpath, strerror(errno));
688 (void) close(pfd[0]);
689 mail = fdopen(pfd[1], "w");
691 /* Pipes are all setup, send message. */
692 (void) fprintf(mail, "To: %s\nFrom: %s\nAuto-Submitted: %s\nSubject: ",
693 def_mailto, def_mailfrom ? def_mailfrom : user_name, "auto-generated");
694 for (p = _(def_mailsub); *p; p++) {
695 /* Expand escapes in the subject */
696 if (*p == '%' && *(p+1) != '%') {
699 (void) fputs(user_host, mail);
702 (void) fputs(user_name, mail);
709 (void) fputc(*p, mail);
712 #ifdef HAVE_NL_LANGINFO
713 if (strcmp(def_sudoers_locale, "C") != 0)
714 (void) fprintf(mail, "\nContent-Type: text/plain; charset=\"%s\"\nContent-Transfer-Encoding: 8bit", nl_langinfo(CODESET));
715 #endif /* HAVE_NL_LANGINFO */
717 (void) fprintf(mail, "\n\n%s : %s : %s : ", user_host,
718 get_timestr(time(NULL), def_log_year), user_name);
720 (void) vfprintf(mail, fmt, ap);
726 rv = waitpid(pid, &status, 0);
727 } while (rv == -1 && errno == EINTR);
728 sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
733 * Determine whether we should send mail based on "status" and defaults options.
736 should_mail(int status)
738 debug_decl(should_mail, SUDO_DEBUG_LOGGING)
740 debug_return_bool(def_mail_always || ISSET(status, VALIDATE_ERROR) ||
741 (def_mail_no_user && ISSET(status, FLAG_NO_USER)) ||
742 (def_mail_no_host && ISSET(status, FLAG_NO_HOST)) ||
743 (def_mail_no_perms && !ISSET(status, VALIDATE_OK)));
746 #define LL_TTY_STR "TTY="
747 #define LL_CWD_STR "PWD=" /* XXX - should be CWD= */
748 #define LL_USER_STR "USER="
749 #define LL_GROUP_STR "GROUP="
750 #define LL_ENV_STR "ENV="
751 #define LL_CMND_STR "COMMAND="
752 #define LL_TSID_STR "TSID="
754 #define IS_SESSID(s) ( \
755 isalnum((unsigned char)(s)[0]) && isalnum((unsigned char)(s)[1]) && \
757 isalnum((unsigned char)(s)[3]) && isalnum((unsigned char)(s)[4]) && \
759 isalnum((unsigned char)(s)[6]) && isalnum((unsigned char)(s)[7]) && \
763 * Allocate and fill in a new logline.
766 new_logline(const char *message, int serrno)
768 char *line, *errstr = NULL, *evstr = NULL;
769 #ifndef SUDOERS_NO_SEQ
772 const char *tsid = NULL;
774 debug_decl(new_logline, SUDO_DEBUG_LOGGING)
776 #ifndef SUDOERS_NO_SEQ
777 /* A TSID may be a sudoers-style session ID or a free-form string. */
778 if (sudo_user.iolog_file != NULL) {
779 if (IS_SESSID(sudo_user.iolog_file)) {
780 sessid[0] = sudo_user.iolog_file[0];
781 sessid[1] = sudo_user.iolog_file[1];
782 sessid[2] = sudo_user.iolog_file[3];
783 sessid[3] = sudo_user.iolog_file[4];
784 sessid[4] = sudo_user.iolog_file[6];
785 sessid[5] = sudo_user.iolog_file[7];
789 tsid = sudo_user.iolog_file;
795 * Compute line length
798 len += strlen(message) + 3;
800 errstr = strerror(serrno);
801 len += strlen(errstr) + 3;
803 len += sizeof(LL_TTY_STR) + 2 + strlen(user_tty);
804 len += sizeof(LL_CWD_STR) + 2 + strlen(user_cwd);
805 if (runas_pw != NULL)
806 len += sizeof(LL_USER_STR) + 2 + strlen(runas_pw->pw_name);
807 if (runas_gr != NULL)
808 len += sizeof(LL_GROUP_STR) + 2 + strlen(runas_gr->gr_name);
810 len += sizeof(LL_TSID_STR) + 2 + strlen(tsid);
811 if (sudo_user.env_vars != NULL) {
815 for (ep = sudo_user.env_vars; *ep != NULL; ep++)
816 evlen += strlen(*ep) + 1;
817 evstr = emalloc(evlen);
819 for (ep = sudo_user.env_vars; *ep != NULL; ep++) {
820 strlcat(evstr, *ep, evlen);
821 strlcat(evstr, " ", evlen); /* NOTE: last one will fail */
823 len += sizeof(LL_ENV_STR) + 2 + evlen;
825 if (user_cmnd != NULL) {
826 /* Note: we log "sudo -l command arg ..." as "list command arg ..." */
827 len += sizeof(LL_CMND_STR) - 1 + strlen(user_cmnd);
828 if (ISSET(sudo_mode, MODE_CHECK))
829 len += sizeof("list ") - 1;
830 if (user_args != NULL)
831 len += strlen(user_args) + 1;
835 * Allocate and build up the line.
837 line = emalloc(++len);
840 if (message != NULL) {
841 if (strlcat(line, message, len) >= len ||
842 strlcat(line, errstr ? " : " : " ; ", len) >= len)
846 if (strlcat(line, errstr, len) >= len ||
847 strlcat(line, " ; ", len) >= len)
850 if (strlcat(line, LL_TTY_STR, len) >= len ||
851 strlcat(line, user_tty, len) >= len ||
852 strlcat(line, " ; ", len) >= len)
854 if (strlcat(line, LL_CWD_STR, len) >= len ||
855 strlcat(line, user_cwd, len) >= len ||
856 strlcat(line, " ; ", len) >= len)
858 if (runas_pw != NULL) {
859 if (strlcat(line, LL_USER_STR, len) >= len ||
860 strlcat(line, runas_pw->pw_name, len) >= len ||
861 strlcat(line, " ; ", len) >= len)
864 if (runas_gr != NULL) {
865 if (strlcat(line, LL_GROUP_STR, len) >= len ||
866 strlcat(line, runas_gr->gr_name, len) >= len ||
867 strlcat(line, " ; ", len) >= len)
871 if (strlcat(line, LL_TSID_STR, len) >= len ||
872 strlcat(line, tsid, len) >= len ||
873 strlcat(line, " ; ", len) >= len)
877 if (strlcat(line, LL_ENV_STR, len) >= len ||
878 strlcat(line, evstr, len) >= len ||
879 strlcat(line, " ; ", len) >= len)
883 if (user_cmnd != NULL) {
884 if (strlcat(line, LL_CMND_STR, len) >= len)
886 if (ISSET(sudo_mode, MODE_CHECK) && strlcat(line, "list ", len) >= len)
888 if (strlcat(line, user_cmnd, len) >= len)
890 if (user_args != NULL) {
891 if (strlcat(line, " ", len) >= len ||
892 strlcat(line, user_args, len) >= len)
897 debug_return_str(line);
899 fatalx(_("internal error: insufficient space for log line"));