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