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