source: branches/samba-3.3.x/source/lib/util.c@ 538

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

Update 3.3 to 3.3.7

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