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