Add free_local_machine_name().
[ira/wip.git] / source / 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 ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t),
909                                                 ssize_t (*write_fn)(int, const void *, size_t))
910 {
911         char *buf;
912         size_t total = 0;
913         ssize_t read_ret;
914         ssize_t write_ret;
915         size_t num_to_read_thistime;
916         size_t num_written = 0;
917
918         if ((buf = SMB_MALLOC_ARRAY(char, TRANSFER_BUF_SIZE)) == NULL)
919                 return -1;
920
921         while (total < n) {
922                 num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
923
924                 read_ret = (*read_fn)(infd, buf, num_to_read_thistime);
925                 if (read_ret == -1) {
926                         DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) ));
927                         SAFE_FREE(buf);
928                         return -1;
929                 }
930                 if (read_ret == 0)
931                         break;
932
933                 num_written = 0;
934  
935                 while (num_written < read_ret) {
936                         write_ret = (*write_fn)(outfd,buf + num_written, read_ret - num_written);
937  
938                         if (write_ret == -1) {
939                                 DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) ));
940                                 SAFE_FREE(buf);
941                                 return -1;
942                         }
943                         if (write_ret == 0)
944                                 return (ssize_t)total;
945  
946                         num_written += (size_t)write_ret;
947                 }
948
949                 total += (size_t)read_ret;
950         }
951
952         SAFE_FREE(buf);
953         return (ssize_t)total;          
954 }
955
956 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
957 {
958         return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, sys_read, sys_write);
959 }
960
961 /*******************************************************************
962  Sleep for a specified number of milliseconds.
963 ********************************************************************/
964
965 void smb_msleep(unsigned int t)
966 {
967 #if defined(HAVE_NANOSLEEP)
968         struct timespec tval;
969         int ret;
970
971         tval.tv_sec = t/1000;
972         tval.tv_nsec = 1000000*(t%1000);
973
974         do {
975                 errno = 0;
976                 ret = nanosleep(&tval, &tval);
977         } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
978 #else
979         unsigned int tdiff=0;
980         struct timeval tval,t1,t2;  
981         fd_set fds;
982
983         GetTimeOfDay(&t1);
984         t2 = t1;
985   
986         while (tdiff < t) {
987                 tval.tv_sec = (t-tdiff)/1000;
988                 tval.tv_usec = 1000*((t-tdiff)%1000);
989
990                 /* Never wait for more than 1 sec. */
991                 if (tval.tv_sec > 1) {
992                         tval.tv_sec = 1; 
993                         tval.tv_usec = 0;
994                 }
995
996                 FD_ZERO(&fds);
997                 errno = 0;
998                 sys_select_intr(0,&fds,NULL,NULL,&tval);
999
1000                 GetTimeOfDay(&t2);
1001                 if (t2.tv_sec < t1.tv_sec) {
1002                         /* Someone adjusted time... */
1003                         t1 = t2;
1004                 }
1005
1006                 tdiff = TvalDiff(&t1,&t2);
1007         }
1008 #endif
1009 }
1010
1011 /****************************************************************************
1012  Become a daemon, discarding the controlling terminal.
1013 ****************************************************************************/
1014
1015 void become_daemon(bool Fork, bool no_process_group)
1016 {
1017         if (Fork) {
1018                 if (sys_fork()) {
1019                         _exit(0);
1020                 }
1021         }
1022
1023   /* detach from the terminal */
1024 #ifdef HAVE_SETSID
1025         if (!no_process_group) setsid();
1026 #elif defined(TIOCNOTTY)
1027         if (!no_process_group) {
1028                 int i = sys_open("/dev/tty", O_RDWR, 0);
1029                 if (i != -1) {
1030                         ioctl(i, (int) TIOCNOTTY, (char *)0);      
1031                         close(i);
1032                 }
1033         }
1034 #endif /* HAVE_SETSID */
1035
1036         /* Close fd's 0,1,2. Needed if started by rsh */
1037         close_low_fds(False);  /* Don't close stderr, let the debug system
1038                                   attach it to the logfile */
1039 }
1040
1041 /****************************************************************************
1042  Put up a yes/no prompt.
1043 ****************************************************************************/
1044
1045 bool yesno(const char *p)
1046 {
1047         char ans[20];
1048         printf("%s",p);
1049
1050         if (!fgets(ans,sizeof(ans)-1,stdin))
1051                 return(False);
1052
1053         if (*ans == 'y' || *ans == 'Y')
1054                 return(True);
1055
1056         return(False);
1057 }
1058
1059 #if defined(PARANOID_MALLOC_CHECKER)
1060
1061 /****************************************************************************
1062  Internal malloc wrapper. Externally visible.
1063 ****************************************************************************/
1064
1065 void *malloc_(size_t size)
1066 {
1067         if (size == 0) {
1068                 return NULL;
1069         }
1070 #undef malloc
1071         return malloc(size);
1072 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
1073 }
1074
1075 /****************************************************************************
1076  Internal calloc wrapper. Not externally visible.
1077 ****************************************************************************/
1078
1079 static void *calloc_(size_t count, size_t size)
1080 {
1081         if (size == 0 || count == 0) {
1082                 return NULL;
1083         }
1084 #undef calloc
1085         return calloc(count, size);
1086 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
1087 }
1088
1089 /****************************************************************************
1090  Internal realloc wrapper. Not externally visible.
1091 ****************************************************************************/
1092
1093 static void *realloc_(void *ptr, size_t size)
1094 {
1095 #undef realloc
1096         return realloc(ptr, size);
1097 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
1098 }
1099
1100 #endif /* PARANOID_MALLOC_CHECKER */
1101
1102 /****************************************************************************
1103  Type-safe malloc.
1104 ****************************************************************************/
1105
1106 void *malloc_array(size_t el_size, unsigned int count)
1107 {
1108         if (count >= MAX_ALLOC_SIZE/el_size) {
1109                 return NULL;
1110         }
1111
1112         if (el_size == 0 || count == 0) {
1113                 return NULL;
1114         }
1115 #if defined(PARANOID_MALLOC_CHECKER)
1116         return malloc_(el_size*count);
1117 #else
1118         return malloc(el_size*count);
1119 #endif
1120 }
1121
1122 /****************************************************************************
1123  Type-safe memalign
1124 ****************************************************************************/
1125
1126 void *memalign_array(size_t el_size, size_t align, unsigned int count)
1127 {
1128         if (count >= MAX_ALLOC_SIZE/el_size) {
1129                 return NULL;
1130         }
1131
1132         return sys_memalign(align, el_size*count);
1133 }
1134
1135 /****************************************************************************
1136  Type-safe calloc.
1137 ****************************************************************************/
1138
1139 void *calloc_array(size_t size, size_t nmemb)
1140 {
1141         if (nmemb >= MAX_ALLOC_SIZE/size) {
1142                 return NULL;
1143         }
1144         if (size == 0 || nmemb == 0) {
1145                 return NULL;
1146         }
1147 #if defined(PARANOID_MALLOC_CHECKER)
1148         return calloc_(nmemb, size);
1149 #else
1150         return calloc(nmemb, size);
1151 #endif
1152 }
1153
1154 /****************************************************************************
1155  Expand a pointer to be a particular size.
1156  Note that this version of Realloc has an extra parameter that decides
1157  whether to free the passed in storage on allocation failure or if the
1158  new size is zero.
1159
1160  This is designed for use in the typical idiom of :
1161
1162  p = SMB_REALLOC(p, size)
1163  if (!p) {
1164     return error;
1165  }
1166
1167  and not to have to keep track of the old 'p' contents to free later, nor
1168  to worry if the size parameter was zero. In the case where NULL is returned
1169  we guarentee that p has been freed.
1170
1171  If free later semantics are desired, then pass 'free_old_on_error' as False which
1172  guarentees that the old contents are not freed on error, even if size == 0. To use
1173  this idiom use :
1174
1175  tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
1176  if (!tmp) {
1177     SAFE_FREE(p);
1178     return error;
1179  } else {
1180     p = tmp;
1181  }
1182
1183  Changes were instigated by Coverity error checking. JRA.
1184 ****************************************************************************/
1185
1186 void *Realloc(void *p, size_t size, bool free_old_on_error)
1187 {
1188         void *ret=NULL;
1189
1190         if (size == 0) {
1191                 if (free_old_on_error) {
1192                         SAFE_FREE(p);
1193                 }
1194                 DEBUG(2,("Realloc asked for 0 bytes\n"));
1195                 return NULL;
1196         }
1197
1198 #if defined(PARANOID_MALLOC_CHECKER)
1199         if (!p) {
1200                 ret = (void *)malloc_(size);
1201         } else {
1202                 ret = (void *)realloc_(p,size);
1203         }
1204 #else
1205         if (!p) {
1206                 ret = (void *)malloc(size);
1207         } else {
1208                 ret = (void *)realloc(p,size);
1209         }
1210 #endif
1211
1212         if (!ret) {
1213                 if (free_old_on_error && p) {
1214                         SAFE_FREE(p);
1215                 }
1216                 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1217         }
1218
1219         return(ret);
1220 }
1221
1222 /****************************************************************************
1223  Type-safe realloc.
1224 ****************************************************************************/
1225
1226 void *realloc_array(void *p, size_t el_size, unsigned int count, bool free_old_on_error)
1227 {
1228         if (count >= MAX_ALLOC_SIZE/el_size) {
1229                 if (free_old_on_error) {
1230                         SAFE_FREE(p);
1231                 }
1232                 return NULL;
1233         }
1234         return Realloc(p, el_size*count, free_old_on_error);
1235 }
1236
1237 /****************************************************************************
1238  (Hopefully) efficient array append.
1239 ****************************************************************************/
1240
1241 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1242                         void *element, void *_array, uint32 *num_elements,
1243                         ssize_t *array_size)
1244 {
1245         void **array = (void **)_array;
1246
1247         if (*array_size < 0) {
1248                 return;
1249         }
1250
1251         if (*array == NULL) {
1252                 if (*array_size == 0) {
1253                         *array_size = 128;
1254                 }
1255
1256                 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1257                         goto error;
1258                 }
1259
1260                 *array = TALLOC(mem_ctx, element_size * (*array_size));
1261                 if (*array == NULL) {
1262                         goto error;
1263                 }
1264         }
1265
1266         if (*num_elements == *array_size) {
1267                 *array_size *= 2;
1268
1269                 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1270                         goto error;
1271                 }
1272
1273                 *array = TALLOC_REALLOC(mem_ctx, *array,
1274                                         element_size * (*array_size));
1275
1276                 if (*array == NULL) {
1277                         goto error;
1278                 }
1279         }
1280
1281         memcpy((char *)(*array) + element_size*(*num_elements),
1282                element, element_size);
1283         *num_elements += 1;
1284
1285         return;
1286
1287  error:
1288         *num_elements = 0;
1289         *array_size = -1;
1290 }
1291
1292 /****************************************************************************
1293  Free memory, checks for NULL.
1294  Use directly SAFE_FREE()
1295  Exists only because we need to pass a function pointer somewhere --SSS
1296 ****************************************************************************/
1297
1298 void safe_free(void *p)
1299 {
1300         SAFE_FREE(p);
1301 }
1302
1303 /****************************************************************************
1304  Get my own name and IP.
1305 ****************************************************************************/
1306
1307 char *get_myname(TALLOC_CTX *ctx)
1308 {
1309         char *p;
1310         char hostname[HOST_NAME_MAX];
1311
1312         *hostname = 0;
1313
1314         /* get my host name */
1315         if (gethostname(hostname, sizeof(hostname)) == -1) {
1316                 DEBUG(0,("gethostname failed\n"));
1317                 return False;
1318         }
1319
1320         /* Ensure null termination. */
1321         hostname[sizeof(hostname)-1] = '\0';
1322
1323         /* split off any parts after an initial . */
1324         p = strchr_m(hostname,'.');
1325         if (p) {
1326                 *p = 0;
1327         }
1328
1329         return talloc_strdup(ctx, hostname);
1330 }
1331
1332 /****************************************************************************
1333  Get my own domain name, or "" if we have none.
1334 ****************************************************************************/
1335
1336 char *get_mydnsdomname(TALLOC_CTX *ctx)
1337 {
1338         const char *domname;
1339         char *p;
1340
1341         domname = get_mydnsfullname();
1342         if (!domname) {
1343                 return NULL;
1344         }
1345
1346         p = strchr_m(domname, '.');
1347         if (p) {
1348                 p++;
1349                 return talloc_strdup(ctx, p);
1350         } else {
1351                 return talloc_strdup(ctx, "");
1352         }
1353 }
1354
1355 /****************************************************************************
1356  Interpret a protocol description string, with a default.
1357 ****************************************************************************/
1358
1359 int interpret_protocol(const char *str,int def)
1360 {
1361         if (strequal(str,"NT1"))
1362                 return(PROTOCOL_NT1);
1363         if (strequal(str,"LANMAN2"))
1364                 return(PROTOCOL_LANMAN2);
1365         if (strequal(str,"LANMAN1"))
1366                 return(PROTOCOL_LANMAN1);
1367         if (strequal(str,"CORE"))
1368                 return(PROTOCOL_CORE);
1369         if (strequal(str,"COREPLUS"))
1370                 return(PROTOCOL_COREPLUS);
1371         if (strequal(str,"CORE+"))
1372                 return(PROTOCOL_COREPLUS);
1373   
1374         DEBUG(0,("Unrecognised protocol level %s\n",str));
1375   
1376         return(def);
1377 }
1378
1379
1380 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1381 /******************************************************************
1382  Remove any mount options such as -rsize=2048,wsize=2048 etc.
1383  Based on a fix from <Thomas.Hepper@icem.de>.
1384  Returns a malloc'ed string.
1385 *******************************************************************/
1386
1387 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
1388 {
1389         if (*str == '-') {
1390                 const char *p = str;
1391                 while(*p && !isspace(*p))
1392                         p++;
1393                 while(*p && isspace(*p))
1394                         p++;
1395                 if(*p) {
1396                         return talloc_strdup(ctx, p);
1397                 }
1398         }
1399         return NULL;
1400 }
1401
1402 /*******************************************************************
1403  Patch from jkf@soton.ac.uk
1404  Split Luke's automount_server into YP lookup and string splitter
1405  so can easily implement automount_path().
1406  Returns a malloc'ed string.
1407 *******************************************************************/
1408
1409 #ifdef WITH_NISPLUS_HOME
1410 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1411 {
1412         char *value = NULL;
1413
1414         char *nis_map = (char *)lp_nis_home_map_name();
1415
1416         char buffer[NIS_MAXATTRVAL + 1];
1417         nis_result *result;
1418         nis_object *object;
1419         entry_obj  *entry;
1420
1421         snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
1422         DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1423
1424         if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1425                 if (result->status != NIS_SUCCESS) {
1426                         DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1427                 } else {
1428                         object = result->objects.objects_val;
1429                         if (object->zo_data.zo_type == ENTRY_OBJ) {
1430                                 entry = &object->zo_data.objdata_u.en_data;
1431                                 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1432                                 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1433
1434                                 value = talloc_strdup(ctx,
1435                                                 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1436                                 if (!value) {
1437                                         nis_freeresult(result);
1438                                         return NULL;
1439                                 }
1440                                 value = talloc_string_sub(ctx,
1441                                                 value,
1442                                                 "&",
1443                                                 user_name);
1444                         }
1445                 }
1446         }
1447         nis_freeresult(result);
1448
1449         if (value) {
1450                 value = strip_mount_options(ctx, value);
1451                 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
1452                                         user_name, value));
1453         }
1454         return value;
1455 }
1456 #else /* WITH_NISPLUS_HOME */
1457
1458 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1459 {
1460         char *value = NULL;
1461
1462         int nis_error;        /* returned by yp all functions */
1463         char *nis_result;     /* yp_match inits this */
1464         int nis_result_len;  /* and set this */
1465         char *nis_domain;     /* yp_get_default_domain inits this */
1466         char *nis_map = (char *)lp_nis_home_map_name();
1467
1468         if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1469                 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1470                 return NULL;
1471         }
1472
1473         DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1474
1475         if ((nis_error = yp_match(nis_domain, nis_map, user_name,
1476                                         strlen(user_name), &nis_result,
1477                                         &nis_result_len)) == 0) {
1478                 value = talloc_strdup(ctx, nis_result);
1479                 if (!value) {
1480                         return NULL;
1481                 }
1482                 value = strip_mount_options(ctx, value);
1483         } else if(nis_error == YPERR_KEY) {
1484                 DEBUG(3, ("YP Key not found:  while looking up \"%s\" in map \"%s\"\n", 
1485                                 user_name, nis_map));
1486                 DEBUG(3, ("using defaults for server and home directory\n"));
1487         } else {
1488                 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", 
1489                                 yperr_string(nis_error), user_name, nis_map));
1490         }
1491
1492         if (value) {
1493                 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
1494         }
1495         return value;
1496 }
1497 #endif /* WITH_NISPLUS_HOME */
1498 #endif
1499
1500 /****************************************************************************
1501  Check if a process exists. Does this work on all unixes?
1502 ****************************************************************************/
1503
1504 bool process_exists(const struct server_id pid)
1505 {
1506         if (procid_is_me(&pid)) {
1507                 return True;
1508         }
1509
1510         if (procid_is_local(&pid)) {
1511                 return (kill(pid.pid,0) == 0 || errno != ESRCH);
1512         }
1513
1514 #ifdef CLUSTER_SUPPORT
1515         return ctdbd_process_exists(messaging_ctdbd_connection(), pid.vnn,
1516                                     pid.pid);
1517 #else
1518         return False;
1519 #endif
1520 }
1521
1522 bool process_exists_by_pid(pid_t pid)
1523 {
1524         /* Doing kill with a non-positive pid causes messages to be
1525          * sent to places we don't want. */
1526         SMB_ASSERT(pid > 0);
1527         return(kill(pid,0) == 0 || errno != ESRCH);
1528 }
1529
1530 /*******************************************************************
1531  Convert a uid into a user name.
1532 ********************************************************************/
1533
1534 const char *uidtoname(uid_t uid)
1535 {
1536         TALLOC_CTX *ctx = talloc_tos();
1537         char *name = NULL;
1538         struct passwd *pass = NULL;
1539
1540         pass = getpwuid_alloc(ctx,uid);
1541         if (pass) {
1542                 name = talloc_strdup(ctx,pass->pw_name);
1543                 TALLOC_FREE(pass);
1544         } else {
1545                 name = talloc_asprintf(ctx,
1546                                 "%ld",
1547                                 (long int)uid);
1548         }
1549         return name;
1550 }
1551
1552 /*******************************************************************
1553  Convert a gid into a group name.
1554 ********************************************************************/
1555
1556 char *gidtoname(gid_t gid)
1557 {
1558         struct group *grp;
1559
1560         grp = getgrgid(gid);
1561         if (grp) {
1562                 return talloc_strdup(talloc_tos(), grp->gr_name);
1563         }
1564         else {
1565                 return talloc_asprintf(talloc_tos(),
1566                                         "%d",
1567                                         (int)gid);
1568         }
1569 }
1570
1571 /*******************************************************************
1572  Convert a user name into a uid.
1573 ********************************************************************/
1574
1575 uid_t nametouid(const char *name)
1576 {
1577         struct passwd *pass;
1578         char *p;
1579         uid_t u;
1580
1581         pass = getpwnam_alloc(NULL, name);
1582         if (pass) {
1583                 u = pass->pw_uid;
1584                 TALLOC_FREE(pass);
1585                 return u;
1586         }
1587
1588         u = (uid_t)strtol(name, &p, 0);
1589         if ((p != name) && (*p == '\0'))
1590                 return u;
1591
1592         return (uid_t)-1;
1593 }
1594
1595 /*******************************************************************
1596  Convert a name to a gid_t if possible. Return -1 if not a group. 
1597 ********************************************************************/
1598
1599 gid_t nametogid(const char *name)
1600 {
1601         struct group *grp;
1602         char *p;
1603         gid_t g;
1604
1605         g = (gid_t)strtol(name, &p, 0);
1606         if ((p != name) && (*p == '\0'))
1607                 return g;
1608
1609         grp = sys_getgrnam(name);
1610         if (grp)
1611                 return(grp->gr_gid);
1612         return (gid_t)-1;
1613 }
1614
1615 /*******************************************************************
1616  Something really nasty happened - panic !
1617 ********************************************************************/
1618
1619 void smb_panic(const char *const why)
1620 {
1621         char *cmd;
1622         int result;
1623
1624 #ifdef DEVELOPER
1625         {
1626
1627                 if (global_clobber_region_function) {
1628                         DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1629                                          global_clobber_region_function,
1630                                          global_clobber_region_line));
1631                 } 
1632         }
1633 #endif
1634
1635         DEBUG(0,("PANIC (pid %llu): %s\n",
1636                     (unsigned long long)sys_getpid(), why));
1637         log_stack_trace();
1638
1639         cmd = lp_panic_action();
1640         if (cmd && *cmd) {
1641                 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1642                 result = system(cmd);
1643
1644                 if (result == -1)
1645                         DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1646                                           strerror(errno)));
1647                 else
1648                         DEBUG(0, ("smb_panic(): action returned status %d\n",
1649                                           WEXITSTATUS(result)));
1650         }
1651
1652         dump_core();
1653 }
1654
1655 /*******************************************************************
1656  Print a backtrace of the stack to the debug log. This function
1657  DELIBERATELY LEAKS MEMORY. The expectation is that you should
1658  exit shortly after calling it.
1659 ********************************************************************/
1660
1661 #ifdef HAVE_LIBUNWIND_H
1662 #include <libunwind.h>
1663 #endif
1664
1665 #ifdef HAVE_EXECINFO_H
1666 #include <execinfo.h>
1667 #endif
1668
1669 #ifdef HAVE_LIBEXC_H
1670 #include <libexc.h>
1671 #endif
1672
1673 void log_stack_trace(void)
1674 {
1675 #ifdef HAVE_LIBUNWIND
1676         /* Try to use libunwind before any other technique since on ia64
1677          * libunwind correctly walks the stack in more circumstances than
1678          * backtrace.
1679          */ 
1680         unw_cursor_t cursor;
1681         unw_context_t uc;
1682         unsigned i = 0;
1683
1684         char procname[256];
1685         unw_word_t ip, sp, off;
1686
1687         procname[sizeof(procname) - 1] = '\0';
1688
1689         if (unw_getcontext(&uc) != 0) {
1690                 goto libunwind_failed;
1691         }
1692
1693         if (unw_init_local(&cursor, &uc) != 0) {
1694                 goto libunwind_failed;
1695         }
1696
1697         DEBUG(0, ("BACKTRACE:\n"));
1698
1699         do {
1700             ip = sp = 0;
1701             unw_get_reg(&cursor, UNW_REG_IP, &ip);
1702             unw_get_reg(&cursor, UNW_REG_SP, &sp);
1703
1704             switch (unw_get_proc_name(&cursor,
1705                         procname, sizeof(procname) - 1, &off) ) {
1706             case 0:
1707                     /* Name found. */
1708             case -UNW_ENOMEM:
1709                     /* Name truncated. */
1710                     DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1711                             i, procname, (long long)off,
1712                             (long long)ip, (long long) sp));
1713                     break;
1714             default:
1715             /* case -UNW_ENOINFO: */
1716             /* case -UNW_EUNSPEC: */
1717                     /* No symbol name found. */
1718                     DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1719                             i, "<unknown symbol>",
1720                             (long long)ip, (long long) sp));
1721             }
1722             ++i;
1723         } while (unw_step(&cursor) > 0);
1724
1725         return;
1726
1727 libunwind_failed:
1728         DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1729
1730 #elif HAVE_BACKTRACE_SYMBOLS
1731         void *backtrace_stack[BACKTRACE_STACK_SIZE];
1732         size_t backtrace_size;
1733         char **backtrace_strings;
1734
1735         /* get the backtrace (stack frames) */
1736         backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1737         backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1738
1739         DEBUG(0, ("BACKTRACE: %lu stack frames:\n", 
1740                   (unsigned long)backtrace_size));
1741         
1742         if (backtrace_strings) {
1743                 int i;
1744
1745                 for (i = 0; i < backtrace_size; i++)
1746                         DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1747
1748                 /* Leak the backtrace_strings, rather than risk what free() might do */
1749         }
1750
1751 #elif HAVE_LIBEXC
1752
1753         /* The IRIX libexc library provides an API for unwinding the stack. See
1754          * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1755          * since we are about to abort anyway, it hardly matters.
1756          */
1757
1758 #define NAMESIZE 32 /* Arbitrary */
1759
1760         __uint64_t      addrs[BACKTRACE_STACK_SIZE];
1761         char *          names[BACKTRACE_STACK_SIZE];
1762         char            namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1763
1764         int             i;
1765         int             levels;
1766
1767         ZERO_ARRAY(addrs);
1768         ZERO_ARRAY(names);
1769         ZERO_ARRAY(namebuf);
1770
1771         /* We need to be root so we can open our /proc entry to walk
1772          * our stack. It also helps when we want to dump core.
1773          */
1774         become_root();
1775
1776         for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1777                 names[i] = namebuf + (i * NAMESIZE);
1778         }
1779
1780         levels = trace_back_stack(0, addrs, names,
1781                         BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1782
1783         DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1784         for (i = 0; i < levels; i++) {
1785                 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1786         }
1787 #undef NAMESIZE
1788
1789 #else
1790         DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1791 #endif
1792 }
1793
1794 /*******************************************************************
1795   A readdir wrapper which just returns the file name.
1796  ********************************************************************/
1797
1798 const char *readdirname(SMB_STRUCT_DIR *p)
1799 {
1800         SMB_STRUCT_DIRENT *ptr;
1801         char *dname;
1802
1803         if (!p)
1804                 return(NULL);
1805   
1806         ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1807         if (!ptr)
1808                 return(NULL);
1809
1810         dname = ptr->d_name;
1811
1812 #ifdef NEXT2
1813         if (telldir(p) < 0)
1814                 return(NULL);
1815 #endif
1816
1817 #ifdef HAVE_BROKEN_READDIR_NAME
1818         /* using /usr/ucb/cc is BAD */
1819         dname = dname - 2;
1820 #endif
1821
1822         return talloc_strdup(talloc_tos(), dname);
1823 }
1824
1825 /*******************************************************************
1826  Utility function used to decide if the last component 
1827  of a path matches a (possibly wildcarded) entry in a namelist.
1828 ********************************************************************/
1829
1830 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1831 {
1832         const char *last_component;
1833
1834         /* if we have no list it's obviously not in the path */
1835         if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1836                 return False;
1837         }
1838
1839         DEBUG(8, ("is_in_path: %s\n", name));
1840
1841         /* Get the last component of the unix name. */
1842         last_component = strrchr_m(name, '/');
1843         if (!last_component) {
1844                 last_component = name;
1845         } else {
1846                 last_component++; /* Go past '/' */
1847         }
1848
1849         for(; namelist->name != NULL; namelist++) {
1850                 if(namelist->is_wild) {
1851                         if (mask_match(last_component, namelist->name, case_sensitive)) {
1852                                 DEBUG(8,("is_in_path: mask match succeeded\n"));
1853                                 return True;
1854                         }
1855                 } else {
1856                         if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1857                                                 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1858                                 DEBUG(8,("is_in_path: match succeeded\n"));
1859                                 return True;
1860                         }
1861                 }
1862         }
1863         DEBUG(8,("is_in_path: match not found\n"));
1864         return False;
1865 }
1866
1867 /*******************************************************************
1868  Strip a '/' separated list into an array of 
1869  name_compare_enties structures suitable for 
1870  passing to is_in_path(). We do this for
1871  speed so we can pre-parse all the names in the list 
1872  and don't do it for each call to is_in_path().
1873  namelist is modified here and is assumed to be 
1874  a copy owned by the caller.
1875  We also check if the entry contains a wildcard to
1876  remove a potentially expensive call to mask_match
1877  if possible.
1878 ********************************************************************/
1879  
1880 void set_namearray(name_compare_entry **ppname_array, char *namelist)
1881 {
1882         char *name_end;
1883         char *nameptr = namelist;
1884         int num_entries = 0;
1885         int i;
1886
1887         (*ppname_array) = NULL;
1888
1889         if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) 
1890                 return;
1891
1892         /* We need to make two passes over the string. The
1893                 first to count the number of elements, the second
1894                 to split it.
1895         */
1896
1897         while(*nameptr) {
1898                 if ( *nameptr == '/' ) {
1899                         /* cope with multiple (useless) /s) */
1900                         nameptr++;
1901                         continue;
1902                 }
1903                 /* find the next / */
1904                 name_end = strchr_m(nameptr, '/');
1905
1906                 /* oops - the last check for a / didn't find one. */
1907                 if (name_end == NULL)
1908                         break;
1909
1910                 /* next segment please */
1911                 nameptr = name_end + 1;
1912                 num_entries++;
1913         }
1914
1915         if(num_entries == 0)
1916                 return;
1917
1918         if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1919                 DEBUG(0,("set_namearray: malloc fail\n"));
1920                 return;
1921         }
1922
1923         /* Now copy out the names */
1924         nameptr = namelist;
1925         i = 0;
1926         while(*nameptr) {
1927                 if ( *nameptr == '/' ) {
1928                         /* cope with multiple (useless) /s) */
1929                         nameptr++;
1930                         continue;
1931                 }
1932                 /* find the next / */
1933                 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1934                         *name_end = 0;
1935
1936                 /* oops - the last check for a / didn't find one. */
1937                 if(name_end == NULL) 
1938                         break;
1939
1940                 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1941                 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1942                         DEBUG(0,("set_namearray: malloc fail (1)\n"));
1943                         return;
1944                 }
1945
1946                 /* next segment please */
1947                 nameptr = name_end + 1;
1948                 i++;
1949         }
1950   
1951         (*ppname_array)[i].name = NULL;
1952
1953         return;
1954 }
1955
1956 /****************************************************************************
1957  Routine to free a namearray.
1958 ****************************************************************************/
1959
1960 void free_namearray(name_compare_entry *name_array)
1961 {
1962         int i;
1963
1964         if(name_array == NULL)
1965                 return;
1966
1967         for(i=0; name_array[i].name!=NULL; i++)
1968                 SAFE_FREE(name_array[i].name);
1969         SAFE_FREE(name_array);
1970 }
1971
1972 #undef DBGC_CLASS
1973 #define DBGC_CLASS DBGC_LOCKING
1974
1975 /****************************************************************************
1976  Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
1977  is dealt with in posix.c
1978  Returns True if the lock was granted, False otherwise.
1979 ****************************************************************************/
1980
1981 bool fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
1982 {
1983         SMB_STRUCT_FLOCK lock;
1984         int ret;
1985
1986         DEBUG(8,("fcntl_lock fd=%d op=%d offset=%.0f count=%.0f type=%d\n",
1987                 fd,op,(double)offset,(double)count,type));
1988
1989         lock.l_type = type;
1990         lock.l_whence = SEEK_SET;
1991         lock.l_start = offset;
1992         lock.l_len = count;
1993         lock.l_pid = 0;
1994
1995         ret = sys_fcntl_ptr(fd,op,&lock);
1996
1997         if (ret == -1) {
1998                 int sav = errno;
1999                 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
2000                         (double)offset,(double)count,op,type,strerror(errno)));
2001                 errno = sav;
2002                 return False;
2003         }
2004
2005         /* everything went OK */
2006         DEBUG(8,("fcntl_lock: Lock call successful\n"));
2007
2008         return True;
2009 }
2010
2011 /****************************************************************************
2012  Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
2013  is dealt with in posix.c
2014  Returns True if we have information regarding this lock region (and returns
2015  F_UNLCK in *ptype if the region is unlocked). False if the call failed.
2016 ****************************************************************************/
2017
2018 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
2019 {
2020         SMB_STRUCT_FLOCK lock;
2021         int ret;
2022
2023         DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
2024                     fd,(double)*poffset,(double)*pcount,*ptype));
2025
2026         lock.l_type = *ptype;
2027         lock.l_whence = SEEK_SET;
2028         lock.l_start = *poffset;
2029         lock.l_len = *pcount;
2030         lock.l_pid = 0;
2031
2032         ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
2033
2034         if (ret == -1) {
2035                 int sav = errno;
2036                 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
2037                         (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
2038                 errno = sav;
2039                 return False;
2040         }
2041
2042         *ptype = lock.l_type;
2043         *poffset = lock.l_start;
2044         *pcount = lock.l_len;
2045         *ppid = lock.l_pid;
2046         
2047         DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
2048                         fd, (int)lock.l_type, (unsigned int)lock.l_pid));
2049         return True;
2050 }
2051
2052 #undef DBGC_CLASS
2053 #define DBGC_CLASS DBGC_ALL
2054
2055 /*******************************************************************
2056  Is the name specified one of my netbios names.
2057  Returns true if it is equal, false otherwise.
2058 ********************************************************************/
2059
2060 bool is_myname(const char *s)
2061 {
2062         int n;
2063         bool ret = False;
2064
2065         for (n=0; my_netbios_names(n); n++) {
2066                 if (strequal(my_netbios_names(n), s)) {
2067                         ret=True;
2068                         break;
2069                 }
2070         }
2071         DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2072         return(ret);
2073 }
2074
2075 /*******************************************************************
2076  Is the name specified our workgroup/domain.
2077  Returns true if it is equal, false otherwise.
2078 ********************************************************************/
2079
2080 bool is_myworkgroup(const char *s)
2081 {
2082         bool ret = False;
2083
2084         if (strequal(s, lp_workgroup())) {
2085                 ret=True;
2086         }
2087
2088         DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
2089         return(ret);
2090 }
2091
2092 /*******************************************************************
2093  we distinguish between 2K and XP by the "Native Lan Manager" string
2094    WinXP => "Windows 2002 5.1"
2095    WinXP 64bit => "Windows XP 5.2"
2096    Win2k => "Windows 2000 5.0"
2097    NT4   => "Windows NT 4.0"
2098    Win9x => "Windows 4.0"
2099  Windows 2003 doesn't set the native lan manager string but
2100  they do set the domain to "Windows 2003 5.2" (probably a bug).
2101 ********************************************************************/
2102
2103 void ra_lanman_string( const char *native_lanman )
2104 {
2105         if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
2106                 set_remote_arch( RA_WINXP );
2107         else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
2108                 set_remote_arch( RA_WINXP );
2109         else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
2110                 set_remote_arch( RA_WIN2K3 );
2111 }
2112
2113 static const char *remote_arch_str;
2114
2115 const char *get_remote_arch_str(void)
2116 {
2117         if (!remote_arch_str) {
2118                 return "UNKNOWN";
2119         }
2120         return remote_arch_str;
2121 }
2122
2123 /*******************************************************************
2124  Set the horrid remote_arch string based on an enum.
2125 ********************************************************************/
2126
2127 void set_remote_arch(enum remote_arch_types type)
2128 {
2129         ra_type = type;
2130         switch( type ) {
2131         case RA_WFWG:
2132                 remote_arch_str = "WfWg";
2133                 break;
2134         case RA_OS2:
2135                 remote_arch_str = "OS2";
2136                 break;
2137         case RA_WIN95:
2138                 remote_arch_str = "Win95";
2139                 break;
2140         case RA_WINNT:
2141                 remote_arch_str = "WinNT";
2142                 break;
2143         case RA_WIN2K:
2144                 remote_arch_str = "Win2K";
2145                 break;
2146         case RA_WINXP:
2147                 remote_arch_str = "WinXP";
2148                 break;
2149         case RA_WIN2K3:
2150                 remote_arch_str = "Win2K3";
2151                 break;
2152         case RA_VISTA:
2153                 remote_arch_str = "Vista";
2154                 break;
2155         case RA_SAMBA:
2156                 remote_arch_str = "Samba";
2157                 break;
2158         case RA_CIFSFS:
2159                 remote_arch_str = "CIFSFS";
2160                 break;
2161         default:
2162                 ra_type = RA_UNKNOWN;
2163                 remote_arch_str = "UNKNOWN";
2164                 break;
2165         }
2166
2167         DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
2168                                 remote_arch_str));
2169 }
2170
2171 /*******************************************************************
2172  Get the remote_arch type.
2173 ********************************************************************/
2174
2175 enum remote_arch_types get_remote_arch(void)
2176 {
2177         return ra_type;
2178 }
2179
2180 void print_asc(int level, const unsigned char *buf,int len)
2181 {
2182         int i;
2183         for (i=0;i<len;i++)
2184                 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2185 }
2186
2187 void dump_data(int level, const unsigned char *buf1,int len)
2188 {
2189         const unsigned char *buf = (const unsigned char *)buf1;
2190         int i=0;
2191         if (len<=0) return;
2192
2193         if (!DEBUGLVL(level)) return;
2194         
2195         DEBUGADD(level,("[%03X] ",i));
2196         for (i=0;i<len;) {
2197                 DEBUGADD(level,("%02X ",(int)buf[i]));
2198                 i++;
2199                 if (i%8 == 0) DEBUGADD(level,(" "));
2200                 if (i%16 == 0) {      
2201                         print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2202                         print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2203                         if (i<len) DEBUGADD(level,("[%03X] ",i));
2204                 }
2205         }
2206         if (i%16) {
2207                 int n;
2208                 n = 16 - (i%16);
2209                 DEBUGADD(level,(" "));
2210                 if (n>8) DEBUGADD(level,(" "));
2211                 while (n--) DEBUGADD(level,("   "));
2212                 n = MIN(8,i%16);
2213                 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2214                 n = (i%16) - n;
2215                 if (n>0) print_asc(level,&buf[i-n],n);
2216                 DEBUGADD(level,("\n"));
2217         }
2218 }
2219
2220 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2221 {
2222 #ifdef DEBUG_PASSWORD
2223         DEBUG(11, ("%s", msg));
2224         if (data != NULL && len > 0)
2225         {
2226                 dump_data(11, data, len);
2227         }
2228 #endif
2229 }
2230
2231 const char *tab_depth(int level, int depth)
2232 {
2233         if( DEBUGLVL(level) ) {
2234                 dbgtext("%*s", depth*4, "");
2235         }
2236         return "";
2237 }
2238
2239 /*****************************************************************************
2240  Provide a checksum on a string
2241
2242  Input:  s - the null-terminated character string for which the checksum
2243              will be calculated.
2244
2245   Output: The checksum value calculated for s.
2246 *****************************************************************************/
2247
2248 int str_checksum(const char *s)
2249 {
2250         int res = 0;
2251         int c;
2252         int i=0;
2253
2254         while(*s) {
2255                 c = *s;
2256                 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2257                 s++;
2258                 i++;
2259         }
2260         return(res);
2261 }
2262
2263 /*****************************************************************
2264  Zero a memory area then free it. Used to catch bugs faster.
2265 *****************************************************************/  
2266
2267 void zero_free(void *p, size_t size)
2268 {
2269         memset(p, 0, size);
2270         SAFE_FREE(p);
2271 }
2272
2273 /*****************************************************************
2274  Set our open file limit to a requested max and return the limit.
2275 *****************************************************************/  
2276
2277 int set_maxfiles(int requested_max)
2278 {
2279 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2280         struct rlimit rlp;
2281         int saved_current_limit;
2282
2283         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2284                 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2285                         strerror(errno) ));
2286                 /* just guess... */
2287                 return requested_max;
2288         }
2289
2290         /* 
2291          * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2292          * account for the extra fd we need 
2293          * as well as the log files and standard
2294          * handles etc. Save the limit we want to set in case
2295          * we are running on an OS that doesn't support this limit (AIX)
2296          * which always returns RLIM_INFINITY for rlp.rlim_max.
2297          */
2298
2299         /* Try raising the hard (max) limit to the requested amount. */
2300
2301 #if defined(RLIM_INFINITY)
2302         if (rlp.rlim_max != RLIM_INFINITY) {
2303                 int orig_max = rlp.rlim_max;
2304
2305                 if ( rlp.rlim_max < requested_max )
2306                         rlp.rlim_max = requested_max;
2307
2308                 /* This failing is not an error - many systems (Linux) don't
2309                         support our default request of 10,000 open files. JRA. */
2310
2311                 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2312                         DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n", 
2313                                 (int)rlp.rlim_max, strerror(errno) ));
2314
2315                         /* Set failed - restore original value from get. */
2316                         rlp.rlim_max = orig_max;
2317                 }
2318         }
2319 #endif
2320
2321         /* Now try setting the soft (current) limit. */
2322
2323         saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2324
2325         if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2326                 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n", 
2327                         (int)rlp.rlim_cur, strerror(errno) ));
2328                 /* just guess... */
2329                 return saved_current_limit;
2330         }
2331
2332         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2333                 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2334                         strerror(errno) ));
2335                 /* just guess... */
2336                 return saved_current_limit;
2337     }
2338
2339 #if defined(RLIM_INFINITY)
2340         if(rlp.rlim_cur == RLIM_INFINITY)
2341                 return saved_current_limit;
2342 #endif
2343
2344         if((int)rlp.rlim_cur > saved_current_limit)
2345                 return saved_current_limit;
2346
2347         return rlp.rlim_cur;
2348 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2349         /*
2350          * No way to know - just guess...
2351          */
2352         return requested_max;
2353 #endif
2354 }
2355
2356 /*****************************************************************
2357  Possibly replace mkstemp if it is broken.
2358 *****************************************************************/  
2359
2360 int smb_mkstemp(char *name_template)
2361 {
2362 #if HAVE_SECURE_MKSTEMP
2363         return mkstemp(name_template);
2364 #else
2365         /* have a reasonable go at emulating it. Hope that
2366            the system mktemp() isn't completly hopeless */
2367         char *p = mktemp(name_template);
2368         if (!p)
2369                 return -1;
2370         return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2371 #endif
2372 }
2373
2374 /*****************************************************************
2375  malloc that aborts with smb_panic on fail or zero size.
2376  *****************************************************************/  
2377
2378 void *smb_xmalloc_array(size_t size, unsigned int count)
2379 {
2380         void *p;
2381         if (size == 0) {
2382                 smb_panic("smb_xmalloc_array: called with zero size");
2383         }
2384         if (count >= MAX_ALLOC_SIZE/size) {
2385                 smb_panic("smb_xmalloc_array: alloc size too large");
2386         }
2387         if ((p = SMB_MALLOC(size*count)) == NULL) {
2388                 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2389                         (unsigned long)size, (unsigned long)count));
2390                 smb_panic("smb_xmalloc_array: malloc failed");
2391         }
2392         return p;
2393 }
2394
2395 /**
2396  Memdup with smb_panic on fail.
2397 **/
2398
2399 void *smb_xmemdup(const void *p, size_t size)
2400 {
2401         void *p2;
2402         p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2403         memcpy(p2, p, size);
2404         return p2;
2405 }
2406
2407 /**
2408  strdup that aborts on malloc fail.
2409 **/
2410
2411 char *smb_xstrdup(const char *s)
2412 {
2413 #if defined(PARANOID_MALLOC_CHECKER)
2414 #ifdef strdup
2415 #undef strdup
2416 #endif
2417 #endif
2418
2419 #ifndef HAVE_STRDUP
2420 #define strdup rep_strdup
2421 #endif
2422
2423         char *s1 = strdup(s);
2424 #if defined(PARANOID_MALLOC_CHECKER)
2425 #ifdef strdup
2426 #undef strdup
2427 #endif
2428 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2429 #endif
2430         if (!s1) {
2431                 smb_panic("smb_xstrdup: malloc failed");
2432         }
2433         return s1;
2434
2435 }
2436
2437 /**
2438  strndup that aborts on malloc fail.
2439 **/
2440
2441 char *smb_xstrndup(const char *s, size_t n)
2442 {
2443 #if defined(PARANOID_MALLOC_CHECKER)
2444 #ifdef strndup
2445 #undef strndup
2446 #endif
2447 #endif
2448
2449 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
2450 #undef HAVE_STRNDUP
2451 #define strndup rep_strndup
2452 #endif
2453
2454         char *s1 = strndup(s, n);
2455 #if defined(PARANOID_MALLOC_CHECKER)
2456 #ifdef strndup
2457 #undef strndup
2458 #endif
2459 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2460 #endif
2461         if (!s1) {
2462                 smb_panic("smb_xstrndup: malloc failed");
2463         }
2464         return s1;
2465 }
2466
2467 /*
2468   vasprintf that aborts on malloc fail
2469 */
2470
2471  int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2472 {
2473         int n;
2474         va_list ap2;
2475
2476         VA_COPY(ap2, ap);
2477
2478         n = vasprintf(ptr, format, ap2);
2479         if (n == -1 || ! *ptr) {
2480                 smb_panic("smb_xvasprintf: out of memory");
2481         }
2482         return n;
2483 }
2484
2485 /*****************************************************************
2486  Like strdup but for memory.
2487 *****************************************************************/
2488
2489 void *memdup(const void *p, size_t size)
2490 {
2491         void *p2;
2492         if (size == 0)
2493                 return NULL;
2494         p2 = SMB_MALLOC(size);
2495         if (!p2)
2496                 return NULL;
2497         memcpy(p2, p, size);
2498         return p2;
2499 }
2500
2501 /*****************************************************************
2502  Get local hostname and cache result.
2503 *****************************************************************/
2504
2505 char *myhostname(void)
2506 {
2507         static char *ret;
2508         if (ret == NULL) {
2509                 /* This is cached forever so
2510                  * use NULL talloc ctx. */
2511                 ret = get_myname(NULL);
2512         }
2513         return ret;
2514 }
2515
2516 /*****************************************************************
2517  A useful function for returning a path in the Samba pid directory.
2518 *****************************************************************/
2519
2520 static char *xx_path(const char *name, const char *rootpath)
2521 {
2522         char *fname = NULL;
2523
2524         fname = talloc_strdup(talloc_tos(), rootpath);
2525         if (!fname) {
2526                 return NULL;
2527         }
2528         trim_string(fname,"","/");
2529
2530         if (!directory_exist(fname,NULL)) {
2531                 mkdir(fname,0755);
2532         }
2533
2534         return talloc_asprintf(talloc_tos(),
2535                                 "%s/%s",
2536                                 fname,
2537                                 name);
2538 }
2539
2540 /*****************************************************************
2541  A useful function for returning a path in the Samba lock directory.
2542 *****************************************************************/
2543
2544 char *lock_path(const char *name)
2545 {
2546         return xx_path(name, lp_lockdir());
2547 }
2548
2549 /*****************************************************************
2550  A useful function for returning a path in the Samba pid directory.
2551 *****************************************************************/
2552
2553 char *pid_path(const char *name)
2554 {
2555         return xx_path(name, lp_piddir());
2556 }
2557
2558 /**
2559  * @brief Returns an absolute path to a file in the Samba lib directory.
2560  *
2561  * @param name File to find, relative to LIBDIR.
2562  *
2563  * @retval Pointer to a string containing the full path.
2564  **/
2565
2566 char *lib_path(const char *name)
2567 {
2568         return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
2569 }
2570
2571 /**
2572  * @brief Returns an absolute path to a file in the Samba data directory.
2573  *
2574  * @param name File to find, relative to CODEPAGEDIR.
2575  *
2576  * @retval Pointer to a talloc'ed string containing the full path.
2577  **/
2578
2579 char *data_path(const char *name)
2580 {
2581         return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
2582 }
2583
2584 /*****************************************************************
2585 a useful function for returning a path in the Samba state directory
2586  *****************************************************************/
2587
2588 char *state_path(const char *name)
2589 {
2590         return xx_path(name, get_dyn_STATEDIR());
2591 }
2592
2593 /**
2594  * @brief Returns the platform specific shared library extension.
2595  *
2596  * @retval Pointer to a const char * containing the extension.
2597  **/
2598
2599 const char *shlib_ext(void)
2600 {
2601         return get_dyn_SHLIBEXT();
2602 }
2603
2604 /*******************************************************************
2605  Given a filename - get its directory name
2606  NB: Returned in static storage.  Caveats:
2607  o  If caller wishes to preserve, they should copy.
2608 ********************************************************************/
2609
2610 char *parent_dirname(const char *path)
2611 {
2612         char *parent;
2613
2614         if (!parent_dirname_talloc(talloc_tos(), path, &parent, NULL)) {
2615                 return NULL;
2616         }
2617
2618         return parent;
2619 }
2620
2621 bool parent_dirname_talloc(TALLOC_CTX *mem_ctx, const char *dir,
2622                            char **parent, const char **name)
2623 {
2624         char *p;
2625         ptrdiff_t len;
2626  
2627         p = strrchr_m(dir, '/'); /* Find final '/', if any */
2628
2629         if (p == NULL) {
2630                 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2631                         return False;
2632                 }
2633                 if (name) {
2634                         *name = "";
2635                 }
2636                 return True;
2637         }
2638
2639         len = p-dir;
2640
2641         if (!(*parent = TALLOC_ARRAY(mem_ctx, char, len+1))) {
2642                 return False;
2643         }
2644         memcpy(*parent, dir, len);
2645         (*parent)[len] = '\0';
2646
2647         if (name) {
2648                 *name = p+1;
2649         }
2650         return True;
2651 }
2652
2653 /*******************************************************************
2654  Determine if a pattern contains any Microsoft wildcard characters.
2655 *******************************************************************/
2656
2657 bool ms_has_wild(const char *s)
2658 {
2659         char c;
2660
2661         if (lp_posix_pathnames()) {
2662                 /* With posix pathnames no characters are wild. */
2663                 return False;
2664         }
2665
2666         while ((c = *s++)) {
2667                 switch (c) {
2668                 case '*':
2669                 case '?':
2670                 case '<':
2671                 case '>':
2672                 case '"':
2673                         return True;
2674                 }
2675         }
2676         return False;
2677 }
2678
2679 bool ms_has_wild_w(const smb_ucs2_t *s)
2680 {
2681         smb_ucs2_t c;
2682         if (!s) return False;
2683         while ((c = *s++)) {
2684                 switch (c) {
2685                 case UCS2_CHAR('*'):
2686                 case UCS2_CHAR('?'):
2687                 case UCS2_CHAR('<'):
2688                 case UCS2_CHAR('>'):
2689                 case UCS2_CHAR('"'):
2690                         return True;
2691                 }
2692         }
2693         return False;
2694 }
2695
2696 /*******************************************************************
2697  A wrapper that handles case sensitivity and the special handling
2698  of the ".." name.
2699 *******************************************************************/
2700
2701 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
2702 {
2703         if (strcmp(string,"..") == 0)
2704                 string = ".";
2705         if (strcmp(pattern,".") == 0)
2706                 return False;
2707         
2708         return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2709 }
2710
2711 /*******************************************************************
2712  A wrapper that handles case sensitivity and the special handling
2713  of the ".." name. Varient that is only called by old search code which requires
2714  pattern translation.
2715 *******************************************************************/
2716
2717 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
2718 {
2719         if (strcmp(string,"..") == 0)
2720                 string = ".";
2721         if (strcmp(pattern,".") == 0)
2722                 return False;
2723         
2724         return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2725 }
2726
2727 /*******************************************************************
2728  A wrapper that handles a list of patters and calls mask_match()
2729  on each.  Returns True if any of the patterns match.
2730 *******************************************************************/
2731
2732 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
2733 {
2734        while (listLen-- > 0) {
2735                if (mask_match(string, *list++, is_case_sensitive))
2736                        return True;
2737        }
2738        return False;
2739 }
2740
2741 /*********************************************************
2742  Recursive routine that is called by unix_wild_match.
2743 *********************************************************/
2744
2745 static bool unix_do_match(const char *regexp, const char *str)
2746 {
2747         const char *p;
2748
2749         for( p = regexp; *p && *str; ) {
2750
2751                 switch(*p) {
2752                         case '?':
2753                                 str++;
2754                                 p++;
2755                                 break;
2756
2757                         case '*':
2758
2759                                 /*
2760                                  * Look for a character matching 
2761                                  * the one after the '*'.
2762                                  */
2763                                 p++;
2764                                 if(!*p)
2765                                         return true; /* Automatic match */
2766                                 while(*str) {
2767
2768                                         while(*str && (*p != *str))
2769                                                 str++;
2770
2771                                         /*
2772                                          * Patch from weidel@multichart.de. In the case of the regexp
2773                                          * '*XX*' we want to ensure there are at least 2 'X' characters
2774                                          * in the string after the '*' for a match to be made.
2775                                          */
2776
2777                                         {
2778                                                 int matchcount=0;
2779
2780                                                 /*
2781                                                  * Eat all the characters that match, but count how many there were.
2782                                                  */
2783
2784                                                 while(*str && (*p == *str)) {
2785                                                         str++;
2786                                                         matchcount++;
2787                                                 }
2788
2789                                                 /*
2790                                                  * Now check that if the regexp had n identical characters that
2791                                                  * matchcount had at least that many matches.
2792                                                  */
2793
2794                                                 while ( *(p+1) && (*(p+1) == *p)) {
2795                                                         p++;
2796                                                         matchcount--;
2797                                                 }
2798
2799                                                 if ( matchcount <= 0 )
2800                                                         return false;
2801                                         }
2802
2803                                         str--; /* We've eaten the match char after the '*' */
2804
2805                                         if(unix_do_match(p, str))
2806                                                 return true;
2807
2808                                         if(!*str)
2809                                                 return false;
2810                                         else
2811                                                 str++;
2812                                 }
2813                                 return false;
2814
2815                         default:
2816                                 if(*str != *p)
2817                                         return false;
2818                                 str++;
2819                                 p++;
2820                                 break;
2821                 }
2822         }
2823
2824         if(!*p && !*str)
2825                 return true;
2826
2827         if (!*p && str[0] == '.' && str[1] == 0)
2828                 return true;
2829
2830         if (!*str && *p == '?') {
2831                 while (*p == '?')
2832                         p++;
2833                 return(!*p);
2834         }
2835
2836         if(!*str && (*p == '*' && p[1] == '\0'))
2837                 return true;
2838
2839         return false;
2840 }
2841
2842 /*******************************************************************
2843  Simple case insensitive interface to a UNIX wildcard matcher.
2844  Returns True if match, False if not.
2845 *******************************************************************/
2846
2847 bool unix_wild_match(const char *pattern, const char *string)
2848 {
2849         TALLOC_CTX *ctx = talloc_stackframe();
2850         char *p2;
2851         char *s2;
2852         char *p;
2853         bool ret = false;
2854
2855         p2 = talloc_strdup(ctx,pattern);
2856         s2 = talloc_strdup(ctx,string);
2857         if (!p2 || !s2) {
2858                 TALLOC_FREE(ctx);
2859                 return false;
2860         }
2861         strlower_m(p2);
2862         strlower_m(s2);
2863
2864         /* Remove any *? and ** from the pattern as they are meaningless */
2865         for(p = p2; *p; p++) {
2866                 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
2867                         memmove(&p[1], &p[2], strlen(&p[2])+1);
2868                 }
2869         }
2870
2871         if (strequal(p2,"*")) {
2872                 TALLOC_FREE(ctx);
2873                 return true;
2874         }
2875
2876         ret = unix_do_match(p2, s2);
2877         TALLOC_FREE(ctx);
2878         return ret;
2879 }
2880
2881 /**********************************************************************
2882  Converts a name to a fully qualified domain name.
2883  Returns true if lookup succeeded, false if not (then fqdn is set to name)
2884  Note we deliberately use gethostbyname here, not getaddrinfo as we want
2885  to examine the h_aliases and I don't know how to do that with getaddrinfo.
2886 ***********************************************************************/
2887
2888 bool name_to_fqdn(fstring fqdn, const char *name)
2889 {
2890         char *full = NULL;
2891         struct hostent *hp = gethostbyname(name);
2892
2893         if (!hp || !hp->h_name || !*hp->h_name) {
2894                 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2895                 fstrcpy(fqdn, name);
2896                 return false;
2897         }
2898
2899         /* Find out if the fqdn is returned as an alias
2900          * to cope with /etc/hosts files where the first
2901          * name is not the fqdn but the short name */
2902         if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2903                 int i;
2904                 for (i = 0; hp->h_aliases[i]; i++) {
2905                         if (strchr_m(hp->h_aliases[i], '.')) {
2906                                 full = hp->h_aliases[i];
2907                                 break;
2908                         }
2909                 }
2910         }
2911         if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2912                 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2913                 DEBUGADD(1, ("    Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2914                 DEBUGADD(1, ("    to Kerberos authentication problems as localhost.localdomain\n"));
2915                 DEBUGADD(1, ("    may end up being used instead of the real machine FQDN.\n"));
2916                 full = hp->h_name;
2917         }
2918         if (!full) {
2919                 full = hp->h_name;
2920         }
2921
2922         DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2923         fstrcpy(fqdn, full);
2924         return true;
2925 }
2926
2927 /**********************************************************************
2928  Extension to talloc_get_type: Abort on type mismatch
2929 ***********************************************************************/
2930
2931 void *talloc_check_name_abort(const void *ptr, const char *name)
2932 {
2933         void *result;
2934
2935         result = talloc_check_name(ptr, name);
2936         if (result != NULL)
2937                 return result;
2938
2939         DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2940                   name, talloc_get_name(ptr)));
2941         smb_panic("talloc type mismatch");
2942         /* Keep the compiler happy */
2943         return NULL;
2944 }
2945
2946 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2947 {
2948         switch (share_access & ~FILE_SHARE_DELETE) {
2949                 case FILE_SHARE_NONE:
2950                         return DENY_ALL;
2951                 case FILE_SHARE_READ:
2952                         return DENY_WRITE;
2953                 case FILE_SHARE_WRITE:
2954                         return DENY_READ;
2955                 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2956                         return DENY_NONE;
2957         }
2958         if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2959                 return DENY_DOS;
2960         } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2961                 return DENY_FCB;
2962         }
2963
2964         return (uint32)-1;
2965 }
2966
2967 pid_t procid_to_pid(const struct server_id *proc)
2968 {
2969         return proc->pid;
2970 }
2971
2972 static uint32 my_vnn = NONCLUSTER_VNN;
2973
2974 void set_my_vnn(uint32 vnn)
2975 {
2976         DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
2977         my_vnn = vnn;
2978 }
2979
2980 uint32 get_my_vnn(void)
2981 {
2982         return my_vnn;
2983 }
2984
2985 struct server_id pid_to_procid(pid_t pid)
2986 {
2987         struct server_id result;
2988         result.pid = pid;
2989 #ifdef CLUSTER_SUPPORT
2990         result.vnn = my_vnn;
2991 #endif
2992         return result;
2993 }
2994
2995 struct server_id procid_self(void)
2996 {
2997         return pid_to_procid(sys_getpid());
2998 }
2999
3000 struct server_id server_id_self(void)
3001 {
3002         return procid_self();
3003 }
3004
3005 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
3006 {
3007         if (p1->pid != p2->pid)
3008                 return False;
3009 #ifdef CLUSTER_SUPPORT
3010         if (p1->vnn != p2->vnn)
3011                 return False;
3012 #endif
3013         return True;
3014 }
3015
3016 bool cluster_id_equal(const struct server_id *id1,
3017                       const struct server_id *id2)
3018 {
3019         return procid_equal(id1, id2);
3020 }
3021
3022 bool procid_is_me(const struct server_id *pid)
3023 {
3024         if (pid->pid != sys_getpid())
3025                 return False;
3026 #ifdef CLUSTER_SUPPORT
3027         if (pid->vnn != my_vnn)
3028                 return False;
3029 #endif
3030         return True;
3031 }
3032
3033 struct server_id interpret_pid(const char *pid_string)
3034 {
3035 #ifdef CLUSTER_SUPPORT
3036         unsigned int vnn, pid;
3037         struct server_id result;
3038         if (sscanf(pid_string, "%u:%u", &vnn, &pid) == 2) {
3039                 result.vnn = vnn;
3040                 result.pid = pid;
3041         }
3042         else if (sscanf(pid_string, "%u", &pid) == 1) {
3043                 result.vnn = NONCLUSTER_VNN;
3044                 result.pid = pid;
3045         }
3046         else {
3047                 result.vnn = NONCLUSTER_VNN;
3048                 result.pid = -1;
3049         }
3050         return result;
3051 #else
3052         return pid_to_procid(atoi(pid_string));
3053 #endif
3054 }
3055
3056 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
3057 {
3058 #ifdef CLUSTER_SUPPORT
3059         if (pid->vnn == NONCLUSTER_VNN) {
3060                 return talloc_asprintf(mem_ctx,
3061                                 "%d",
3062                                 (int)pid->pid);
3063         }
3064         else {
3065                 return talloc_asprintf(mem_ctx,
3066                                         "%u:%d",
3067                                         (unsigned)pid->vnn,
3068                                         (int)pid->pid);
3069         }
3070 #else
3071         return talloc_asprintf(mem_ctx,
3072                         "%d",
3073                         (int)pid->pid);
3074 #endif
3075 }
3076
3077 char *procid_str_static(const struct server_id *pid)
3078 {
3079         return procid_str(talloc_tos(), pid);
3080 }
3081
3082 bool procid_valid(const struct server_id *pid)
3083 {
3084         return (pid->pid != -1);
3085 }
3086
3087 bool procid_is_local(const struct server_id *pid)
3088 {
3089 #ifdef CLUSTER_SUPPORT
3090         return pid->vnn == my_vnn;
3091 #else
3092         return True;
3093 #endif
3094 }
3095
3096 int this_is_smp(void)
3097 {
3098 #if defined(HAVE_SYSCONF)
3099
3100 #if defined(SYSCONF_SC_NPROC_ONLN)
3101         return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
3102 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3103         return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
3104 #else
3105         return 0;
3106 #endif
3107
3108 #else
3109         return 0;
3110 #endif
3111 }
3112
3113 /****************************************************************
3114  Check if an offset into a buffer is safe.
3115  If this returns True it's safe to indirect into the byte at
3116  pointer ptr+off.
3117 ****************************************************************/
3118
3119 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3120 {
3121         const char *end_base = buf_base + buf_len;
3122         char *end_ptr = ptr + off;
3123
3124         if (!buf_base || !ptr) {
3125                 return False;
3126         }
3127
3128         if (end_base < buf_base || end_ptr < ptr) {
3129                 return False; /* wrap. */
3130         }
3131
3132         if (end_ptr < end_base) {
3133                 return True;
3134         }
3135         return False;
3136 }
3137
3138 /****************************************************************
3139  Return a safe pointer into a buffer, or NULL.
3140 ****************************************************************/
3141
3142 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3143 {
3144         return is_offset_safe(buf_base, buf_len, ptr, off) ?
3145                         ptr + off : NULL;
3146 }
3147
3148 /****************************************************************
3149  Return a safe pointer into a string within a buffer, or NULL.
3150 ****************************************************************/
3151
3152 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3153 {
3154         if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
3155                 return NULL;
3156         }
3157         /* Check if a valid string exists at this offset. */
3158         if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
3159                 return NULL;
3160         }
3161         return ptr + off;
3162 }
3163
3164 /****************************************************************
3165  Return an SVAL at a pointer, or failval if beyond the end.
3166 ****************************************************************/
3167
3168 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3169 {
3170         /*
3171          * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
3172          * NOT ptr[2].
3173          */
3174         if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
3175                 return failval;
3176         }
3177         return SVAL(ptr,off);
3178 }
3179
3180 /****************************************************************
3181  Return an IVAL at a pointer, or failval if beyond the end.
3182 ****************************************************************/
3183
3184 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3185 {
3186         /*
3187          * Note we use off+3 here, not off+4 as IVAL accesses 
3188          * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
3189          */
3190         if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
3191                 return failval;
3192         }
3193         return IVAL(ptr,off);
3194 }
3195
3196 /****************************************************************
3197  Split DOM\user into DOM and user. Do not mix with winbind variants of that
3198  call (they take care of winbind separator and other winbind specific settings).
3199 ****************************************************************/
3200
3201 void split_domain_user(TALLOC_CTX *mem_ctx,
3202                        const char *full_name,
3203                        char **domain,
3204                        char **user)
3205 {
3206         const char *p = NULL;
3207
3208         p = strchr_m(full_name, '\\');
3209
3210         if (p != NULL) {
3211                 *domain = talloc_strndup(mem_ctx, full_name,
3212                                          PTR_DIFF(p, full_name));
3213                 *user = talloc_strdup(mem_ctx, p+1);
3214         } else {
3215                 *domain = talloc_strdup(mem_ctx, "");
3216                 *user = talloc_strdup(mem_ctx, full_name);
3217         }
3218 }
3219
3220 #if 0
3221
3222 Disable these now we have checked all code paths and ensured
3223 NULL returns on zero request. JRA.
3224
3225 /****************************************************************
3226  talloc wrapper functions that guarentee a null pointer return
3227  if size == 0.
3228 ****************************************************************/
3229
3230 #ifndef MAX_TALLOC_SIZE
3231 #define MAX_TALLOC_SIZE 0x10000000
3232 #endif
3233
3234 /*
3235  *    talloc and zero memory.
3236  *    - returns NULL if size is zero.
3237  */
3238
3239 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
3240 {
3241         void *p;
3242
3243         if (size == 0) {
3244                 return NULL;
3245         }
3246
3247         p = talloc_named_const(ctx, size, name);
3248
3249         if (p) {
3250                 memset(p, '\0', size);
3251         }
3252
3253         return p;
3254 }
3255
3256 /*
3257  *   memdup with a talloc.
3258  *   - returns NULL if size is zero.
3259  */
3260
3261 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
3262 {
3263         void *newp;
3264
3265         if (size == 0) {
3266                 return NULL;
3267         }
3268
3269         newp = talloc_named_const(t, size, name);
3270         if (newp) {
3271                 memcpy(newp, p, size);
3272         }
3273
3274         return newp;
3275 }
3276
3277 /*
3278  *   alloc an array, checking for integer overflow in the array size.
3279  *   - returns NULL if count or el_size are zero.
3280  */
3281
3282 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3283 {
3284         if (count >= MAX_TALLOC_SIZE/el_size) {
3285                 return NULL;
3286         }
3287
3288         if (el_size == 0 || count == 0) {
3289                 return NULL;
3290         }
3291
3292         return talloc_named_const(ctx, el_size * count, name);
3293 }
3294
3295 /*
3296  *   alloc an zero array, checking for integer overflow in the array size
3297  *   - returns NULL if count or el_size are zero.
3298  */
3299
3300 void *_talloc_zero_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_zero(ctx, el_size * count, name);
3311 }
3312
3313 /*
3314  *   Talloc wrapper that returns NULL if size == 0.
3315  */
3316 void *talloc_zeronull(const void *context, size_t size, const char *name)
3317 {
3318         if (size == 0) {
3319                 return NULL;
3320         }
3321         return talloc_named_const(context, size, name);
3322 }
3323 #endif