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