s3: only include tdb headers where needed.
[samba.git] / source3 / lib / util.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jeremy Allison 2001-2007
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 #include "system/passwd.h"
26 #include "system/filesys.h"
27 #include "util_tdb.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/util_pw.h"
30 #include "messages.h"
31
32 /* Max allowable allococation - 256mb - 0x10000000 */
33 #define MAX_ALLOC_SIZE (1024*1024*256)
34
35 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
36 #ifdef WITH_NISPLUS_HOME
37 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
38 /*
39  * The following lines are needed due to buggy include files
40  * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
41  * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
42  * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
43  * an enum in /usr/include/rpcsvc/nis.h.
44  */
45
46 #if defined(GROUP)
47 #undef GROUP
48 #endif
49
50 #if defined(GROUP_OBJ)
51 #undef GROUP_OBJ
52 #endif
53
54 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
55
56 #include <rpcsvc/nis.h>
57
58 #endif /* WITH_NISPLUS_HOME */
59 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
60
61 static enum protocol_types Protocol = PROTOCOL_COREPLUS;
62
63 enum protocol_types get_Protocol(void)
64 {
65         return Protocol;
66 }
67
68 void set_Protocol(enum protocol_types  p)
69 {
70         Protocol = p;
71 }
72
73 static enum remote_arch_types ra_type = RA_UNKNOWN;
74
75 /***********************************************************************
76  Definitions for all names.
77 ***********************************************************************/
78
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 scope. Ensure upper case.
85 ***********************************************************************/
86
87 bool set_global_scope(const char *scope)
88 {
89         SAFE_FREE(smb_scope);
90         smb_scope = SMB_STRDUP(scope);
91         if (!smb_scope)
92                 return False;
93         strupper_m(smb_scope);
94         return True;
95 }
96
97 /*********************************************************************
98  Ensure scope is never null string.
99 *********************************************************************/
100
101 const char *global_scope(void)
102 {
103         if (!smb_scope)
104                 set_global_scope("");
105         return smb_scope;
106 }
107
108 static void free_netbios_names_array(void)
109 {
110         int i;
111
112         for (i = 0; i < smb_num_netbios_names; i++)
113                 SAFE_FREE(smb_my_netbios_names[i]);
114
115         SAFE_FREE(smb_my_netbios_names);
116         smb_num_netbios_names = 0;
117 }
118
119 static bool allocate_my_netbios_names_array(size_t number)
120 {
121         free_netbios_names_array();
122
123         smb_num_netbios_names = number + 1;
124         smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
125
126         if (!smb_my_netbios_names)
127                 return False;
128
129         memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
130         return True;
131 }
132
133 static bool set_my_netbios_names(const char *name, int i)
134 {
135         SAFE_FREE(smb_my_netbios_names[i]);
136
137         smb_my_netbios_names[i] = SMB_STRDUP(name);
138         if (!smb_my_netbios_names[i])
139                 return False;
140         strupper_m(smb_my_netbios_names[i]);
141         return True;
142 }
143
144 /***********************************************************************
145  Free memory allocated to global objects
146 ***********************************************************************/
147
148 void gfree_names(void)
149 {
150         gfree_netbios_names();
151         SAFE_FREE( smb_scope );
152         free_netbios_names_array();
153         free_local_machine_name();
154 }
155
156 void gfree_all( void )
157 {
158         gfree_names();
159         gfree_loadparm();
160         gfree_charcnv();
161         gfree_interfaces();
162         gfree_debugsyms();
163 }
164
165 const char *my_netbios_names(int i)
166 {
167         return smb_my_netbios_names[i];
168 }
169
170 bool set_netbios_aliases(const char **str_array)
171 {
172         size_t namecount;
173
174         /* Work out the max number of netbios aliases that we have */
175         for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
176                 ;
177
178         if ( global_myname() && *global_myname())
179                 namecount++;
180
181         /* Allocate space for the netbios aliases */
182         if (!allocate_my_netbios_names_array(namecount))
183                 return False;
184
185         /* Use the global_myname string first */
186         namecount=0;
187         if ( global_myname() && *global_myname()) {
188                 set_my_netbios_names( global_myname(), namecount );
189                 namecount++;
190         }
191
192         if (str_array) {
193                 size_t i;
194                 for ( i = 0; str_array[i] != NULL; i++) {
195                         size_t n;
196                         bool duplicate = False;
197
198                         /* Look for duplicates */
199                         for( n=0; n<namecount; n++ ) {
200                                 if( strequal( str_array[i], my_netbios_names(n) ) ) {
201                                         duplicate = True;
202                                         break;
203                                 }
204                         }
205                         if (!duplicate) {
206                                 if (!set_my_netbios_names(str_array[i], namecount))
207                                         return False;
208                                 namecount++;
209                         }
210                 }
211         }
212         return True;
213 }
214
215 /****************************************************************************
216   Common name initialization code.
217 ****************************************************************************/
218
219 bool init_names(void)
220 {
221         int n;
222
223         if (global_myname() == NULL || *global_myname() == '\0') {
224                 if (!set_global_myname(myhostname())) {
225                         DEBUG( 0, ( "init_names: malloc fail.\n" ) );
226                         return False;
227                 }
228         }
229
230         if (!set_netbios_aliases(lp_netbios_aliases())) {
231                 DEBUG( 0, ( "init_names: malloc fail.\n" ) );
232                 return False;
233         }
234
235         set_local_machine_name(global_myname(),false);
236
237         DEBUG( 5, ("Netbios name list:-\n") );
238         for( n=0; my_netbios_names(n); n++ ) {
239                 DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",
240                                         n, my_netbios_names(n) ) );
241         }
242
243         return( True );
244 }
245
246 /*******************************************************************
247  Check if a file exists - call vfs_file_exist for samba files.
248 ********************************************************************/
249
250 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf,
251                      bool fake_dir_create_times)
252 {
253         SMB_STRUCT_STAT st;
254         if (!sbuf)
255                 sbuf = &st;
256
257         if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
258                 return(False);
259
260         return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
261 }
262
263 /*******************************************************************
264  Check if a unix domain socket exists - call vfs_file_exist for samba files.
265 ********************************************************************/
266
267 bool socket_exist(const char *fname)
268 {
269         SMB_STRUCT_STAT st;
270         if (sys_stat(fname, &st, false) != 0)
271                 return(False);
272
273         return S_ISSOCK(st.st_ex_mode);
274 }
275
276 /*******************************************************************
277  Returns the size in bytes of the named given the stat struct.
278 ********************************************************************/
279
280 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
281 {
282         return sbuf->st_ex_size;
283 }
284
285 /*******************************************************************
286  Returns the size in bytes of the named file.
287 ********************************************************************/
288
289 SMB_OFF_T get_file_size(char *file_name)
290 {
291         SMB_STRUCT_STAT buf;
292         buf.st_ex_size = 0;
293         if (sys_stat(file_name, &buf, false) != 0)
294                 return (SMB_OFF_T)-1;
295         return get_file_size_stat(&buf);
296 }
297
298 /*******************************************************************
299  Show a smb message structure.
300 ********************************************************************/
301
302 void show_msg(const char *buf)
303 {
304         int i;
305         int bcc=0;
306
307         if (!DEBUGLVL(5))
308                 return;
309
310         DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
311                         smb_len(buf),
312                         (int)CVAL(buf,smb_com),
313                         (int)CVAL(buf,smb_rcls),
314                         (int)CVAL(buf,smb_reh),
315                         (int)SVAL(buf,smb_err),
316                         (int)CVAL(buf,smb_flg),
317                         (int)SVAL(buf,smb_flg2)));
318         DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
319                         (int)SVAL(buf,smb_tid),
320                         (int)SVAL(buf,smb_pid),
321                         (int)SVAL(buf,smb_uid),
322                         (int)SVAL(buf,smb_mid)));
323         DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
324
325         for (i=0;i<(int)CVAL(buf,smb_wct);i++)
326                 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
327                         SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
328
329         bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
330
331         DEBUGADD(5,("smb_bcc=%d\n",bcc));
332
333         if (DEBUGLEVEL < 10)
334                 return;
335
336         if (DEBUGLEVEL < 50)
337                 bcc = MIN(bcc, 512);
338
339         dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
340 }
341
342 /*******************************************************************
343  Set the length and marker of an encrypted smb packet.
344 ********************************************************************/
345
346 void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num)
347 {
348         _smb_setlen(buf,len);
349
350         SCVAL(buf,4,0xFF);
351         SCVAL(buf,5,'E');
352         SSVAL(buf,6,enc_ctx_num);
353 }
354
355 /*******************************************************************
356  Set the length and marker of an smb packet.
357 ********************************************************************/
358
359 void smb_setlen(char *buf,int len)
360 {
361         _smb_setlen(buf,len);
362
363         SCVAL(buf,4,0xFF);
364         SCVAL(buf,5,'S');
365         SCVAL(buf,6,'M');
366         SCVAL(buf,7,'B');
367 }
368
369 /*******************************************************************
370  Setup only the byte count for a smb message.
371 ********************************************************************/
372
373 int set_message_bcc(char *buf,int num_bytes)
374 {
375         int num_words = CVAL(buf,smb_wct);
376         SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
377         _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
378         return (smb_size + num_words*2 + num_bytes);
379 }
380
381 /*******************************************************************
382  Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
383  Return the bytes added
384 ********************************************************************/
385
386 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
387 {
388         size_t newlen = smb_len(*outbuf) + 4 + blob.length;
389         uint8 *tmp;
390
391         if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
392                 DEBUG(0, ("talloc failed\n"));
393                 return -1;
394         }
395         *outbuf = tmp;
396
397         memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
398         set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
399         return blob.length;
400 }
401
402 /*******************************************************************
403  Reduce a file name, removing .. elements.
404 ********************************************************************/
405
406 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
407 {
408         char *p = NULL;
409         char *str = NULL;
410
411         DEBUG(3,("dos_clean_name [%s]\n",s));
412
413         /* remove any double slashes */
414         str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
415         if (!str) {
416                 return NULL;
417         }
418
419         /* Remove leading .\\ characters */
420         if(strncmp(str, ".\\", 2) == 0) {
421                 trim_string(str, ".\\", NULL);
422                 if(*str == 0) {
423                         str = talloc_strdup(ctx, ".\\");
424                         if (!str) {
425                                 return NULL;
426                         }
427                 }
428         }
429
430         while ((p = strstr_m(str,"\\..\\")) != NULL) {
431                 char *s1;
432
433                 *p = 0;
434                 s1 = p+3;
435
436                 if ((p=strrchr_m(str,'\\')) != NULL) {
437                         *p = 0;
438                 } else {
439                         *str = 0;
440                 }
441                 str = talloc_asprintf(ctx,
442                                 "%s%s",
443                                 str,
444                                 s1);
445                 if (!str) {
446                         return NULL;
447                 }
448         }
449
450         trim_string(str,NULL,"\\..");
451         return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
452 }
453
454 /*******************************************************************
455  Reduce a file name, removing .. elements.
456 ********************************************************************/
457
458 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
459 {
460         char *p = NULL;
461         char *str = NULL;
462
463         DEBUG(3,("unix_clean_name [%s]\n",s));
464
465         /* remove any double slashes */
466         str = talloc_all_string_sub(ctx, s, "//","/");
467         if (!str) {
468                 return NULL;
469         }
470
471         /* Remove leading ./ characters */
472         if(strncmp(str, "./", 2) == 0) {
473                 trim_string(str, "./", NULL);
474                 if(*str == 0) {
475                         str = talloc_strdup(ctx, "./");
476                         if (!str) {
477                                 return NULL;
478                         }
479                 }
480         }
481
482         while ((p = strstr_m(str,"/../")) != NULL) {
483                 char *s1;
484
485                 *p = 0;
486                 s1 = p+3;
487
488                 if ((p=strrchr_m(str,'/')) != NULL) {
489                         *p = 0;
490                 } else {
491                         *str = 0;
492                 }
493                 str = talloc_asprintf(ctx,
494                                 "%s%s",
495                                 str,
496                                 s1);
497                 if (!str) {
498                         return NULL;
499                 }
500         }
501
502         trim_string(str,NULL,"/..");
503         return talloc_all_string_sub(ctx, str, "/./", "/");
504 }
505
506 char *clean_name(TALLOC_CTX *ctx, const char *s)
507 {
508         char *str = dos_clean_name(ctx, s);
509         if (!str) {
510                 return NULL;
511         }
512         return unix_clean_name(ctx, str);
513 }
514
515 /*******************************************************************
516  Write data into an fd at a given offset. Ignore seek errors.
517 ********************************************************************/
518
519 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
520 {
521         size_t total=0;
522         ssize_t ret;
523
524         if (pos == (SMB_OFF_T)-1) {
525                 return write_data(fd, buffer, N);
526         }
527 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
528         while (total < N) {
529                 ret = sys_pwrite(fd,buffer + total,N - total, pos);
530                 if (ret == -1 && errno == ESPIPE) {
531                         return write_data(fd, buffer + total,N - total);
532                 }
533                 if (ret == -1) {
534                         DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
535                         return -1;
536                 }
537                 if (ret == 0) {
538                         return total;
539                 }
540                 total += ret;
541                 pos += ret;
542         }
543         return (ssize_t)total;
544 #else
545         /* Use lseek and write_data. */
546         if (sys_lseek(fd, pos, SEEK_SET) == -1) {
547                 if (errno != ESPIPE) {
548                         return -1;
549                 }
550         }
551         return write_data(fd, buffer, N);
552 #endif
553 }
554
555
556 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
557                            struct event_context *ev_ctx,
558                            struct server_id id,
559                            bool parent_longlived)
560 {
561         NTSTATUS status = NT_STATUS_OK;
562
563         /* Reset the state of the random
564          * number generation system, so
565          * children do not get the same random
566          * numbers as each other */
567         set_need_random_reseed();
568
569         /* tdb needs special fork handling */
570         if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
571                 DEBUG(0,("tdb_reopen_all failed.\n"));
572                 status = NT_STATUS_OPEN_FAILED;
573                 goto done;
574         }
575
576         if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
577                 smb_panic(__location__ ": Failed to re-initialise event context");
578         }
579
580         if (msg_ctx) {
581                 /*
582                  * For clustering, we need to re-init our ctdbd connection after the
583                  * fork
584                  */
585                 status = messaging_reinit(msg_ctx, id);
586                 if (!NT_STATUS_IS_OK(status)) {
587                         DEBUG(0,("messaging_reinit() failed: %s\n",
588                                  nt_errstr(status)));
589                 }
590         }
591  done:
592         return status;
593 }
594
595 #if defined(PARANOID_MALLOC_CHECKER)
596
597 /****************************************************************************
598  Internal malloc wrapper. Externally visible.
599 ****************************************************************************/
600
601 void *malloc_(size_t size)
602 {
603         if (size == 0) {
604                 return NULL;
605         }
606 #undef malloc
607         return malloc(size);
608 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
609 }
610
611 /****************************************************************************
612  Internal calloc wrapper. Not externally visible.
613 ****************************************************************************/
614
615 static void *calloc_(size_t count, size_t size)
616 {
617         if (size == 0 || count == 0) {
618                 return NULL;
619         }
620 #undef calloc
621         return calloc(count, size);
622 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
623 }
624
625 /****************************************************************************
626  Internal realloc wrapper. Not externally visible.
627 ****************************************************************************/
628
629 static void *realloc_(void *ptr, size_t size)
630 {
631 #undef realloc
632         return realloc(ptr, size);
633 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
634 }
635
636 #endif /* PARANOID_MALLOC_CHECKER */
637
638 /****************************************************************************
639  Type-safe memalign
640 ****************************************************************************/
641
642 void *memalign_array(size_t el_size, size_t align, unsigned int count)
643 {
644         if (count >= MAX_ALLOC_SIZE/el_size) {
645                 return NULL;
646         }
647
648         return sys_memalign(align, el_size*count);
649 }
650
651 /****************************************************************************
652  Type-safe calloc.
653 ****************************************************************************/
654
655 void *calloc_array(size_t size, size_t nmemb)
656 {
657         if (nmemb >= MAX_ALLOC_SIZE/size) {
658                 return NULL;
659         }
660         if (size == 0 || nmemb == 0) {
661                 return NULL;
662         }
663 #if defined(PARANOID_MALLOC_CHECKER)
664         return calloc_(nmemb, size);
665 #else
666         return calloc(nmemb, size);
667 #endif
668 }
669
670 /****************************************************************************
671  Expand a pointer to be a particular size.
672  Note that this version of Realloc has an extra parameter that decides
673  whether to free the passed in storage on allocation failure or if the
674  new size is zero.
675
676  This is designed for use in the typical idiom of :
677
678  p = SMB_REALLOC(p, size)
679  if (!p) {
680     return error;
681  }
682
683  and not to have to keep track of the old 'p' contents to free later, nor
684  to worry if the size parameter was zero. In the case where NULL is returned
685  we guarentee that p has been freed.
686
687  If free later semantics are desired, then pass 'free_old_on_error' as False which
688  guarentees that the old contents are not freed on error, even if size == 0. To use
689  this idiom use :
690
691  tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
692  if (!tmp) {
693     SAFE_FREE(p);
694     return error;
695  } else {
696     p = tmp;
697  }
698
699  Changes were instigated by Coverity error checking. JRA.
700 ****************************************************************************/
701
702 void *Realloc(void *p, size_t size, bool free_old_on_error)
703 {
704         void *ret=NULL;
705
706         if (size == 0) {
707                 if (free_old_on_error) {
708                         SAFE_FREE(p);
709                 }
710                 DEBUG(2,("Realloc asked for 0 bytes\n"));
711                 return NULL;
712         }
713
714 #if defined(PARANOID_MALLOC_CHECKER)
715         if (!p) {
716                 ret = (void *)malloc_(size);
717         } else {
718                 ret = (void *)realloc_(p,size);
719         }
720 #else
721         if (!p) {
722                 ret = (void *)malloc(size);
723         } else {
724                 ret = (void *)realloc(p,size);
725         }
726 #endif
727
728         if (!ret) {
729                 if (free_old_on_error && p) {
730                         SAFE_FREE(p);
731                 }
732                 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
733         }
734
735         return(ret);
736 }
737
738 /****************************************************************************
739  (Hopefully) efficient array append.
740 ****************************************************************************/
741
742 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
743                         void *element, void *_array, uint32 *num_elements,
744                         ssize_t *array_size)
745 {
746         void **array = (void **)_array;
747
748         if (*array_size < 0) {
749                 return;
750         }
751
752         if (*array == NULL) {
753                 if (*array_size == 0) {
754                         *array_size = 128;
755                 }
756
757                 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
758                         goto error;
759                 }
760
761                 *array = TALLOC(mem_ctx, element_size * (*array_size));
762                 if (*array == NULL) {
763                         goto error;
764                 }
765         }
766
767         if (*num_elements == *array_size) {
768                 *array_size *= 2;
769
770                 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
771                         goto error;
772                 }
773
774                 *array = TALLOC_REALLOC(mem_ctx, *array,
775                                         element_size * (*array_size));
776
777                 if (*array == NULL) {
778                         goto error;
779                 }
780         }
781
782         memcpy((char *)(*array) + element_size*(*num_elements),
783                element, element_size);
784         *num_elements += 1;
785
786         return;
787
788  error:
789         *num_elements = 0;
790         *array_size = -1;
791 }
792
793 /****************************************************************************
794  Get my own domain name, or "" if we have none.
795 ****************************************************************************/
796
797 char *get_mydnsdomname(TALLOC_CTX *ctx)
798 {
799         const char *domname;
800         char *p;
801
802         domname = get_mydnsfullname();
803         if (!domname) {
804                 return NULL;
805         }
806
807         p = strchr_m(domname, '.');
808         if (p) {
809                 p++;
810                 return talloc_strdup(ctx, p);
811         } else {
812                 return talloc_strdup(ctx, "");
813         }
814 }
815
816 /****************************************************************************
817  Interpret a protocol description string, with a default.
818 ****************************************************************************/
819
820 int interpret_protocol(const char *str,int def)
821 {
822         if (strequal(str,"NT1"))
823                 return(PROTOCOL_NT1);
824         if (strequal(str,"LANMAN2"))
825                 return(PROTOCOL_LANMAN2);
826         if (strequal(str,"LANMAN1"))
827                 return(PROTOCOL_LANMAN1);
828         if (strequal(str,"CORE"))
829                 return(PROTOCOL_CORE);
830         if (strequal(str,"COREPLUS"))
831                 return(PROTOCOL_COREPLUS);
832         if (strequal(str,"CORE+"))
833                 return(PROTOCOL_COREPLUS);
834
835         DEBUG(0,("Unrecognised protocol level %s\n",str));
836
837         return(def);
838 }
839
840
841 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
842 /******************************************************************
843  Remove any mount options such as -rsize=2048,wsize=2048 etc.
844  Based on a fix from <Thomas.Hepper@icem.de>.
845  Returns a malloc'ed string.
846 *******************************************************************/
847
848 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
849 {
850         if (*str == '-') {
851                 const char *p = str;
852                 while(*p && !isspace(*p))
853                         p++;
854                 while(*p && isspace(*p))
855                         p++;
856                 if(*p) {
857                         return talloc_strdup(ctx, p);
858                 }
859         }
860         return NULL;
861 }
862
863 /*******************************************************************
864  Patch from jkf@soton.ac.uk
865  Split Luke's automount_server into YP lookup and string splitter
866  so can easily implement automount_path().
867  Returns a malloc'ed string.
868 *******************************************************************/
869
870 #ifdef WITH_NISPLUS_HOME
871 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
872 {
873         char *value = NULL;
874
875         char *nis_map = (char *)lp_nis_home_map_name();
876
877         char buffer[NIS_MAXATTRVAL + 1];
878         nis_result *result;
879         nis_object *object;
880         entry_obj  *entry;
881
882         snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
883         DEBUG(5, ("NIS+ querystring: %s\n", buffer));
884
885         if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
886                 if (result->status != NIS_SUCCESS) {
887                         DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
888                 } else {
889                         object = result->objects.objects_val;
890                         if (object->zo_data.zo_type == ENTRY_OBJ) {
891                                 entry = &object->zo_data.objdata_u.en_data;
892                                 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
893                                 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
894
895                                 value = talloc_strdup(ctx,
896                                                 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
897                                 if (!value) {
898                                         nis_freeresult(result);
899                                         return NULL;
900                                 }
901                                 value = talloc_string_sub(ctx,
902                                                 value,
903                                                 "&",
904                                                 user_name);
905                         }
906                 }
907         }
908         nis_freeresult(result);
909
910         if (value) {
911                 value = strip_mount_options(ctx, value);
912                 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
913                                         user_name, value));
914         }
915         return value;
916 }
917 #else /* WITH_NISPLUS_HOME */
918
919 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
920 {
921         char *value = NULL;
922
923         int nis_error;        /* returned by yp all functions */
924         char *nis_result;     /* yp_match inits this */
925         int nis_result_len;  /* and set this */
926         char *nis_domain;     /* yp_get_default_domain inits this */
927         char *nis_map = (char *)lp_nis_home_map_name();
928
929         if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
930                 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
931                 return NULL;
932         }
933
934         DEBUG(5, ("NIS Domain: %s\n", nis_domain));
935
936         if ((nis_error = yp_match(nis_domain, nis_map, user_name,
937                                         strlen(user_name), &nis_result,
938                                         &nis_result_len)) == 0) {
939                 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
940                         nis_result[nis_result_len] = '\0';
941                 }
942                 value = talloc_strdup(ctx, nis_result);
943                 if (!value) {
944                         return NULL;
945                 }
946                 value = strip_mount_options(ctx, value);
947         } else if(nis_error == YPERR_KEY) {
948                 DEBUG(3, ("YP Key not found:  while looking up \"%s\" in map \"%s\"\n", 
949                                 user_name, nis_map));
950                 DEBUG(3, ("using defaults for server and home directory\n"));
951         } else {
952                 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", 
953                                 yperr_string(nis_error), user_name, nis_map));
954         }
955
956         if (value) {
957                 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
958         }
959         return value;
960 }
961 #endif /* WITH_NISPLUS_HOME */
962 #endif
963
964 /****************************************************************************
965  Check if a process exists. Does this work on all unixes?
966 ****************************************************************************/
967
968 bool process_exists(const struct server_id pid)
969 {
970         if (procid_is_me(&pid)) {
971                 return True;
972         }
973
974         if (procid_is_local(&pid)) {
975                 return (kill(pid.pid,0) == 0 || errno != ESRCH);
976         }
977
978 #ifdef CLUSTER_SUPPORT
979         return ctdbd_process_exists(messaging_ctdbd_connection(),
980                                     pid.vnn, pid.pid);
981 #else
982         return False;
983 #endif
984 }
985
986 /*******************************************************************
987  Convert a uid into a user name.
988 ********************************************************************/
989
990 const char *uidtoname(uid_t uid)
991 {
992         TALLOC_CTX *ctx = talloc_tos();
993         char *name = NULL;
994         struct passwd *pass = NULL;
995
996         pass = getpwuid_alloc(ctx,uid);
997         if (pass) {
998                 name = talloc_strdup(ctx,pass->pw_name);
999                 TALLOC_FREE(pass);
1000         } else {
1001                 name = talloc_asprintf(ctx,
1002                                 "%ld",
1003                                 (long int)uid);
1004         }
1005         return name;
1006 }
1007
1008 /*******************************************************************
1009  Convert a gid into a group name.
1010 ********************************************************************/
1011
1012 char *gidtoname(gid_t gid)
1013 {
1014         struct group *grp;
1015
1016         grp = getgrgid(gid);
1017         if (grp) {
1018                 return talloc_strdup(talloc_tos(), grp->gr_name);
1019         }
1020         else {
1021                 return talloc_asprintf(talloc_tos(),
1022                                         "%d",
1023                                         (int)gid);
1024         }
1025 }
1026
1027 /*******************************************************************
1028  Convert a user name into a uid.
1029 ********************************************************************/
1030
1031 uid_t nametouid(const char *name)
1032 {
1033         struct passwd *pass;
1034         char *p;
1035         uid_t u;
1036
1037         pass = Get_Pwnam_alloc(talloc_tos(), name);
1038         if (pass) {
1039                 u = pass->pw_uid;
1040                 TALLOC_FREE(pass);
1041                 return u;
1042         }
1043
1044         u = (uid_t)strtol(name, &p, 0);
1045         if ((p != name) && (*p == '\0'))
1046                 return u;
1047
1048         return (uid_t)-1;
1049 }
1050
1051 /*******************************************************************
1052  Convert a name to a gid_t if possible. Return -1 if not a group. 
1053 ********************************************************************/
1054
1055 gid_t nametogid(const char *name)
1056 {
1057         struct group *grp;
1058         char *p;
1059         gid_t g;
1060
1061         g = (gid_t)strtol(name, &p, 0);
1062         if ((p != name) && (*p == '\0'))
1063                 return g;
1064
1065         grp = sys_getgrnam(name);
1066         if (grp)
1067                 return(grp->gr_gid);
1068         return (gid_t)-1;
1069 }
1070
1071 /*******************************************************************
1072  Something really nasty happened - panic !
1073 ********************************************************************/
1074
1075 void smb_panic_s3(const char *why)
1076 {
1077         char *cmd;
1078         int result;
1079
1080         DEBUG(0,("PANIC (pid %llu): %s\n",
1081                     (unsigned long long)sys_getpid(), why));
1082         log_stack_trace();
1083
1084         cmd = lp_panic_action();
1085         if (cmd && *cmd) {
1086                 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1087                 result = system(cmd);
1088
1089                 if (result == -1)
1090                         DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1091                                           strerror(errno)));
1092                 else
1093                         DEBUG(0, ("smb_panic(): action returned status %d\n",
1094                                           WEXITSTATUS(result)));
1095         }
1096
1097         dump_core();
1098 }
1099
1100 /*******************************************************************
1101  Print a backtrace of the stack to the debug log. This function
1102  DELIBERATELY LEAKS MEMORY. The expectation is that you should
1103  exit shortly after calling it.
1104 ********************************************************************/
1105
1106 #ifdef HAVE_LIBUNWIND_H
1107 #include <libunwind.h>
1108 #endif
1109
1110 #ifdef HAVE_EXECINFO_H
1111 #include <execinfo.h>
1112 #endif
1113
1114 #ifdef HAVE_LIBEXC_H
1115 #include <libexc.h>
1116 #endif
1117
1118 void log_stack_trace(void)
1119 {
1120 #ifdef HAVE_LIBUNWIND
1121         /* Try to use libunwind before any other technique since on ia64
1122          * libunwind correctly walks the stack in more circumstances than
1123          * backtrace.
1124          */ 
1125         unw_cursor_t cursor;
1126         unw_context_t uc;
1127         unsigned i = 0;
1128
1129         char procname[256];
1130         unw_word_t ip, sp, off;
1131
1132         procname[sizeof(procname) - 1] = '\0';
1133
1134         if (unw_getcontext(&uc) != 0) {
1135                 goto libunwind_failed;
1136         }
1137
1138         if (unw_init_local(&cursor, &uc) != 0) {
1139                 goto libunwind_failed;
1140         }
1141
1142         DEBUG(0, ("BACKTRACE:\n"));
1143
1144         do {
1145             ip = sp = 0;
1146             unw_get_reg(&cursor, UNW_REG_IP, &ip);
1147             unw_get_reg(&cursor, UNW_REG_SP, &sp);
1148
1149             switch (unw_get_proc_name(&cursor,
1150                         procname, sizeof(procname) - 1, &off) ) {
1151             case 0:
1152                     /* Name found. */
1153             case -UNW_ENOMEM:
1154                     /* Name truncated. */
1155                     DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1156                             i, procname, (long long)off,
1157                             (long long)ip, (long long) sp));
1158                     break;
1159             default:
1160             /* case -UNW_ENOINFO: */
1161             /* case -UNW_EUNSPEC: */
1162                     /* No symbol name found. */
1163                     DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1164                             i, "<unknown symbol>",
1165                             (long long)ip, (long long) sp));
1166             }
1167             ++i;
1168         } while (unw_step(&cursor) > 0);
1169
1170         return;
1171
1172 libunwind_failed:
1173         DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1174
1175 #elif HAVE_BACKTRACE_SYMBOLS
1176         void *backtrace_stack[BACKTRACE_STACK_SIZE];
1177         size_t backtrace_size;
1178         char **backtrace_strings;
1179
1180         /* get the backtrace (stack frames) */
1181         backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1182         backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1183
1184         DEBUG(0, ("BACKTRACE: %lu stack frames:\n", 
1185                   (unsigned long)backtrace_size));
1186
1187         if (backtrace_strings) {
1188                 int i;
1189
1190                 for (i = 0; i < backtrace_size; i++)
1191                         DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1192
1193                 /* Leak the backtrace_strings, rather than risk what free() might do */
1194         }
1195
1196 #elif HAVE_LIBEXC
1197
1198         /* The IRIX libexc library provides an API for unwinding the stack. See
1199          * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1200          * since we are about to abort anyway, it hardly matters.
1201          */
1202
1203 #define NAMESIZE 32 /* Arbitrary */
1204
1205         __uint64_t      addrs[BACKTRACE_STACK_SIZE];
1206         char *          names[BACKTRACE_STACK_SIZE];
1207         char            namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1208
1209         int             i;
1210         int             levels;
1211
1212         ZERO_ARRAY(addrs);
1213         ZERO_ARRAY(names);
1214         ZERO_ARRAY(namebuf);
1215
1216         /* We need to be root so we can open our /proc entry to walk
1217          * our stack. It also helps when we want to dump core.
1218          */
1219         become_root();
1220
1221         for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1222                 names[i] = namebuf + (i * NAMESIZE);
1223         }
1224
1225         levels = trace_back_stack(0, addrs, names,
1226                         BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1227
1228         DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1229         for (i = 0; i < levels; i++) {
1230                 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1231         }
1232 #undef NAMESIZE
1233
1234 #else
1235         DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1236 #endif
1237 }
1238
1239 /*******************************************************************
1240   A readdir wrapper which just returns the file name.
1241  ********************************************************************/
1242
1243 const char *readdirname(SMB_STRUCT_DIR *p)
1244 {
1245         SMB_STRUCT_DIRENT *ptr;
1246         char *dname;
1247
1248         if (!p)
1249                 return(NULL);
1250
1251         ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1252         if (!ptr)
1253                 return(NULL);
1254
1255         dname = ptr->d_name;
1256
1257 #ifdef NEXT2
1258         if (telldir(p) < 0)
1259                 return(NULL);
1260 #endif
1261
1262 #ifdef HAVE_BROKEN_READDIR_NAME
1263         /* using /usr/ucb/cc is BAD */
1264         dname = dname - 2;
1265 #endif
1266
1267         return talloc_strdup(talloc_tos(), dname);
1268 }
1269
1270 /*******************************************************************
1271  Utility function used to decide if the last component 
1272  of a path matches a (possibly wildcarded) entry in a namelist.
1273 ********************************************************************/
1274
1275 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1276 {
1277         const char *last_component;
1278
1279         /* if we have no list it's obviously not in the path */
1280         if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1281                 return False;
1282         }
1283
1284         DEBUG(8, ("is_in_path: %s\n", name));
1285
1286         /* Get the last component of the unix name. */
1287         last_component = strrchr_m(name, '/');
1288         if (!last_component) {
1289                 last_component = name;
1290         } else {
1291                 last_component++; /* Go past '/' */
1292         }
1293
1294         for(; namelist->name != NULL; namelist++) {
1295                 if(namelist->is_wild) {
1296                         if (mask_match(last_component, namelist->name, case_sensitive)) {
1297                                 DEBUG(8,("is_in_path: mask match succeeded\n"));
1298                                 return True;
1299                         }
1300                 } else {
1301                         if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1302                                                 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1303                                 DEBUG(8,("is_in_path: match succeeded\n"));
1304                                 return True;
1305                         }
1306                 }
1307         }
1308         DEBUG(8,("is_in_path: match not found\n"));
1309         return False;
1310 }
1311
1312 /*******************************************************************
1313  Strip a '/' separated list into an array of 
1314  name_compare_enties structures suitable for 
1315  passing to is_in_path(). We do this for
1316  speed so we can pre-parse all the names in the list 
1317  and don't do it for each call to is_in_path().
1318  We also check if the entry contains a wildcard to
1319  remove a potentially expensive call to mask_match
1320  if possible.
1321 ********************************************************************/
1322
1323 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1324 {
1325         char *name_end;
1326         char *namelist;
1327         char *nameptr;
1328         int num_entries = 0;
1329         int i;
1330
1331         (*ppname_array) = NULL;
1332
1333         if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0'))) 
1334                 return;
1335
1336         namelist = talloc_strdup(talloc_tos(), namelist_in);
1337         if (namelist == NULL) {
1338                 DEBUG(0,("set_namearray: talloc fail\n"));
1339                 return;
1340         }
1341         nameptr = namelist;
1342
1343         /* We need to make two passes over the string. The
1344                 first to count the number of elements, the second
1345                 to split it.
1346         */
1347
1348         while(*nameptr) {
1349                 if ( *nameptr == '/' ) {
1350                         /* cope with multiple (useless) /s) */
1351                         nameptr++;
1352                         continue;
1353                 }
1354                 /* anything left? */
1355                 if ( *nameptr == '\0' )
1356                         break;
1357
1358                 /* find the next '/' or consume remaining */
1359                 name_end = strchr_m(nameptr, '/');
1360                 if (name_end == NULL)
1361                         name_end = (char *)nameptr + strlen(nameptr);
1362
1363                 /* next segment please */
1364                 nameptr = name_end + 1;
1365                 num_entries++;
1366         }
1367
1368         if(num_entries == 0) {
1369                 talloc_free(namelist);
1370                 return;
1371         }
1372
1373         if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1374                 DEBUG(0,("set_namearray: malloc fail\n"));
1375                 talloc_free(namelist);
1376                 return;
1377         }
1378
1379         /* Now copy out the names */
1380         nameptr = namelist;
1381         i = 0;
1382         while(*nameptr) {
1383                 if ( *nameptr == '/' ) {
1384                         /* cope with multiple (useless) /s) */
1385                         nameptr++;
1386                         continue;
1387                 }
1388                 /* anything left? */
1389                 if ( *nameptr == '\0' )
1390                         break;
1391
1392                 /* find the next '/' or consume remaining */
1393                 name_end = strchr_m(nameptr, '/');
1394                 if (name_end)
1395                         *name_end = '\0';
1396                 else
1397                         name_end = nameptr + strlen(nameptr);
1398
1399                 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1400                 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1401                         DEBUG(0,("set_namearray: malloc fail (1)\n"));
1402                         talloc_free(namelist);
1403                         return;
1404                 }
1405
1406                 /* next segment please */
1407                 nameptr = name_end + 1;
1408                 i++;
1409         }
1410
1411         (*ppname_array)[i].name = NULL;
1412
1413         talloc_free(namelist);
1414         return;
1415 }
1416
1417 /****************************************************************************
1418  Routine to free a namearray.
1419 ****************************************************************************/
1420
1421 void free_namearray(name_compare_entry *name_array)
1422 {
1423         int i;
1424
1425         if(name_array == NULL)
1426                 return;
1427
1428         for(i=0; name_array[i].name!=NULL; i++)
1429                 SAFE_FREE(name_array[i].name);
1430         SAFE_FREE(name_array);
1431 }
1432
1433 #undef DBGC_CLASS
1434 #define DBGC_CLASS DBGC_LOCKING
1435
1436 /****************************************************************************
1437  Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1438  is dealt with in posix.c
1439  Returns True if we have information regarding this lock region (and returns
1440  F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1441 ****************************************************************************/
1442
1443 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1444 {
1445         SMB_STRUCT_FLOCK lock;
1446         int ret;
1447
1448         DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1449                     fd,(double)*poffset,(double)*pcount,*ptype));
1450
1451         lock.l_type = *ptype;
1452         lock.l_whence = SEEK_SET;
1453         lock.l_start = *poffset;
1454         lock.l_len = *pcount;
1455         lock.l_pid = 0;
1456
1457         ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1458
1459         if (ret == -1) {
1460                 int sav = errno;
1461                 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1462                         (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1463                 errno = sav;
1464                 return False;
1465         }
1466
1467         *ptype = lock.l_type;
1468         *poffset = lock.l_start;
1469         *pcount = lock.l_len;
1470         *ppid = lock.l_pid;
1471
1472         DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1473                         fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1474         return True;
1475 }
1476
1477 #undef DBGC_CLASS
1478 #define DBGC_CLASS DBGC_ALL
1479
1480 /*******************************************************************
1481  Is the name specified one of my netbios names.
1482  Returns true if it is equal, false otherwise.
1483 ********************************************************************/
1484
1485 bool is_myname(const char *s)
1486 {
1487         int n;
1488         bool ret = False;
1489
1490         for (n=0; my_netbios_names(n); n++) {
1491                 if (strequal(my_netbios_names(n), s)) {
1492                         ret=True;
1493                         break;
1494                 }
1495         }
1496         DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1497         return(ret);
1498 }
1499
1500 /*******************************************************************
1501  Is the name specified our workgroup/domain.
1502  Returns true if it is equal, false otherwise.
1503 ********************************************************************/
1504
1505 bool is_myworkgroup(const char *s)
1506 {
1507         bool ret = False;
1508
1509         if (strequal(s, lp_workgroup())) {
1510                 ret=True;
1511         }
1512
1513         DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1514         return(ret);
1515 }
1516
1517 /*******************************************************************
1518  we distinguish between 2K and XP by the "Native Lan Manager" string
1519    WinXP => "Windows 2002 5.1"
1520    WinXP 64bit => "Windows XP 5.2"
1521    Win2k => "Windows 2000 5.0"
1522    NT4   => "Windows NT 4.0"
1523    Win9x => "Windows 4.0"
1524  Windows 2003 doesn't set the native lan manager string but
1525  they do set the domain to "Windows 2003 5.2" (probably a bug).
1526 ********************************************************************/
1527
1528 void ra_lanman_string( const char *native_lanman )
1529 {
1530         if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1531                 set_remote_arch( RA_WINXP );
1532         else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1533                 set_remote_arch( RA_WINXP64 );
1534         else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1535                 set_remote_arch( RA_WIN2K3 );
1536 }
1537
1538 static const char *remote_arch_str;
1539
1540 const char *get_remote_arch_str(void)
1541 {
1542         if (!remote_arch_str) {
1543                 return "UNKNOWN";
1544         }
1545         return remote_arch_str;
1546 }
1547
1548 /*******************************************************************
1549  Set the horrid remote_arch string based on an enum.
1550 ********************************************************************/
1551
1552 void set_remote_arch(enum remote_arch_types type)
1553 {
1554         ra_type = type;
1555         switch( type ) {
1556         case RA_WFWG:
1557                 remote_arch_str = "WfWg";
1558                 break;
1559         case RA_OS2:
1560                 remote_arch_str = "OS2";
1561                 break;
1562         case RA_WIN95:
1563                 remote_arch_str = "Win95";
1564                 break;
1565         case RA_WINNT:
1566                 remote_arch_str = "WinNT";
1567                 break;
1568         case RA_WIN2K:
1569                 remote_arch_str = "Win2K";
1570                 break;
1571         case RA_WINXP:
1572                 remote_arch_str = "WinXP";
1573                 break;
1574         case RA_WINXP64:
1575                 remote_arch_str = "WinXP64";
1576                 break;
1577         case RA_WIN2K3:
1578                 remote_arch_str = "Win2K3";
1579                 break;
1580         case RA_VISTA:
1581                 remote_arch_str = "Vista";
1582                 break;
1583         case RA_SAMBA:
1584                 remote_arch_str = "Samba";
1585                 break;
1586         case RA_CIFSFS:
1587                 remote_arch_str = "CIFSFS";
1588                 break;
1589         case RA_OSX:
1590                 remote_arch_str = "OSX";
1591                 break;
1592         default:
1593                 ra_type = RA_UNKNOWN;
1594                 remote_arch_str = "UNKNOWN";
1595                 break;
1596         }
1597
1598         DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1599                                 remote_arch_str));
1600 }
1601
1602 /*******************************************************************
1603  Get the remote_arch type.
1604 ********************************************************************/
1605
1606 enum remote_arch_types get_remote_arch(void)
1607 {
1608         return ra_type;
1609 }
1610
1611 const char *tab_depth(int level, int depth)
1612 {
1613         if( CHECK_DEBUGLVL(level) ) {
1614                 dbgtext("%*s", depth*4, "");
1615         }
1616         return "";
1617 }
1618
1619 /*****************************************************************************
1620  Provide a checksum on a string
1621
1622  Input:  s - the null-terminated character string for which the checksum
1623              will be calculated.
1624
1625   Output: The checksum value calculated for s.
1626 *****************************************************************************/
1627
1628 int str_checksum(const char *s)
1629 {
1630         TDB_DATA key = string_tdb_data(s);
1631         return tdb_jenkins_hash(&key);
1632 }
1633
1634 /*****************************************************************
1635  Zero a memory area then free it. Used to catch bugs faster.
1636 *****************************************************************/  
1637
1638 void zero_free(void *p, size_t size)
1639 {
1640         memset(p, 0, size);
1641         SAFE_FREE(p);
1642 }
1643
1644 /*****************************************************************
1645  Set our open file limit to a requested max and return the limit.
1646 *****************************************************************/  
1647
1648 int set_maxfiles(int requested_max)
1649 {
1650 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1651         struct rlimit rlp;
1652         int saved_current_limit;
1653
1654         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1655                 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1656                         strerror(errno) ));
1657                 /* just guess... */
1658                 return requested_max;
1659         }
1660
1661         /* 
1662          * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1663          * account for the extra fd we need 
1664          * as well as the log files and standard
1665          * handles etc. Save the limit we want to set in case
1666          * we are running on an OS that doesn't support this limit (AIX)
1667          * which always returns RLIM_INFINITY for rlp.rlim_max.
1668          */
1669
1670         /* Try raising the hard (max) limit to the requested amount. */
1671
1672 #if defined(RLIM_INFINITY)
1673         if (rlp.rlim_max != RLIM_INFINITY) {
1674                 int orig_max = rlp.rlim_max;
1675
1676                 if ( rlp.rlim_max < requested_max )
1677                         rlp.rlim_max = requested_max;
1678
1679                 /* This failing is not an error - many systems (Linux) don't
1680                         support our default request of 10,000 open files. JRA. */
1681
1682                 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1683                         DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n", 
1684                                 (int)rlp.rlim_max, strerror(errno) ));
1685
1686                         /* Set failed - restore original value from get. */
1687                         rlp.rlim_max = orig_max;
1688                 }
1689         }
1690 #endif
1691
1692         /* Now try setting the soft (current) limit. */
1693
1694         saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1695
1696         if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1697                 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n", 
1698                         (int)rlp.rlim_cur, strerror(errno) ));
1699                 /* just guess... */
1700                 return saved_current_limit;
1701         }
1702
1703         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1704                 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1705                         strerror(errno) ));
1706                 /* just guess... */
1707                 return saved_current_limit;
1708     }
1709
1710 #if defined(RLIM_INFINITY)
1711         if(rlp.rlim_cur == RLIM_INFINITY)
1712                 return saved_current_limit;
1713 #endif
1714
1715         if((int)rlp.rlim_cur > saved_current_limit)
1716                 return saved_current_limit;
1717
1718         return rlp.rlim_cur;
1719 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1720         /*
1721          * No way to know - just guess...
1722          */
1723         return requested_max;
1724 #endif
1725 }
1726
1727 /*****************************************************************
1728  malloc that aborts with smb_panic on fail or zero size.
1729  *****************************************************************/  
1730
1731 void *smb_xmalloc_array(size_t size, unsigned int count)
1732 {
1733         void *p;
1734         if (size == 0) {
1735                 smb_panic("smb_xmalloc_array: called with zero size");
1736         }
1737         if (count >= MAX_ALLOC_SIZE/size) {
1738                 smb_panic("smb_xmalloc_array: alloc size too large");
1739         }
1740         if ((p = SMB_MALLOC(size*count)) == NULL) {
1741                 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1742                         (unsigned long)size, (unsigned long)count));
1743                 smb_panic("smb_xmalloc_array: malloc failed");
1744         }
1745         return p;
1746 }
1747
1748 /*
1749   vasprintf that aborts on malloc fail
1750 */
1751
1752  int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1753 {
1754         int n;
1755         va_list ap2;
1756
1757         va_copy(ap2, ap);
1758
1759         n = vasprintf(ptr, format, ap2);
1760         va_end(ap2);
1761         if (n == -1 || ! *ptr) {
1762                 smb_panic("smb_xvasprintf: out of memory");
1763         }
1764         return n;
1765 }
1766
1767 /*****************************************************************
1768  Get local hostname and cache result.
1769 *****************************************************************/
1770
1771 char *myhostname(void)
1772 {
1773         static char *ret;
1774         if (ret == NULL) {
1775                 ret = get_myname(NULL);
1776         }
1777         return ret;
1778 }
1779
1780 /**
1781  * @brief Returns an absolute path to a file concatenating the provided
1782  * @a rootpath and @a basename
1783  *
1784  * @param name Filename, relative to @a rootpath
1785  *
1786  * @retval Pointer to a string containing the full path.
1787  **/
1788
1789 static char *xx_path(const char *name, const char *rootpath)
1790 {
1791         char *fname = NULL;
1792
1793         fname = talloc_strdup(talloc_tos(), rootpath);
1794         if (!fname) {
1795                 return NULL;
1796         }
1797         trim_string(fname,"","/");
1798
1799         if (!directory_exist(fname)) {
1800                 if (!mkdir(fname,0755))
1801                         DEBUG(1, ("Unable to create directory %s for file %s. "
1802                               "Error was %s\n", fname, name, strerror(errno)));
1803         }
1804
1805         return talloc_asprintf(talloc_tos(),
1806                                 "%s/%s",
1807                                 fname,
1808                                 name);
1809 }
1810
1811 /**
1812  * @brief Returns an absolute path to a file in the Samba lock directory.
1813  *
1814  * @param name File to find, relative to LOCKDIR.
1815  *
1816  * @retval Pointer to a talloc'ed string containing the full path.
1817  **/
1818
1819 char *lock_path(const char *name)
1820 {
1821         return xx_path(name, lp_lockdir());
1822 }
1823
1824 /**
1825  * @brief Returns an absolute path to a file in the Samba pid directory.
1826  *
1827  * @param name File to find, relative to PIDDIR.
1828  *
1829  * @retval Pointer to a talloc'ed string containing the full path.
1830  **/
1831
1832 char *pid_path(const char *name)
1833 {
1834         return xx_path(name, lp_piddir());
1835 }
1836
1837 /**
1838  * @brief Returns an absolute path to a file in the Samba lib directory.
1839  *
1840  * @param name File to find, relative to LIBDIR.
1841  *
1842  * @retval Pointer to a string containing the full path.
1843  **/
1844
1845 char *lib_path(const char *name)
1846 {
1847         return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
1848 }
1849
1850 /**
1851  * @brief Returns an absolute path to a file in the Samba modules directory.
1852  *
1853  * @param name File to find, relative to MODULESDIR.
1854  *
1855  * @retval Pointer to a string containing the full path.
1856  **/
1857
1858 char *modules_path(const char *name)
1859 {
1860         return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_MODULESDIR(), name);
1861 }
1862
1863 /**
1864  * @brief Returns an absolute path to a file in the Samba data directory.
1865  *
1866  * @param name File to find, relative to CODEPAGEDIR.
1867  *
1868  * @retval Pointer to a talloc'ed string containing the full path.
1869  **/
1870
1871 char *data_path(const char *name)
1872 {
1873         return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
1874 }
1875
1876 /**
1877  * @brief Returns an absolute path to a file in the Samba state directory.
1878  *
1879  * @param name File to find, relative to STATEDIR.
1880  *
1881  * @retval Pointer to a talloc'ed string containing the full path.
1882  **/
1883
1884 char *state_path(const char *name)
1885 {
1886         return xx_path(name, lp_statedir());
1887 }
1888
1889 /**
1890  * @brief Returns an absolute path to a file in the Samba cache directory.
1891  *
1892  * @param name File to find, relative to CACHEDIR.
1893  *
1894  * @retval Pointer to a talloc'ed string containing the full path.
1895  **/
1896
1897 char *cache_path(const char *name)
1898 {
1899         return xx_path(name, lp_cachedir());
1900 }
1901
1902 /**
1903  * @brief Returns the platform specific shared library extension.
1904  *
1905  * @retval Pointer to a const char * containing the extension.
1906  **/
1907
1908 const char *shlib_ext(void)
1909 {
1910         return get_dyn_SHLIBEXT();
1911 }
1912
1913 /*******************************************************************
1914  Given a filename - get its directory name
1915 ********************************************************************/
1916
1917 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1918                     const char **name)
1919 {
1920         char *p;
1921         ptrdiff_t len;
1922
1923         p = strrchr_m(dir, '/'); /* Find final '/', if any */
1924
1925         if (p == NULL) {
1926                 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1927                         return False;
1928                 }
1929                 if (name) {
1930                         *name = dir;
1931                 }
1932                 return True;
1933         }
1934
1935         len = p-dir;
1936
1937         if (!(*parent = (char *)TALLOC_MEMDUP(mem_ctx, dir, len+1))) {
1938                 return False;
1939         }
1940         (*parent)[len] = '\0';
1941
1942         if (name) {
1943                 *name = p+1;
1944         }
1945         return True;
1946 }
1947
1948 /*******************************************************************
1949  Determine if a pattern contains any Microsoft wildcard characters.
1950 *******************************************************************/
1951
1952 bool ms_has_wild(const char *s)
1953 {
1954         char c;
1955
1956         if (lp_posix_pathnames()) {
1957                 /* With posix pathnames no characters are wild. */
1958                 return False;
1959         }
1960
1961         while ((c = *s++)) {
1962                 switch (c) {
1963                 case '*':
1964                 case '?':
1965                 case '<':
1966                 case '>':
1967                 case '"':
1968                         return True;
1969                 }
1970         }
1971         return False;
1972 }
1973
1974 bool ms_has_wild_w(const smb_ucs2_t *s)
1975 {
1976         smb_ucs2_t c;
1977         if (!s) return False;
1978         while ((c = *s++)) {
1979                 switch (c) {
1980                 case UCS2_CHAR('*'):
1981                 case UCS2_CHAR('?'):
1982                 case UCS2_CHAR('<'):
1983                 case UCS2_CHAR('>'):
1984                 case UCS2_CHAR('"'):
1985                         return True;
1986                 }
1987         }
1988         return False;
1989 }
1990
1991 /*******************************************************************
1992  A wrapper that handles case sensitivity and the special handling
1993  of the ".." name.
1994 *******************************************************************/
1995
1996 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1997 {
1998         if (ISDOTDOT(string))
1999                 string = ".";
2000         if (ISDOT(pattern))
2001                 return False;
2002
2003         return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2004 }
2005
2006 /*******************************************************************
2007  A wrapper that handles case sensitivity and the special handling
2008  of the ".." name. Varient that is only called by old search code which requires
2009  pattern translation.
2010 *******************************************************************/
2011
2012 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
2013 {
2014         if (ISDOTDOT(string))
2015                 string = ".";
2016         if (ISDOT(pattern))
2017                 return False;
2018
2019         return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2020 }
2021
2022 /*******************************************************************
2023  A wrapper that handles a list of patters and calls mask_match()
2024  on each.  Returns True if any of the patterns match.
2025 *******************************************************************/
2026
2027 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
2028 {
2029        while (listLen-- > 0) {
2030                if (mask_match(string, *list++, is_case_sensitive))
2031                        return True;
2032        }
2033        return False;
2034 }
2035
2036 /*********************************************************
2037  Recursive routine that is called by unix_wild_match.
2038 *********************************************************/
2039
2040 static bool unix_do_match(const char *regexp, const char *str)
2041 {
2042         const char *p;
2043
2044         for( p = regexp; *p && *str; ) {
2045
2046                 switch(*p) {
2047                         case '?':
2048                                 str++;
2049                                 p++;
2050                                 break;
2051
2052                         case '*':
2053
2054                                 /*
2055                                  * Look for a character matching 
2056                                  * the one after the '*'.
2057                                  */
2058                                 p++;
2059                                 if(!*p)
2060                                         return true; /* Automatic match */
2061                                 while(*str) {
2062
2063                                         while(*str && (*p != *str))
2064                                                 str++;
2065
2066                                         /*
2067                                          * Patch from weidel@multichart.de. In the case of the regexp
2068                                          * '*XX*' we want to ensure there are at least 2 'X' characters
2069                                          * in the string after the '*' for a match to be made.
2070                                          */
2071
2072                                         {
2073                                                 int matchcount=0;
2074
2075                                                 /*
2076                                                  * Eat all the characters that match, but count how many there were.
2077                                                  */
2078
2079                                                 while(*str && (*p == *str)) {
2080                                                         str++;
2081                                                         matchcount++;
2082                                                 }
2083
2084                                                 /*
2085                                                  * Now check that if the regexp had n identical characters that
2086                                                  * matchcount had at least that many matches.
2087                                                  */
2088
2089                                                 while ( *(p+1) && (*(p+1) == *p)) {
2090                                                         p++;
2091                                                         matchcount--;
2092                                                 }
2093
2094                                                 if ( matchcount <= 0 )
2095                                                         return false;
2096                                         }
2097
2098                                         str--; /* We've eaten the match char after the '*' */
2099
2100                                         if(unix_do_match(p, str))
2101                                                 return true;
2102
2103                                         if(!*str)
2104                                                 return false;
2105                                         else
2106                                                 str++;
2107                                 }
2108                                 return false;
2109
2110                         default:
2111                                 if(*str != *p)
2112                                         return false;
2113                                 str++;
2114                                 p++;
2115                                 break;
2116                 }
2117         }
2118
2119         if(!*p && !*str)
2120                 return true;
2121
2122         if (!*p && str[0] == '.' && str[1] == 0)
2123                 return true;
2124
2125         if (!*str && *p == '?') {
2126                 while (*p == '?')
2127                         p++;
2128                 return(!*p);
2129         }
2130
2131         if(!*str && (*p == '*' && p[1] == '\0'))
2132                 return true;
2133
2134         return false;
2135 }
2136
2137 /*******************************************************************
2138  Simple case insensitive interface to a UNIX wildcard matcher.
2139  Returns True if match, False if not.
2140 *******************************************************************/
2141
2142 bool unix_wild_match(const char *pattern, const char *string)
2143 {
2144         TALLOC_CTX *ctx = talloc_stackframe();
2145         char *p2;
2146         char *s2;
2147         char *p;
2148         bool ret = false;
2149
2150         p2 = talloc_strdup(ctx,pattern);
2151         s2 = talloc_strdup(ctx,string);
2152         if (!p2 || !s2) {
2153                 TALLOC_FREE(ctx);
2154                 return false;
2155         }
2156         strlower_m(p2);
2157         strlower_m(s2);
2158
2159         /* Remove any *? and ** from the pattern as they are meaningless */
2160         for(p = p2; *p; p++) {
2161                 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
2162                         memmove(&p[1], &p[2], strlen(&p[2])+1);
2163                 }
2164         }
2165
2166         if (strequal(p2,"*")) {
2167                 TALLOC_FREE(ctx);
2168                 return true;
2169         }
2170
2171         ret = unix_do_match(p2, s2);
2172         TALLOC_FREE(ctx);
2173         return ret;
2174 }
2175
2176 /**********************************************************************
2177  Converts a name to a fully qualified domain name.
2178  Returns true if lookup succeeded, false if not (then fqdn is set to name)
2179  Note we deliberately use gethostbyname here, not getaddrinfo as we want
2180  to examine the h_aliases and I don't know how to do that with getaddrinfo.
2181 ***********************************************************************/
2182
2183 bool name_to_fqdn(fstring fqdn, const char *name)
2184 {
2185         char *full = NULL;
2186         struct hostent *hp = gethostbyname(name);
2187
2188         if (!hp || !hp->h_name || !*hp->h_name) {
2189                 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2190                 fstrcpy(fqdn, name);
2191                 return false;
2192         }
2193
2194         /* Find out if the fqdn is returned as an alias
2195          * to cope with /etc/hosts files where the first
2196          * name is not the fqdn but the short name */
2197         if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2198                 int i;
2199                 for (i = 0; hp->h_aliases[i]; i++) {
2200                         if (strchr_m(hp->h_aliases[i], '.')) {
2201                                 full = hp->h_aliases[i];
2202                                 break;
2203                         }
2204                 }
2205         }
2206         if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2207                 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2208                 DEBUGADD(1, ("    Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2209                 DEBUGADD(1, ("    to Kerberos authentication problems as localhost.localdomain\n"));
2210                 DEBUGADD(1, ("    may end up being used instead of the real machine FQDN.\n"));
2211                 full = hp->h_name;
2212         }
2213         if (!full) {
2214                 full = hp->h_name;
2215         }
2216
2217         DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2218         fstrcpy(fqdn, full);
2219         return true;
2220 }
2221
2222 /**********************************************************************
2223  Append a DATA_BLOB to a talloc'ed object
2224 ***********************************************************************/
2225
2226 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
2227 {
2228         size_t old_size = 0;
2229         char *result;
2230
2231         if (blob.length == 0) {
2232                 return buf;
2233         }
2234
2235         if (buf != NULL) {
2236                 old_size = talloc_get_size(buf);
2237         }
2238
2239         result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
2240         if (result == NULL) {
2241                 return NULL;
2242         }
2243
2244         memcpy(result + old_size, blob.data, blob.length);
2245         return result;
2246 }
2247
2248 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2249 {
2250         switch (share_access & ~FILE_SHARE_DELETE) {
2251                 case FILE_SHARE_NONE:
2252                         return DENY_ALL;
2253                 case FILE_SHARE_READ:
2254                         return DENY_WRITE;
2255                 case FILE_SHARE_WRITE:
2256                         return DENY_READ;
2257                 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2258                         return DENY_NONE;
2259         }
2260         if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2261                 return DENY_DOS;
2262         } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2263                 return DENY_FCB;
2264         }
2265
2266         return (uint32)-1;
2267 }
2268
2269 pid_t procid_to_pid(const struct server_id *proc)
2270 {
2271         return proc->pid;
2272 }
2273
2274 static uint32 my_vnn = NONCLUSTER_VNN;
2275
2276 void set_my_vnn(uint32 vnn)
2277 {
2278         DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
2279         my_vnn = vnn;
2280 }
2281
2282 uint32 get_my_vnn(void)
2283 {
2284         return my_vnn;
2285 }
2286
2287 static uint64_t my_unique_id = 0;
2288
2289 void set_my_unique_id(uint64_t unique_id)
2290 {
2291         my_unique_id = unique_id;
2292 }
2293
2294 struct server_id pid_to_procid(pid_t pid)
2295 {
2296         struct server_id result;
2297         result.pid = pid;
2298         result.unique_id = my_unique_id;
2299         result.vnn = my_vnn;
2300         return result;
2301 }
2302
2303 struct server_id procid_self(void)
2304 {
2305         return pid_to_procid(sys_getpid());
2306 }
2307
2308 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
2309 {
2310         if (p1->pid != p2->pid)
2311                 return False;
2312         if (p1->vnn != p2->vnn)
2313                 return False;
2314         return True;
2315 }
2316
2317 bool cluster_id_equal(const struct server_id *id1,
2318                       const struct server_id *id2)
2319 {
2320         return procid_equal(id1, id2);
2321 }
2322
2323 bool procid_is_me(const struct server_id *pid)
2324 {
2325         if (pid->pid != sys_getpid())
2326                 return False;
2327         if (pid->vnn != my_vnn)
2328                 return False;
2329         return True;
2330 }
2331
2332 struct server_id interpret_pid(const char *pid_string)
2333 {
2334         struct server_id result;
2335         int pid;
2336         unsigned int vnn;
2337         if (sscanf(pid_string, "%u:%d", &vnn, &pid) == 2) {
2338                 result.vnn = vnn;
2339                 result.pid = pid;
2340         }
2341         else if (sscanf(pid_string, "%d", &pid) == 1) {
2342                 result.vnn = get_my_vnn();
2343                 result.pid = pid;
2344         }
2345         else {
2346                 result.vnn = NONCLUSTER_VNN;
2347                 result.pid = -1;
2348         }
2349         /* Assigning to result.pid may have overflowed
2350            Map negative pid to -1: i.e. error */
2351         if (result.pid < 0) {
2352                 result.pid = -1;
2353         }
2354         result.unique_id = 0;
2355         return result;
2356 }
2357
2358 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
2359 {
2360         if (pid->vnn == NONCLUSTER_VNN) {
2361                 return talloc_asprintf(mem_ctx,
2362                                 "%d",
2363                                 (int)pid->pid);
2364         }
2365         else {
2366                 return talloc_asprintf(mem_ctx,
2367                                         "%u:%d",
2368                                         (unsigned)pid->vnn,
2369                                         (int)pid->pid);
2370         }
2371 }
2372
2373 char *procid_str_static(const struct server_id *pid)
2374 {
2375         return procid_str(talloc_tos(), pid);
2376 }
2377
2378 bool procid_valid(const struct server_id *pid)
2379 {
2380         return (pid->pid != -1);
2381 }
2382
2383 bool procid_is_local(const struct server_id *pid)
2384 {
2385         return pid->vnn == my_vnn;
2386 }
2387
2388 /****************************************************************
2389  Check if offset/length fit into bufsize. Should probably be
2390  merged with is_offset_safe, but this would require a rewrite
2391  of lanman.c. Later :-)
2392 ****************************************************************/
2393
2394 bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
2395 {
2396         if ((offset + length < offset) || (offset + length < length)) {
2397                 /* wrap */
2398                 return true;
2399         }
2400         if ((offset > bufsize) || (offset + length > bufsize)) {
2401                 /* overflow */
2402                 return true;
2403         }
2404         return false;
2405 }
2406
2407 /****************************************************************
2408  Check if an offset into a buffer is safe.
2409  If this returns True it's safe to indirect into the byte at
2410  pointer ptr+off.
2411 ****************************************************************/
2412
2413 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2414 {
2415         const char *end_base = buf_base + buf_len;
2416         char *end_ptr = ptr + off;
2417
2418         if (!buf_base || !ptr) {
2419                 return False;
2420         }
2421
2422         if (end_base < buf_base || end_ptr < ptr) {
2423                 return False; /* wrap. */
2424         }
2425
2426         if (end_ptr < end_base) {
2427                 return True;
2428         }
2429         return False;
2430 }
2431
2432 /****************************************************************
2433  Return a safe pointer into a buffer, or NULL.
2434 ****************************************************************/
2435
2436 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2437 {
2438         return is_offset_safe(buf_base, buf_len, ptr, off) ?
2439                         ptr + off : NULL;
2440 }
2441
2442 /****************************************************************
2443  Return a safe pointer into a string within a buffer, or NULL.
2444 ****************************************************************/
2445
2446 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2447 {
2448         if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2449                 return NULL;
2450         }
2451         /* Check if a valid string exists at this offset. */
2452         if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2453                 return NULL;
2454         }
2455         return ptr + off;
2456 }
2457
2458 /****************************************************************
2459  Return an SVAL at a pointer, or failval if beyond the end.
2460 ****************************************************************/
2461
2462 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2463 {
2464         /*
2465          * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2466          * NOT ptr[2].
2467          */
2468         if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2469                 return failval;
2470         }
2471         return SVAL(ptr,off);
2472 }
2473
2474 /****************************************************************
2475  Return an IVAL at a pointer, or failval if beyond the end.
2476 ****************************************************************/
2477
2478 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2479 {
2480         /*
2481          * Note we use off+3 here, not off+4 as IVAL accesses 
2482          * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2483          */
2484         if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2485                 return failval;
2486         }
2487         return IVAL(ptr,off);
2488 }
2489
2490 /****************************************************************
2491  Split DOM\user into DOM and user. Do not mix with winbind variants of that
2492  call (they take care of winbind separator and other winbind specific settings).
2493 ****************************************************************/
2494
2495 void split_domain_user(TALLOC_CTX *mem_ctx,
2496                        const char *full_name,
2497                        char **domain,
2498                        char **user)
2499 {
2500         const char *p = NULL;
2501
2502         p = strchr_m(full_name, '\\');
2503
2504         if (p != NULL) {
2505                 *domain = talloc_strndup(mem_ctx, full_name,
2506                                          PTR_DIFF(p, full_name));
2507                 *user = talloc_strdup(mem_ctx, p+1);
2508         } else {
2509                 *domain = talloc_strdup(mem_ctx, "");
2510                 *user = talloc_strdup(mem_ctx, full_name);
2511         }
2512 }
2513
2514 #if 0
2515
2516 Disable these now we have checked all code paths and ensured
2517 NULL returns on zero request. JRA.
2518
2519 /****************************************************************
2520  talloc wrapper functions that guarentee a null pointer return
2521  if size == 0.
2522 ****************************************************************/
2523
2524 #ifndef MAX_TALLOC_SIZE
2525 #define MAX_TALLOC_SIZE 0x10000000
2526 #endif
2527
2528 /*
2529  *    talloc and zero memory.
2530  *    - returns NULL if size is zero.
2531  */
2532
2533 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
2534 {
2535         void *p;
2536
2537         if (size == 0) {
2538                 return NULL;
2539         }
2540
2541         p = talloc_named_const(ctx, size, name);
2542
2543         if (p) {
2544                 memset(p, '\0', size);
2545         }
2546
2547         return p;
2548 }
2549
2550 /*
2551  *   memdup with a talloc.
2552  *   - returns NULL if size is zero.
2553  */
2554
2555 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
2556 {
2557         void *newp;
2558
2559         if (size == 0) {
2560                 return NULL;
2561         }
2562
2563         newp = talloc_named_const(t, size, name);
2564         if (newp) {
2565                 memcpy(newp, p, size);
2566         }
2567
2568         return newp;
2569 }
2570
2571 /*
2572  *   alloc an array, checking for integer overflow in the array size.
2573  *   - returns NULL if count or el_size are zero.
2574  */
2575
2576 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
2577 {
2578         if (count >= MAX_TALLOC_SIZE/el_size) {
2579                 return NULL;
2580         }
2581
2582         if (el_size == 0 || count == 0) {
2583                 return NULL;
2584         }
2585
2586         return talloc_named_const(ctx, el_size * count, name);
2587 }
2588
2589 /*
2590  *   alloc an zero array, checking for integer overflow in the array size
2591  *   - returns NULL if count or el_size are zero.
2592  */
2593
2594 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
2595 {
2596         if (count >= MAX_TALLOC_SIZE/el_size) {
2597                 return NULL;
2598         }
2599
2600         if (el_size == 0 || count == 0) {
2601                 return NULL;
2602         }
2603
2604         return _talloc_zero(ctx, el_size * count, name);
2605 }
2606
2607 /*
2608  *   Talloc wrapper that returns NULL if size == 0.
2609  */
2610 void *talloc_zeronull(const void *context, size_t size, const char *name)
2611 {
2612         if (size == 0) {
2613                 return NULL;
2614         }
2615         return talloc_named_const(context, size, name);
2616 }
2617 #endif
2618
2619 /****************************************************************
2620  strip off leading '\\' from a hostname
2621 ****************************************************************/
2622
2623 const char *strip_hostname(const char *s)
2624 {
2625         if (!s) {
2626                 return NULL;
2627         }
2628
2629         if (strlen_m(s) < 3) {
2630                 return s;
2631         }
2632
2633         if (s[0] == '\\') s++;
2634         if (s[0] == '\\') s++;
2635
2636         return s;
2637 }
2638
2639 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2640                               struct tevent_context *ev,
2641                               NTSTATUS *status)
2642 {
2643         bool ret = tevent_req_poll(req, ev);
2644         if (!ret) {
2645                 *status = map_nt_error_from_unix(errno);
2646         }
2647         return ret;
2648 }
2649
2650 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2651 {
2652         if (!NT_STATUS_IS_OK(err1)) {
2653                 *result = err1;
2654                 return true;
2655         }
2656         if (!NT_STATUS_IS_OK(err2)) {
2657                 *result = err2;
2658                 return true;
2659         }
2660         return false;
2661 }
2662
2663 int timeval_to_msec(struct timeval t)
2664 {
2665         return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2666 }
2667
2668 /*******************************************************************
2669  Check a given DOS pathname is valid for a share.
2670 ********************************************************************/
2671
2672 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2673 {
2674         char *ptr = NULL;
2675
2676         if (!dos_pathname) {
2677                 return NULL;
2678         }
2679
2680         ptr = talloc_strdup(ctx, dos_pathname);
2681         if (!ptr) {
2682                 return NULL;
2683         }
2684         /* Convert any '\' paths to '/' */
2685         unix_format(ptr);
2686         ptr = unix_clean_name(ctx, ptr);
2687         if (!ptr) {
2688                 return NULL;
2689         }
2690
2691         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2692         if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2693                 ptr += 2;
2694
2695         /* Only absolute paths allowed. */
2696         if (*ptr != '/')
2697                 return NULL;
2698
2699         return ptr;
2700 }