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