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 /* a default finfo structure to ensure all fields are sensible */
63 /* this is used by the chaining code */
68 static enum remote_arch_types ra_type
= RA_UNKNOWN
;
70 /***********************************************************************
71 Definitions for all names.
72 ***********************************************************************/
74 static char *smb_myname
;
75 static char *smb_myworkgroup
;
76 static char *smb_scope
;
77 static int smb_num_netbios_names
;
78 static char **smb_my_netbios_names
;
80 /***********************************************************************
81 Allocate and set myname. Ensure upper case.
82 ***********************************************************************/
84 bool set_global_myname(const char *myname
)
86 SAFE_FREE(smb_myname
);
87 smb_myname
= SMB_STRDUP(myname
);
90 strupper_m(smb_myname
);
94 const char *global_myname(void)
99 /***********************************************************************
100 Allocate and set myworkgroup. Ensure upper case.
101 ***********************************************************************/
103 bool set_global_myworkgroup(const char *myworkgroup
)
105 SAFE_FREE(smb_myworkgroup
);
106 smb_myworkgroup
= SMB_STRDUP(myworkgroup
);
107 if (!smb_myworkgroup
)
109 strupper_m(smb_myworkgroup
);
113 const char *lp_workgroup(void)
115 return smb_myworkgroup
;
118 /***********************************************************************
119 Allocate and set scope. Ensure upper case.
120 ***********************************************************************/
122 bool set_global_scope(const char *scope
)
124 SAFE_FREE(smb_scope
);
125 smb_scope
= SMB_STRDUP(scope
);
128 strupper_m(smb_scope
);
132 /*********************************************************************
133 Ensure scope is never null string.
134 *********************************************************************/
136 const char *global_scope(void)
139 set_global_scope("");
143 static void free_netbios_names_array(void)
147 for (i
= 0; i
< smb_num_netbios_names
; i
++)
148 SAFE_FREE(smb_my_netbios_names
[i
]);
150 SAFE_FREE(smb_my_netbios_names
);
151 smb_num_netbios_names
= 0;
154 static bool allocate_my_netbios_names_array(size_t number
)
156 free_netbios_names_array();
158 smb_num_netbios_names
= number
+ 1;
159 smb_my_netbios_names
= SMB_MALLOC_ARRAY( char *, smb_num_netbios_names
);
161 if (!smb_my_netbios_names
)
164 memset(smb_my_netbios_names
, '\0', sizeof(char *) * smb_num_netbios_names
);
168 static bool set_my_netbios_names(const char *name
, int i
)
170 SAFE_FREE(smb_my_netbios_names
[i
]);
172 smb_my_netbios_names
[i
] = SMB_STRDUP(name
);
173 if (!smb_my_netbios_names
[i
])
175 strupper_m(smb_my_netbios_names
[i
]);
179 /***********************************************************************
180 Free memory allocated to global objects
181 ***********************************************************************/
183 void gfree_names(void)
185 SAFE_FREE( smb_myname
);
186 SAFE_FREE( smb_myworkgroup
);
187 SAFE_FREE( smb_scope
);
188 free_netbios_names_array();
191 void gfree_all( void )
200 /* release the talloc null_context memory last */
201 talloc_disable_null_tracking();
204 const char *my_netbios_names(int i
)
206 return smb_my_netbios_names
[i
];
209 bool set_netbios_aliases(const char **str_array
)
213 /* Work out the max number of netbios aliases that we have */
214 for( namecount
=0; str_array
&& (str_array
[namecount
] != NULL
); namecount
++ )
217 if ( global_myname() && *global_myname())
220 /* Allocate space for the netbios aliases */
221 if (!allocate_my_netbios_names_array(namecount
))
224 /* Use the global_myname string first */
226 if ( global_myname() && *global_myname()) {
227 set_my_netbios_names( global_myname(), namecount
);
233 for ( i
= 0; str_array
[i
] != NULL
; i
++) {
235 bool duplicate
= False
;
237 /* Look for duplicates */
238 for( n
=0; n
<namecount
; n
++ ) {
239 if( strequal( str_array
[i
], my_netbios_names(n
) ) ) {
245 if (!set_my_netbios_names(str_array
[i
], namecount
))
254 /****************************************************************************
255 Common name initialization code.
256 ****************************************************************************/
258 bool init_names(void)
262 if (global_myname() == NULL
|| *global_myname() == '\0') {
263 if (!set_global_myname(myhostname())) {
264 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
269 if (!set_netbios_aliases(lp_netbios_aliases())) {
270 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
274 set_local_machine_name(global_myname(),false);
276 DEBUG( 5, ("Netbios name list:-\n") );
277 for( n
=0; my_netbios_names(n
); n
++ ) {
278 DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",
279 n
, my_netbios_names(n
) ) );
285 /**************************************************************************n
286 Find a suitable temporary directory. The result should be copied immediately
287 as it may be overwritten by a subsequent call.
288 ****************************************************************************/
290 const char *tmpdir(void)
293 if ((p
= getenv("TMPDIR")))
298 /****************************************************************************
299 Add a gid to an array of gids if it's not already there.
300 ****************************************************************************/
302 bool add_gid_to_array_unique(TALLOC_CTX
*mem_ctx
, gid_t gid
,
303 gid_t
**gids
, size_t *num_gids
)
307 if ((*num_gids
!= 0) && (*gids
== NULL
)) {
309 * A former call to this routine has failed to allocate memory
314 for (i
=0; i
<*num_gids
; i
++) {
315 if ((*gids
)[i
] == gid
) {
320 *gids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *gids
, gid_t
, *num_gids
+1);
326 (*gids
)[*num_gids
] = gid
;
331 /****************************************************************************
332 Like atoi but gets the value up to the separator character.
333 ****************************************************************************/
335 static const char *Atoic(const char *p
, int *n
, const char *c
)
337 if (!isdigit((int)*p
)) {
338 DEBUG(5, ("Atoic: malformed number\n"));
344 while ((*p
) && isdigit((int)*p
))
347 if (strchr_m(c
, *p
) == NULL
) {
348 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c
));
355 /*************************************************************************
356 Reads a list of numbers.
357 *************************************************************************/
359 const char *get_numlist(const char *p
, uint32
**num
, int *count
)
363 if (num
== NULL
|| count
== NULL
)
369 while ((p
= Atoic(p
, &val
, ":,")) != NULL
&& (*p
) != ':') {
370 *num
= SMB_REALLOC_ARRAY((*num
), uint32
, (*count
)+1);
374 (*num
)[(*count
)] = val
;
382 /*******************************************************************
383 Check if a file exists - call vfs_file_exist for samba files.
384 ********************************************************************/
386 bool file_exist(const char *fname
,SMB_STRUCT_STAT
*sbuf
)
392 if (sys_stat(fname
,sbuf
) != 0)
395 return((S_ISREG(sbuf
->st_mode
)) || (S_ISFIFO(sbuf
->st_mode
)));
398 /*******************************************************************
399 Check a files mod time.
400 ********************************************************************/
402 time_t file_modtime(const char *fname
)
406 if (sys_stat(fname
,&st
) != 0)
412 /*******************************************************************
413 Check if a directory exists.
414 ********************************************************************/
416 bool directory_exist(char *dname
,SMB_STRUCT_STAT
*st
)
424 if (sys_stat(dname
,st
) != 0)
427 ret
= S_ISDIR(st
->st_mode
);
433 /*******************************************************************
434 Returns the size in bytes of the named file.
435 ********************************************************************/
437 SMB_OFF_T
get_file_size(char *file_name
)
441 if(sys_stat(file_name
,&buf
) != 0)
442 return (SMB_OFF_T
)-1;
446 /*******************************************************************
447 Return a string representing an attribute for a file.
448 ********************************************************************/
450 char *attrib_string(uint16 mode
)
456 if (mode
& aVOLID
) fstrcat(attrstr
,"V");
457 if (mode
& aDIR
) fstrcat(attrstr
,"D");
458 if (mode
& aARCH
) fstrcat(attrstr
,"A");
459 if (mode
& aHIDDEN
) fstrcat(attrstr
,"H");
460 if (mode
& aSYSTEM
) fstrcat(attrstr
,"S");
461 if (mode
& aRONLY
) fstrcat(attrstr
,"R");
463 return talloc_strdup(talloc_tos(), attrstr
);
466 /*******************************************************************
467 Show a smb message structure.
468 ********************************************************************/
470 void show_msg(char *buf
)
478 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
480 (int)CVAL(buf
,smb_com
),
481 (int)CVAL(buf
,smb_rcls
),
482 (int)CVAL(buf
,smb_reh
),
483 (int)SVAL(buf
,smb_err
),
484 (int)CVAL(buf
,smb_flg
),
485 (int)SVAL(buf
,smb_flg2
)));
486 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
487 (int)SVAL(buf
,smb_tid
),
488 (int)SVAL(buf
,smb_pid
),
489 (int)SVAL(buf
,smb_uid
),
490 (int)SVAL(buf
,smb_mid
)));
491 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf
,smb_wct
)));
493 for (i
=0;i
<(int)CVAL(buf
,smb_wct
);i
++)
494 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i
,
495 SVAL(buf
,smb_vwv
+2*i
),SVAL(buf
,smb_vwv
+2*i
)));
497 bcc
= (int)SVAL(buf
,smb_vwv
+2*(CVAL(buf
,smb_wct
)));
499 DEBUGADD(5,("smb_bcc=%d\n",bcc
));
507 dump_data(10, (uint8
*)smb_buf(buf
), bcc
);
510 /*******************************************************************
511 Set the length and marker of an smb packet.
512 ********************************************************************/
514 void smb_setlen(char *buf
,int len
)
516 _smb_setlen(buf
,len
);
524 /*******************************************************************
525 Setup the word count and byte count for a smb message.
526 ********************************************************************/
528 int set_message(char *buf
,int num_words
,int num_bytes
,bool zero
)
530 if (zero
&& (num_words
|| num_bytes
)) {
531 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
533 SCVAL(buf
,smb_wct
,num_words
);
534 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
535 smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
536 return (smb_size
+ num_words
*2 + num_bytes
);
539 /*******************************************************************
540 Setup only the byte count for a smb message.
541 ********************************************************************/
543 int set_message_bcc(char *buf
,int num_bytes
)
545 int num_words
= CVAL(buf
,smb_wct
);
546 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
547 smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
548 return (smb_size
+ num_words
*2 + num_bytes
);
551 /*******************************************************************
552 Setup only the byte count for a smb message, using the end of the
554 ********************************************************************/
556 int set_message_end(void *outbuf
,void *end_ptr
)
558 return set_message_bcc((char *)outbuf
,PTR_DIFF(end_ptr
,smb_buf((char *)outbuf
)));
561 /*******************************************************************
562 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
563 Return the bytes added
564 ********************************************************************/
566 ssize_t
message_push_blob(uint8
**outbuf
, DATA_BLOB blob
)
568 size_t newlen
= smb_len(*outbuf
) + 4 + blob
.length
;
571 if (!(tmp
= TALLOC_REALLOC_ARRAY(NULL
, *outbuf
, uint8
, newlen
))) {
572 DEBUG(0, ("talloc failed\n"));
577 memcpy(tmp
+ smb_len(tmp
) + 4, blob
.data
, blob
.length
);
578 set_message_bcc((char *)tmp
, smb_buflen(tmp
) + blob
.length
);
582 /*******************************************************************
583 Reduce a file name, removing .. elements.
584 ********************************************************************/
586 static char *dos_clean_name(TALLOC_CTX
*ctx
, const char *s
)
591 DEBUG(3,("dos_clean_name [%s]\n",s
));
593 /* remove any double slashes */
594 str
= talloc_all_string_sub(ctx
, s
, "\\\\", "\\");
599 /* Remove leading .\\ characters */
600 if(strncmp(str
, ".\\", 2) == 0) {
601 trim_string(str
, ".\\", NULL
);
603 str
= talloc_strdup(ctx
, ".\\");
610 while ((p
= strstr_m(str
,"\\..\\")) != NULL
) {
616 if ((p
=strrchr_m(str
,'\\')) != NULL
) {
621 str
= talloc_asprintf(ctx
,
630 trim_string(str
,NULL
,"\\..");
631 return talloc_all_string_sub(ctx
, str
, "\\.\\", "\\");
634 /*******************************************************************
635 Reduce a file name, removing .. elements.
636 ********************************************************************/
638 char *unix_clean_name(TALLOC_CTX
*ctx
, const char *s
)
643 DEBUG(3,("unix_clean_name [%s]\n",s
));
645 /* remove any double slashes */
646 str
= talloc_all_string_sub(ctx
, s
, "//","/");
651 /* Remove leading ./ characters */
652 if(strncmp(str
, "./", 2) == 0) {
653 trim_string(str
, "./", NULL
);
655 str
= talloc_strdup(ctx
, "./");
662 while ((p
= strstr_m(str
,"/../")) != NULL
) {
668 if ((p
=strrchr_m(str
,'/')) != NULL
) {
673 str
= talloc_asprintf(ctx
,
682 trim_string(str
,NULL
,"/..");
683 return talloc_all_string_sub(ctx
, str
, "/./", "/");
686 char *clean_name(TALLOC_CTX
*ctx
, const char *s
)
688 char *str
= dos_clean_name(ctx
, s
);
692 return unix_clean_name(ctx
, str
);
695 /*******************************************************************
696 Horrible temporary hack until pstring is dead.
697 ********************************************************************/
699 char *pstring_clean_name(pstring s
)
701 char *str
= clean_name(NULL
,s
);
710 /*******************************************************************
711 Close the low 3 fd's and open dev/null in their place.
712 ********************************************************************/
714 void close_low_fds(bool stderr_too
)
726 /* try and use up these file descriptors, so silly
727 library routines writing to stdout etc won't cause havoc */
729 if (i
== 2 && !stderr_too
)
732 fd
= sys_open("/dev/null",O_RDWR
,0);
734 fd
= sys_open("/dev/null",O_WRONLY
,0);
736 DEBUG(0,("Can't open /dev/null\n"));
740 DEBUG(0,("Didn't get file descriptor %d\n",i
));
747 /*******************************************************************
748 Write data into an fd at a given offset. Ignore seek errors.
749 ********************************************************************/
751 ssize_t
write_data_at_offset(int fd
, const char *buffer
, size_t N
, SMB_OFF_T pos
)
756 if (pos
== (SMB_OFF_T
)-1) {
757 return write_data(fd
, buffer
, N
);
759 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
761 ret
= sys_pwrite(fd
,buffer
+ total
,N
- total
, pos
);
762 if (ret
== -1 && errno
== ESPIPE
) {
763 return write_data(fd
, buffer
+ total
,N
- total
);
766 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno
) ));
775 return (ssize_t
)total
;
777 /* Use lseek and write_data. */
778 if (sys_lseek(fd
, pos
, SEEK_SET
) == -1) {
779 if (errno
!= ESPIPE
) {
783 return write_data(fd
, buffer
, N
);
787 /****************************************************************************
788 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
792 ****************************************************************************/
794 int set_blocking(int fd
, bool set
)
798 #define FLAG_TO_SET O_NONBLOCK
801 #define FLAG_TO_SET O_NDELAY
803 #define FLAG_TO_SET FNDELAY
807 if((val
= sys_fcntl_long(fd
, F_GETFL
, 0)) == -1)
809 if(set
) /* Turn blocking on - ie. clear nonblock flag */
813 return sys_fcntl_long( fd
, F_SETFL
, val
);
817 /****************************************************************************
818 Transfer some data between two fd's.
819 ****************************************************************************/
821 #ifndef TRANSFER_BUF_SIZE
822 #define TRANSFER_BUF_SIZE 65536
825 ssize_t
transfer_file_internal(int infd
, int outfd
, size_t n
, ssize_t (*read_fn
)(int, void *, size_t),
826 ssize_t (*write_fn
)(int, const void *, size_t))
832 size_t num_to_read_thistime
;
833 size_t num_written
= 0;
835 if ((buf
= SMB_MALLOC_ARRAY(char, TRANSFER_BUF_SIZE
)) == NULL
)
839 num_to_read_thistime
= MIN((n
- total
), TRANSFER_BUF_SIZE
);
841 read_ret
= (*read_fn
)(infd
, buf
, num_to_read_thistime
);
842 if (read_ret
== -1) {
843 DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno
) ));
852 while (num_written
< read_ret
) {
853 write_ret
= (*write_fn
)(outfd
,buf
+ num_written
, read_ret
- num_written
);
855 if (write_ret
== -1) {
856 DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno
) ));
861 return (ssize_t
)total
;
863 num_written
+= (size_t)write_ret
;
866 total
+= (size_t)read_ret
;
870 return (ssize_t
)total
;
873 SMB_OFF_T
transfer_file(int infd
,int outfd
,SMB_OFF_T n
)
875 return (SMB_OFF_T
)transfer_file_internal(infd
, outfd
, (size_t)n
, sys_read
, sys_write
);
878 /*******************************************************************
879 Sleep for a specified number of milliseconds.
880 ********************************************************************/
882 void smb_msleep(unsigned int t
)
884 #if defined(HAVE_NANOSLEEP)
885 struct timespec tval
;
888 tval
.tv_sec
= t
/1000;
889 tval
.tv_nsec
= 1000000*(t
%1000);
893 ret
= nanosleep(&tval
, &tval
);
894 } while (ret
< 0 && errno
== EINTR
&& (tval
.tv_sec
> 0 || tval
.tv_nsec
> 0));
896 unsigned int tdiff
=0;
897 struct timeval tval
,t1
,t2
;
904 tval
.tv_sec
= (t
-tdiff
)/1000;
905 tval
.tv_usec
= 1000*((t
-tdiff
)%1000);
907 /* Never wait for more than 1 sec. */
908 if (tval
.tv_sec
> 1) {
915 sys_select_intr(0,&fds
,NULL
,NULL
,&tval
);
918 if (t2
.tv_sec
< t1
.tv_sec
) {
919 /* Someone adjusted time... */
923 tdiff
= TvalDiff(&t1
,&t2
);
928 /****************************************************************************
929 Become a daemon, discarding the controlling terminal.
930 ****************************************************************************/
932 void become_daemon(bool Fork
, bool no_process_group
)
940 /* detach from the terminal */
942 if (!no_process_group
) setsid();
943 #elif defined(TIOCNOTTY)
944 if (!no_process_group
) {
945 int i
= sys_open("/dev/tty", O_RDWR
, 0);
947 ioctl(i
, (int) TIOCNOTTY
, (char *)0);
951 #endif /* HAVE_SETSID */
953 /* Close fd's 0,1,2. Needed if started by rsh */
954 close_low_fds(False
); /* Don't close stderr, let the debug system
955 attach it to the logfile */
958 /****************************************************************************
959 Put up a yes/no prompt.
960 ****************************************************************************/
962 bool yesno(const char *p
)
967 if (!fgets(ans
,sizeof(ans
)-1,stdin
))
970 if (*ans
== 'y' || *ans
== 'Y')
976 #if defined(PARANOID_MALLOC_CHECKER)
978 /****************************************************************************
979 Internal malloc wrapper. Externally visible.
980 ****************************************************************************/
982 void *malloc_(size_t size
)
989 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
992 /****************************************************************************
993 Internal calloc wrapper. Not externally visible.
994 ****************************************************************************/
996 static void *calloc_(size_t count
, size_t size
)
998 if (size
== 0 || count
== 0) {
1002 return calloc(count
, size
);
1003 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
1006 /****************************************************************************
1007 Internal realloc wrapper. Not externally visible.
1008 ****************************************************************************/
1010 static void *realloc_(void *ptr
, size_t size
)
1013 return realloc(ptr
, size
);
1014 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
1017 #endif /* PARANOID_MALLOC_CHECKER */
1019 /****************************************************************************
1021 ****************************************************************************/
1023 void *malloc_array(size_t el_size
, unsigned int count
)
1025 if (count
>= MAX_ALLOC_SIZE
/el_size
) {
1029 if (el_size
== 0 || count
== 0) {
1032 #if defined(PARANOID_MALLOC_CHECKER)
1033 return malloc_(el_size
*count
);
1035 return malloc(el_size
*count
);
1039 /****************************************************************************
1041 ****************************************************************************/
1043 void *memalign_array(size_t el_size
, size_t align
, unsigned int count
)
1045 if (count
>= MAX_ALLOC_SIZE
/el_size
) {
1049 return sys_memalign(align
, el_size
*count
);
1052 /****************************************************************************
1054 ****************************************************************************/
1056 void *calloc_array(size_t size
, size_t nmemb
)
1058 if (nmemb
>= MAX_ALLOC_SIZE
/size
) {
1061 if (size
== 0 || nmemb
== 0) {
1064 #if defined(PARANOID_MALLOC_CHECKER)
1065 return calloc_(nmemb
, size
);
1067 return calloc(nmemb
, size
);
1071 /****************************************************************************
1072 Expand a pointer to be a particular size.
1073 Note that this version of Realloc has an extra parameter that decides
1074 whether to free the passed in storage on allocation failure or if the
1077 This is designed for use in the typical idiom of :
1079 p = SMB_REALLOC(p, size)
1084 and not to have to keep track of the old 'p' contents to free later, nor
1085 to worry if the size parameter was zero. In the case where NULL is returned
1086 we guarentee that p has been freed.
1088 If free later semantics are desired, then pass 'free_old_on_error' as False which
1089 guarentees that the old contents are not freed on error, even if size == 0. To use
1092 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
1100 Changes were instigated by Coverity error checking. JRA.
1101 ****************************************************************************/
1103 void *Realloc(void *p
, size_t size
, bool free_old_on_error
)
1108 if (free_old_on_error
) {
1111 DEBUG(2,("Realloc asked for 0 bytes\n"));
1115 #if defined(PARANOID_MALLOC_CHECKER)
1117 ret
= (void *)malloc_(size
);
1119 ret
= (void *)realloc_(p
,size
);
1123 ret
= (void *)malloc(size
);
1125 ret
= (void *)realloc(p
,size
);
1130 if (free_old_on_error
&& p
) {
1133 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size
));
1139 /****************************************************************************
1141 ****************************************************************************/
1143 void *realloc_array(void *p
, size_t el_size
, unsigned int count
, bool free_old_on_error
)
1145 if (count
>= MAX_ALLOC_SIZE
/el_size
) {
1146 if (free_old_on_error
) {
1151 return Realloc(p
, el_size
*count
, free_old_on_error
);
1154 /****************************************************************************
1155 (Hopefully) efficient array append.
1156 ****************************************************************************/
1158 void add_to_large_array(TALLOC_CTX
*mem_ctx
, size_t element_size
,
1159 void *element
, void *_array
, uint32
*num_elements
,
1160 ssize_t
*array_size
)
1162 void **array
= (void **)_array
;
1164 if (*array_size
< 0) {
1168 if (*array
== NULL
) {
1169 if (*array_size
== 0) {
1173 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
1177 *array
= TALLOC(mem_ctx
, element_size
* (*array_size
));
1178 if (*array
== NULL
) {
1183 if (*num_elements
== *array_size
) {
1186 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
1190 *array
= TALLOC_REALLOC(mem_ctx
, *array
,
1191 element_size
* (*array_size
));
1193 if (*array
== NULL
) {
1198 memcpy((char *)(*array
) + element_size
*(*num_elements
),
1199 element
, element_size
);
1209 /****************************************************************************
1210 Free memory, checks for NULL.
1211 Use directly SAFE_FREE()
1212 Exists only because we need to pass a function pointer somewhere --SSS
1213 ****************************************************************************/
1215 void safe_free(void *p
)
1220 /****************************************************************************
1221 Get my own name and IP.
1222 ****************************************************************************/
1224 char *get_myname(TALLOC_CTX
*ctx
)
1227 char hostname
[HOST_NAME_MAX
];
1231 /* get my host name */
1232 if (gethostname(hostname
, sizeof(hostname
)) == -1) {
1233 DEBUG(0,("gethostname failed\n"));
1237 /* Ensure null termination. */
1238 hostname
[sizeof(hostname
)-1] = '\0';
1240 /* split off any parts after an initial . */
1241 p
= strchr_m(hostname
,'.');
1246 return talloc_strdup(ctx
, hostname
);
1249 /****************************************************************************
1250 Get my own domain name, or "" if we have none.
1251 ****************************************************************************/
1253 char *get_mydnsdomname(TALLOC_CTX
*ctx
)
1255 const char *domname
;
1258 domname
= get_mydnsfullname();
1263 p
= strchr_m(domname
, '.');
1266 return talloc_strdup(ctx
, p
);
1268 return talloc_strdup(ctx
, "");
1272 /****************************************************************************
1273 Interpret a protocol description string, with a default.
1274 ****************************************************************************/
1276 int interpret_protocol(const char *str
,int def
)
1278 if (strequal(str
,"NT1"))
1279 return(PROTOCOL_NT1
);
1280 if (strequal(str
,"LANMAN2"))
1281 return(PROTOCOL_LANMAN2
);
1282 if (strequal(str
,"LANMAN1"))
1283 return(PROTOCOL_LANMAN1
);
1284 if (strequal(str
,"CORE"))
1285 return(PROTOCOL_CORE
);
1286 if (strequal(str
,"COREPLUS"))
1287 return(PROTOCOL_COREPLUS
);
1288 if (strequal(str
,"CORE+"))
1289 return(PROTOCOL_COREPLUS
);
1291 DEBUG(0,("Unrecognised protocol level %s\n",str
));
1297 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1298 /******************************************************************
1299 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1300 Based on a fix from <Thomas.Hepper@icem.de>.
1301 Returns a malloc'ed string.
1302 *******************************************************************/
1304 static char *strip_mount_options(TALLOC_CTX
*ctx
, const char *str
)
1307 const char *p
= str
;
1308 while(*p
&& !isspace(*p
))
1310 while(*p
&& isspace(*p
))
1313 return talloc_strdup(ctx
, p
);
1319 /*******************************************************************
1320 Patch from jkf@soton.ac.uk
1321 Split Luke's automount_server into YP lookup and string splitter
1322 so can easily implement automount_path().
1323 Returns a malloc'ed string.
1324 *******************************************************************/
1326 #ifdef WITH_NISPLUS_HOME
1327 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
1331 char *nis_map
= (char *)lp_nis_home_map_name();
1333 char buffer
[NIS_MAXATTRVAL
+ 1];
1338 snprintf(buffer
, sizeof(buffer
), "[key=%s],%s", user_name
, nis_map
);
1339 DEBUG(5, ("NIS+ querystring: %s\n", buffer
));
1341 if (result
= nis_list(buffer
, FOLLOW_PATH
|EXPAND_NAME
|HARD_LOOKUP
, NULL
, NULL
)) {
1342 if (result
->status
!= NIS_SUCCESS
) {
1343 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result
->status
)));
1345 object
= result
->objects
.objects_val
;
1346 if (object
->zo_data
.zo_type
== ENTRY_OBJ
) {
1347 entry
= &object
->zo_data
.objdata_u
.en_data
;
1348 DEBUG(5, ("NIS+ entry type: %s\n", entry
->en_type
));
1349 DEBUG(3, ("NIS+ result: %s\n", entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
));
1351 value
= talloc_strdup(ctx
,
1352 entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
);
1354 nis_freeresult(result
);
1357 value
= talloc_string_sub(ctx
,
1364 nis_freeresult(result
);
1367 value
= strip_mount_options(ctx
, value
);
1368 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
1373 #else /* WITH_NISPLUS_HOME */
1375 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
1379 int nis_error
; /* returned by yp all functions */
1380 char *nis_result
; /* yp_match inits this */
1381 int nis_result_len
; /* and set this */
1382 char *nis_domain
; /* yp_get_default_domain inits this */
1383 char *nis_map
= (char *)lp_nis_home_map_name();
1385 if ((nis_error
= yp_get_default_domain(&nis_domain
)) != 0) {
1386 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error
)));
1390 DEBUG(5, ("NIS Domain: %s\n", nis_domain
));
1392 if ((nis_error
= yp_match(nis_domain
, nis_map
, user_name
,
1393 strlen(user_name
), &nis_result
,
1394 &nis_result_len
)) == 0) {
1395 value
= talloc_strdup(ctx
, nis_result
);
1399 value
= strip_mount_options(ctx
, value
);
1400 } else if(nis_error
== YPERR_KEY
) {
1401 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1402 user_name
, nis_map
));
1403 DEBUG(3, ("using defaults for server and home directory\n"));
1405 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1406 yperr_string(nis_error
), user_name
, nis_map
));
1410 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name
, value
));
1414 #endif /* WITH_NISPLUS_HOME */
1417 /****************************************************************************
1418 Check if a process exists. Does this work on all unixes?
1419 ****************************************************************************/
1421 bool process_exists(const struct server_id pid
)
1423 if (procid_is_me(&pid
)) {
1427 if (procid_is_local(&pid
)) {
1428 return (kill(pid
.pid
,0) == 0 || errno
!= ESRCH
);
1431 #ifdef CLUSTER_SUPPORT
1432 return ctdbd_process_exists(messaging_ctdbd_connection(), pid
.vnn
,
1439 bool process_exists_by_pid(pid_t pid
)
1441 /* Doing kill with a non-positive pid causes messages to be
1442 * sent to places we don't want. */
1443 SMB_ASSERT(pid
> 0);
1444 return(kill(pid
,0) == 0 || errno
!= ESRCH
);
1447 /*******************************************************************
1448 Convert a uid into a user name.
1449 ********************************************************************/
1451 const char *uidtoname(uid_t uid
)
1453 TALLOC_CTX
*ctx
= talloc_tos();
1455 struct passwd
*pass
= NULL
;
1457 pass
= getpwuid_alloc(ctx
,uid
);
1459 name
= talloc_strdup(ctx
,pass
->pw_name
);
1462 name
= talloc_asprintf(ctx
,
1469 /*******************************************************************
1470 Convert a gid into a group name.
1471 ********************************************************************/
1473 char *gidtoname(gid_t gid
)
1477 grp
= getgrgid(gid
);
1479 return talloc_strdup(talloc_tos(), grp
->gr_name
);
1482 return talloc_asprintf(talloc_tos(),
1488 /*******************************************************************
1489 Convert a user name into a uid.
1490 ********************************************************************/
1492 uid_t
nametouid(const char *name
)
1494 struct passwd
*pass
;
1498 pass
= getpwnam_alloc(NULL
, name
);
1505 u
= (uid_t
)strtol(name
, &p
, 0);
1506 if ((p
!= name
) && (*p
== '\0'))
1512 /*******************************************************************
1513 Convert a name to a gid_t if possible. Return -1 if not a group.
1514 ********************************************************************/
1516 gid_t
nametogid(const char *name
)
1522 g
= (gid_t
)strtol(name
, &p
, 0);
1523 if ((p
!= name
) && (*p
== '\0'))
1526 grp
= sys_getgrnam(name
);
1528 return(grp
->gr_gid
);
1532 /*******************************************************************
1533 Something really nasty happened - panic !
1534 ********************************************************************/
1536 void smb_panic(const char *const why
)
1544 if (global_clobber_region_function
) {
1545 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1546 global_clobber_region_function
,
1547 global_clobber_region_line
));
1552 DEBUG(0,("PANIC (pid %llu): %s\n",
1553 (unsigned long long)sys_getpid(), why
));
1556 cmd
= lp_panic_action();
1558 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd
));
1559 result
= system(cmd
);
1562 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1565 DEBUG(0, ("smb_panic(): action returned status %d\n",
1566 WEXITSTATUS(result
)));
1572 /*******************************************************************
1573 Print a backtrace of the stack to the debug log. This function
1574 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1575 exit shortly after calling it.
1576 ********************************************************************/
1578 #ifdef HAVE_LIBUNWIND_H
1579 #include <libunwind.h>
1582 #ifdef HAVE_EXECINFO_H
1583 #include <execinfo.h>
1586 #ifdef HAVE_LIBEXC_H
1590 void log_stack_trace(void)
1592 #ifdef HAVE_LIBUNWIND
1593 /* Try to use libunwind before any other technique since on ia64
1594 * libunwind correctly walks the stack in more circumstances than
1597 unw_cursor_t cursor
;
1602 unw_word_t ip
, sp
, off
;
1604 procname
[sizeof(procname
) - 1] = '\0';
1606 if (unw_getcontext(&uc
) != 0) {
1607 goto libunwind_failed
;
1610 if (unw_init_local(&cursor
, &uc
) != 0) {
1611 goto libunwind_failed
;
1614 DEBUG(0, ("BACKTRACE:\n"));
1618 unw_get_reg(&cursor
, UNW_REG_IP
, &ip
);
1619 unw_get_reg(&cursor
, UNW_REG_SP
, &sp
);
1621 switch (unw_get_proc_name(&cursor
,
1622 procname
, sizeof(procname
) - 1, &off
) ) {
1626 /* Name truncated. */
1627 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1628 i
, procname
, (long long)off
,
1629 (long long)ip
, (long long) sp
));
1632 /* case -UNW_ENOINFO: */
1633 /* case -UNW_EUNSPEC: */
1634 /* No symbol name found. */
1635 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1636 i
, "<unknown symbol>",
1637 (long long)ip
, (long long) sp
));
1640 } while (unw_step(&cursor
) > 0);
1645 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1647 #elif HAVE_BACKTRACE_SYMBOLS
1648 void *backtrace_stack
[BACKTRACE_STACK_SIZE
];
1649 size_t backtrace_size
;
1650 char **backtrace_strings
;
1652 /* get the backtrace (stack frames) */
1653 backtrace_size
= backtrace(backtrace_stack
,BACKTRACE_STACK_SIZE
);
1654 backtrace_strings
= backtrace_symbols(backtrace_stack
, backtrace_size
);
1656 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1657 (unsigned long)backtrace_size
));
1659 if (backtrace_strings
) {
1662 for (i
= 0; i
< backtrace_size
; i
++)
1663 DEBUGADD(0, (" #%u %s\n", i
, backtrace_strings
[i
]));
1665 /* Leak the backtrace_strings, rather than risk what free() might do */
1670 /* The IRIX libexc library provides an API for unwinding the stack. See
1671 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1672 * since we are about to abort anyway, it hardly matters.
1675 #define NAMESIZE 32 /* Arbitrary */
1677 __uint64_t addrs
[BACKTRACE_STACK_SIZE
];
1678 char * names
[BACKTRACE_STACK_SIZE
];
1679 char namebuf
[BACKTRACE_STACK_SIZE
* NAMESIZE
];
1686 ZERO_ARRAY(namebuf
);
1688 /* We need to be root so we can open our /proc entry to walk
1689 * our stack. It also helps when we want to dump core.
1693 for (i
= 0; i
< BACKTRACE_STACK_SIZE
; i
++) {
1694 names
[i
] = namebuf
+ (i
* NAMESIZE
);
1697 levels
= trace_back_stack(0, addrs
, names
,
1698 BACKTRACE_STACK_SIZE
, NAMESIZE
- 1);
1700 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels
));
1701 for (i
= 0; i
< levels
; i
++) {
1702 DEBUGADD(0, (" #%d 0x%llx %s\n", i
, addrs
[i
], names
[i
]));
1707 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1711 /*******************************************************************
1712 A readdir wrapper which just returns the file name.
1713 ********************************************************************/
1715 const char *readdirname(SMB_STRUCT_DIR
*p
)
1717 SMB_STRUCT_DIRENT
*ptr
;
1723 ptr
= (SMB_STRUCT_DIRENT
*)sys_readdir(p
);
1727 dname
= ptr
->d_name
;
1734 #ifdef HAVE_BROKEN_READDIR_NAME
1735 /* using /usr/ucb/cc is BAD */
1739 return talloc_strdup(talloc_tos(), dname
);
1742 /*******************************************************************
1743 Utility function used to decide if the last component
1744 of a path matches a (possibly wildcarded) entry in a namelist.
1745 ********************************************************************/
1747 bool is_in_path(const char *name
, name_compare_entry
*namelist
, bool case_sensitive
)
1749 const char *last_component
;
1751 /* if we have no list it's obviously not in the path */
1752 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
))) {
1756 DEBUG(8, ("is_in_path: %s\n", name
));
1758 /* Get the last component of the unix name. */
1759 last_component
= strrchr_m(name
, '/');
1760 if (!last_component
) {
1761 last_component
= name
;
1763 last_component
++; /* Go past '/' */
1766 for(; namelist
->name
!= NULL
; namelist
++) {
1767 if(namelist
->is_wild
) {
1768 if (mask_match(last_component
, namelist
->name
, case_sensitive
)) {
1769 DEBUG(8,("is_in_path: mask match succeeded\n"));
1773 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
1774 (!case_sensitive
&& (StrCaseCmp(last_component
, namelist
->name
) == 0))) {
1775 DEBUG(8,("is_in_path: match succeeded\n"));
1780 DEBUG(8,("is_in_path: match not found\n"));
1784 /*******************************************************************
1785 Strip a '/' separated list into an array of
1786 name_compare_enties structures suitable for
1787 passing to is_in_path(). We do this for
1788 speed so we can pre-parse all the names in the list
1789 and don't do it for each call to is_in_path().
1790 namelist is modified here and is assumed to be
1791 a copy owned by the caller.
1792 We also check if the entry contains a wildcard to
1793 remove a potentially expensive call to mask_match
1795 ********************************************************************/
1797 void set_namearray(name_compare_entry
**ppname_array
, char *namelist
)
1800 char *nameptr
= namelist
;
1801 int num_entries
= 0;
1804 (*ppname_array
) = NULL
;
1806 if((nameptr
== NULL
) || ((nameptr
!= NULL
) && (*nameptr
== '\0')))
1809 /* We need to make two passes over the string. The
1810 first to count the number of elements, the second
1815 if ( *nameptr
== '/' ) {
1816 /* cope with multiple (useless) /s) */
1820 /* find the next / */
1821 name_end
= strchr_m(nameptr
, '/');
1823 /* oops - the last check for a / didn't find one. */
1824 if (name_end
== NULL
)
1827 /* next segment please */
1828 nameptr
= name_end
+ 1;
1832 if(num_entries
== 0)
1835 if(( (*ppname_array
) = SMB_MALLOC_ARRAY(name_compare_entry
, num_entries
+ 1)) == NULL
) {
1836 DEBUG(0,("set_namearray: malloc fail\n"));
1840 /* Now copy out the names */
1844 if ( *nameptr
== '/' ) {
1845 /* cope with multiple (useless) /s) */
1849 /* find the next / */
1850 if ((name_end
= strchr_m(nameptr
, '/')) != NULL
)
1853 /* oops - the last check for a / didn't find one. */
1854 if(name_end
== NULL
)
1857 (*ppname_array
)[i
].is_wild
= ms_has_wild(nameptr
);
1858 if(((*ppname_array
)[i
].name
= SMB_STRDUP(nameptr
)) == NULL
) {
1859 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1863 /* next segment please */
1864 nameptr
= name_end
+ 1;
1868 (*ppname_array
)[i
].name
= NULL
;
1873 /****************************************************************************
1874 Routine to free a namearray.
1875 ****************************************************************************/
1877 void free_namearray(name_compare_entry
*name_array
)
1881 if(name_array
== NULL
)
1884 for(i
=0; name_array
[i
].name
!=NULL
; i
++)
1885 SAFE_FREE(name_array
[i
].name
);
1886 SAFE_FREE(name_array
);
1890 #define DBGC_CLASS DBGC_LOCKING
1892 /****************************************************************************
1893 Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
1894 is dealt with in posix.c
1895 Returns True if the lock was granted, False otherwise.
1896 ****************************************************************************/
1898 bool fcntl_lock(int fd
, int op
, SMB_OFF_T offset
, SMB_OFF_T count
, int type
)
1900 SMB_STRUCT_FLOCK lock
;
1903 DEBUG(8,("fcntl_lock fd=%d op=%d offset=%.0f count=%.0f type=%d\n",
1904 fd
,op
,(double)offset
,(double)count
,type
));
1907 lock
.l_whence
= SEEK_SET
;
1908 lock
.l_start
= offset
;
1912 ret
= sys_fcntl_ptr(fd
,op
,&lock
);
1916 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
1917 (double)offset
,(double)count
,op
,type
,strerror(errno
)));
1922 /* everything went OK */
1923 DEBUG(8,("fcntl_lock: Lock call successful\n"));
1928 /****************************************************************************
1929 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1930 is dealt with in posix.c
1931 Returns True if we have information regarding this lock region (and returns
1932 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1933 ****************************************************************************/
1935 bool fcntl_getlock(int fd
, SMB_OFF_T
*poffset
, SMB_OFF_T
*pcount
, int *ptype
, pid_t
*ppid
)
1937 SMB_STRUCT_FLOCK lock
;
1940 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1941 fd
,(double)*poffset
,(double)*pcount
,*ptype
));
1943 lock
.l_type
= *ptype
;
1944 lock
.l_whence
= SEEK_SET
;
1945 lock
.l_start
= *poffset
;
1946 lock
.l_len
= *pcount
;
1949 ret
= sys_fcntl_ptr(fd
,SMB_F_GETLK
,&lock
);
1953 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1954 (double)*poffset
,(double)*pcount
,*ptype
,strerror(errno
)));
1959 *ptype
= lock
.l_type
;
1960 *poffset
= lock
.l_start
;
1961 *pcount
= lock
.l_len
;
1964 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1965 fd
, (int)lock
.l_type
, (unsigned int)lock
.l_pid
));
1970 #define DBGC_CLASS DBGC_ALL
1972 /*******************************************************************
1973 Is the name specified one of my netbios names.
1974 Returns true if it is equal, false otherwise.
1975 ********************************************************************/
1977 bool is_myname(const char *s
)
1982 for (n
=0; my_netbios_names(n
); n
++) {
1983 if (strequal(my_netbios_names(n
), s
)) {
1988 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));
1992 /*******************************************************************
1993 Is the name specified our workgroup/domain.
1994 Returns true if it is equal, false otherwise.
1995 ********************************************************************/
1997 bool is_myworkgroup(const char *s
)
2001 if (strequal(s
, lp_workgroup())) {
2005 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s
, ret
));
2009 /*******************************************************************
2010 we distinguish between 2K and XP by the "Native Lan Manager" string
2011 WinXP => "Windows 2002 5.1"
2012 WinXP 64bit => "Windows XP 5.2"
2013 Win2k => "Windows 2000 5.0"
2014 NT4 => "Windows NT 4.0"
2015 Win9x => "Windows 4.0"
2016 Windows 2003 doesn't set the native lan manager string but
2017 they do set the domain to "Windows 2003 5.2" (probably a bug).
2018 ********************************************************************/
2020 void ra_lanman_string( const char *native_lanman
)
2022 if ( strcmp( native_lanman
, "Windows 2002 5.1" ) == 0 )
2023 set_remote_arch( RA_WINXP
);
2024 else if ( strcmp( native_lanman
, "Windows XP 5.2" ) == 0 )
2025 set_remote_arch( RA_WINXP
);
2026 else if ( strcmp( native_lanman
, "Windows Server 2003 5.2" ) == 0 )
2027 set_remote_arch( RA_WIN2K3
);
2030 static const char *remote_arch_str
;
2032 const char *get_remote_arch_str(void)
2034 if (!remote_arch_str
) {
2037 return remote_arch_str
;
2040 /*******************************************************************
2041 Set the horrid remote_arch string based on an enum.
2042 ********************************************************************/
2044 void set_remote_arch(enum remote_arch_types type
)
2049 remote_arch_str
= "WfWg";
2052 remote_arch_str
= "OS2";
2055 remote_arch_str
= "Win95";
2058 remote_arch_str
= "WinNT";
2061 remote_arch_str
= "Win2K";
2064 remote_arch_str
= "WinXP";
2067 remote_arch_str
= "Win2K3";
2070 remote_arch_str
= "Vista";
2073 remote_arch_str
= "Samba";
2076 remote_arch_str
= "CIFSFS";
2079 ra_type
= RA_UNKNOWN
;
2080 remote_arch_str
= "UNKNOWN";
2084 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
2088 /*******************************************************************
2089 Get the remote_arch type.
2090 ********************************************************************/
2092 enum remote_arch_types
get_remote_arch(void)
2097 void print_asc(int level
, const unsigned char *buf
,int len
)
2101 DEBUG(level
,("%c", isprint(buf
[i
])?buf
[i
]:'.'));
2104 void dump_data(int level
, const unsigned char *buf1
,int len
)
2106 const unsigned char *buf
= (const unsigned char *)buf1
;
2110 if (!DEBUGLVL(level
)) return;
2112 DEBUGADD(level
,("[%03X] ",i
));
2114 DEBUGADD(level
,("%02X ",(int)buf
[i
]));
2116 if (i
%8 == 0) DEBUGADD(level
,(" "));
2118 print_asc(level
,&buf
[i
-16],8); DEBUGADD(level
,(" "));
2119 print_asc(level
,&buf
[i
-8],8); DEBUGADD(level
,("\n"));
2120 if (i
<len
) DEBUGADD(level
,("[%03X] ",i
));
2126 DEBUGADD(level
,(" "));
2127 if (n
>8) DEBUGADD(level
,(" "));
2128 while (n
--) DEBUGADD(level
,(" "));
2130 print_asc(level
,&buf
[i
-(i
%16)],n
); DEBUGADD(level
,( " " ));
2132 if (n
>0) print_asc(level
,&buf
[i
-n
],n
);
2133 DEBUGADD(level
,("\n"));
2137 void dump_data_pw(const char *msg
, const uchar
* data
, size_t len
)
2139 #ifdef DEBUG_PASSWORD
2140 DEBUG(11, ("%s", msg
));
2141 if (data
!= NULL
&& len
> 0)
2143 dump_data(11, data
, len
);
2148 char *tab_depth(int depth
)
2150 static pstring spaces
;
2151 size_t len
= depth
* 4;
2152 if (len
> sizeof(pstring
)-1) {
2153 len
= sizeof(pstring
)-1;
2156 memset(spaces
, ' ', len
);
2161 /*****************************************************************************
2162 Provide a checksum on a string
2164 Input: s - the null-terminated character string for which the checksum
2167 Output: The checksum value calculated for s.
2168 *****************************************************************************/
2170 int str_checksum(const char *s
)
2178 res
^= (c
<< (i
% 15)) ^ (c
>> (15-(i
%15)));
2185 /*****************************************************************
2186 Zero a memory area then free it. Used to catch bugs faster.
2187 *****************************************************************/
2189 void zero_free(void *p
, size_t size
)
2195 /*****************************************************************
2196 Set our open file limit to a requested max and return the limit.
2197 *****************************************************************/
2199 int set_maxfiles(int requested_max
)
2201 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2203 int saved_current_limit
;
2205 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
2206 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2209 return requested_max
;
2213 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2214 * account for the extra fd we need
2215 * as well as the log files and standard
2216 * handles etc. Save the limit we want to set in case
2217 * we are running on an OS that doesn't support this limit (AIX)
2218 * which always returns RLIM_INFINITY for rlp.rlim_max.
2221 /* Try raising the hard (max) limit to the requested amount. */
2223 #if defined(RLIM_INFINITY)
2224 if (rlp
.rlim_max
!= RLIM_INFINITY
) {
2225 int orig_max
= rlp
.rlim_max
;
2227 if ( rlp
.rlim_max
< requested_max
)
2228 rlp
.rlim_max
= requested_max
;
2230 /* This failing is not an error - many systems (Linux) don't
2231 support our default request of 10,000 open files. JRA. */
2233 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
2234 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2235 (int)rlp
.rlim_max
, strerror(errno
) ));
2237 /* Set failed - restore original value from get. */
2238 rlp
.rlim_max
= orig_max
;
2243 /* Now try setting the soft (current) limit. */
2245 saved_current_limit
= rlp
.rlim_cur
= MIN(requested_max
,rlp
.rlim_max
);
2247 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
2248 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2249 (int)rlp
.rlim_cur
, strerror(errno
) ));
2251 return saved_current_limit
;
2254 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
2255 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2258 return saved_current_limit
;
2261 #if defined(RLIM_INFINITY)
2262 if(rlp
.rlim_cur
== RLIM_INFINITY
)
2263 return saved_current_limit
;
2266 if((int)rlp
.rlim_cur
> saved_current_limit
)
2267 return saved_current_limit
;
2269 return rlp
.rlim_cur
;
2270 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2272 * No way to know - just guess...
2274 return requested_max
;
2278 /*****************************************************************
2279 Possibly replace mkstemp if it is broken.
2280 *****************************************************************/
2282 int smb_mkstemp(char *name_template
)
2284 #if HAVE_SECURE_MKSTEMP
2285 return mkstemp(name_template
);
2287 /* have a reasonable go at emulating it. Hope that
2288 the system mktemp() isn't completly hopeless */
2289 char *p
= mktemp(name_template
);
2292 return open(p
, O_CREAT
|O_EXCL
|O_RDWR
, 0600);
2296 /*****************************************************************
2297 malloc that aborts with smb_panic on fail or zero size.
2298 *****************************************************************/
2300 void *smb_xmalloc_array(size_t size
, unsigned int count
)
2304 smb_panic("smb_xmalloc_array: called with zero size");
2306 if (count
>= MAX_ALLOC_SIZE
/size
) {
2307 smb_panic("smb_xmalloc_array: alloc size too large");
2309 if ((p
= SMB_MALLOC(size
*count
)) == NULL
) {
2310 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2311 (unsigned long)size
, (unsigned long)count
));
2312 smb_panic("smb_xmalloc_array: malloc failed");
2318 Memdup with smb_panic on fail.
2321 void *smb_xmemdup(const void *p
, size_t size
)
2324 p2
= SMB_XMALLOC_ARRAY(unsigned char,size
);
2325 memcpy(p2
, p
, size
);
2330 strdup that aborts on malloc fail.
2333 char *smb_xstrdup(const char *s
)
2335 #if defined(PARANOID_MALLOC_CHECKER)
2342 #define strdup rep_strdup
2345 char *s1
= strdup(s
);
2346 #if defined(PARANOID_MALLOC_CHECKER)
2350 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2353 smb_panic("smb_xstrdup: malloc failed");
2360 strndup that aborts on malloc fail.
2363 char *smb_xstrndup(const char *s
, size_t n
)
2365 #if defined(PARANOID_MALLOC_CHECKER)
2371 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
2373 #define strndup rep_strndup
2376 char *s1
= strndup(s
, n
);
2377 #if defined(PARANOID_MALLOC_CHECKER)
2381 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2384 smb_panic("smb_xstrndup: malloc failed");
2390 vasprintf that aborts on malloc fail
2393 int smb_xvasprintf(char **ptr
, const char *format
, va_list ap
)
2400 n
= vasprintf(ptr
, format
, ap2
);
2401 if (n
== -1 || ! *ptr
) {
2402 smb_panic("smb_xvasprintf: out of memory");
2407 /*****************************************************************
2408 Like strdup but for memory.
2409 *****************************************************************/
2411 void *memdup(const void *p
, size_t size
)
2416 p2
= SMB_MALLOC(size
);
2419 memcpy(p2
, p
, size
);
2423 /*****************************************************************
2424 Get local hostname and cache result.
2425 *****************************************************************/
2427 char *myhostname(void)
2431 /* This is cached forever so
2432 * use NULL talloc ctx. */
2433 ret
= get_myname(NULL
);
2438 /*****************************************************************
2439 A useful function for returning a path in the Samba pid directory.
2440 *****************************************************************/
2442 static char *xx_path(const char *name
, const char *rootpath
)
2446 fname
= talloc_strdup(talloc_tos(), rootpath
);
2450 trim_string(fname
,"","/");
2452 if (!directory_exist(fname
,NULL
)) {
2456 return talloc_asprintf(talloc_tos(),
2462 /*****************************************************************
2463 A useful function for returning a path in the Samba lock directory.
2464 *****************************************************************/
2466 char *lock_path(const char *name
)
2468 return xx_path(name
, lp_lockdir());
2471 /*****************************************************************
2472 A useful function for returning a path in the Samba pid directory.
2473 *****************************************************************/
2475 char *pid_path(const char *name
)
2477 return xx_path(name
, lp_piddir());
2481 * @brief Returns an absolute path to a file in the Samba lib directory.
2483 * @param name File to find, relative to LIBDIR.
2485 * @retval Pointer to a static #pstring containing the full path.
2488 char *lib_path(const char *name
)
2490 return talloc_asprintf(talloc_tos(), "%s/%s", dyn_LIBDIR
, name
);
2494 * @brief Returns an absolute path to a file in the Samba data directory.
2496 * @param name File to find, relative to CODEPAGEDIR.
2498 * @retval Pointer to a talloc'ed string containing the full path.
2501 char *data_path(const char *name
)
2503 return talloc_asprintf(talloc_tos(), "%s/%s", dyn_CODEPAGEDIR
, name
);
2506 /*****************************************************************
2507 a useful function for returning a path in the Samba state directory
2508 *****************************************************************/
2510 char *state_path(const char *name
)
2512 return xx_path(name
, dyn_STATEDIR());
2516 * @brief Returns the platform specific shared library extension.
2518 * @retval Pointer to a static #fstring containing the extension.
2521 const char *shlib_ext(void)
2523 return dyn_SHLIBEXT
;
2526 /*******************************************************************
2527 Given a filename - get its directory name
2528 NB: Returned in static storage. Caveats:
2529 o If caller wishes to preserve, they should copy.
2530 ********************************************************************/
2532 char *parent_dirname(const char *path
)
2536 if (!parent_dirname_talloc(talloc_tos(), path
, &parent
, NULL
)) {
2543 bool parent_dirname_talloc(TALLOC_CTX
*mem_ctx
, const char *dir
,
2544 char **parent
, const char **name
)
2549 p
= strrchr_m(dir
, '/'); /* Find final '/', if any */
2552 if (!(*parent
= talloc_strdup(mem_ctx
, "."))) {
2563 if (!(*parent
= TALLOC_ARRAY(mem_ctx
, char, len
+1))) {
2566 memcpy(*parent
, dir
, len
);
2567 (*parent
)[len
] = '\0';
2575 /*******************************************************************
2576 Determine if a pattern contains any Microsoft wildcard characters.
2577 *******************************************************************/
2579 bool ms_has_wild(const char *s
)
2583 if (lp_posix_pathnames()) {
2584 /* With posix pathnames no characters are wild. */
2588 while ((c
= *s
++)) {
2601 bool ms_has_wild_w(const smb_ucs2_t
*s
)
2604 if (!s
) return False
;
2605 while ((c
= *s
++)) {
2607 case UCS2_CHAR('*'):
2608 case UCS2_CHAR('?'):
2609 case UCS2_CHAR('<'):
2610 case UCS2_CHAR('>'):
2611 case UCS2_CHAR('"'):
2618 /*******************************************************************
2619 A wrapper that handles case sensitivity and the special handling
2621 *******************************************************************/
2623 bool mask_match(const char *string
, const char *pattern
, bool is_case_sensitive
)
2625 if (strcmp(string
,"..") == 0)
2627 if (strcmp(pattern
,".") == 0)
2630 return ms_fnmatch(pattern
, string
, Protocol
<= PROTOCOL_LANMAN2
, is_case_sensitive
) == 0;
2633 /*******************************************************************
2634 A wrapper that handles case sensitivity and the special handling
2635 of the ".." name. Varient that is only called by old search code which requires
2636 pattern translation.
2637 *******************************************************************/
2639 bool mask_match_search(const char *string
, const char *pattern
, bool is_case_sensitive
)
2641 if (strcmp(string
,"..") == 0)
2643 if (strcmp(pattern
,".") == 0)
2646 return ms_fnmatch(pattern
, string
, True
, is_case_sensitive
) == 0;
2649 /*******************************************************************
2650 A wrapper that handles a list of patters and calls mask_match()
2651 on each. Returns True if any of the patterns match.
2652 *******************************************************************/
2654 bool mask_match_list(const char *string
, char **list
, int listLen
, bool is_case_sensitive
)
2656 while (listLen
-- > 0) {
2657 if (mask_match(string
, *list
++, is_case_sensitive
))
2663 /*********************************************************
2664 Recursive routine that is called by unix_wild_match.
2665 *********************************************************/
2667 static bool unix_do_match(const char *regexp
, const char *str
)
2671 for( p
= regexp
; *p
&& *str
; ) {
2682 * Look for a character matching
2683 * the one after the '*'.
2687 return true; /* Automatic match */
2690 while(*str
&& (*p
!= *str
))
2694 * Patch from weidel@multichart.de. In the case of the regexp
2695 * '*XX*' we want to ensure there are at least 2 'X' characters
2696 * in the string after the '*' for a match to be made.
2703 * Eat all the characters that match, but count how many there were.
2706 while(*str
&& (*p
== *str
)) {
2712 * Now check that if the regexp had n identical characters that
2713 * matchcount had at least that many matches.
2716 while ( *(p
+1) && (*(p
+1) == *p
)) {
2721 if ( matchcount
<= 0 )
2725 str
--; /* We've eaten the match char after the '*' */
2727 if(unix_do_match(p
, str
))
2749 if (!*p
&& str
[0] == '.' && str
[1] == 0)
2752 if (!*str
&& *p
== '?') {
2758 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
2764 /*******************************************************************
2765 Simple case insensitive interface to a UNIX wildcard matcher.
2766 Returns True if match, False if not.
2767 *******************************************************************/
2769 bool unix_wild_match(const char *pattern
, const char *string
)
2771 TALLOC_CTX
*ctx
= talloc_stackframe();
2777 p2
= talloc_strdup(ctx
,pattern
);
2778 s2
= talloc_strdup(ctx
,string
);
2786 /* Remove any *? and ** from the pattern as they are meaningless */
2787 for(p
= p2
; *p
; p
++) {
2788 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*')) {
2789 memmove(&p
[1], &p
[2], strlen(&p
[2])+1);
2793 if (strequal(p2
,"*")) {
2798 ret
= unix_do_match(p2
, s2
);
2803 /**********************************************************************
2804 Converts a name to a fully qualified domain name.
2805 Returns true if lookup succeeded, false if not (then fqdn is set to name)
2806 Note we deliberately use gethostbyname here, not getaddrinfo as we want
2807 to examine the h_aliases and I don't know how to do that with getaddrinfo.
2808 ***********************************************************************/
2810 bool name_to_fqdn(fstring fqdn
, const char *name
)
2813 struct hostent
*hp
= gethostbyname(name
);
2815 if (!hp
|| !hp
->h_name
|| !*hp
->h_name
) {
2816 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name
));
2817 fstrcpy(fqdn
, name
);
2821 /* Find out if the fqdn is returned as an alias
2822 * to cope with /etc/hosts files where the first
2823 * name is not the fqdn but the short name */
2824 if (hp
->h_aliases
&& (! strchr_m(hp
->h_name
, '.'))) {
2826 for (i
= 0; hp
->h_aliases
[i
]; i
++) {
2827 if (strchr_m(hp
->h_aliases
[i
], '.')) {
2828 full
= hp
->h_aliases
[i
];
2833 if (full
&& (StrCaseCmp(full
, "localhost.localdomain") == 0)) {
2834 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2835 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2836 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
2837 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
2844 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name
, full
));
2845 fstrcpy(fqdn
, full
);
2849 /**********************************************************************
2850 Extension to talloc_get_type: Abort on type mismatch
2851 ***********************************************************************/
2853 void *talloc_check_name_abort(const void *ptr
, const char *name
)
2857 result
= talloc_check_name(ptr
, name
);
2861 DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2862 name
, talloc_get_name(ptr
)));
2863 smb_panic("talloc type mismatch");
2864 /* Keep the compiler happy */
2868 uint32
map_share_mode_to_deny_mode(uint32 share_access
, uint32 private_options
)
2870 switch (share_access
& ~FILE_SHARE_DELETE
) {
2871 case FILE_SHARE_NONE
:
2873 case FILE_SHARE_READ
:
2875 case FILE_SHARE_WRITE
:
2877 case FILE_SHARE_READ
|FILE_SHARE_WRITE
:
2880 if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) {
2882 } else if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
) {
2889 pid_t
procid_to_pid(const struct server_id
*proc
)
2894 static uint32 my_vnn
= NONCLUSTER_VNN
;
2896 void set_my_vnn(uint32 vnn
)
2898 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn
));
2902 uint32
get_my_vnn(void)
2907 struct server_id
pid_to_procid(pid_t pid
)
2909 struct server_id result
;
2911 #ifdef CLUSTER_SUPPORT
2912 result
.vnn
= my_vnn
;
2917 struct server_id
procid_self(void)
2919 return pid_to_procid(sys_getpid());
2922 struct server_id
server_id_self(void)
2924 return procid_self();
2927 bool procid_equal(const struct server_id
*p1
, const struct server_id
*p2
)
2929 if (p1
->pid
!= p2
->pid
)
2931 #ifdef CLUSTER_SUPPORT
2932 if (p1
->vnn
!= p2
->vnn
)
2938 bool cluster_id_equal(const struct server_id
*id1
,
2939 const struct server_id
*id2
)
2941 return procid_equal(id1
, id2
);
2944 bool procid_is_me(const struct server_id
*pid
)
2946 if (pid
->pid
!= sys_getpid())
2948 #ifdef CLUSTER_SUPPORT
2949 if (pid
->vnn
!= my_vnn
)
2955 struct server_id
interpret_pid(const char *pid_string
)
2957 #ifdef CLUSTER_SUPPORT
2958 unsigned int vnn
, pid
;
2959 struct server_id result
;
2960 if (sscanf(pid_string
, "%u:%u", &vnn
, &pid
) == 2) {
2964 else if (sscanf(pid_string
, "%u", &pid
) == 1) {
2965 result
.vnn
= NONCLUSTER_VNN
;
2969 result
.vnn
= NONCLUSTER_VNN
;
2974 return pid_to_procid(atoi(pid_string
));
2978 char *procid_str(TALLOC_CTX
*mem_ctx
, const struct server_id
*pid
)
2980 #ifdef CLUSTER_SUPPORT
2981 if (pid
->vnn
== NONCLUSTER_VNN
) {
2982 return talloc_asprintf(mem_ctx
,
2987 return talloc_asprintf(mem_ctx
,
2993 return talloc_asprintf(mem_ctx
,
2999 char *procid_str_static(const struct server_id
*pid
)
3001 return procid_str(talloc_tos(), pid
);
3004 bool procid_valid(const struct server_id
*pid
)
3006 return (pid
->pid
!= -1);
3009 bool procid_is_local(const struct server_id
*pid
)
3011 #ifdef CLUSTER_SUPPORT
3012 return pid
->vnn
== my_vnn
;
3018 int this_is_smp(void)
3020 #if defined(HAVE_SYSCONF)
3022 #if defined(SYSCONF_SC_NPROC_ONLN)
3023 return (sysconf(_SC_NPROC_ONLN
) > 1) ? 1 : 0;
3024 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3025 return (sysconf(_SC_NPROCESSORS_ONLN
) > 1) ? 1 : 0;
3035 /****************************************************************
3036 Check if an offset into a buffer is safe.
3037 If this returns True it's safe to indirect into the byte at
3039 ****************************************************************/
3041 bool is_offset_safe(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
3043 const char *end_base
= buf_base
+ buf_len
;
3044 char *end_ptr
= ptr
+ off
;
3046 if (!buf_base
|| !ptr
) {
3050 if (end_base
< buf_base
|| end_ptr
< ptr
) {
3051 return False
; /* wrap. */
3054 if (end_ptr
< end_base
) {
3060 /****************************************************************
3061 Return a safe pointer into a buffer, or NULL.
3062 ****************************************************************/
3064 char *get_safe_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
3066 return is_offset_safe(buf_base
, buf_len
, ptr
, off
) ?
3070 /****************************************************************
3071 Return a safe pointer into a string within a buffer, or NULL.
3072 ****************************************************************/
3074 char *get_safe_str_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
3076 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
)) {
3079 /* Check if a valid string exists at this offset. */
3080 if (skip_string(buf_base
,buf_len
, ptr
+ off
) == NULL
) {
3086 /****************************************************************
3087 Return an SVAL at a pointer, or failval if beyond the end.
3088 ****************************************************************/
3090 int get_safe_SVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
3093 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
3096 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+1)) {
3099 return SVAL(ptr
,off
);
3102 /****************************************************************
3103 Return an IVAL at a pointer, or failval if beyond the end.
3104 ****************************************************************/
3106 int get_safe_IVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
3109 * Note we use off+3 here, not off+4 as IVAL accesses
3110 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
3112 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+3)) {
3115 return IVAL(ptr
,off
);
3120 Disable these now we have checked all code paths
and ensured
3121 NULL returns on zero request
. JRA
.
3123 /****************************************************************
3124 talloc wrapper functions that guarentee a null pointer return
3126 ****************************************************************/
3128 #ifndef MAX_TALLOC_SIZE
3129 #define MAX_TALLOC_SIZE 0x10000000
3133 * talloc and zero memory.
3134 * - returns NULL if size is zero.
3137 void *_talloc_zero_zeronull(const void *ctx
, size_t size
, const char *name
)
3145 p
= talloc_named_const(ctx
, size
, name
);
3148 memset(p
, '\0', size
);
3155 * memdup with a talloc.
3156 * - returns NULL if size is zero.
3159 void *_talloc_memdup_zeronull(const void *t
, const void *p
, size_t size
, const char *name
)
3167 newp
= talloc_named_const(t
, size
, name
);
3169 memcpy(newp
, p
, size
);
3176 * alloc an array, checking for integer overflow in the array size.
3177 * - returns NULL if count or el_size are zero.
3180 void *_talloc_array_zeronull(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
3182 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
3186 if (el_size
== 0 || count
== 0) {
3190 return talloc_named_const(ctx
, el_size
* count
, name
);
3194 * alloc an zero array, checking for integer overflow in the array size
3195 * - returns NULL if count or el_size are zero.
3198 void *_talloc_zero_array_zeronull(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
3200 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
3204 if (el_size
== 0 || count
== 0) {
3208 return _talloc_zero(ctx
, el_size
* count
, name
);
3212 * Talloc wrapper that returns NULL if size == 0.
3214 void *talloc_zeronull(const void *context
, size_t size
, const char *name
)
3219 return talloc_named_const(context
, size
, name
);