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