LCOV - code coverage report
Current view: top level - lib/util - debug.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 427 571 74.8 %
Date: 2021-09-23 10:06:22 Functions: 44 54 81.5 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Samba utility functions
       4             :    Copyright (C) Andrew Tridgell 1992-1998
       5             :    Copyright (C) Elrond               2002
       6             :    Copyright (C) Simo Sorce           2002
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "replace.h"
      23             : #include <talloc.h>
      24             : #include "system/filesys.h"
      25             : #include "system/syslog.h"
      26             : #include "system/locale.h"
      27             : #include "time_basic.h"
      28             : #include "close_low_fd.h"
      29             : #include "memory.h"
      30             : #include "util_strlist.h" /* LIST_SEP */
      31             : #include "blocking.h"
      32             : #include "debug.h"
      33             : #include <assert.h>
      34             : 
      35             : /* define what facility to use for syslog */
      36             : #ifndef SYSLOG_FACILITY
      37             : #define SYSLOG_FACILITY LOG_DAEMON
      38             : #endif
      39             : 
      40             : /* -------------------------------------------------------------------------- **
      41             :  * Defines...
      42             :  */
      43             : 
      44             : /*
      45             :  * format_bufr[FORMAT_BUFR_SIZE - 1] should always be reserved
      46             :  * for a terminating null byte.
      47             :  */
      48             : #define FORMAT_BUFR_SIZE 4096
      49             : 
      50             : /* -------------------------------------------------------------------------- **
      51             :  * This module implements Samba's debugging utility.
      52             :  *
      53             :  * The syntax of a debugging log file is represented as:
      54             :  *
      55             :  *  <debugfile> :== { <debugmsg> }
      56             :  *
      57             :  *  <debugmsg>  :== <debughdr> '\n' <debugtext>
      58             :  *
      59             :  *  <debughdr>  :== '[' TIME ',' LEVEL ']' [ [FILENAME ':'] [FUNCTION '()'] ]
      60             :  *
      61             :  *  <debugtext> :== { <debugline> }
      62             :  *
      63             :  *  <debugline> :== TEXT '\n'
      64             :  *
      65             :  * TEXT     is a string of characters excluding the newline character.
      66             :  * LEVEL    is the DEBUG level of the message (an integer in the range 0..10).
      67             :  * TIME     is a timestamp.
      68             :  * FILENAME is the name of the file from which the debug message was generated.
      69             :  * FUNCTION is the function from which the debug message was generated.
      70             :  *
      71             :  * Basically, what that all means is:
      72             :  *
      73             :  * - A debugging log file is made up of debug messages.
      74             :  *
      75             :  * - Each debug message is made up of a header and text.  The header is
      76             :  *   separated from the text by a newline.
      77             :  *
      78             :  * - The header begins with the timestamp and debug level of the message
      79             :  *   enclosed in brackets.  The filename and function from which the
      80             :  *   message was generated may follow.  The filename is terminated by a
      81             :  *   colon, and the function name is terminated by parenthesis.
      82             :  *
      83             :  * - The message text is made up of zero or more lines, each terminated by
      84             :  *   a newline.
      85             :  */
      86             : 
      87             : /* state variables for the debug system */
      88             : static struct {
      89             :         bool initialized;
      90             :         enum debug_logtype logtype; /* The type of logging we are doing: eg stdout, file, stderr */
      91             :         char prog_name[255];
      92             :         bool reopening_logs;
      93             :         bool schedule_reopen_logs;
      94             : 
      95             :         struct debug_settings settings;
      96             :         debug_callback_fn callback;
      97             :         void *callback_private;
      98             : } state = {
      99             :         .settings = {
     100             :                 .timestamp_logs = true
     101             :         },
     102             : };
     103             : 
     104             : struct debug_class {
     105             :         /*
     106             :          * The debug loglevel of the class.
     107             :          */
     108             :         int loglevel;
     109             : 
     110             :         /*
     111             :          * An optional class specific logfile, may be NULL in which case the
     112             :          * "global" logfile is used and fd is -1.
     113             :          */
     114             :         char *logfile;
     115             :         int fd;
     116             :         /* inode number of the logfile to detect logfile rotation */
     117             :         ino_t ino;
     118             : };
     119             : 
     120             : static const char *default_classname_table[] = {
     121             :         [DBGC_ALL] =                    "all",
     122             :         [DBGC_TDB] =                    "tdb",
     123             :         [DBGC_PRINTDRIVERS] =           "printdrivers",
     124             :         [DBGC_LANMAN] =                 "lanman",
     125             :         [DBGC_SMB] =                    "smb",
     126             :         [DBGC_RPC_PARSE] =              "rpc_parse",
     127             :         [DBGC_RPC_SRV] =                "rpc_srv",
     128             :         [DBGC_RPC_CLI] =                "rpc_cli",
     129             :         [DBGC_PASSDB] =                 "passdb",
     130             :         [DBGC_SAM] =                    "sam",
     131             :         [DBGC_AUTH] =                   "auth",
     132             :         [DBGC_WINBIND] =                "winbind",
     133             :         [DBGC_VFS] =                    "vfs",
     134             :         [DBGC_IDMAP] =                  "idmap",
     135             :         [DBGC_QUOTA] =                  "quota",
     136             :         [DBGC_ACLS] =                   "acls",
     137             :         [DBGC_LOCKING] =                "locking",
     138             :         [DBGC_MSDFS] =                  "msdfs",
     139             :         [DBGC_DMAPI] =                  "dmapi",
     140             :         [DBGC_REGISTRY] =               "registry",
     141             :         [DBGC_SCAVENGER] =              "scavenger",
     142             :         [DBGC_DNS] =                    "dns",
     143             :         [DBGC_LDB] =                    "ldb",
     144             :         [DBGC_TEVENT] =                 "tevent",
     145             :         [DBGC_AUTH_AUDIT] =             "auth_audit",
     146             :         [DBGC_AUTH_AUDIT_JSON] =        "auth_json_audit",
     147             :         [DBGC_KERBEROS] =               "kerberos",
     148             :         [DBGC_DRS_REPL] =               "drs_repl",
     149             :         [DBGC_SMB2] =                   "smb2",
     150             :         [DBGC_SMB2_CREDITS] =           "smb2_credits",
     151             :         [DBGC_DSDB_AUDIT] =             "dsdb_audit",
     152             :         [DBGC_DSDB_AUDIT_JSON] =        "dsdb_json_audit",
     153             :         [DBGC_DSDB_PWD_AUDIT]  =        "dsdb_password_audit",
     154             :         [DBGC_DSDB_PWD_AUDIT_JSON] =    "dsdb_password_json_audit",
     155             :         [DBGC_DSDB_TXN_AUDIT]  =        "dsdb_transaction_audit",
     156             :         [DBGC_DSDB_TXN_AUDIT_JSON] =    "dsdb_transaction_json_audit",
     157             :         [DBGC_DSDB_GROUP_AUDIT] =       "dsdb_group_audit",
     158             :         [DBGC_DSDB_GROUP_AUDIT_JSON] =  "dsdb_group_json_audit",
     159             : };
     160             : 
     161             : /*
     162             :  * This is to allow reading of dbgc_config before the debug
     163             :  * system has been initialized.
     164             :  */
     165             : static struct debug_class debug_class_list_initial[ARRAY_SIZE(default_classname_table)] = {
     166             :         [DBGC_ALL] = { .fd = 2 },
     167             : };
     168             : 
     169             : static size_t debug_num_classes = 0;
     170             : static struct debug_class *dbgc_config = debug_class_list_initial;
     171             : 
     172             : static int current_msg_level = 0;
     173             : static int current_msg_class = 0;
     174             : 
     175             : #if defined(WITH_SYSLOG) || defined(HAVE_LIBSYSTEMD_JOURNAL) || defined(HAVE_LIBSYSTEMD)
     176         423 : static int debug_level_to_priority(int level)
     177             : {
     178             :         /*
     179             :          * map debug levels to syslog() priorities
     180             :          */
     181             :         static const int priority_map[] = {
     182             :                 LOG_ERR,     /* 0 */
     183             :                 LOG_WARNING, /* 1 */
     184             :                 LOG_NOTICE,  /* 2 */
     185             :                 LOG_NOTICE,  /* 3 */
     186             :                 LOG_NOTICE,  /* 4 */
     187             :                 LOG_NOTICE,  /* 5 */
     188             :                 LOG_INFO,    /* 6 */
     189             :                 LOG_INFO,    /* 7 */
     190             :                 LOG_INFO,    /* 8 */
     191             :                 LOG_INFO,    /* 9 */
     192             :         };
     193             :         int priority;
     194             : 
     195         423 :         if (level < 0 || (size_t)level >= ARRAY_SIZE(priority_map))
     196           0 :                 priority = LOG_DEBUG;
     197             :         else
     198         423 :                 priority = priority_map[level];
     199             : 
     200         423 :         return priority;
     201             : }
     202             : #endif
     203             : 
     204             : /* -------------------------------------------------------------------------- **
     205             :  * Debug backends. When logging to DEBUG_FILE, send the log entries to
     206             :  * all active backends.
     207             :  */
     208             : 
     209        6364 : static void debug_file_log(int msg_level,
     210             :                            const char *msg, const char *msg_no_nl)
     211             : {
     212             :         ssize_t ret;
     213             :         int fd;
     214             : 
     215        6364 :         check_log_size();
     216             : 
     217        6364 :         if (dbgc_config[current_msg_class].fd != -1) {
     218        2127 :                 fd = dbgc_config[current_msg_class].fd;
     219             :         } else {
     220        4171 :                 fd = dbgc_config[DBGC_ALL].fd;
     221             :         }
     222             : 
     223             :         do {
     224        6364 :                 ret = write(fd, msg, strlen(msg));
     225        6364 :         } while (ret == -1 && errno == EINTR);
     226        6364 : }
     227             : 
     228             : #ifdef WITH_SYSLOG
     229      160578 : static void debug_syslog_reload(bool enabled, bool previously_enabled,
     230             :                                 const char *prog_name, char *option)
     231             : {
     232      160578 :         if (enabled && !previously_enabled) {
     233        8894 :                 const char *ident = NULL;
     234        8894 :                 if ((prog_name != NULL) && (prog_name[0] != '\0')) {
     235        4235 :                         ident = prog_name;
     236             :                 }
     237             : #ifdef LOG_DAEMON
     238        8894 :                 openlog(ident, LOG_PID, SYSLOG_FACILITY);
     239             : #else
     240             :                 /* for old systems that have no facility codes. */
     241             :                 openlog(ident, LOG_PID);
     242             : #endif
     243        8894 :                 return;
     244             :         }
     245             : 
     246      151684 :         if (!enabled && previously_enabled) {
     247           0 :                 closelog();
     248             :         }
     249             : }
     250             : 
     251         423 : static void debug_syslog_log(int msg_level,
     252             :                              const char *msg, const char *msg_no_nl)
     253             : {
     254             :         int priority;
     255             : 
     256         423 :         priority = debug_level_to_priority(msg_level);
     257             : 
     258             :         /*
     259             :          * Specify the facility to interoperate with other syslog
     260             :          * callers (vfs_full_audit for example).
     261             :          */
     262         423 :         priority |= SYSLOG_FACILITY;
     263             : 
     264         423 :         syslog(priority, "%s", msg);
     265         423 : }
     266             : #endif /* WITH_SYSLOG */
     267             : 
     268             : #if defined(HAVE_LIBSYSTEMD_JOURNAL) || defined(HAVE_LIBSYSTEMD)
     269             : #include <systemd/sd-journal.h>
     270           0 : static void debug_systemd_log(int msg_level,
     271             :                               const char *msg, const char *msg_no_nl)
     272             : {
     273           0 :         sd_journal_send("MESSAGE=%s", msg_no_nl,
     274             :                         "PRIORITY=%d", debug_level_to_priority(msg_level),
     275             :                         "LEVEL=%d", msg_level,
     276             :                         NULL);
     277           0 : }
     278             : #endif
     279             : 
     280             : #ifdef HAVE_LTTNG_TRACEF
     281             : #include <lttng/tracef.h>
     282             : static void debug_lttng_log(int msg_level,
     283             :                             const char *msg, const char *msg_no_nl)
     284             : {
     285             :         tracef(msg_no_nl);
     286             : }
     287             : #endif /* WITH_LTTNG_TRACEF */
     288             : 
     289             : #ifdef HAVE_GPFS
     290             : #include "gpfswrap.h"
     291      160578 : static void debug_gpfs_reload(bool enabled, bool previously_enabled,
     292             :                               const char *prog_name, char *option)
     293             : {
     294      160578 :         gpfswrap_init();
     295             : 
     296      160578 :         if (enabled && !previously_enabled) {
     297           0 :                 gpfswrap_init_trace();
     298           0 :                 return;
     299             :         }
     300             : 
     301      160578 :         if (!enabled && previously_enabled) {
     302           0 :                 gpfswrap_fini_trace();
     303           0 :                 return;
     304             :         }
     305             : 
     306      160578 :         if (enabled) {
     307             :                 /*
     308             :                  * Trigger GPFS library to adjust state if necessary.
     309             :                  */
     310           0 :                 gpfswrap_query_trace();
     311             :         }
     312             : }
     313             : 
     314           0 : static void debug_gpfs_log(int msg_level,
     315             :                            const char *msg, const char *msg_no_nl)
     316             : {
     317           0 :         gpfswrap_add_trace(msg_level, msg_no_nl);
     318           0 : }
     319             : #endif /* HAVE_GPFS */
     320             : 
     321             : #define DEBUG_RINGBUF_SIZE (1024 * 1024)
     322             : #define DEBUG_RINGBUF_SIZE_OPT "size="
     323             : 
     324             : static char *debug_ringbuf;
     325             : static size_t debug_ringbuf_size;
     326             : static size_t debug_ringbuf_ofs;
     327             : 
     328             : /* We ensure in debug_ringbuf_log() that this is always \0 terminated */
     329           0 : char *debug_get_ringbuf(void)
     330             : {
     331           0 :         return debug_ringbuf;
     332             : }
     333             : 
     334             : /* Return the size of the ringbuf (including a \0 terminator) */
     335           0 : size_t debug_get_ringbuf_size(void)
     336             : {
     337           0 :         return debug_ringbuf_size;
     338             : }
     339             : 
     340      160578 : static void debug_ringbuf_reload(bool enabled, bool previously_enabled,
     341             :                                  const char *prog_name, char *option)
     342             : {
     343             :         bool cmp;
     344      160578 :         size_t optlen = strlen(DEBUG_RINGBUF_SIZE_OPT);
     345             : 
     346      160578 :         debug_ringbuf_size = DEBUG_RINGBUF_SIZE;
     347      160578 :         debug_ringbuf_ofs = 0;
     348             : 
     349      160578 :         SAFE_FREE(debug_ringbuf);
     350             : 
     351      160578 :         if (!enabled) {
     352      157061 :                 return;
     353             :         }
     354             : 
     355           0 :         if (option != NULL) {
     356           0 :                 cmp = strncmp(option, DEBUG_RINGBUF_SIZE_OPT, optlen);
     357           0 :                 if (cmp == 0) {
     358           0 :                         debug_ringbuf_size = (size_t)strtoull(
     359           0 :                                 option + optlen, NULL, 10);
     360             :                 }
     361             :         }
     362             : 
     363           0 :         debug_ringbuf = calloc(debug_ringbuf_size, sizeof(char));
     364           0 :         if (debug_ringbuf == NULL) {
     365           0 :                 return;
     366             :         }
     367             : }
     368             : 
     369           0 : static void debug_ringbuf_log(int msg_level,
     370             :                               const char *msg,
     371             :                               const char *msg_no_nl)
     372             : {
     373           0 :         size_t msglen = strlen(msg);
     374             :         size_t allowed_size;
     375             : 
     376           0 :         if (debug_ringbuf == NULL) {
     377           0 :                 return;
     378             :         }
     379             : 
     380             :         /* Ensure the buffer is always \0 terminated */
     381           0 :         allowed_size = debug_ringbuf_size - 1;
     382             : 
     383           0 :         if (msglen > allowed_size) {
     384           0 :                 return;
     385             :         }
     386             : 
     387           0 :         if ((debug_ringbuf_ofs + msglen) < debug_ringbuf_ofs) {
     388           0 :                 return;
     389             :         }
     390             : 
     391           0 :         if ((debug_ringbuf_ofs + msglen) > allowed_size) {
     392           0 :                 debug_ringbuf_ofs = 0;
     393             :         }
     394             : 
     395           0 :         memcpy(debug_ringbuf + debug_ringbuf_ofs, msg, msglen);
     396           0 :         debug_ringbuf_ofs += msglen;
     397             : }
     398             : 
     399             : static struct debug_backend {
     400             :         const char *name;
     401             :         int log_level;
     402             :         int new_log_level;
     403             :         void (*reload)(bool enabled, bool prev_enabled,
     404             :                        const char *prog_name, char *option);
     405             :         void (*log)(int msg_level, const char *msg, const char *msg_no_nl);
     406             :         char *option;
     407             : } debug_backends[] = {
     408             :         {
     409             :                 .name = "file",
     410             :                 .log = debug_file_log,
     411             :         },
     412             : #ifdef WITH_SYSLOG
     413             :         {
     414             :                 .name = "syslog",
     415             :                 .reload = debug_syslog_reload,
     416             :                 .log = debug_syslog_log,
     417             :         },
     418             : #endif
     419             : 
     420             : #if defined(HAVE_LIBSYSTEMD_JOURNAL) || defined(HAVE_LIBSYSTEMD)
     421             :         {
     422             :                 .name = "systemd",
     423             :                 .log = debug_systemd_log,
     424             :         },
     425             : #endif
     426             : 
     427             : #ifdef HAVE_LTTNG_TRACEF
     428             :         {
     429             :                 .name = "lttng",
     430             :                 .log = debug_lttng_log,
     431             :         },
     432             : #endif
     433             : 
     434             : #ifdef HAVE_GPFS
     435             :         {
     436             :                 .name = "gpfs",
     437             :                 .reload = debug_gpfs_reload,
     438             :                 .log = debug_gpfs_log,
     439             :         },
     440             : #endif
     441             :         {
     442             :                 .name = "ringbuf",
     443             :                 .log = debug_ringbuf_log,
     444             :                 .reload = debug_ringbuf_reload,
     445             :         },
     446             : };
     447             : 
     448      223055 : static struct debug_backend *debug_find_backend(const char *name)
     449             : {
     450             :         unsigned i;
     451             : 
     452      256142 :         for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
     453      259048 :                 if (strcmp(name, debug_backends[i].name) == 0) {
     454      229977 :                         return &debug_backends[i];
     455             :                 }
     456             :         }
     457             : 
     458           2 :         return NULL;
     459             : }
     460             : 
     461             : /*
     462             :  * parse "backend[:option][@loglevel]
     463             :  */
     464      189637 : static void debug_backend_parse_token(char *tok)
     465             : {
     466             :         char *backend_name_option, *backend_name,*backend_level, *saveptr;
     467             :         char *backend_option;
     468             :         struct debug_backend *b;
     469             : 
     470             :         /*
     471             :          * First parse into backend[:option] and loglevel
     472             :          */
     473      189637 :         backend_name_option = strtok_r(tok, "@\0", &saveptr);
     474      189637 :         if (backend_name_option == NULL) {
     475           2 :                 return;
     476             :         }
     477             : 
     478      189637 :         backend_level = strtok_r(NULL, "\0", &saveptr);
     479             : 
     480             :         /*
     481             :          * Now parse backend[:option]
     482             :          */
     483      189637 :         backend_name = strtok_r(backend_name_option, ":\0", &saveptr);
     484      189637 :         if (backend_name == NULL) {
     485           0 :                 return;
     486             :         }
     487             : 
     488      189637 :         backend_option = strtok_r(NULL, "\0", &saveptr);
     489             : 
     490             :         /*
     491             :          * Find and update backend
     492             :          */
     493      189637 :         b = debug_find_backend(backend_name);
     494      189637 :         if (b == NULL) {
     495           2 :                 return;
     496             :         }
     497             : 
     498      189635 :         if (backend_level == NULL) {
     499      131515 :                 b->new_log_level = MAX_DEBUG_LEVEL;
     500             :         } else {
     501       58120 :                 b->new_log_level = atoi(backend_level);
     502             :         }
     503             : 
     504      189635 :         if (backend_option != NULL) {
     505           0 :                 b->option = strdup(backend_option);
     506           0 :                 if (b->option == NULL) {
     507           0 :                         return;
     508             :                 }
     509             :         }
     510             : }
     511             : 
     512             : /*
     513             :  * parse "backend1[:option1][@loglevel1] backend2[option2][@loglevel2] ... "
     514             :  * and enable/disable backends accordingly
     515             :  */
     516      160578 : static void debug_set_backends(const char *param)
     517      160578 : {
     518      160578 :         size_t str_len = strlen(param);
     519      160578 :         char str[str_len+1];
     520             :         char *tok, *saveptr;
     521             :         unsigned i;
     522             : 
     523             :         /*
     524             :          * initialize new_log_level to detect backends that have been
     525             :          * disabled
     526             :          */
     527      963468 :         for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
     528      802890 :                 SAFE_FREE(debug_backends[i].option);
     529      802890 :                 debug_backends[i].new_log_level = -1;
     530             :         }
     531             : 
     532      164095 :         memcpy(str, param, str_len + 1);
     533             : 
     534      160578 :         tok = strtok_r(str, LIST_SEP, &saveptr);
     535      160578 :         if (tok == NULL) {
     536           0 :                 return;
     537             :         }
     538             : 
     539      486606 :         while (tok != NULL) {
     540      189637 :                 debug_backend_parse_token(tok);
     541      189637 :                 tok = strtok_r(NULL, LIST_SEP, &saveptr);
     542             :         }
     543             : 
     544             :         /*
     545             :          * Let backends react to config changes
     546             :          */
     547      959951 :         for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
     548      802890 :                 struct debug_backend *b = &debug_backends[i];
     549             : 
     550      802890 :                 if (b->reload) {
     551      481734 :                         bool enabled = b->new_log_level > -1;
     552      481734 :                         bool previously_enabled = b->log_level > -1;
     553             : 
     554      481734 :                         b->reload(enabled, previously_enabled, state.prog_name,
     555             :                                   b->option);
     556             :                 }
     557      802890 :                 b->log_level = b->new_log_level;
     558             :         }
     559             : }
     560             : 
     561        6364 : static void debug_backends_log(const char *msg, int msg_level)
     562             : {
     563             :         char msg_no_nl[FORMAT_BUFR_SIZE];
     564             :         size_t i;
     565             :         size_t len;
     566             : 
     567             :         /*
     568             :          * Some backends already add an extra newline, so also provide
     569             :          * a buffer without the newline character.
     570             :          */
     571        6364 :         len = MIN(strlen(msg), FORMAT_BUFR_SIZE - 1);
     572        6364 :         if ((len > 0) && (msg[len - 1] == '\n')) {
     573        6364 :                 len--;
     574             :         }
     575             : 
     576        6364 :         memcpy(msg_no_nl, msg, len);
     577        6364 :         msg_no_nl[len] = '\0';
     578             : 
     579       38184 :         for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
     580       31820 :                 if (msg_level <= debug_backends[i].log_level) {
     581        6787 :                         debug_backends[i].log(msg_level, msg, msg_no_nl);
     582             :                 }
     583             :         }
     584        6364 : }
     585             : 
     586   964271937 : int debuglevel_get_class(size_t idx)
     587             : {
     588   964271937 :         return dbgc_config[idx].loglevel;
     589             : }
     590             : 
     591        1965 : void debuglevel_set_class(size_t idx, int level)
     592             : {
     593        1965 :         dbgc_config[idx].loglevel = level;
     594        1965 : }
     595             : 
     596             : 
     597             : /* -------------------------------------------------------------------------- **
     598             :  * Internal variables.
     599             :  *
     600             :  *  debug_count     - Number of debug messages that have been output.
     601             :  *                    Used to check log size.
     602             :  *
     603             :  *  current_msg_level    - Internal copy of the message debug level.  Written by
     604             :  *                    dbghdr() and read by Debug1().
     605             :  *
     606             :  *  format_bufr     - Used to format debug messages.  The dbgtext() function
     607             :  *                    prints debug messages to a string, and then passes the
     608             :  *                    string to format_debug_text(), which uses format_bufr
     609             :  *                    to build the formatted output.
     610             :  *
     611             :  *  format_pos      - Marks the first free byte of the format_bufr.
     612             :  *
     613             :  *
     614             :  *  log_overflow    - When this variable is true, never attempt to check the
     615             :  *                    size of the log. This is a hack, so that we can write
     616             :  *                    a message using DEBUG, from open_logs() when we
     617             :  *                    are unable to open a new log file for some reason.
     618             :  */
     619             : 
     620             : static int     debug_count    = 0;
     621             : static char format_bufr[FORMAT_BUFR_SIZE];
     622             : static size_t     format_pos     = 0;
     623             : static bool    log_overflow   = false;
     624             : 
     625             : /*
     626             :  * Define all the debug class selection names here. Names *MUST NOT* contain
     627             :  * white space. There must be one name for each DBGC_<class name>, and they
     628             :  * must be in the table in the order of DBGC_<class name>..
     629             :  */
     630             : 
     631             : static char **classname_table = NULL;
     632             : 
     633             : 
     634             : /* -------------------------------------------------------------------------- **
     635             :  * Functions...
     636             :  */
     637             : 
     638             : static void debug_init(void);
     639             : 
     640             : /***************************************************************************
     641             :  Free memory pointed to by global pointers.
     642             : ****************************************************************************/
     643             : 
     644        1019 : void gfree_debugsyms(void)
     645             : {
     646             :         unsigned i;
     647             : 
     648        1019 :         TALLOC_FREE(classname_table);
     649             : 
     650        1019 :         if ( dbgc_config != debug_class_list_initial ) {
     651        1019 :                 TALLOC_FREE( dbgc_config );
     652        1019 :                 dbgc_config = discard_const_p(struct debug_class,
     653             :                                                    debug_class_list_initial);
     654             :         }
     655             : 
     656        1019 :         debug_num_classes = 0;
     657             : 
     658        1019 :         state.initialized = false;
     659             : 
     660        6114 :         for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
     661        5095 :                 SAFE_FREE(debug_backends[i].option);
     662             :         }
     663        1019 : }
     664             : 
     665             : /****************************************************************************
     666             : utility lists registered debug class names's
     667             : ****************************************************************************/
     668             : 
     669           0 : char *debug_list_class_names_and_levels(void)
     670             : {
     671           0 :         char *buf = NULL;
     672             :         size_t i;
     673             :         /* prepare strings */
     674           0 :         for (i = 0; i < debug_num_classes; i++) {
     675           0 :                 buf = talloc_asprintf_append(buf,
     676             :                                              "%s:%d%s",
     677           0 :                                              classname_table[i],
     678           0 :                                              dbgc_config[i].loglevel,
     679           0 :                                              i == (debug_num_classes - 1) ? "\n" : " ");
     680           0 :                 if (buf == NULL) {
     681           0 :                         return NULL;
     682             :                 }
     683             :         }
     684           0 :         return buf;
     685             : }
     686             : 
     687             : /****************************************************************************
     688             :  Utility to translate names to debug class index's (internal version).
     689             : ****************************************************************************/
     690             : 
     691     1173699 : static int debug_lookup_classname_int(const char* classname)
     692             : {
     693             :         size_t i;
     694             : 
     695     1173699 :         if (classname == NULL) {
     696           0 :                 return -1;
     697             :         }
     698             : 
     699    23369551 :         for (i=0; i < debug_num_classes; i++) {
     700    22218763 :                 char *entry = classname_table[i];
     701    22218763 :                 if (entry != NULL && strcmp(classname, entry)==0) {
     702           1 :                         return i;
     703             :                 }
     704             :         }
     705     1150789 :         return -1;
     706             : }
     707             : 
     708             : /****************************************************************************
     709             :  Add a new debug class to the system.
     710             : ****************************************************************************/
     711             : 
     712     1173698 : int debug_add_class(const char *classname)
     713             : {
     714             :         int ndx;
     715     1173698 :         struct debug_class *new_class_list = NULL;
     716             :         char **new_name_list;
     717             :         int default_level;
     718             : 
     719     1173698 :         if (classname == NULL) {
     720           0 :                 return -1;
     721             :         }
     722             : 
     723             :         /* check the init has yet been called */
     724     1173698 :         debug_init();
     725             : 
     726     1173698 :         ndx = debug_lookup_classname_int(classname);
     727     1173698 :         if (ndx >= 0) {
     728           0 :                 return ndx;
     729             :         }
     730     1173698 :         ndx = debug_num_classes;
     731             : 
     732     1173698 :         if (dbgc_config == debug_class_list_initial) {
     733             :                 /* Initial loading... */
     734       29619 :                 new_class_list = NULL;
     735             :         } else {
     736     1143490 :                 new_class_list = dbgc_config;
     737             :         }
     738             : 
     739     1173698 :         default_level = dbgc_config[DBGC_ALL].loglevel;
     740             : 
     741     1173698 :         new_class_list = talloc_realloc(NULL,
     742             :                                         new_class_list,
     743             :                                         struct debug_class,
     744             :                                         ndx + 1);
     745     1173698 :         if (new_class_list == NULL) {
     746           0 :                 return -1;
     747             :         }
     748             : 
     749     1173698 :         dbgc_config = new_class_list;
     750             : 
     751     1173698 :         dbgc_config[ndx] = (struct debug_class) {
     752             :                 .loglevel = default_level,
     753             :                 .fd = -1,
     754             :         };
     755             : 
     756     1173698 :         new_name_list = talloc_realloc(NULL, classname_table, char *, ndx + 1);
     757     1173698 :         if (new_name_list == NULL) {
     758           0 :                 return -1;
     759             :         }
     760     1173698 :         classname_table = new_name_list;
     761             : 
     762     1173698 :         classname_table[ndx] = talloc_strdup(classname_table, classname);
     763     1173698 :         if (classname_table[ndx] == NULL) {
     764           0 :                 return -1;
     765             :         }
     766             : 
     767     1173698 :         debug_num_classes = ndx + 1;
     768             : 
     769     1173698 :         return ndx;
     770             : }
     771             : 
     772             : /****************************************************************************
     773             :  Utility to translate names to debug class index's (public version).
     774             : ****************************************************************************/
     775             : 
     776           1 : static int debug_lookup_classname(const char *classname)
     777             : {
     778             :         int ndx;
     779             : 
     780           1 :         if (classname == NULL || !*classname)
     781           0 :                 return -1;
     782             : 
     783           1 :         ndx = debug_lookup_classname_int(classname);
     784             : 
     785           1 :         if (ndx != -1)
     786           0 :                 return ndx;
     787             : 
     788           0 :         DBG_WARNING("Unknown classname[%s] -> adding it...\n", classname);
     789           0 :         return debug_add_class(classname);
     790             : }
     791             : 
     792             : /****************************************************************************
     793             :  Dump the current registered debug levels.
     794             : ****************************************************************************/
     795             : 
     796      228961 : static void debug_dump_status(int level)
     797             : {
     798             :         size_t q;
     799             : 
     800      228961 :         DEBUG(level, ("INFO: Current debug levels:\n"));
     801     8930696 :         for (q = 0; q < debug_num_classes; q++) {
     802     8705875 :                 const char *classname = classname_table[q];
     803     8705875 :                 DEBUGADD(level, ("  %s: %d\n",
     804             :                                  classname,
     805             :                                  dbgc_config[q].loglevel));
     806             :         }
     807      228961 : }
     808             : 
     809           1 : static bool debug_parse_param(char *param)
     810             : {
     811             :         char *class_name;
     812           1 :         char *class_file = NULL;
     813             :         char *class_level;
     814           1 :         char *saveptr = NULL;
     815             :         int ndx;
     816             : 
     817           1 :         class_name = strtok_r(param, ":", &saveptr);
     818           1 :         if (class_name == NULL) {
     819           0 :                 return false;
     820             :         }
     821             : 
     822           1 :         class_level = strtok_r(NULL, "@\0", &saveptr);
     823           1 :         if (class_level == NULL) {
     824           0 :                 return false;
     825             :         }
     826             : 
     827           1 :         class_file = strtok_r(NULL, "\0", &saveptr);
     828             : 
     829           1 :         ndx = debug_lookup_classname(class_name);
     830           1 :         if (ndx == -1) {
     831           0 :                 return false;
     832             :         }
     833             : 
     834           2 :         dbgc_config[ndx].loglevel = atoi(class_level);
     835             : 
     836           1 :         if (class_file == NULL) {
     837           0 :                 return true;
     838             :         }
     839             : 
     840           0 :         TALLOC_FREE(dbgc_config[ndx].logfile);
     841             : 
     842           0 :         dbgc_config[ndx].logfile = talloc_strdup(NULL, class_file);
     843           0 :         if (dbgc_config[ndx].logfile == NULL) {
     844           0 :                 return false;
     845             :         }
     846           0 :         return true;
     847             : }
     848             : 
     849             : /****************************************************************************
     850             :  Parse the debug levels from smb.conf. Example debug level string:
     851             :   3 tdb:5 printdrivers:7
     852             :  Note: the 1st param has no "name:" preceding it.
     853             : ****************************************************************************/
     854             : 
     855      228961 : bool debug_parse_levels(const char *params_str)
     856      228961 : {
     857      228961 :         size_t str_len = strlen(params_str);
     858      228961 :         char str[str_len+1];
     859             :         char *tok, *saveptr;
     860             :         size_t i;
     861             : 
     862             :         /* Just in case */
     863      228961 :         debug_init();
     864             : 
     865      233101 :         memcpy(str, params_str, str_len+1);
     866             : 
     867      228961 :         tok = strtok_r(str, LIST_SEP, &saveptr);
     868      228961 :         if (tok == NULL) {
     869           0 :                 return true;
     870             :         }
     871             : 
     872             :         /* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10"
     873             :          * v.s. "all:10", this is the traditional way to set DEBUGLEVEL
     874             :          */
     875      228961 :         if (isdigit(tok[0])) {
     876      233101 :                 dbgc_config[DBGC_ALL].loglevel = atoi(tok);
     877      228961 :                 tok = strtok_r(NULL, LIST_SEP, &saveptr);
     878             :         } else {
     879           0 :                 dbgc_config[DBGC_ALL].loglevel = 0;
     880             :         }
     881             : 
     882             :         /* Array is debug_num_classes long */
     883     8705875 :         for (i = DBGC_ALL+1; i < debug_num_classes; i++) {
     884     8476914 :                 dbgc_config[i].loglevel = dbgc_config[DBGC_ALL].loglevel;
     885     8476914 :                 TALLOC_FREE(dbgc_config[i].logfile);
     886             :         }
     887             : 
     888      426856 :         while (tok != NULL) {
     889             :                 bool ok;
     890             : 
     891           1 :                 ok = debug_parse_param(tok);
     892           1 :                 if (!ok) {
     893           0 :                         DEBUG(0,("debug_parse_params: unrecognized debug "
     894             :                                  "class name or format [%s]\n", tok));
     895           0 :                         return false;
     896             :                 }
     897             : 
     898           1 :                 tok = strtok_r(NULL, LIST_SEP, &saveptr);
     899             :         }
     900             : 
     901      228961 :         debug_dump_status(5);
     902             : 
     903      228961 :         return true;
     904             : }
     905             : 
     906             : /* setup for logging of talloc warnings */
     907           0 : static void talloc_log_fn(const char *msg)
     908             : {
     909           0 :         DEBUG(0,("%s", msg));
     910           0 : }
     911             : 
     912       42251 : void debug_setup_talloc_log(void)
     913             : {
     914       42251 :         talloc_set_log_fn(talloc_log_fn);
     915       42251 : }
     916             : 
     917             : 
     918             : /****************************************************************************
     919             : Init debugging (one time stuff)
     920             : ****************************************************************************/
     921             : 
     922     3619734 : static void debug_init(void)
     923             : {
     924             :         size_t i;
     925             : 
     926     3619734 :         if (state.initialized)
     927     3471683 :                 return;
     928             : 
     929       30208 :         state.initialized = true;
     930             : 
     931       30208 :         debug_setup_talloc_log();
     932             : 
     933     1178112 :         for (i = 0; i < ARRAY_SIZE(default_classname_table); i++) {
     934     1147904 :                 debug_add_class(default_classname_table[i]);
     935             :         }
     936       30208 :         dbgc_config[DBGC_ALL].fd = 2;
     937             : 
     938      181248 :         for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
     939      151040 :                 debug_backends[i].log_level = -1;
     940      151040 :                 debug_backends[i].new_log_level = -1;
     941             :         }
     942             : }
     943             : 
     944      160578 : void debug_set_settings(struct debug_settings *settings,
     945             :                         const char *logging_param,
     946             :                         int syslog_level, bool syslog_only)
     947             : {
     948             :         char fake_param[256];
     949      160578 :         size_t len = 0;
     950             : 
     951             :         /*
     952             :          * This forces in some smb.conf derived values into the debug
     953             :          * system. There are no pointers in this structure, so we can
     954             :          * just structure-assign it in
     955             :          */
     956      160578 :         state.settings = *settings;
     957             : 
     958             :         /*
     959             :          * If 'logging' is not set, create backend settings from
     960             :          * deprecated 'syslog' and 'syslog only' parameters
     961             :          */
     962      160578 :         if (logging_param != NULL) {
     963      160578 :                 len = strlen(logging_param);
     964             :         }
     965      160578 :         if (len == 0) {
     966       29061 :                 if (syslog_only) {
     967           2 :                         snprintf(fake_param, sizeof(fake_param),
     968             :                                  "syslog@%d", syslog_level - 1);
     969             :                 } else {
     970       29059 :                         snprintf(fake_param, sizeof(fake_param),
     971             :                                  "syslog@%d file@%d", syslog_level -1,
     972             :                                  MAX_DEBUG_LEVEL);
     973             :                 }
     974             : 
     975       28562 :                 logging_param = fake_param;
     976             :         }
     977             : 
     978      160578 :         debug_set_backends(logging_param);
     979      160578 : }
     980             : 
     981             : /**
     982             :   control the name of the logfile and whether logging will be to stdout, stderr
     983             :   or a file, and set up syslog
     984             : 
     985             :   new_log indicates the destination for the debug log (an enum in
     986             :   order of precedence - once set to DEBUG_FILE, it is not possible to
     987             :   reset to DEBUG_STDOUT for example.  This makes it easy to override
     988             :   for debug to stderr on the command line, as the smb.conf cannot
     989             :   reset it back to file-based logging
     990             : */
     991       24343 : void setup_logging(const char *prog_name, enum debug_logtype new_logtype)
     992             : {
     993       24343 :         debug_init();
     994       24343 :         if (state.logtype < new_logtype) {
     995        1364 :                 state.logtype = new_logtype;
     996             :         }
     997       24343 :         if (prog_name) {
     998       24343 :                 const char *p = strrchr(prog_name, '/');
     999             : 
    1000       24343 :                 if (p) {
    1001         191 :                         prog_name = p + 1;
    1002             :                 }
    1003             : 
    1004       24343 :                 strlcpy(state.prog_name, prog_name, sizeof(state.prog_name));
    1005             :         }
    1006       24343 :         reopen_logs_internal();
    1007       24343 : }
    1008             : 
    1009             : /***************************************************************************
    1010             :  Set the logfile name.
    1011             : **************************************************************************/
    1012             : 
    1013      192086 : void debug_set_logfile(const char *name)
    1014             : {
    1015      192086 :         if (name == NULL || *name == 0) {
    1016             :                 /* this copes with calls when smb.conf is not loaded yet */
    1017          64 :                 return;
    1018             :         }
    1019      192022 :         TALLOC_FREE(dbgc_config[DBGC_ALL].logfile);
    1020      192022 :         dbgc_config[DBGC_ALL].logfile = talloc_strdup(NULL, name);
    1021             : }
    1022             : 
    1023     1531912 : static void debug_close_fd(int fd)
    1024             : {
    1025     1642355 :         if (fd > 2) {
    1026       39850 :                 close(fd);
    1027             :         }
    1028     1531912 : }
    1029             : 
    1030         265 : enum debug_logtype debug_get_log_type(void)
    1031             : {
    1032         265 :         return state.logtype;
    1033             : }
    1034             : 
    1035           4 : bool debug_get_output_is_stderr(void)
    1036             : {
    1037           4 :         return (state.logtype == DEBUG_DEFAULT_STDERR) || (state.logtype == DEBUG_STDERR);
    1038             : }
    1039             : 
    1040         111 : bool debug_get_output_is_stdout(void)
    1041             : {
    1042         111 :         return (state.logtype == DEBUG_DEFAULT_STDOUT) || (state.logtype == DEBUG_STDOUT);
    1043             : }
    1044             : 
    1045          52 : void debug_set_callback(void *private_ptr, debug_callback_fn fn)
    1046             : {
    1047          52 :         debug_init();
    1048          52 :         if (fn) {
    1049          34 :                 state.logtype = DEBUG_CALLBACK;
    1050          34 :                 state.callback_private = private_ptr;
    1051          34 :                 state.callback = fn;
    1052             :         } else {
    1053          18 :                 state.logtype = DEBUG_DEFAULT_STDERR;
    1054          18 :                 state.callback_private = NULL;
    1055          18 :                 state.callback = NULL;
    1056             :         }
    1057          52 : }
    1058             : 
    1059          92 : static void debug_callback_log(const char *msg, int msg_level)
    1060          92 : {
    1061          92 :         size_t msg_len = strlen(msg);
    1062          92 :         char msg_copy[msg_len];
    1063             : 
    1064          92 :         if ((msg_len > 0) && (msg[msg_len-1] == '\n')) {
    1065          92 :                 memcpy(msg_copy, msg, msg_len-1);
    1066          92 :                 msg_copy[msg_len-1] = '\0';
    1067          92 :                 msg = msg_copy;
    1068             :         }
    1069             : 
    1070          92 :         state.callback(state.callback_private, msg_level, msg);
    1071          92 : }
    1072             : 
    1073             : /**************************************************************************
    1074             :  reopen the log files
    1075             :  note that we now do this unconditionally
    1076             :  We attempt to open the new debug fp before closing the old. This means
    1077             :  if we run out of fd's we just keep using the old fd rather than aborting.
    1078             :  Fix from dgibson@linuxcare.com.
    1079             : **************************************************************************/
    1080             : 
    1081     1522629 : static bool reopen_one_log(struct debug_class *config)
    1082             : {
    1083     1522629 :         int old_fd = config->fd;
    1084     1522629 :         const char *logfile = config->logfile;
    1085             :         struct stat st;
    1086             :         int new_fd;
    1087             :         int ret;
    1088             : 
    1089     1522629 :         if (logfile == NULL) {
    1090     1482287 :                 debug_close_fd(old_fd);
    1091     1482287 :                 config->fd = -1;
    1092     1482287 :                 return true;
    1093             :         }
    1094             : 
    1095       40342 :         new_fd = open(logfile, O_WRONLY|O_APPEND|O_CREAT, 0644);
    1096       40342 :         if (new_fd == -1) {
    1097         315 :                 log_overflow = true;
    1098         315 :                 DBG_ERR("Unable to open new log file '%s': %s\n",
    1099             :                         logfile, strerror(errno));
    1100         315 :                 log_overflow = false;
    1101         315 :                 return false;
    1102             :         }
    1103             : 
    1104       40027 :         debug_close_fd(old_fd);
    1105       40027 :         smb_set_close_on_exec(new_fd);
    1106       40027 :         config->fd = new_fd;
    1107             : 
    1108       40027 :         ret = fstat(new_fd, &st);
    1109       40027 :         if (ret != 0) {
    1110           0 :                 log_overflow = true;
    1111           0 :                 DBG_ERR("Unable to fstat() new log file '%s': %s\n",
    1112             :                         logfile, strerror(errno));
    1113           0 :                 log_overflow = false;
    1114           0 :                 return false;
    1115             :         }
    1116             : 
    1117       40027 :         config->ino = st.st_ino;
    1118       40027 :         return true;
    1119             : }
    1120             : 
    1121             : /**
    1122             :   reopen the log file (usually called because the log file name might have changed)
    1123             : */
    1124      160383 : bool reopen_logs_internal(void)
    1125             : {
    1126      160383 :         struct debug_backend *b = NULL;
    1127             :         mode_t oldumask;
    1128      160383 :         int new_fd = 0;
    1129             :         size_t i;
    1130             :         bool ok;
    1131             : 
    1132      160383 :         if (state.reopening_logs) {
    1133           0 :                 return true;
    1134             :         }
    1135             : 
    1136             :         /* Now clear the SIGHUP induced flag */
    1137      160383 :         state.schedule_reopen_logs = false;
    1138             : 
    1139      160383 :         switch (state.logtype) {
    1140           0 :         case DEBUG_CALLBACK:
    1141           0 :                 return true;
    1142       96924 :         case DEBUG_STDOUT:
    1143             :         case DEBUG_DEFAULT_STDOUT:
    1144       97001 :                 debug_close_fd(dbgc_config[DBGC_ALL].fd);
    1145       96924 :                 dbgc_config[DBGC_ALL].fd = 1;
    1146       96924 :                 return true;
    1147             : 
    1148       23117 :         case DEBUG_DEFAULT_STDERR:
    1149             :         case DEBUG_STDERR:
    1150       23511 :                 debug_close_fd(dbgc_config[DBGC_ALL].fd);
    1151       23117 :                 dbgc_config[DBGC_ALL].fd = 2;
    1152       23117 :                 return true;
    1153             : 
    1154       37434 :         case DEBUG_FILE:
    1155       40342 :                 b = debug_find_backend("file");
    1156       40342 :                 assert(b != NULL);
    1157             : 
    1158       40342 :                 b->log_level = MAX_DEBUG_LEVEL;
    1159       40342 :                 break;
    1160             :         }
    1161             : 
    1162       40342 :         oldumask = umask( 022 );
    1163             : 
    1164       40342 :         for (i = DBGC_ALL; i < debug_num_classes; i++) {
    1165       40342 :                 if (dbgc_config[i].logfile != NULL) {
    1166       37434 :                         break;
    1167             :                 }
    1168             :         }
    1169       40342 :         if (i == debug_num_classes) {
    1170           0 :                 return false;
    1171             :         }
    1172             : 
    1173       40342 :         state.reopening_logs = true;
    1174             : 
    1175     1562656 :         for (i = DBGC_ALL; i < debug_num_classes; i++) {
    1176     1522629 :                 ok = reopen_one_log(&dbgc_config[i]);
    1177     1522629 :                 if (!ok) {
    1178         301 :                         break;
    1179             :                 }
    1180             :         }
    1181             : 
    1182             :         /* Fix from klausr@ITAP.Physik.Uni-Stuttgart.De
    1183             :          * to fix problem where smbd's that generate less
    1184             :          * than 100 messages keep growing the log.
    1185             :          */
    1186       40342 :         force_check_log_size();
    1187       40342 :         (void)umask(oldumask);
    1188             : 
    1189             :         /*
    1190             :          * If log file was opened or created successfully, take over stderr to
    1191             :          * catch output into logs.
    1192             :          */
    1193       37434 :         if (new_fd != -1) {
    1194       40342 :                 if (dup2(dbgc_config[DBGC_ALL].fd, 2) == -1) {
    1195             :                         /* Close stderr too, if dup2 can't point it -
    1196             :                            at the logfile.  There really isn't much
    1197             :                            that can be done on such a fundamental
    1198             :                            failure... */
    1199           0 :                         close_low_fd(2);
    1200             :                 }
    1201             :         }
    1202             : 
    1203       40342 :         state.reopening_logs = false;
    1204             : 
    1205       40342 :         return ok;
    1206             : }
    1207             : 
    1208             : /**************************************************************************
    1209             :  Force a check of the log size.
    1210             :  ***************************************************************************/
    1211             : 
    1212    11765014 : void force_check_log_size( void )
    1213             : {
    1214    11765014 :         debug_count = 100;
    1215    11765014 : }
    1216             : 
    1217           0 : _PUBLIC_ void debug_schedule_reopen_logs(void)
    1218             : {
    1219           0 :         state.schedule_reopen_logs = true;
    1220           0 : }
    1221             : 
    1222             : 
    1223             : /***************************************************************************
    1224             :  Check to see if there is any need to check if the logfile has grown too big.
    1225             : **************************************************************************/
    1226             : 
    1227    11725325 : bool need_to_check_log_size(void)
    1228             : {
    1229             :         int maxlog;
    1230             :         size_t i;
    1231             : 
    1232    11725325 :         if (debug_count < 100) {
    1233       33405 :                 return false;
    1234             :         }
    1235             : 
    1236    11691761 :         maxlog = state.settings.max_log_size * 1024;
    1237    11691761 :         if (maxlog <= 0) {
    1238        1880 :                 debug_count = 0;
    1239        1880 :                 return false;
    1240             :         }
    1241             : 
    1242    11689881 :         if (dbgc_config[DBGC_ALL].fd > 2) {
    1243        2460 :                 return true;
    1244             :         }
    1245             : 
    1246   444094344 :         for (i = DBGC_ALL + 1; i < debug_num_classes; i++) {
    1247   432432135 :                 if (dbgc_config[i].fd != -1) {
    1248           0 :                         return true;
    1249             :                 }
    1250             :         }
    1251             : 
    1252    11687355 :         debug_count = 0;
    1253    11687355 :         return false;
    1254             : }
    1255             : 
    1256             : /**************************************************************************
    1257             :  Check to see if the log has grown to be too big.
    1258             :  **************************************************************************/
    1259             : 
    1260        1768 : static void do_one_check_log_size(off_t maxlog, struct debug_class *config)
    1261        1768 : {
    1262        1768 :         char name[strlen(config->logfile) + 5];
    1263             :         struct stat st;
    1264             :         int ret;
    1265        1768 :         bool reopen = false;
    1266             :         bool ok;
    1267             : 
    1268        1768 :         if (maxlog == 0) {
    1269        1768 :                 return;
    1270             :         }
    1271             : 
    1272        1804 :         ret = stat(config->logfile, &st);
    1273        1768 :         if (ret != 0) {
    1274           0 :                 return;
    1275             :         }
    1276        1768 :         if (st.st_size >= maxlog ) {
    1277           0 :                 reopen = true;
    1278             :         }
    1279             : 
    1280        1768 :         if (st.st_ino != config->ino) {
    1281           0 :                 reopen = true;
    1282             :         }
    1283             : 
    1284        1768 :         if (!reopen) {
    1285        1732 :                 return;
    1286             :         }
    1287             : 
    1288             :         /* reopen_logs_internal() modifies *_fd */
    1289           0 :         (void)reopen_logs_internal();
    1290             : 
    1291           0 :         if (config->fd <= 2) {
    1292           0 :                 return;
    1293             :         }
    1294           0 :         ret = fstat(config->fd, &st);
    1295           0 :         if (ret != 0) {
    1296           0 :                 config->ino = (ino_t)0;
    1297           0 :                 return;
    1298             :         }
    1299             : 
    1300           0 :         config->ino = st.st_ino;
    1301             : 
    1302           0 :         if (st.st_size < maxlog) {
    1303           0 :                 return;
    1304             :         }
    1305             : 
    1306           0 :         snprintf(name, sizeof(name), "%s.old", config->logfile);
    1307             : 
    1308           0 :         (void)rename(config->logfile, name);
    1309             : 
    1310           0 :         ok = reopen_logs_internal();
    1311           0 :         if (ok) {
    1312           0 :                 return;
    1313             :         }
    1314             :         /* We failed to reopen a log - continue using the old name. */
    1315           0 :         (void)rename(name, config->logfile);
    1316             : }
    1317             : 
    1318        1768 : static void do_check_log_size(off_t maxlog)
    1319             : {
    1320             :         size_t i;
    1321             : 
    1322       70567 :         for (i = DBGC_ALL; i < debug_num_classes; i++) {
    1323       68799 :                 if (dbgc_config[i].fd == -1) {
    1324       67031 :                         continue;
    1325             :                 }
    1326        1768 :                 if (dbgc_config[i].logfile == NULL) {
    1327           0 :                         continue;
    1328             :                 }
    1329        1768 :                 do_one_check_log_size(maxlog, &dbgc_config[i]);
    1330             :         }
    1331        1768 : }
    1332             : 
    1333        8040 : void check_log_size( void )
    1334             : {
    1335             :         off_t maxlog;
    1336             : 
    1337             :         /*
    1338             :          *  We need to be root to check/change log-file, skip this and let the main
    1339             :          *  loop check do a new check as root.
    1340             :          */
    1341             : 
    1342             : #if _SAMBA_BUILD_ == 3
    1343             :         if (geteuid() != sec_initial_uid())
    1344             : #else
    1345        8040 :         if( geteuid() != 0)
    1346             : #endif
    1347             :         {
    1348             :                 /* We don't check sec_initial_uid() here as it isn't
    1349             :                  * available in common code and we don't generally
    1350             :                  * want to rotate and the possibly lose logs in
    1351             :                  * make test or the build farm */
    1352        1902 :                 return;
    1353             :         }
    1354             : 
    1355        6124 :         if(log_overflow || (!state.schedule_reopen_logs && !need_to_check_log_size())) {
    1356        4298 :                 return;
    1357             :         }
    1358             : 
    1359        1768 :         maxlog = state.settings.max_log_size * 1024;
    1360             : 
    1361        1768 :         if (state.schedule_reopen_logs) {
    1362           0 :                 (void)reopen_logs_internal();
    1363             :         }
    1364             : 
    1365        1768 :         do_check_log_size(maxlog);
    1366             : 
    1367             :         /*
    1368             :          * Here's where we need to panic if dbgc_config[DBGC_ALL].fd == 0 or -1
    1369             :          * (invalid values)
    1370             :          */
    1371             : 
    1372        1768 :         if (dbgc_config[DBGC_ALL].fd <= 0) {
    1373             :                 /* This code should only be reached in very strange
    1374             :                  * circumstances. If we merely fail to open the new log we
    1375             :                  * should stick with the old one. ergo this should only be
    1376             :                  * reached when opening the logs for the first time: at
    1377             :                  * startup or when the log level is increased from zero.
    1378             :                  * -dwg 6 June 2000
    1379             :                  */
    1380           0 :                 int fd = open( "/dev/console", O_WRONLY, 0);
    1381           0 :                 if (fd != -1) {
    1382           0 :                         smb_set_close_on_exec(fd);
    1383           0 :                         dbgc_config[DBGC_ALL].fd = fd;
    1384           0 :                         DBG_ERR("check_log_size: open of debug file %s failed "
    1385             :                                 "- using console.\n",
    1386             :                                 dbgc_config[DBGC_ALL].logfile);
    1387             :                 } else {
    1388             :                         /*
    1389             :                          * We cannot continue without a debug file handle.
    1390             :                          */
    1391           0 :                         abort();
    1392             :                 }
    1393             :         }
    1394        1768 :         debug_count = 0;
    1395             : }
    1396             : 
    1397             : /*************************************************************************
    1398             :  Write an debug message on the debugfile.
    1399             :  This is called by dbghdr() and format_debug_text().
    1400             : ************************************************************************/
    1401             : 
    1402      344550 : static void Debug1(const char *msg)
    1403             : {
    1404      344550 :         int old_errno = errno;
    1405             : 
    1406      344550 :         debug_count++;
    1407             : 
    1408      344550 :         switch(state.logtype) {
    1409          92 :         case DEBUG_CALLBACK:
    1410          92 :                 debug_callback_log(msg, current_msg_level);
    1411          92 :                 break;
    1412      338094 :         case DEBUG_STDOUT:
    1413             :         case DEBUG_STDERR:
    1414             :         case DEBUG_DEFAULT_STDOUT:
    1415             :         case DEBUG_DEFAULT_STDERR:
    1416      338094 :                 if (dbgc_config[DBGC_ALL].fd > 0) {
    1417             :                         ssize_t ret;
    1418             :                         do {
    1419      338094 :                                 ret = write(dbgc_config[DBGC_ALL].fd,
    1420             :                                             msg,
    1421             :                                             strlen(msg));
    1422      338094 :                         } while (ret == -1 && errno == EINTR);
    1423             :                 }
    1424      330951 :                 break;
    1425        6364 :         case DEBUG_FILE:
    1426        6364 :                 debug_backends_log(msg, current_msg_level);
    1427        6364 :                 break;
    1428             :         };
    1429             : 
    1430      344550 :         errno = old_errno;
    1431      344550 : }
    1432             : 
    1433             : /**************************************************************************
    1434             :  Print the buffer content via Debug1(), then reset the buffer.
    1435             :  Input:  none
    1436             :  Output: none
    1437             : ****************************************************************************/
    1438             : 
    1439      334270 : static void bufr_print( void )
    1440             : {
    1441      341454 :         format_bufr[format_pos] = '\0';
    1442      341454 :         (void)Debug1(format_bufr);
    1443      341454 :         format_pos = 0;
    1444      334270 : }
    1445             : 
    1446             : /***************************************************************************
    1447             :  Format the debug message text.
    1448             : 
    1449             :  Input:  msg - Text to be added to the "current" debug message text.
    1450             : 
    1451             :  Output: none.
    1452             : 
    1453             :  Notes:  The purpose of this is two-fold.  First, each call to syslog()
    1454             :          (used by Debug1(), see above) generates a new line of syslog
    1455             :          output.  This is fixed by storing the partial lines until the
    1456             :          newline character is encountered.  Second, printing the debug
    1457             :          message lines when a newline is encountered allows us to add
    1458             :          spaces, thus indenting the body of the message and making it
    1459             :          more readable.
    1460             : **************************************************************************/
    1461             : 
    1462     2192680 : static void format_debug_text( const char *msg )
    1463             : {
    1464             :         size_t i;
    1465     2192680 :         bool timestamp = (state.logtype == DEBUG_FILE && (state.settings.timestamp_logs));
    1466             : 
    1467     2192680 :         debug_init();
    1468             : 
    1469    25699589 :         for( i = 0; msg[i]; i++ ) {
    1470             :                 /* Indent two spaces at each new line. */
    1471    23506909 :                 if(timestamp && 0 == format_pos) {
    1472        3268 :                         format_bufr[0] = format_bufr[1] = ' ';
    1473        3268 :                         format_pos = 2;
    1474             :                 }
    1475             : 
    1476             :                 /* If there's room, copy the character to the format buffer. */
    1477    23506909 :                 if (format_pos < FORMAT_BUFR_SIZE - 1)
    1478    23506909 :                         format_bufr[format_pos++] = msg[i];
    1479             : 
    1480             :                 /* If a newline is encountered, print & restart. */
    1481    23506909 :                 if( '\n' == msg[i] )
    1482      334270 :                         bufr_print();
    1483             : 
    1484             :                 /* If the buffer is full dump it out, reset it, and put out a line
    1485             :                  * continuation indicator.
    1486             :                  */
    1487    23506909 :                 if (format_pos >= FORMAT_BUFR_SIZE - 1) {
    1488           0 :                         bufr_print();
    1489           0 :                         (void)Debug1( " +>\n" );
    1490             :                 }
    1491             :         }
    1492             : 
    1493             :         /* Just to be safe... */
    1494     2192680 :         format_bufr[format_pos] = '\0';
    1495     2192680 : }
    1496             : 
    1497             : /***************************************************************************
    1498             :  Flush debug output, including the format buffer content.
    1499             : 
    1500             :  Input:  none
    1501             :  Output: none
    1502             : ***************************************************************************/
    1503             : 
    1504           0 : void dbgflush( void )
    1505             : {
    1506           0 :         bufr_print();
    1507           0 : }
    1508             : 
    1509     2169816 : bool dbgsetclass(int level, int cls)
    1510             : {
    1511             :         /* Set current_msg_level. */
    1512     2169816 :         current_msg_level = level;
    1513             : 
    1514             :         /* Set current message class */
    1515     2169816 :         current_msg_class = cls;
    1516             : 
    1517     2169816 :         return true;
    1518             : }
    1519             : 
    1520             : /***************************************************************************
    1521             :  Print a Debug Header.
    1522             : 
    1523             :  Input:  level    - Debug level of the message (not the system-wide debug
    1524             :                     level. )
    1525             :          cls      - Debuglevel class of the calling module.
    1526             :          location - Pointer to a string containing the name of the file
    1527             :                     from which this function was called, or an empty string
    1528             :                     if the __FILE__ macro is not implemented.
    1529             :          func     - Pointer to a string containing the name of the function
    1530             :                     from which this function was called, or an empty string
    1531             :                     if the __FUNCTION__ macro is not implemented.
    1532             : 
    1533             :  Output: Always true.  This makes it easy to fudge a call to dbghdr()
    1534             :          in a macro, since the function can be called as part of a test.
    1535             :          Eg: ( (level <= DEBUGLEVEL) && (dbghdr(level,"",line)) )
    1536             : 
    1537             :  Notes:  This function takes care of setting current_msg_level.
    1538             : 
    1539             : ****************************************************************************/
    1540             : 
    1541      103251 : bool dbghdrclass(int level, int cls, const char *location, const char *func)
    1542             : {
    1543             :         /* Ensure we don't lose any real errno value. */
    1544      103251 :         int old_errno = errno;
    1545      103251 :         bool verbose = false;
    1546             :         char header_str[300];
    1547             :         size_t hs_len;
    1548             :         struct timeval tv;
    1549             :         struct timeval_buf tvbuf;
    1550             : 
    1551      103251 :         if( format_pos ) {
    1552             :                 /* This is a fudge.  If there is stuff sitting in the format_bufr, then
    1553             :                  * the *right* thing to do is to call
    1554             :                  *   format_debug_text( "\n" );
    1555             :                  * to write the remainder, and then proceed with the new header.
    1556             :                  * Unfortunately, there are several places in the code at which
    1557             :                  * the DEBUG() macro is used to build partial lines.  That in mind,
    1558             :                  * we'll work under the assumption that an incomplete line indicates
    1559             :                  * that a new header is *not* desired.
    1560             :                  */
    1561        1576 :                 return( true );
    1562             :         }
    1563             : 
    1564      101672 :         dbgsetclass(level, cls);
    1565             : 
    1566             :         /* Don't print a header if we're logging to stdout. */
    1567      101672 :         if ( state.logtype != DEBUG_FILE ) {
    1568       93817 :                 return( true );
    1569             :         }
    1570             : 
    1571             :         /* Print the header if timestamps are turned on.  If parameters are
    1572             :          * not yet loaded, then default to timestamps on.
    1573             :          */
    1574        3096 :         if (!(state.settings.timestamp_logs ||
    1575           0 :               state.settings.debug_prefix_timestamp)) {
    1576           0 :                 return true;
    1577             :         }
    1578             : 
    1579        3096 :         GetTimeOfDay(&tv);
    1580        3096 :         timeval_str_buf(&tv, false, state.settings.debug_hires_timestamp,
    1581             :                         &tvbuf);
    1582             : 
    1583        3096 :         hs_len = snprintf(header_str, sizeof(header_str), "[%s, %2d",
    1584             :                           tvbuf.buf, level);
    1585        3096 :         if (hs_len >= sizeof(header_str)) {
    1586           0 :                 goto full;
    1587             :         }
    1588             : 
    1589        3096 :         if (unlikely(dbgc_config[cls].loglevel >= 10)) {
    1590           0 :                 verbose = true;
    1591             :         }
    1592             : 
    1593        3096 :         if (verbose || state.settings.debug_pid) {
    1594         652 :                 hs_len += snprintf(
    1595             :                         header_str + hs_len, sizeof(header_str) - hs_len,
    1596         652 :                         ", pid=%u", (unsigned int)getpid());
    1597         652 :                 if (hs_len >= sizeof(header_str)) {
    1598           0 :                         goto full;
    1599             :                 }
    1600             :         }
    1601             : 
    1602        3096 :         if (verbose || state.settings.debug_uid) {
    1603           0 :                 hs_len += snprintf(
    1604             :                         header_str + hs_len, sizeof(header_str) - hs_len,
    1605             :                         ", effective(%u, %u), real(%u, %u)",
    1606           0 :                         (unsigned int)geteuid(), (unsigned int)getegid(),
    1607           0 :                         (unsigned int)getuid(), (unsigned int)getgid());
    1608           0 :                 if (hs_len >= sizeof(header_str)) {
    1609           0 :                         goto full;
    1610             :                 }
    1611             :         }
    1612             : 
    1613        3096 :         if ((verbose || state.settings.debug_class)
    1614           0 :             && (cls != DBGC_ALL)) {
    1615           0 :                 hs_len += snprintf(
    1616             :                         header_str + hs_len, sizeof(header_str) - hs_len,
    1617           0 :                         ", class=%s", classname_table[cls]);
    1618           0 :                 if (hs_len >= sizeof(header_str)) {
    1619           0 :                         goto full;
    1620             :                 }
    1621             :         }
    1622             : 
    1623             :         /*
    1624             :          * No +=, see man man strlcat
    1625             :          */
    1626        3096 :         hs_len = strlcat(header_str, "] ", sizeof(header_str));
    1627        3096 :         if (hs_len >= sizeof(header_str)) {
    1628           0 :                 goto full;
    1629             :         }
    1630             : 
    1631        3096 :         if (!state.settings.debug_prefix_timestamp) {
    1632        3133 :                 hs_len += snprintf(
    1633             :                         header_str + hs_len, sizeof(header_str) - hs_len,
    1634             :                         "%s(%s)\n", location, func);
    1635        3059 :                 if (hs_len >= sizeof(header_str)) {
    1636           0 :                         goto full;
    1637             :                 }
    1638             :         }
    1639             : 
    1640        5816 : full:
    1641        3096 :         (void)Debug1(header_str);
    1642             : 
    1643        3096 :         errno = old_errno;
    1644        3096 :         return( true );
    1645             : }
    1646             : 
    1647             : /***************************************************************************
    1648             :  Add text to the body of the "current" debug message via the format buffer.
    1649             : 
    1650             :   Input:  format_str  - Format string, as used in printf(), et. al.
    1651             :           ...         - Variable argument list.
    1652             : 
    1653             :   ..or..  va_alist    - Old style variable parameter list starting point.
    1654             : 
    1655             :   Output: Always true.  See dbghdr() for more info, though this is not
    1656             :           likely to be used in the same way.
    1657             : 
    1658             : ***************************************************************************/
    1659             : 
    1660             : static inline bool __dbgtext_va(const char *format_str, va_list ap) PRINTF_ATTRIBUTE(1,0);
    1661     2192680 : static inline bool __dbgtext_va(const char *format_str, va_list ap)
    1662             : {
    1663     2192680 :         char *msgbuf = NULL;
    1664     2192680 :         bool ret = true;
    1665             :         int res;
    1666             : 
    1667     2192680 :         res = vasprintf(&msgbuf, format_str, ap);
    1668     2192680 :         if (res != -1) {
    1669     2192680 :                 format_debug_text(msgbuf);
    1670             :         } else {
    1671           0 :                 ret = false;
    1672             :         }
    1673     2192680 :         SAFE_FREE(msgbuf);
    1674     2192680 :         return ret;
    1675             : }
    1676             : 
    1677           0 : bool dbgtext_va(const char *format_str, va_list ap)
    1678             : {
    1679           0 :         return __dbgtext_va(format_str, ap);
    1680             : }
    1681             : 
    1682     2192680 : bool dbgtext(const char *format_str, ... )
    1683             : {
    1684             :         va_list ap;
    1685             :         bool ret;
    1686             : 
    1687     2192680 :         va_start(ap, format_str);
    1688     2192680 :         ret = __dbgtext_va(format_str, ap);
    1689     2192680 :         va_end(ap);
    1690             : 
    1691     2192680 :         return ret;
    1692             : }

Generated by: LCOV version 1.13