Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/lib/util/debug.c

    r860 r988  
    2020*/
    2121
    22 #include "includes.h"
     22#include "replace.h"
     23#include <talloc.h>
    2324#include "system/filesys.h"
    2425#include "system/syslog.h"
    25 #include "lib/util/time.h"
     26#include "system/locale.h"
     27#include "time_basic.h"
     28#include "close_low_fd.h"
     29#include "memory.h"
     30#include "samba_util.h" /* LIST_SEP */
     31#include "debug.h"
    2632
    2733/* define what facility to use for syslog */
     
    3238/* -------------------------------------------------------------------------- **
    3339 * Defines...
    34  *
    35  *  FORMAT_BUFR_MAX - Index of the last byte of the format buffer;
    36  *                    format_bufr[FORMAT_BUFR_MAX] should always be reserved
    37  *                    for a terminating null byte.
    3840 */
    3941
     42/*
     43 * format_bufr[FORMAT_BUFR_SIZE - 1] should always be reserved
     44 * for a terminating null byte.
     45 */
    4046#define FORMAT_BUFR_SIZE 1024
    41 #define FORMAT_BUFR_MAX (FORMAT_BUFR_SIZE - 1)
    4247
    4348/* -------------------------------------------------------------------------- **
     
    8994        struct debug_settings settings;
    9095        char *debugf;
     96        debug_callback_fn callback;
     97        void *callback_private;
    9198} state = {
    9299        .settings = {
    93100                .timestamp_logs = true
    94         }
     101        },
     102        .fd = 2 /* stderr by default */
    95103};
     104
     105#if defined(WITH_SYSLOG) || defined(HAVE_LIBSYSTEMD_JOURNAL)
     106static int debug_level_to_priority(int level)
     107{
     108        /*
     109         * map debug levels to syslog() priorities
     110         */
     111        static const int priority_map[] = {
     112                LOG_ERR,     /* 0 */
     113                LOG_WARNING, /* 1 */
     114                LOG_NOTICE,  /* 2 */
     115                LOG_NOTICE,  /* 3 */
     116                LOG_NOTICE,  /* 4 */
     117                LOG_NOTICE,  /* 5 */
     118                LOG_INFO,    /* 6 */
     119                LOG_INFO,    /* 7 */
     120                LOG_INFO,    /* 8 */
     121                LOG_INFO,    /* 9 */
     122        };
     123        int priority;
     124
     125        if( level >= ARRAY_SIZE(priority_map) || level < 0)
     126                priority = LOG_DEBUG;
     127        else
     128                priority = priority_map[level];
     129
     130        return priority;
     131}
     132#endif
     133
     134/* -------------------------------------------------------------------------- **
     135 * Debug backends. When logging to DEBUG_FILE, send the log entries to
     136 * all active backends.
     137 */
     138
     139static void debug_file_log(int msg_level,
     140                           const char *msg, const char *msg_no_nl)
     141{
     142        check_log_size();
     143        write(state.fd, msg, strlen(msg));
     144}
     145
     146#ifdef WITH_SYSLOG
     147static void debug_syslog_reload(bool enabled, bool previously_enabled,
     148                                const char *prog_name)
     149{
     150        if (enabled && !previously_enabled) {
     151#ifdef LOG_DAEMON
     152                openlog(prog_name, LOG_PID, SYSLOG_FACILITY);
     153#else
     154                /* for old systems that have no facility codes. */
     155                openlog(prog_name, LOG_PID );
     156#endif
     157                return;
     158        }
     159
     160        if (!enabled && previously_enabled) {
     161                closelog();
     162        }
     163}
     164
     165static void debug_syslog_log(int msg_level,
     166                             const char *msg, const char *msg_no_nl)
     167{
     168        int priority;
     169
     170        priority = debug_level_to_priority(msg_level);
     171
     172        /*
     173         * Specify the facility to interoperate with other syslog
     174         * callers (vfs_full_audit for example).
     175         */
     176        priority |= SYSLOG_FACILITY;
     177
     178        syslog(priority, "%s", msg);
     179}
     180#endif /* WITH_SYSLOG */
     181
     182#ifdef HAVE_LIBSYSTEMD_JOURNAL
     183#include <systemd/sd-journal.h>
     184static void debug_systemd_log(int msg_level,
     185                              const char *msg, const char *msg_no_nl)
     186{
     187        sd_journal_send("MESSAGE=%s", msg_no_nl,
     188                        "PRIORITY=%d", debug_level_to_priority(msg_level),
     189                        "LEVEL=%d", msg_level,
     190                        NULL);
     191}
     192#endif
     193
     194#ifdef HAVE_LTTNG_TRACEF
     195#include <lttng/tracef.h>
     196static void debug_lttng_log(int msg_level,
     197                            const char *msg, const char *msg_no_nl)
     198{
     199        tracef(msg_no_nl);
     200}
     201#endif /* WITH_LTTNG_TRACEF */
     202
     203#ifdef HAVE_GPFS
     204#include "gpfswrap.h"
     205static void debug_gpfs_reload(bool enabled, bool previously_enabled,
     206                              const char *prog_name)
     207{
     208        gpfswrap_init();
     209
     210        if (enabled && !previously_enabled) {
     211                gpfswrap_init_trace();
     212                return;
     213        }
     214
     215        if (!enabled && previously_enabled) {
     216                gpfswrap_fini_trace();
     217                return;
     218        }
     219
     220        if (enabled) {
     221                /*
     222                 * Trigger GPFS library to adjust state if necessary.
     223                 */
     224                gpfswrap_query_trace();
     225        }
     226}
     227
     228static void debug_gpfs_log(int msg_level,
     229                           const char *msg, const char *msg_no_nl)
     230{
     231        gpfswrap_add_trace(msg_level, msg_no_nl);
     232}
     233#endif /* HAVE_GPFS */
     234
     235static struct debug_backend {
     236        const char *name;
     237        int log_level;
     238        int new_log_level;
     239        void (*reload)(bool enabled, bool prev_enabled, const char *prog_name);
     240        void (*log)(int msg_level, const char *msg, const char *msg_no_nl);
     241} debug_backends[] = {
     242        {
     243                .name = "file",
     244                .log = debug_file_log,
     245        },
     246#ifdef WITH_SYSLOG
     247        {
     248                .name = "syslog",
     249                .reload = debug_syslog_reload,
     250                .log = debug_syslog_log,
     251        },
     252#endif
     253
     254#ifdef HAVE_LIBSYSTEMD_JOURNAL
     255        {
     256                .name = "systemd",
     257                .log = debug_systemd_log,
     258        },
     259#endif
     260
     261#ifdef HAVE_LTTNG_TRACEF
     262        {
     263                .name = "lttng",
     264                .log = debug_lttng_log,
     265        },
     266#endif
     267
     268#ifdef HAVE_GPFS
     269        {
     270                .name = "gpfs",
     271                .reload = debug_gpfs_reload,
     272                .log = debug_gpfs_log,
     273        },
     274#endif
     275};
     276
     277static struct debug_backend *debug_find_backend(const char *name)
     278{
     279        int i;
     280
     281        for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
     282                if (strcmp(name, debug_backends[i].name) == 0) {
     283                        return &debug_backends[i];
     284                }
     285        }
     286
     287        return NULL;
     288}
     289
     290/*
     291 * parse "backend[:option][@loglevel]
     292 */
     293static void debug_backend_parse_token(char *tok)
     294{
     295        char *backend_name_option, *backend_name,*backend_level, *saveptr;
     296        struct debug_backend *b;
     297
     298        /*
     299         * First parse into backend[:option] and loglevel
     300         */
     301        backend_name_option = strtok_r(tok, "@\0", &saveptr);
     302        if (backend_name_option == NULL) {
     303                return;
     304        }
     305
     306        backend_level = strtok_r(NULL, "\0", &saveptr);
     307
     308        /*
     309         * Now parse backend[:option]
     310         */
     311        backend_name = strtok_r(backend_name_option, ":\0", &saveptr);
     312        if (backend_name == NULL) {
     313                return;
     314        }
     315
     316        /*
     317         * No backend is using the option yet.
     318         */
     319#if 0
     320        backend_option = strtok_r(NULL, "\0", &saveptr);
     321#endif
     322
     323        /*
     324         * Find and update backend
     325         */
     326        b = debug_find_backend(backend_name);
     327        if (b == NULL) {
     328                return;
     329        }
     330
     331        if (backend_level == NULL) {
     332                b->new_log_level = MAX_DEBUG_LEVEL;
     333        } else {
     334                b->new_log_level = atoi(backend_level);
     335        }
     336}
     337
     338/*
     339 * parse "backend1[:option1][@loglevel1] backend2[option2][@loglevel2] ... "
     340 * and enable/disable backends accordingly
     341 */
     342static void debug_set_backends(const char *param)
     343{
     344        size_t str_len = strlen(param);
     345        char str[str_len+1];
     346        char *tok, *saveptr;
     347        int i;
     348
     349        /*
     350         * initialize new_log_level to detect backends that have been
     351         * disabled
     352         */
     353        for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
     354                debug_backends[i].new_log_level = -1;
     355        }
     356
     357        memcpy(str, param, str_len + 1);
     358
     359        tok = strtok_r(str, LIST_SEP, &saveptr);
     360        if (tok == NULL) {
     361                return;
     362        }
     363
     364        while (tok != NULL) {
     365                debug_backend_parse_token(tok);
     366                tok = strtok_r(NULL, LIST_SEP, &saveptr);
     367        }
     368
     369        /*
     370         * Let backends react to config changes
     371         */
     372        for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
     373                struct debug_backend *b = &debug_backends[i];
     374
     375                if (b->reload) {
     376                        bool enabled = b->new_log_level > -1;
     377                        bool previously_enabled = b->log_level > -1;
     378
     379                        b->reload(enabled, previously_enabled, state.prog_name);
     380                }
     381                b->log_level = b->new_log_level;
     382        }
     383}
     384
     385static void debug_backends_log(const char *msg, int msg_level)
     386{
     387        char msg_no_nl[FORMAT_BUFR_SIZE];
     388        int i, len;
     389
     390        /*
     391         * Some backends already add an extra newline, so also provide
     392         * a buffer without the newline character.
     393         */
     394        len = MIN(strlen(msg), FORMAT_BUFR_SIZE - 1);
     395        if (msg[len - 1] == '\n') {
     396                len--;
     397        }
     398
     399        memcpy(msg_no_nl, msg, len);
     400        msg_no_nl[len] = '\0';
     401
     402        for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
     403                if (msg_level <= debug_backends[i].log_level) {
     404                        debug_backends[i].log(msg_level, msg, msg_no_nl);
     405                }
     406        }
     407}
    96408
    97409/* -------------------------------------------------------------------------- **
    98410 * External variables.
    99  *
    100  *  debugf        - Debug file name.
    101  *  DEBUGLEVEL    - System-wide debug message limit.  Messages with message-
    102  *                  levels higher than DEBUGLEVEL will not be processed.
    103411 */
    104412
     
    109417bool    override_logfile;
    110418
     419static const char *default_classname_table[] = {
     420        [DBGC_ALL] =            "all",
     421        [DBGC_TDB] =            "tdb",
     422        [DBGC_PRINTDRIVERS] =   "printdrivers",
     423        [DBGC_LANMAN] =         "lanman",
     424        [DBGC_SMB] =            "smb",
     425        [DBGC_RPC_PARSE] =      "rpc_parse",
     426        [DBGC_RPC_SRV] =        "rpc_srv",
     427        [DBGC_RPC_CLI] =        "rpc_cli",
     428        [DBGC_PASSDB] =         "passdb",
     429        [DBGC_SAM] =            "sam",
     430        [DBGC_AUTH] =           "auth",
     431        [DBGC_WINBIND] =        "winbind",
     432        [DBGC_VFS] =            "vfs",
     433        [DBGC_IDMAP] =          "idmap",
     434        [DBGC_QUOTA] =          "quota",
     435        [DBGC_ACLS] =           "acls",
     436        [DBGC_LOCKING] =        "locking",
     437        [DBGC_MSDFS] =          "msdfs",
     438        [DBGC_DMAPI] =          "dmapi",
     439        [DBGC_REGISTRY] =       "registry",
     440        [DBGC_SCAVENGER] =      "scavenger",
     441        [DBGC_DNS] =            "dns",
     442        [DBGC_LDB] =            "ldb",
     443        [DBGC_TEVENT] =         "tevent",
     444};
     445
    111446/*
    112447 * This is to allow reading of DEBUGLEVEL_CLASS before the debug
    113448 * system has been initialized.
    114449 */
    115 static const int debug_class_list_initial[DBGC_MAX_FIXED + 1];
     450static const int debug_class_list_initial[ARRAY_SIZE(default_classname_table)];
    116451
    117452static int debug_num_classes = 0;
     
    125460 *                    Used to check log size.
    126461 *
    127  *  syslog_level    - Internal copy of the message debug level.  Written by
     462 *  current_msg_level    - Internal copy of the message debug level.  Written by
    128463 *                    dbghdr() and read by Debug1().
    129464 *
     
    143478
    144479static int     debug_count    = 0;
    145 #ifdef WITH_SYSLOG
    146 static int     syslog_level   = 0;
    147 #endif
    148 static char *format_bufr = NULL;
     480static int     current_msg_level   = 0;
     481static char format_bufr[FORMAT_BUFR_SIZE];
    149482static size_t     format_pos     = 0;
    150483static bool    log_overflow   = false;
     
    155488 * must be in the table in the order of DBGC_<class name>..
    156489 */
    157 static const char *default_classname_table[] = {
    158         "all",               /* DBGC_ALL; index refs traditional DEBUGLEVEL */
    159         "tdb",               /* DBGC_TDB          */
    160         "printdrivers",      /* DBGC_PRINTDRIVERS */
    161         "lanman",            /* DBGC_LANMAN       */
    162         "smb",               /* DBGC_SMB          */
    163         "rpc_parse",         /* DBGC_RPC_PARSE    */
    164         "rpc_srv",           /* DBGC_RPC_SRV      */
    165         "rpc_cli",           /* DBGC_RPC_CLI      */
    166         "passdb",            /* DBGC_PASSDB       */
    167         "sam",               /* DBGC_SAM          */
    168         "auth",              /* DBGC_AUTH         */
    169         "winbind",           /* DBGC_WINBIND      */
    170         "vfs",               /* DBGC_VFS          */
    171         "idmap",             /* DBGC_IDMAP        */
    172         "quota",             /* DBGC_QUOTA        */
    173         "acls",              /* DBGC_ACLS         */
    174         "locking",           /* DBGC_LOCKING      */
    175         "msdfs",             /* DBGC_MSDFS        */
    176         "dmapi",             /* DBGC_DMAPI        */
    177         "registry",          /* DBGC_REGISTRY     */
    178         NULL
    179 };
    180490
    181491static char **classname_table = NULL;
     
    200510                DEBUGLEVEL_CLASS = discard_const_p(int, debug_class_list_initial);
    201511        }
    202 
    203         TALLOC_FREE(format_bufr);
    204512
    205513        debug_num_classes = 0;
     
    218526        /* prepare strings */
    219527        for (i = 0; i < debug_num_classes; i++) {
    220                 buf = talloc_asprintf_append(buf, 
     528                buf = talloc_asprintf_append(buf,
    221529                                             "%s:%d%s",
    222530                                             classname_table[i],
     
    303611****************************************************************************/
    304612
    305 int debug_lookup_classname(const char *classname)
     613static int debug_lookup_classname(const char *classname)
    306614{
    307615        int ndx;
     
    337645}
    338646
    339 /****************************************************************************
    340  parse the debug levels from smbcontrol. Example debug level parameter:
    341  printdrivers:7
    342 ****************************************************************************/
    343 
    344 static bool debug_parse_params(char **params)
    345 {
    346         int   i, ndx;
     647static bool debug_parse_param(char *param)
     648{
    347649        char *class_name;
    348650        char *class_level;
    349 
    350         if (!params)
     651        char *saveptr;
     652        int ndx;
     653
     654        class_name = strtok_r(param, ":", &saveptr);
     655        if (class_name == NULL) {
    351656                return false;
    352 
    353         /* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10"
    354          * v.s. "all:10", this is the traditional way to set DEBUGLEVEL
    355          */
    356         if (isdigit((int)params[0][0])) {
    357                 DEBUGLEVEL_CLASS[DBGC_ALL] = atoi(params[0]);
    358                 i = 1; /* start processing at the next params */
    359         } else {
    360                 DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
    361                 i = 0; /* DBGC_ALL not specified OR class name was included */
    362         }
    363 
    364         /* Array is debug_num_classes long */
    365         for (ndx = DBGC_ALL; ndx < debug_num_classes; ndx++) {
    366                 DEBUGLEVEL_CLASS[ndx] = DEBUGLEVEL_CLASS[DBGC_ALL];
    367         }
    368                
    369         /* Fill in new debug class levels */
    370         for (; i < debug_num_classes && params[i]; i++) {
    371                 char *saveptr;
    372                 if ((class_name = strtok_r(params[i],":", &saveptr)) &&
    373                         (class_level = strtok_r(NULL, "\0", &saveptr)) &&
    374             ((ndx = debug_lookup_classname(class_name)) != -1)) {
    375                                 DEBUGLEVEL_CLASS[ndx] = atoi(class_level);
    376                 } else {
    377                         DEBUG(0,("debug_parse_params: unrecognized debug class name or format [%s]\n", params[i]));
    378                         return false;
    379                 }
    380         }
     657        }
     658
     659        class_level = strtok_r(NULL, "\0", &saveptr);
     660        if (class_level == NULL) {
     661                return false;
     662        }
     663
     664        ndx = debug_lookup_classname(class_name);
     665        if (ndx == -1) {
     666                return false;
     667        }
     668
     669        DEBUGLEVEL_CLASS[ndx] = atoi(class_level);
    381670
    382671        return true;
     
    391680bool debug_parse_levels(const char *params_str)
    392681{
    393         char **params;
     682        size_t str_len = strlen(params_str);
     683        char str[str_len+1];
     684        char *tok, *saveptr;
     685        int i;
    394686
    395687        /* Just in case */
    396688        debug_init();
    397689
    398         params = str_list_make(NULL, params_str, NULL);
    399 
    400         if (debug_parse_params(params)) {
    401                 debug_dump_status(5);
    402                 TALLOC_FREE(params);
     690        memcpy(str, params_str, str_len+1);
     691
     692        tok = strtok_r(str, LIST_SEP, &saveptr);
     693        if (tok == NULL) {
    403694                return true;
     695        }
     696
     697        /* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10"
     698         * v.s. "all:10", this is the traditional way to set DEBUGLEVEL
     699         */
     700        if (isdigit(tok[0])) {
     701                DEBUGLEVEL_CLASS[DBGC_ALL] = atoi(tok);
     702                tok = strtok_r(NULL, LIST_SEP, &saveptr);
    404703        } else {
    405                 TALLOC_FREE(params);
    406                 return false;
    407         }
     704                DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
     705        }
     706
     707        /* Array is debug_num_classes long */
     708        for (i = DBGC_ALL+1; i < debug_num_classes; i++) {
     709                DEBUGLEVEL_CLASS[i] = DEBUGLEVEL_CLASS[DBGC_ALL];
     710        }
     711
     712        while (tok != NULL) {
     713                bool ok;
     714
     715                ok = debug_parse_param(tok);
     716                if (!ok) {
     717                        DEBUG(0,("debug_parse_params: unrecognized debug "
     718                                 "class name or format [%s]\n", tok));
     719                        return false;
     720                }
     721
     722                tok = strtok_r(NULL, LIST_SEP, &saveptr);
     723        }
     724
     725        debug_dump_status(5);
     726
     727        return true;
    408728}
    409729
     
    426746static void debug_init(void)
    427747{
    428         const char **p;
     748        size_t i;
    429749
    430750        if (state.initialized)
     
    435755        debug_setup_talloc_log();
    436756
    437         for(p = default_classname_table; *p; p++) {
    438                 debug_add_class(*p);
    439         }
    440         format_bufr = talloc_array(NULL, char, FORMAT_BUFR_SIZE);
    441         if (!format_bufr) {
    442                 smb_panic("debug_init: unable to create buffer");
    443         }
    444 }
    445 
    446 /* This forces in some smb.conf derived values into the debug system.
    447  * There are no pointers in this structure, so we can just
    448  * structure-assign it in */
    449 void debug_set_settings(struct debug_settings *settings)
    450 {
     757        for (i = 0; i < ARRAY_SIZE(default_classname_table); i++) {
     758                debug_add_class(default_classname_table[i]);
     759        }
     760
     761        for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
     762                debug_backends[i].log_level = -1;
     763                debug_backends[i].new_log_level = -1;
     764        }
     765}
     766
     767void debug_set_settings(struct debug_settings *settings,
     768                        const char *logging_param,
     769                        int syslog_level, bool syslog_only)
     770{
     771        char fake_param[256];
     772        size_t len = 0;
     773
     774        /*
     775         * This forces in some smb.conf derived values into the debug
     776         * system. There are no pointers in this structure, so we can
     777         * just structure-assign it in
     778         */
    451779        state.settings = *settings;
     780
     781        /*
     782         * If 'logging' is not set, create backend settings from
     783         * deprecated 'syslog' and 'syslog only' parameters
     784         */
     785        if (logging_param != NULL) {
     786                len = strlen(logging_param);
     787        }
     788        if (len == 0) {
     789                if (syslog_only) {
     790                        snprintf(fake_param, sizeof(fake_param),
     791                                 "syslog@%d", syslog_level - 1);
     792                } else {
     793                        snprintf(fake_param, sizeof(fake_param),
     794                                 "syslog@%d file@%d", syslog_level -1,
     795                                 MAX_DEBUG_LEVEL);
     796                }
     797
     798                logging_param = fake_param;
     799        }
     800
     801        debug_set_backends(logging_param);
    452802}
    453803
     
    469819        }
    470820        if (prog_name) {
     821                const char *p = strrchr(prog_name, '/');
     822
     823                if (p) {
     824                        prog_name = p + 1;
     825                }
     826
    471827                state.prog_name = prog_name;
    472828        }
    473829        reopen_logs_internal();
    474 
    475         if (state.logtype == DEBUG_FILE) {
    476 #ifdef WITH_SYSLOG
    477                 const char *p = strrchr_m( prog_name,'/' );
    478                 if (p)
    479                         prog_name = p + 1;
    480 #ifdef LOG_DAEMON
    481                 openlog( prog_name, LOG_PID, SYSLOG_FACILITY );
    482 #else
    483                 /* for old systems that have no facility codes. */
    484                 openlog( prog_name, LOG_PID );
    485 #endif
    486 #endif
    487         }
    488830}
    489831
     
    512854{
    513855        return (state.logtype == DEBUG_DEFAULT_STDERR) || (state.logtype == DEBUG_STDERR);
     856}
     857
     858bool debug_get_output_is_stdout(void)
     859{
     860        return (state.logtype == DEBUG_DEFAULT_STDOUT) || (state.logtype == DEBUG_STDOUT);
     861}
     862
     863void debug_set_callback(void *private_ptr, debug_callback_fn fn)
     864{
     865        debug_init();
     866        if (fn) {
     867                state.logtype = DEBUG_CALLBACK;
     868                state.callback_private = private_ptr;
     869                state.callback = fn;
     870        } else {
     871                state.logtype = DEBUG_DEFAULT_STDERR;
     872                state.callback_private = NULL;
     873                state.callback = NULL;
     874        }
     875}
     876
     877static void debug_callback_log(const char *msg, int msg_level)
     878{
     879        size_t msg_len = strlen(msg);
     880        char msg_copy[msg_len];
     881
     882        if ((msg_len > 0) && (msg[msg_len-1] == '\n')) {
     883                memcpy(msg_copy, msg, msg_len-1);
     884                msg_copy[msg_len-1] = '\0';
     885                msg = msg_copy;
     886        }
     887
     888        state.callback(state.callback_private, msg_level, msg);
    514889}
    515890
     
    532907        bool ret = true;
    533908
    534         char *fname = NULL;
    535909        if (state.reopening_logs) {
    536910                return true;
     
    541915
    542916        switch (state.logtype) {
     917        case DEBUG_CALLBACK:
     918                return true;
    543919        case DEBUG_STDOUT:
     920        case DEBUG_DEFAULT_STDOUT:
    544921                debug_close_fd(state.fd);
    545922                state.fd = 1;
     
    558935        oldumask = umask( 022 );
    559936
    560         fname = state.debugf;
    561         if (!fname) {
     937        if (!state.debugf) {
    562938                return false;
    563939        }
     
    573949                ret = false;
    574950        } else {
     951                smb_set_close_on_exec(new_fd);
    575952                old_fd = state.fd;
    576953                state.fd = new_fd;
     
    586963
    587964        /* Take over stderr to catch output into logs */
    588         if (state.fd > 0 && dup2(state.fd, 2) == -1) {
    589                 close_low_fds(true); /* Close stderr too, if dup2 can't point it
    590                                         at the logfile */
     965        if (state.fd > 0) {
     966                if (dup2(state.fd, 2) == -1) {
     967                        /* Close stderr too, if dup2 can't point it -
     968                           at the logfile.  There really isn't much
     969                           that can be done on such a fundamental
     970                           failure... */
     971                        close_low_fd(2);
     972                }
    591973        }
    592974
     
    6441026         */
    6451027
    646         if( geteuid() != 0) {
     1028#if _SAMBA_BUILD_ == 3
     1029        if (geteuid() != sec_initial_uid())
     1030#else
     1031        if( geteuid() != 0)
     1032#endif
     1033        {
    6471034                /* We don't check sec_initial_uid() here as it isn't
    6481035                 * available in common code and we don't generally
     
    6581045        maxlog = state.settings.max_log_size * 1024;
    6591046
    660         if (state.schedule_reopen_logs ||
    661            (fstat(state.fd, &st) == 0
     1047        if (state.schedule_reopen_logs) {
     1048            (void)reopen_logs_internal();
     1049        }
     1050
     1051        if (maxlog && (fstat(state.fd, &st) == 0
    6621052            && st.st_size > maxlog )) {
    6631053                (void)reopen_logs_internal();
    664                 if (state.fd > 0 && fstat(state.fd, &st) == 0) {
    665                         if (st.st_size > maxlog) {
    666                                 char *name = NULL;
    667 
    668                                 if (asprintf(&name, "%s.old", state.debugf ) < 0) {
    669                                         return;
    670                                 }
    671                                 (void)rename(state.debugf, name);
    672 
    673                                 if (!reopen_logs_internal()) {
    674                                         /* We failed to reopen a log - continue using the old name. */
    675                                         (void)rename(name, state.debugf);
    676                                 }
    677                                 SAFE_FREE(name);
     1054                if (state.fd > 2 && (fstat(state.fd, &st) == 0
     1055                                     && st.st_size > maxlog)) {
     1056                        char name[strlen(state.debugf) + 5];
     1057
     1058                        snprintf(name, sizeof(name), "%s.old", state.debugf);
     1059
     1060                        (void)rename(state.debugf, name);
     1061
     1062                        if (!reopen_logs_internal()) {
     1063                                /* We failed to reopen a log - continue using the old name. */
     1064                                (void)rename(name, state.debugf);
    6781065                        }
    6791066                }
     
    6941081                int fd = open( "/dev/console", O_WRONLY, 0);
    6951082                if (fd != -1) {
     1083                        smb_set_close_on_exec(fd);
    6961084                        state.fd = fd;
    6971085                        DEBUG(0,("check_log_size: open of debug file %s failed - using console.\n",
     
    7121100************************************************************************/
    7131101
    714  int Debug1( const char *format_str, ... )
    715 {
    716         va_list ap;
     1102static void Debug1(const char *msg)
     1103{
    7171104        int old_errno = errno;
    7181105
    7191106        debug_count++;
    7201107
    721         if ( state.logtype != DEBUG_FILE ) {
    722                 va_start( ap, format_str );
    723                 if (state.fd > 0)
    724                         (void)vdprintf( state.fd, format_str, ap );
    725                 va_end( ap );
    726                 errno = old_errno;
    727                 goto done;
    728         }
    729 
    730 #ifdef WITH_SYSLOG
    731         if( !state.settings.syslog_only)
    732 #endif
    733         {
    734                 if( state.fd <= 0 ) {
    735                         mode_t oldumask = umask( 022 );
    736                         int fd = open( state.debugf, O_WRONLY|O_APPEND|O_CREAT, 0644 );
    737                         (void)umask( oldumask );
    738                         if(fd == -1) {
    739                                 errno = old_errno;
    740                                 goto done;
    741                         }
    742                         state.fd = fd;
    743                 }
    744         }
    745 
    746 #ifdef WITH_SYSLOG
    747         if( syslog_level < state.settings.syslog ) {
    748                 /* map debug levels to syslog() priorities
    749                  * note that not all DEBUG(0, ...) calls are
    750                  * necessarily errors */
    751                 static const int priority_map[4] = {
    752                         LOG_ERR,     /* 0 */
    753                         LOG_WARNING, /* 1 */
    754                         LOG_NOTICE,  /* 2 */
    755                         LOG_INFO,    /* 3 */
    756                 };
    757                 int     priority;
    758                 char *msgbuf = NULL;
    759                 int ret;
    760 
    761                 if( syslog_level >= ARRAY_SIZE(priority_map) || syslog_level < 0)
    762                         priority = LOG_DEBUG;
    763                 else
    764                         priority = priority_map[syslog_level];
    765 
    766                 /*
    767                  * Specify the facility to interoperate with other syslog
    768                  * callers (vfs_full_audit for example).
    769                  */
    770                 priority |= SYSLOG_FACILITY;
    771 
    772                 va_start(ap, format_str);
    773                 ret = vasprintf(&msgbuf, format_str, ap);
    774                 va_end(ap);
    775 
    776                 if (ret != -1) {
    777                         syslog(priority, "%s", msgbuf);
    778                 }
    779                 SAFE_FREE(msgbuf);
    780         }
    781 #endif
    782 
    783         check_log_size();
    784 
    785 #ifdef WITH_SYSLOG
    786         if( !state.settings.syslog_only)
    787 #endif
    788         {
    789                 va_start( ap, format_str );
    790                 if (state.fd > 0)
    791                         (void)vdprintf( state.fd, format_str, ap );
    792                 va_end( ap );
    793         }
    794 
    795  done:
     1108        switch(state.logtype) {
     1109        case DEBUG_CALLBACK:
     1110                debug_callback_log(msg, current_msg_level);
     1111                break;
     1112        case DEBUG_STDOUT:
     1113        case DEBUG_STDERR:
     1114        case DEBUG_DEFAULT_STDOUT:
     1115        case DEBUG_DEFAULT_STDERR:
     1116                if (state.fd > 0) {
     1117                        write(state.fd, msg, strlen(msg));
     1118                }
     1119                break;
     1120        case DEBUG_FILE:
     1121                debug_backends_log(msg, current_msg_level);
     1122                break;
     1123        };
     1124
    7961125        errno = old_errno;
    797 
    798         return( 0 );
    799 }
    800 
     1126}
    8011127
    8021128/**************************************************************************
     
    8091135{
    8101136        format_bufr[format_pos] = '\0';
    811         (void)Debug1( "%s", format_bufr );
     1137        (void)Debug1(format_bufr);
    8121138        format_pos = 0;
    8131139}
     
    8341160        bool timestamp = (state.logtype == DEBUG_FILE && (state.settings.timestamp_logs));
    8351161
    836         if (!format_bufr) {
    837                 debug_init();
    838         }
     1162        debug_init();
    8391163
    8401164        for( i = 0; msg[i]; i++ ) {
     
    8461170
    8471171                /* If there's room, copy the character to the format buffer. */
    848                 if( format_pos < FORMAT_BUFR_MAX )
     1172                if (format_pos < FORMAT_BUFR_SIZE - 1)
    8491173                        format_bufr[format_pos++] = msg[i];
    8501174
     
    8561180                 * continuation indicator.
    8571181                 */
    858                 if( format_pos >= FORMAT_BUFR_MAX ) {
     1182                if (format_pos >= FORMAT_BUFR_SIZE - 1) {
    8591183                        bufr_print();
    8601184                        (void)Debug1( " +>\n" );
     
    8971221          Eg: ( (level <= DEBUGLEVEL) && (dbghdr(level,"",line)) )
    8981222
    899   Notes:  This function takes care of setting syslog_level.
     1223  Notes:  This function takes care of setting current_msg_level.
    9001224
    9011225****************************************************************************/
     
    9051229        /* Ensure we don't lose any real errno value. */
    9061230        int old_errno = errno;
     1231        bool verbose = false;
     1232        char header_str[300];
     1233        size_t hs_len;
     1234        struct timeval tv;
     1235        struct timeval_buf tvbuf;
    9071236
    9081237        if( format_pos ) {
     
    9191248        }
    9201249
    921 #ifdef WITH_SYSLOG
    922         /* Set syslog_level. */
    923         syslog_level = level;
    924 #endif
     1250        /* Set current_msg_level. */
     1251        current_msg_level = level;
    9251252
    9261253        /* Don't print a header if we're logging to stdout. */
     
    9321259         * not yet loaded, then default to timestamps on.
    9331260         */
    934         if( state.settings.timestamp_logs || state.settings.debug_prefix_timestamp) {
    935                 char header_str[200];
    936 
    937                 header_str[0] = '\0';
    938 
    939                 if( state.settings.debug_pid)
    940                         slprintf(header_str,sizeof(header_str)-1,", pid=%u",(unsigned int)getpid());
    941 
    942                 if( state.settings.debug_uid) {
    943                         size_t hs_len = strlen(header_str);
    944                         slprintf(header_str + hs_len,
    945                         sizeof(header_str) - 1 - hs_len,
    946                                 ", effective(%u, %u), real(%u, %u)",
    947                                 (unsigned int)geteuid(), (unsigned int)getegid(),
    948                                 (unsigned int)getuid(), (unsigned int)getgid());
    949                 }
    950 
    951                 if (state.settings.debug_class && (cls != DBGC_ALL)) {
    952                         size_t hs_len = strlen(header_str);
    953                         slprintf(header_str + hs_len,
    954                                  sizeof(header_str) -1 - hs_len,
    955                                  ", class=%s",
    956                                  classname_table[cls]);
    957                 }
    958 
    959                 /* Print it all out at once to prevent split syslog output. */
    960                 if( state.settings.debug_prefix_timestamp ) {
    961                         char *time_str = current_timestring(NULL,
    962                                                             state.settings.debug_hires_timestamp);
    963                         (void)Debug1( "[%s, %2d%s] ",
    964                                       time_str,
    965                                       level, header_str);
    966                         talloc_free(time_str);
    967                 } else {
    968                         char *time_str = current_timestring(NULL,
    969                                                             state.settings.debug_hires_timestamp);
    970                         (void)Debug1( "[%s, %2d%s] %s(%s)\n",
    971                                       time_str,
    972                                       level, header_str, location, func );
    973                         talloc_free(time_str);
    974                 }
    975         }
     1261        if (!(state.settings.timestamp_logs ||
     1262              state.settings.debug_prefix_timestamp)) {
     1263                return true;
     1264        }
     1265
     1266        GetTimeOfDay(&tv);
     1267        timeval_str_buf(&tv, false, state.settings.debug_hires_timestamp,
     1268                        &tvbuf);
     1269
     1270        hs_len = snprintf(header_str, sizeof(header_str), "[%s, %2d",
     1271                          tvbuf.buf, level);
     1272        if (hs_len >= sizeof(header_str)) {
     1273                goto full;
     1274        }
     1275
     1276        if (unlikely(DEBUGLEVEL_CLASS[ cls ] >= 10)) {
     1277                verbose = true;
     1278        }
     1279
     1280        if (verbose || state.settings.debug_pid) {
     1281                hs_len += snprintf(
     1282                        header_str + hs_len, sizeof(header_str) - hs_len,
     1283                        ", pid=%u", (unsigned int)getpid());
     1284                if (hs_len >= sizeof(header_str)) {
     1285                        goto full;
     1286                }
     1287        }
     1288
     1289        if (verbose || state.settings.debug_uid) {
     1290                hs_len += snprintf(
     1291                        header_str + hs_len, sizeof(header_str) - hs_len,
     1292                        ", effective(%u, %u), real(%u, %u)",
     1293                        (unsigned int)geteuid(), (unsigned int)getegid(),
     1294                        (unsigned int)getuid(), (unsigned int)getgid());
     1295                if (hs_len >= sizeof(header_str)) {
     1296                        goto full;
     1297                }
     1298        }
     1299
     1300        if ((verbose || state.settings.debug_class)
     1301            && (cls != DBGC_ALL)) {
     1302                hs_len += snprintf(
     1303                        header_str + hs_len, sizeof(header_str) - hs_len,
     1304                        ", class=%s", classname_table[cls]);
     1305                if (hs_len >= sizeof(header_str)) {
     1306                        goto full;
     1307                }
     1308        }
     1309
     1310        /*
     1311         * No +=, see man man strlcat
     1312         */
     1313        hs_len = strlcat(header_str, "] ", sizeof(header_str));
     1314        if (hs_len >= sizeof(header_str)) {
     1315                goto full;
     1316        }
     1317
     1318        if (!state.settings.debug_prefix_timestamp) {
     1319                hs_len += snprintf(
     1320                        header_str + hs_len, sizeof(header_str) - hs_len,
     1321                        "%s(%s)\n", location, func);
     1322                if (hs_len >= sizeof(header_str)) {
     1323                        goto full;
     1324                }
     1325        }
     1326
     1327full:
     1328        (void)Debug1(header_str);
    9761329
    9771330        errno = old_errno;
     
    9921345***************************************************************************/
    9931346
    994  bool dbgtext( const char *format_str, ... )
    995 {
    996         va_list ap;
     1347static inline bool __dbgtext_va(const char *format_str, va_list ap) PRINTF_ATTRIBUTE(1,0);
     1348static inline bool __dbgtext_va(const char *format_str, va_list ap)
     1349{
    9971350        char *msgbuf = NULL;
    9981351        bool ret = true;
    9991352        int res;
    10001353
    1001         va_start(ap, format_str);
    10021354        res = vasprintf(&msgbuf, format_str, ap);
    1003         va_end(ap);
    1004 
    10051355        if (res != -1) {
    10061356                format_debug_text(msgbuf);
     
    10121362}
    10131363
    1014 
    1015 /* the registered mutex handlers */
    1016 static struct {
    1017         const char *name;
    1018         struct debug_ops ops;
    1019 } debug_handlers;
    1020 
    1021 /**
    1022   log suspicious usage - print comments and backtrace
    1023 */     
    1024 _PUBLIC_ void log_suspicious_usage(const char *from, const char *info)
    1025 {
    1026         if (!debug_handlers.ops.log_suspicious_usage) return;
    1027 
    1028         debug_handlers.ops.log_suspicious_usage(from, info);
    1029 }
    1030 
    1031 
    1032 /**
    1033   print suspicious usage - print comments and backtrace
    1034 */     
    1035 _PUBLIC_ void print_suspicious_usage(const char* from, const char* info)
    1036 {
    1037         if (!debug_handlers.ops.print_suspicious_usage) return;
    1038 
    1039         debug_handlers.ops.print_suspicious_usage(from, info);
    1040 }
    1041 
    1042 _PUBLIC_ uint32_t get_task_id(void)
    1043 {
    1044         if (debug_handlers.ops.get_task_id) {
    1045                 return debug_handlers.ops.get_task_id();
    1046         }
    1047         return getpid();
    1048 }
    1049 
    1050 _PUBLIC_ void log_task_id(void)
    1051 {
    1052         if (!debug_handlers.ops.log_task_id) return;
    1053 
    1054         if (!reopen_logs_internal()) return;
    1055 
    1056         debug_handlers.ops.log_task_id(state.fd);
    1057 }
    1058 
    1059 /**
    1060   register a set of debug handlers.
    1061 */
    1062 _PUBLIC_ void register_debug_handlers(const char *name, struct debug_ops *ops)
    1063 {
    1064         debug_handlers.name = name;
    1065         debug_handlers.ops = *ops;
    1066 }
     1364bool dbgtext_va(const char *format_str, va_list ap)
     1365{
     1366        return __dbgtext_va(format_str, ap);
     1367}
     1368
     1369bool dbgtext(const char *format_str, ... )
     1370{
     1371        va_list ap;
     1372        bool ret;
     1373
     1374        va_start(ap, format_str);
     1375        ret = __dbgtext_va(format_str, ap);
     1376        va_end(ap);
     1377
     1378        return ret;
     1379}
Note: See TracChangeset for help on using the changeset viewer.