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