2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2007
6 Copyright (C) Simo Sorce 2001
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) James Peach 2006
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 extern char *global_clobber_region_function;
27 extern unsigned int global_clobber_region_line;
29 /* Max allowable allococation - 256mb - 0x10000000 */
30 #define MAX_ALLOC_SIZE (1024*1024*256)
32 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
33 #ifdef WITH_NISPLUS_HOME
34 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
36 * The following lines are needed due to buggy include files
37 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
38 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
39 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
40 * an enum in /usr/include/rpcsvc/nis.h.
47 #if defined(GROUP_OBJ)
51 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
53 #include <rpcsvc/nis.h>
55 #endif /* WITH_NISPLUS_HOME */
56 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
58 enum protocol_types Protocol = PROTOCOL_COREPLUS;
60 /* this is used by the chaining code */
65 static enum remote_arch_types ra_type = RA_UNKNOWN;
67 /***********************************************************************
68 Definitions for all names.
69 ***********************************************************************/
71 static char *smb_myname;
72 static char *smb_myworkgroup;
73 static char *smb_scope;
74 static int smb_num_netbios_names;
75 static char **smb_my_netbios_names;
77 /***********************************************************************
78 Allocate and set myname. Ensure upper case.
79 ***********************************************************************/
81 bool set_global_myname(const char *myname)
83 SAFE_FREE(smb_myname);
84 smb_myname = SMB_STRDUP(myname);
87 strupper_m(smb_myname);
91 const char *global_myname(void)
96 /***********************************************************************
97 Allocate and set myworkgroup. Ensure upper case.
98 ***********************************************************************/
100 bool set_global_myworkgroup(const char *myworkgroup)
102 SAFE_FREE(smb_myworkgroup);
103 smb_myworkgroup = SMB_STRDUP(myworkgroup);
104 if (!smb_myworkgroup)
106 strupper_m(smb_myworkgroup);
110 const char *lp_workgroup(void)
112 return smb_myworkgroup;
115 /***********************************************************************
116 Allocate and set scope. Ensure upper case.
117 ***********************************************************************/
119 bool set_global_scope(const char *scope)
121 SAFE_FREE(smb_scope);
122 smb_scope = SMB_STRDUP(scope);
125 strupper_m(smb_scope);
129 /*********************************************************************
130 Ensure scope is never null string.
131 *********************************************************************/
133 const char *global_scope(void)
136 set_global_scope("");
140 static void free_netbios_names_array(void)
144 for (i = 0; i < smb_num_netbios_names; i++)
145 SAFE_FREE(smb_my_netbios_names[i]);
147 SAFE_FREE(smb_my_netbios_names);
148 smb_num_netbios_names = 0;
151 static bool allocate_my_netbios_names_array(size_t number)
153 free_netbios_names_array();
155 smb_num_netbios_names = number + 1;
156 smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
158 if (!smb_my_netbios_names)
161 memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
165 static bool set_my_netbios_names(const char *name, int i)
167 SAFE_FREE(smb_my_netbios_names[i]);
169 smb_my_netbios_names[i] = SMB_STRDUP(name);
170 if (!smb_my_netbios_names[i])
172 strupper_m(smb_my_netbios_names[i]);
176 /***********************************************************************
177 Free memory allocated to global objects
178 ***********************************************************************/
180 void gfree_names(void)
182 SAFE_FREE( smb_myname );
183 SAFE_FREE( smb_myworkgroup );
184 SAFE_FREE( smb_scope );
185 free_netbios_names_array();
186 free_local_machine_name();
189 void gfree_all( void )
198 /* release the talloc null_context memory last */
199 talloc_disable_null_tracking();
202 const char *my_netbios_names(int i)
204 return smb_my_netbios_names[i];
207 bool set_netbios_aliases(const char **str_array)
211 /* Work out the max number of netbios aliases that we have */
212 for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
215 if ( global_myname() && *global_myname())
218 /* Allocate space for the netbios aliases */
219 if (!allocate_my_netbios_names_array(namecount))
222 /* Use the global_myname string first */
224 if ( global_myname() && *global_myname()) {
225 set_my_netbios_names( global_myname(), namecount );
231 for ( i = 0; str_array[i] != NULL; i++) {
233 bool duplicate = False;
235 /* Look for duplicates */
236 for( n=0; n<namecount; n++ ) {
237 if( strequal( str_array[i], my_netbios_names(n) ) ) {
243 if (!set_my_netbios_names(str_array[i], namecount))
252 /****************************************************************************
253 Common name initialization code.
254 ****************************************************************************/
256 bool init_names(void)
260 if (global_myname() == NULL || *global_myname() == '\0') {
261 if (!set_global_myname(myhostname())) {
262 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
267 if (!set_netbios_aliases(lp_netbios_aliases())) {
268 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
272 set_local_machine_name(global_myname(),false);
274 DEBUG( 5, ("Netbios name list:-\n") );
275 for( n=0; my_netbios_names(n); n++ ) {
276 DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",
277 n, my_netbios_names(n) ) );
283 /**************************************************************************n
284 Code to cope with username/password auth options from the commandline.
285 Used mainly in client tools.
286 ****************************************************************************/
288 static struct user_auth_info cmdline_auth_info = {
291 false, /* got_pass */
292 false, /* use_kerberos */
293 Undefined, /* signing state */
294 false /* smb_encrypt */
297 const char *get_cmdline_auth_info_username(void)
299 if (!cmdline_auth_info.username) {
302 return cmdline_auth_info.username;
305 void set_cmdline_auth_info_username(const char *username)
307 SAFE_FREE(cmdline_auth_info.username);
308 cmdline_auth_info.username = SMB_STRDUP(username);
309 if (!cmdline_auth_info.username) {
314 const char *get_cmdline_auth_info_password(void)
316 if (!cmdline_auth_info.password) {
319 return cmdline_auth_info.password;
322 void set_cmdline_auth_info_password(const char *password)
324 SAFE_FREE(cmdline_auth_info.password);
325 cmdline_auth_info.password = SMB_STRDUP(password);
326 if (!cmdline_auth_info.password) {
329 cmdline_auth_info.got_pass = true;
332 bool set_cmdline_auth_info_signing_state(const char *arg)
334 cmdline_auth_info.signing_state = -1;
335 if (strequal(arg, "off") || strequal(arg, "no") ||
336 strequal(arg, "false")) {
337 cmdline_auth_info.signing_state = false;
338 } else if (strequal(arg, "on") || strequal(arg, "yes") ||
339 strequal(arg, "true") || strequal(arg, "auto")) {
340 cmdline_auth_info.signing_state = true;
341 } else if (strequal(arg, "force") || strequal(arg, "required") ||
342 strequal(arg, "forced")) {
343 cmdline_auth_info.signing_state = Required;
350 int get_cmdline_auth_info_signing_state(void)
352 return cmdline_auth_info.signing_state;
355 bool get_cmdline_auth_info_use_kerberos(void)
357 return cmdline_auth_info.use_kerberos;
360 /* This should only be used by lib/popt_common.c JRA */
361 void set_cmdline_auth_info_use_krb5_ticket(void)
363 cmdline_auth_info.use_kerberos = true;
364 cmdline_auth_info.got_pass = true;
367 /* This should only be used by lib/popt_common.c JRA */
368 void set_cmdline_auth_info_smb_encrypt(void)
370 cmdline_auth_info.smb_encrypt = true;
373 bool get_cmdline_auth_info_got_pass(void)
375 return cmdline_auth_info.got_pass;
378 bool get_cmdline_auth_info_smb_encrypt(void)
380 return cmdline_auth_info.smb_encrypt;
383 bool get_cmdline_auth_info_copy(struct user_auth_info *info)
385 *info = cmdline_auth_info;
386 /* Now re-alloc the strings. */
387 info->username = SMB_STRDUP(get_cmdline_auth_info_username());
388 info->password = SMB_STRDUP(get_cmdline_auth_info_password());
389 if (!info->username || !info->password) {
395 /**************************************************************************n
396 Find a suitable temporary directory. The result should be copied immediately
397 as it may be overwritten by a subsequent call.
398 ****************************************************************************/
400 const char *tmpdir(void)
403 if ((p = getenv("TMPDIR")))
408 /****************************************************************************
409 Add a gid to an array of gids if it's not already there.
410 ****************************************************************************/
412 bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
413 gid_t **gids, size_t *num_gids)
417 if ((*num_gids != 0) && (*gids == NULL)) {
419 * A former call to this routine has failed to allocate memory
424 for (i=0; i<*num_gids; i++) {
425 if ((*gids)[i] == gid) {
430 *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1);
436 (*gids)[*num_gids] = gid;
441 /****************************************************************************
442 Like atoi but gets the value up to the separator character.
443 ****************************************************************************/
445 static const char *Atoic(const char *p, int *n, const char *c)
447 if (!isdigit((int)*p)) {
448 DEBUG(5, ("Atoic: malformed number\n"));
454 while ((*p) && isdigit((int)*p))
457 if (strchr_m(c, *p) == NULL) {
458 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
465 /*************************************************************************
466 Reads a list of numbers.
467 *************************************************************************/
469 const char *get_numlist(const char *p, uint32 **num, int *count)
473 if (num == NULL || count == NULL)
479 while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
480 *num = SMB_REALLOC_ARRAY((*num), uint32, (*count)+1);
484 (*num)[(*count)] = val;
492 /*******************************************************************
493 Check if a file exists - call vfs_file_exist for samba files.
494 ********************************************************************/
496 bool file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
502 if (sys_stat(fname,sbuf) != 0)
505 return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
508 /*******************************************************************
509 Check a files mod time.
510 ********************************************************************/
512 time_t file_modtime(const char *fname)
516 if (sys_stat(fname,&st) != 0)
522 /*******************************************************************
523 Check if a directory exists.
524 ********************************************************************/
526 bool directory_exist(char *dname,SMB_STRUCT_STAT *st)
534 if (sys_stat(dname,st) != 0)
537 ret = S_ISDIR(st->st_mode);
543 /*******************************************************************
544 Returns the size in bytes of the named file.
545 ********************************************************************/
547 SMB_OFF_T get_file_size(char *file_name)
551 if(sys_stat(file_name,&buf) != 0)
552 return (SMB_OFF_T)-1;
556 /*******************************************************************
557 Return a string representing an attribute for a file.
558 ********************************************************************/
560 char *attrib_string(uint16 mode)
566 if (mode & aVOLID) fstrcat(attrstr,"V");
567 if (mode & aDIR) fstrcat(attrstr,"D");
568 if (mode & aARCH) fstrcat(attrstr,"A");
569 if (mode & aHIDDEN) fstrcat(attrstr,"H");
570 if (mode & aSYSTEM) fstrcat(attrstr,"S");
571 if (mode & aRONLY) fstrcat(attrstr,"R");
573 return talloc_strdup(talloc_tos(), attrstr);
576 /*******************************************************************
577 Show a smb message structure.
578 ********************************************************************/
580 void show_msg(char *buf)
588 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
590 (int)CVAL(buf,smb_com),
591 (int)CVAL(buf,smb_rcls),
592 (int)CVAL(buf,smb_reh),
593 (int)SVAL(buf,smb_err),
594 (int)CVAL(buf,smb_flg),
595 (int)SVAL(buf,smb_flg2)));
596 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
597 (int)SVAL(buf,smb_tid),
598 (int)SVAL(buf,smb_pid),
599 (int)SVAL(buf,smb_uid),
600 (int)SVAL(buf,smb_mid)));
601 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
603 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
604 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
605 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
607 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
609 DEBUGADD(5,("smb_bcc=%d\n",bcc));
617 dump_data(10, (uint8 *)smb_buf(buf), bcc);
620 /*******************************************************************
621 Set the length and marker of an encrypted smb packet.
622 ********************************************************************/
624 void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num)
626 _smb_setlen(buf,len);
630 SSVAL(buf,6,enc_ctx_num);
633 /*******************************************************************
634 Set the length and marker of an smb packet.
635 ********************************************************************/
637 void smb_setlen(char *buf,int len)
639 _smb_setlen(buf,len);
647 /*******************************************************************
648 Setup only the byte count for a smb message.
649 ********************************************************************/
651 int set_message_bcc(char *buf,int num_bytes)
653 int num_words = CVAL(buf,smb_wct);
654 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
655 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
656 return (smb_size + num_words*2 + num_bytes);
659 /*******************************************************************
660 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
661 Return the bytes added
662 ********************************************************************/
664 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
666 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
669 if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
670 DEBUG(0, ("talloc failed\n"));
675 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
676 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
680 /*******************************************************************
681 Reduce a file name, removing .. elements.
682 ********************************************************************/
684 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
689 DEBUG(3,("dos_clean_name [%s]\n",s));
691 /* remove any double slashes */
692 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
697 /* Remove leading .\\ characters */
698 if(strncmp(str, ".\\", 2) == 0) {
699 trim_string(str, ".\\", NULL);
701 str = talloc_strdup(ctx, ".\\");
708 while ((p = strstr_m(str,"\\..\\")) != NULL) {
714 if ((p=strrchr_m(str,'\\')) != NULL) {
719 str = talloc_asprintf(ctx,
728 trim_string(str,NULL,"\\..");
729 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
732 /*******************************************************************
733 Reduce a file name, removing .. elements.
734 ********************************************************************/
736 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
741 DEBUG(3,("unix_clean_name [%s]\n",s));
743 /* remove any double slashes */
744 str = talloc_all_string_sub(ctx, s, "//","/");
749 /* Remove leading ./ characters */
750 if(strncmp(str, "./", 2) == 0) {
751 trim_string(str, "./", NULL);
753 str = talloc_strdup(ctx, "./");
760 while ((p = strstr_m(str,"/../")) != NULL) {
766 if ((p=strrchr_m(str,'/')) != NULL) {
771 str = talloc_asprintf(ctx,
780 trim_string(str,NULL,"/..");
781 return talloc_all_string_sub(ctx, str, "/./", "/");
784 char *clean_name(TALLOC_CTX *ctx, const char *s)
786 char *str = dos_clean_name(ctx, s);
790 return unix_clean_name(ctx, str);
793 /*******************************************************************
794 Close the low 3 fd's and open dev/null in their place.
795 ********************************************************************/
797 void close_low_fds(bool stderr_too)
809 /* try and use up these file descriptors, so silly
810 library routines writing to stdout etc won't cause havoc */
812 if (i == 2 && !stderr_too)
815 fd = sys_open("/dev/null",O_RDWR,0);
817 fd = sys_open("/dev/null",O_WRONLY,0);
819 DEBUG(0,("Can't open /dev/null\n"));
823 DEBUG(0,("Didn't get file descriptor %d\n",i));
830 /*******************************************************************
831 Write data into an fd at a given offset. Ignore seek errors.
832 ********************************************************************/
834 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
839 if (pos == (SMB_OFF_T)-1) {
840 return write_data(fd, buffer, N);
842 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
844 ret = sys_pwrite(fd,buffer + total,N - total, pos);
845 if (ret == -1 && errno == ESPIPE) {
846 return write_data(fd, buffer + total,N - total);
849 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
858 return (ssize_t)total;
860 /* Use lseek and write_data. */
861 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
862 if (errno != ESPIPE) {
866 return write_data(fd, buffer, N);
870 /****************************************************************************
871 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
875 ****************************************************************************/
877 int set_blocking(int fd, bool set)
881 #define FLAG_TO_SET O_NONBLOCK
884 #define FLAG_TO_SET O_NDELAY
886 #define FLAG_TO_SET FNDELAY
890 if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
892 if(set) /* Turn blocking on - ie. clear nonblock flag */
896 return sys_fcntl_long( fd, F_SETFL, val);
900 /****************************************************************************
901 Transfer some data between two fd's.
902 ****************************************************************************/
904 #ifndef TRANSFER_BUF_SIZE
905 #define TRANSFER_BUF_SIZE 65536
908 ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t),
909 ssize_t (*write_fn)(int, const void *, size_t))
915 size_t num_to_read_thistime;
916 size_t num_written = 0;
918 if ((buf = SMB_MALLOC_ARRAY(char, TRANSFER_BUF_SIZE)) == NULL)
922 num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
924 read_ret = (*read_fn)(infd, buf, num_to_read_thistime);
925 if (read_ret == -1) {
926 DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) ));
935 while (num_written < read_ret) {
936 write_ret = (*write_fn)(outfd,buf + num_written, read_ret - num_written);
938 if (write_ret == -1) {
939 DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) ));
944 return (ssize_t)total;
946 num_written += (size_t)write_ret;
949 total += (size_t)read_ret;
953 return (ssize_t)total;
956 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
958 return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, sys_read, sys_write);
961 /*******************************************************************
962 Sleep for a specified number of milliseconds.
963 ********************************************************************/
965 void smb_msleep(unsigned int t)
967 #if defined(HAVE_NANOSLEEP)
968 struct timespec tval;
971 tval.tv_sec = t/1000;
972 tval.tv_nsec = 1000000*(t%1000);
976 ret = nanosleep(&tval, &tval);
977 } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
979 unsigned int tdiff=0;
980 struct timeval tval,t1,t2;
987 tval.tv_sec = (t-tdiff)/1000;
988 tval.tv_usec = 1000*((t-tdiff)%1000);
990 /* Never wait for more than 1 sec. */
991 if (tval.tv_sec > 1) {
998 sys_select_intr(0,&fds,NULL,NULL,&tval);
1001 if (t2.tv_sec < t1.tv_sec) {
1002 /* Someone adjusted time... */
1006 tdiff = TvalDiff(&t1,&t2);
1011 /****************************************************************************
1012 Become a daemon, discarding the controlling terminal.
1013 ****************************************************************************/
1015 void become_daemon(bool Fork, bool no_process_group)
1023 /* detach from the terminal */
1025 if (!no_process_group) setsid();
1026 #elif defined(TIOCNOTTY)
1027 if (!no_process_group) {
1028 int i = sys_open("/dev/tty", O_RDWR, 0);
1030 ioctl(i, (int) TIOCNOTTY, (char *)0);
1034 #endif /* HAVE_SETSID */
1036 /* Close fd's 0,1,2. Needed if started by rsh */
1037 close_low_fds(False); /* Don't close stderr, let the debug system
1038 attach it to the logfile */
1041 /****************************************************************************
1042 Put up a yes/no prompt.
1043 ****************************************************************************/
1045 bool yesno(const char *p)
1050 if (!fgets(ans,sizeof(ans)-1,stdin))
1053 if (*ans == 'y' || *ans == 'Y')
1059 #if defined(PARANOID_MALLOC_CHECKER)
1061 /****************************************************************************
1062 Internal malloc wrapper. Externally visible.
1063 ****************************************************************************/
1065 void *malloc_(size_t size)
1071 return malloc(size);
1072 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
1075 /****************************************************************************
1076 Internal calloc wrapper. Not externally visible.
1077 ****************************************************************************/
1079 static void *calloc_(size_t count, size_t size)
1081 if (size == 0 || count == 0) {
1085 return calloc(count, size);
1086 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
1089 /****************************************************************************
1090 Internal realloc wrapper. Not externally visible.
1091 ****************************************************************************/
1093 static void *realloc_(void *ptr, size_t size)
1096 return realloc(ptr, size);
1097 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
1100 #endif /* PARANOID_MALLOC_CHECKER */
1102 /****************************************************************************
1104 ****************************************************************************/
1106 void *malloc_array(size_t el_size, unsigned int count)
1108 if (count >= MAX_ALLOC_SIZE/el_size) {
1112 if (el_size == 0 || count == 0) {
1115 #if defined(PARANOID_MALLOC_CHECKER)
1116 return malloc_(el_size*count);
1118 return malloc(el_size*count);
1122 /****************************************************************************
1124 ****************************************************************************/
1126 void *memalign_array(size_t el_size, size_t align, unsigned int count)
1128 if (count >= MAX_ALLOC_SIZE/el_size) {
1132 return sys_memalign(align, el_size*count);
1135 /****************************************************************************
1137 ****************************************************************************/
1139 void *calloc_array(size_t size, size_t nmemb)
1141 if (nmemb >= MAX_ALLOC_SIZE/size) {
1144 if (size == 0 || nmemb == 0) {
1147 #if defined(PARANOID_MALLOC_CHECKER)
1148 return calloc_(nmemb, size);
1150 return calloc(nmemb, size);
1154 /****************************************************************************
1155 Expand a pointer to be a particular size.
1156 Note that this version of Realloc has an extra parameter that decides
1157 whether to free the passed in storage on allocation failure or if the
1160 This is designed for use in the typical idiom of :
1162 p = SMB_REALLOC(p, size)
1167 and not to have to keep track of the old 'p' contents to free later, nor
1168 to worry if the size parameter was zero. In the case where NULL is returned
1169 we guarentee that p has been freed.
1171 If free later semantics are desired, then pass 'free_old_on_error' as False which
1172 guarentees that the old contents are not freed on error, even if size == 0. To use
1175 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
1183 Changes were instigated by Coverity error checking. JRA.
1184 ****************************************************************************/
1186 void *Realloc(void *p, size_t size, bool free_old_on_error)
1191 if (free_old_on_error) {
1194 DEBUG(2,("Realloc asked for 0 bytes\n"));
1198 #if defined(PARANOID_MALLOC_CHECKER)
1200 ret = (void *)malloc_(size);
1202 ret = (void *)realloc_(p,size);
1206 ret = (void *)malloc(size);
1208 ret = (void *)realloc(p,size);
1213 if (free_old_on_error && p) {
1216 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1222 /****************************************************************************
1224 ****************************************************************************/
1226 void *realloc_array(void *p, size_t el_size, unsigned int count, bool free_old_on_error)
1228 if (count >= MAX_ALLOC_SIZE/el_size) {
1229 if (free_old_on_error) {
1234 return Realloc(p, el_size*count, free_old_on_error);
1237 /****************************************************************************
1238 (Hopefully) efficient array append.
1239 ****************************************************************************/
1241 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1242 void *element, void *_array, uint32 *num_elements,
1243 ssize_t *array_size)
1245 void **array = (void **)_array;
1247 if (*array_size < 0) {
1251 if (*array == NULL) {
1252 if (*array_size == 0) {
1256 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1260 *array = TALLOC(mem_ctx, element_size * (*array_size));
1261 if (*array == NULL) {
1266 if (*num_elements == *array_size) {
1269 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1273 *array = TALLOC_REALLOC(mem_ctx, *array,
1274 element_size * (*array_size));
1276 if (*array == NULL) {
1281 memcpy((char *)(*array) + element_size*(*num_elements),
1282 element, element_size);
1292 /****************************************************************************
1293 Free memory, checks for NULL.
1294 Use directly SAFE_FREE()
1295 Exists only because we need to pass a function pointer somewhere --SSS
1296 ****************************************************************************/
1298 void safe_free(void *p)
1303 /****************************************************************************
1304 Get my own name and IP.
1305 ****************************************************************************/
1307 char *get_myname(TALLOC_CTX *ctx)
1310 char hostname[HOST_NAME_MAX];
1314 /* get my host name */
1315 if (gethostname(hostname, sizeof(hostname)) == -1) {
1316 DEBUG(0,("gethostname failed\n"));
1320 /* Ensure null termination. */
1321 hostname[sizeof(hostname)-1] = '\0';
1323 /* split off any parts after an initial . */
1324 p = strchr_m(hostname,'.');
1329 return talloc_strdup(ctx, hostname);
1332 /****************************************************************************
1333 Get my own domain name, or "" if we have none.
1334 ****************************************************************************/
1336 char *get_mydnsdomname(TALLOC_CTX *ctx)
1338 const char *domname;
1341 domname = get_mydnsfullname();
1346 p = strchr_m(domname, '.');
1349 return talloc_strdup(ctx, p);
1351 return talloc_strdup(ctx, "");
1355 /****************************************************************************
1356 Interpret a protocol description string, with a default.
1357 ****************************************************************************/
1359 int interpret_protocol(const char *str,int def)
1361 if (strequal(str,"NT1"))
1362 return(PROTOCOL_NT1);
1363 if (strequal(str,"LANMAN2"))
1364 return(PROTOCOL_LANMAN2);
1365 if (strequal(str,"LANMAN1"))
1366 return(PROTOCOL_LANMAN1);
1367 if (strequal(str,"CORE"))
1368 return(PROTOCOL_CORE);
1369 if (strequal(str,"COREPLUS"))
1370 return(PROTOCOL_COREPLUS);
1371 if (strequal(str,"CORE+"))
1372 return(PROTOCOL_COREPLUS);
1374 DEBUG(0,("Unrecognised protocol level %s\n",str));
1380 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1381 /******************************************************************
1382 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1383 Based on a fix from <Thomas.Hepper@icem.de>.
1384 Returns a malloc'ed string.
1385 *******************************************************************/
1387 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
1390 const char *p = str;
1391 while(*p && !isspace(*p))
1393 while(*p && isspace(*p))
1396 return talloc_strdup(ctx, p);
1402 /*******************************************************************
1403 Patch from jkf@soton.ac.uk
1404 Split Luke's automount_server into YP lookup and string splitter
1405 so can easily implement automount_path().
1406 Returns a malloc'ed string.
1407 *******************************************************************/
1409 #ifdef WITH_NISPLUS_HOME
1410 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1414 char *nis_map = (char *)lp_nis_home_map_name();
1416 char buffer[NIS_MAXATTRVAL + 1];
1421 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
1422 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1424 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1425 if (result->status != NIS_SUCCESS) {
1426 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1428 object = result->objects.objects_val;
1429 if (object->zo_data.zo_type == ENTRY_OBJ) {
1430 entry = &object->zo_data.objdata_u.en_data;
1431 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1432 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1434 value = talloc_strdup(ctx,
1435 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1437 nis_freeresult(result);
1440 value = talloc_string_sub(ctx,
1447 nis_freeresult(result);
1450 value = strip_mount_options(ctx, value);
1451 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
1456 #else /* WITH_NISPLUS_HOME */
1458 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1462 int nis_error; /* returned by yp all functions */
1463 char *nis_result; /* yp_match inits this */
1464 int nis_result_len; /* and set this */
1465 char *nis_domain; /* yp_get_default_domain inits this */
1466 char *nis_map = (char *)lp_nis_home_map_name();
1468 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1469 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1473 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1475 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
1476 strlen(user_name), &nis_result,
1477 &nis_result_len)) == 0) {
1478 value = talloc_strdup(ctx, nis_result);
1482 value = strip_mount_options(ctx, value);
1483 } else if(nis_error == YPERR_KEY) {
1484 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1485 user_name, nis_map));
1486 DEBUG(3, ("using defaults for server and home directory\n"));
1488 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1489 yperr_string(nis_error), user_name, nis_map));
1493 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
1497 #endif /* WITH_NISPLUS_HOME */
1500 /****************************************************************************
1501 Check if a process exists. Does this work on all unixes?
1502 ****************************************************************************/
1504 bool process_exists(const struct server_id pid)
1506 if (procid_is_me(&pid)) {
1510 if (procid_is_local(&pid)) {
1511 return (kill(pid.pid,0) == 0 || errno != ESRCH);
1514 #ifdef CLUSTER_SUPPORT
1515 return ctdbd_process_exists(messaging_ctdbd_connection(), pid.vnn,
1522 bool process_exists_by_pid(pid_t pid)
1524 /* Doing kill with a non-positive pid causes messages to be
1525 * sent to places we don't want. */
1526 SMB_ASSERT(pid > 0);
1527 return(kill(pid,0) == 0 || errno != ESRCH);
1530 /*******************************************************************
1531 Convert a uid into a user name.
1532 ********************************************************************/
1534 const char *uidtoname(uid_t uid)
1536 TALLOC_CTX *ctx = talloc_tos();
1538 struct passwd *pass = NULL;
1540 pass = getpwuid_alloc(ctx,uid);
1542 name = talloc_strdup(ctx,pass->pw_name);
1545 name = talloc_asprintf(ctx,
1552 /*******************************************************************
1553 Convert a gid into a group name.
1554 ********************************************************************/
1556 char *gidtoname(gid_t gid)
1560 grp = getgrgid(gid);
1562 return talloc_strdup(talloc_tos(), grp->gr_name);
1565 return talloc_asprintf(talloc_tos(),
1571 /*******************************************************************
1572 Convert a user name into a uid.
1573 ********************************************************************/
1575 uid_t nametouid(const char *name)
1577 struct passwd *pass;
1581 pass = getpwnam_alloc(NULL, name);
1588 u = (uid_t)strtol(name, &p, 0);
1589 if ((p != name) && (*p == '\0'))
1595 /*******************************************************************
1596 Convert a name to a gid_t if possible. Return -1 if not a group.
1597 ********************************************************************/
1599 gid_t nametogid(const char *name)
1605 g = (gid_t)strtol(name, &p, 0);
1606 if ((p != name) && (*p == '\0'))
1609 grp = sys_getgrnam(name);
1611 return(grp->gr_gid);
1615 /*******************************************************************
1616 Something really nasty happened - panic !
1617 ********************************************************************/
1619 void smb_panic(const char *const why)
1627 if (global_clobber_region_function) {
1628 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1629 global_clobber_region_function,
1630 global_clobber_region_line));
1635 DEBUG(0,("PANIC (pid %llu): %s\n",
1636 (unsigned long long)sys_getpid(), why));
1639 cmd = lp_panic_action();
1641 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1642 result = system(cmd);
1645 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1648 DEBUG(0, ("smb_panic(): action returned status %d\n",
1649 WEXITSTATUS(result)));
1655 /*******************************************************************
1656 Print a backtrace of the stack to the debug log. This function
1657 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1658 exit shortly after calling it.
1659 ********************************************************************/
1661 #ifdef HAVE_LIBUNWIND_H
1662 #include <libunwind.h>
1665 #ifdef HAVE_EXECINFO_H
1666 #include <execinfo.h>
1669 #ifdef HAVE_LIBEXC_H
1673 void log_stack_trace(void)
1675 #ifdef HAVE_LIBUNWIND
1676 /* Try to use libunwind before any other technique since on ia64
1677 * libunwind correctly walks the stack in more circumstances than
1680 unw_cursor_t cursor;
1685 unw_word_t ip, sp, off;
1687 procname[sizeof(procname) - 1] = '\0';
1689 if (unw_getcontext(&uc) != 0) {
1690 goto libunwind_failed;
1693 if (unw_init_local(&cursor, &uc) != 0) {
1694 goto libunwind_failed;
1697 DEBUG(0, ("BACKTRACE:\n"));
1701 unw_get_reg(&cursor, UNW_REG_IP, &ip);
1702 unw_get_reg(&cursor, UNW_REG_SP, &sp);
1704 switch (unw_get_proc_name(&cursor,
1705 procname, sizeof(procname) - 1, &off) ) {
1709 /* Name truncated. */
1710 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1711 i, procname, (long long)off,
1712 (long long)ip, (long long) sp));
1715 /* case -UNW_ENOINFO: */
1716 /* case -UNW_EUNSPEC: */
1717 /* No symbol name found. */
1718 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1719 i, "<unknown symbol>",
1720 (long long)ip, (long long) sp));
1723 } while (unw_step(&cursor) > 0);
1728 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1730 #elif HAVE_BACKTRACE_SYMBOLS
1731 void *backtrace_stack[BACKTRACE_STACK_SIZE];
1732 size_t backtrace_size;
1733 char **backtrace_strings;
1735 /* get the backtrace (stack frames) */
1736 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1737 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1739 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1740 (unsigned long)backtrace_size));
1742 if (backtrace_strings) {
1745 for (i = 0; i < backtrace_size; i++)
1746 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1748 /* Leak the backtrace_strings, rather than risk what free() might do */
1753 /* The IRIX libexc library provides an API for unwinding the stack. See
1754 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1755 * since we are about to abort anyway, it hardly matters.
1758 #define NAMESIZE 32 /* Arbitrary */
1760 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1761 char * names[BACKTRACE_STACK_SIZE];
1762 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1769 ZERO_ARRAY(namebuf);
1771 /* We need to be root so we can open our /proc entry to walk
1772 * our stack. It also helps when we want to dump core.
1776 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1777 names[i] = namebuf + (i * NAMESIZE);
1780 levels = trace_back_stack(0, addrs, names,
1781 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1783 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1784 for (i = 0; i < levels; i++) {
1785 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1790 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1794 /*******************************************************************
1795 A readdir wrapper which just returns the file name.
1796 ********************************************************************/
1798 const char *readdirname(SMB_STRUCT_DIR *p)
1800 SMB_STRUCT_DIRENT *ptr;
1806 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1810 dname = ptr->d_name;
1817 #ifdef HAVE_BROKEN_READDIR_NAME
1818 /* using /usr/ucb/cc is BAD */
1822 return talloc_strdup(talloc_tos(), dname);
1825 /*******************************************************************
1826 Utility function used to decide if the last component
1827 of a path matches a (possibly wildcarded) entry in a namelist.
1828 ********************************************************************/
1830 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1832 const char *last_component;
1834 /* if we have no list it's obviously not in the path */
1835 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1839 DEBUG(8, ("is_in_path: %s\n", name));
1841 /* Get the last component of the unix name. */
1842 last_component = strrchr_m(name, '/');
1843 if (!last_component) {
1844 last_component = name;
1846 last_component++; /* Go past '/' */
1849 for(; namelist->name != NULL; namelist++) {
1850 if(namelist->is_wild) {
1851 if (mask_match(last_component, namelist->name, case_sensitive)) {
1852 DEBUG(8,("is_in_path: mask match succeeded\n"));
1856 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1857 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1858 DEBUG(8,("is_in_path: match succeeded\n"));
1863 DEBUG(8,("is_in_path: match not found\n"));
1867 /*******************************************************************
1868 Strip a '/' separated list into an array of
1869 name_compare_enties structures suitable for
1870 passing to is_in_path(). We do this for
1871 speed so we can pre-parse all the names in the list
1872 and don't do it for each call to is_in_path().
1873 namelist is modified here and is assumed to be
1874 a copy owned by the caller.
1875 We also check if the entry contains a wildcard to
1876 remove a potentially expensive call to mask_match
1878 ********************************************************************/
1880 void set_namearray(name_compare_entry **ppname_array, char *namelist)
1883 char *nameptr = namelist;
1884 int num_entries = 0;
1887 (*ppname_array) = NULL;
1889 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
1892 /* We need to make two passes over the string. The
1893 first to count the number of elements, the second
1898 if ( *nameptr == '/' ) {
1899 /* cope with multiple (useless) /s) */
1903 /* find the next / */
1904 name_end = strchr_m(nameptr, '/');
1906 /* oops - the last check for a / didn't find one. */
1907 if (name_end == NULL)
1910 /* next segment please */
1911 nameptr = name_end + 1;
1915 if(num_entries == 0)
1918 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1919 DEBUG(0,("set_namearray: malloc fail\n"));
1923 /* Now copy out the names */
1927 if ( *nameptr == '/' ) {
1928 /* cope with multiple (useless) /s) */
1932 /* find the next / */
1933 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1936 /* oops - the last check for a / didn't find one. */
1937 if(name_end == NULL)
1940 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1941 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1942 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1946 /* next segment please */
1947 nameptr = name_end + 1;
1951 (*ppname_array)[i].name = NULL;
1956 /****************************************************************************
1957 Routine to free a namearray.
1958 ****************************************************************************/
1960 void free_namearray(name_compare_entry *name_array)
1964 if(name_array == NULL)
1967 for(i=0; name_array[i].name!=NULL; i++)
1968 SAFE_FREE(name_array[i].name);
1969 SAFE_FREE(name_array);
1973 #define DBGC_CLASS DBGC_LOCKING
1975 /****************************************************************************
1976 Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
1977 is dealt with in posix.c
1978 Returns True if the lock was granted, False otherwise.
1979 ****************************************************************************/
1981 bool fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
1983 SMB_STRUCT_FLOCK lock;
1986 DEBUG(8,("fcntl_lock fd=%d op=%d offset=%.0f count=%.0f type=%d\n",
1987 fd,op,(double)offset,(double)count,type));
1990 lock.l_whence = SEEK_SET;
1991 lock.l_start = offset;
1995 ret = sys_fcntl_ptr(fd,op,&lock);
1999 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
2000 (double)offset,(double)count,op,type,strerror(errno)));
2005 /* everything went OK */
2006 DEBUG(8,("fcntl_lock: Lock call successful\n"));
2011 /****************************************************************************
2012 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
2013 is dealt with in posix.c
2014 Returns True if we have information regarding this lock region (and returns
2015 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
2016 ****************************************************************************/
2018 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
2020 SMB_STRUCT_FLOCK lock;
2023 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
2024 fd,(double)*poffset,(double)*pcount,*ptype));
2026 lock.l_type = *ptype;
2027 lock.l_whence = SEEK_SET;
2028 lock.l_start = *poffset;
2029 lock.l_len = *pcount;
2032 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
2036 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
2037 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
2042 *ptype = lock.l_type;
2043 *poffset = lock.l_start;
2044 *pcount = lock.l_len;
2047 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
2048 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
2053 #define DBGC_CLASS DBGC_ALL
2055 /*******************************************************************
2056 Is the name specified one of my netbios names.
2057 Returns true if it is equal, false otherwise.
2058 ********************************************************************/
2060 bool is_myname(const char *s)
2065 for (n=0; my_netbios_names(n); n++) {
2066 if (strequal(my_netbios_names(n), s)) {
2071 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2075 /*******************************************************************
2076 Is the name specified our workgroup/domain.
2077 Returns true if it is equal, false otherwise.
2078 ********************************************************************/
2080 bool is_myworkgroup(const char *s)
2084 if (strequal(s, lp_workgroup())) {
2088 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
2092 /*******************************************************************
2093 we distinguish between 2K and XP by the "Native Lan Manager" string
2094 WinXP => "Windows 2002 5.1"
2095 WinXP 64bit => "Windows XP 5.2"
2096 Win2k => "Windows 2000 5.0"
2097 NT4 => "Windows NT 4.0"
2098 Win9x => "Windows 4.0"
2099 Windows 2003 doesn't set the native lan manager string but
2100 they do set the domain to "Windows 2003 5.2" (probably a bug).
2101 ********************************************************************/
2103 void ra_lanman_string( const char *native_lanman )
2105 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
2106 set_remote_arch( RA_WINXP );
2107 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
2108 set_remote_arch( RA_WINXP );
2109 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
2110 set_remote_arch( RA_WIN2K3 );
2113 static const char *remote_arch_str;
2115 const char *get_remote_arch_str(void)
2117 if (!remote_arch_str) {
2120 return remote_arch_str;
2123 /*******************************************************************
2124 Set the horrid remote_arch string based on an enum.
2125 ********************************************************************/
2127 void set_remote_arch(enum remote_arch_types type)
2132 remote_arch_str = "WfWg";
2135 remote_arch_str = "OS2";
2138 remote_arch_str = "Win95";
2141 remote_arch_str = "WinNT";
2144 remote_arch_str = "Win2K";
2147 remote_arch_str = "WinXP";
2150 remote_arch_str = "Win2K3";
2153 remote_arch_str = "Vista";
2156 remote_arch_str = "Samba";
2159 remote_arch_str = "CIFSFS";
2162 ra_type = RA_UNKNOWN;
2163 remote_arch_str = "UNKNOWN";
2167 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
2171 /*******************************************************************
2172 Get the remote_arch type.
2173 ********************************************************************/
2175 enum remote_arch_types get_remote_arch(void)
2180 void print_asc(int level, const unsigned char *buf,int len)
2184 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2187 void dump_data(int level, const unsigned char *buf1,int len)
2189 const unsigned char *buf = (const unsigned char *)buf1;
2193 if (!DEBUGLVL(level)) return;
2195 DEBUGADD(level,("[%03X] ",i));
2197 DEBUGADD(level,("%02X ",(int)buf[i]));
2199 if (i%8 == 0) DEBUGADD(level,(" "));
2201 print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2202 print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2203 if (i<len) DEBUGADD(level,("[%03X] ",i));
2209 DEBUGADD(level,(" "));
2210 if (n>8) DEBUGADD(level,(" "));
2211 while (n--) DEBUGADD(level,(" "));
2213 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2215 if (n>0) print_asc(level,&buf[i-n],n);
2216 DEBUGADD(level,("\n"));
2220 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2222 #ifdef DEBUG_PASSWORD
2223 DEBUG(11, ("%s", msg));
2224 if (data != NULL && len > 0)
2226 dump_data(11, data, len);
2231 const char *tab_depth(int level, int depth)
2233 if( DEBUGLVL(level) ) {
2234 dbgtext("%*s", depth*4, "");
2239 /*****************************************************************************
2240 Provide a checksum on a string
2242 Input: s - the null-terminated character string for which the checksum
2245 Output: The checksum value calculated for s.
2246 *****************************************************************************/
2248 int str_checksum(const char *s)
2256 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2263 /*****************************************************************
2264 Zero a memory area then free it. Used to catch bugs faster.
2265 *****************************************************************/
2267 void zero_free(void *p, size_t size)
2273 /*****************************************************************
2274 Set our open file limit to a requested max and return the limit.
2275 *****************************************************************/
2277 int set_maxfiles(int requested_max)
2279 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2281 int saved_current_limit;
2283 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2284 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2287 return requested_max;
2291 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2292 * account for the extra fd we need
2293 * as well as the log files and standard
2294 * handles etc. Save the limit we want to set in case
2295 * we are running on an OS that doesn't support this limit (AIX)
2296 * which always returns RLIM_INFINITY for rlp.rlim_max.
2299 /* Try raising the hard (max) limit to the requested amount. */
2301 #if defined(RLIM_INFINITY)
2302 if (rlp.rlim_max != RLIM_INFINITY) {
2303 int orig_max = rlp.rlim_max;
2305 if ( rlp.rlim_max < requested_max )
2306 rlp.rlim_max = requested_max;
2308 /* This failing is not an error - many systems (Linux) don't
2309 support our default request of 10,000 open files. JRA. */
2311 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2312 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2313 (int)rlp.rlim_max, strerror(errno) ));
2315 /* Set failed - restore original value from get. */
2316 rlp.rlim_max = orig_max;
2321 /* Now try setting the soft (current) limit. */
2323 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2325 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2326 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2327 (int)rlp.rlim_cur, strerror(errno) ));
2329 return saved_current_limit;
2332 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2333 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2336 return saved_current_limit;
2339 #if defined(RLIM_INFINITY)
2340 if(rlp.rlim_cur == RLIM_INFINITY)
2341 return saved_current_limit;
2344 if((int)rlp.rlim_cur > saved_current_limit)
2345 return saved_current_limit;
2347 return rlp.rlim_cur;
2348 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2350 * No way to know - just guess...
2352 return requested_max;
2356 /*****************************************************************
2357 Possibly replace mkstemp if it is broken.
2358 *****************************************************************/
2360 int smb_mkstemp(char *name_template)
2362 #if HAVE_SECURE_MKSTEMP
2363 return mkstemp(name_template);
2365 /* have a reasonable go at emulating it. Hope that
2366 the system mktemp() isn't completly hopeless */
2367 char *p = mktemp(name_template);
2370 return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2374 /*****************************************************************
2375 malloc that aborts with smb_panic on fail or zero size.
2376 *****************************************************************/
2378 void *smb_xmalloc_array(size_t size, unsigned int count)
2382 smb_panic("smb_xmalloc_array: called with zero size");
2384 if (count >= MAX_ALLOC_SIZE/size) {
2385 smb_panic("smb_xmalloc_array: alloc size too large");
2387 if ((p = SMB_MALLOC(size*count)) == NULL) {
2388 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2389 (unsigned long)size, (unsigned long)count));
2390 smb_panic("smb_xmalloc_array: malloc failed");
2396 Memdup with smb_panic on fail.
2399 void *smb_xmemdup(const void *p, size_t size)
2402 p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2403 memcpy(p2, p, size);
2408 strdup that aborts on malloc fail.
2411 char *smb_xstrdup(const char *s)
2413 #if defined(PARANOID_MALLOC_CHECKER)
2420 #define strdup rep_strdup
2423 char *s1 = strdup(s);
2424 #if defined(PARANOID_MALLOC_CHECKER)
2428 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2431 smb_panic("smb_xstrdup: malloc failed");
2438 strndup that aborts on malloc fail.
2441 char *smb_xstrndup(const char *s, size_t n)
2443 #if defined(PARANOID_MALLOC_CHECKER)
2449 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
2451 #define strndup rep_strndup
2454 char *s1 = strndup(s, n);
2455 #if defined(PARANOID_MALLOC_CHECKER)
2459 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2462 smb_panic("smb_xstrndup: malloc failed");
2468 vasprintf that aborts on malloc fail
2471 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2478 n = vasprintf(ptr, format, ap2);
2479 if (n == -1 || ! *ptr) {
2480 smb_panic("smb_xvasprintf: out of memory");
2485 /*****************************************************************
2486 Like strdup but for memory.
2487 *****************************************************************/
2489 void *memdup(const void *p, size_t size)
2494 p2 = SMB_MALLOC(size);
2497 memcpy(p2, p, size);
2501 /*****************************************************************
2502 Get local hostname and cache result.
2503 *****************************************************************/
2505 char *myhostname(void)
2509 /* This is cached forever so
2510 * use NULL talloc ctx. */
2511 ret = get_myname(NULL);
2516 /*****************************************************************
2517 A useful function for returning a path in the Samba pid directory.
2518 *****************************************************************/
2520 static char *xx_path(const char *name, const char *rootpath)
2524 fname = talloc_strdup(talloc_tos(), rootpath);
2528 trim_string(fname,"","/");
2530 if (!directory_exist(fname,NULL)) {
2534 return talloc_asprintf(talloc_tos(),
2540 /*****************************************************************
2541 A useful function for returning a path in the Samba lock directory.
2542 *****************************************************************/
2544 char *lock_path(const char *name)
2546 return xx_path(name, lp_lockdir());
2549 /*****************************************************************
2550 A useful function for returning a path in the Samba pid directory.
2551 *****************************************************************/
2553 char *pid_path(const char *name)
2555 return xx_path(name, lp_piddir());
2559 * @brief Returns an absolute path to a file in the Samba lib directory.
2561 * @param name File to find, relative to LIBDIR.
2563 * @retval Pointer to a string containing the full path.
2566 char *lib_path(const char *name)
2568 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
2572 * @brief Returns an absolute path to a file in the Samba data directory.
2574 * @param name File to find, relative to CODEPAGEDIR.
2576 * @retval Pointer to a talloc'ed string containing the full path.
2579 char *data_path(const char *name)
2581 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
2584 /*****************************************************************
2585 a useful function for returning a path in the Samba state directory
2586 *****************************************************************/
2588 char *state_path(const char *name)
2590 return xx_path(name, get_dyn_STATEDIR());
2594 * @brief Returns the platform specific shared library extension.
2596 * @retval Pointer to a const char * containing the extension.
2599 const char *shlib_ext(void)
2601 return get_dyn_SHLIBEXT();
2604 /*******************************************************************
2605 Given a filename - get its directory name
2606 NB: Returned in static storage. Caveats:
2607 o If caller wishes to preserve, they should copy.
2608 ********************************************************************/
2610 char *parent_dirname(const char *path)
2614 if (!parent_dirname_talloc(talloc_tos(), path, &parent, NULL)) {
2621 bool parent_dirname_talloc(TALLOC_CTX *mem_ctx, const char *dir,
2622 char **parent, const char **name)
2627 p = strrchr_m(dir, '/'); /* Find final '/', if any */
2630 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2641 if (!(*parent = TALLOC_ARRAY(mem_ctx, char, len+1))) {
2644 memcpy(*parent, dir, len);
2645 (*parent)[len] = '\0';
2653 /*******************************************************************
2654 Determine if a pattern contains any Microsoft wildcard characters.
2655 *******************************************************************/
2657 bool ms_has_wild(const char *s)
2661 if (lp_posix_pathnames()) {
2662 /* With posix pathnames no characters are wild. */
2666 while ((c = *s++)) {
2679 bool ms_has_wild_w(const smb_ucs2_t *s)
2682 if (!s) return False;
2683 while ((c = *s++)) {
2685 case UCS2_CHAR('*'):
2686 case UCS2_CHAR('?'):
2687 case UCS2_CHAR('<'):
2688 case UCS2_CHAR('>'):
2689 case UCS2_CHAR('"'):
2696 /*******************************************************************
2697 A wrapper that handles case sensitivity and the special handling
2699 *******************************************************************/
2701 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
2703 if (strcmp(string,"..") == 0)
2705 if (strcmp(pattern,".") == 0)
2708 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2711 /*******************************************************************
2712 A wrapper that handles case sensitivity and the special handling
2713 of the ".." name. Varient that is only called by old search code which requires
2714 pattern translation.
2715 *******************************************************************/
2717 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
2719 if (strcmp(string,"..") == 0)
2721 if (strcmp(pattern,".") == 0)
2724 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2727 /*******************************************************************
2728 A wrapper that handles a list of patters and calls mask_match()
2729 on each. Returns True if any of the patterns match.
2730 *******************************************************************/
2732 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
2734 while (listLen-- > 0) {
2735 if (mask_match(string, *list++, is_case_sensitive))
2741 /*********************************************************
2742 Recursive routine that is called by unix_wild_match.
2743 *********************************************************/
2745 static bool unix_do_match(const char *regexp, const char *str)
2749 for( p = regexp; *p && *str; ) {
2760 * Look for a character matching
2761 * the one after the '*'.
2765 return true; /* Automatic match */
2768 while(*str && (*p != *str))
2772 * Patch from weidel@multichart.de. In the case of the regexp
2773 * '*XX*' we want to ensure there are at least 2 'X' characters
2774 * in the string after the '*' for a match to be made.
2781 * Eat all the characters that match, but count how many there were.
2784 while(*str && (*p == *str)) {
2790 * Now check that if the regexp had n identical characters that
2791 * matchcount had at least that many matches.
2794 while ( *(p+1) && (*(p+1) == *p)) {
2799 if ( matchcount <= 0 )
2803 str--; /* We've eaten the match char after the '*' */
2805 if(unix_do_match(p, str))
2827 if (!*p && str[0] == '.' && str[1] == 0)
2830 if (!*str && *p == '?') {
2836 if(!*str && (*p == '*' && p[1] == '\0'))
2842 /*******************************************************************
2843 Simple case insensitive interface to a UNIX wildcard matcher.
2844 Returns True if match, False if not.
2845 *******************************************************************/
2847 bool unix_wild_match(const char *pattern, const char *string)
2849 TALLOC_CTX *ctx = talloc_stackframe();
2855 p2 = talloc_strdup(ctx,pattern);
2856 s2 = talloc_strdup(ctx,string);
2864 /* Remove any *? and ** from the pattern as they are meaningless */
2865 for(p = p2; *p; p++) {
2866 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
2867 memmove(&p[1], &p[2], strlen(&p[2])+1);
2871 if (strequal(p2,"*")) {
2876 ret = unix_do_match(p2, s2);
2881 /**********************************************************************
2882 Converts a name to a fully qualified domain name.
2883 Returns true if lookup succeeded, false if not (then fqdn is set to name)
2884 Note we deliberately use gethostbyname here, not getaddrinfo as we want
2885 to examine the h_aliases and I don't know how to do that with getaddrinfo.
2886 ***********************************************************************/
2888 bool name_to_fqdn(fstring fqdn, const char *name)
2891 struct hostent *hp = gethostbyname(name);
2893 if (!hp || !hp->h_name || !*hp->h_name) {
2894 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2895 fstrcpy(fqdn, name);
2899 /* Find out if the fqdn is returned as an alias
2900 * to cope with /etc/hosts files where the first
2901 * name is not the fqdn but the short name */
2902 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2904 for (i = 0; hp->h_aliases[i]; i++) {
2905 if (strchr_m(hp->h_aliases[i], '.')) {
2906 full = hp->h_aliases[i];
2911 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2912 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2913 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2914 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
2915 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
2922 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2923 fstrcpy(fqdn, full);
2927 /**********************************************************************
2928 Extension to talloc_get_type: Abort on type mismatch
2929 ***********************************************************************/
2931 void *talloc_check_name_abort(const void *ptr, const char *name)
2935 result = talloc_check_name(ptr, name);
2939 DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2940 name, talloc_get_name(ptr)));
2941 smb_panic("talloc type mismatch");
2942 /* Keep the compiler happy */
2946 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2948 switch (share_access & ~FILE_SHARE_DELETE) {
2949 case FILE_SHARE_NONE:
2951 case FILE_SHARE_READ:
2953 case FILE_SHARE_WRITE:
2955 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2958 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2960 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2967 pid_t procid_to_pid(const struct server_id *proc)
2972 static uint32 my_vnn = NONCLUSTER_VNN;
2974 void set_my_vnn(uint32 vnn)
2976 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
2980 uint32 get_my_vnn(void)
2985 struct server_id pid_to_procid(pid_t pid)
2987 struct server_id result;
2989 #ifdef CLUSTER_SUPPORT
2990 result.vnn = my_vnn;
2995 struct server_id procid_self(void)
2997 return pid_to_procid(sys_getpid());
3000 struct server_id server_id_self(void)
3002 return procid_self();
3005 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
3007 if (p1->pid != p2->pid)
3009 #ifdef CLUSTER_SUPPORT
3010 if (p1->vnn != p2->vnn)
3016 bool cluster_id_equal(const struct server_id *id1,
3017 const struct server_id *id2)
3019 return procid_equal(id1, id2);
3022 bool procid_is_me(const struct server_id *pid)
3024 if (pid->pid != sys_getpid())
3026 #ifdef CLUSTER_SUPPORT
3027 if (pid->vnn != my_vnn)
3033 struct server_id interpret_pid(const char *pid_string)
3035 #ifdef CLUSTER_SUPPORT
3036 unsigned int vnn, pid;
3037 struct server_id result;
3038 if (sscanf(pid_string, "%u:%u", &vnn, &pid) == 2) {
3042 else if (sscanf(pid_string, "%u", &pid) == 1) {
3043 result.vnn = NONCLUSTER_VNN;
3047 result.vnn = NONCLUSTER_VNN;
3052 return pid_to_procid(atoi(pid_string));
3056 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
3058 #ifdef CLUSTER_SUPPORT
3059 if (pid->vnn == NONCLUSTER_VNN) {
3060 return talloc_asprintf(mem_ctx,
3065 return talloc_asprintf(mem_ctx,
3071 return talloc_asprintf(mem_ctx,
3077 char *procid_str_static(const struct server_id *pid)
3079 return procid_str(talloc_tos(), pid);
3082 bool procid_valid(const struct server_id *pid)
3084 return (pid->pid != -1);
3087 bool procid_is_local(const struct server_id *pid)
3089 #ifdef CLUSTER_SUPPORT
3090 return pid->vnn == my_vnn;
3096 int this_is_smp(void)
3098 #if defined(HAVE_SYSCONF)
3100 #if defined(SYSCONF_SC_NPROC_ONLN)
3101 return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
3102 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3103 return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
3113 /****************************************************************
3114 Check if an offset into a buffer is safe.
3115 If this returns True it's safe to indirect into the byte at
3117 ****************************************************************/
3119 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3121 const char *end_base = buf_base + buf_len;
3122 char *end_ptr = ptr + off;
3124 if (!buf_base || !ptr) {
3128 if (end_base < buf_base || end_ptr < ptr) {
3129 return False; /* wrap. */
3132 if (end_ptr < end_base) {
3138 /****************************************************************
3139 Return a safe pointer into a buffer, or NULL.
3140 ****************************************************************/
3142 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3144 return is_offset_safe(buf_base, buf_len, ptr, off) ?
3148 /****************************************************************
3149 Return a safe pointer into a string within a buffer, or NULL.
3150 ****************************************************************/
3152 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3154 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
3157 /* Check if a valid string exists at this offset. */
3158 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
3164 /****************************************************************
3165 Return an SVAL at a pointer, or failval if beyond the end.
3166 ****************************************************************/
3168 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3171 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
3174 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
3177 return SVAL(ptr,off);
3180 /****************************************************************
3181 Return an IVAL at a pointer, or failval if beyond the end.
3182 ****************************************************************/
3184 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3187 * Note we use off+3 here, not off+4 as IVAL accesses
3188 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
3190 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
3193 return IVAL(ptr,off);
3196 /****************************************************************
3197 Split DOM\user into DOM and user. Do not mix with winbind variants of that
3198 call (they take care of winbind separator and other winbind specific settings).
3199 ****************************************************************/
3201 void split_domain_user(TALLOC_CTX *mem_ctx,
3202 const char *full_name,
3206 const char *p = NULL;
3208 p = strchr_m(full_name, '\\');
3211 *domain = talloc_strndup(mem_ctx, full_name,
3212 PTR_DIFF(p, full_name));
3213 *user = talloc_strdup(mem_ctx, p+1);
3215 *domain = talloc_strdup(mem_ctx, "");
3216 *user = talloc_strdup(mem_ctx, full_name);
3222 Disable these now we have checked all code paths and ensured
3223 NULL returns on zero request. JRA.
3225 /****************************************************************
3226 talloc wrapper functions that guarentee a null pointer return
3228 ****************************************************************/
3230 #ifndef MAX_TALLOC_SIZE
3231 #define MAX_TALLOC_SIZE 0x10000000
3235 * talloc and zero memory.
3236 * - returns NULL if size is zero.
3239 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
3247 p = talloc_named_const(ctx, size, name);
3250 memset(p, '\0', size);
3257 * memdup with a talloc.
3258 * - returns NULL if size is zero.
3261 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
3269 newp = talloc_named_const(t, size, name);
3271 memcpy(newp, p, size);
3278 * alloc an array, checking for integer overflow in the array size.
3279 * - returns NULL if count or el_size are zero.
3282 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3284 if (count >= MAX_TALLOC_SIZE/el_size) {
3288 if (el_size == 0 || count == 0) {
3292 return talloc_named_const(ctx, el_size * count, name);
3296 * alloc an zero array, checking for integer overflow in the array size
3297 * - returns NULL if count or el_size are zero.
3300 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3302 if (count >= MAX_TALLOC_SIZE/el_size) {
3306 if (el_size == 0 || count == 0) {
3310 return _talloc_zero(ctx, el_size * count, name);
3314 * Talloc wrapper that returns NULL if size == 0.
3316 void *talloc_zeronull(const void *context, size_t size, const char *name)
3321 return talloc_named_const(context, size, name);