Allow reinit_after_fork to be called safely from within swat and other binaries that...
[Samba/gbeck.git] / source / lib / util.c
blob5ec6f2641035af5c958e054b206cb040869685be
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
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.
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.
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/>.
24 #include "includes.h"
26 extern char *global_clobber_region_function;
27 extern unsigned int global_clobber_region_line;
29 /* Max allowable allococation - 256mb - 0x10000000 */
30 #define MAX_ALLOC_SIZE (1024*1024*256)
32 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
33 #ifdef WITH_NISPLUS_HOME
34 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
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.
43 #if defined(GROUP)
44 #undef GROUP
45 #endif
47 #if defined(GROUP_OBJ)
48 #undef GROUP_OBJ
49 #endif
51 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
53 #include <rpcsvc/nis.h>
55 #endif /* WITH_NISPLUS_HOME */
56 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
58 enum protocol_types Protocol = PROTOCOL_COREPLUS;
60 /* this is used by the chaining code */
61 int chain_size = 0;
63 static enum remote_arch_types ra_type = RA_UNKNOWN;
65 /***********************************************************************
66 Definitions for all names.
67 ***********************************************************************/
69 static char *smb_myname;
70 static char *smb_myworkgroup;
71 static char *smb_scope;
72 static int smb_num_netbios_names;
73 static char **smb_my_netbios_names;
75 /***********************************************************************
76 Allocate and set myname. Ensure upper case.
77 ***********************************************************************/
79 bool set_global_myname(const char *myname)
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;
89 const char *global_myname(void)
91 return smb_myname;
94 /***********************************************************************
95 Allocate and set myworkgroup. Ensure upper case.
96 ***********************************************************************/
98 bool set_global_myworkgroup(const char *myworkgroup)
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;
108 const char *lp_workgroup(void)
110 return smb_myworkgroup;
113 /***********************************************************************
114 Allocate and set scope. Ensure upper case.
115 ***********************************************************************/
117 bool set_global_scope(const char *scope)
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;
127 /*********************************************************************
128 Ensure scope is never null string.
129 *********************************************************************/
131 const char *global_scope(void)
133 if (!smb_scope)
134 set_global_scope("");
135 return smb_scope;
138 static void free_netbios_names_array(void)
140 int i;
142 for (i = 0; i < smb_num_netbios_names; i++)
143 SAFE_FREE(smb_my_netbios_names[i]);
145 SAFE_FREE(smb_my_netbios_names);
146 smb_num_netbios_names = 0;
149 static bool allocate_my_netbios_names_array(size_t number)
151 free_netbios_names_array();
153 smb_num_netbios_names = number + 1;
154 smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
156 if (!smb_my_netbios_names)
157 return False;
159 memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
160 return True;
163 static bool set_my_netbios_names(const char *name, int i)
165 SAFE_FREE(smb_my_netbios_names[i]);
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;
174 /***********************************************************************
175 Free memory allocated to global objects
176 ***********************************************************************/
178 void gfree_names(void)
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();
187 void gfree_all( void )
189 gfree_names();
190 gfree_loadparm();
191 gfree_case_tables();
192 gfree_charcnv();
193 gfree_interfaces();
194 gfree_debugsyms();
197 const char *my_netbios_names(int i)
199 return smb_my_netbios_names[i];
202 bool set_netbios_aliases(const char **str_array)
204 size_t namecount;
206 /* Work out the max number of netbios aliases that we have */
207 for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
210 if ( global_myname() && *global_myname())
211 namecount++;
213 /* Allocate space for the netbios aliases */
214 if (!allocate_my_netbios_names_array(namecount))
215 return False;
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++;
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;
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;
237 if (!duplicate) {
238 if (!set_my_netbios_names(str_array[i], namecount))
239 return False;
240 namecount++;
244 return True;
247 /****************************************************************************
248 Common name initialization code.
249 ****************************************************************************/
251 bool init_names(void)
253 int n;
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;
262 if (!set_netbios_aliases(lp_netbios_aliases())) {
263 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
264 return False;
267 set_local_machine_name(global_myname(),false);
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) ) );
275 return( True );
278 /**************************************************************************n
279 Code to cope with username/password auth options from the commandline.
280 Used mainly in client tools.
281 ****************************************************************************/
283 static struct user_auth_info cmdline_auth_info = {
284 NULL, /* username */
285 NULL, /* password */
286 false, /* got_pass */
287 false, /* use_kerberos */
288 Undefined, /* signing state */
289 false, /* smb_encrypt */
290 false /* use machine account */
293 const char *get_cmdline_auth_info_username(void)
295 if (!cmdline_auth_info.username) {
296 return "";
298 return cmdline_auth_info.username;
301 void set_cmdline_auth_info_username(const char *username)
303 SAFE_FREE(cmdline_auth_info.username);
304 cmdline_auth_info.username = SMB_STRDUP(username);
305 if (!cmdline_auth_info.username) {
306 exit(ENOMEM);
310 const char *get_cmdline_auth_info_password(void)
312 if (!cmdline_auth_info.password) {
313 return "";
315 return cmdline_auth_info.password;
318 void set_cmdline_auth_info_password(const char *password)
320 SAFE_FREE(cmdline_auth_info.password);
321 cmdline_auth_info.password = SMB_STRDUP(password);
322 if (!cmdline_auth_info.password) {
323 exit(ENOMEM);
325 cmdline_auth_info.got_pass = true;
328 bool set_cmdline_auth_info_signing_state(const char *arg)
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;
343 return true;
346 int get_cmdline_auth_info_signing_state(void)
348 return cmdline_auth_info.signing_state;
351 void set_cmdline_auth_info_use_kerberos(bool b)
353 cmdline_auth_info.use_kerberos = b;
356 bool get_cmdline_auth_info_use_kerberos(void)
358 return cmdline_auth_info.use_kerberos;
361 /* This should only be used by lib/popt_common.c JRA */
362 void set_cmdline_auth_info_use_krb5_ticket(void)
364 cmdline_auth_info.use_kerberos = true;
365 cmdline_auth_info.got_pass = true;
368 /* This should only be used by lib/popt_common.c JRA */
369 void set_cmdline_auth_info_smb_encrypt(void)
371 cmdline_auth_info.smb_encrypt = true;
374 void set_cmdline_auth_info_use_machine_account(void)
376 cmdline_auth_info.use_machine_account = true;
379 bool get_cmdline_auth_info_got_pass(void)
381 return cmdline_auth_info.got_pass;
384 bool get_cmdline_auth_info_smb_encrypt(void)
386 return cmdline_auth_info.smb_encrypt;
389 bool get_cmdline_auth_info_use_machine_account(void)
391 return cmdline_auth_info.use_machine_account;
394 bool get_cmdline_auth_info_copy(struct user_auth_info *info)
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;
403 return true;
406 bool set_cmdline_auth_info_machine_account_creds(void)
408 char *pass = NULL;
409 char *account = NULL;
411 if (!get_cmdline_auth_info_use_machine_account()) {
412 return false;
415 if (!secrets_init()) {
416 d_printf("ERROR: Unable to open secrets database\n");
417 return false;
420 if (asprintf(&account, "%s$@%s", global_myname(), lp_realm()) < 0) {
421 return false;
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;
433 set_cmdline_auth_info_username(account);
434 set_cmdline_auth_info_password(pass);
436 SAFE_FREE(account);
437 SAFE_FREE(pass);
439 return true;
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 ****************************************************************************/
447 const char *tmpdir(void)
449 char *p;
450 if ((p = getenv("TMPDIR")))
451 return p;
452 return "/tmp";
455 /****************************************************************************
456 Add a gid to an array of gids if it's not already there.
457 ****************************************************************************/
459 bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
460 gid_t **gids, size_t *num_gids)
462 int i;
464 if ((*num_gids != 0) && (*gids == NULL)) {
466 * A former call to this routine has failed to allocate memory
468 return False;
471 for (i=0; i<*num_gids; i++) {
472 if ((*gids)[i] == gid) {
473 return True;
477 *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1);
478 if (*gids == NULL) {
479 *num_gids = 0;
480 return False;
483 (*gids)[*num_gids] = gid;
484 *num_gids += 1;
485 return True;
488 /****************************************************************************
489 Like atoi but gets the value up to the separator character.
490 ****************************************************************************/
492 static const char *Atoic(const char *p, int *n, const char *c)
494 if (!isdigit((int)*p)) {
495 DEBUG(5, ("Atoic: malformed number\n"));
496 return NULL;
499 (*n) = atoi(p);
501 while ((*p) && isdigit((int)*p))
502 p++;
504 if (strchr_m(c, *p) == NULL) {
505 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
506 return NULL;
509 return p;
512 /*************************************************************************
513 Reads a list of numbers.
514 *************************************************************************/
516 const char *get_numlist(const char *p, uint32 **num, int *count)
518 int val;
520 if (num == NULL || count == NULL)
521 return NULL;
523 (*count) = 0;
524 (*num ) = NULL;
526 while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
527 *num = SMB_REALLOC_ARRAY((*num), uint32, (*count)+1);
528 if (!(*num)) {
529 return NULL;
531 (*num)[(*count)] = val;
532 (*count)++;
533 p++;
536 return p;
539 /*******************************************************************
540 Check if a file exists - call vfs_file_exist for samba files.
541 ********************************************************************/
543 bool file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
545 SMB_STRUCT_STAT st;
546 if (!sbuf)
547 sbuf = &st;
549 if (sys_stat(fname,sbuf) != 0)
550 return(False);
552 return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
555 /*******************************************************************
556 Check if a unix domain socket exists - call vfs_file_exist for samba files.
557 ********************************************************************/
559 bool socket_exist(const char *fname)
561 SMB_STRUCT_STAT st;
562 if (sys_stat(fname,&st) != 0)
563 return(False);
565 return S_ISSOCK(st.st_mode);
568 /*******************************************************************
569 Check a files mod time.
570 ********************************************************************/
572 time_t file_modtime(const char *fname)
574 SMB_STRUCT_STAT st;
576 if (sys_stat(fname,&st) != 0)
577 return(0);
579 return(st.st_mtime);
582 /*******************************************************************
583 Check if a directory exists.
584 ********************************************************************/
586 bool directory_exist(char *dname,SMB_STRUCT_STAT *st)
588 SMB_STRUCT_STAT st2;
589 bool ret;
591 if (!st)
592 st = &st2;
594 if (sys_stat(dname,st) != 0)
595 return(False);
597 ret = S_ISDIR(st->st_mode);
598 if(!ret)
599 errno = ENOTDIR;
600 return ret;
603 /*******************************************************************
604 Returns the size in bytes of the named file.
605 ********************************************************************/
607 SMB_OFF_T get_file_size(char *file_name)
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);
616 /*******************************************************************
617 Return a string representing an attribute for a file.
618 ********************************************************************/
620 char *attrib_string(uint16 mode)
622 fstring attrstr;
624 attrstr[0] = 0;
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");
633 return talloc_strdup(talloc_tos(), attrstr);
636 /*******************************************************************
637 Show a smb message structure.
638 ********************************************************************/
640 void show_msg(char *buf)
642 int i;
643 int bcc=0;
645 if (!DEBUGLVL(5))
646 return;
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)));
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)));
667 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
669 DEBUGADD(5,("smb_bcc=%d\n",bcc));
671 if (DEBUGLEVEL < 10)
672 return;
674 if (DEBUGLEVEL < 50)
675 bcc = MIN(bcc, 512);
677 dump_data(10, (uint8 *)smb_buf(buf), bcc);
680 /*******************************************************************
681 Set the length and marker of an encrypted smb packet.
682 ********************************************************************/
684 void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num)
686 _smb_setlen(buf,len);
688 SCVAL(buf,4,0xFF);
689 SCVAL(buf,5,'E');
690 SSVAL(buf,6,enc_ctx_num);
693 /*******************************************************************
694 Set the length and marker of an smb packet.
695 ********************************************************************/
697 void smb_setlen(char *buf,int len)
699 _smb_setlen(buf,len);
701 SCVAL(buf,4,0xFF);
702 SCVAL(buf,5,'S');
703 SCVAL(buf,6,'M');
704 SCVAL(buf,7,'B');
707 /*******************************************************************
708 Setup only the byte count for a smb message.
709 ********************************************************************/
711 int set_message_bcc(char *buf,int num_bytes)
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);
719 /*******************************************************************
720 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
721 Return the bytes added
722 ********************************************************************/
724 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
726 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
727 uint8 *tmp;
729 if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
730 DEBUG(0, ("talloc failed\n"));
731 return -1;
733 *outbuf = tmp;
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;
740 /*******************************************************************
741 Reduce a file name, removing .. elements.
742 ********************************************************************/
744 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
746 char *p = NULL;
747 char *str = NULL;
749 DEBUG(3,("dos_clean_name [%s]\n",s));
751 /* remove any double slashes */
752 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
753 if (!str) {
754 return NULL;
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;
768 while ((p = strstr_m(str,"\\..\\")) != NULL) {
769 char *s1;
771 *p = 0;
772 s1 = p+3;
774 if ((p=strrchr_m(str,'\\')) != NULL) {
775 *p = 0;
776 } else {
777 *str = 0;
779 str = talloc_asprintf(ctx,
780 "%s%s",
781 str,
782 s1);
783 if (!str) {
784 return NULL;
788 trim_string(str,NULL,"\\..");
789 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
792 /*******************************************************************
793 Reduce a file name, removing .. elements.
794 ********************************************************************/
796 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
798 char *p = NULL;
799 char *str = NULL;
801 DEBUG(3,("unix_clean_name [%s]\n",s));
803 /* remove any double slashes */
804 str = talloc_all_string_sub(ctx, s, "//","/");
805 if (!str) {
806 return NULL;
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;
820 while ((p = strstr_m(str,"/../")) != NULL) {
821 char *s1;
823 *p = 0;
824 s1 = p+3;
826 if ((p=strrchr_m(str,'/')) != NULL) {
827 *p = 0;
828 } else {
829 *str = 0;
831 str = talloc_asprintf(ctx,
832 "%s%s",
833 str,
834 s1);
835 if (!str) {
836 return NULL;
840 trim_string(str,NULL,"/..");
841 return talloc_all_string_sub(ctx, str, "/./", "/");
844 char *clean_name(TALLOC_CTX *ctx, const char *s)
846 char *str = dos_clean_name(ctx, s);
847 if (!str) {
848 return NULL;
850 return unix_clean_name(ctx, str);
853 /*******************************************************************
854 Close the low 3 fd's and open dev/null in their place.
855 ********************************************************************/
857 void close_low_fds(bool stderr_too)
859 #ifndef VALGRIND
860 int fd;
861 int i;
863 close(0);
864 close(1);
866 if (stderr_too)
867 close(2);
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;
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;
882 if (fd != i) {
883 DEBUG(0,("Didn't get file descriptor %d\n",i));
884 return;
887 #endif
890 /*******************************************************************
891 Write data into an fd at a given offset. Ignore seek errors.
892 ********************************************************************/
894 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
896 size_t total=0;
897 ssize_t ret;
899 if (pos == (SMB_OFF_T)-1) {
900 return write_data(fd, buffer, N);
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);
908 if (ret == -1) {
909 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
910 return -1;
912 if (ret == 0) {
913 return total;
915 total += ret;
916 pos += ret;
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;
926 return write_data(fd, buffer, N);
927 #endif
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 ****************************************************************************/
937 int set_blocking(int fd, bool set)
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
950 if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
951 return -1;
952 if(set) /* Turn blocking on - ie. clear nonblock flag */
953 val &= ~FLAG_TO_SET;
954 else
955 val |= FLAG_TO_SET;
956 return sys_fcntl_long( fd, F_SETFL, val);
957 #undef FLAG_TO_SET
960 /*******************************************************************
961 Sleep for a specified number of milliseconds.
962 ********************************************************************/
964 void smb_msleep(unsigned int t)
966 #if defined(HAVE_NANOSLEEP)
967 struct timespec tval;
968 int ret;
970 tval.tv_sec = t/1000;
971 tval.tv_nsec = 1000000*(t%1000);
973 do {
974 errno = 0;
975 ret = nanosleep(&tval, &tval);
976 } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
977 #else
978 unsigned int tdiff=0;
979 struct timeval tval,t1,t2;
980 fd_set fds;
982 GetTimeOfDay(&t1);
983 t2 = t1;
985 while (tdiff < t) {
986 tval.tv_sec = (t-tdiff)/1000;
987 tval.tv_usec = 1000*((t-tdiff)%1000);
989 /* Never wait for more than 1 sec. */
990 if (tval.tv_sec > 1) {
991 tval.tv_sec = 1;
992 tval.tv_usec = 0;
995 FD_ZERO(&fds);
996 errno = 0;
997 sys_select_intr(0,&fds,NULL,NULL,&tval);
999 GetTimeOfDay(&t2);
1000 if (t2.tv_sec < t1.tv_sec) {
1001 /* Someone adjusted time... */
1002 t1 = t2;
1005 tdiff = TvalDiff(&t1,&t2);
1007 #endif
1010 /****************************************************************************
1011 Become a daemon, discarding the controlling terminal.
1012 ****************************************************************************/
1014 void become_daemon(bool Fork, bool no_process_group)
1016 if (Fork) {
1017 if (sys_fork()) {
1018 _exit(0);
1022 /* detach from the terminal */
1023 #ifdef HAVE_SETSID
1024 if (!no_process_group) setsid();
1025 #elif defined(TIOCNOTTY)
1026 if (!no_process_group) {
1027 int i = sys_open("/dev/tty", O_RDWR, 0);
1028 if (i != -1) {
1029 ioctl(i, (int) TIOCNOTTY, (char *)0);
1030 close(i);
1033 #endif /* HAVE_SETSID */
1035 /* Close fd's 0,1,2. Needed if started by rsh */
1036 close_low_fds(False); /* Don't close stderr, let the debug system
1037 attach it to the logfile */
1040 bool reinit_after_fork(struct messaging_context *msg_ctx,
1041 struct event_context *ev_ctx,
1042 bool parent_longlived)
1044 NTSTATUS status;
1046 /* Reset the state of the random
1047 * number generation system, so
1048 * children do not get the same random
1049 * numbers as each other */
1050 set_need_random_reseed();
1052 /* tdb needs special fork handling */
1053 if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
1054 DEBUG(0,("tdb_reopen_all failed.\n"));
1055 return false;
1058 if (msg_ctx) {
1060 * For clustering, we need to re-init our ctdbd connection after the
1061 * fork
1063 status = messaging_reinit(msg_ctx);
1064 if (!NT_STATUS_IS_OK(status)) {
1065 DEBUG(0,("messaging_reinit() failed: %s\n",
1066 nt_errstr(status)));
1067 return false;
1071 if (ev_ctx) {
1072 event_context_reinit(ev_ctx);
1075 return true;
1078 /****************************************************************************
1079 Put up a yes/no prompt.
1080 ****************************************************************************/
1082 bool yesno(const char *p)
1084 char ans[20];
1085 printf("%s",p);
1087 if (!fgets(ans,sizeof(ans)-1,stdin))
1088 return(False);
1090 if (*ans == 'y' || *ans == 'Y')
1091 return(True);
1093 return(False);
1096 #if defined(PARANOID_MALLOC_CHECKER)
1098 /****************************************************************************
1099 Internal malloc wrapper. Externally visible.
1100 ****************************************************************************/
1102 void *malloc_(size_t size)
1104 if (size == 0) {
1105 return NULL;
1107 #undef malloc
1108 return malloc(size);
1109 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
1112 /****************************************************************************
1113 Internal calloc wrapper. Not externally visible.
1114 ****************************************************************************/
1116 static void *calloc_(size_t count, size_t size)
1118 if (size == 0 || count == 0) {
1119 return NULL;
1121 #undef calloc
1122 return calloc(count, size);
1123 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
1126 /****************************************************************************
1127 Internal realloc wrapper. Not externally visible.
1128 ****************************************************************************/
1130 static void *realloc_(void *ptr, size_t size)
1132 #undef realloc
1133 return realloc(ptr, size);
1134 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
1137 #endif /* PARANOID_MALLOC_CHECKER */
1139 /****************************************************************************
1140 Type-safe malloc.
1141 ****************************************************************************/
1143 void *malloc_array(size_t el_size, unsigned int count)
1145 if (count >= MAX_ALLOC_SIZE/el_size) {
1146 return NULL;
1149 if (el_size == 0 || count == 0) {
1150 return NULL;
1152 #if defined(PARANOID_MALLOC_CHECKER)
1153 return malloc_(el_size*count);
1154 #else
1155 return malloc(el_size*count);
1156 #endif
1159 /****************************************************************************
1160 Type-safe memalign
1161 ****************************************************************************/
1163 void *memalign_array(size_t el_size, size_t align, unsigned int count)
1165 if (count >= MAX_ALLOC_SIZE/el_size) {
1166 return NULL;
1169 return sys_memalign(align, el_size*count);
1172 /****************************************************************************
1173 Type-safe calloc.
1174 ****************************************************************************/
1176 void *calloc_array(size_t size, size_t nmemb)
1178 if (nmemb >= MAX_ALLOC_SIZE/size) {
1179 return NULL;
1181 if (size == 0 || nmemb == 0) {
1182 return NULL;
1184 #if defined(PARANOID_MALLOC_CHECKER)
1185 return calloc_(nmemb, size);
1186 #else
1187 return calloc(nmemb, size);
1188 #endif
1191 /****************************************************************************
1192 Expand a pointer to be a particular size.
1193 Note that this version of Realloc has an extra parameter that decides
1194 whether to free the passed in storage on allocation failure or if the
1195 new size is zero.
1197 This is designed for use in the typical idiom of :
1199 p = SMB_REALLOC(p, size)
1200 if (!p) {
1201 return error;
1204 and not to have to keep track of the old 'p' contents to free later, nor
1205 to worry if the size parameter was zero. In the case where NULL is returned
1206 we guarentee that p has been freed.
1208 If free later semantics are desired, then pass 'free_old_on_error' as False which
1209 guarentees that the old contents are not freed on error, even if size == 0. To use
1210 this idiom use :
1212 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
1213 if (!tmp) {
1214 SAFE_FREE(p);
1215 return error;
1216 } else {
1217 p = tmp;
1220 Changes were instigated by Coverity error checking. JRA.
1221 ****************************************************************************/
1223 void *Realloc(void *p, size_t size, bool free_old_on_error)
1225 void *ret=NULL;
1227 if (size == 0) {
1228 if (free_old_on_error) {
1229 SAFE_FREE(p);
1231 DEBUG(2,("Realloc asked for 0 bytes\n"));
1232 return NULL;
1235 #if defined(PARANOID_MALLOC_CHECKER)
1236 if (!p) {
1237 ret = (void *)malloc_(size);
1238 } else {
1239 ret = (void *)realloc_(p,size);
1241 #else
1242 if (!p) {
1243 ret = (void *)malloc(size);
1244 } else {
1245 ret = (void *)realloc(p,size);
1247 #endif
1249 if (!ret) {
1250 if (free_old_on_error && p) {
1251 SAFE_FREE(p);
1253 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1256 return(ret);
1259 /****************************************************************************
1260 Type-safe realloc.
1261 ****************************************************************************/
1263 void *realloc_array(void *p, size_t el_size, unsigned int count, bool free_old_on_error)
1265 if (count >= MAX_ALLOC_SIZE/el_size) {
1266 if (free_old_on_error) {
1267 SAFE_FREE(p);
1269 return NULL;
1271 return Realloc(p, el_size*count, free_old_on_error);
1274 /****************************************************************************
1275 (Hopefully) efficient array append.
1276 ****************************************************************************/
1278 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1279 void *element, void *_array, uint32 *num_elements,
1280 ssize_t *array_size)
1282 void **array = (void **)_array;
1284 if (*array_size < 0) {
1285 return;
1288 if (*array == NULL) {
1289 if (*array_size == 0) {
1290 *array_size = 128;
1293 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1294 goto error;
1297 *array = TALLOC(mem_ctx, element_size * (*array_size));
1298 if (*array == NULL) {
1299 goto error;
1303 if (*num_elements == *array_size) {
1304 *array_size *= 2;
1306 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1307 goto error;
1310 *array = TALLOC_REALLOC(mem_ctx, *array,
1311 element_size * (*array_size));
1313 if (*array == NULL) {
1314 goto error;
1318 memcpy((char *)(*array) + element_size*(*num_elements),
1319 element, element_size);
1320 *num_elements += 1;
1322 return;
1324 error:
1325 *num_elements = 0;
1326 *array_size = -1;
1329 /****************************************************************************
1330 Free memory, checks for NULL.
1331 Use directly SAFE_FREE()
1332 Exists only because we need to pass a function pointer somewhere --SSS
1333 ****************************************************************************/
1335 void safe_free(void *p)
1337 SAFE_FREE(p);
1340 /****************************************************************************
1341 Get my own name and IP.
1342 ****************************************************************************/
1344 char *get_myname(TALLOC_CTX *ctx)
1346 char *p;
1347 char hostname[HOST_NAME_MAX];
1349 *hostname = 0;
1351 /* get my host name */
1352 if (gethostname(hostname, sizeof(hostname)) == -1) {
1353 DEBUG(0,("gethostname failed\n"));
1354 return False;
1357 /* Ensure null termination. */
1358 hostname[sizeof(hostname)-1] = '\0';
1360 /* split off any parts after an initial . */
1361 p = strchr_m(hostname,'.');
1362 if (p) {
1363 *p = 0;
1366 return talloc_strdup(ctx, hostname);
1369 /****************************************************************************
1370 Get my own domain name, or "" if we have none.
1371 ****************************************************************************/
1373 char *get_mydnsdomname(TALLOC_CTX *ctx)
1375 const char *domname;
1376 char *p;
1378 domname = get_mydnsfullname();
1379 if (!domname) {
1380 return NULL;
1383 p = strchr_m(domname, '.');
1384 if (p) {
1385 p++;
1386 return talloc_strdup(ctx, p);
1387 } else {
1388 return talloc_strdup(ctx, "");
1392 /****************************************************************************
1393 Interpret a protocol description string, with a default.
1394 ****************************************************************************/
1396 int interpret_protocol(const char *str,int def)
1398 if (strequal(str,"NT1"))
1399 return(PROTOCOL_NT1);
1400 if (strequal(str,"LANMAN2"))
1401 return(PROTOCOL_LANMAN2);
1402 if (strequal(str,"LANMAN1"))
1403 return(PROTOCOL_LANMAN1);
1404 if (strequal(str,"CORE"))
1405 return(PROTOCOL_CORE);
1406 if (strequal(str,"COREPLUS"))
1407 return(PROTOCOL_COREPLUS);
1408 if (strequal(str,"CORE+"))
1409 return(PROTOCOL_COREPLUS);
1411 DEBUG(0,("Unrecognised protocol level %s\n",str));
1413 return(def);
1417 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1418 /******************************************************************
1419 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1420 Based on a fix from <Thomas.Hepper@icem.de>.
1421 Returns a malloc'ed string.
1422 *******************************************************************/
1424 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
1426 if (*str == '-') {
1427 const char *p = str;
1428 while(*p && !isspace(*p))
1429 p++;
1430 while(*p && isspace(*p))
1431 p++;
1432 if(*p) {
1433 return talloc_strdup(ctx, p);
1436 return NULL;
1439 /*******************************************************************
1440 Patch from jkf@soton.ac.uk
1441 Split Luke's automount_server into YP lookup and string splitter
1442 so can easily implement automount_path().
1443 Returns a malloc'ed string.
1444 *******************************************************************/
1446 #ifdef WITH_NISPLUS_HOME
1447 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1449 char *value = NULL;
1451 char *nis_map = (char *)lp_nis_home_map_name();
1453 char buffer[NIS_MAXATTRVAL + 1];
1454 nis_result *result;
1455 nis_object *object;
1456 entry_obj *entry;
1458 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
1459 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1461 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1462 if (result->status != NIS_SUCCESS) {
1463 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1464 } else {
1465 object = result->objects.objects_val;
1466 if (object->zo_data.zo_type == ENTRY_OBJ) {
1467 entry = &object->zo_data.objdata_u.en_data;
1468 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1469 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1471 value = talloc_strdup(ctx,
1472 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1473 if (!value) {
1474 nis_freeresult(result);
1475 return NULL;
1477 value = talloc_string_sub(ctx,
1478 value,
1479 "&",
1480 user_name);
1484 nis_freeresult(result);
1486 if (value) {
1487 value = strip_mount_options(ctx, value);
1488 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
1489 user_name, value));
1491 return value;
1493 #else /* WITH_NISPLUS_HOME */
1495 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1497 char *value = NULL;
1499 int nis_error; /* returned by yp all functions */
1500 char *nis_result; /* yp_match inits this */
1501 int nis_result_len; /* and set this */
1502 char *nis_domain; /* yp_get_default_domain inits this */
1503 char *nis_map = (char *)lp_nis_home_map_name();
1505 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1506 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1507 return NULL;
1510 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1512 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
1513 strlen(user_name), &nis_result,
1514 &nis_result_len)) == 0) {
1515 value = talloc_strdup(ctx, nis_result);
1516 if (!value) {
1517 return NULL;
1519 value = strip_mount_options(ctx, value);
1520 } else if(nis_error == YPERR_KEY) {
1521 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1522 user_name, nis_map));
1523 DEBUG(3, ("using defaults for server and home directory\n"));
1524 } else {
1525 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1526 yperr_string(nis_error), user_name, nis_map));
1529 if (value) {
1530 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
1532 return value;
1534 #endif /* WITH_NISPLUS_HOME */
1535 #endif
1537 /****************************************************************************
1538 Check if a process exists. Does this work on all unixes?
1539 ****************************************************************************/
1541 bool process_exists(const struct server_id pid)
1543 if (procid_is_me(&pid)) {
1544 return True;
1547 if (procid_is_local(&pid)) {
1548 return (kill(pid.pid,0) == 0 || errno != ESRCH);
1551 #ifdef CLUSTER_SUPPORT
1552 return ctdbd_process_exists(messaging_ctdbd_connection(), pid.vnn,
1553 pid.pid);
1554 #else
1555 return False;
1556 #endif
1559 bool process_exists_by_pid(pid_t pid)
1561 /* Doing kill with a non-positive pid causes messages to be
1562 * sent to places we don't want. */
1563 SMB_ASSERT(pid > 0);
1564 return(kill(pid,0) == 0 || errno != ESRCH);
1567 /*******************************************************************
1568 Convert a uid into a user name.
1569 ********************************************************************/
1571 const char *uidtoname(uid_t uid)
1573 TALLOC_CTX *ctx = talloc_tos();
1574 char *name = NULL;
1575 struct passwd *pass = NULL;
1577 pass = getpwuid_alloc(ctx,uid);
1578 if (pass) {
1579 name = talloc_strdup(ctx,pass->pw_name);
1580 TALLOC_FREE(pass);
1581 } else {
1582 name = talloc_asprintf(ctx,
1583 "%ld",
1584 (long int)uid);
1586 return name;
1589 /*******************************************************************
1590 Convert a gid into a group name.
1591 ********************************************************************/
1593 char *gidtoname(gid_t gid)
1595 struct group *grp;
1597 grp = getgrgid(gid);
1598 if (grp) {
1599 return talloc_strdup(talloc_tos(), grp->gr_name);
1601 else {
1602 return talloc_asprintf(talloc_tos(),
1603 "%d",
1604 (int)gid);
1608 /*******************************************************************
1609 Convert a user name into a uid.
1610 ********************************************************************/
1612 uid_t nametouid(const char *name)
1614 struct passwd *pass;
1615 char *p;
1616 uid_t u;
1618 pass = getpwnam_alloc(talloc_autofree_context(), name);
1619 if (pass) {
1620 u = pass->pw_uid;
1621 TALLOC_FREE(pass);
1622 return u;
1625 u = (uid_t)strtol(name, &p, 0);
1626 if ((p != name) && (*p == '\0'))
1627 return u;
1629 return (uid_t)-1;
1632 /*******************************************************************
1633 Convert a name to a gid_t if possible. Return -1 if not a group.
1634 ********************************************************************/
1636 gid_t nametogid(const char *name)
1638 struct group *grp;
1639 char *p;
1640 gid_t g;
1642 g = (gid_t)strtol(name, &p, 0);
1643 if ((p != name) && (*p == '\0'))
1644 return g;
1646 grp = sys_getgrnam(name);
1647 if (grp)
1648 return(grp->gr_gid);
1649 return (gid_t)-1;
1652 /*******************************************************************
1653 Something really nasty happened - panic !
1654 ********************************************************************/
1656 void smb_panic(const char *const why)
1658 char *cmd;
1659 int result;
1661 #ifdef DEVELOPER
1664 if (global_clobber_region_function) {
1665 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1666 global_clobber_region_function,
1667 global_clobber_region_line));
1670 #endif
1672 DEBUG(0,("PANIC (pid %llu): %s\n",
1673 (unsigned long long)sys_getpid(), why));
1674 log_stack_trace();
1676 cmd = lp_panic_action();
1677 if (cmd && *cmd) {
1678 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1679 result = system(cmd);
1681 if (result == -1)
1682 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1683 strerror(errno)));
1684 else
1685 DEBUG(0, ("smb_panic(): action returned status %d\n",
1686 WEXITSTATUS(result)));
1689 dump_core();
1692 /*******************************************************************
1693 Print a backtrace of the stack to the debug log. This function
1694 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1695 exit shortly after calling it.
1696 ********************************************************************/
1698 #ifdef HAVE_LIBUNWIND_H
1699 #include <libunwind.h>
1700 #endif
1702 #ifdef HAVE_EXECINFO_H
1703 #include <execinfo.h>
1704 #endif
1706 #ifdef HAVE_LIBEXC_H
1707 #include <libexc.h>
1708 #endif
1710 void log_stack_trace(void)
1712 #ifdef HAVE_LIBUNWIND
1713 /* Try to use libunwind before any other technique since on ia64
1714 * libunwind correctly walks the stack in more circumstances than
1715 * backtrace.
1717 unw_cursor_t cursor;
1718 unw_context_t uc;
1719 unsigned i = 0;
1721 char procname[256];
1722 unw_word_t ip, sp, off;
1724 procname[sizeof(procname) - 1] = '\0';
1726 if (unw_getcontext(&uc) != 0) {
1727 goto libunwind_failed;
1730 if (unw_init_local(&cursor, &uc) != 0) {
1731 goto libunwind_failed;
1734 DEBUG(0, ("BACKTRACE:\n"));
1736 do {
1737 ip = sp = 0;
1738 unw_get_reg(&cursor, UNW_REG_IP, &ip);
1739 unw_get_reg(&cursor, UNW_REG_SP, &sp);
1741 switch (unw_get_proc_name(&cursor,
1742 procname, sizeof(procname) - 1, &off) ) {
1743 case 0:
1744 /* Name found. */
1745 case -UNW_ENOMEM:
1746 /* Name truncated. */
1747 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1748 i, procname, (long long)off,
1749 (long long)ip, (long long) sp));
1750 break;
1751 default:
1752 /* case -UNW_ENOINFO: */
1753 /* case -UNW_EUNSPEC: */
1754 /* No symbol name found. */
1755 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1756 i, "<unknown symbol>",
1757 (long long)ip, (long long) sp));
1759 ++i;
1760 } while (unw_step(&cursor) > 0);
1762 return;
1764 libunwind_failed:
1765 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1767 #elif HAVE_BACKTRACE_SYMBOLS
1768 void *backtrace_stack[BACKTRACE_STACK_SIZE];
1769 size_t backtrace_size;
1770 char **backtrace_strings;
1772 /* get the backtrace (stack frames) */
1773 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1774 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1776 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1777 (unsigned long)backtrace_size));
1779 if (backtrace_strings) {
1780 int i;
1782 for (i = 0; i < backtrace_size; i++)
1783 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1785 /* Leak the backtrace_strings, rather than risk what free() might do */
1788 #elif HAVE_LIBEXC
1790 /* The IRIX libexc library provides an API for unwinding the stack. See
1791 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1792 * since we are about to abort anyway, it hardly matters.
1795 #define NAMESIZE 32 /* Arbitrary */
1797 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1798 char * names[BACKTRACE_STACK_SIZE];
1799 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1801 int i;
1802 int levels;
1804 ZERO_ARRAY(addrs);
1805 ZERO_ARRAY(names);
1806 ZERO_ARRAY(namebuf);
1808 /* We need to be root so we can open our /proc entry to walk
1809 * our stack. It also helps when we want to dump core.
1811 become_root();
1813 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1814 names[i] = namebuf + (i * NAMESIZE);
1817 levels = trace_back_stack(0, addrs, names,
1818 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1820 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1821 for (i = 0; i < levels; i++) {
1822 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1824 #undef NAMESIZE
1826 #else
1827 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1828 #endif
1831 /*******************************************************************
1832 A readdir wrapper which just returns the file name.
1833 ********************************************************************/
1835 const char *readdirname(SMB_STRUCT_DIR *p)
1837 SMB_STRUCT_DIRENT *ptr;
1838 char *dname;
1840 if (!p)
1841 return(NULL);
1843 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1844 if (!ptr)
1845 return(NULL);
1847 dname = ptr->d_name;
1849 #ifdef NEXT2
1850 if (telldir(p) < 0)
1851 return(NULL);
1852 #endif
1854 #ifdef HAVE_BROKEN_READDIR_NAME
1855 /* using /usr/ucb/cc is BAD */
1856 dname = dname - 2;
1857 #endif
1859 return talloc_strdup(talloc_tos(), dname);
1862 /*******************************************************************
1863 Utility function used to decide if the last component
1864 of a path matches a (possibly wildcarded) entry in a namelist.
1865 ********************************************************************/
1867 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1869 const char *last_component;
1871 /* if we have no list it's obviously not in the path */
1872 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1873 return False;
1876 DEBUG(8, ("is_in_path: %s\n", name));
1878 /* Get the last component of the unix name. */
1879 last_component = strrchr_m(name, '/');
1880 if (!last_component) {
1881 last_component = name;
1882 } else {
1883 last_component++; /* Go past '/' */
1886 for(; namelist->name != NULL; namelist++) {
1887 if(namelist->is_wild) {
1888 if (mask_match(last_component, namelist->name, case_sensitive)) {
1889 DEBUG(8,("is_in_path: mask match succeeded\n"));
1890 return True;
1892 } else {
1893 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1894 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1895 DEBUG(8,("is_in_path: match succeeded\n"));
1896 return True;
1900 DEBUG(8,("is_in_path: match not found\n"));
1901 return False;
1904 /*******************************************************************
1905 Strip a '/' separated list into an array of
1906 name_compare_enties structures suitable for
1907 passing to is_in_path(). We do this for
1908 speed so we can pre-parse all the names in the list
1909 and don't do it for each call to is_in_path().
1910 namelist is modified here and is assumed to be
1911 a copy owned by the caller.
1912 We also check if the entry contains a wildcard to
1913 remove a potentially expensive call to mask_match
1914 if possible.
1915 ********************************************************************/
1917 void set_namearray(name_compare_entry **ppname_array, const char *namelist)
1919 char *name_end;
1920 const char *nameptr = namelist;
1921 int num_entries = 0;
1922 int i;
1924 (*ppname_array) = NULL;
1926 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
1927 return;
1929 /* We need to make two passes over the string. The
1930 first to count the number of elements, the second
1931 to split it.
1934 while(*nameptr) {
1935 if ( *nameptr == '/' ) {
1936 /* cope with multiple (useless) /s) */
1937 nameptr++;
1938 continue;
1940 /* find the next / */
1941 name_end = strchr_m(nameptr, '/');
1943 /* oops - the last check for a / didn't find one. */
1944 if (name_end == NULL)
1945 break;
1947 /* next segment please */
1948 nameptr = name_end + 1;
1949 num_entries++;
1952 if(num_entries == 0)
1953 return;
1955 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1956 DEBUG(0,("set_namearray: malloc fail\n"));
1957 return;
1960 /* Now copy out the names */
1961 nameptr = namelist;
1962 i = 0;
1963 while(*nameptr) {
1964 if ( *nameptr == '/' ) {
1965 /* cope with multiple (useless) /s) */
1966 nameptr++;
1967 continue;
1969 /* find the next / */
1970 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1971 *name_end = 0;
1973 /* oops - the last check for a / didn't find one. */
1974 if(name_end == NULL)
1975 break;
1977 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1978 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1979 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1980 return;
1983 /* next segment please */
1984 nameptr = name_end + 1;
1985 i++;
1988 (*ppname_array)[i].name = NULL;
1990 return;
1993 /****************************************************************************
1994 Routine to free a namearray.
1995 ****************************************************************************/
1997 void free_namearray(name_compare_entry *name_array)
1999 int i;
2001 if(name_array == NULL)
2002 return;
2004 for(i=0; name_array[i].name!=NULL; i++)
2005 SAFE_FREE(name_array[i].name);
2006 SAFE_FREE(name_array);
2009 #undef DBGC_CLASS
2010 #define DBGC_CLASS DBGC_LOCKING
2012 /****************************************************************************
2013 Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
2014 is dealt with in posix.c
2015 Returns True if the lock was granted, False otherwise.
2016 ****************************************************************************/
2018 bool fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
2020 SMB_STRUCT_FLOCK lock;
2021 int ret;
2023 DEBUG(8,("fcntl_lock fd=%d op=%d offset=%.0f count=%.0f type=%d\n",
2024 fd,op,(double)offset,(double)count,type));
2026 lock.l_type = type;
2027 lock.l_whence = SEEK_SET;
2028 lock.l_start = offset;
2029 lock.l_len = count;
2030 lock.l_pid = 0;
2032 ret = sys_fcntl_ptr(fd,op,&lock);
2034 if (ret == -1) {
2035 int sav = errno;
2036 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
2037 (double)offset,(double)count,op,type,strerror(errno)));
2038 errno = sav;
2039 return False;
2042 /* everything went OK */
2043 DEBUG(8,("fcntl_lock: Lock call successful\n"));
2045 return True;
2048 /****************************************************************************
2049 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
2050 is dealt with in posix.c
2051 Returns True if we have information regarding this lock region (and returns
2052 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
2053 ****************************************************************************/
2055 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
2057 SMB_STRUCT_FLOCK lock;
2058 int ret;
2060 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
2061 fd,(double)*poffset,(double)*pcount,*ptype));
2063 lock.l_type = *ptype;
2064 lock.l_whence = SEEK_SET;
2065 lock.l_start = *poffset;
2066 lock.l_len = *pcount;
2067 lock.l_pid = 0;
2069 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
2071 if (ret == -1) {
2072 int sav = errno;
2073 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
2074 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
2075 errno = sav;
2076 return False;
2079 *ptype = lock.l_type;
2080 *poffset = lock.l_start;
2081 *pcount = lock.l_len;
2082 *ppid = lock.l_pid;
2084 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
2085 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
2086 return True;
2089 #undef DBGC_CLASS
2090 #define DBGC_CLASS DBGC_ALL
2092 /*******************************************************************
2093 Is the name specified one of my netbios names.
2094 Returns true if it is equal, false otherwise.
2095 ********************************************************************/
2097 bool is_myname(const char *s)
2099 int n;
2100 bool ret = False;
2102 for (n=0; my_netbios_names(n); n++) {
2103 if (strequal(my_netbios_names(n), s)) {
2104 ret=True;
2105 break;
2108 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2109 return(ret);
2112 /*******************************************************************
2113 Is the name specified our workgroup/domain.
2114 Returns true if it is equal, false otherwise.
2115 ********************************************************************/
2117 bool is_myworkgroup(const char *s)
2119 bool ret = False;
2121 if (strequal(s, lp_workgroup())) {
2122 ret=True;
2125 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
2126 return(ret);
2129 /*******************************************************************
2130 we distinguish between 2K and XP by the "Native Lan Manager" string
2131 WinXP => "Windows 2002 5.1"
2132 WinXP 64bit => "Windows XP 5.2"
2133 Win2k => "Windows 2000 5.0"
2134 NT4 => "Windows NT 4.0"
2135 Win9x => "Windows 4.0"
2136 Windows 2003 doesn't set the native lan manager string but
2137 they do set the domain to "Windows 2003 5.2" (probably a bug).
2138 ********************************************************************/
2140 void ra_lanman_string( const char *native_lanman )
2142 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
2143 set_remote_arch( RA_WINXP );
2144 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
2145 set_remote_arch( RA_WINXP64 );
2146 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
2147 set_remote_arch( RA_WIN2K3 );
2150 static const char *remote_arch_str;
2152 const char *get_remote_arch_str(void)
2154 if (!remote_arch_str) {
2155 return "UNKNOWN";
2157 return remote_arch_str;
2160 /*******************************************************************
2161 Set the horrid remote_arch string based on an enum.
2162 ********************************************************************/
2164 void set_remote_arch(enum remote_arch_types type)
2166 ra_type = type;
2167 switch( type ) {
2168 case RA_WFWG:
2169 remote_arch_str = "WfWg";
2170 break;
2171 case RA_OS2:
2172 remote_arch_str = "OS2";
2173 break;
2174 case RA_WIN95:
2175 remote_arch_str = "Win95";
2176 break;
2177 case RA_WINNT:
2178 remote_arch_str = "WinNT";
2179 break;
2180 case RA_WIN2K:
2181 remote_arch_str = "Win2K";
2182 break;
2183 case RA_WINXP:
2184 remote_arch_str = "WinXP";
2185 break;
2186 case RA_WINXP64:
2187 remote_arch_str = "WinXP64";
2188 break;
2189 case RA_WIN2K3:
2190 remote_arch_str = "Win2K3";
2191 break;
2192 case RA_VISTA:
2193 remote_arch_str = "Vista";
2194 break;
2195 case RA_SAMBA:
2196 remote_arch_str = "Samba";
2197 break;
2198 case RA_CIFSFS:
2199 remote_arch_str = "CIFSFS";
2200 break;
2201 default:
2202 ra_type = RA_UNKNOWN;
2203 remote_arch_str = "UNKNOWN";
2204 break;
2207 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
2208 remote_arch_str));
2211 /*******************************************************************
2212 Get the remote_arch type.
2213 ********************************************************************/
2215 enum remote_arch_types get_remote_arch(void)
2217 return ra_type;
2220 void print_asc(int level, const unsigned char *buf,int len)
2222 int i;
2223 for (i=0;i<len;i++)
2224 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2227 void dump_data(int level, const unsigned char *buf1,int len)
2229 const unsigned char *buf = (const unsigned char *)buf1;
2230 int i=0;
2231 if (len<=0) return;
2233 if (!DEBUGLVL(level)) return;
2235 DEBUGADD(level,("[%03X] ",i));
2236 for (i=0;i<len;) {
2237 DEBUGADD(level,("%02X ",(int)buf[i]));
2238 i++;
2239 if (i%8 == 0) DEBUGADD(level,(" "));
2240 if (i%16 == 0) {
2241 print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2242 print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2243 if (i<len) DEBUGADD(level,("[%03X] ",i));
2246 if (i%16) {
2247 int n;
2248 n = 16 - (i%16);
2249 DEBUGADD(level,(" "));
2250 if (n>8) DEBUGADD(level,(" "));
2251 while (n--) DEBUGADD(level,(" "));
2252 n = MIN(8,i%16);
2253 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2254 n = (i%16) - n;
2255 if (n>0) print_asc(level,&buf[i-n],n);
2256 DEBUGADD(level,("\n"));
2260 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2262 #ifdef DEBUG_PASSWORD
2263 DEBUG(11, ("%s", msg));
2264 if (data != NULL && len > 0)
2266 dump_data(11, data, len);
2268 #endif
2271 const char *tab_depth(int level, int depth)
2273 if( CHECK_DEBUGLVL(level) ) {
2274 dbgtext("%*s", depth*4, "");
2276 return "";
2279 /*****************************************************************************
2280 Provide a checksum on a string
2282 Input: s - the null-terminated character string for which the checksum
2283 will be calculated.
2285 Output: The checksum value calculated for s.
2286 *****************************************************************************/
2288 int str_checksum(const char *s)
2290 int res = 0;
2291 int c;
2292 int i=0;
2294 while(*s) {
2295 c = *s;
2296 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2297 s++;
2298 i++;
2300 return(res);
2303 /*****************************************************************
2304 Zero a memory area then free it. Used to catch bugs faster.
2305 *****************************************************************/
2307 void zero_free(void *p, size_t size)
2309 memset(p, 0, size);
2310 SAFE_FREE(p);
2313 /*****************************************************************
2314 Set our open file limit to a requested max and return the limit.
2315 *****************************************************************/
2317 int set_maxfiles(int requested_max)
2319 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2320 struct rlimit rlp;
2321 int saved_current_limit;
2323 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2324 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2325 strerror(errno) ));
2326 /* just guess... */
2327 return requested_max;
2331 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2332 * account for the extra fd we need
2333 * as well as the log files and standard
2334 * handles etc. Save the limit we want to set in case
2335 * we are running on an OS that doesn't support this limit (AIX)
2336 * which always returns RLIM_INFINITY for rlp.rlim_max.
2339 /* Try raising the hard (max) limit to the requested amount. */
2341 #if defined(RLIM_INFINITY)
2342 if (rlp.rlim_max != RLIM_INFINITY) {
2343 int orig_max = rlp.rlim_max;
2345 if ( rlp.rlim_max < requested_max )
2346 rlp.rlim_max = requested_max;
2348 /* This failing is not an error - many systems (Linux) don't
2349 support our default request of 10,000 open files. JRA. */
2351 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2352 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2353 (int)rlp.rlim_max, strerror(errno) ));
2355 /* Set failed - restore original value from get. */
2356 rlp.rlim_max = orig_max;
2359 #endif
2361 /* Now try setting the soft (current) limit. */
2363 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2365 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2366 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2367 (int)rlp.rlim_cur, strerror(errno) ));
2368 /* just guess... */
2369 return saved_current_limit;
2372 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2373 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2374 strerror(errno) ));
2375 /* just guess... */
2376 return saved_current_limit;
2379 #if defined(RLIM_INFINITY)
2380 if(rlp.rlim_cur == RLIM_INFINITY)
2381 return saved_current_limit;
2382 #endif
2384 if((int)rlp.rlim_cur > saved_current_limit)
2385 return saved_current_limit;
2387 return rlp.rlim_cur;
2388 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2390 * No way to know - just guess...
2392 return requested_max;
2393 #endif
2396 /*****************************************************************
2397 Possibly replace mkstemp if it is broken.
2398 *****************************************************************/
2400 int smb_mkstemp(char *name_template)
2402 #if HAVE_SECURE_MKSTEMP
2403 return mkstemp(name_template);
2404 #else
2405 /* have a reasonable go at emulating it. Hope that
2406 the system mktemp() isn't completly hopeless */
2407 char *p = mktemp(name_template);
2408 if (!p)
2409 return -1;
2410 return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2411 #endif
2414 /*****************************************************************
2415 malloc that aborts with smb_panic on fail or zero size.
2416 *****************************************************************/
2418 void *smb_xmalloc_array(size_t size, unsigned int count)
2420 void *p;
2421 if (size == 0) {
2422 smb_panic("smb_xmalloc_array: called with zero size");
2424 if (count >= MAX_ALLOC_SIZE/size) {
2425 smb_panic("smb_xmalloc_array: alloc size too large");
2427 if ((p = SMB_MALLOC(size*count)) == NULL) {
2428 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2429 (unsigned long)size, (unsigned long)count));
2430 smb_panic("smb_xmalloc_array: malloc failed");
2432 return p;
2436 Memdup with smb_panic on fail.
2439 void *smb_xmemdup(const void *p, size_t size)
2441 void *p2;
2442 p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2443 memcpy(p2, p, size);
2444 return p2;
2448 strdup that aborts on malloc fail.
2451 char *smb_xstrdup(const char *s)
2453 #if defined(PARANOID_MALLOC_CHECKER)
2454 #ifdef strdup
2455 #undef strdup
2456 #endif
2457 #endif
2459 #ifndef HAVE_STRDUP
2460 #define strdup rep_strdup
2461 #endif
2463 char *s1 = strdup(s);
2464 #if defined(PARANOID_MALLOC_CHECKER)
2465 #ifdef strdup
2466 #undef strdup
2467 #endif
2468 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2469 #endif
2470 if (!s1) {
2471 smb_panic("smb_xstrdup: malloc failed");
2473 return s1;
2478 strndup that aborts on malloc fail.
2481 char *smb_xstrndup(const char *s, size_t n)
2483 #if defined(PARANOID_MALLOC_CHECKER)
2484 #ifdef strndup
2485 #undef strndup
2486 #endif
2487 #endif
2489 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
2490 #undef HAVE_STRNDUP
2491 #define strndup rep_strndup
2492 #endif
2494 char *s1 = strndup(s, n);
2495 #if defined(PARANOID_MALLOC_CHECKER)
2496 #ifdef strndup
2497 #undef strndup
2498 #endif
2499 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2500 #endif
2501 if (!s1) {
2502 smb_panic("smb_xstrndup: malloc failed");
2504 return s1;
2508 vasprintf that aborts on malloc fail
2511 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2513 int n;
2514 va_list ap2;
2516 VA_COPY(ap2, ap);
2518 n = vasprintf(ptr, format, ap2);
2519 if (n == -1 || ! *ptr) {
2520 smb_panic("smb_xvasprintf: out of memory");
2522 va_end(ap2);
2523 return n;
2526 /*****************************************************************
2527 Like strdup but for memory.
2528 *****************************************************************/
2530 void *memdup(const void *p, size_t size)
2532 void *p2;
2533 if (size == 0)
2534 return NULL;
2535 p2 = SMB_MALLOC(size);
2536 if (!p2)
2537 return NULL;
2538 memcpy(p2, p, size);
2539 return p2;
2542 /*****************************************************************
2543 Get local hostname and cache result.
2544 *****************************************************************/
2546 char *myhostname(void)
2548 static char *ret;
2549 if (ret == NULL) {
2550 /* This is cached forever so
2551 * use autofree talloc ctx. */
2552 ret = get_myname(talloc_autofree_context());
2554 return ret;
2557 /*****************************************************************
2558 A useful function for returning a path in the Samba pid directory.
2559 *****************************************************************/
2561 static char *xx_path(const char *name, const char *rootpath)
2563 char *fname = NULL;
2565 fname = talloc_strdup(talloc_tos(), rootpath);
2566 if (!fname) {
2567 return NULL;
2569 trim_string(fname,"","/");
2571 if (!directory_exist(fname,NULL)) {
2572 mkdir(fname,0755);
2575 return talloc_asprintf(talloc_tos(),
2576 "%s/%s",
2577 fname,
2578 name);
2581 /*****************************************************************
2582 A useful function for returning a path in the Samba lock directory.
2583 *****************************************************************/
2585 char *lock_path(const char *name)
2587 return xx_path(name, lp_lockdir());
2590 /*****************************************************************
2591 A useful function for returning a path in the Samba pid directory.
2592 *****************************************************************/
2594 char *pid_path(const char *name)
2596 return xx_path(name, lp_piddir());
2600 * @brief Returns an absolute path to a file in the Samba lib directory.
2602 * @param name File to find, relative to LIBDIR.
2604 * @retval Pointer to a string containing the full path.
2607 char *lib_path(const char *name)
2609 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
2613 * @brief Returns an absolute path to a file in the Samba modules directory.
2615 * @param name File to find, relative to MODULESDIR.
2617 * @retval Pointer to a string containing the full path.
2620 char *modules_path(const char *name)
2622 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_MODULESDIR(), name);
2626 * @brief Returns an absolute path to a file in the Samba data directory.
2628 * @param name File to find, relative to CODEPAGEDIR.
2630 * @retval Pointer to a talloc'ed string containing the full path.
2633 char *data_path(const char *name)
2635 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
2638 /*****************************************************************
2639 a useful function for returning a path in the Samba state directory
2640 *****************************************************************/
2642 char *state_path(const char *name)
2644 return xx_path(name, get_dyn_STATEDIR());
2648 * @brief Returns the platform specific shared library extension.
2650 * @retval Pointer to a const char * containing the extension.
2653 const char *shlib_ext(void)
2655 return get_dyn_SHLIBEXT();
2658 /*******************************************************************
2659 Given a filename - get its directory name
2660 NB: Returned in static storage. Caveats:
2661 o If caller wishes to preserve, they should copy.
2662 ********************************************************************/
2664 char *parent_dirname(const char *path)
2666 char *parent;
2668 if (!parent_dirname_talloc(talloc_tos(), path, &parent, NULL)) {
2669 return NULL;
2672 return parent;
2675 bool parent_dirname_talloc(TALLOC_CTX *mem_ctx, const char *dir,
2676 char **parent, const char **name)
2678 char *p;
2679 ptrdiff_t len;
2681 p = strrchr_m(dir, '/'); /* Find final '/', if any */
2683 if (p == NULL) {
2684 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2685 return False;
2687 if (name) {
2688 *name = "";
2690 return True;
2693 len = p-dir;
2695 if (!(*parent = TALLOC_ARRAY(mem_ctx, char, len+1))) {
2696 return False;
2698 memcpy(*parent, dir, len);
2699 (*parent)[len] = '\0';
2701 if (name) {
2702 *name = p+1;
2704 return True;
2707 /*******************************************************************
2708 Determine if a pattern contains any Microsoft wildcard characters.
2709 *******************************************************************/
2711 bool ms_has_wild(const char *s)
2713 char c;
2715 if (lp_posix_pathnames()) {
2716 /* With posix pathnames no characters are wild. */
2717 return False;
2720 while ((c = *s++)) {
2721 switch (c) {
2722 case '*':
2723 case '?':
2724 case '<':
2725 case '>':
2726 case '"':
2727 return True;
2730 return False;
2733 bool ms_has_wild_w(const smb_ucs2_t *s)
2735 smb_ucs2_t c;
2736 if (!s) return False;
2737 while ((c = *s++)) {
2738 switch (c) {
2739 case UCS2_CHAR('*'):
2740 case UCS2_CHAR('?'):
2741 case UCS2_CHAR('<'):
2742 case UCS2_CHAR('>'):
2743 case UCS2_CHAR('"'):
2744 return True;
2747 return False;
2750 /*******************************************************************
2751 A wrapper that handles case sensitivity and the special handling
2752 of the ".." name.
2753 *******************************************************************/
2755 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
2757 if (strcmp(string,"..") == 0)
2758 string = ".";
2759 if (strcmp(pattern,".") == 0)
2760 return False;
2762 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2765 /*******************************************************************
2766 A wrapper that handles case sensitivity and the special handling
2767 of the ".." name. Varient that is only called by old search code which requires
2768 pattern translation.
2769 *******************************************************************/
2771 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
2773 if (strcmp(string,"..") == 0)
2774 string = ".";
2775 if (strcmp(pattern,".") == 0)
2776 return False;
2778 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2781 /*******************************************************************
2782 A wrapper that handles a list of patters and calls mask_match()
2783 on each. Returns True if any of the patterns match.
2784 *******************************************************************/
2786 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
2788 while (listLen-- > 0) {
2789 if (mask_match(string, *list++, is_case_sensitive))
2790 return True;
2792 return False;
2795 /*********************************************************
2796 Recursive routine that is called by unix_wild_match.
2797 *********************************************************/
2799 static bool unix_do_match(const char *regexp, const char *str)
2801 const char *p;
2803 for( p = regexp; *p && *str; ) {
2805 switch(*p) {
2806 case '?':
2807 str++;
2808 p++;
2809 break;
2811 case '*':
2814 * Look for a character matching
2815 * the one after the '*'.
2817 p++;
2818 if(!*p)
2819 return true; /* Automatic match */
2820 while(*str) {
2822 while(*str && (*p != *str))
2823 str++;
2826 * Patch from weidel@multichart.de. In the case of the regexp
2827 * '*XX*' we want to ensure there are at least 2 'X' characters
2828 * in the string after the '*' for a match to be made.
2832 int matchcount=0;
2835 * Eat all the characters that match, but count how many there were.
2838 while(*str && (*p == *str)) {
2839 str++;
2840 matchcount++;
2844 * Now check that if the regexp had n identical characters that
2845 * matchcount had at least that many matches.
2848 while ( *(p+1) && (*(p+1) == *p)) {
2849 p++;
2850 matchcount--;
2853 if ( matchcount <= 0 )
2854 return false;
2857 str--; /* We've eaten the match char after the '*' */
2859 if(unix_do_match(p, str))
2860 return true;
2862 if(!*str)
2863 return false;
2864 else
2865 str++;
2867 return false;
2869 default:
2870 if(*str != *p)
2871 return false;
2872 str++;
2873 p++;
2874 break;
2878 if(!*p && !*str)
2879 return true;
2881 if (!*p && str[0] == '.' && str[1] == 0)
2882 return true;
2884 if (!*str && *p == '?') {
2885 while (*p == '?')
2886 p++;
2887 return(!*p);
2890 if(!*str && (*p == '*' && p[1] == '\0'))
2891 return true;
2893 return false;
2896 /*******************************************************************
2897 Simple case insensitive interface to a UNIX wildcard matcher.
2898 Returns True if match, False if not.
2899 *******************************************************************/
2901 bool unix_wild_match(const char *pattern, const char *string)
2903 TALLOC_CTX *ctx = talloc_stackframe();
2904 char *p2;
2905 char *s2;
2906 char *p;
2907 bool ret = false;
2909 p2 = talloc_strdup(ctx,pattern);
2910 s2 = talloc_strdup(ctx,string);
2911 if (!p2 || !s2) {
2912 TALLOC_FREE(ctx);
2913 return false;
2915 strlower_m(p2);
2916 strlower_m(s2);
2918 /* Remove any *? and ** from the pattern as they are meaningless */
2919 for(p = p2; *p; p++) {
2920 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
2921 memmove(&p[1], &p[2], strlen(&p[2])+1);
2925 if (strequal(p2,"*")) {
2926 TALLOC_FREE(ctx);
2927 return true;
2930 ret = unix_do_match(p2, s2);
2931 TALLOC_FREE(ctx);
2932 return ret;
2935 /**********************************************************************
2936 Converts a name to a fully qualified domain name.
2937 Returns true if lookup succeeded, false if not (then fqdn is set to name)
2938 Note we deliberately use gethostbyname here, not getaddrinfo as we want
2939 to examine the h_aliases and I don't know how to do that with getaddrinfo.
2940 ***********************************************************************/
2942 bool name_to_fqdn(fstring fqdn, const char *name)
2944 char *full = NULL;
2945 struct hostent *hp = gethostbyname(name);
2947 if (!hp || !hp->h_name || !*hp->h_name) {
2948 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2949 fstrcpy(fqdn, name);
2950 return false;
2953 /* Find out if the fqdn is returned as an alias
2954 * to cope with /etc/hosts files where the first
2955 * name is not the fqdn but the short name */
2956 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2957 int i;
2958 for (i = 0; hp->h_aliases[i]; i++) {
2959 if (strchr_m(hp->h_aliases[i], '.')) {
2960 full = hp->h_aliases[i];
2961 break;
2965 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2966 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2967 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2968 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
2969 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
2970 full = hp->h_name;
2972 if (!full) {
2973 full = hp->h_name;
2976 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2977 fstrcpy(fqdn, full);
2978 return true;
2981 /**********************************************************************
2982 Extension to talloc_get_type: Abort on type mismatch
2983 ***********************************************************************/
2985 void *talloc_check_name_abort(const void *ptr, const char *name)
2987 void *result;
2989 result = talloc_check_name(ptr, name);
2990 if (result != NULL)
2991 return result;
2993 DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2994 name, talloc_get_name(ptr)));
2995 smb_panic("talloc type mismatch");
2996 /* Keep the compiler happy */
2997 return NULL;
3000 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
3002 switch (share_access & ~FILE_SHARE_DELETE) {
3003 case FILE_SHARE_NONE:
3004 return DENY_ALL;
3005 case FILE_SHARE_READ:
3006 return DENY_WRITE;
3007 case FILE_SHARE_WRITE:
3008 return DENY_READ;
3009 case FILE_SHARE_READ|FILE_SHARE_WRITE:
3010 return DENY_NONE;
3012 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
3013 return DENY_DOS;
3014 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
3015 return DENY_FCB;
3018 return (uint32)-1;
3021 pid_t procid_to_pid(const struct server_id *proc)
3023 return proc->pid;
3026 static uint32 my_vnn = NONCLUSTER_VNN;
3028 void set_my_vnn(uint32 vnn)
3030 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
3031 my_vnn = vnn;
3034 uint32 get_my_vnn(void)
3036 return my_vnn;
3039 struct server_id pid_to_procid(pid_t pid)
3041 struct server_id result;
3042 result.pid = pid;
3043 #ifdef CLUSTER_SUPPORT
3044 result.vnn = my_vnn;
3045 #endif
3046 return result;
3049 struct server_id procid_self(void)
3051 return pid_to_procid(sys_getpid());
3054 struct server_id server_id_self(void)
3056 return procid_self();
3059 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
3061 if (p1->pid != p2->pid)
3062 return False;
3063 #ifdef CLUSTER_SUPPORT
3064 if (p1->vnn != p2->vnn)
3065 return False;
3066 #endif
3067 return True;
3070 bool cluster_id_equal(const struct server_id *id1,
3071 const struct server_id *id2)
3073 return procid_equal(id1, id2);
3076 bool procid_is_me(const struct server_id *pid)
3078 if (pid->pid != sys_getpid())
3079 return False;
3080 #ifdef CLUSTER_SUPPORT
3081 if (pid->vnn != my_vnn)
3082 return False;
3083 #endif
3084 return True;
3087 struct server_id interpret_pid(const char *pid_string)
3089 #ifdef CLUSTER_SUPPORT
3090 unsigned int vnn, pid;
3091 struct server_id result;
3092 if (sscanf(pid_string, "%u:%u", &vnn, &pid) == 2) {
3093 result.vnn = vnn;
3094 result.pid = pid;
3096 else if (sscanf(pid_string, "%u", &pid) == 1) {
3097 result.vnn = get_my_vnn();
3098 result.pid = pid;
3100 else {
3101 result.vnn = NONCLUSTER_VNN;
3102 result.pid = -1;
3104 return result;
3105 #else
3106 return pid_to_procid(atoi(pid_string));
3107 #endif
3110 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
3112 #ifdef CLUSTER_SUPPORT
3113 if (pid->vnn == NONCLUSTER_VNN) {
3114 return talloc_asprintf(mem_ctx,
3115 "%d",
3116 (int)pid->pid);
3118 else {
3119 return talloc_asprintf(mem_ctx,
3120 "%u:%d",
3121 (unsigned)pid->vnn,
3122 (int)pid->pid);
3124 #else
3125 return talloc_asprintf(mem_ctx,
3126 "%d",
3127 (int)pid->pid);
3128 #endif
3131 char *procid_str_static(const struct server_id *pid)
3133 return procid_str(talloc_tos(), pid);
3136 bool procid_valid(const struct server_id *pid)
3138 return (pid->pid != -1);
3141 bool procid_is_local(const struct server_id *pid)
3143 #ifdef CLUSTER_SUPPORT
3144 return pid->vnn == my_vnn;
3145 #else
3146 return True;
3147 #endif
3150 int this_is_smp(void)
3152 #if defined(HAVE_SYSCONF)
3154 #if defined(SYSCONF_SC_NPROC_ONLN)
3155 return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
3156 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3157 return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
3158 #else
3159 return 0;
3160 #endif
3162 #else
3163 return 0;
3164 #endif
3167 /****************************************************************
3168 Check if an offset into a buffer is safe.
3169 If this returns True it's safe to indirect into the byte at
3170 pointer ptr+off.
3171 ****************************************************************/
3173 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3175 const char *end_base = buf_base + buf_len;
3176 char *end_ptr = ptr + off;
3178 if (!buf_base || !ptr) {
3179 return False;
3182 if (end_base < buf_base || end_ptr < ptr) {
3183 return False; /* wrap. */
3186 if (end_ptr < end_base) {
3187 return True;
3189 return False;
3192 /****************************************************************
3193 Return a safe pointer into a buffer, or NULL.
3194 ****************************************************************/
3196 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3198 return is_offset_safe(buf_base, buf_len, ptr, off) ?
3199 ptr + off : NULL;
3202 /****************************************************************
3203 Return a safe pointer into a string within a buffer, or NULL.
3204 ****************************************************************/
3206 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3208 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
3209 return NULL;
3211 /* Check if a valid string exists at this offset. */
3212 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
3213 return NULL;
3215 return ptr + off;
3218 /****************************************************************
3219 Return an SVAL at a pointer, or failval if beyond the end.
3220 ****************************************************************/
3222 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3225 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
3226 * NOT ptr[2].
3228 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
3229 return failval;
3231 return SVAL(ptr,off);
3234 /****************************************************************
3235 Return an IVAL at a pointer, or failval if beyond the end.
3236 ****************************************************************/
3238 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3241 * Note we use off+3 here, not off+4 as IVAL accesses
3242 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
3244 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
3245 return failval;
3247 return IVAL(ptr,off);
3250 /****************************************************************
3251 Split DOM\user into DOM and user. Do not mix with winbind variants of that
3252 call (they take care of winbind separator and other winbind specific settings).
3253 ****************************************************************/
3255 void split_domain_user(TALLOC_CTX *mem_ctx,
3256 const char *full_name,
3257 char **domain,
3258 char **user)
3260 const char *p = NULL;
3262 p = strchr_m(full_name, '\\');
3264 if (p != NULL) {
3265 *domain = talloc_strndup(mem_ctx, full_name,
3266 PTR_DIFF(p, full_name));
3267 *user = talloc_strdup(mem_ctx, p+1);
3268 } else {
3269 *domain = talloc_strdup(mem_ctx, "");
3270 *user = talloc_strdup(mem_ctx, full_name);
3274 #if 0
3276 Disable these now we have checked all code paths and ensured
3277 NULL returns on zero request. JRA.
3279 /****************************************************************
3280 talloc wrapper functions that guarentee a null pointer return
3281 if size == 0.
3282 ****************************************************************/
3284 #ifndef MAX_TALLOC_SIZE
3285 #define MAX_TALLOC_SIZE 0x10000000
3286 #endif
3289 * talloc and zero memory.
3290 * - returns NULL if size is zero.
3293 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
3295 void *p;
3297 if (size == 0) {
3298 return NULL;
3301 p = talloc_named_const(ctx, size, name);
3303 if (p) {
3304 memset(p, '\0', size);
3307 return p;
3311 * memdup with a talloc.
3312 * - returns NULL if size is zero.
3315 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
3317 void *newp;
3319 if (size == 0) {
3320 return NULL;
3323 newp = talloc_named_const(t, size, name);
3324 if (newp) {
3325 memcpy(newp, p, size);
3328 return newp;
3332 * alloc an array, checking for integer overflow in the array size.
3333 * - returns NULL if count or el_size are zero.
3336 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3338 if (count >= MAX_TALLOC_SIZE/el_size) {
3339 return NULL;
3342 if (el_size == 0 || count == 0) {
3343 return NULL;
3346 return talloc_named_const(ctx, el_size * count, name);
3350 * alloc an zero array, checking for integer overflow in the array size
3351 * - returns NULL if count or el_size are zero.
3354 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3356 if (count >= MAX_TALLOC_SIZE/el_size) {
3357 return NULL;
3360 if (el_size == 0 || count == 0) {
3361 return NULL;
3364 return _talloc_zero(ctx, el_size * count, name);
3368 * Talloc wrapper that returns NULL if size == 0.
3370 void *talloc_zeronull(const void *context, size_t size, const char *name)
3372 if (size == 0) {
3373 return NULL;
3375 return talloc_named_const(context, size, name);
3377 #endif
3379 /* Split a path name into filename and stream name components. Canonicalise
3380 * such that an implicit $DATA token is always explicit.
3382 * The "specification" of this function can be found in the
3383 * run_local_stream_name() function in torture.c, I've tried those
3384 * combinations against a W2k3 server.
3387 NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
3388 char **pbase, char **pstream)
3390 char *base = NULL;
3391 char *stream = NULL;
3392 char *sname; /* stream name */
3393 const char *stype; /* stream type */
3395 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
3397 sname = strchr_m(fname, ':');
3399 if (lp_posix_pathnames() || (sname == NULL)) {
3400 if (pbase != NULL) {
3401 base = talloc_strdup(mem_ctx, fname);
3402 NT_STATUS_HAVE_NO_MEMORY(base);
3404 goto done;
3407 if (pbase != NULL) {
3408 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
3409 NT_STATUS_HAVE_NO_MEMORY(base);
3412 sname += 1;
3414 stype = strchr_m(sname, ':');
3416 if (stype == NULL) {
3417 sname = talloc_strdup(mem_ctx, sname);
3418 stype = "$DATA";
3420 else {
3421 if (StrCaseCmp(stype, ":$DATA") != 0) {
3423 * If there is an explicit stream type, so far we only
3424 * allow $DATA. Is there anything else allowed? -- vl
3426 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
3427 TALLOC_FREE(base);
3428 return NT_STATUS_OBJECT_NAME_INVALID;
3430 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
3431 stype += 1;
3434 if (sname == NULL) {
3435 TALLOC_FREE(base);
3436 return NT_STATUS_NO_MEMORY;
3439 if (sname[0] == '\0') {
3441 * no stream name, so no stream
3443 goto done;
3446 if (pstream != NULL) {
3447 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
3448 if (stream == NULL) {
3449 TALLOC_FREE(sname);
3450 TALLOC_FREE(base);
3451 return NT_STATUS_NO_MEMORY;
3454 * upper-case the type field
3456 strupper_m(strchr_m(stream, ':')+1);
3459 done:
3460 if (pbase != NULL) {
3461 *pbase = base;
3463 if (pstream != NULL) {
3464 *pstream = stream;
3466 return NT_STATUS_OK;
3469 bool is_valid_policy_hnd(const POLICY_HND *hnd)
3471 POLICY_HND tmp;
3472 ZERO_STRUCT(tmp);
3473 return (memcmp(&tmp, hnd, sizeof(tmp)) != 0);
3476 bool policy_hnd_equal(const struct policy_handle *hnd1,
3477 const struct policy_handle *hnd2)
3479 if (!hnd1 || !hnd2) {
3480 return false;
3483 return (memcmp(hnd1, hnd2, sizeof(*hnd1)) == 0);
3486 /****************************************************************
3487 strip off leading '\\' from a hostname
3488 ****************************************************************/
3490 const char *strip_hostname(const char *s)
3492 if (!s) {
3493 return NULL;
3496 if (strlen_m(s) < 3) {
3497 return s;
3500 if (s[0] == '\\') s++;
3501 if (s[0] == '\\') s++;
3503 return s;