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