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