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/util.c

    r740 r988  
    44   Copyright (C) Andrew Tridgell 1992-1998
    55   Copyright (C) Jeremy Allison 2001-2002
    6    Copyright (C) Simo Sorce 2001
     6   Copyright (C) Simo Sorce 2001-2011
    77   Copyright (C) Jim McDonough (jmcd@us.ibm.com)  2003.
    88   Copyright (C) James J Myers 2003
     9   Copyright (C) Volker Lendecke 2010
    910   
    1011   This program is free software; you can redistribute it and/or modify
     
    2223*/
    2324
    24 #include "includes.h"
     25#include "replace.h"
     26#include <talloc.h>
    2527#include "system/network.h"
    2628#include "system/filesys.h"
    2729#include "system/locale.h"
    2830#include "system/shmem.h"
     31#include "system/passwd.h"
     32#include "system/time.h"
     33#include "system/wait.h"
     34#include "debug.h"
     35#include "samba_util.h"
    2936
    3037#undef malloc
     
    3340#undef strdup
    3441#undef realloc
    35 
    36 #if defined(UID_WRAPPER)
    37 #if !defined(UID_WRAPPER_REPLACE) && !defined(UID_WRAPPER_NOT_REPLACE)
    38 #define UID_WRAPPER_REPLACE
    39 #include "../uid_wrapper/uid_wrapper.h"
    40 #endif
    41 #else
    42 #define uwrap_enabled() 0
    43 #endif
     42#undef calloc
    4443
    4544/**
     
    6261
    6362/**
     63 Create a tmp file, open it and immediately unlink it.
     64 If dir is NULL uses tmpdir()
     65 Returns the file descriptor or -1 on error.
     66**/
     67int create_unlink_tmp(const char *dir)
     68{
     69        size_t len = strlen(dir);
     70        char fname[len+25];
     71        int fd;
     72        mode_t mask;
     73
     74        if (!dir) {
     75                dir = tmpdir();
     76        }
     77
     78        len = snprintf(fname, sizeof(fname), "%s/listenerlock_XXXXXX", dir);
     79        if (len >= sizeof(fname)) {
     80                errno = ENOMEM;
     81                return -1;
     82        }
     83        mask = umask(S_IRWXO | S_IRWXG);
     84        fd = mkstemp(fname);
     85        umask(mask);
     86        if (fd == -1) {
     87                return -1;
     88        }
     89        if (unlink(fname) == -1) {
     90                int sys_errno = errno;
     91                close(fd);
     92                errno = sys_errno;
     93                return -1;
     94        }
     95        return fd;
     96}
     97
     98
     99/**
    64100 Check if a file exists - call vfs_file_exist for samba files.
    65101**/
     
    90126
    91127/**
     128 Check file permissions.
     129**/
     130
     131_PUBLIC_ bool file_check_permissions(const char *fname,
     132                                     uid_t uid,
     133                                     mode_t file_perms,
     134                                     struct stat *pst)
     135{
     136        int ret;
     137        struct stat st;
     138
     139        if (pst == NULL) {
     140                pst = &st;
     141        }
     142
     143        ZERO_STRUCTP(pst);
     144
     145        ret = stat(fname, pst);
     146        if (ret != 0) {
     147                DEBUG(0, ("stat failed on file '%s': %s\n",
     148                         fname, strerror(errno)));
     149                return false;
     150        }
     151
     152        if (pst->st_uid != uid && !uid_wrapper_enabled()) {
     153                DEBUG(0, ("invalid ownership of file '%s': "
     154                         "owned by uid %u, should be %u\n",
     155                         fname, (unsigned int)pst->st_uid,
     156                         (unsigned int)uid));
     157                return false;
     158        }
     159
     160        if ((pst->st_mode & 0777) != file_perms) {
     161                DEBUG(0, ("invalid permissions on file "
     162                         "'%s': has 0%o should be 0%o\n", fname,
     163                         (unsigned int)(pst->st_mode & 0777),
     164                         (unsigned int)file_perms));
     165                return false;
     166        }
     167
     168        return true;
     169}
     170
     171/**
    92172 Check if a directory exists.
    93173**/
     
    111191 * Try to create the specified directory if it didn't exist.
    112192 *
    113  * @retval true if the directory already existed and has the right permissions
     193 * @retval true if the directory already existed
    114194 * or was successfully created.
    115195 */
    116 _PUBLIC_ bool directory_create_or_exist(const char *dname, uid_t uid,
    117                                mode_t dir_perms)
    118 {
     196_PUBLIC_ bool directory_create_or_exist(const char *dname,
     197                                        mode_t dir_perms)
     198{
     199        int ret;
     200        struct stat st;
    119201        mode_t old_umask;
    120         struct stat st;
    121      
     202
     203        ret = lstat(dname, &st);
     204        if (ret == 0) {
     205                return true;
     206        }
     207
     208        if (errno != ENOENT) {
     209                DEBUG(0, ("lstat failed on directory %s: %s\n",
     210                          dname, strerror(errno)));
     211                return false;
     212        }
     213
     214        /* Create directory */
    122215        old_umask = umask(0);
    123         if (lstat(dname, &st) == -1) {
    124                 if (errno == ENOENT) {
    125                         /* Create directory */
    126                         if (mkdir(dname, dir_perms) == -1) {
    127                                 DEBUG(0, ("error creating directory "
    128                                           "%s: %s\n", dname,
    129                                           strerror(errno)));
    130                                 umask(old_umask);
    131                                 return false;
    132                         }
    133                 } else {
    134                         DEBUG(0, ("lstat failed on directory %s: %s\n",
    135                                   dname, strerror(errno)));
    136                         umask(old_umask);
    137                         return false;
    138                 }
    139         } else {
    140                 /* Check ownership and permission on existing directory */
    141                 if (!S_ISDIR(st.st_mode)) {
    142                         DEBUG(0, ("directory %s isn't a directory\n",
    143                                 dname));
    144                         umask(old_umask);
    145                         return false;
    146                 }
    147                 if (st.st_uid != uid && !uwrap_enabled()) {
    148                         DEBUG(0, ("invalid ownership on directory "
    149                                   "%s\n", dname));
    150                         umask(old_umask);
    151                         return false;
    152                 }
    153                 if ((st.st_mode & 0777) != dir_perms) {
    154                         DEBUG(0, ("invalid permissions on directory "
    155                                   "%s\n", dname));
    156                         umask(old_umask);
    157                         return false;
    158                 }
    159         }
     216        ret = mkdir(dname, dir_perms);
     217        if (ret == -1 && errno != EEXIST) {
     218                DEBUG(0, ("mkdir failed on directory "
     219                          "%s: %s\n", dname,
     220                          strerror(errno)));
     221                umask(old_umask);
     222                return false;
     223        }
     224        umask(old_umask);
     225
     226        ret = lstat(dname, &st);
     227        if (ret == -1) {
     228                DEBUG(0, ("lstat failed on created directory %s: %s\n",
     229                          dname, strerror(errno)));
     230                return false;
     231        }
     232
    160233        return true;
    161 }       
     234}
     235
     236/**
     237 * @brief Try to create a specified directory if it doesn't exist.
     238 *
     239 * The function creates a directory with the given uid and permissions if it
     240 * doesn't exist. If it exists it makes sure the uid and permissions are
     241 * correct and it will fail if they are different.
     242 *
     243 * @param[in]  dname  The directory to create.
     244 *
     245 * @param[in]  uid    The uid the directory needs to belong too.
     246 *
     247 * @param[in]  dir_perms  The expected permissions of the directory.
     248 *
     249 * @return True on success, false on error.
     250 */
     251_PUBLIC_ bool directory_create_or_exist_strict(const char *dname,
     252                                               uid_t uid,
     253                                               mode_t dir_perms)
     254{
     255        struct stat st;
     256        bool ok;
     257        int rc;
     258
     259        ok = directory_create_or_exist(dname, dir_perms);
     260        if (!ok) {
     261                return false;
     262        }
     263
     264        rc = lstat(dname, &st);
     265        if (rc == -1) {
     266                DEBUG(0, ("lstat failed on created directory %s: %s\n",
     267                          dname, strerror(errno)));
     268                return false;
     269        }
     270
     271        /* Check ownership and permission on existing directory */
     272        if (!S_ISDIR(st.st_mode)) {
     273                DEBUG(0, ("directory %s isn't a directory\n",
     274                        dname));
     275                return false;
     276        }
     277        if (st.st_uid != uid && !uid_wrapper_enabled()) {
     278                DBG_NOTICE("invalid ownership on directory "
     279                          "%s\n", dname);
     280                return false;
     281        }
     282        if ((st.st_mode & 0777) != dir_perms) {
     283                DEBUG(0, ("invalid permissions on directory "
     284                          "'%s': has 0%o should be 0%o\n", dname,
     285                          (unsigned int)(st.st_mode & 0777), (unsigned int)dir_perms));
     286                return false;
     287        }
     288
     289        return true;
     290}
    162291
    163292
     
    247376        /* Doing kill with a non-positive pid causes messages to be
    248377         * sent to places we don't want. */
    249         SMB_ASSERT(pid > 0);
     378        if (pid <= 0) {
     379                return false;
     380        }
    250381        return(kill(pid,0) == 0 || errno != ESRCH);
    251382}
     
    299430
    300431        return true;
     432}
     433
     434struct debug_channel_level {
     435        int channel;
     436        int level;
     437};
     438
     439static void debugadd_channel_cb(const char *buf, void *private_data)
     440{
     441        struct debug_channel_level *dcl =
     442                (struct debug_channel_level *)private_data;
     443
     444        DEBUGADDC(dcl->channel, dcl->level,("%s", buf));
    301445}
    302446
     
    387531                int n;
    388532                n = 16 - (i%16);
    389                 cb(" ", private_data);
     533                cb("  ", private_data);
    390534                if (n>8) {
    391535                        cb(" ", private_data);
     
    422566 * Write dump of binary data to the log file.
    423567 *
     568 * The data is only written if the log level is at least level for
     569 * debug class dbgc_class.
     570 */
     571_PUBLIC_ void dump_data_dbgc(int dbgc_class, int level, const uint8_t *buf, int len)
     572{
     573        struct debug_channel_level dcl = { dbgc_class, level };
     574
     575        if (!DEBUGLVLC(dbgc_class, level)) {
     576                return;
     577        }
     578        dump_data_cb(buf, len, false, debugadd_channel_cb, &dcl);
     579}
     580
     581/**
     582 * Write dump of binary data to the log file.
     583 *
    424584 * The data is only written if the log level is at least level.
    425585 * 16 zero bytes in a row are omitted
     
    433593}
    434594
     595static void fprintf_cb(const char *buf, void *private_data)
     596{
     597        FILE *f = (FILE *)private_data;
     598        fprintf(f, "%s", buf);
     599}
     600
     601void dump_data_file(const uint8_t *buf, int len, bool omit_zero_bytes,
     602                    FILE *f)
     603{
     604        dump_data_cb(buf, len, omit_zero_bytes, fprintf_cb, f);
     605}
    435606
    436607/**
     
    526697**/
    527698
    528 _PUBLIC_ void *memdup(const void *p, size_t size)
     699_PUBLIC_ void *smb_memdup(const void *p, size_t size)
    529700{
    530701        void *p2;
     
    562733_PUBLIC_ bool all_zero(const uint8_t *ptr, size_t size)
    563734{
    564         int i;
     735        size_t i;
    565736        if (!ptr) return true;
    566737        for (i=0;i<size;i++) {
     
    595766{
    596767        return realloc_array(NULL, el_size, count, false);
     768}
     769
     770/****************************************************************************
     771 Type-safe memalign
     772****************************************************************************/
     773
     774void *memalign_array(size_t el_size, size_t align, unsigned int count)
     775{
     776        if (el_size == 0 || count >= MAX_MALLOC_SIZE/el_size) {
     777                return NULL;
     778        }
     779
     780        return memalign(align, el_size*count);
     781}
     782
     783/****************************************************************************
     784 Type-safe calloc.
     785****************************************************************************/
     786
     787void *calloc_array(size_t size, size_t nmemb)
     788{
     789        if (nmemb >= MAX_MALLOC_SIZE/size) {
     790                return NULL;
     791        }
     792        if (size == 0 || nmemb == 0) {
     793                return NULL;
     794        }
     795        return calloc(nmemb, size);
    597796}
    598797
     
    652851
    653852/**
    654  Routine to get hex characters and turn them into a 16 byte array.
    655  the array can be variable length, and any non-hex-numeric
    656  characters are skipped.  "0xnn" or "0Xnn" is specially catered
    657  for.
    658 
    659  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
    660 
    661 
    662 **/
     853 * Routine to get hex characters and turn them into a byte array.
     854 * the array can be variable length.
     855 * -  "0xnn" or "0Xnn" is specially catered for.
     856 * - The first non-hex-digit character (apart from possibly leading "0x"
     857 *   finishes the conversion and skips the rest of the input.
     858 * - A single hex-digit character at the end of the string is skipped.
     859 *
     860 * valid examples: "0A5D15"; "0x123456"
     861 */
    663862_PUBLIC_ size_t strhex_to_str(char *p, size_t p_len, const char *strhex, size_t strhex_len)
    664863{
     
    674873        }
    675874
    676         for (; i < strhex_len && strhex[i] != 0; i++) {
    677                 if (!(p1 = strchr(hexchars, toupper((unsigned char)strhex[i]))))
     875        for (; i+1 < strhex_len && strhex[i] != 0 && strhex[i+1] != 0; i++) {
     876                p1 = strchr(hexchars, toupper((unsigned char)strhex[i]));
     877                if (p1 == NULL) {
    678878                        break;
     879                }
    679880
    680881                i++; /* next hex digit */
    681882
    682                 if (!(p2 = strchr(hexchars, toupper((unsigned char)strhex[i]))))
     883                p2 = strchr(hexchars, toupper((unsigned char)strhex[i]));
     884                if (p2 == NULL) {
    683885                        break;
     886                }
    684887
    685888                /* get the two nybbles */
     
    714917}
    715918
    716 
    717 /**
    718  * Routine to print a buffer as HEX digits, into an allocated string.
    719  */
    720 _PUBLIC_ void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
    721 {
    722         int i;
    723         char *hex_buffer;
    724 
    725         *out_hex_buffer = malloc_array_p(char, (len*2)+1);
    726         hex_buffer = *out_hex_buffer;
    727 
    728         for (i = 0; i < len; i++)
    729                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
    730 }
    731 
    732 /**
    733  * talloc version of hex_encode()
     919/**
     920 * Print a buf in hex. Assumes dst is at least (srclen*2)+1 large.
     921 */
     922_PUBLIC_ void hex_encode_buf(char *dst, const uint8_t *src, size_t srclen)
     923{
     924        size_t i;
     925        for (i=0; i<srclen; i++) {
     926                snprintf(dst + i*2, 3, "%02X", src[i]);
     927        }
     928        /*
     929         * Ensure 0-termination for 0-length buffers
     930         */
     931        dst[srclen*2] = '\0';
     932}
     933
     934/**
     935 * talloc version of hex_encode_buf()
    734936 */
    735937_PUBLIC_ char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
    736938{
    737         int i;
    738939        char *hex_buffer;
    739940
     
    742943                return NULL;
    743944        }
    744 
    745         for (i = 0; i < len; i++)
    746                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
    747 
     945        hex_encode_buf(hex_buffer, buff_in, len);
    748946        talloc_set_name_const(hex_buffer, hex_buffer);
    749947        return hex_buffer;
     
    780978
    781979        return len;
    782 }
    783 
    784 /**
    785  Set a boolean variable from the text value stored in the passed string.
    786  Returns true in success, false if the passed string does not correctly
    787  represent a boolean.
    788 **/
    789 
    790 _PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean)
    791 {
    792         if (strwicmp(boolean_string, "yes") == 0 ||
    793             strwicmp(boolean_string, "true") == 0 ||
    794             strwicmp(boolean_string, "on") == 0 ||
    795             strwicmp(boolean_string, "1") == 0) {
    796                 *boolean = true;
    797                 return true;
    798         } else if (strwicmp(boolean_string, "no") == 0 ||
    799                    strwicmp(boolean_string, "false") == 0 ||
    800                    strwicmp(boolean_string, "off") == 0 ||
    801                    strwicmp(boolean_string, "0") == 0) {
    802                 *boolean = false;
    803                 return true;
    804         }
    805         return false;
    806 }
    807 
    808 /**
    809 return the number of bytes occupied by a buffer in CH_UTF16 format
    810 the result includes the null termination
    811 **/
    812 _PUBLIC_ size_t utf16_len(const void *buf)
    813 {
    814         size_t len;
    815 
    816         for (len = 0; SVAL(buf,len); len += 2) ;
    817 
    818         return len + 2;
    819 }
    820 
    821 /**
    822 return the number of bytes occupied by a buffer in CH_UTF16 format
    823 the result includes the null termination
    824 limited by 'n' bytes
    825 **/
    826 _PUBLIC_ size_t utf16_len_n(const void *src, size_t n)
    827 {
    828         size_t len;
    829 
    830         for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
    831 
    832         if (len+2 <= n) {
    833                 len += 2;
    834         }
    835 
    836         return len;
    837 }
    838 
    839 /**
    840  * @file
    841  * @brief String utilities.
    842  **/
    843 
    844 static bool next_token_internal_talloc(TALLOC_CTX *ctx,
    845                                 const char **ptr,
    846                                 char **pp_buff,
    847                                 const char *sep,
    848                                 bool ltrim)
    849 {
    850         const char *s;
    851         const char *saved_s;
    852         char *pbuf;
    853         bool quoted;
    854         size_t len=1;
    855 
    856         *pp_buff = NULL;
    857         if (!ptr) {
    858                 return(false);
    859         }
    860 
    861         s = *ptr;
    862 
    863         /* default to simple separators */
    864         if (!sep) {
    865                 sep = " \t\n\r";
    866         }
    867 
    868         /* find the first non sep char, if left-trimming is requested */
    869         if (ltrim) {
    870                 while (*s && strchr_m(sep,*s)) {
    871                         s++;
    872                 }
    873         }
    874 
    875         /* nothing left? */
    876         if (!*s) {
    877                 return false;
    878         }
    879 
    880         /* When restarting we need to go from here. */
    881         saved_s = s;
    882 
    883         /* Work out the length needed. */
    884         for (quoted = false; *s &&
    885                         (quoted || !strchr_m(sep,*s)); s++) {
    886                 if (*s == '\"') {
    887                         quoted = !quoted;
    888                 } else {
    889                         len++;
    890                 }
    891         }
    892 
    893         /* We started with len = 1 so we have space for the nul. */
    894         *pp_buff = talloc_array(ctx, char, len);
    895         if (!*pp_buff) {
    896                 return false;
    897         }
    898 
    899         /* copy over the token */
    900         pbuf = *pp_buff;
    901         s = saved_s;
    902         for (quoted = false; *s &&
    903                         (quoted || !strchr_m(sep,*s)); s++) {
    904                 if ( *s == '\"' ) {
    905                         quoted = !quoted;
    906                 } else {
    907                         *pbuf++ = *s;
    908                 }
    909         }
    910 
    911         *ptr = (*s) ? s+1 : s;
    912         *pbuf = 0;
    913 
    914         return true;
    915 }
    916 
    917 bool next_token_talloc(TALLOC_CTX *ctx,
    918                         const char **ptr,
    919                         char **pp_buff,
    920                         const char *sep)
    921 {
    922         return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
    923 }
    924 
    925 /*
    926  * Get the next token from a string, return false if none found.  Handles
    927  * double-quotes.  This version does not trim leading separator characters
    928  * before looking for a token.
    929  */
    930 
    931 bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
    932                         const char **ptr,
    933                         char **pp_buff,
    934                         const char *sep)
    935 {
    936         return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
    937 }
    938 
    939 /**
    940  * Get the next token from a string, return False if none found.
    941  * Handles double-quotes.
    942  *
    943  * Based on a routine by GJC@VILLAGE.COM.
    944  * Extensively modified by Andrew.Tridgell@anu.edu.au
    945  **/
    946 _PUBLIC_ bool next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
    947 {
    948         const char *s;
    949         bool quoted;
    950         size_t len=1;
    951 
    952         if (!ptr)
    953                 return false;
    954 
    955         s = *ptr;
    956 
    957         /* default to simple separators */
    958         if (!sep)
    959                 sep = " \t\n\r";
    960 
    961         /* find the first non sep char */
    962         while (*s && strchr_m(sep,*s))
    963                 s++;
    964 
    965         /* nothing left? */
    966         if (!*s)
    967                 return false;
    968 
    969         /* copy over the token */
    970         for (quoted = false; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
    971                 if (*s == '\"') {
    972                         quoted = !quoted;
    973                 } else {
    974                         len++;
    975                         *buff++ = *s;
    976                 }
    977         }
    978 
    979         *ptr = (*s) ? s+1 : s;
    980         *buff = 0;
    981 
    982         return true;
    983980}
    984981
     
    10201017                        -1 /* fd */, 0 /* offset */);
    10211018#else
     1019{
     1020        int saved_errno;
     1021        int fd;
     1022
     1023        fd = open("/dev/zero", O_RDWR);
     1024        if (fd == -1) {
     1025                return NULL;
     1026        }
     1027
    10221028        buf = mmap(NULL, bufsz, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
    1023                         open("/dev/zero", O_RDWR), 0 /* offset */);
     1029                   fd, 0 /* offset */);
     1030        saved_errno = errno;
     1031        close(fd);
     1032        errno = saved_errno;
     1033}
    10241034#endif
    10251035
     
    10341044
    10351045        return ptr;
     1046}
     1047
     1048void *anonymous_shared_resize(void *ptr, size_t new_size, bool maymove)
     1049{
     1050#ifdef HAVE_MREMAP
     1051        void *buf;
     1052        size_t pagesz = getpagesize();
     1053        size_t pagecnt;
     1054        size_t bufsz;
     1055        struct anonymous_shared_header *hdr;
     1056        int flags = 0;
     1057
     1058        if (ptr == NULL) {
     1059                errno = EINVAL;
     1060                return NULL;
     1061        }
     1062
     1063        hdr = (struct anonymous_shared_header *)ptr;
     1064        hdr--;
     1065        if (hdr->u.length > (new_size + sizeof(*hdr))) {
     1066                errno = EINVAL;
     1067                return NULL;
     1068        }
     1069
     1070        bufsz = new_size + sizeof(*hdr);
     1071
     1072        /* round up to full pages */
     1073        pagecnt = bufsz / pagesz;
     1074        if (bufsz % pagesz) {
     1075                pagecnt += 1;
     1076        }
     1077        bufsz = pagesz * pagecnt;
     1078
     1079        if (new_size >= bufsz) {
     1080                /* integer wrap */
     1081                errno = ENOSPC;
     1082                return NULL;
     1083        }
     1084
     1085        if (bufsz <= hdr->u.length) {
     1086                return ptr;
     1087        }
     1088
     1089        if (maymove) {
     1090                flags = MREMAP_MAYMOVE;
     1091        }
     1092
     1093        buf = mremap(hdr, hdr->u.length, bufsz, flags);
     1094
     1095        if (buf == MAP_FAILED) {
     1096                errno = ENOSPC;
     1097                return NULL;
     1098        }
     1099
     1100        hdr = (struct anonymous_shared_header *)buf;
     1101        hdr->u.length = bufsz;
     1102
     1103        ptr = (void *)(&hdr[1]);
     1104
     1105        return ptr;
     1106#else
     1107        errno = ENOSPC;
     1108        return NULL;
     1109#endif
    10361110}
    10371111
Note: See TracChangeset for help on using the changeset viewer.