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