source: branches/samba-3.2.x/source/lib/util.c@ 237

Last change on this file since 237 was 233, checked in by Herwig Bauernfeind, 16 years ago

Update 3.2 branch to 3.2.9

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