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