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