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