Remove unneeded variable.
[ira/wip.git] / source3 / lib / util.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jeremy Allison 2001-2002
6    Copyright (C) Simo Sorce 2001
7    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8    Copyright (C) James Peach 2006
9
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.
14    
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.
19    
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/>.
22 */
23
24 #include "includes.h"
25
26 extern fstring local_machine;
27 extern char *global_clobber_region_function;
28 extern unsigned int global_clobber_region_line;
29 extern fstring remote_arch;
30
31 /* Max allowable allococation - 256mb - 0x10000000 */
32 #define MAX_ALLOC_SIZE (1024*1024*256)
33
34 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
35 #ifdef WITH_NISPLUS_HOME
36 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
37 /*
38  * The following lines are needed due to buggy include files
39  * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
40  * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
41  * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
42  * an enum in /usr/include/rpcsvc/nis.h.
43  */
44
45 #if defined(GROUP)
46 #undef GROUP
47 #endif
48
49 #if defined(GROUP_OBJ)
50 #undef GROUP_OBJ
51 #endif
52
53 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
54
55 #include <rpcsvc/nis.h>
56
57 #endif /* WITH_NISPLUS_HOME */
58 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
59
60 enum protocol_types Protocol = PROTOCOL_COREPLUS;
61
62 /* a default finfo structure to ensure all fields are sensible */
63 file_info def_finfo;
64
65 /* this is used by the chaining code */
66 int chain_size = 0;
67
68 int trans_num = 0;
69
70 static enum remote_arch_types ra_type = RA_UNKNOWN;
71 pstring user_socket_options=DEFAULT_SOCKET_OPTIONS;   
72
73 /***********************************************************************
74  Definitions for all names.
75 ***********************************************************************/
76
77 static char *smb_myname;
78 static char *smb_myworkgroup;
79 static char *smb_scope;
80 static int smb_num_netbios_names;
81 static char **smb_my_netbios_names;
82
83 /***********************************************************************
84  Allocate and set myname. Ensure upper case.
85 ***********************************************************************/
86
87 bool set_global_myname(const char *myname)
88 {
89         SAFE_FREE(smb_myname);
90         smb_myname = SMB_STRDUP(myname);
91         if (!smb_myname)
92                 return False;
93         strupper_m(smb_myname);
94         return True;
95 }
96
97 const char *global_myname(void)
98 {
99         return smb_myname;
100 }
101
102 /***********************************************************************
103  Allocate and set myworkgroup. Ensure upper case.
104 ***********************************************************************/
105
106 bool set_global_myworkgroup(const char *myworkgroup)
107 {
108         SAFE_FREE(smb_myworkgroup);
109         smb_myworkgroup = SMB_STRDUP(myworkgroup);
110         if (!smb_myworkgroup)
111                 return False;
112         strupper_m(smb_myworkgroup);
113         return True;
114 }
115
116 const char *lp_workgroup(void)
117 {
118         return smb_myworkgroup;
119 }
120
121 /***********************************************************************
122  Allocate and set scope. Ensure upper case.
123 ***********************************************************************/
124
125 bool set_global_scope(const char *scope)
126 {
127         SAFE_FREE(smb_scope);
128         smb_scope = SMB_STRDUP(scope);
129         if (!smb_scope)
130                 return False;
131         strupper_m(smb_scope);
132         return True;
133 }
134
135 /*********************************************************************
136  Ensure scope is never null string.
137 *********************************************************************/
138
139 const char *global_scope(void)
140 {
141         if (!smb_scope)
142                 set_global_scope("");
143         return smb_scope;
144 }
145
146 static void free_netbios_names_array(void)
147 {
148         int i;
149
150         for (i = 0; i < smb_num_netbios_names; i++)
151                 SAFE_FREE(smb_my_netbios_names[i]);
152
153         SAFE_FREE(smb_my_netbios_names);
154         smb_num_netbios_names = 0;
155 }
156
157 static bool allocate_my_netbios_names_array(size_t number)
158 {
159         free_netbios_names_array();
160
161         smb_num_netbios_names = number + 1;
162         smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
163
164         if (!smb_my_netbios_names)
165                 return False;
166
167         memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
168         return True;
169 }
170
171 static bool set_my_netbios_names(const char *name, int i)
172 {
173         SAFE_FREE(smb_my_netbios_names[i]);
174
175         smb_my_netbios_names[i] = SMB_STRDUP(name);
176         if (!smb_my_netbios_names[i])
177                 return False;
178         strupper_m(smb_my_netbios_names[i]);
179         return True;
180 }
181
182 /***********************************************************************
183  Free memory allocated to global objects
184 ***********************************************************************/
185
186 void gfree_names(void)
187 {
188         SAFE_FREE( smb_myname );
189         SAFE_FREE( smb_myworkgroup );
190         SAFE_FREE( smb_scope );
191         free_netbios_names_array();
192 }
193
194 void gfree_all( void )
195 {
196         gfree_names();  
197         gfree_loadparm();
198         gfree_case_tables();
199         gfree_debugsyms();
200         gfree_charcnv();
201         gfree_interfaces();
202
203         /* release the talloc null_context memory last */
204         talloc_disable_null_tracking();
205 }
206
207 const char *my_netbios_names(int i)
208 {
209         return smb_my_netbios_names[i];
210 }
211
212 bool set_netbios_aliases(const char **str_array)
213 {
214         size_t namecount;
215
216         /* Work out the max number of netbios aliases that we have */
217         for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
218                 ;
219
220         if ( global_myname() && *global_myname())
221                 namecount++;
222
223         /* Allocate space for the netbios aliases */
224         if (!allocate_my_netbios_names_array(namecount))
225                 return False;
226
227         /* Use the global_myname string first */
228         namecount=0;
229         if ( global_myname() && *global_myname()) {
230                 set_my_netbios_names( global_myname(), namecount );
231                 namecount++;
232         }
233
234         if (str_array) {
235                 size_t i;
236                 for ( i = 0; str_array[i] != NULL; i++) {
237                         size_t n;
238                         bool duplicate = False;
239
240                         /* Look for duplicates */
241                         for( n=0; n<namecount; n++ ) {
242                                 if( strequal( str_array[i], my_netbios_names(n) ) ) {
243                                         duplicate = True;
244                                         break;
245                                 }
246                         }
247                         if (!duplicate) {
248                                 if (!set_my_netbios_names(str_array[i], namecount))
249                                         return False;
250                                 namecount++;
251                         }
252                 }
253         }
254         return True;
255 }
256
257 /****************************************************************************
258   Common name initialization code.
259 ****************************************************************************/
260
261 bool init_names(void)
262 {
263         char *p;
264         int n;
265
266         if (global_myname() == NULL || *global_myname() == '\0') {
267                 if (!set_global_myname(myhostname())) {
268                         DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
269                         return False;
270                 }
271         }
272
273         if (!set_netbios_aliases(lp_netbios_aliases())) {
274                 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
275                 return False;
276         }                       
277
278         fstrcpy( local_machine, global_myname() );
279         trim_char( local_machine, ' ', ' ' );
280         p = strchr( local_machine, ' ' );
281         if (p)
282                 *p = 0;
283         strlower_m( local_machine );
284
285         DEBUG( 5, ("Netbios name list:-\n") );
286         for( n=0; my_netbios_names(n); n++ )
287                 DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names(n) ) );
288
289         return( True );
290 }
291
292 /**************************************************************************n
293  Find a suitable temporary directory. The result should be copied immediately
294  as it may be overwritten by a subsequent call.
295 ****************************************************************************/
296
297 const char *tmpdir(void)
298 {
299         char *p;
300         if ((p = getenv("TMPDIR")))
301                 return p;
302         return "/tmp";
303 }
304
305 /****************************************************************************
306  Add a gid to an array of gids if it's not already there.
307 ****************************************************************************/
308
309 bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
310                              gid_t **gids, size_t *num_gids)
311 {
312         int i;
313
314         if ((*num_gids != 0) && (*gids == NULL)) {
315                 /*
316                  * A former call to this routine has failed to allocate memory
317                  */
318                 return False;
319         }
320
321         for (i=0; i<*num_gids; i++) {
322                 if ((*gids)[i] == gid) {
323                         return True;
324                 }
325         }
326
327         *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1);
328         if (*gids == NULL) {
329                 *num_gids = 0;
330                 return False;
331         }
332
333         (*gids)[*num_gids] = gid;
334         *num_gids += 1;
335         return True;
336 }
337
338 /****************************************************************************
339  Like atoi but gets the value up to the separator character.
340 ****************************************************************************/
341
342 static const char *Atoic(const char *p, int *n, const char *c)
343 {
344         if (!isdigit((int)*p)) {
345                 DEBUG(5, ("Atoic: malformed number\n"));
346                 return NULL;
347         }
348
349         (*n) = atoi(p);
350
351         while ((*p) && isdigit((int)*p))
352                 p++;
353
354         if (strchr_m(c, *p) == NULL) {
355                 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
356                 return NULL;
357         }
358
359         return p;
360 }
361
362 /*************************************************************************
363  Reads a list of numbers.
364  *************************************************************************/
365
366 const char *get_numlist(const char *p, uint32 **num, int *count)
367 {
368         int val;
369
370         if (num == NULL || count == NULL)
371                 return NULL;
372
373         (*count) = 0;
374         (*num  ) = NULL;
375
376         while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
377                 *num = SMB_REALLOC_ARRAY((*num), uint32, (*count)+1);
378                 if (!(*num)) {
379                         return NULL;
380                 }
381                 (*num)[(*count)] = val;
382                 (*count)++;
383                 p++;
384         }
385
386         return p;
387 }
388
389 /*******************************************************************
390  Check if a file exists - call vfs_file_exist for samba files.
391 ********************************************************************/
392
393 bool file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
394 {
395         SMB_STRUCT_STAT st;
396         if (!sbuf)
397                 sbuf = &st;
398   
399         if (sys_stat(fname,sbuf) != 0) 
400                 return(False);
401
402         return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
403 }
404
405 /*******************************************************************
406  Check a files mod time.
407 ********************************************************************/
408
409 time_t file_modtime(const char *fname)
410 {
411         SMB_STRUCT_STAT st;
412   
413         if (sys_stat(fname,&st) != 0) 
414                 return(0);
415
416         return(st.st_mtime);
417 }
418
419 /*******************************************************************
420  Check if a directory exists.
421 ********************************************************************/
422
423 bool directory_exist(char *dname,SMB_STRUCT_STAT *st)
424 {
425         SMB_STRUCT_STAT st2;
426         bool ret;
427
428         if (!st)
429                 st = &st2;
430
431         if (sys_stat(dname,st) != 0) 
432                 return(False);
433
434         ret = S_ISDIR(st->st_mode);
435         if(!ret)
436                 errno = ENOTDIR;
437         return ret;
438 }
439
440 /*******************************************************************
441  Returns the size in bytes of the named file.
442 ********************************************************************/
443
444 SMB_OFF_T get_file_size(char *file_name)
445 {
446         SMB_STRUCT_STAT buf;
447         buf.st_size = 0;
448         if(sys_stat(file_name,&buf) != 0)
449                 return (SMB_OFF_T)-1;
450         return(buf.st_size);
451 }
452
453 /*******************************************************************
454  Return a string representing an attribute for a file.
455 ********************************************************************/
456
457 char *attrib_string(uint16 mode)
458 {
459         fstring attrstr;
460
461         attrstr[0] = 0;
462
463         if (mode & aVOLID) fstrcat(attrstr,"V");
464         if (mode & aDIR) fstrcat(attrstr,"D");
465         if (mode & aARCH) fstrcat(attrstr,"A");
466         if (mode & aHIDDEN) fstrcat(attrstr,"H");
467         if (mode & aSYSTEM) fstrcat(attrstr,"S");
468         if (mode & aRONLY) fstrcat(attrstr,"R");          
469
470         return talloc_strdup(talloc_tos(), attrstr);
471 }
472
473 /*******************************************************************
474  Show a smb message structure.
475 ********************************************************************/
476
477 void show_msg(char *buf)
478 {
479         int i;
480         int bcc=0;
481
482         if (!DEBUGLVL(5))
483                 return;
484         
485         DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
486                         smb_len(buf),
487                         (int)CVAL(buf,smb_com),
488                         (int)CVAL(buf,smb_rcls),
489                         (int)CVAL(buf,smb_reh),
490                         (int)SVAL(buf,smb_err),
491                         (int)CVAL(buf,smb_flg),
492                         (int)SVAL(buf,smb_flg2)));
493         DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
494                         (int)SVAL(buf,smb_tid),
495                         (int)SVAL(buf,smb_pid),
496                         (int)SVAL(buf,smb_uid),
497                         (int)SVAL(buf,smb_mid)));
498         DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
499
500         for (i=0;i<(int)CVAL(buf,smb_wct);i++)
501                 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
502                         SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
503         
504         bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
505
506         DEBUGADD(5,("smb_bcc=%d\n",bcc));
507
508         if (DEBUGLEVEL < 10)
509                 return;
510
511         if (DEBUGLEVEL < 50)
512                 bcc = MIN(bcc, 512);
513
514         dump_data(10, (uint8 *)smb_buf(buf), bcc);      
515 }
516
517 /*******************************************************************
518  Set the length and marker of an smb packet.
519 ********************************************************************/
520
521 void smb_setlen(char *buf,int len)
522 {
523         _smb_setlen(buf,len);
524
525         SCVAL(buf,4,0xFF);
526         SCVAL(buf,5,'S');
527         SCVAL(buf,6,'M');
528         SCVAL(buf,7,'B');
529 }
530
531 /*******************************************************************
532  Setup the word count and byte count for a smb message.
533 ********************************************************************/
534
535 int set_message(char *buf,int num_words,int num_bytes,bool zero)
536 {
537         if (zero && (num_words || num_bytes)) {
538                 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
539         }
540         SCVAL(buf,smb_wct,num_words);
541         SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);  
542         smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
543         return (smb_size + num_words*2 + num_bytes);
544 }
545
546 /*******************************************************************
547  Setup only the byte count for a smb message.
548 ********************************************************************/
549
550 int set_message_bcc(char *buf,int num_bytes)
551 {
552         int num_words = CVAL(buf,smb_wct);
553         SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
554         smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
555         return (smb_size + num_words*2 + num_bytes);
556 }
557
558 /*******************************************************************
559  Setup only the byte count for a smb message, using the end of the
560  message as a marker.
561 ********************************************************************/
562
563 int set_message_end(void *outbuf,void *end_ptr)
564 {
565         return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
566 }
567
568 /*******************************************************************
569  Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
570  Return the bytes added
571 ********************************************************************/
572
573 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
574 {
575         size_t newlen = smb_len(*outbuf) + 4 + blob.length;
576         uint8 *tmp;
577
578         if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
579                 DEBUG(0, ("talloc failed\n"));
580                 return -1;
581         }
582         *outbuf = tmp;
583
584         memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
585         set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
586         return blob.length;
587 }
588
589 /*******************************************************************
590  Reduce a file name, removing .. elements.
591 ********************************************************************/
592
593 void dos_clean_name(char *s)
594 {
595         char *p=NULL;
596
597         DEBUG(3,("dos_clean_name [%s]\n",s));
598
599         /* remove any double slashes */
600         all_string_sub(s, "\\\\", "\\", 0);
601
602         /* Remove leading .\\ characters */
603         if(strncmp(s, ".\\", 2) == 0) {
604                 trim_string(s, ".\\", NULL);
605                 if(*s == 0)
606                         pstrcpy(s,".\\");
607         }
608
609         while ((p = strstr_m(s,"\\..\\")) != NULL) {
610                 pstring s1;
611
612                 *p = 0;
613                 pstrcpy(s1,p+3);
614
615                 if ((p=strrchr_m(s,'\\')) != NULL)
616                         *p = 0;
617                 else
618                         *s = 0;
619                 pstrcat(s,s1);
620         }  
621
622         trim_string(s,NULL,"\\..");
623         all_string_sub(s, "\\.\\", "\\", 0);
624 }
625
626 /*******************************************************************
627  Reduce a file name, removing .. elements. 
628 ********************************************************************/
629
630 void unix_clean_name(char *s)
631 {
632         char *p=NULL;
633
634         DEBUG(3,("unix_clean_name [%s]\n",s));
635
636         /* remove any double slashes */
637         all_string_sub(s, "//","/", 0);
638
639         /* Remove leading ./ characters */
640         if(strncmp(s, "./", 2) == 0) {
641                 trim_string(s, "./", NULL);
642                 if(*s == 0)
643                         pstrcpy(s,"./");
644         }
645
646         while ((p = strstr_m(s,"/../")) != NULL) {
647                 pstring s1;
648
649                 *p = 0;
650                 pstrcpy(s1,p+3);
651
652                 if ((p=strrchr_m(s,'/')) != NULL)
653                         *p = 0;
654                 else
655                         *s = 0;
656                 pstrcat(s,s1);
657         }  
658
659         trim_string(s,NULL,"/..");
660         all_string_sub(s, "/./", "/", 0);
661 }
662
663 void clean_name(char *s)
664 {
665         dos_clean_name(s);
666         unix_clean_name(s);
667 }
668
669 /*******************************************************************
670  Close the low 3 fd's and open dev/null in their place.
671 ********************************************************************/
672
673 void close_low_fds(bool stderr_too)
674 {
675 #ifndef VALGRIND
676         int fd;
677         int i;
678
679         close(0);
680         close(1); 
681
682         if (stderr_too)
683                 close(2);
684
685         /* try and use up these file descriptors, so silly
686                 library routines writing to stdout etc won't cause havoc */
687         for (i=0;i<3;i++) {
688                 if (i == 2 && !stderr_too)
689                         continue;
690
691                 fd = sys_open("/dev/null",O_RDWR,0);
692                 if (fd < 0)
693                         fd = sys_open("/dev/null",O_WRONLY,0);
694                 if (fd < 0) {
695                         DEBUG(0,("Can't open /dev/null\n"));
696                         return;
697                 }
698                 if (fd != i) {
699                         DEBUG(0,("Didn't get file descriptor %d\n",i));
700                         return;
701                 }
702         }
703 #endif
704 }
705
706 /*******************************************************************
707  Write data into an fd at a given offset. Ignore seek errors.
708 ********************************************************************/
709
710 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
711 {
712         size_t total=0;
713         ssize_t ret;
714
715         if (pos == (SMB_OFF_T)-1) {
716                 return write_data(fd, buffer, N);
717         }
718 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
719         while (total < N) {
720                 ret = sys_pwrite(fd,buffer + total,N - total, pos);
721                 if (ret == -1 && errno == ESPIPE) {
722                         return write_data(fd, buffer + total,N - total);
723                 }
724                 if (ret == -1) {
725                         DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
726                         return -1;
727                 }
728                 if (ret == 0) {
729                         return total;
730                 }
731                 total += ret;
732                 pos += ret;
733         }
734         return (ssize_t)total;
735 #else
736         /* Use lseek and write_data. */
737         if (sys_lseek(fd, pos, SEEK_SET) == -1) {
738                 if (errno != ESPIPE) {
739                         return -1;
740                 }
741         }
742         return write_data(fd, buffer, N);
743 #endif
744 }
745
746 /****************************************************************************
747  Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
748  else
749   if SYSV use O_NDELAY
750   if BSD use FNDELAY
751 ****************************************************************************/
752
753 int set_blocking(int fd, bool set)
754 {
755         int val;
756 #ifdef O_NONBLOCK
757 #define FLAG_TO_SET O_NONBLOCK
758 #else
759 #ifdef SYSV
760 #define FLAG_TO_SET O_NDELAY
761 #else /* BSD */
762 #define FLAG_TO_SET FNDELAY
763 #endif
764 #endif
765
766         if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
767                 return -1;
768         if(set) /* Turn blocking on - ie. clear nonblock flag */
769                 val &= ~FLAG_TO_SET;
770         else
771                 val |= FLAG_TO_SET;
772         return sys_fcntl_long( fd, F_SETFL, val);
773 #undef FLAG_TO_SET
774 }
775
776 /****************************************************************************
777  Transfer some data between two fd's.
778 ****************************************************************************/
779
780 #ifndef TRANSFER_BUF_SIZE
781 #define TRANSFER_BUF_SIZE 65536
782 #endif
783
784 ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t),
785                                                 ssize_t (*write_fn)(int, const void *, size_t))
786 {
787         char *buf;
788         size_t total = 0;
789         ssize_t read_ret;
790         ssize_t write_ret;
791         size_t num_to_read_thistime;
792         size_t num_written = 0;
793
794         if ((buf = SMB_MALLOC_ARRAY(char, TRANSFER_BUF_SIZE)) == NULL)
795                 return -1;
796
797         while (total < n) {
798                 num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
799
800                 read_ret = (*read_fn)(infd, buf, num_to_read_thistime);
801                 if (read_ret == -1) {
802                         DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) ));
803                         SAFE_FREE(buf);
804                         return -1;
805                 }
806                 if (read_ret == 0)
807                         break;
808
809                 num_written = 0;
810  
811                 while (num_written < read_ret) {
812                         write_ret = (*write_fn)(outfd,buf + num_written, read_ret - num_written);
813  
814                         if (write_ret == -1) {
815                                 DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) ));
816                                 SAFE_FREE(buf);
817                                 return -1;
818                         }
819                         if (write_ret == 0)
820                                 return (ssize_t)total;
821  
822                         num_written += (size_t)write_ret;
823                 }
824
825                 total += (size_t)read_ret;
826         }
827
828         SAFE_FREE(buf);
829         return (ssize_t)total;          
830 }
831
832 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
833 {
834         return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, sys_read, sys_write);
835 }
836
837 /*******************************************************************
838  Sleep for a specified number of milliseconds.
839 ********************************************************************/
840
841 void smb_msleep(unsigned int t)
842 {
843 #if defined(HAVE_NANOSLEEP)
844         struct timespec tval;
845         int ret;
846
847         tval.tv_sec = t/1000;
848         tval.tv_nsec = 1000000*(t%1000);
849
850         do {
851                 errno = 0;
852                 ret = nanosleep(&tval, &tval);
853         } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
854 #else
855         unsigned int tdiff=0;
856         struct timeval tval,t1,t2;  
857         fd_set fds;
858
859         GetTimeOfDay(&t1);
860         t2 = t1;
861   
862         while (tdiff < t) {
863                 tval.tv_sec = (t-tdiff)/1000;
864                 tval.tv_usec = 1000*((t-tdiff)%1000);
865
866                 /* Never wait for more than 1 sec. */
867                 if (tval.tv_sec > 1) {
868                         tval.tv_sec = 1; 
869                         tval.tv_usec = 0;
870                 }
871
872                 FD_ZERO(&fds);
873                 errno = 0;
874                 sys_select_intr(0,&fds,NULL,NULL,&tval);
875
876                 GetTimeOfDay(&t2);
877                 if (t2.tv_sec < t1.tv_sec) {
878                         /* Someone adjusted time... */
879                         t1 = t2;
880                 }
881
882                 tdiff = TvalDiff(&t1,&t2);
883         }
884 #endif
885 }
886
887 /****************************************************************************
888  Become a daemon, discarding the controlling terminal.
889 ****************************************************************************/
890
891 void become_daemon(bool Fork, bool no_process_group)
892 {
893         if (Fork) {
894                 if (sys_fork()) {
895                         _exit(0);
896                 }
897         }
898
899   /* detach from the terminal */
900 #ifdef HAVE_SETSID
901         if (!no_process_group) setsid();
902 #elif defined(TIOCNOTTY)
903         if (!no_process_group) {
904                 int i = sys_open("/dev/tty", O_RDWR, 0);
905                 if (i != -1) {
906                         ioctl(i, (int) TIOCNOTTY, (char *)0);      
907                         close(i);
908                 }
909         }
910 #endif /* HAVE_SETSID */
911
912         /* Close fd's 0,1,2. Needed if started by rsh */
913         close_low_fds(False);  /* Don't close stderr, let the debug system
914                                   attach it to the logfile */
915 }
916
917 /****************************************************************************
918  Put up a yes/no prompt.
919 ****************************************************************************/
920
921 bool yesno(char *p)
922 {
923         pstring ans;
924         printf("%s",p);
925
926         if (!fgets(ans,sizeof(ans)-1,stdin))
927                 return(False);
928
929         if (*ans == 'y' || *ans == 'Y')
930                 return(True);
931
932         return(False);
933 }
934
935 #if defined(PARANOID_MALLOC_CHECKER)
936
937 /****************************************************************************
938  Internal malloc wrapper. Externally visible.
939 ****************************************************************************/
940
941 void *malloc_(size_t size)
942 {
943         if (size == 0) {
944                 return NULL;
945         }
946 #undef malloc
947         return malloc(size);
948 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
949 }
950
951 /****************************************************************************
952  Internal calloc wrapper. Not externally visible.
953 ****************************************************************************/
954
955 static void *calloc_(size_t count, size_t size)
956 {
957         if (size == 0 || count == 0) {
958                 return NULL;
959         }
960 #undef calloc
961         return calloc(count, size);
962 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
963 }
964
965 /****************************************************************************
966  Internal realloc wrapper. Not externally visible.
967 ****************************************************************************/
968
969 static void *realloc_(void *ptr, size_t size)
970 {
971 #undef realloc
972         return realloc(ptr, size);
973 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
974 }
975
976 #endif /* PARANOID_MALLOC_CHECKER */
977
978 /****************************************************************************
979  Type-safe malloc.
980 ****************************************************************************/
981
982 void *malloc_array(size_t el_size, unsigned int count)
983 {
984         if (count >= MAX_ALLOC_SIZE/el_size) {
985                 return NULL;
986         }
987
988         if (el_size == 0 || count == 0) {
989                 return NULL;
990         }
991 #if defined(PARANOID_MALLOC_CHECKER)
992         return malloc_(el_size*count);
993 #else
994         return malloc(el_size*count);
995 #endif
996 }
997
998 /****************************************************************************
999  Type-safe memalign
1000 ****************************************************************************/
1001
1002 void *memalign_array(size_t el_size, size_t align, unsigned int count)
1003 {
1004         if (count >= MAX_ALLOC_SIZE/el_size) {
1005                 return NULL;
1006         }
1007
1008         return sys_memalign(align, el_size*count);
1009 }
1010
1011 /****************************************************************************
1012  Type-safe calloc.
1013 ****************************************************************************/
1014
1015 void *calloc_array(size_t size, size_t nmemb)
1016 {
1017         if (nmemb >= MAX_ALLOC_SIZE/size) {
1018                 return NULL;
1019         }
1020         if (size == 0 || nmemb == 0) {
1021                 return NULL;
1022         }
1023 #if defined(PARANOID_MALLOC_CHECKER)
1024         return calloc_(nmemb, size);
1025 #else
1026         return calloc(nmemb, size);
1027 #endif
1028 }
1029
1030 /****************************************************************************
1031  Expand a pointer to be a particular size.
1032  Note that this version of Realloc has an extra parameter that decides
1033  whether to free the passed in storage on allocation failure or if the
1034  new size is zero.
1035
1036  This is designed for use in the typical idiom of :
1037
1038  p = SMB_REALLOC(p, size)
1039  if (!p) {
1040     return error;
1041  }
1042
1043  and not to have to keep track of the old 'p' contents to free later, nor
1044  to worry if the size parameter was zero. In the case where NULL is returned
1045  we guarentee that p has been freed.
1046
1047  If free later semantics are desired, then pass 'free_old_on_error' as False which
1048  guarentees that the old contents are not freed on error, even if size == 0. To use
1049  this idiom use :
1050
1051  tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
1052  if (!tmp) {
1053     SAFE_FREE(p);
1054     return error;
1055  } else {
1056     p = tmp;
1057  }
1058
1059  Changes were instigated by Coverity error checking. JRA.
1060 ****************************************************************************/
1061
1062 void *Realloc(void *p, size_t size, bool free_old_on_error)
1063 {
1064         void *ret=NULL;
1065
1066         if (size == 0) {
1067                 if (free_old_on_error) {
1068                         SAFE_FREE(p);
1069                 }
1070                 DEBUG(2,("Realloc asked for 0 bytes\n"));
1071                 return NULL;
1072         }
1073
1074 #if defined(PARANOID_MALLOC_CHECKER)
1075         if (!p) {
1076                 ret = (void *)malloc_(size);
1077         } else {
1078                 ret = (void *)realloc_(p,size);
1079         }
1080 #else
1081         if (!p) {
1082                 ret = (void *)malloc(size);
1083         } else {
1084                 ret = (void *)realloc(p,size);
1085         }
1086 #endif
1087
1088         if (!ret) {
1089                 if (free_old_on_error && p) {
1090                         SAFE_FREE(p);
1091                 }
1092                 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1093         }
1094
1095         return(ret);
1096 }
1097
1098 /****************************************************************************
1099  Type-safe realloc.
1100 ****************************************************************************/
1101
1102 void *realloc_array(void *p, size_t el_size, unsigned int count, bool free_old_on_error)
1103 {
1104         if (count >= MAX_ALLOC_SIZE/el_size) {
1105                 if (free_old_on_error) {
1106                         SAFE_FREE(p);
1107                 }
1108                 return NULL;
1109         }
1110         return Realloc(p, el_size*count, free_old_on_error);
1111 }
1112
1113 /****************************************************************************
1114  (Hopefully) efficient array append.
1115 ****************************************************************************/
1116
1117 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1118                         void *element, void *_array, uint32 *num_elements,
1119                         ssize_t *array_size)
1120 {
1121         void **array = (void **)_array;
1122
1123         if (*array_size < 0) {
1124                 return;
1125         }
1126
1127         if (*array == NULL) {
1128                 if (*array_size == 0) {
1129                         *array_size = 128;
1130                 }
1131
1132                 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1133                         goto error;
1134                 }
1135
1136                 *array = TALLOC(mem_ctx, element_size * (*array_size));
1137                 if (*array == NULL) {
1138                         goto error;
1139                 }
1140         }
1141
1142         if (*num_elements == *array_size) {
1143                 *array_size *= 2;
1144
1145                 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1146                         goto error;
1147                 }
1148
1149                 *array = TALLOC_REALLOC(mem_ctx, *array,
1150                                         element_size * (*array_size));
1151
1152                 if (*array == NULL) {
1153                         goto error;
1154                 }
1155         }
1156
1157         memcpy((char *)(*array) + element_size*(*num_elements),
1158                element, element_size);
1159         *num_elements += 1;
1160
1161         return;
1162
1163  error:
1164         *num_elements = 0;
1165         *array_size = -1;
1166 }
1167
1168 /****************************************************************************
1169  Free memory, checks for NULL.
1170  Use directly SAFE_FREE()
1171  Exists only because we need to pass a function pointer somewhere --SSS
1172 ****************************************************************************/
1173
1174 void safe_free(void *p)
1175 {
1176         SAFE_FREE(p);
1177 }
1178
1179 /****************************************************************************
1180  Get my own name and IP.
1181 ****************************************************************************/
1182
1183 bool get_myname(char *my_name)
1184 {
1185         fstring hostname;
1186
1187         *hostname = 0;
1188
1189         /* get my host name */
1190         if (gethostname(hostname, sizeof(hostname)) == -1) {
1191                 DEBUG(0,("gethostname failed\n"));
1192                 return False;
1193         }
1194
1195         /* Ensure null termination. */
1196         hostname[sizeof(hostname)-1] = '\0';
1197
1198         if (my_name) {
1199                 /* split off any parts after an initial . */
1200                 char *p = strchr_m(hostname,'.');
1201
1202                 if (p)
1203                         *p = 0;
1204
1205                 fstrcpy(my_name,hostname);
1206         }
1207
1208         return(True);
1209 }
1210
1211 /****************************************************************************
1212  Get my own domain name, or "" if we have none.
1213 ****************************************************************************/
1214
1215 char *get_mydnsdomname(TALLOC_CTX *ctx)
1216 {
1217         const char *domname;
1218         char *p;
1219
1220         domname = get_mydnsfullname();
1221         if (!domname) {
1222                 return NULL;
1223         }
1224
1225         p = strchr_m(domname, '.');
1226         if (p) {
1227                 p++;
1228                 return talloc_strdup(ctx, p);
1229         } else {
1230                 return talloc_strdup(ctx, "");
1231         }
1232 }
1233
1234 /****************************************************************************
1235  Interpret a protocol description string, with a default.
1236 ****************************************************************************/
1237
1238 int interpret_protocol(const char *str,int def)
1239 {
1240         if (strequal(str,"NT1"))
1241                 return(PROTOCOL_NT1);
1242         if (strequal(str,"LANMAN2"))
1243                 return(PROTOCOL_LANMAN2);
1244         if (strequal(str,"LANMAN1"))
1245                 return(PROTOCOL_LANMAN1);
1246         if (strequal(str,"CORE"))
1247                 return(PROTOCOL_CORE);
1248         if (strequal(str,"COREPLUS"))
1249                 return(PROTOCOL_COREPLUS);
1250         if (strequal(str,"CORE+"))
1251                 return(PROTOCOL_COREPLUS);
1252   
1253         DEBUG(0,("Unrecognised protocol level %s\n",str));
1254   
1255         return(def);
1256 }
1257
1258
1259 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1260 /******************************************************************
1261  Remove any mount options such as -rsize=2048,wsize=2048 etc.
1262  Based on a fix from <Thomas.Hepper@icem.de>.
1263 *******************************************************************/
1264
1265 static void strip_mount_options( pstring *str)
1266 {
1267         if (**str == '-') { 
1268                 char *p = *str;
1269                 while(*p && !isspace(*p))
1270                         p++;
1271                 while(*p && isspace(*p))
1272                         p++;
1273                 if(*p) {
1274                         pstring tmp_str;
1275
1276                         pstrcpy(tmp_str, p);
1277                         pstrcpy(*str, tmp_str);
1278                 }
1279         }
1280 }
1281
1282 /*******************************************************************
1283  Patch from jkf@soton.ac.uk
1284  Split Luke's automount_server into YP lookup and string splitter
1285  so can easily implement automount_path(). 
1286  As we may end up doing both, cache the last YP result. 
1287 *******************************************************************/
1288
1289 #ifdef WITH_NISPLUS_HOME
1290 char *automount_lookup(const char *user_name)
1291 {
1292         static fstring last_key = "";
1293         static pstring last_value = "";
1294  
1295         char *nis_map = (char *)lp_nis_home_map_name();
1296  
1297         char buffer[NIS_MAXATTRVAL + 1];
1298         nis_result *result;
1299         nis_object *object;
1300         entry_obj  *entry;
1301  
1302         if (strcmp(user_name, last_key)) {
1303                 slprintf(buffer, sizeof(buffer)-1, "[key=%s],%s", user_name, nis_map);
1304                 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1305  
1306                 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1307                         if (result->status != NIS_SUCCESS) {
1308                                 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1309                                 fstrcpy(last_key, ""); pstrcpy(last_value, "");
1310                         } else {
1311                                 object = result->objects.objects_val;
1312                                 if (object->zo_data.zo_type == ENTRY_OBJ) {
1313                                         entry = &object->zo_data.objdata_u.en_data;
1314                                         DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1315                                         DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1316  
1317                                         pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1318                                         pstring_sub(last_value, "&", user_name);
1319                                         fstrcpy(last_key, user_name);
1320                                 }
1321                         }
1322                 }
1323                 nis_freeresult(result);
1324         }
1325
1326         strip_mount_options(&last_value);
1327
1328         DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
1329         return last_value;
1330 }
1331 #else /* WITH_NISPLUS_HOME */
1332
1333 char *automount_lookup(const char *user_name)
1334 {
1335         static fstring last_key = "";
1336         static pstring last_value = "";
1337
1338         int nis_error;        /* returned by yp all functions */
1339         char *nis_result;     /* yp_match inits this */
1340         int nis_result_len;  /* and set this */
1341         char *nis_domain;     /* yp_get_default_domain inits this */
1342         char *nis_map = (char *)lp_nis_home_map_name();
1343
1344         if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1345                 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1346                 return last_value;
1347         }
1348
1349         DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1350
1351         if (!strcmp(user_name, last_key)) {
1352                 nis_result = last_value;
1353                 nis_result_len = strlen(last_value);
1354                 nis_error = 0;
1355         } else {
1356                 if ((nis_error = yp_match(nis_domain, nis_map, user_name, strlen(user_name),
1357                                 &nis_result, &nis_result_len)) == 0) {
1358                         fstrcpy(last_key, user_name);
1359                         pstrcpy(last_value, nis_result);
1360                         strip_mount_options(&last_value);
1361
1362                 } else if(nis_error == YPERR_KEY) {
1363
1364                         /* If Key lookup fails user home server is not in nis_map 
1365                                 use default information for server, and home directory */
1366                         last_value[0] = 0;
1367                         DEBUG(3, ("YP Key not found:  while looking up \"%s\" in map \"%s\"\n", 
1368                                         user_name, nis_map));
1369                         DEBUG(3, ("using defaults for server and home directory\n"));
1370                 } else {
1371                         DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", 
1372                                         yperr_string(nis_error), user_name, nis_map));
1373                 }
1374         }
1375
1376         DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
1377         return last_value;
1378 }
1379 #endif /* WITH_NISPLUS_HOME */
1380 #endif
1381
1382 /****************************************************************************
1383  Check if a process exists. Does this work on all unixes?
1384 ****************************************************************************/
1385
1386 bool process_exists(const struct server_id pid)
1387 {
1388         if (procid_is_me(&pid)) {
1389                 return True;
1390         }
1391
1392         if (procid_is_local(&pid)) {
1393                 return (kill(pid.pid,0) == 0 || errno != ESRCH);
1394         }
1395
1396 #ifdef CLUSTER_SUPPORT
1397         return ctdbd_process_exists(messaging_ctdbd_connection(), pid.vnn,
1398                                     pid.pid);
1399 #else
1400         return False;
1401 #endif
1402 }
1403
1404 bool process_exists_by_pid(pid_t pid)
1405 {
1406         /* Doing kill with a non-positive pid causes messages to be
1407          * sent to places we don't want. */
1408         SMB_ASSERT(pid > 0);
1409         return(kill(pid,0) == 0 || errno != ESRCH);
1410 }
1411
1412 /*******************************************************************
1413  Convert a uid into a user name.
1414 ********************************************************************/
1415
1416 const char *uidtoname(uid_t uid)
1417 {
1418         TALLOC_CTX *ctx = talloc_tos();
1419         char *name = NULL;
1420         struct passwd *pass = NULL;
1421
1422         pass = getpwuid_alloc(ctx,uid);
1423         if (pass) {
1424                 name = talloc_strdup(ctx,pass->pw_name);
1425                 TALLOC_FREE(pass);
1426         } else {
1427                 name = talloc_asprintf(ctx,
1428                                 "%ld",
1429                                 (long int)uid);
1430         }
1431         return name;
1432 }
1433
1434 /*******************************************************************
1435  Convert a gid into a group name.
1436 ********************************************************************/
1437
1438 char *gidtoname(gid_t gid)
1439 {
1440         fstring name;
1441         struct group *grp;
1442
1443         grp = getgrgid(gid);
1444         if (grp) {
1445                 fstrcpy(name, grp->gr_name);
1446         }
1447         else {
1448                 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
1449         }
1450         return talloc_strdup(talloc_tos(), name);
1451 }
1452
1453 /*******************************************************************
1454  Convert a user name into a uid. 
1455 ********************************************************************/
1456
1457 uid_t nametouid(const char *name)
1458 {
1459         struct passwd *pass;
1460         char *p;
1461         uid_t u;
1462
1463         pass = getpwnam_alloc(NULL, name);
1464         if (pass) {
1465                 u = pass->pw_uid;
1466                 TALLOC_FREE(pass);
1467                 return u;
1468         }
1469
1470         u = (uid_t)strtol(name, &p, 0);
1471         if ((p != name) && (*p == '\0'))
1472                 return u;
1473
1474         return (uid_t)-1;
1475 }
1476
1477 /*******************************************************************
1478  Convert a name to a gid_t if possible. Return -1 if not a group. 
1479 ********************************************************************/
1480
1481 gid_t nametogid(const char *name)
1482 {
1483         struct group *grp;
1484         char *p;
1485         gid_t g;
1486
1487         g = (gid_t)strtol(name, &p, 0);
1488         if ((p != name) && (*p == '\0'))
1489                 return g;
1490
1491         grp = sys_getgrnam(name);
1492         if (grp)
1493                 return(grp->gr_gid);
1494         return (gid_t)-1;
1495 }
1496
1497 /*******************************************************************
1498  Something really nasty happened - panic !
1499 ********************************************************************/
1500
1501 void smb_panic(const char *const why)
1502 {
1503         char *cmd;
1504         int result;
1505
1506 #ifdef DEVELOPER
1507         {
1508
1509                 if (global_clobber_region_function) {
1510                         DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1511                                          global_clobber_region_function,
1512                                          global_clobber_region_line));
1513                 } 
1514         }
1515 #endif
1516
1517         DEBUG(0,("PANIC (pid %llu): %s\n",
1518                     (unsigned long long)sys_getpid(), why));
1519         log_stack_trace();
1520
1521         cmd = lp_panic_action();
1522         if (cmd && *cmd) {
1523                 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1524                 result = system(cmd);
1525
1526                 if (result == -1)
1527                         DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1528                                           strerror(errno)));
1529                 else
1530                         DEBUG(0, ("smb_panic(): action returned status %d\n",
1531                                           WEXITSTATUS(result)));
1532         }
1533
1534         dump_core();
1535 }
1536
1537 /*******************************************************************
1538  Print a backtrace of the stack to the debug log. This function
1539  DELIBERATELY LEAKS MEMORY. The expectation is that you should
1540  exit shortly after calling it.
1541 ********************************************************************/
1542
1543 #ifdef HAVE_LIBUNWIND_H
1544 #include <libunwind.h>
1545 #endif
1546
1547 #ifdef HAVE_EXECINFO_H
1548 #include <execinfo.h>
1549 #endif
1550
1551 #ifdef HAVE_LIBEXC_H
1552 #include <libexc.h>
1553 #endif
1554
1555 void log_stack_trace(void)
1556 {
1557 #ifdef HAVE_LIBUNWIND
1558         /* Try to use libunwind before any other technique since on ia64
1559          * libunwind correctly walks the stack in more circumstances than
1560          * backtrace.
1561          */ 
1562         unw_cursor_t cursor;
1563         unw_context_t uc;
1564         unsigned i = 0;
1565
1566         char procname[256];
1567         unw_word_t ip, sp, off;
1568
1569         procname[sizeof(procname) - 1] = '\0';
1570
1571         if (unw_getcontext(&uc) != 0) {
1572                 goto libunwind_failed;
1573         }
1574
1575         if (unw_init_local(&cursor, &uc) != 0) {
1576                 goto libunwind_failed;
1577         }
1578
1579         DEBUG(0, ("BACKTRACE:\n"));
1580
1581         do {
1582             ip = sp = 0;
1583             unw_get_reg(&cursor, UNW_REG_IP, &ip);
1584             unw_get_reg(&cursor, UNW_REG_SP, &sp);
1585
1586             switch (unw_get_proc_name(&cursor,
1587                         procname, sizeof(procname) - 1, &off) ) {
1588             case 0:
1589                     /* Name found. */
1590             case -UNW_ENOMEM:
1591                     /* Name truncated. */
1592                     DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1593                             i, procname, (long long)off,
1594                             (long long)ip, (long long) sp));
1595                     break;
1596             default:
1597             /* case -UNW_ENOINFO: */
1598             /* case -UNW_EUNSPEC: */
1599                     /* No symbol name found. */
1600                     DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1601                             i, "<unknown symbol>",
1602                             (long long)ip, (long long) sp));
1603             }
1604             ++i;
1605         } while (unw_step(&cursor) > 0);
1606
1607         return;
1608
1609 libunwind_failed:
1610         DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1611
1612 #elif HAVE_BACKTRACE_SYMBOLS
1613         void *backtrace_stack[BACKTRACE_STACK_SIZE];
1614         size_t backtrace_size;
1615         char **backtrace_strings;
1616
1617         /* get the backtrace (stack frames) */
1618         backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1619         backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1620
1621         DEBUG(0, ("BACKTRACE: %lu stack frames:\n", 
1622                   (unsigned long)backtrace_size));
1623         
1624         if (backtrace_strings) {
1625                 int i;
1626
1627                 for (i = 0; i < backtrace_size; i++)
1628                         DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1629
1630                 /* Leak the backtrace_strings, rather than risk what free() might do */
1631         }
1632
1633 #elif HAVE_LIBEXC
1634
1635         /* The IRIX libexc library provides an API for unwinding the stack. See
1636          * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1637          * since we are about to abort anyway, it hardly matters.
1638          */
1639
1640 #define NAMESIZE 32 /* Arbitrary */
1641
1642         __uint64_t      addrs[BACKTRACE_STACK_SIZE];
1643         char *          names[BACKTRACE_STACK_SIZE];
1644         char            namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1645
1646         int             i;
1647         int             levels;
1648
1649         ZERO_ARRAY(addrs);
1650         ZERO_ARRAY(names);
1651         ZERO_ARRAY(namebuf);
1652
1653         /* We need to be root so we can open our /proc entry to walk
1654          * our stack. It also helps when we want to dump core.
1655          */
1656         become_root();
1657
1658         for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1659                 names[i] = namebuf + (i * NAMESIZE);
1660         }
1661
1662         levels = trace_back_stack(0, addrs, names,
1663                         BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1664
1665         DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1666         for (i = 0; i < levels; i++) {
1667                 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1668         }
1669 #undef NAMESIZE
1670
1671 #else
1672         DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1673 #endif
1674 }
1675
1676 /*******************************************************************
1677   A readdir wrapper which just returns the file name.
1678  ********************************************************************/
1679
1680 const char *readdirname(SMB_STRUCT_DIR *p)
1681 {
1682         SMB_STRUCT_DIRENT *ptr;
1683         char *dname;
1684
1685         if (!p)
1686                 return(NULL);
1687   
1688         ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1689         if (!ptr)
1690                 return(NULL);
1691
1692         dname = ptr->d_name;
1693
1694 #ifdef NEXT2
1695         if (telldir(p) < 0)
1696                 return(NULL);
1697 #endif
1698
1699 #ifdef HAVE_BROKEN_READDIR_NAME
1700         /* using /usr/ucb/cc is BAD */
1701         dname = dname - 2;
1702 #endif
1703
1704         return talloc_strdup(talloc_tos(), dname);
1705 }
1706
1707 /*******************************************************************
1708  Utility function used to decide if the last component 
1709  of a path matches a (possibly wildcarded) entry in a namelist.
1710 ********************************************************************/
1711
1712 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1713 {
1714         const char *last_component;
1715
1716         /* if we have no list it's obviously not in the path */
1717         if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1718                 return False;
1719         }
1720
1721         DEBUG(8, ("is_in_path: %s\n", name));
1722
1723         /* Get the last component of the unix name. */
1724         last_component = strrchr_m(name, '/');
1725         if (!last_component) {
1726                 last_component = name;
1727         } else {
1728                 last_component++; /* Go past '/' */
1729         }
1730
1731         for(; namelist->name != NULL; namelist++) {
1732                 if(namelist->is_wild) {
1733                         if (mask_match(last_component, namelist->name, case_sensitive)) {
1734                                 DEBUG(8,("is_in_path: mask match succeeded\n"));
1735                                 return True;
1736                         }
1737                 } else {
1738                         if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1739                                                 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1740                                 DEBUG(8,("is_in_path: match succeeded\n"));
1741                                 return True;
1742                         }
1743                 }
1744         }
1745         DEBUG(8,("is_in_path: match not found\n"));
1746         return False;
1747 }
1748
1749 /*******************************************************************
1750  Strip a '/' separated list into an array of 
1751  name_compare_enties structures suitable for 
1752  passing to is_in_path(). We do this for
1753  speed so we can pre-parse all the names in the list 
1754  and don't do it for each call to is_in_path().
1755  namelist is modified here and is assumed to be 
1756  a copy owned by the caller.
1757  We also check if the entry contains a wildcard to
1758  remove a potentially expensive call to mask_match
1759  if possible.
1760 ********************************************************************/
1761  
1762 void set_namearray(name_compare_entry **ppname_array, char *namelist)
1763 {
1764         char *name_end;
1765         char *nameptr = namelist;
1766         int num_entries = 0;
1767         int i;
1768
1769         (*ppname_array) = NULL;
1770
1771         if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) 
1772                 return;
1773
1774         /* We need to make two passes over the string. The
1775                 first to count the number of elements, the second
1776                 to split it.
1777         */
1778
1779         while(*nameptr) {
1780                 if ( *nameptr == '/' ) {
1781                         /* cope with multiple (useless) /s) */
1782                         nameptr++;
1783                         continue;
1784                 }
1785                 /* find the next / */
1786                 name_end = strchr_m(nameptr, '/');
1787
1788                 /* oops - the last check for a / didn't find one. */
1789                 if (name_end == NULL)
1790                         break;
1791
1792                 /* next segment please */
1793                 nameptr = name_end + 1;
1794                 num_entries++;
1795         }
1796
1797         if(num_entries == 0)
1798                 return;
1799
1800         if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1801                 DEBUG(0,("set_namearray: malloc fail\n"));
1802                 return;
1803         }
1804
1805         /* Now copy out the names */
1806         nameptr = namelist;
1807         i = 0;
1808         while(*nameptr) {
1809                 if ( *nameptr == '/' ) {
1810                         /* cope with multiple (useless) /s) */
1811                         nameptr++;
1812                         continue;
1813                 }
1814                 /* find the next / */
1815                 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1816                         *name_end = 0;
1817
1818                 /* oops - the last check for a / didn't find one. */
1819                 if(name_end == NULL) 
1820                         break;
1821
1822                 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1823                 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1824                         DEBUG(0,("set_namearray: malloc fail (1)\n"));
1825                         return;
1826                 }
1827
1828                 /* next segment please */
1829                 nameptr = name_end + 1;
1830                 i++;
1831         }
1832   
1833         (*ppname_array)[i].name = NULL;
1834
1835         return;
1836 }
1837
1838 /****************************************************************************
1839  Routine to free a namearray.
1840 ****************************************************************************/
1841
1842 void free_namearray(name_compare_entry *name_array)
1843 {
1844         int i;
1845
1846         if(name_array == NULL)
1847                 return;
1848
1849         for(i=0; name_array[i].name!=NULL; i++)
1850                 SAFE_FREE(name_array[i].name);
1851         SAFE_FREE(name_array);
1852 }
1853
1854 #undef DBGC_CLASS
1855 #define DBGC_CLASS DBGC_LOCKING
1856
1857 /****************************************************************************
1858  Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
1859  is dealt with in posix.c
1860  Returns True if the lock was granted, False otherwise.
1861 ****************************************************************************/
1862
1863 bool fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
1864 {
1865         SMB_STRUCT_FLOCK lock;
1866         int ret;
1867
1868         DEBUG(8,("fcntl_lock fd=%d op=%d offset=%.0f count=%.0f type=%d\n",
1869                 fd,op,(double)offset,(double)count,type));
1870
1871         lock.l_type = type;
1872         lock.l_whence = SEEK_SET;
1873         lock.l_start = offset;
1874         lock.l_len = count;
1875         lock.l_pid = 0;
1876
1877         ret = sys_fcntl_ptr(fd,op,&lock);
1878
1879         if (ret == -1) {
1880                 int sav = errno;
1881                 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
1882                         (double)offset,(double)count,op,type,strerror(errno)));
1883                 errno = sav;
1884                 return False;
1885         }
1886
1887         /* everything went OK */
1888         DEBUG(8,("fcntl_lock: Lock call successful\n"));
1889
1890         return True;
1891 }
1892
1893 /****************************************************************************
1894  Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1895  is dealt with in posix.c
1896  Returns True if we have information regarding this lock region (and returns
1897  F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1898 ****************************************************************************/
1899
1900 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1901 {
1902         SMB_STRUCT_FLOCK lock;
1903         int ret;
1904
1905         DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1906                     fd,(double)*poffset,(double)*pcount,*ptype));
1907
1908         lock.l_type = *ptype;
1909         lock.l_whence = SEEK_SET;
1910         lock.l_start = *poffset;
1911         lock.l_len = *pcount;
1912         lock.l_pid = 0;
1913
1914         ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1915
1916         if (ret == -1) {
1917                 int sav = errno;
1918                 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1919                         (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1920                 errno = sav;
1921                 return False;
1922         }
1923
1924         *ptype = lock.l_type;
1925         *poffset = lock.l_start;
1926         *pcount = lock.l_len;
1927         *ppid = lock.l_pid;
1928         
1929         DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1930                         fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1931         return True;
1932 }
1933
1934 #undef DBGC_CLASS
1935 #define DBGC_CLASS DBGC_ALL
1936
1937 /*******************************************************************
1938  Is the name specified one of my netbios names.
1939  Returns true if it is equal, false otherwise.
1940 ********************************************************************/
1941
1942 bool is_myname(const char *s)
1943 {
1944         int n;
1945         bool ret = False;
1946
1947         for (n=0; my_netbios_names(n); n++) {
1948                 if (strequal(my_netbios_names(n), s)) {
1949                         ret=True;
1950                         break;
1951                 }
1952         }
1953         DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1954         return(ret);
1955 }
1956
1957 /*******************************************************************
1958  Is the name specified our workgroup/domain.
1959  Returns true if it is equal, false otherwise.
1960 ********************************************************************/
1961
1962 bool is_myworkgroup(const char *s)
1963 {
1964         bool ret = False;
1965
1966         if (strequal(s, lp_workgroup())) {
1967                 ret=True;
1968         }
1969
1970         DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1971         return(ret);
1972 }
1973
1974 /*******************************************************************
1975  we distinguish between 2K and XP by the "Native Lan Manager" string
1976    WinXP => "Windows 2002 5.1"
1977    WinXP 64bit => "Windows XP 5.2"
1978    Win2k => "Windows 2000 5.0"
1979    NT4   => "Windows NT 4.0"
1980    Win9x => "Windows 4.0"
1981  Windows 2003 doesn't set the native lan manager string but
1982  they do set the domain to "Windows 2003 5.2" (probably a bug).
1983 ********************************************************************/
1984
1985 void ra_lanman_string( const char *native_lanman )
1986 {
1987         if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1988                 set_remote_arch( RA_WINXP );
1989         else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1990                 set_remote_arch( RA_WINXP );
1991         else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1992                 set_remote_arch( RA_WIN2K3 );
1993 }
1994
1995 /*******************************************************************
1996  Set the horrid remote_arch string based on an enum.
1997 ********************************************************************/
1998
1999 void set_remote_arch(enum remote_arch_types type)
2000 {
2001         ra_type = type;
2002         switch( type ) {
2003         case RA_WFWG:
2004                 fstrcpy(remote_arch, "WfWg");
2005                 break;
2006         case RA_OS2:
2007                 fstrcpy(remote_arch, "OS2");
2008                 break;
2009         case RA_WIN95:
2010                 fstrcpy(remote_arch, "Win95");
2011                 break;
2012         case RA_WINNT:
2013                 fstrcpy(remote_arch, "WinNT");
2014                 break;
2015         case RA_WIN2K:
2016                 fstrcpy(remote_arch, "Win2K");
2017                 break;
2018         case RA_WINXP:
2019                 fstrcpy(remote_arch, "WinXP");
2020                 break;
2021         case RA_WIN2K3:
2022                 fstrcpy(remote_arch, "Win2K3");
2023                 break;
2024         case RA_VISTA:
2025                 fstrcpy(remote_arch, "Vista");
2026                 break;
2027         case RA_SAMBA:
2028                 fstrcpy(remote_arch,"Samba");
2029                 break;
2030         case RA_CIFSFS:
2031                 fstrcpy(remote_arch,"CIFSFS");
2032                 break;
2033         default:
2034                 ra_type = RA_UNKNOWN;
2035                 fstrcpy(remote_arch, "UNKNOWN");
2036                 break;
2037         }
2038
2039         DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n", remote_arch));
2040 }
2041
2042 /*******************************************************************
2043  Get the remote_arch type.
2044 ********************************************************************/
2045
2046 enum remote_arch_types get_remote_arch(void)
2047 {
2048         return ra_type;
2049 }
2050
2051 void print_asc(int level, const unsigned char *buf,int len)
2052 {
2053         int i;
2054         for (i=0;i<len;i++)
2055                 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2056 }
2057
2058 void dump_data(int level, const unsigned char *buf1,int len)
2059 {
2060         const unsigned char *buf = (const unsigned char *)buf1;
2061         int i=0;
2062         if (len<=0) return;
2063
2064         if (!DEBUGLVL(level)) return;
2065         
2066         DEBUGADD(level,("[%03X] ",i));
2067         for (i=0;i<len;) {
2068                 DEBUGADD(level,("%02X ",(int)buf[i]));
2069                 i++;
2070                 if (i%8 == 0) DEBUGADD(level,(" "));
2071                 if (i%16 == 0) {      
2072                         print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2073                         print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2074                         if (i<len) DEBUGADD(level,("[%03X] ",i));
2075                 }
2076         }
2077         if (i%16) {
2078                 int n;
2079                 n = 16 - (i%16);
2080                 DEBUGADD(level,(" "));
2081                 if (n>8) DEBUGADD(level,(" "));
2082                 while (n--) DEBUGADD(level,("   "));
2083                 n = MIN(8,i%16);
2084                 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2085                 n = (i%16) - n;
2086                 if (n>0) print_asc(level,&buf[i-n],n); 
2087                 DEBUGADD(level,("\n"));    
2088         }       
2089 }
2090
2091 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2092 {
2093 #ifdef DEBUG_PASSWORD
2094         DEBUG(11, ("%s", msg));
2095         if (data != NULL && len > 0)
2096         {
2097                 dump_data(11, data, len);
2098         }
2099 #endif
2100 }
2101
2102 char *tab_depth(int depth)
2103 {
2104         static pstring spaces;
2105         memset(spaces, ' ', depth * 4);
2106         spaces[depth * 4] = 0;
2107         return spaces;
2108 }
2109
2110 /*****************************************************************************
2111  Provide a checksum on a string
2112
2113  Input:  s - the null-terminated character string for which the checksum
2114              will be calculated.
2115
2116   Output: The checksum value calculated for s.
2117 *****************************************************************************/
2118
2119 int str_checksum(const char *s)
2120 {
2121         int res = 0;
2122         int c;
2123         int i=0;
2124         
2125         while(*s) {
2126                 c = *s;
2127                 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2128                 s++;
2129                 i++;
2130         }
2131         return(res);
2132 }
2133
2134 /*****************************************************************
2135  Zero a memory area then free it. Used to catch bugs faster.
2136 *****************************************************************/  
2137
2138 void zero_free(void *p, size_t size)
2139 {
2140         memset(p, 0, size);
2141         SAFE_FREE(p);
2142 }
2143
2144 /*****************************************************************
2145  Set our open file limit to a requested max and return the limit.
2146 *****************************************************************/  
2147
2148 int set_maxfiles(int requested_max)
2149 {
2150 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2151         struct rlimit rlp;
2152         int saved_current_limit;
2153
2154         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2155                 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2156                         strerror(errno) ));
2157                 /* just guess... */
2158                 return requested_max;
2159         }
2160
2161         /* 
2162          * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2163          * account for the extra fd we need 
2164          * as well as the log files and standard
2165          * handles etc. Save the limit we want to set in case
2166          * we are running on an OS that doesn't support this limit (AIX)
2167          * which always returns RLIM_INFINITY for rlp.rlim_max.
2168          */
2169
2170         /* Try raising the hard (max) limit to the requested amount. */
2171
2172 #if defined(RLIM_INFINITY)
2173         if (rlp.rlim_max != RLIM_INFINITY) {
2174                 int orig_max = rlp.rlim_max;
2175
2176                 if ( rlp.rlim_max < requested_max )
2177                         rlp.rlim_max = requested_max;
2178
2179                 /* This failing is not an error - many systems (Linux) don't
2180                         support our default request of 10,000 open files. JRA. */
2181
2182                 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2183                         DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n", 
2184                                 (int)rlp.rlim_max, strerror(errno) ));
2185
2186                         /* Set failed - restore original value from get. */
2187                         rlp.rlim_max = orig_max;
2188                 }
2189         }
2190 #endif
2191
2192         /* Now try setting the soft (current) limit. */
2193
2194         saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2195
2196         if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2197                 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n", 
2198                         (int)rlp.rlim_cur, strerror(errno) ));
2199                 /* just guess... */
2200                 return saved_current_limit;
2201         }
2202
2203         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2204                 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2205                         strerror(errno) ));
2206                 /* just guess... */
2207                 return saved_current_limit;
2208     }
2209
2210 #if defined(RLIM_INFINITY)
2211         if(rlp.rlim_cur == RLIM_INFINITY)
2212                 return saved_current_limit;
2213 #endif
2214
2215         if((int)rlp.rlim_cur > saved_current_limit)
2216                 return saved_current_limit;
2217
2218         return rlp.rlim_cur;
2219 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2220         /*
2221          * No way to know - just guess...
2222          */
2223         return requested_max;
2224 #endif
2225 }
2226
2227 /*****************************************************************
2228  Possibly replace mkstemp if it is broken.
2229 *****************************************************************/  
2230
2231 int smb_mkstemp(char *name_template)
2232 {
2233 #if HAVE_SECURE_MKSTEMP
2234         return mkstemp(name_template);
2235 #else
2236         /* have a reasonable go at emulating it. Hope that
2237            the system mktemp() isn't completly hopeless */
2238         char *p = mktemp(name_template);
2239         if (!p)
2240                 return -1;
2241         return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2242 #endif
2243 }
2244
2245 /*****************************************************************
2246  malloc that aborts with smb_panic on fail or zero size.
2247  *****************************************************************/  
2248
2249 void *smb_xmalloc_array(size_t size, unsigned int count)
2250 {
2251         void *p;
2252         if (size == 0) {
2253                 smb_panic("smb_xmalloc_array: called with zero size");
2254         }
2255         if (count >= MAX_ALLOC_SIZE/size) {
2256                 smb_panic("smb_xmalloc_array: alloc size too large");
2257         }
2258         if ((p = SMB_MALLOC(size*count)) == NULL) {
2259                 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2260                         (unsigned long)size, (unsigned long)count));
2261                 smb_panic("smb_xmalloc_array: malloc failed");
2262         }
2263         return p;
2264 }
2265
2266 /**
2267  Memdup with smb_panic on fail.
2268 **/
2269
2270 void *smb_xmemdup(const void *p, size_t size)
2271 {
2272         void *p2;
2273         p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2274         memcpy(p2, p, size);
2275         return p2;
2276 }
2277
2278 /**
2279  strdup that aborts on malloc fail.
2280 **/
2281
2282 char *smb_xstrdup(const char *s)
2283 {
2284 #if defined(PARANOID_MALLOC_CHECKER)
2285 #ifdef strdup
2286 #undef strdup
2287 #endif
2288 #endif
2289
2290 #ifndef HAVE_STRDUP
2291 #define strdup rep_strdup
2292 #endif
2293
2294         char *s1 = strdup(s);
2295 #if defined(PARANOID_MALLOC_CHECKER)
2296 #ifdef strdup
2297 #undef strdup
2298 #endif
2299 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2300 #endif
2301         if (!s1) {
2302                 smb_panic("smb_xstrdup: malloc failed");
2303         }
2304         return s1;
2305
2306 }
2307
2308 /**
2309  strndup that aborts on malloc fail.
2310 **/
2311
2312 char *smb_xstrndup(const char *s, size_t n)
2313 {
2314 #if defined(PARANOID_MALLOC_CHECKER)
2315 #ifdef strndup
2316 #undef strndup
2317 #endif
2318 #endif
2319
2320 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
2321 #undef HAVE_STRNDUP
2322 #define strndup rep_strndup
2323 #endif
2324
2325         char *s1 = strndup(s, n);
2326 #if defined(PARANOID_MALLOC_CHECKER)
2327 #ifdef strndup
2328 #undef strndup
2329 #endif
2330 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2331 #endif
2332         if (!s1) {
2333                 smb_panic("smb_xstrndup: malloc failed");
2334         }
2335         return s1;
2336 }
2337
2338 /*
2339   vasprintf that aborts on malloc fail
2340 */
2341
2342  int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2343 {
2344         int n;
2345         va_list ap2;
2346
2347         VA_COPY(ap2, ap);
2348
2349         n = vasprintf(ptr, format, ap2);
2350         if (n == -1 || ! *ptr) {
2351                 smb_panic("smb_xvasprintf: out of memory");
2352         }
2353         return n;
2354 }
2355
2356 /*****************************************************************
2357  Like strdup but for memory.
2358 *****************************************************************/  
2359
2360 void *memdup(const void *p, size_t size)
2361 {
2362         void *p2;
2363         if (size == 0)
2364                 return NULL;
2365         p2 = SMB_MALLOC(size);
2366         if (!p2)
2367                 return NULL;
2368         memcpy(p2, p, size);
2369         return p2;
2370 }
2371
2372 /*****************************************************************
2373  Get local hostname and cache result.
2374 *****************************************************************/  
2375
2376 char *myhostname(void)
2377 {
2378         static pstring ret;
2379         if (ret[0] == 0)
2380                 get_myname(ret);
2381         return ret;
2382 }
2383
2384 /*****************************************************************
2385  A useful function for returning a path in the Samba lock directory.
2386 *****************************************************************/  
2387
2388 char *lock_path(const char *name)
2389 {
2390         pstring fname;
2391
2392         pstrcpy(fname,lp_lockdir());
2393         trim_char(fname,'\0','/');
2394         
2395         if (!directory_exist(fname,NULL))
2396                 mkdir(fname,0755);
2397         
2398         pstrcat(fname,"/");
2399         pstrcat(fname,name);
2400
2401         return talloc_strdup(talloc_tos(), fname);
2402 }
2403
2404 /*****************************************************************
2405  A useful function for returning a path in the Samba pid directory.
2406 *****************************************************************/
2407
2408 char *pid_path(const char *name)
2409 {
2410         pstring fname;
2411
2412         pstrcpy(fname,lp_piddir());
2413         trim_char(fname,'\0','/');
2414
2415         if (!directory_exist(fname,NULL))
2416                 mkdir(fname,0755);
2417
2418         pstrcat(fname,"/");
2419         pstrcat(fname,name);
2420
2421         return talloc_strdup(talloc_tos(), fname);
2422 }
2423
2424 /**
2425  * @brief Returns an absolute path to a file in the Samba lib directory.
2426  *
2427  * @param name File to find, relative to LIBDIR.
2428  *
2429  * @retval Pointer to a static #pstring containing the full path.
2430  **/
2431
2432 char *lib_path(const char *name)
2433 {
2434         return talloc_asprintf(talloc_tos(), "%s/%s", dyn_LIBDIR, name);
2435 }
2436
2437 /**
2438  * @brief Returns an absolute path to a file in the Samba data directory.
2439  *
2440  * @param name File to find, relative to CODEPAGEDIR.
2441  *
2442  * @retval Pointer to a talloc'ed string containing the full path.
2443  **/
2444
2445 char *data_path(const char *name)
2446 {
2447         return talloc_asprintf(talloc_tos(), "%s/%s", dyn_CODEPAGEDIR, name);
2448 }
2449
2450 /*****************************************************************
2451 a useful function for returning a path in the Samba state directory
2452  *****************************************************************/
2453
2454 char *state_path(const char *name)
2455 {
2456         TALLOC_CTX *ctx = talloc_tos();
2457         char *fname = talloc_strdup(ctx, dyn_STATEDIR());
2458
2459         if (!fname) {
2460                 smb_panic("state_path: out of memory");
2461         }
2462         trim_string(fname,"","/");
2463
2464         if (!directory_exist(fname,NULL)) {
2465                 mkdir(fname,0755);
2466         }
2467
2468         fname = talloc_asprintf(ctx, "%s/%s",
2469                         fname, name);
2470
2471         return fname;
2472 }
2473
2474 /**
2475  * @brief Returns the platform specific shared library extension.
2476  *
2477  * @retval Pointer to a static #fstring containing the extension.
2478  **/
2479
2480 const char *shlib_ext(void)
2481 {
2482   return dyn_SHLIBEXT;
2483 }
2484
2485 /*******************************************************************
2486  Given a filename - get its directory name
2487  NB: Returned in static storage.  Caveats:
2488  o  If caller wishes to preserve, they should copy.
2489 ********************************************************************/
2490
2491 char *parent_dirname(const char *path)
2492 {
2493         char *parent;
2494
2495         if (!parent_dirname_talloc(talloc_tos(), path, &parent, NULL)) {
2496                 return NULL;
2497         }
2498
2499         return parent;
2500 }
2501
2502 bool parent_dirname_talloc(TALLOC_CTX *mem_ctx, const char *dir,
2503                            char **parent, const char **name)
2504 {
2505         char *p;
2506         ptrdiff_t len;
2507  
2508         p = strrchr_m(dir, '/'); /* Find final '/', if any */
2509
2510         if (p == NULL) {
2511                 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2512                         return False;
2513                 }
2514                 if (name) {
2515                         *name = "";
2516                 }
2517                 return True;
2518         }
2519
2520         len = p-dir;
2521
2522         if (!(*parent = TALLOC_ARRAY(mem_ctx, char, len+1))) {
2523                 return False;
2524         }
2525         memcpy(*parent, dir, len);
2526         (*parent)[len] = '\0';
2527
2528         if (name) {
2529                 *name = p+1;
2530         }
2531         return True;
2532 }
2533
2534 /*******************************************************************
2535  Determine if a pattern contains any Microsoft wildcard characters.
2536 *******************************************************************/
2537
2538 bool ms_has_wild(const char *s)
2539 {
2540         char c;
2541
2542         if (lp_posix_pathnames()) {
2543                 /* With posix pathnames no characters are wild. */
2544                 return False;
2545         }
2546
2547         while ((c = *s++)) {
2548                 switch (c) {
2549                 case '*':
2550                 case '?':
2551                 case '<':
2552                 case '>':
2553                 case '"':
2554                         return True;
2555                 }
2556         }
2557         return False;
2558 }
2559
2560 bool ms_has_wild_w(const smb_ucs2_t *s)
2561 {
2562         smb_ucs2_t c;
2563         if (!s) return False;
2564         while ((c = *s++)) {
2565                 switch (c) {
2566                 case UCS2_CHAR('*'):
2567                 case UCS2_CHAR('?'):
2568                 case UCS2_CHAR('<'):
2569                 case UCS2_CHAR('>'):
2570                 case UCS2_CHAR('"'):
2571                         return True;
2572                 }
2573         }
2574         return False;
2575 }
2576
2577 /*******************************************************************
2578  A wrapper that handles case sensitivity and the special handling
2579  of the ".." name.
2580 *******************************************************************/
2581
2582 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
2583 {
2584         if (strcmp(string,"..") == 0)
2585                 string = ".";
2586         if (strcmp(pattern,".") == 0)
2587                 return False;
2588         
2589         return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2590 }
2591
2592 /*******************************************************************
2593  A wrapper that handles case sensitivity and the special handling
2594  of the ".." name. Varient that is only called by old search code which requires
2595  pattern translation.
2596 *******************************************************************/
2597
2598 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
2599 {
2600         if (strcmp(string,"..") == 0)
2601                 string = ".";
2602         if (strcmp(pattern,".") == 0)
2603                 return False;
2604         
2605         return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2606 }
2607
2608 /*******************************************************************
2609  A wrapper that handles a list of patters and calls mask_match()
2610  on each.  Returns True if any of the patterns match.
2611 *******************************************************************/
2612
2613 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
2614 {
2615        while (listLen-- > 0) {
2616                if (mask_match(string, *list++, is_case_sensitive))
2617                        return True;
2618        }
2619        return False;
2620 }
2621
2622 /*********************************************************
2623  Recursive routine that is called by unix_wild_match.
2624 *********************************************************/
2625
2626 static bool unix_do_match(const char *regexp, const char *str)
2627 {
2628         const char *p;
2629
2630         for( p = regexp; *p && *str; ) {
2631
2632                 switch(*p) {
2633                         case '?':
2634                                 str++;
2635                                 p++;
2636                                 break;
2637
2638                         case '*':
2639
2640                                 /*
2641                                  * Look for a character matching 
2642                                  * the one after the '*'.
2643                                  */
2644                                 p++;
2645                                 if(!*p)
2646                                         return true; /* Automatic match */
2647                                 while(*str) {
2648
2649                                         while(*str && (*p != *str))
2650                                                 str++;
2651
2652                                         /*
2653                                          * Patch from weidel@multichart.de. In the case of the regexp
2654                                          * '*XX*' we want to ensure there are at least 2 'X' characters
2655                                          * in the string after the '*' for a match to be made.
2656                                          */
2657
2658                                         {
2659                                                 int matchcount=0;
2660
2661                                                 /*
2662                                                  * Eat all the characters that match, but count how many there were.
2663                                                  */
2664
2665                                                 while(*str && (*p == *str)) {
2666                                                         str++;
2667                                                         matchcount++;
2668                                                 }
2669
2670                                                 /*
2671                                                  * Now check that if the regexp had n identical characters that
2672                                                  * matchcount had at least that many matches.
2673                                                  */
2674
2675                                                 while ( *(p+1) && (*(p+1) == *p)) {
2676                                                         p++;
2677                                                         matchcount--;
2678                                                 }
2679
2680                                                 if ( matchcount <= 0 )
2681                                                         return false;
2682                                         }
2683
2684                                         str--; /* We've eaten the match char after the '*' */
2685
2686                                         if(unix_do_match(p, str))
2687                                                 return true;
2688
2689                                         if(!*str)
2690                                                 return false;
2691                                         else
2692                                                 str++;
2693                                 }
2694                                 return false;
2695
2696                         default:
2697                                 if(*str != *p)
2698                                         return false;
2699                                 str++;
2700                                 p++;
2701                                 break;
2702                 }
2703         }
2704
2705         if(!*p && !*str)
2706                 return true;
2707
2708         if (!*p && str[0] == '.' && str[1] == 0)
2709                 return true;
2710
2711         if (!*str && *p == '?') {
2712                 while (*p == '?')
2713                         p++;
2714                 return(!*p);
2715         }
2716
2717         if(!*str && (*p == '*' && p[1] == '\0'))
2718                 return true;
2719
2720         return false;
2721 }
2722
2723 /*******************************************************************
2724  Simple case insensitive interface to a UNIX wildcard matcher.
2725  Returns True if match, False if not.
2726 *******************************************************************/
2727
2728 bool unix_wild_match(const char *pattern, const char *string)
2729 {
2730         TALLOC_CTX *ctx = talloc_stackframe();
2731         char *p2;
2732         char *s2;
2733         char *p;
2734         bool ret = false;
2735
2736         p2 = talloc_strdup(ctx,pattern);
2737         s2 = talloc_strdup(ctx,string);
2738         if (!p2 || !s2) {
2739                 TALLOC_FREE(ctx);
2740                 return false;
2741         }
2742         strlower_m(p2);
2743         strlower_m(s2);
2744
2745         /* Remove any *? and ** from the pattern as they are meaningless */
2746         for(p = p2; *p; p++) {
2747                 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
2748                         memmove(&p[1], &p[2], strlen(&p[2])+1);
2749                 }
2750         }
2751
2752         if (strequal(p2,"*")) {
2753                 TALLOC_FREE(ctx);
2754                 return true;
2755         }
2756
2757         ret = unix_do_match(p2, s2);
2758         TALLOC_FREE(ctx);
2759         return ret;
2760 }
2761
2762 /**********************************************************************
2763  Converts a name to a fully qualified domain name.
2764  Returns true if lookup succeeded, false if not (then fqdn is set to name)
2765  Note we deliberately use gethostbyname here, not getaddrinfo as we want
2766  to examine the h_aliases and I don't know how to do that with getaddrinfo.
2767 ***********************************************************************/
2768
2769 bool name_to_fqdn(fstring fqdn, const char *name)
2770 {
2771         char *full = NULL;
2772         struct hostent *hp = gethostbyname(name);
2773
2774         if (!hp || !hp->h_name || !*hp->h_name) {
2775                 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2776                 fstrcpy(fqdn, name);
2777                 return false;
2778         }
2779
2780         /* Find out if the fqdn is returned as an alias
2781          * to cope with /etc/hosts files where the first
2782          * name is not the fqdn but the short name */
2783         if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2784                 int i;
2785                 for (i = 0; hp->h_aliases[i]; i++) {
2786                         if (strchr_m(hp->h_aliases[i], '.')) {
2787                                 full = hp->h_aliases[i];
2788                                 break;
2789                         }
2790                 }
2791         }
2792         if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2793                 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2794                 DEBUGADD(1, ("    Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2795                 DEBUGADD(1, ("    to Kerberos authentication problems as localhost.localdomain\n"));
2796                 DEBUGADD(1, ("    may end up being used instead of the real machine FQDN.\n"));
2797                 full = hp->h_name;
2798         }
2799         if (!full) {
2800                 full = hp->h_name;
2801         }
2802
2803         DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2804         fstrcpy(fqdn, full);
2805         return true;
2806 }
2807
2808 /**********************************************************************
2809  Extension to talloc_get_type: Abort on type mismatch
2810 ***********************************************************************/
2811
2812 void *talloc_check_name_abort(const void *ptr, const char *name)
2813 {
2814         void *result;
2815
2816         result = talloc_check_name(ptr, name);
2817         if (result != NULL)
2818                 return result;
2819
2820         DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2821                   name, talloc_get_name(ptr)));
2822         smb_panic("talloc type mismatch");
2823         /* Keep the compiler happy */
2824         return NULL;
2825 }
2826
2827
2828 #ifdef __INSURE__
2829
2830 /*******************************************************************
2831 This routine is a trick to immediately catch errors when debugging
2832 with insure. A xterm with a gdb is popped up when insure catches
2833 a error. It is Linux specific.
2834 ********************************************************************/
2835
2836 int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
2837 {
2838         static int (*fn)();
2839         int ret;
2840         char pidstr[10];
2841         /* you can get /usr/bin/backtrace from 
2842            http://samba.org/ftp/unpacked/junkcode/backtrace */
2843         pstring cmd = "/usr/bin/backtrace %d";
2844
2845         slprintf(pidstr, sizeof(pidstr)-1, "%d", sys_getpid());
2846         pstring_sub(cmd, "%d", pidstr);
2847
2848         if (!fn) {
2849                 static void *h;
2850                 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
2851                 fn = dlsym(h, "_Insure_trap_error");
2852
2853                 if (!h || h == _Insure_trap_error) {
2854                         h = dlopen("/usr/local/parasoft/lib.linux2/libinsure.so", RTLD_LAZY);
2855                         fn = dlsym(h, "_Insure_trap_error");
2856                 }               
2857         }
2858
2859         ret = fn(a1, a2, a3, a4, a5, a6);
2860
2861         system(cmd);
2862
2863         return ret;
2864 }
2865 #endif
2866
2867 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2868 {
2869         switch (share_access & ~FILE_SHARE_DELETE) {
2870                 case FILE_SHARE_NONE:
2871                         return DENY_ALL;
2872                 case FILE_SHARE_READ:
2873                         return DENY_WRITE;
2874                 case FILE_SHARE_WRITE:
2875                         return DENY_READ;
2876                 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2877                         return DENY_NONE;
2878         }
2879         if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2880                 return DENY_DOS;
2881         } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2882                 return DENY_FCB;
2883         }
2884
2885         return (uint32)-1;
2886 }
2887
2888 pid_t procid_to_pid(const struct server_id *proc)
2889 {
2890         return proc->pid;
2891 }
2892
2893 static uint32 my_vnn = NONCLUSTER_VNN;
2894
2895 void set_my_vnn(uint32 vnn)
2896 {
2897         DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
2898         my_vnn = vnn;
2899 }
2900
2901 uint32 get_my_vnn(void)
2902 {
2903         return my_vnn;
2904 }
2905
2906 struct server_id pid_to_procid(pid_t pid)
2907 {
2908         struct server_id result;
2909         result.pid = pid;
2910 #ifdef CLUSTER_SUPPORT
2911         result.vnn = my_vnn;
2912 #endif
2913         return result;
2914 }
2915
2916 struct server_id procid_self(void)
2917 {
2918         return pid_to_procid(sys_getpid());
2919 }
2920
2921 struct server_id server_id_self(void)
2922 {
2923         return procid_self();
2924 }
2925
2926 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
2927 {
2928         if (p1->pid != p2->pid)
2929                 return False;
2930 #ifdef CLUSTER_SUPPORT
2931         if (p1->vnn != p2->vnn)
2932                 return False;
2933 #endif
2934         return True;
2935 }
2936
2937 bool cluster_id_equal(const struct server_id *id1,
2938                       const struct server_id *id2)
2939 {
2940         return procid_equal(id1, id2);
2941 }
2942
2943 bool procid_is_me(const struct server_id *pid)
2944 {
2945         if (pid->pid != sys_getpid())
2946                 return False;
2947 #ifdef CLUSTER_SUPPORT
2948         if (pid->vnn != my_vnn)
2949                 return False;
2950 #endif
2951         return True;
2952 }
2953
2954 struct server_id interpret_pid(const char *pid_string)
2955 {
2956 #ifdef CLUSTER_SUPPORT
2957         unsigned int vnn, pid;
2958         struct server_id result;
2959         if (sscanf(pid_string, "%u:%u", &vnn, &pid) == 2) {
2960                 result.vnn = vnn;
2961                 result.pid = pid;
2962         }
2963         else if (sscanf(pid_string, "%u", &pid) == 1) {
2964                 result.vnn = NONCLUSTER_VNN;
2965                 result.pid = pid;
2966         }
2967         else {
2968                 result.vnn = NONCLUSTER_VNN;
2969                 result.pid = -1;
2970         }
2971         return result;
2972 #else
2973         return pid_to_procid(atoi(pid_string));
2974 #endif
2975 }
2976
2977 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
2978 {
2979         fstring str;
2980 #ifdef CLUSTER_SUPPORT
2981         if (pid->vnn == NONCLUSTER_VNN) {
2982                 fstr_sprintf(str, "%d", (int)pid->pid);
2983         }
2984         else {
2985                 fstr_sprintf(str, "%u:%d", (unsigned)pid->vnn, (int)pid->pid);
2986         }
2987 #else
2988         fstr_sprintf(str, "%d", (int)pid->pid);
2989 #endif
2990         return talloc_strdup(mem_ctx, str);
2991 }
2992
2993 char *procid_str_static(const struct server_id *pid)
2994 {
2995         return procid_str(talloc_tos(), pid);
2996 }
2997
2998 bool procid_valid(const struct server_id *pid)
2999 {
3000         return (pid->pid != -1);
3001 }
3002
3003 bool procid_is_local(const struct server_id *pid)
3004 {
3005 #ifdef CLUSTER_SUPPORT
3006         return pid->vnn == my_vnn;
3007 #else
3008         return True;
3009 #endif
3010 }
3011
3012 int this_is_smp(void)
3013 {
3014 #if defined(HAVE_SYSCONF)
3015
3016 #if defined(SYSCONF_SC_NPROC_ONLN)
3017         return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
3018 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3019         return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
3020 #else
3021         return 0;
3022 #endif
3023
3024 #else
3025         return 0;
3026 #endif
3027 }
3028
3029 /****************************************************************
3030  Check if an offset into a buffer is safe.
3031  If this returns True it's safe to indirect into the byte at
3032  pointer ptr+off.
3033 ****************************************************************/
3034
3035 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3036 {
3037         const char *end_base = buf_base + buf_len;
3038         char *end_ptr = ptr + off;
3039
3040         if (!buf_base || !ptr) {
3041                 return False;
3042         }
3043
3044         if (end_base < buf_base || end_ptr < ptr) {
3045                 return False; /* wrap. */
3046         }
3047
3048         if (end_ptr < end_base) {
3049                 return True;
3050         }
3051         return False;
3052 }
3053
3054 /****************************************************************
3055  Return a safe pointer into a buffer, or NULL.
3056 ****************************************************************/
3057
3058 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3059 {
3060         return is_offset_safe(buf_base, buf_len, ptr, off) ?
3061                         ptr + off : NULL;
3062 }
3063
3064 /****************************************************************
3065  Return a safe pointer into a string within a buffer, or NULL.
3066 ****************************************************************/
3067
3068 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3069 {
3070         if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
3071                 return NULL;
3072         }
3073         /* Check if a valid string exists at this offset. */
3074         if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
3075                 return NULL;
3076         }
3077         return ptr + off;
3078 }
3079
3080 /****************************************************************
3081  Return an SVAL at a pointer, or failval if beyond the end.
3082 ****************************************************************/
3083
3084 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3085 {
3086         /*
3087          * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
3088          * NOT ptr[2].
3089          */
3090         if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
3091                 return failval;
3092         }
3093         return SVAL(ptr,off);
3094 }
3095
3096 /****************************************************************
3097  Return an IVAL at a pointer, or failval if beyond the end.
3098 ****************************************************************/
3099
3100 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3101 {
3102         /*
3103          * Note we use off+3 here, not off+4 as IVAL accesses 
3104          * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
3105          */
3106         if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
3107                 return failval;
3108         }
3109         return IVAL(ptr,off);
3110 }
3111
3112 #if 0
3113
3114 Disable these now we have checked all code paths and ensured
3115 NULL returns on zero request. JRA.
3116
3117 /****************************************************************
3118  talloc wrapper functions that guarentee a null pointer return
3119  if size == 0.
3120 ****************************************************************/
3121
3122 #ifndef MAX_TALLOC_SIZE
3123 #define MAX_TALLOC_SIZE 0x10000000
3124 #endif
3125
3126 /*
3127  *    talloc and zero memory.
3128  *    - returns NULL if size is zero.
3129  */
3130
3131 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
3132 {
3133         void *p;
3134
3135         if (size == 0) {
3136                 return NULL;
3137         }
3138
3139         p = talloc_named_const(ctx, size, name);
3140
3141         if (p) {
3142                 memset(p, '\0', size);
3143         }
3144
3145         return p;
3146 }
3147
3148 /*
3149  *   memdup with a talloc.
3150  *   - returns NULL if size is zero.
3151  */
3152
3153 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
3154 {
3155         void *newp;
3156
3157         if (size == 0) {
3158                 return NULL;
3159         }
3160
3161         newp = talloc_named_const(t, size, name);
3162         if (newp) {
3163                 memcpy(newp, p, size);
3164         }
3165
3166         return newp;
3167 }
3168
3169 /*
3170  *   alloc an array, checking for integer overflow in the array size.
3171  *   - returns NULL if count or el_size are zero.
3172  */
3173
3174 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3175 {
3176         if (count >= MAX_TALLOC_SIZE/el_size) {
3177                 return NULL;
3178         }
3179
3180         if (el_size == 0 || count == 0) {
3181                 return NULL;
3182         }
3183
3184         return talloc_named_const(ctx, el_size * count, name);
3185 }
3186
3187 /*
3188  *   alloc an zero array, checking for integer overflow in the array size
3189  *   - returns NULL if count or el_size are zero.
3190  */
3191
3192 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3193 {
3194         if (count >= MAX_TALLOC_SIZE/el_size) {
3195                 return NULL;
3196         }
3197
3198         if (el_size == 0 || count == 0) {
3199                 return NULL;
3200         }
3201
3202         return _talloc_zero(ctx, el_size * count, name);
3203 }
3204
3205 /*
3206  *   Talloc wrapper that returns NULL if size == 0.
3207  */
3208 void *talloc_zeronull(const void *context, size_t size, const char *name)
3209 {
3210         if (size == 0) {
3211                 return NULL;
3212         }
3213         return talloc_named_const(context, size, name);
3214 }
3215 #endif