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