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