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

    r860 r988  
    2929#include "../lib/util/util_pw.h"
    3030#include "messages.h"
     31#include "messages_dgm.h"
    3132#include "libcli/security/security.h"
    32 
    33 extern char *global_clobber_region_function;
    34 extern unsigned int global_clobber_region_line;
     33#include "serverid.h"
     34#include "lib/util/sys_rw.h"
     35#include "lib/util/sys_rw_data.h"
     36#include "lib/util/util_process.h"
     37
     38#ifdef HAVE_SYS_PRCTL_H
     39#include <sys/prctl.h>
     40#endif
    3541
    3642/* Max allowable allococation - 256mb - 0x10000000 */
     
    7783static enum remote_arch_types ra_type = RA_UNKNOWN;
    7884
    79 /***********************************************************************
    80  Definitions for all names.
    81 ***********************************************************************/
    82 
    83 static char *smb_scope;
    84 static int smb_num_netbios_names;
    85 static char **smb_my_netbios_names;
    86 
    87 /***********************************************************************
    88  Allocate and set scope. Ensure upper case.
    89 ***********************************************************************/
    90 
    91 bool set_global_scope(const char *scope)
    92 {
    93         SAFE_FREE(smb_scope);
    94         smb_scope = SMB_STRDUP(scope);
    95         if (!smb_scope)
    96                 return False;
    97         strupper_m(smb_scope);
    98         return True;
    99 }
    100 
    101 /*********************************************************************
    102  Ensure scope is never null string.
    103 *********************************************************************/
    104 
    105 const char *global_scope(void)
    106 {
    107         if (!smb_scope)
    108                 set_global_scope("");
    109         return smb_scope;
    110 }
    111 
    112 static void free_netbios_names_array(void)
    113 {
    114         int i;
    115 
    116         for (i = 0; i < smb_num_netbios_names; i++)
    117                 SAFE_FREE(smb_my_netbios_names[i]);
    118 
    119         SAFE_FREE(smb_my_netbios_names);
    120         smb_num_netbios_names = 0;
    121 }
    122 
    123 static bool allocate_my_netbios_names_array(size_t number)
    124 {
    125         free_netbios_names_array();
    126 
    127         smb_num_netbios_names = number + 1;
    128         smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
    129 
    130         if (!smb_my_netbios_names)
    131                 return False;
    132 
    133         memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
    134         return True;
    135 }
    136 
    137 static bool set_my_netbios_names(const char *name, int i)
    138 {
    139         SAFE_FREE(smb_my_netbios_names[i]);
    140 
    141         smb_my_netbios_names[i] = SMB_STRDUP(name);
    142         if (!smb_my_netbios_names[i])
    143                 return False;
    144         strupper_m(smb_my_netbios_names[i]);
    145         return True;
    146 }
    147 
    148 /***********************************************************************
    149  Free memory allocated to global objects
    150 ***********************************************************************/
    151 
    152 void gfree_names(void)
    153 {
    154         gfree_netbios_names();
    155         SAFE_FREE( smb_scope );
    156         free_netbios_names_array();
    157         free_local_machine_name();
    158 }
    159 
    16085void gfree_all( void )
    16186{
    16287        gfree_names();
    16388        gfree_loadparm();
    164         gfree_case_tables();
    16589        gfree_charcnv();
    16690        gfree_interfaces();
     
    16892}
    16993
    170 const char *my_netbios_names(int i)
    171 {
    172         return smb_my_netbios_names[i];
    173 }
    174 
    175 bool set_netbios_aliases(const char **str_array)
    176 {
    177         size_t namecount;
    178 
    179         /* Work out the max number of netbios aliases that we have */
    180         for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
    181                 ;
    182 
    183         if ( global_myname() && *global_myname())
    184                 namecount++;
    185 
    186         /* Allocate space for the netbios aliases */
    187         if (!allocate_my_netbios_names_array(namecount))
    188                 return False;
    189 
    190         /* Use the global_myname string first */
    191         namecount=0;
    192         if ( global_myname() && *global_myname()) {
    193                 set_my_netbios_names( global_myname(), namecount );
    194                 namecount++;
    195         }
    196 
    197         if (str_array) {
    198                 size_t i;
    199                 for ( i = 0; str_array[i] != NULL; i++) {
    200                         size_t n;
    201                         bool duplicate = False;
    202 
    203                         /* Look for duplicates */
    204                         for( n=0; n<namecount; n++ ) {
    205                                 if( strequal( str_array[i], my_netbios_names(n) ) ) {
    206                                         duplicate = True;
    207                                         break;
    208                                 }
    209                         }
    210                         if (!duplicate) {
    211                                 if (!set_my_netbios_names(str_array[i], namecount))
    212                                         return False;
    213                                 namecount++;
    214                         }
    215                 }
    216         }
    217         return True;
    218 }
    219 
    220 /****************************************************************************
    221   Common name initialization code.
    222 ****************************************************************************/
    223 
    224 bool init_names(void)
    225 {
    226         int n;
    227 
    228         if (global_myname() == NULL || *global_myname() == '\0') {
    229                 if (!set_global_myname(myhostname())) {
    230                         DEBUG( 0, ( "init_names: malloc fail.\n" ) );
    231                         return False;
    232                 }
    233         }
    234 
    235         if (!set_netbios_aliases(lp_netbios_aliases())) {
    236                 DEBUG( 0, ( "init_names: malloc fail.\n" ) );
    237                 return False;
    238         }
    239 
    240         set_local_machine_name(global_myname(),false);
    241 
    242         DEBUG( 5, ("Netbios name list:-\n") );
    243         for( n=0; my_netbios_names(n); n++ ) {
    244                 DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",
    245                                         n, my_netbios_names(n) ) );
    246         }
    247 
    248         return( True );
    249 }
    250 
    25194/*******************************************************************
    25295 Check if a file exists - call vfs_file_exist for samba files.
     
    288131}
    289132
    290 /*******************************************************************
    291  Returns the size in bytes of the named file.
    292 ********************************************************************/
    293 
    294 SMB_OFF_T get_file_size(char *file_name)
    295 {
    296         SMB_STRUCT_STAT buf;
    297         buf.st_ex_size = 0;
    298         if (sys_stat(file_name, &buf, false) != 0)
    299                 return (SMB_OFF_T)-1;
    300         return get_file_size_stat(&buf);
    301 }
    302 
    303 /*******************************************************************
    304  Return a string representing an attribute for a file.
    305 ********************************************************************/
    306 
    307 char *attrib_string(uint16 mode)
    308 {
    309         fstring attrstr;
    310 
    311         attrstr[0] = 0;
    312 
    313         if (mode & FILE_ATTRIBUTE_VOLUME) fstrcat(attrstr,"V");
    314         if (mode & FILE_ATTRIBUTE_DIRECTORY) fstrcat(attrstr,"D");
    315         if (mode & FILE_ATTRIBUTE_ARCHIVE) fstrcat(attrstr,"A");
    316         if (mode & FILE_ATTRIBUTE_HIDDEN) fstrcat(attrstr,"H");
    317         if (mode & FILE_ATTRIBUTE_SYSTEM) fstrcat(attrstr,"S");
    318         if (mode & FILE_ATTRIBUTE_READONLY) fstrcat(attrstr,"R");
    319 
    320         return talloc_strdup(talloc_tos(), attrstr);
     133/****************************************************************************
     134 Check two stats have identical dev and ino fields.
     135****************************************************************************/
     136
     137bool check_same_dev_ino(const SMB_STRUCT_STAT *sbuf1,
     138                        const SMB_STRUCT_STAT *sbuf2)
     139{
     140        if (sbuf1->st_ex_dev != sbuf2->st_ex_dev ||
     141                        sbuf1->st_ex_ino != sbuf2->st_ex_ino) {
     142                return false;
     143        }
     144        return true;
     145}
     146
     147/****************************************************************************
     148 Check if a stat struct is identical for use.
     149****************************************************************************/
     150
     151bool check_same_stat(const SMB_STRUCT_STAT *sbuf1,
     152                        const SMB_STRUCT_STAT *sbuf2)
     153{
     154        if (sbuf1->st_ex_uid != sbuf2->st_ex_uid ||
     155                        sbuf1->st_ex_gid != sbuf2->st_ex_gid ||
     156                        !check_same_dev_ino(sbuf1, sbuf2)) {
     157                return false;
     158        }
     159        return true;
    321160}
    322161
     
    325164********************************************************************/
    326165
    327 void show_msg(char *buf)
     166void show_msg(const char *buf)
    328167{
    329168        int i;
     
    362201                bcc = MIN(bcc, 512);
    363202
    364         dump_data(10, (uint8 *)smb_buf(buf), bcc);     
    365 }
    366 
    367 /*******************************************************************
    368  Set the length and marker of an encrypted smb packet.
    369 ********************************************************************/
    370 
    371 void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num)
    372 {
    373         _smb_setlen(buf,len);
    374 
    375         SCVAL(buf,4,0xFF);
    376         SCVAL(buf,5,'E');
    377         SSVAL(buf,6,enc_ctx_num);
    378 }
    379 
    380 /*******************************************************************
    381  Set the length and marker of an smb packet.
    382 ********************************************************************/
    383 
    384 void smb_setlen(char *buf,int len)
    385 {
    386         _smb_setlen_large(buf,len);
    387 
    388         SCVAL(buf,4,0xFF);
    389         SCVAL(buf,5,'S');
    390         SCVAL(buf,6,'M');
    391         SCVAL(buf,7,'B');
     203        dump_data(10, (const uint8_t *)smb_buf_const(buf), bcc);
    392204}
    393205
     
    409221********************************************************************/
    410222
    411 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
     223ssize_t message_push_blob(uint8_t **outbuf, DATA_BLOB blob)
    412224{
    413225        size_t newlen = smb_len(*outbuf) + 4 + blob.length;
    414         uint8 *tmp;
    415 
    416         if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
     226        uint8_t *tmp;
     227
     228        if (!(tmp = talloc_realloc(NULL, *outbuf, uint8_t, newlen))) {
    417229                DEBUG(0, ("talloc failed\n"));
    418230                return -1;
     
    542354********************************************************************/
    543355
    544 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
     356ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, off_t pos)
    545357{
    546358        size_t total=0;
    547359        ssize_t ret;
    548360
    549         if (pos == (SMB_OFF_T)-1) {
     361        if (pos == (off_t)-1) {
    550362                return write_data(fd, buffer, N);
    551363        }
     
    569381#else
    570382        /* Use lseek and write_data. */
    571         if (sys_lseek(fd, pos, SEEK_SET) == -1) {
     383        if (lseek(fd, pos, SEEK_SET) == -1) {
    572384                if (errno != ESPIPE) {
    573385                        return -1;
     
    578390}
    579391
     392static int reinit_after_fork_pipe[2] = { -1, -1 };
     393
     394NTSTATUS init_before_fork(void)
     395{
     396        int ret;
     397
     398        ret = pipe(reinit_after_fork_pipe);
     399        if (ret == -1) {
     400                NTSTATUS status;
     401
     402                status = map_nt_error_from_unix_common(errno);
     403
     404                DEBUG(0, ("Error creating child_pipe: %s\n",
     405                          nt_errstr(status)));
     406
     407                return status;
     408        }
     409
     410        return NT_STATUS_OK;
     411}
     412
     413/**
     414 * Detect died parent by detecting EOF on the pipe
     415 */
     416static void reinit_after_fork_pipe_handler(struct tevent_context *ev,
     417                                           struct tevent_fd *fde,
     418                                           uint16_t flags,
     419                                           void *private_data)
     420{
     421        char c;
     422
     423        if (sys_read(reinit_after_fork_pipe[0], &c, 1) != 1) {
     424                /*
     425                 * we have reached EOF on stdin, which means the
     426                 * parent has exited. Shutdown the server
     427                 */
     428                (void)kill(getpid(), SIGTERM);
     429        }
     430}
     431
    580432
    581433NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
    582                            struct event_context *ev_ctx,
    583                            struct server_id id,
    584                            bool parent_longlived)
     434                           struct tevent_context *ev_ctx,
     435                           bool parent_longlived,
     436                           const char *comment)
    585437{
    586438        NTSTATUS status = NT_STATUS_OK;
    587439
    588         /* Reset the state of the random
    589          * number generation system, so
    590          * children do not get the same random
    591          * numbers as each other */
    592         set_need_random_reseed();
     440        if (reinit_after_fork_pipe[1] != -1) {
     441                close(reinit_after_fork_pipe[1]);
     442                reinit_after_fork_pipe[1] = -1;
     443        }
    593444
    594445        /* tdb needs special fork handling */
    595         if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
     446        if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
    596447                DEBUG(0,("tdb_reopen_all failed.\n"));
    597448                status = NT_STATUS_OPEN_FAILED;
     
    599450        }
    600451
    601         if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
    602                 smb_panic(__location__ ": Failed to re-initialise event context");
     452        if (ev_ctx != NULL) {
     453                tevent_set_trace_callback(ev_ctx, NULL, NULL);
     454                if (tevent_re_initialise(ev_ctx) != 0) {
     455                        smb_panic(__location__ ": Failed to re-initialise event context");
     456                }
     457        }
     458
     459        if (reinit_after_fork_pipe[0] != -1) {
     460                struct tevent_fd *fde;
     461
     462                fde = tevent_add_fd(ev_ctx, ev_ctx /* TALLOC_CTX */,
     463                                    reinit_after_fork_pipe[0], TEVENT_FD_READ,
     464                                    reinit_after_fork_pipe_handler, NULL);
     465                if (fde == NULL) {
     466                        smb_panic(__location__ ": Failed to add reinit_after_fork pipe event");
     467                }
    603468        }
    604469
     
    608473                 * fork
    609474                 */
    610                 status = messaging_reinit(msg_ctx, id);
     475                status = messaging_reinit(msg_ctx);
    611476                if (!NT_STATUS_IS_OK(status)) {
    612477                        DEBUG(0,("messaging_reinit() failed: %s\n",
     
    614479                }
    615480        }
     481
     482        if (comment) {
     483                prctl_set_comment(comment);
     484        }
     485
    616486 done:
    617487        return status;
    618 }
    619 
    620 #if defined(PARANOID_MALLOC_CHECKER)
    621 
    622 /****************************************************************************
    623  Internal malloc wrapper. Externally visible.
    624 ****************************************************************************/
    625 
    626 void *malloc_(size_t size)
    627 {
    628         if (size == 0) {
    629                 return NULL;
    630         }
    631 #undef malloc
    632         return malloc(size);
    633 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
    634 }
    635 
    636 /****************************************************************************
    637  Internal calloc wrapper. Not externally visible.
    638 ****************************************************************************/
    639 
    640 static void *calloc_(size_t count, size_t size)
    641 {
    642         if (size == 0 || count == 0) {
    643                 return NULL;
    644         }
    645 #undef calloc
    646         return calloc(count, size);
    647 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
    648 }
    649 
    650 /****************************************************************************
    651  Internal realloc wrapper. Not externally visible.
    652 ****************************************************************************/
    653 
    654 static void *realloc_(void *ptr, size_t size)
    655 {
    656 #undef realloc
    657         return realloc(ptr, size);
    658 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
    659 }
    660 
    661 #endif /* PARANOID_MALLOC_CHECKER */
    662 
    663 /****************************************************************************
    664  Type-safe memalign
    665 ****************************************************************************/
    666 
    667 void *memalign_array(size_t el_size, size_t align, unsigned int count)
    668 {
    669         if (count >= MAX_ALLOC_SIZE/el_size) {
    670                 return NULL;
    671         }
    672 
    673         return sys_memalign(align, el_size*count);
    674 }
    675 
    676 /****************************************************************************
    677  Type-safe calloc.
    678 ****************************************************************************/
    679 
    680 void *calloc_array(size_t size, size_t nmemb)
    681 {
    682         if (nmemb >= MAX_ALLOC_SIZE/size) {
    683                 return NULL;
    684         }
    685         if (size == 0 || nmemb == 0) {
    686                 return NULL;
    687         }
    688 #if defined(PARANOID_MALLOC_CHECKER)
    689         return calloc_(nmemb, size);
    690 #else
    691         return calloc(nmemb, size);
    692 #endif
    693 }
    694 
    695 /****************************************************************************
    696  Expand a pointer to be a particular size.
    697  Note that this version of Realloc has an extra parameter that decides
    698  whether to free the passed in storage on allocation failure or if the
    699  new size is zero.
    700 
    701  This is designed for use in the typical idiom of :
    702 
    703  p = SMB_REALLOC(p, size)
    704  if (!p) {
    705     return error;
    706  }
    707 
    708  and not to have to keep track of the old 'p' contents to free later, nor
    709  to worry if the size parameter was zero. In the case where NULL is returned
    710  we guarentee that p has been freed.
    711 
    712  If free later semantics are desired, then pass 'free_old_on_error' as False which
    713  guarentees that the old contents are not freed on error, even if size == 0. To use
    714  this idiom use :
    715 
    716  tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
    717  if (!tmp) {
    718     SAFE_FREE(p);
    719     return error;
    720  } else {
    721     p = tmp;
    722  }
    723 
    724  Changes were instigated by Coverity error checking. JRA.
    725 ****************************************************************************/
    726 
    727 void *Realloc(void *p, size_t size, bool free_old_on_error)
    728 {
    729         void *ret=NULL;
    730 
    731         if (size == 0) {
    732                 if (free_old_on_error) {
    733                         SAFE_FREE(p);
    734                 }
    735                 DEBUG(2,("Realloc asked for 0 bytes\n"));
    736                 return NULL;
    737         }
    738 
    739 #if defined(PARANOID_MALLOC_CHECKER)
    740         if (!p) {
    741                 ret = (void *)malloc_(size);
    742         } else {
    743                 ret = (void *)realloc_(p,size);
    744         }
    745 #else
    746         if (!p) {
    747                 ret = (void *)malloc(size);
    748         } else {
    749                 ret = (void *)realloc(p,size);
    750         }
    751 #endif
    752 
    753         if (!ret) {
    754                 if (free_old_on_error && p) {
    755                         SAFE_FREE(p);
    756                 }
    757                 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
    758         }
    759 
    760         return(ret);
    761488}
    762489
     
    766493
    767494void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
    768                         void *element, void *_array, uint32 *num_elements,
     495                        void *element, void *_array, uint32_t *num_elements,
    769496                        ssize_t *array_size)
    770497{
     
    838565        }
    839566}
    840 
    841 /****************************************************************************
    842  Interpret a protocol description string, with a default.
    843 ****************************************************************************/
    844 
    845 int interpret_protocol(const char *str,int def)
    846 {
    847         if (strequal(str,"NT1"))
    848                 return(PROTOCOL_NT1);
    849         if (strequal(str,"LANMAN2"))
    850                 return(PROTOCOL_LANMAN2);
    851         if (strequal(str,"LANMAN1"))
    852                 return(PROTOCOL_LANMAN1);
    853         if (strequal(str,"CORE"))
    854                 return(PROTOCOL_CORE);
    855         if (strequal(str,"COREPLUS"))
    856                 return(PROTOCOL_COREPLUS);
    857         if (strequal(str,"CORE+"))
    858                 return(PROTOCOL_COREPLUS);
    859 
    860         DEBUG(0,("Unrecognised protocol level %s\n",str));
    861 
    862         return(def);
    863 }
    864 
    865567
    866568#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
     
    898600        char *value = NULL;
    899601
    900         char *nis_map = (char *)lp_nis_home_map_name();
     602        char *nis_map = (char *)lp_homedir_map();
    901603
    902604        char buffer[NIS_MAXATTRVAL + 1];
     
    950652        int nis_result_len;  /* and set this */
    951653        char *nis_domain;     /* yp_get_default_domain inits this */
    952         char *nis_map = (char *)lp_nis_home_map_name();
     654        char *nis_map = lp_homedir_map(talloc_tos());
    953655
    954656        if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
     
    987689#endif
    988690
    989 /****************************************************************************
    990  Check if a process exists. Does this work on all unixes?
    991 ****************************************************************************/
    992 
    993691bool process_exists(const struct server_id pid)
    994692{
    995         if (procid_is_me(&pid)) {
    996                 return True;
    997         }
    998 
    999         if (procid_is_local(&pid)) {
    1000                 return (kill(pid.pid,0) == 0 || errno != ESRCH);
    1001         }
    1002 
    1003 #ifdef CLUSTER_SUPPORT
    1004         return ctdbd_process_exists(messaging_ctdbd_connection(),
    1005                                     pid.vnn, pid.pid);
    1006 #else
    1007         return False;
    1008 #endif
     693        return serverid_exists(&pid);
    1009694}
    1010695
     
    1088773                return g;
    1089774
    1090         grp = sys_getgrnam(name);
     775        grp = getgrnam(name);
    1091776        if (grp)
    1092777                return(grp->gr_gid);
     
    1098783********************************************************************/
    1099784
    1100 void smb_panic(const char *const why)
     785void smb_panic_s3(const char *why)
    1101786{
    1102787        char *cmd;
    1103788        int result;
    1104789
    1105 #ifdef DEVELOPER
    1106         {
    1107 
    1108                 if (global_clobber_region_function) {
    1109                         DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
    1110                                          global_clobber_region_function,
    1111                                          global_clobber_region_line));
    1112                 }
    1113         }
     790        DEBUG(0,("PANIC (pid %llu): %s\n",
     791                    (unsigned long long)getpid(), why));
     792        log_stack_trace();
     793
     794#if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
     795        /*
     796         * Make sure all children can attach a debugger.
     797         */
     798        prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
    1114799#endif
    1115800
    1116         DEBUG(0,("PANIC (pid %llu): %s\n",
    1117                     (unsigned long long)sys_getpid(), why));
    1118         log_stack_trace();
    1119 
    1120         cmd = lp_panic_action();
     801        cmd = lp_panic_action(talloc_tos());
    1121802        if (cmd && *cmd) {
    1122803                DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
     
    1277958 ********************************************************************/
    1278959
    1279 const char *readdirname(SMB_STRUCT_DIR *p)
    1280 {
    1281         SMB_STRUCT_DIRENT *ptr;
     960const char *readdirname(DIR *p)
     961{
     962        struct dirent *ptr;
    1282963        char *dname;
    1283964
     
    1285966                return(NULL);
    1286967
    1287         ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
     968        ptr = (struct dirent *)readdir(p);
    1288969        if (!ptr)
    1289970                return(NULL);
     
    13361017                } else {
    13371018                        if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
    1338                                                 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
     1019                                                (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
    13391020                                DEBUG(8,("is_in_path: match succeeded\n"));
    13401021                                return True;
     
    13521033 speed so we can pre-parse all the names in the list
    13531034 and don't do it for each call to is_in_path().
    1354  namelist is modified here and is assumed to be
    1355  a copy owned by the caller.
    13561035 We also check if the entry contains a wildcard to
    13571036 remove a potentially expensive call to mask_match
     
    13591038********************************************************************/
    13601039
    1361 void set_namearray(name_compare_entry **ppname_array, const char *namelist)
     1040void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
    13621041{
    13631042        char *name_end;
    1364         char *nameptr = (char *)namelist;
     1043        char *namelist;
     1044        char *namelist_end;
     1045        char *nameptr;
    13651046        int num_entries = 0;
    13661047        int i;
     
    13681049        (*ppname_array) = NULL;
    13691050
    1370         if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
     1051        if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0')))
    13711052                return;
     1053
     1054        namelist = talloc_strdup(talloc_tos(), namelist_in);
     1055        if (namelist == NULL) {
     1056                DEBUG(0,("set_namearray: talloc fail\n"));
     1057                return;
     1058        }
     1059        nameptr = namelist;
     1060
     1061        namelist_end = &namelist[strlen(namelist)];
    13721062
    13731063        /* We need to make two passes over the string. The
     
    13761066        */
    13771067
    1378         while(*nameptr) {
     1068        while(nameptr <= namelist_end) {
    13791069                if ( *nameptr == '/' ) {
    13801070                        /* cope with multiple (useless) /s) */
     
    13881078                /* find the next '/' or consume remaining */
    13891079                name_end = strchr_m(nameptr, '/');
    1390                 if (name_end == NULL)
    1391                         name_end = (char *)nameptr + strlen(nameptr);
    1392 
    1393                 /* next segment please */
    1394                 nameptr = name_end + 1;
     1080                if (name_end == NULL) {
     1081                        /* Point nameptr at the terminating '\0' */
     1082                        nameptr += strlen(nameptr);
     1083                } else {
     1084                        /* next segment please */
     1085                        nameptr = name_end + 1;
     1086                }
    13951087                num_entries++;
    13961088        }
    13971089
    1398         if(num_entries == 0)
     1090        if(num_entries == 0) {
     1091                talloc_free(namelist);
    13991092                return;
     1093        }
    14001094
    14011095        if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
    14021096                DEBUG(0,("set_namearray: malloc fail\n"));
     1097                talloc_free(namelist);
    14031098                return;
    14041099        }
    14051100
    14061101        /* Now copy out the names */
    1407         nameptr = (char *)namelist;
     1102        nameptr = namelist;
    14081103        i = 0;
    1409         while(*nameptr) {
     1104        while(nameptr <= namelist_end) {
    14101105                if ( *nameptr == '/' ) {
    14111106                        /* cope with multiple (useless) /s) */
     
    14191114                /* find the next '/' or consume remaining */
    14201115                name_end = strchr_m(nameptr, '/');
    1421                 if (name_end)
     1116                if (name_end != NULL) {
    14221117                        *name_end = '\0';
    1423                 else
    1424                         name_end = nameptr + strlen(nameptr);
     1118                }
    14251119
    14261120                (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
    14271121                if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
    14281122                        DEBUG(0,("set_namearray: malloc fail (1)\n"));
     1123                        talloc_free(namelist);
    14291124                        return;
    14301125                }
    14311126
    1432                 /* next segment please */
    1433                 nameptr = name_end + 1;
     1127                if (name_end == NULL) {
     1128                        /* Point nameptr at the terminating '\0' */
     1129                        nameptr += strlen(nameptr);
     1130                } else {
     1131                        /* next segment please */
     1132                        nameptr = name_end + 1;
     1133                }
    14341134                i++;
    14351135        }
     
    14371137        (*ppname_array)[i].name = NULL;
    14381138
     1139        talloc_free(namelist);
    14391140        return;
    1440 }
    1441 
    1442 /****************************************************************************
    1443  Routine to free a namearray.
    1444 ****************************************************************************/
    1445 
    1446 void free_namearray(name_compare_entry *name_array)
    1447 {
    1448         int i;
    1449 
    1450         if(name_array == NULL)
    1451                 return;
    1452 
    1453         for(i=0; name_array[i].name!=NULL; i++)
    1454                 SAFE_FREE(name_array[i].name);
    1455         SAFE_FREE(name_array);
    14561141}
    14571142
     
    14661151****************************************************************************/
    14671152
    1468 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
    1469 {
    1470         SMB_STRUCT_FLOCK lock;
     1153bool fcntl_getlock(int fd, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid)
     1154{
     1155        struct flock lock;
    14711156        int ret;
    14721157
     
    14801165        lock.l_pid = 0;
    14811166
    1482         ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
     1167        ret = sys_fcntl_ptr(fd,F_GETLK,&lock);
    14831168
    14841169        if (ret == -1) {
     
    15141199
    15151200        for (n=0; my_netbios_names(n); n++) {
    1516                 if (strequal(my_netbios_names(n), s)) {
     1201                const char *nbt_name = my_netbios_names(n);
     1202
     1203                if (strncasecmp_m(nbt_name, s, MAX_NETBIOSNAME_LEN-1) == 0) {
    15171204                        ret=True;
    15181205                        break;
     
    15201207        }
    15211208        DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
    1522         return(ret);
    1523 }
    1524 
    1525 /*******************************************************************
    1526  Is the name specified our workgroup/domain.
    1527  Returns true if it is equal, false otherwise.
    1528 ********************************************************************/
    1529 
    1530 bool is_myworkgroup(const char *s)
    1531 {
    1532         bool ret = False;
    1533 
    1534         if (strequal(s, lp_workgroup())) {
    1535                 ret=True;
    1536         }
    1537 
    1538         DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
    15391209        return(ret);
    15401210}
     
    16531323int str_checksum(const char *s)
    16541324{
    1655         TDB_DATA key = string_tdb_data(s);
     1325        TDB_DATA key;
     1326        if (s == NULL)
     1327                return 0;
     1328
     1329        key = (TDB_DATA) { .dptr = discard_const_p(uint8_t, s),
     1330                           .dsize = strlen(s) };
     1331
    16561332        return tdb_jenkins_hash(&key);
    16571333}
     
    18031479}
    18041480
    1805 /**
    1806  * @brief Returns an absolute path to a file concatenating the provided
    1807  * @a rootpath and @a basename
    1808  *
    1809  * @param name Filename, relative to @a rootpath
    1810  *
    1811  * @retval Pointer to a string containing the full path.
    1812  **/
    1813 
    1814 static char *xx_path(const char *name, const char *rootpath)
    1815 {
    1816         char *fname = NULL;
    1817 
    1818         fname = talloc_strdup(talloc_tos(), rootpath);
    1819         if (!fname) {
    1820                 return NULL;
    1821         }
    1822         trim_string(fname,"","/");
    1823 
    1824         if (!directory_exist(fname)) {
    1825                 if (!mkdir(fname,0755))
    1826                         DEBUG(1, ("Unable to create directory %s for file %s. "
    1827                               "Error was %s\n", fname, name, strerror(errno)));
    1828         }
    1829 
    1830         return talloc_asprintf(talloc_tos(),
    1831                                 "%s/%s",
    1832                                 fname,
    1833                                 name);
    1834 }
    1835 
    1836 /**
    1837  * @brief Returns an absolute path to a file in the Samba lock directory.
    1838  *
    1839  * @param name File to find, relative to LOCKDIR.
    1840  *
    1841  * @retval Pointer to a talloc'ed string containing the full path.
    1842  **/
    1843 
    1844 char *lock_path(const char *name)
    1845 {
    1846         return xx_path(name, lp_lockdir());
    1847 }
    1848 
    1849 /**
    1850  * @brief Returns an absolute path to a file in the Samba pid directory.
    1851  *
    1852  * @param name File to find, relative to PIDDIR.
    1853  *
    1854  * @retval Pointer to a talloc'ed string containing the full path.
    1855  **/
    1856 
    1857 char *pid_path(const char *name)
    1858 {
    1859         return xx_path(name, lp_piddir());
    1860 }
    1861 
    1862 /**
    1863  * @brief Returns an absolute path to a file in the Samba lib directory.
    1864  *
    1865  * @param name File to find, relative to LIBDIR.
    1866  *
    1867  * @retval Pointer to a string containing the full path.
    1868  **/
    1869 
    1870 char *lib_path(const char *name)
    1871 {
    1872         return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
    1873 }
    1874 
    1875 /**
    1876  * @brief Returns an absolute path to a file in the Samba modules directory.
    1877  *
    1878  * @param name File to find, relative to MODULESDIR.
    1879  *
    1880  * @retval Pointer to a string containing the full path.
    1881  **/
    1882 
    1883 char *modules_path(const char *name)
    1884 {
    1885         return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_MODULESDIR(), name);
    1886 }
    1887 
    1888 /**
    1889  * @brief Returns an absolute path to a file in the Samba data directory.
    1890  *
    1891  * @param name File to find, relative to CODEPAGEDIR.
    1892  *
    1893  * @retval Pointer to a talloc'ed string containing the full path.
    1894  **/
    1895 
    1896 char *data_path(const char *name)
    1897 {
    1898         return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
    1899 }
    1900 
    1901 /**
    1902  * @brief Returns an absolute path to a file in the Samba state directory.
    1903  *
    1904  * @param name File to find, relative to STATEDIR.
    1905  *
    1906  * @retval Pointer to a talloc'ed string containing the full path.
    1907  **/
    1908 
    1909 char *state_path(const char *name)
    1910 {
    1911         return xx_path(name, lp_statedir());
    1912 }
    1913 
    1914 /**
    1915  * @brief Returns an absolute path to a file in the Samba cache directory.
    1916  *
    1917  * @param name File to find, relative to CACHEDIR.
    1918  *
    1919  * @retval Pointer to a talloc'ed string containing the full path.
    1920  **/
    1921 
    1922 char *cache_path(const char *name)
    1923 {
    1924         return xx_path(name, lp_cachedir());
    1925 }
    1926 
    1927 /**
    1928  * @brief Returns the platform specific shared library extension.
    1929  *
    1930  * @retval Pointer to a const char * containing the extension.
    1931  **/
    1932 
    1933 const char *shlib_ext(void)
    1934 {
    1935         return get_dyn_SHLIBEXT();
     1481/*****************************************************************
     1482 Get local hostname and cache result.
     1483*****************************************************************/
     1484
     1485char *myhostname_upper(void)
     1486{
     1487        static char *ret;
     1488        if (ret == NULL) {
     1489                char *name = get_myname(NULL);
     1490                if (name == NULL) {
     1491                        return NULL;
     1492                }
     1493                ret = strupper_talloc(NULL, name);
     1494                talloc_free(name);
     1495        }
     1496        return ret;
    19361497}
    19371498
     
    19601521        len = p-dir;
    19611522
    1962         if (!(*parent = (char *)TALLOC_MEMDUP(mem_ctx, dir, len+1))) {
     1523        if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
    19631524                return False;
    19641525        }
     
    19781539{
    19791540        char c;
    1980 
    1981         if (lp_posix_pathnames()) {
    1982                 /* With posix pathnames no characters are wild. */
    1983                 return False;
    1984         }
    19851541
    19861542        while ((c = *s++)) {
     
    21791735                return false;
    21801736        }
    2181         strlower_m(p2);
    2182         strlower_m(s2);
     1737        if (!strlower_m(p2)) {
     1738                TALLOC_FREE(ctx);
     1739                return false;
     1740        }
     1741        if (!strlower_m(s2)) {
     1742                TALLOC_FREE(ctx);
     1743                return false;
     1744        }
    21831745
    21841746        /* Remove any *? and ** from the pattern as they are meaningless */
     
    22001762
    22011763/**********************************************************************
    2202  Converts a name to a fully qualified domain name.
    2203  Returns true if lookup succeeded, false if not (then fqdn is set to name)
    2204  Note we deliberately use gethostbyname here, not getaddrinfo as we want
    2205  to examine the h_aliases and I don't know how to do that with getaddrinfo.
    2206 ***********************************************************************/
     1764  Converts a name to a fully qualified domain name.
     1765  Returns true if lookup succeeded, false if not (then fqdn is set to name)
     1766  Uses getaddrinfo() with AI_CANONNAME flag to obtain the official
     1767  canonical name of the host. getaddrinfo() may use a variety of sources
     1768  including /etc/hosts to obtain the domainname. It expects aliases in
     1769  /etc/hosts to NOT be the FQDN. The FQDN should come first.
     1770************************************************************************/
    22071771
    22081772bool name_to_fqdn(fstring fqdn, const char *name)
    22091773{
    22101774        char *full = NULL;
    2211         struct hostent *hp = gethostbyname(name);
    2212 
    2213         if (!hp || !hp->h_name || !*hp->h_name) {
     1775        struct addrinfo hints;
     1776        struct addrinfo *result;
     1777        int s;
     1778
     1779        /* Configure hints to obtain canonical name */
     1780
     1781        memset(&hints, 0, sizeof(struct addrinfo));
     1782        hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
     1783        hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
     1784        hints.ai_flags = AI_CANONNAME;  /* Get host's FQDN */
     1785        hints.ai_protocol = 0;          /* Any protocol */
     1786
     1787        s = getaddrinfo(name, NULL, &hints, &result);
     1788        if (s != 0) {
     1789                DEBUG(1, ("getaddrinfo: %s\n", gai_strerror(s)));
    22141790                DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
    22151791                fstrcpy(fqdn, name);
    22161792                return false;
    22171793        }
    2218 
    2219         /* Find out if the fqdn is returned as an alias
     1794        full = result->ai_canonname;
     1795
     1796        /* Find out if the FQDN is returned as an alias
    22201797         * to cope with /etc/hosts files where the first
    2221          * name is not the fqdn but the short name */
    2222         if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
    2223                 int i;
    2224                 for (i = 0; hp->h_aliases[i]; i++) {
    2225                         if (strchr_m(hp->h_aliases[i], '.')) {
    2226                                 full = hp->h_aliases[i];
    2227                                 break;
    2228                         }
    2229                 }
    2230         }
    2231         if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
     1798         * name is not the FQDN but the short name.
     1799         * getaddrinfo provides no easy way of handling aliases
     1800         * in /etc/hosts. Users should make sure the FQDN
     1801         * comes first in /etc/hosts. */
     1802        if (full && (! strchr_m(full, '.'))) {
    22321803                DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
    2233                 DEBUGADD(1, ("    Specifing the machine hostname for address 127.0.0.1 may lead\n"));
     1804                DEBUGADD(1, ("    Full qualified domain names (FQDNs) should not be specified\n"));
     1805                DEBUGADD(1, ("    as an alias in /etc/hosts. FQDN should be the first name\n"));
     1806                DEBUGADD(1, ("    prior to any aliases.\n"));
     1807        }
     1808        if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
     1809                DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
     1810                DEBUGADD(1, ("    Specifying the machine hostname for address 127.0.0.1 may lead\n"));
    22341811                DEBUGADD(1, ("    to Kerberos authentication problems as localhost.localdomain\n"));
    22351812                DEBUGADD(1, ("    may end up being used instead of the real machine FQDN.\n"));
    2236                 full = hp->h_name;
    2237         }
    2238         if (!full) {
    2239                 full = hp->h_name;
    22401813        }
    22411814
    22421815        DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
    22431816        fstrcpy(fqdn, full);
     1817        freeaddrinfo(result);           /* No longer needed */
    22441818        return true;
    22451819}
    22461820
    2247 /**********************************************************************
    2248  Append a DATA_BLOB to a talloc'ed object
    2249 ***********************************************************************/
    2250 
    2251 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
    2252 {
    2253         size_t old_size = 0;
    2254         char *result;
    2255 
    2256         if (blob.length == 0) {
    2257                 return buf;
    2258         }
    2259 
    2260         if (buf != NULL) {
    2261                 old_size = talloc_get_size(buf);
    2262         }
    2263 
    2264         result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
    2265         if (result == NULL) {
    2266                 return NULL;
    2267         }
    2268 
    2269         memcpy(result + old_size, blob.data, blob.length);
    2270         return result;
    2271 }
    2272 
    2273 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
     1821uint32_t map_share_mode_to_deny_mode(uint32_t share_access, uint32_t private_options)
    22741822{
    22751823        switch (share_access & ~FILE_SHARE_DELETE) {
     
    22891837        }
    22901838
    2291         return (uint32)-1;
    2292 }
    2293 
    2294 pid_t procid_to_pid(const struct server_id *proc)
    2295 {
    2296         return proc->pid;
    2297 }
    2298 
    2299 static uint32 my_vnn = NONCLUSTER_VNN;
    2300 
    2301 void set_my_vnn(uint32 vnn)
    2302 {
    2303         DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
    2304         my_vnn = vnn;
    2305 }
    2306 
    2307 uint32 get_my_vnn(void)
    2308 {
    2309         return my_vnn;
    2310 }
    2311 
    2312 static uint64_t my_unique_id = 0;
    2313 
    2314 void set_my_unique_id(uint64_t unique_id)
    2315 {
    2316         my_unique_id = unique_id;
    2317 }
    2318 
    2319 struct server_id pid_to_procid(pid_t pid)
    2320 {
    2321         struct server_id result;
    2322         result.pid = pid;
    2323         result.unique_id = my_unique_id;
    2324         result.vnn = my_vnn;
    2325         return result;
    2326 }
    2327 
    2328 struct server_id procid_self(void)
    2329 {
    2330         return pid_to_procid(sys_getpid());
    2331 }
    2332 
    2333 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
    2334 {
    2335         if (p1->pid != p2->pid)
    2336                 return False;
    2337         if (p1->vnn != p2->vnn)
    2338                 return False;
    2339         return True;
    2340 }
    2341 
    2342 bool cluster_id_equal(const struct server_id *id1,
    2343                       const struct server_id *id2)
    2344 {
    2345         return procid_equal(id1, id2);
    2346 }
    2347 
    2348 bool procid_is_me(const struct server_id *pid)
    2349 {
    2350         if (pid->pid != sys_getpid())
    2351                 return False;
    2352         if (pid->vnn != my_vnn)
    2353                 return False;
    2354         return True;
     1839        return (uint32_t)-1;
    23551840}
    23561841
    23571842struct server_id interpret_pid(const char *pid_string)
    23581843{
    2359         struct server_id result;
    2360         int pid;
    2361         unsigned int vnn;
    2362         if (sscanf(pid_string, "%u:%d", &vnn, &pid) == 2) {
    2363                 result.vnn = vnn;
    2364                 result.pid = pid;
    2365         }
    2366         else if (sscanf(pid_string, "%d", &pid) == 1) {
    2367                 result.vnn = get_my_vnn();
    2368                 result.pid = pid;
    2369         }
    2370         else {
    2371                 result.vnn = NONCLUSTER_VNN;
    2372                 result.pid = -1;
    2373         }
    2374         /* Assigning to result.pid may have overflowed
    2375            Map negative pid to -1: i.e. error */
    2376         if (result.pid < 0) {
    2377                 result.pid = -1;
    2378         }
    2379         result.unique_id = 0;
    2380         return result;
    2381 }
    2382 
    2383 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
    2384 {
    2385         if (pid->vnn == NONCLUSTER_VNN) {
    2386                 return talloc_asprintf(mem_ctx,
    2387                                 "%d",
    2388                                 (int)pid->pid);
    2389         }
    2390         else {
    2391                 return talloc_asprintf(mem_ctx,
    2392                                         "%u:%d",
    2393                                         (unsigned)pid->vnn,
    2394                                         (int)pid->pid);
    2395         }
    2396 }
    2397 
    2398 char *procid_str_static(const struct server_id *pid)
    2399 {
    2400         return procid_str(talloc_tos(), pid);
    2401 }
    2402 
    2403 bool procid_valid(const struct server_id *pid)
    2404 {
    2405         return (pid->pid != -1);
    2406 }
    2407 
    2408 bool procid_is_local(const struct server_id *pid)
    2409 {
    2410         return pid->vnn == my_vnn;
    2411 }
    2412 
    2413 /****************************************************************
    2414  Check if offset/length fit into bufsize. Should probably be
    2415  merged with is_offset_safe, but this would require a rewrite
    2416  of lanman.c. Later :-)
    2417 ****************************************************************/
    2418 
    2419 bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
    2420 {
    2421         if ((offset + length < offset) || (offset + length < length)) {
    2422                 /* wrap */
    2423                 return true;
    2424         }
    2425         if ((offset > bufsize) || (offset + length > bufsize)) {
    2426                 /* overflow */
    2427                 return true;
    2428         }
    2429         return false;
     1844        return server_id_from_string(get_my_vnn(), pid_string);
    24301845}
    24311846
     
    25371952}
    25381953
    2539 #if 0
    2540 
    2541 Disable these now we have checked all code paths and ensured
    2542 NULL returns on zero request. JRA.
    2543 
    2544 /****************************************************************
    2545  talloc wrapper functions that guarentee a null pointer return
    2546  if size == 0.
    2547 ****************************************************************/
    2548 
    2549 #ifndef MAX_TALLOC_SIZE
    2550 #define MAX_TALLOC_SIZE 0x10000000
    2551 #endif
    2552 
    2553 /*
    2554  *    talloc and zero memory.
    2555  *    - returns NULL if size is zero.
    2556  */
    2557 
    2558 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
    2559 {
    2560         void *p;
    2561 
    2562         if (size == 0) {
    2563                 return NULL;
    2564         }
    2565 
    2566         p = talloc_named_const(ctx, size, name);
    2567 
    2568         if (p) {
    2569                 memset(p, '\0', size);
    2570         }
    2571 
    2572         return p;
    2573 }
    2574 
    2575 /*
    2576  *   memdup with a talloc.
    2577  *   - returns NULL if size is zero.
    2578  */
    2579 
    2580 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
    2581 {
    2582         void *newp;
    2583 
    2584         if (size == 0) {
    2585                 return NULL;
    2586         }
    2587 
    2588         newp = talloc_named_const(t, size, name);
    2589         if (newp) {
    2590                 memcpy(newp, p, size);
    2591         }
    2592 
    2593         return newp;
    2594 }
    2595 
    2596 /*
    2597  *   alloc an array, checking for integer overflow in the array size.
    2598  *   - returns NULL if count or el_size are zero.
    2599  */
    2600 
    2601 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
    2602 {
    2603         if (count >= MAX_TALLOC_SIZE/el_size) {
    2604                 return NULL;
    2605         }
    2606 
    2607         if (el_size == 0 || count == 0) {
    2608                 return NULL;
    2609         }
    2610 
    2611         return talloc_named_const(ctx, el_size * count, name);
    2612 }
    2613 
    2614 /*
    2615  *   alloc an zero array, checking for integer overflow in the array size
    2616  *   - returns NULL if count or el_size are zero.
    2617  */
    2618 
    2619 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
    2620 {
    2621         if (count >= MAX_TALLOC_SIZE/el_size) {
    2622                 return NULL;
    2623         }
    2624 
    2625         if (el_size == 0 || count == 0) {
    2626                 return NULL;
    2627         }
    2628 
    2629         return _talloc_zero(ctx, el_size * count, name);
    2630 }
    2631 
    2632 /*
    2633  *   Talloc wrapper that returns NULL if size == 0.
    2634  */
    2635 void *talloc_zeronull(const void *context, size_t size, const char *name)
    2636 {
    2637         if (size == 0) {
    2638                 return NULL;
    2639         }
    2640         return talloc_named_const(context, size, name);
    2641 }
    2642 #endif
    2643 
    26441954/****************************************************************
    26451955 strip off leading '\\' from a hostname
     
    26601970
    26611971        return s;
    2662 }
    2663 
    2664 bool tevent_req_poll_ntstatus(struct tevent_req *req,
    2665                               struct tevent_context *ev,
    2666                               NTSTATUS *status)
    2667 {
    2668         bool ret = tevent_req_poll(req, ev);
    2669         if (!ret) {
    2670                 *status = map_nt_error_from_unix(errno);
    2671         }
    2672         return ret;
    26731972}
    26741973
     
    27482047bool map_open_params_to_ntcreate(const char *smb_base_fname,
    27492048                                 int deny_mode, int open_func,
    2750                                  uint32 *paccess_mask,
    2751                                  uint32 *pshare_mode,
    2752                                  uint32 *pcreate_disposition,
    2753                                  uint32 *pcreate_options,
     2049                                 uint32_t *paccess_mask,
     2050                                 uint32_t *pshare_mode,
     2051                                 uint32_t *pcreate_disposition,
     2052                                 uint32_t *pcreate_options,
    27542053                                 uint32_t *pprivate_flags)
    27552054{
    2756         uint32 access_mask;
    2757         uint32 share_mode;
    2758         uint32 create_disposition;
    2759         uint32 create_options = FILE_NON_DIRECTORY_FILE;
     2055        uint32_t access_mask;
     2056        uint32_t share_mode;
     2057        uint32_t create_disposition;
     2058        uint32_t create_options = FILE_NON_DIRECTORY_FILE;
    27602059        uint32_t private_flags = 0;
    27612060
     
    28882187
    28892188}
     2189
     2190/*************************************************************************
     2191 Return a talloced copy of a struct security_unix_token. NULL on fail.
     2192*************************************************************************/
     2193
     2194struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
     2195{
     2196        struct security_unix_token *cpy;
     2197
     2198        cpy = talloc(ctx, struct security_unix_token);
     2199        if (!cpy) {
     2200                return NULL;
     2201        }
     2202
     2203        cpy->uid = tok->uid;
     2204        cpy->gid = tok->gid;
     2205        cpy->ngroups = tok->ngroups;
     2206        if (tok->ngroups) {
     2207                /* Make this a talloc child of cpy. */
     2208                cpy->groups = (gid_t *)talloc_memdup(
     2209                        cpy, tok->groups, tok->ngroups * sizeof(gid_t));
     2210                if (!cpy->groups) {
     2211                        TALLOC_FREE(cpy);
     2212                        return NULL;
     2213                }
     2214        } else {
     2215                cpy->groups = NULL;
     2216        }
     2217        return cpy;
     2218}
     2219
     2220/****************************************************************************
     2221 Check that a file matches a particular file type.
     2222****************************************************************************/
     2223
     2224bool dir_check_ftype(uint32_t mode, uint32_t dirtype)
     2225{
     2226        uint32_t mask;
     2227
     2228        /* Check the "may have" search bits. */
     2229        if (((mode & ~dirtype) &
     2230                        (FILE_ATTRIBUTE_HIDDEN |
     2231                         FILE_ATTRIBUTE_SYSTEM |
     2232                         FILE_ATTRIBUTE_DIRECTORY)) != 0) {
     2233                return false;
     2234        }
     2235
     2236        /* Check the "must have" bits,
     2237           which are the may have bits shifted eight */
     2238        /* If must have bit is set, the file/dir can
     2239           not be returned in search unless the matching
     2240           file attribute is set */
     2241        mask = ((dirtype >> 8) & (FILE_ATTRIBUTE_DIRECTORY|
     2242                                    FILE_ATTRIBUTE_ARCHIVE|
     2243                                   FILE_ATTRIBUTE_READONLY|
     2244                                     FILE_ATTRIBUTE_HIDDEN|
     2245                                     FILE_ATTRIBUTE_SYSTEM)); /* & 0x37 */
     2246        if(mask) {
     2247                if((mask & (mode & (FILE_ATTRIBUTE_DIRECTORY|
     2248                                      FILE_ATTRIBUTE_ARCHIVE|
     2249                                     FILE_ATTRIBUTE_READONLY|
     2250                                       FILE_ATTRIBUTE_HIDDEN|
     2251                                        FILE_ATTRIBUTE_SYSTEM))) == mask) {
     2252                        /* check if matching attribute present */
     2253                        return true;
     2254                } else {
     2255                        return false;
     2256                }
     2257        }
     2258
     2259        return true;
     2260}
Note: See TracChangeset for help on using the changeset viewer.