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