r25117: The mega-patch Jerry was waiting for. Remove all pstrings from
[tprouty/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         fstring attrstr;
460
461         attrstr[0] = 0;
462
463         if (mode & aVOLID) fstrcat(attrstr,"V");
464         if (mode & aDIR) fstrcat(attrstr,"D");
465         if (mode & aARCH) fstrcat(attrstr,"A");
466         if (mode & aHIDDEN) fstrcat(attrstr,"H");
467         if (mode & aSYSTEM) fstrcat(attrstr,"S");
468         if (mode & aRONLY) fstrcat(attrstr,"R");          
469
470         return talloc_strdup(talloc_tos(), attrstr);
471 }
472
473 /*******************************************************************
474  Show a smb message structure.
475 ********************************************************************/
476
477 void show_msg(char *buf)
478 {
479         int i;
480         int bcc=0;
481
482         if (!DEBUGLVL(5))
483                 return;
484         
485         DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
486                         smb_len(buf),
487                         (int)CVAL(buf,smb_com),
488                         (int)CVAL(buf,smb_rcls),
489                         (int)CVAL(buf,smb_reh),
490                         (int)SVAL(buf,smb_err),
491                         (int)CVAL(buf,smb_flg),
492                         (int)SVAL(buf,smb_flg2)));
493         DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
494                         (int)SVAL(buf,smb_tid),
495                         (int)SVAL(buf,smb_pid),
496                         (int)SVAL(buf,smb_uid),
497                         (int)SVAL(buf,smb_mid)));
498         DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
499
500         for (i=0;i<(int)CVAL(buf,smb_wct);i++)
501                 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
502                         SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
503         
504         bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
505
506         DEBUGADD(5,("smb_bcc=%d\n",bcc));
507
508         if (DEBUGLEVEL < 10)
509                 return;
510
511         if (DEBUGLEVEL < 50)
512                 bcc = MIN(bcc, 512);
513
514         dump_data(10, (uint8 *)smb_buf(buf), bcc);      
515 }
516
517 /*******************************************************************
518  Set the length and marker of an 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         TALLOC_CTX *ctx = talloc_tos();
1582         char *name = NULL;
1583         struct passwd *pass = NULL;
1584
1585         pass = getpwuid_alloc(ctx,uid);
1586         if (pass) {
1587                 name = talloc_strdup(ctx,pass->pw_name);
1588                 TALLOC_FREE(pass);
1589         } else {
1590                 name = talloc_asprintf(ctx,
1591                                 "%ld",
1592                                 (long int)uid);
1593         }
1594         return name;
1595 }
1596
1597 /*******************************************************************
1598  Convert a gid into a group name.
1599 ********************************************************************/
1600
1601 char *gidtoname(gid_t gid)
1602 {
1603         fstring name;
1604         struct group *grp;
1605
1606         grp = getgrgid(gid);
1607         if (grp) {
1608                 fstrcpy(name, grp->gr_name);
1609         }
1610         else {
1611                 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
1612         }
1613         return talloc_strdup(talloc_tos(), name);
1614 }
1615
1616 /*******************************************************************
1617  Convert a user name into a uid. 
1618 ********************************************************************/
1619
1620 uid_t nametouid(const char *name)
1621 {
1622         struct passwd *pass;
1623         char *p;
1624         uid_t u;
1625
1626         pass = getpwnam_alloc(NULL, name);
1627         if (pass) {
1628                 u = pass->pw_uid;
1629                 TALLOC_FREE(pass);
1630                 return u;
1631         }
1632
1633         u = (uid_t)strtol(name, &p, 0);
1634         if ((p != name) && (*p == '\0'))
1635                 return u;
1636
1637         return (uid_t)-1;
1638 }
1639
1640 /*******************************************************************
1641  Convert a name to a gid_t if possible. Return -1 if not a group. 
1642 ********************************************************************/
1643
1644 gid_t nametogid(const char *name)
1645 {
1646         struct group *grp;
1647         char *p;
1648         gid_t g;
1649
1650         g = (gid_t)strtol(name, &p, 0);
1651         if ((p != name) && (*p == '\0'))
1652                 return g;
1653
1654         grp = sys_getgrnam(name);
1655         if (grp)
1656                 return(grp->gr_gid);
1657         return (gid_t)-1;
1658 }
1659
1660 /*******************************************************************
1661  Something really nasty happened - panic !
1662 ********************************************************************/
1663
1664 void smb_panic(const char *const why)
1665 {
1666         char *cmd;
1667         int result;
1668
1669 #ifdef DEVELOPER
1670         {
1671
1672                 if (global_clobber_region_function) {
1673                         DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1674                                          global_clobber_region_function,
1675                                          global_clobber_region_line));
1676                 } 
1677         }
1678 #endif
1679
1680         DEBUG(0,("PANIC (pid %llu): %s\n",
1681                     (unsigned long long)sys_getpid(), why));
1682         log_stack_trace();
1683
1684         cmd = lp_panic_action();
1685         if (cmd && *cmd) {
1686                 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1687                 result = system(cmd);
1688
1689                 if (result == -1)
1690                         DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1691                                           strerror(errno)));
1692                 else
1693                         DEBUG(0, ("smb_panic(): action returned status %d\n",
1694                                           WEXITSTATUS(result)));
1695         }
1696
1697         dump_core();
1698 }
1699
1700 /*******************************************************************
1701  Print a backtrace of the stack to the debug log. This function
1702  DELIBERATELY LEAKS MEMORY. The expectation is that you should
1703  exit shortly after calling it.
1704 ********************************************************************/
1705
1706 #ifdef HAVE_LIBUNWIND_H
1707 #include <libunwind.h>
1708 #endif
1709
1710 #ifdef HAVE_EXECINFO_H
1711 #include <execinfo.h>
1712 #endif
1713
1714 #ifdef HAVE_LIBEXC_H
1715 #include <libexc.h>
1716 #endif
1717
1718 void log_stack_trace(void)
1719 {
1720 #ifdef HAVE_LIBUNWIND
1721         /* Try to use libunwind before any other technique since on ia64
1722          * libunwind correctly walks the stack in more circumstances than
1723          * backtrace.
1724          */ 
1725         unw_cursor_t cursor;
1726         unw_context_t uc;
1727         unsigned i = 0;
1728
1729         char procname[256];
1730         unw_word_t ip, sp, off;
1731
1732         procname[sizeof(procname) - 1] = '\0';
1733
1734         if (unw_getcontext(&uc) != 0) {
1735                 goto libunwind_failed;
1736         }
1737
1738         if (unw_init_local(&cursor, &uc) != 0) {
1739                 goto libunwind_failed;
1740         }
1741
1742         DEBUG(0, ("BACKTRACE:\n"));
1743
1744         do {
1745             ip = sp = 0;
1746             unw_get_reg(&cursor, UNW_REG_IP, &ip);
1747             unw_get_reg(&cursor, UNW_REG_SP, &sp);
1748
1749             switch (unw_get_proc_name(&cursor,
1750                         procname, sizeof(procname) - 1, &off) ) {
1751             case 0:
1752                     /* Name found. */
1753             case -UNW_ENOMEM:
1754                     /* Name truncated. */
1755                     DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1756                             i, procname, (long long)off,
1757                             (long long)ip, (long long) sp));
1758                     break;
1759             default:
1760             /* case -UNW_ENOINFO: */
1761             /* case -UNW_EUNSPEC: */
1762                     /* No symbol name found. */
1763                     DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1764                             i, "<unknown symbol>",
1765                             (long long)ip, (long long) sp));
1766             }
1767             ++i;
1768         } while (unw_step(&cursor) > 0);
1769
1770         return;
1771
1772 libunwind_failed:
1773         DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1774
1775 #elif HAVE_BACKTRACE_SYMBOLS
1776         void *backtrace_stack[BACKTRACE_STACK_SIZE];
1777         size_t backtrace_size;
1778         char **backtrace_strings;
1779
1780         /* get the backtrace (stack frames) */
1781         backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1782         backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1783
1784         DEBUG(0, ("BACKTRACE: %lu stack frames:\n", 
1785                   (unsigned long)backtrace_size));
1786         
1787         if (backtrace_strings) {
1788                 int i;
1789
1790                 for (i = 0; i < backtrace_size; i++)
1791                         DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1792
1793                 /* Leak the backtrace_strings, rather than risk what free() might do */
1794         }
1795
1796 #elif HAVE_LIBEXC
1797
1798         /* The IRIX libexc library provides an API for unwinding the stack. See
1799          * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1800          * since we are about to abort anyway, it hardly matters.
1801          */
1802
1803 #define NAMESIZE 32 /* Arbitrary */
1804
1805         __uint64_t      addrs[BACKTRACE_STACK_SIZE];
1806         char *          names[BACKTRACE_STACK_SIZE];
1807         char            namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1808
1809         int             i;
1810         int             levels;
1811
1812         ZERO_ARRAY(addrs);
1813         ZERO_ARRAY(names);
1814         ZERO_ARRAY(namebuf);
1815
1816         /* We need to be root so we can open our /proc entry to walk
1817          * our stack. It also helps when we want to dump core.
1818          */
1819         become_root();
1820
1821         for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1822                 names[i] = namebuf + (i * NAMESIZE);
1823         }
1824
1825         levels = trace_back_stack(0, addrs, names,
1826                         BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1827
1828         DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1829         for (i = 0; i < levels; i++) {
1830                 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1831         }
1832 #undef NAMESIZE
1833
1834 #else
1835         DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1836 #endif
1837 }
1838
1839 /*******************************************************************
1840   A readdir wrapper which just returns the file name.
1841  ********************************************************************/
1842
1843 const char *readdirname(SMB_STRUCT_DIR *p)
1844 {
1845         SMB_STRUCT_DIRENT *ptr;
1846         char *dname;
1847
1848         if (!p)
1849                 return(NULL);
1850   
1851         ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1852         if (!ptr)
1853                 return(NULL);
1854
1855         dname = ptr->d_name;
1856
1857 #ifdef NEXT2
1858         if (telldir(p) < 0)
1859                 return(NULL);
1860 #endif
1861
1862 #ifdef HAVE_BROKEN_READDIR_NAME
1863         /* using /usr/ucb/cc is BAD */
1864         dname = dname - 2;
1865 #endif
1866
1867         return talloc_strdup(talloc_tos(), dname);
1868 }
1869
1870 /*******************************************************************
1871  Utility function used to decide if the last component 
1872  of a path matches a (possibly wildcarded) entry in a namelist.
1873 ********************************************************************/
1874
1875 BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensitive)
1876 {
1877         const char *last_component;
1878
1879         /* if we have no list it's obviously not in the path */
1880         if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1881                 return False;
1882         }
1883
1884         DEBUG(8, ("is_in_path: %s\n", name));
1885
1886         /* Get the last component of the unix name. */
1887         last_component = strrchr_m(name, '/');
1888         if (!last_component) {
1889                 last_component = name;
1890         } else {
1891                 last_component++; /* Go past '/' */
1892         }
1893
1894         for(; namelist->name != NULL; namelist++) {
1895                 if(namelist->is_wild) {
1896                         if (mask_match(last_component, namelist->name, case_sensitive)) {
1897                                 DEBUG(8,("is_in_path: mask match succeeded\n"));
1898                                 return True;
1899                         }
1900                 } else {
1901                         if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1902                                                 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1903                                 DEBUG(8,("is_in_path: match succeeded\n"));
1904                                 return True;
1905                         }
1906                 }
1907         }
1908         DEBUG(8,("is_in_path: match not found\n"));
1909         return False;
1910 }
1911
1912 /*******************************************************************
1913  Strip a '/' separated list into an array of 
1914  name_compare_enties structures suitable for 
1915  passing to is_in_path(). We do this for
1916  speed so we can pre-parse all the names in the list 
1917  and don't do it for each call to is_in_path().
1918  namelist is modified here and is assumed to be 
1919  a copy owned by the caller.
1920  We also check if the entry contains a wildcard to
1921  remove a potentially expensive call to mask_match
1922  if possible.
1923 ********************************************************************/
1924  
1925 void set_namearray(name_compare_entry **ppname_array, char *namelist)
1926 {
1927         char *name_end;
1928         char *nameptr = namelist;
1929         int num_entries = 0;
1930         int i;
1931
1932         (*ppname_array) = NULL;
1933
1934         if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) 
1935                 return;
1936
1937         /* We need to make two passes over the string. The
1938                 first to count the number of elements, the second
1939                 to split it.
1940         */
1941
1942         while(*nameptr) {
1943                 if ( *nameptr == '/' ) {
1944                         /* cope with multiple (useless) /s) */
1945                         nameptr++;
1946                         continue;
1947                 }
1948                 /* find the next / */
1949                 name_end = strchr_m(nameptr, '/');
1950
1951                 /* oops - the last check for a / didn't find one. */
1952                 if (name_end == NULL)
1953                         break;
1954
1955                 /* next segment please */
1956                 nameptr = name_end + 1;
1957                 num_entries++;
1958         }
1959
1960         if(num_entries == 0)
1961                 return;
1962
1963         if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1964                 DEBUG(0,("set_namearray: malloc fail\n"));
1965                 return;
1966         }
1967
1968         /* Now copy out the names */
1969         nameptr = namelist;
1970         i = 0;
1971         while(*nameptr) {
1972                 if ( *nameptr == '/' ) {
1973                         /* cope with multiple (useless) /s) */
1974                         nameptr++;
1975                         continue;
1976                 }
1977                 /* find the next / */
1978                 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1979                         *name_end = 0;
1980
1981                 /* oops - the last check for a / didn't find one. */
1982                 if(name_end == NULL) 
1983                         break;
1984
1985                 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1986                 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1987                         DEBUG(0,("set_namearray: malloc fail (1)\n"));
1988                         return;
1989                 }
1990
1991                 /* next segment please */
1992                 nameptr = name_end + 1;
1993                 i++;
1994         }
1995   
1996         (*ppname_array)[i].name = NULL;
1997
1998         return;
1999 }
2000
2001 /****************************************************************************
2002  Routine to free a namearray.
2003 ****************************************************************************/
2004
2005 void free_namearray(name_compare_entry *name_array)
2006 {
2007         int i;
2008
2009         if(name_array == NULL)
2010                 return;
2011
2012         for(i=0; name_array[i].name!=NULL; i++)
2013                 SAFE_FREE(name_array[i].name);
2014         SAFE_FREE(name_array);
2015 }
2016
2017 #undef DBGC_CLASS
2018 #define DBGC_CLASS DBGC_LOCKING
2019
2020 /****************************************************************************
2021  Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
2022  is dealt with in posix.c
2023  Returns True if the lock was granted, False otherwise.
2024 ****************************************************************************/
2025
2026 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
2027 {
2028         SMB_STRUCT_FLOCK lock;
2029         int ret;
2030
2031         DEBUG(8,("fcntl_lock fd=%d op=%d offset=%.0f count=%.0f type=%d\n",
2032                 fd,op,(double)offset,(double)count,type));
2033
2034         lock.l_type = type;
2035         lock.l_whence = SEEK_SET;
2036         lock.l_start = offset;
2037         lock.l_len = count;
2038         lock.l_pid = 0;
2039
2040         ret = sys_fcntl_ptr(fd,op,&lock);
2041
2042         if (ret == -1) {
2043                 int sav = errno;
2044                 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
2045                         (double)offset,(double)count,op,type,strerror(errno)));
2046                 errno = sav;
2047                 return False;
2048         }
2049
2050         /* everything went OK */
2051         DEBUG(8,("fcntl_lock: Lock call successful\n"));
2052
2053         return True;
2054 }
2055
2056 /****************************************************************************
2057  Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
2058  is dealt with in posix.c
2059  Returns True if we have information regarding this lock region (and returns
2060  F_UNLCK in *ptype if the region is unlocked). False if the call failed.
2061 ****************************************************************************/
2062
2063 BOOL fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
2064 {
2065         SMB_STRUCT_FLOCK lock;
2066         int ret;
2067
2068         DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
2069                     fd,(double)*poffset,(double)*pcount,*ptype));
2070
2071         lock.l_type = *ptype;
2072         lock.l_whence = SEEK_SET;
2073         lock.l_start = *poffset;
2074         lock.l_len = *pcount;
2075         lock.l_pid = 0;
2076
2077         ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
2078
2079         if (ret == -1) {
2080                 int sav = errno;
2081                 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
2082                         (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
2083                 errno = sav;
2084                 return False;
2085         }
2086
2087         *ptype = lock.l_type;
2088         *poffset = lock.l_start;
2089         *pcount = lock.l_len;
2090         *ppid = lock.l_pid;
2091         
2092         DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
2093                         fd, (int)lock.l_type, (unsigned int)lock.l_pid));
2094         return True;
2095 }
2096
2097 #undef DBGC_CLASS
2098 #define DBGC_CLASS DBGC_ALL
2099
2100 /*******************************************************************
2101  Is the name specified one of my netbios names.
2102  Returns true if it is equal, false otherwise.
2103 ********************************************************************/
2104
2105 BOOL is_myname(const char *s)
2106 {
2107         int n;
2108         BOOL ret = False;
2109
2110         for (n=0; my_netbios_names(n); n++) {
2111                 if (strequal(my_netbios_names(n), s)) {
2112                         ret=True;
2113                         break;
2114                 }
2115         }
2116         DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2117         return(ret);
2118 }
2119
2120 BOOL is_myname_or_ipaddr(const char *s)
2121 {
2122         fstring name, dnsname;
2123         char *servername;
2124
2125         if ( !s )
2126                 return False;
2127
2128         /* santize the string from '\\name' */
2129
2130         fstrcpy( name, s );
2131
2132         servername = strrchr_m( name, '\\' );
2133         if ( !servername )
2134                 servername = name;
2135         else
2136                 servername++;
2137
2138         /* optimize for the common case */
2139
2140         if (strequal(servername, global_myname())) 
2141                 return True;
2142
2143         /* check for an alias */
2144
2145         if (is_myname(servername))
2146                 return True;
2147
2148         /* check for loopback */
2149
2150         if (strequal(servername, "127.0.0.1")) 
2151                 return True;
2152
2153         if (strequal(servername, "localhost")) 
2154                 return True;
2155
2156         /* maybe it's my dns name */
2157
2158         if ( get_mydnsfullname( dnsname ) )
2159                 if ( strequal( servername, dnsname ) )
2160                         return True;
2161                 
2162         /* handle possible CNAME records */
2163
2164         if ( !is_ipaddress( servername ) ) {
2165                 /* use DNS to resolve the name, but only the first address */
2166                 struct hostent *hp;
2167
2168                 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
2169                         struct in_addr return_ip;
2170                         putip( (char*)&return_ip, (char*)hp->h_addr );
2171                         fstrcpy( name, inet_ntoa( return_ip ) );
2172                         servername = name;
2173                 }       
2174         }
2175                 
2176         /* maybe its an IP address? */
2177         if (is_ipaddress(servername)) {
2178                 struct iface_struct nics[MAX_INTERFACES];
2179                 int i, n;
2180                 uint32 ip;
2181                 
2182                 ip = interpret_addr(servername);
2183                 if ((ip==0) || (ip==0xffffffff))
2184                         return False;
2185                         
2186                 n = get_interfaces(nics, MAX_INTERFACES);
2187                 for (i=0; i<n; i++) {
2188                         if (ip == nics[i].ip.s_addr)
2189                                 return True;
2190                 }
2191         }       
2192
2193         /* no match */
2194         return False;
2195 }
2196
2197 /*******************************************************************
2198  Is the name specified our workgroup/domain.
2199  Returns true if it is equal, false otherwise.
2200 ********************************************************************/
2201
2202 BOOL is_myworkgroup(const char *s)
2203 {
2204         BOOL ret = False;
2205
2206         if (strequal(s, lp_workgroup())) {
2207                 ret=True;
2208         }
2209
2210         DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
2211         return(ret);
2212 }
2213
2214 /*******************************************************************
2215  we distinguish between 2K and XP by the "Native Lan Manager" string
2216    WinXP => "Windows 2002 5.1"
2217    WinXP 64bit => "Windows XP 5.2"
2218    Win2k => "Windows 2000 5.0"
2219    NT4   => "Windows NT 4.0" 
2220    Win9x => "Windows 4.0"
2221  Windows 2003 doesn't set the native lan manager string but 
2222  they do set the domain to "Windows 2003 5.2" (probably a bug).
2223 ********************************************************************/
2224
2225 void ra_lanman_string( const char *native_lanman )
2226 {       
2227         if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
2228                 set_remote_arch( RA_WINXP );
2229         else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
2230                 set_remote_arch( RA_WINXP );
2231         else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
2232                 set_remote_arch( RA_WIN2K3 );
2233 }
2234
2235 /*******************************************************************
2236  Set the horrid remote_arch string based on an enum.
2237 ********************************************************************/
2238
2239 void set_remote_arch(enum remote_arch_types type)
2240 {
2241         ra_type = type;
2242         switch( type ) {
2243         case RA_WFWG:
2244                 fstrcpy(remote_arch, "WfWg");
2245                 break;
2246         case RA_OS2:
2247                 fstrcpy(remote_arch, "OS2");
2248                 break;
2249         case RA_WIN95:
2250                 fstrcpy(remote_arch, "Win95");
2251                 break;
2252         case RA_WINNT:
2253                 fstrcpy(remote_arch, "WinNT");
2254                 break;
2255         case RA_WIN2K:
2256                 fstrcpy(remote_arch, "Win2K");
2257                 break;
2258         case RA_WINXP:
2259                 fstrcpy(remote_arch, "WinXP");
2260                 break;
2261         case RA_WIN2K3:
2262                 fstrcpy(remote_arch, "Win2K3");
2263                 break;
2264         case RA_VISTA:
2265                 fstrcpy(remote_arch, "Vista");
2266                 break;
2267         case RA_SAMBA:
2268                 fstrcpy(remote_arch,"Samba");
2269                 break;
2270         case RA_CIFSFS:
2271                 fstrcpy(remote_arch,"CIFSFS");
2272                 break;
2273         default:
2274                 ra_type = RA_UNKNOWN;
2275                 fstrcpy(remote_arch, "UNKNOWN");
2276                 break;
2277         }
2278
2279         DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n", remote_arch));
2280 }
2281
2282 /*******************************************************************
2283  Get the remote_arch type.
2284 ********************************************************************/
2285
2286 enum remote_arch_types get_remote_arch(void)
2287 {
2288         return ra_type;
2289 }
2290
2291 void print_asc(int level, const unsigned char *buf,int len)
2292 {
2293         int i;
2294         for (i=0;i<len;i++)
2295                 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2296 }
2297
2298 void dump_data(int level, const unsigned char *buf,int len)
2299 {
2300         int i=0;
2301         if (len<=0) return;
2302
2303         if (!DEBUGLVL(level)) return;
2304         
2305         DEBUGADD(level,("[%03X] ",i));
2306         for (i=0;i<len;) {
2307                 DEBUGADD(level,("%02X ",(int)buf[i]));
2308                 i++;
2309                 if (i%8 == 0) DEBUGADD(level,(" "));
2310                 if (i%16 == 0) {      
2311                         print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2312                         print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2313                         if (i<len) DEBUGADD(level,("[%03X] ",i));
2314                 }
2315         }
2316         if (i%16) {
2317                 int n;
2318                 n = 16 - (i%16);
2319                 DEBUGADD(level,(" "));
2320                 if (n>8) DEBUGADD(level,(" "));
2321                 while (n--) DEBUGADD(level,("   "));
2322                 n = MIN(8,i%16);
2323                 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2324                 n = (i%16) - n;
2325                 if (n>0) print_asc(level,&buf[i-n],n); 
2326                 DEBUGADD(level,("\n"));    
2327         }       
2328 }
2329
2330 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2331 {
2332 #ifdef DEBUG_PASSWORD
2333         DEBUG(11, ("%s", msg));
2334         if (data != NULL && len > 0)
2335         {
2336                 dump_data(11, data, len);
2337         }
2338 #endif
2339 }
2340
2341 char *tab_depth(int depth)
2342 {
2343         static pstring spaces;
2344         memset(spaces, ' ', depth * 4);
2345         spaces[depth * 4] = 0;
2346         return spaces;
2347 }
2348
2349 /*****************************************************************************
2350  Provide a checksum on a string
2351
2352  Input:  s - the null-terminated character string for which the checksum
2353              will be calculated.
2354
2355   Output: The checksum value calculated for s.
2356 *****************************************************************************/
2357
2358 int str_checksum(const char *s)
2359 {
2360         int res = 0;
2361         int c;
2362         int i=0;
2363         
2364         while(*s) {
2365                 c = *s;
2366                 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2367                 s++;
2368                 i++;
2369         }
2370         return(res);
2371 }
2372
2373 /*****************************************************************
2374  Zero a memory area then free it. Used to catch bugs faster.
2375 *****************************************************************/  
2376
2377 void zero_free(void *p, size_t size)
2378 {
2379         memset(p, 0, size);
2380         SAFE_FREE(p);
2381 }
2382
2383 /*****************************************************************
2384  Set our open file limit to a requested max and return the limit.
2385 *****************************************************************/  
2386
2387 int set_maxfiles(int requested_max)
2388 {
2389 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2390         struct rlimit rlp;
2391         int saved_current_limit;
2392
2393         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2394                 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2395                         strerror(errno) ));
2396                 /* just guess... */
2397                 return requested_max;
2398         }
2399
2400         /* 
2401          * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2402          * account for the extra fd we need 
2403          * as well as the log files and standard
2404          * handles etc. Save the limit we want to set in case
2405          * we are running on an OS that doesn't support this limit (AIX)
2406          * which always returns RLIM_INFINITY for rlp.rlim_max.
2407          */
2408
2409         /* Try raising the hard (max) limit to the requested amount. */
2410
2411 #if defined(RLIM_INFINITY)
2412         if (rlp.rlim_max != RLIM_INFINITY) {
2413                 int orig_max = rlp.rlim_max;
2414
2415                 if ( rlp.rlim_max < requested_max )
2416                         rlp.rlim_max = requested_max;
2417
2418                 /* This failing is not an error - many systems (Linux) don't
2419                         support our default request of 10,000 open files. JRA. */
2420
2421                 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2422                         DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n", 
2423                                 (int)rlp.rlim_max, strerror(errno) ));
2424
2425                         /* Set failed - restore original value from get. */
2426                         rlp.rlim_max = orig_max;
2427                 }
2428         }
2429 #endif
2430
2431         /* Now try setting the soft (current) limit. */
2432
2433         saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2434
2435         if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2436                 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n", 
2437                         (int)rlp.rlim_cur, strerror(errno) ));
2438                 /* just guess... */
2439                 return saved_current_limit;
2440         }
2441
2442         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2443                 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2444                         strerror(errno) ));
2445                 /* just guess... */
2446                 return saved_current_limit;
2447     }
2448
2449 #if defined(RLIM_INFINITY)
2450         if(rlp.rlim_cur == RLIM_INFINITY)
2451                 return saved_current_limit;
2452 #endif
2453
2454         if((int)rlp.rlim_cur > saved_current_limit)
2455                 return saved_current_limit;
2456
2457         return rlp.rlim_cur;
2458 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2459         /*
2460          * No way to know - just guess...
2461          */
2462         return requested_max;
2463 #endif
2464 }
2465
2466 /*****************************************************************
2467  Possibly replace mkstemp if it is broken.
2468 *****************************************************************/  
2469
2470 int smb_mkstemp(char *name_template)
2471 {
2472 #if HAVE_SECURE_MKSTEMP
2473         return mkstemp(name_template);
2474 #else
2475         /* have a reasonable go at emulating it. Hope that
2476            the system mktemp() isn't completly hopeless */
2477         char *p = mktemp(name_template);
2478         if (!p)
2479                 return -1;
2480         return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2481 #endif
2482 }
2483
2484 /*****************************************************************
2485  malloc that aborts with smb_panic on fail or zero size.
2486  *****************************************************************/  
2487
2488 void *smb_xmalloc_array(size_t size, unsigned int count)
2489 {
2490         void *p;
2491         if (size == 0) {
2492                 smb_panic("smb_xmalloc_array: called with zero size");
2493         }
2494         if (count >= MAX_ALLOC_SIZE/size) {
2495                 smb_panic("smb_xmalloc_array: alloc size too large");
2496         }
2497         if ((p = SMB_MALLOC(size*count)) == NULL) {
2498                 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2499                         (unsigned long)size, (unsigned long)count));
2500                 smb_panic("smb_xmalloc_array: malloc failed");
2501         }
2502         return p;
2503 }
2504
2505 /**
2506  Memdup with smb_panic on fail.
2507 **/
2508
2509 void *smb_xmemdup(const void *p, size_t size)
2510 {
2511         void *p2;
2512         p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2513         memcpy(p2, p, size);
2514         return p2;
2515 }
2516
2517 /**
2518  strdup that aborts on malloc fail.
2519 **/
2520
2521 char *smb_xstrdup(const char *s)
2522 {
2523 #if defined(PARANOID_MALLOC_CHECKER)
2524 #ifdef strdup
2525 #undef strdup
2526 #endif
2527 #endif
2528
2529 #ifndef HAVE_STRDUP
2530 #define strdup rep_strdup
2531 #endif
2532
2533         char *s1 = strdup(s);
2534 #if defined(PARANOID_MALLOC_CHECKER)
2535 #ifdef strdup
2536 #undef strdup
2537 #endif
2538 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2539 #endif
2540         if (!s1) {
2541                 smb_panic("smb_xstrdup: malloc failed");
2542         }
2543         return s1;
2544
2545 }
2546
2547 /**
2548  strndup that aborts on malloc fail.
2549 **/
2550
2551 char *smb_xstrndup(const char *s, size_t n)
2552 {
2553 #if defined(PARANOID_MALLOC_CHECKER)
2554 #ifdef strndup
2555 #undef strndup
2556 #endif
2557 #endif
2558
2559 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
2560 #undef HAVE_STRNDUP
2561 #define strndup rep_strndup
2562 #endif
2563
2564         char *s1 = strndup(s, n);
2565 #if defined(PARANOID_MALLOC_CHECKER)
2566 #ifdef strndup
2567 #undef strndup
2568 #endif
2569 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2570 #endif
2571         if (!s1) {
2572                 smb_panic("smb_xstrndup: malloc failed");
2573         }
2574         return s1;
2575 }
2576
2577 /*
2578   vasprintf that aborts on malloc fail
2579 */
2580
2581  int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2582 {
2583         int n;
2584         va_list ap2;
2585
2586         VA_COPY(ap2, ap);
2587
2588         n = vasprintf(ptr, format, ap2);
2589         if (n == -1 || ! *ptr) {
2590                 smb_panic("smb_xvasprintf: out of memory");
2591         }
2592         return n;
2593 }
2594
2595 /*****************************************************************
2596  Like strdup but for memory.
2597 *****************************************************************/  
2598
2599 void *memdup(const void *p, size_t size)
2600 {
2601         void *p2;
2602         if (size == 0)
2603                 return NULL;
2604         p2 = SMB_MALLOC(size);
2605         if (!p2)
2606                 return NULL;
2607         memcpy(p2, p, size);
2608         return p2;
2609 }
2610
2611 /*****************************************************************
2612  Get local hostname and cache result.
2613 *****************************************************************/  
2614
2615 char *myhostname(void)
2616 {
2617         static pstring ret;
2618         if (ret[0] == 0)
2619                 get_myname(ret);
2620         return ret;
2621 }
2622
2623 /*****************************************************************
2624  A useful function for returning a path in the Samba lock directory.
2625 *****************************************************************/  
2626
2627 char *lock_path(const char *name)
2628 {
2629         pstring fname;
2630
2631         pstrcpy(fname,lp_lockdir());
2632         trim_char(fname,'\0','/');
2633         
2634         if (!directory_exist(fname,NULL))
2635                 mkdir(fname,0755);
2636         
2637         pstrcat(fname,"/");
2638         pstrcat(fname,name);
2639
2640         return talloc_strdup(talloc_tos(), fname);
2641 }
2642
2643 /*****************************************************************
2644  A useful function for returning a path in the Samba pid directory.
2645 *****************************************************************/
2646
2647 char *pid_path(const char *name)
2648 {
2649         pstring fname;
2650
2651         pstrcpy(fname,lp_piddir());
2652         trim_char(fname,'\0','/');
2653
2654         if (!directory_exist(fname,NULL))
2655                 mkdir(fname,0755);
2656
2657         pstrcat(fname,"/");
2658         pstrcat(fname,name);
2659
2660         return talloc_strdup(talloc_tos(), fname);
2661 }
2662
2663 /**
2664  * @brief Returns an absolute path to a file in the Samba lib directory.
2665  *
2666  * @param name File to find, relative to LIBDIR.
2667  *
2668  * @retval Pointer to a static #pstring containing the full path.
2669  **/
2670
2671 char *lib_path(const char *name)
2672 {
2673         return talloc_asprintf(talloc_tos(), "%s/%s", dyn_LIBDIR, name);
2674 }
2675
2676 /**
2677  * @brief Returns the platform specific shared library extension.
2678  *
2679  * @retval Pointer to a static #fstring containing the extension.
2680  **/
2681
2682 const char *shlib_ext(void)
2683 {
2684   return dyn_SHLIBEXT;
2685 }
2686
2687 /*******************************************************************
2688  Given a filename - get its directory name
2689  NB: Returned in static storage.  Caveats:
2690  o  If caller wishes to preserve, they should copy.
2691 ********************************************************************/
2692
2693 char *parent_dirname(const char *path)
2694 {
2695         char *parent;
2696
2697         if (!parent_dirname_talloc(talloc_tos(), path, &parent, NULL)) {
2698                 return NULL;
2699         }
2700
2701         return parent;
2702 }
2703
2704 BOOL parent_dirname_talloc(TALLOC_CTX *mem_ctx, const char *dir,
2705                            char **parent, const char **name)
2706 {
2707         char *p;
2708         ptrdiff_t len;
2709  
2710         p = strrchr_m(dir, '/'); /* Find final '/', if any */
2711
2712         if (p == NULL) {
2713                 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2714                         return False;
2715                 }
2716                 if (name) {
2717                         *name = "";
2718                 }
2719                 return True;
2720         }
2721
2722         len = p-dir;
2723
2724         if (!(*parent = TALLOC_ARRAY(mem_ctx, char, len+1))) {
2725                 return False;
2726         }
2727         memcpy(*parent, dir, len);
2728         (*parent)[len] = '\0';
2729
2730         if (name) {
2731                 *name = p+1;
2732         }
2733         return True;
2734 }
2735
2736 /*******************************************************************
2737  Determine if a pattern contains any Microsoft wildcard characters.
2738 *******************************************************************/
2739
2740 BOOL ms_has_wild(const char *s)
2741 {
2742         char c;
2743
2744         if (lp_posix_pathnames()) {
2745                 /* With posix pathnames no characters are wild. */
2746                 return False;
2747         }
2748
2749         while ((c = *s++)) {
2750                 switch (c) {
2751                 case '*':
2752                 case '?':
2753                 case '<':
2754                 case '>':
2755                 case '"':
2756                         return True;
2757                 }
2758         }
2759         return False;
2760 }
2761
2762 BOOL ms_has_wild_w(const smb_ucs2_t *s)
2763 {
2764         smb_ucs2_t c;
2765         if (!s) return False;
2766         while ((c = *s++)) {
2767                 switch (c) {
2768                 case UCS2_CHAR('*'):
2769                 case UCS2_CHAR('?'):
2770                 case UCS2_CHAR('<'):
2771                 case UCS2_CHAR('>'):
2772                 case UCS2_CHAR('"'):
2773                         return True;
2774                 }
2775         }
2776         return False;
2777 }
2778
2779 /*******************************************************************
2780  A wrapper that handles case sensitivity and the special handling
2781  of the ".." name.
2782 *******************************************************************/
2783
2784 BOOL mask_match(const char *string, const char *pattern, BOOL is_case_sensitive)
2785 {
2786         if (strcmp(string,"..") == 0)
2787                 string = ".";
2788         if (strcmp(pattern,".") == 0)
2789                 return False;
2790         
2791         return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2792 }
2793
2794 /*******************************************************************
2795  A wrapper that handles case sensitivity and the special handling
2796  of the ".." name. Varient that is only called by old search code which requires
2797  pattern translation.
2798 *******************************************************************/
2799
2800 BOOL mask_match_search(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, True, is_case_sensitive) == 0;
2808 }
2809
2810 /*******************************************************************
2811  A wrapper that handles a list of patters and calls mask_match()
2812  on each.  Returns True if any of the patterns match.
2813 *******************************************************************/
2814
2815 BOOL mask_match_list(const char *string, char **list, int listLen, BOOL is_case_sensitive)
2816 {
2817        while (listLen-- > 0) {
2818                if (mask_match(string, *list++, is_case_sensitive))
2819                        return True;
2820        }
2821        return False;
2822 }
2823
2824 /*********************************************************
2825  Recursive routine that is called by unix_wild_match.
2826 *********************************************************/
2827
2828 static BOOL unix_do_match(const char *regexp, const char *str)
2829 {
2830         const char *p;
2831
2832         for( p = regexp; *p && *str; ) {
2833
2834                 switch(*p) {
2835                         case '?':
2836                                 str++;
2837                                 p++;
2838                                 break;
2839
2840                         case '*':
2841
2842                                 /*
2843                                  * Look for a character matching 
2844                                  * the one after the '*'.
2845                                  */
2846                                 p++;
2847                                 if(!*p)
2848                                         return True; /* Automatic match */
2849                                 while(*str) {
2850
2851                                         while(*str && (*p != *str))
2852                                                 str++;
2853
2854                                         /*
2855                                          * Patch from weidel@multichart.de. In the case of the regexp
2856                                          * '*XX*' we want to ensure there are at least 2 'X' characters
2857                                          * in the string after the '*' for a match to be made.
2858                                          */
2859
2860                                         {
2861                                                 int matchcount=0;
2862
2863                                                 /*
2864                                                  * Eat all the characters that match, but count how many there were.
2865                                                  */
2866
2867                                                 while(*str && (*p == *str)) {
2868                                                         str++;
2869                                                         matchcount++;
2870                                                 }
2871
2872                                                 /*
2873                                                  * Now check that if the regexp had n identical characters that
2874                                                  * matchcount had at least that many matches.
2875                                                  */
2876
2877                                                 while ( *(p+1) && (*(p+1) == *p)) {
2878                                                         p++;
2879                                                         matchcount--;
2880                                                 }
2881
2882                                                 if ( matchcount <= 0 )
2883                                                         return False;
2884                                         }
2885
2886                                         str--; /* We've eaten the match char after the '*' */
2887
2888                                         if(unix_do_match(p, str))
2889                                                 return True;
2890
2891                                         if(!*str)
2892                                                 return False;
2893                                         else
2894                                                 str++;
2895                                 }
2896                                 return False;
2897
2898                         default:
2899                                 if(*str != *p)
2900                                         return False;
2901                                 str++;
2902                                 p++;
2903                                 break;
2904                 }
2905         }
2906
2907         if(!*p && !*str)
2908                 return True;
2909
2910         if (!*p && str[0] == '.' && str[1] == 0)
2911                 return(True);
2912   
2913         if (!*str && *p == '?') {
2914                 while (*p == '?')
2915                         p++;
2916                 return(!*p);
2917         }
2918
2919         if(!*str && (*p == '*' && p[1] == '\0'))
2920                 return True;
2921
2922         return False;
2923 }
2924
2925 /*******************************************************************
2926  Simple case insensitive interface to a UNIX wildcard matcher.
2927  Returns True if match, False if not.
2928 *******************************************************************/
2929
2930 BOOL unix_wild_match(const char *pattern, const char *string)
2931 {
2932         pstring p2, s2;
2933         char *p;
2934
2935         pstrcpy(p2, pattern);
2936         pstrcpy(s2, string);
2937         strlower_m(p2);
2938         strlower_m(s2);
2939
2940         /* Remove any *? and ** from the pattern as they are meaningless */
2941         for(p = p2; *p; p++)
2942                 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2943                         pstrcpy( &p[1], &p[2]);
2944  
2945         if (strequal(p2,"*"))
2946                 return True;
2947
2948         return unix_do_match(p2, s2);
2949 }
2950
2951 /**********************************************************************
2952  Converts a name to a fully qualified domain name.
2953  Returns True if lookup succeeded, False if not (then fqdn is set to name)
2954 ***********************************************************************/
2955                                                                                                                                                    
2956 BOOL name_to_fqdn(fstring fqdn, const char *name)
2957 {
2958         struct hostent *hp = sys_gethostbyname(name);
2959
2960         if ( hp && hp->h_name && *hp->h_name ) {
2961                 char *full = NULL;
2962
2963                 /* find out if the fqdn is returned as an alias
2964                  * to cope with /etc/hosts files where the first
2965                  * name is not the fqdn but the short name */
2966                 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2967                         int i;
2968                         for (i = 0; hp->h_aliases[i]; i++) {
2969                                 if (strchr_m(hp->h_aliases[i], '.')) {
2970                                         full = hp->h_aliases[i];
2971                                         break;
2972                                 }
2973                         }
2974                 }
2975                 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2976                         DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2977                         DEBUGADD(1, ("    Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2978                         DEBUGADD(1, ("    to Kerberos authentication problems as localhost.localdomain\n"));
2979                         DEBUGADD(1, ("    may end up being used instead of the real machine FQDN.\n"));
2980                         full = hp->h_name;
2981                 }
2982                         
2983                 if (!full) {
2984                         full = hp->h_name;
2985                 }
2986
2987                 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2988                 fstrcpy(fqdn, full);
2989                 return True;
2990         } else {
2991                 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2992                 fstrcpy(fqdn, name);
2993                 return False;
2994         }
2995 }
2996
2997 /**********************************************************************
2998  Extension to talloc_get_type: Abort on type mismatch
2999 ***********************************************************************/
3000
3001 void *talloc_check_name_abort(const void *ptr, const char *name)
3002 {
3003         void *result;
3004
3005         result = talloc_check_name(ptr, name);
3006         if (result != NULL)
3007                 return result;
3008
3009         DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
3010                   name, talloc_get_name(ptr)));
3011         smb_panic("talloc type mismatch");
3012         /* Keep the compiler happy */
3013         return NULL;
3014 }
3015
3016
3017 #ifdef __INSURE__
3018
3019 /*******************************************************************
3020 This routine is a trick to immediately catch errors when debugging
3021 with insure. A xterm with a gdb is popped up when insure catches
3022 a error. It is Linux specific.
3023 ********************************************************************/
3024
3025 int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
3026 {
3027         static int (*fn)();
3028         int ret;
3029         char pidstr[10];
3030         /* you can get /usr/bin/backtrace from 
3031            http://samba.org/ftp/unpacked/junkcode/backtrace */
3032         pstring cmd = "/usr/bin/backtrace %d";
3033
3034         slprintf(pidstr, sizeof(pidstr)-1, "%d", sys_getpid());
3035         pstring_sub(cmd, "%d", pidstr);
3036
3037         if (!fn) {
3038                 static void *h;
3039                 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
3040                 fn = dlsym(h, "_Insure_trap_error");
3041
3042                 if (!h || h == _Insure_trap_error) {
3043                         h = dlopen("/usr/local/parasoft/lib.linux2/libinsure.so", RTLD_LAZY);
3044                         fn = dlsym(h, "_Insure_trap_error");
3045                 }               
3046         }
3047
3048         ret = fn(a1, a2, a3, a4, a5, a6);
3049
3050         system(cmd);
3051
3052         return ret;
3053 }
3054 #endif
3055
3056 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
3057 {
3058         switch (share_access & ~FILE_SHARE_DELETE) {
3059                 case FILE_SHARE_NONE:
3060                         return DENY_ALL;
3061                 case FILE_SHARE_READ:
3062                         return DENY_WRITE;
3063                 case FILE_SHARE_WRITE:
3064                         return DENY_READ;
3065                 case FILE_SHARE_READ|FILE_SHARE_WRITE:
3066                         return DENY_NONE;
3067         }
3068         if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
3069                 return DENY_DOS;
3070         } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
3071                 return DENY_FCB;
3072         }
3073
3074         return (uint32)-1;
3075 }
3076
3077 pid_t procid_to_pid(const struct server_id *proc)
3078 {
3079         return proc->pid;
3080 }
3081
3082 static uint32 my_vnn = NONCLUSTER_VNN;
3083
3084 void set_my_vnn(uint32 vnn)
3085 {
3086         DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
3087         my_vnn = vnn;
3088 }
3089
3090 uint32 get_my_vnn(void)
3091 {
3092         return my_vnn;
3093 }
3094
3095 struct server_id pid_to_procid(pid_t pid)
3096 {
3097         struct server_id result;
3098         result.pid = pid;
3099 #ifdef CLUSTER_SUPPORT
3100         result.vnn = my_vnn;
3101 #endif
3102         return result;
3103 }
3104
3105 struct server_id procid_self(void)
3106 {
3107         return pid_to_procid(sys_getpid());
3108 }
3109
3110 struct server_id server_id_self(void)
3111 {
3112         return procid_self();
3113 }
3114
3115 BOOL procid_equal(const struct server_id *p1, const struct server_id *p2)
3116 {
3117         if (p1->pid != p2->pid)
3118                 return False;
3119 #ifdef CLUSTER_SUPPORT
3120         if (p1->vnn != p2->vnn)
3121                 return False;
3122 #endif
3123         return True;
3124 }
3125
3126 BOOL cluster_id_equal(const struct server_id *id1,
3127                       const struct server_id *id2)
3128 {
3129         return procid_equal(id1, id2);
3130 }
3131
3132 BOOL procid_is_me(const struct server_id *pid)
3133 {
3134         if (pid->pid != sys_getpid())
3135                 return False;
3136 #ifdef CLUSTER_SUPPORT
3137         if (pid->vnn != my_vnn)
3138                 return False;
3139 #endif
3140         return True;
3141 }
3142
3143 struct server_id interpret_pid(const char *pid_string)
3144 {
3145 #ifdef CLUSTER_SUPPORT
3146         unsigned int vnn, pid;
3147         struct server_id result;
3148         if (sscanf(pid_string, "%u:%u", &vnn, &pid) == 2) {
3149                 result.vnn = vnn;
3150                 result.pid = pid;
3151         }
3152         else if (sscanf(pid_string, "%u", &pid) == 1) {
3153                 result.vnn = NONCLUSTER_VNN;
3154                 result.pid = pid;
3155         }
3156         else {
3157                 result.vnn = NONCLUSTER_VNN;
3158                 result.pid = -1;
3159         }
3160         return result;
3161 #else
3162         return pid_to_procid(atoi(pid_string));
3163 #endif
3164 }
3165
3166 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
3167 {
3168         fstring str;
3169 #ifdef CLUSTER_SUPPORT
3170         if (pid->vnn == NONCLUSTER_VNN) {
3171                 fstr_sprintf(str, "%d", (int)pid->pid);
3172         }
3173         else {
3174                 fstr_sprintf(str, "%u:%d", (unsigned)pid->vnn, (int)pid->pid);
3175         }
3176 #else
3177         fstr_sprintf(str, "%d", (int)pid->pid);
3178 #endif
3179         return talloc_strdup(mem_ctx, str);
3180 }
3181
3182 char *procid_str_static(const struct server_id *pid)
3183 {
3184         return procid_str(talloc_tos(), pid);
3185 }
3186
3187 BOOL procid_valid(const struct server_id *pid)
3188 {
3189         return (pid->pid != -1);
3190 }
3191
3192 BOOL procid_is_local(const struct server_id *pid)
3193 {
3194 #ifdef CLUSTER_SUPPORT
3195         return pid->vnn == my_vnn;
3196 #else
3197         return True;
3198 #endif
3199 }
3200
3201 int this_is_smp(void)
3202 {
3203 #if defined(HAVE_SYSCONF)
3204
3205 #if defined(SYSCONF_SC_NPROC_ONLN)
3206         return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
3207 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3208         return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
3209 #else
3210         return 0;
3211 #endif
3212
3213 #else
3214         return 0;
3215 #endif
3216 }
3217
3218 /****************************************************************
3219  Check if an offset into a buffer is safe.
3220  If this returns True it's safe to indirect into the byte at
3221  pointer ptr+off.
3222 ****************************************************************/
3223
3224 BOOL is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3225 {
3226         const char *end_base = buf_base + buf_len;
3227         char *end_ptr = ptr + off;
3228
3229         if (!buf_base || !ptr) {
3230                 return False;
3231         }
3232
3233         if (end_base < buf_base || end_ptr < ptr) {
3234                 return False; /* wrap. */
3235         }
3236
3237         if (end_ptr < end_base) {
3238                 return True;
3239         }
3240         return False;
3241 }
3242
3243 /****************************************************************
3244  Return a safe pointer into a buffer, or NULL.
3245 ****************************************************************/
3246
3247 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3248 {
3249         return is_offset_safe(buf_base, buf_len, ptr, off) ?
3250                         ptr + off : NULL;
3251 }
3252
3253 /****************************************************************
3254  Return a safe pointer into a string within a buffer, or NULL.
3255 ****************************************************************/
3256
3257 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3258 {
3259         if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
3260                 return NULL;
3261         }
3262         /* Check if a valid string exists at this offset. */
3263         if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
3264                 return NULL;
3265         }
3266         return ptr + off;
3267 }
3268
3269 /****************************************************************
3270  Return an SVAL at a pointer, or failval if beyond the end.
3271 ****************************************************************/
3272
3273 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3274 {
3275         /*
3276          * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
3277          * NOT ptr[2].
3278          */
3279         if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
3280                 return failval;
3281         }
3282         return SVAL(ptr,off);
3283 }
3284
3285 /****************************************************************
3286  Return an IVAL at a pointer, or failval if beyond the end.
3287 ****************************************************************/
3288
3289 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3290 {
3291         /*
3292          * Note we use off+3 here, not off+4 as IVAL accesses 
3293          * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
3294          */
3295         if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
3296                 return failval;
3297         }
3298         return IVAL(ptr,off);
3299 }
3300
3301 #if 0
3302
3303 Disable these now we have checked all code paths and ensured
3304 NULL returns on zero request. JRA.
3305
3306 /****************************************************************
3307  talloc wrapper functions that guarentee a null pointer return
3308  if size == 0.
3309 ****************************************************************/
3310
3311 #ifndef MAX_TALLOC_SIZE
3312 #define MAX_TALLOC_SIZE 0x10000000
3313 #endif
3314
3315 /*
3316  *    talloc and zero memory.
3317  *    - returns NULL if size is zero.
3318  */
3319
3320 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
3321 {
3322         void *p;
3323
3324         if (size == 0) {
3325                 return NULL;
3326         }
3327
3328         p = talloc_named_const(ctx, size, name);
3329
3330         if (p) {
3331                 memset(p, '\0', size);
3332         }
3333
3334         return p;
3335 }
3336
3337 /*
3338  *   memdup with a talloc.
3339  *   - returns NULL if size is zero.
3340  */
3341
3342 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
3343 {
3344         void *newp;
3345
3346         if (size == 0) {
3347                 return NULL;
3348         }
3349
3350         newp = talloc_named_const(t, size, name);
3351         if (newp) {
3352                 memcpy(newp, p, size);
3353         }
3354
3355         return newp;
3356 }
3357
3358 /*
3359  *   alloc an array, checking for integer overflow in the array size.
3360  *   - returns NULL if count or el_size are zero.
3361  */
3362
3363 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3364 {
3365         if (count >= MAX_TALLOC_SIZE/el_size) {
3366                 return NULL;
3367         }
3368
3369         if (el_size == 0 || count == 0) {
3370                 return NULL;
3371         }
3372
3373         return talloc_named_const(ctx, el_size * count, name);
3374 }
3375
3376 /*
3377  *   alloc an zero array, checking for integer overflow in the array size
3378  *   - returns NULL if count or el_size are zero.
3379  */
3380
3381 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3382 {
3383         if (count >= MAX_TALLOC_SIZE/el_size) {
3384                 return NULL;
3385         }
3386
3387         if (el_size == 0 || count == 0) {
3388                 return NULL;
3389         }
3390
3391         return _talloc_zero(ctx, el_size * count, name);
3392 }
3393
3394 /*
3395  *   Talloc wrapper that returns NULL if size == 0.
3396  */
3397 void *talloc_zeronull(const void *context, size_t size, const char *name)
3398 {
3399         if (size == 0) {
3400                 return NULL;
3401         }
3402         return talloc_named_const(context, size, name);
3403 }
3404 #endif