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