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