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