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