Fix more POSIX path lstat calls. Fix bug where close can return
[Samba.git] / source / lib / util.c
blob002c14a66b0d8b69a49a1bc8a11426c820f4a942
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 int trans_num = 0;
65 static enum remote_arch_types ra_type = RA_UNKNOWN;
67 /***********************************************************************
68 Definitions for all names.
69 ***********************************************************************/
71 static char *smb_myname;
72 static char *smb_myworkgroup;
73 static char *smb_scope;
74 static int smb_num_netbios_names;
75 static char **smb_my_netbios_names;
77 /***********************************************************************
78 Allocate and set myname. Ensure upper case.
79 ***********************************************************************/
81 bool set_global_myname(const char *myname)
83 SAFE_FREE(smb_myname);
84 smb_myname = SMB_STRDUP(myname);
85 if (!smb_myname)
86 return False;
87 strupper_m(smb_myname);
88 return True;
91 const char *global_myname(void)
93 return smb_myname;
96 /***********************************************************************
97 Allocate and set myworkgroup. Ensure upper case.
98 ***********************************************************************/
100 bool set_global_myworkgroup(const char *myworkgroup)
102 SAFE_FREE(smb_myworkgroup);
103 smb_myworkgroup = SMB_STRDUP(myworkgroup);
104 if (!smb_myworkgroup)
105 return False;
106 strupper_m(smb_myworkgroup);
107 return True;
110 const char *lp_workgroup(void)
112 return smb_myworkgroup;
115 /***********************************************************************
116 Allocate and set scope. Ensure upper case.
117 ***********************************************************************/
119 bool set_global_scope(const char *scope)
121 SAFE_FREE(smb_scope);
122 smb_scope = SMB_STRDUP(scope);
123 if (!smb_scope)
124 return False;
125 strupper_m(smb_scope);
126 return True;
129 /*********************************************************************
130 Ensure scope is never null string.
131 *********************************************************************/
133 const char *global_scope(void)
135 if (!smb_scope)
136 set_global_scope("");
137 return smb_scope;
140 static void free_netbios_names_array(void)
142 int i;
144 for (i = 0; i < smb_num_netbios_names; i++)
145 SAFE_FREE(smb_my_netbios_names[i]);
147 SAFE_FREE(smb_my_netbios_names);
148 smb_num_netbios_names = 0;
151 static bool allocate_my_netbios_names_array(size_t number)
153 free_netbios_names_array();
155 smb_num_netbios_names = number + 1;
156 smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
158 if (!smb_my_netbios_names)
159 return False;
161 memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
162 return True;
165 static bool set_my_netbios_names(const char *name, int i)
167 SAFE_FREE(smb_my_netbios_names[i]);
169 smb_my_netbios_names[i] = SMB_STRDUP(name);
170 if (!smb_my_netbios_names[i])
171 return False;
172 strupper_m(smb_my_netbios_names[i]);
173 return True;
176 /***********************************************************************
177 Free memory allocated to global objects
178 ***********************************************************************/
180 void gfree_names(void)
182 SAFE_FREE( smb_myname );
183 SAFE_FREE( smb_myworkgroup );
184 SAFE_FREE( smb_scope );
185 free_netbios_names_array();
186 free_local_machine_name();
189 void gfree_all( void )
191 gfree_names();
192 gfree_loadparm();
193 gfree_case_tables();
194 gfree_charcnv();
195 gfree_interfaces();
196 gfree_debugsyms();
199 const char *my_netbios_names(int i)
201 return smb_my_netbios_names[i];
204 bool set_netbios_aliases(const char **str_array)
206 size_t namecount;
208 /* Work out the max number of netbios aliases that we have */
209 for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
212 if ( global_myname() && *global_myname())
213 namecount++;
215 /* Allocate space for the netbios aliases */
216 if (!allocate_my_netbios_names_array(namecount))
217 return False;
219 /* Use the global_myname string first */
220 namecount=0;
221 if ( global_myname() && *global_myname()) {
222 set_my_netbios_names( global_myname(), namecount );
223 namecount++;
226 if (str_array) {
227 size_t i;
228 for ( i = 0; str_array[i] != NULL; i++) {
229 size_t n;
230 bool duplicate = False;
232 /* Look for duplicates */
233 for( n=0; n<namecount; n++ ) {
234 if( strequal( str_array[i], my_netbios_names(n) ) ) {
235 duplicate = True;
236 break;
239 if (!duplicate) {
240 if (!set_my_netbios_names(str_array[i], namecount))
241 return False;
242 namecount++;
246 return True;
249 /****************************************************************************
250 Common name initialization code.
251 ****************************************************************************/
253 bool init_names(void)
255 int n;
257 if (global_myname() == NULL || *global_myname() == '\0') {
258 if (!set_global_myname(myhostname())) {
259 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
260 return False;
264 if (!set_netbios_aliases(lp_netbios_aliases())) {
265 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
266 return False;
269 set_local_machine_name(global_myname(),false);
271 DEBUG( 5, ("Netbios name list:-\n") );
272 for( n=0; my_netbios_names(n); n++ ) {
273 DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",
274 n, my_netbios_names(n) ) );
277 return( True );
280 /**************************************************************************n
281 Code to cope with username/password auth options from the commandline.
282 Used mainly in client tools.
283 ****************************************************************************/
285 static struct user_auth_info cmdline_auth_info = {
286 NULL, /* username */
287 NULL, /* password */
288 false, /* got_pass */
289 false, /* use_kerberos */
290 Undefined, /* signing state */
291 false, /* smb_encrypt */
292 false /* use machine account */
295 const char *get_cmdline_auth_info_username(void)
297 if (!cmdline_auth_info.username) {
298 return "";
300 return cmdline_auth_info.username;
303 void set_cmdline_auth_info_username(const char *username)
305 SAFE_FREE(cmdline_auth_info.username);
306 cmdline_auth_info.username = SMB_STRDUP(username);
307 if (!cmdline_auth_info.username) {
308 exit(ENOMEM);
312 const char *get_cmdline_auth_info_password(void)
314 if (!cmdline_auth_info.password) {
315 return "";
317 return cmdline_auth_info.password;
320 void set_cmdline_auth_info_password(const char *password)
322 SAFE_FREE(cmdline_auth_info.password);
323 cmdline_auth_info.password = SMB_STRDUP(password);
324 if (!cmdline_auth_info.password) {
325 exit(ENOMEM);
327 cmdline_auth_info.got_pass = true;
330 bool set_cmdline_auth_info_signing_state(const char *arg)
332 cmdline_auth_info.signing_state = -1;
333 if (strequal(arg, "off") || strequal(arg, "no") ||
334 strequal(arg, "false")) {
335 cmdline_auth_info.signing_state = false;
336 } else if (strequal(arg, "on") || strequal(arg, "yes") ||
337 strequal(arg, "true") || strequal(arg, "auto")) {
338 cmdline_auth_info.signing_state = true;
339 } else if (strequal(arg, "force") || strequal(arg, "required") ||
340 strequal(arg, "forced")) {
341 cmdline_auth_info.signing_state = Required;
342 } else {
343 return false;
345 return true;
348 int get_cmdline_auth_info_signing_state(void)
350 return cmdline_auth_info.signing_state;
353 bool get_cmdline_auth_info_use_kerberos(void)
355 return cmdline_auth_info.use_kerberos;
358 /* This should only be used by lib/popt_common.c JRA */
359 void set_cmdline_auth_info_use_krb5_ticket(void)
361 cmdline_auth_info.use_kerberos = true;
362 cmdline_auth_info.got_pass = true;
365 /* This should only be used by lib/popt_common.c JRA */
366 void set_cmdline_auth_info_smb_encrypt(void)
368 cmdline_auth_info.smb_encrypt = true;
371 void set_cmdline_auth_info_use_machine_account(void)
373 cmdline_auth_info.use_machine_account = true;
376 bool get_cmdline_auth_info_got_pass(void)
378 return cmdline_auth_info.got_pass;
381 bool get_cmdline_auth_info_smb_encrypt(void)
383 return cmdline_auth_info.smb_encrypt;
386 bool get_cmdline_auth_info_use_machine_account(void)
388 return cmdline_auth_info.use_machine_account;
391 bool get_cmdline_auth_info_copy(struct user_auth_info *info)
393 *info = cmdline_auth_info;
394 /* Now re-alloc the strings. */
395 info->username = SMB_STRDUP(get_cmdline_auth_info_username());
396 info->password = SMB_STRDUP(get_cmdline_auth_info_password());
397 if (!info->username || !info->password) {
398 return false;
400 return true;
403 bool set_cmdline_auth_info_machine_account_creds(void)
405 char *pass = NULL;
406 char *account = NULL;
408 if (!get_cmdline_auth_info_use_machine_account()) {
409 return false;
412 if (!secrets_init()) {
413 d_printf("ERROR: Unable to open secrets database\n");
414 return false;
417 if (asprintf(&account, "%s$@%s", global_myname(), lp_realm()) < 0) {
418 return false;
421 pass = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
422 if (!pass) {
423 d_printf("ERROR: Unable to fetch machine password for "
424 "%s in domain %s\n",
425 account, lp_workgroup());
426 SAFE_FREE(account);
427 return false;
430 set_cmdline_auth_info_username(account);
431 set_cmdline_auth_info_password(pass);
433 SAFE_FREE(account);
434 SAFE_FREE(pass);
436 return true;
439 /**************************************************************************n
440 Find a suitable temporary directory. The result should be copied immediately
441 as it may be overwritten by a subsequent call.
442 ****************************************************************************/
444 const char *tmpdir(void)
446 char *p;
447 if ((p = getenv("TMPDIR")))
448 return p;
449 return "/tmp";
452 /****************************************************************************
453 Add a gid to an array of gids if it's not already there.
454 ****************************************************************************/
456 bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
457 gid_t **gids, size_t *num_gids)
459 int i;
461 if ((*num_gids != 0) && (*gids == NULL)) {
463 * A former call to this routine has failed to allocate memory
465 return False;
468 for (i=0; i<*num_gids; i++) {
469 if ((*gids)[i] == gid) {
470 return True;
474 *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1);
475 if (*gids == NULL) {
476 *num_gids = 0;
477 return False;
480 (*gids)[*num_gids] = gid;
481 *num_gids += 1;
482 return True;
485 /****************************************************************************
486 Like atoi but gets the value up to the separator character.
487 ****************************************************************************/
489 static const char *Atoic(const char *p, int *n, const char *c)
491 if (!isdigit((int)*p)) {
492 DEBUG(5, ("Atoic: malformed number\n"));
493 return NULL;
496 (*n) = atoi(p);
498 while ((*p) && isdigit((int)*p))
499 p++;
501 if (strchr_m(c, *p) == NULL) {
502 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
503 return NULL;
506 return p;
509 /*************************************************************************
510 Reads a list of numbers.
511 *************************************************************************/
513 const char *get_numlist(const char *p, uint32 **num, int *count)
515 int val;
517 if (num == NULL || count == NULL)
518 return NULL;
520 (*count) = 0;
521 (*num ) = NULL;
523 while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
524 *num = SMB_REALLOC_ARRAY((*num), uint32, (*count)+1);
525 if (!(*num)) {
526 return NULL;
528 (*num)[(*count)] = val;
529 (*count)++;
530 p++;
533 return p;
536 /*******************************************************************
537 Check if a file exists - call vfs_file_exist for samba files.
538 ********************************************************************/
540 bool file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
542 SMB_STRUCT_STAT st;
543 if (!sbuf)
544 sbuf = &st;
546 if (sys_stat(fname,sbuf) != 0)
547 return(False);
549 return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
552 /*******************************************************************
553 Check if a unix domain socket exists - call vfs_file_exist for samba files.
554 ********************************************************************/
556 bool socket_exist(const char *fname)
558 SMB_STRUCT_STAT st;
559 if (sys_stat(fname,&st) != 0)
560 return(False);
562 return S_ISSOCK(st.st_mode);
565 /*******************************************************************
566 Check a files mod time.
567 ********************************************************************/
569 time_t file_modtime(const char *fname)
571 SMB_STRUCT_STAT st;
573 if (sys_stat(fname,&st) != 0)
574 return(0);
576 return(st.st_mtime);
579 /*******************************************************************
580 Check if a directory exists.
581 ********************************************************************/
583 bool directory_exist(char *dname,SMB_STRUCT_STAT *st)
585 SMB_STRUCT_STAT st2;
586 bool ret;
588 if (!st)
589 st = &st2;
591 if (sys_stat(dname,st) != 0)
592 return(False);
594 ret = S_ISDIR(st->st_mode);
595 if(!ret)
596 errno = ENOTDIR;
597 return ret;
600 /*******************************************************************
601 Returns the size in bytes of the named file.
602 ********************************************************************/
604 SMB_OFF_T get_file_size(char *file_name)
606 SMB_STRUCT_STAT buf;
607 buf.st_size = 0;
608 if(sys_stat(file_name,&buf) != 0)
609 return (SMB_OFF_T)-1;
610 return(buf.st_size);
613 /*******************************************************************
614 Return a string representing an attribute for a file.
615 ********************************************************************/
617 char *attrib_string(uint16 mode)
619 fstring attrstr;
621 attrstr[0] = 0;
623 if (mode & aVOLID) fstrcat(attrstr,"V");
624 if (mode & aDIR) fstrcat(attrstr,"D");
625 if (mode & aARCH) fstrcat(attrstr,"A");
626 if (mode & aHIDDEN) fstrcat(attrstr,"H");
627 if (mode & aSYSTEM) fstrcat(attrstr,"S");
628 if (mode & aRONLY) fstrcat(attrstr,"R");
630 return talloc_strdup(talloc_tos(), attrstr);
633 /*******************************************************************
634 Show a smb message structure.
635 ********************************************************************/
637 void show_msg(char *buf)
639 int i;
640 int bcc=0;
642 if (!DEBUGLVL(5))
643 return;
645 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
646 smb_len(buf),
647 (int)CVAL(buf,smb_com),
648 (int)CVAL(buf,smb_rcls),
649 (int)CVAL(buf,smb_reh),
650 (int)SVAL(buf,smb_err),
651 (int)CVAL(buf,smb_flg),
652 (int)SVAL(buf,smb_flg2)));
653 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
654 (int)SVAL(buf,smb_tid),
655 (int)SVAL(buf,smb_pid),
656 (int)SVAL(buf,smb_uid),
657 (int)SVAL(buf,smb_mid)));
658 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
660 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
661 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
662 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
664 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
666 DEBUGADD(5,("smb_bcc=%d\n",bcc));
668 if (DEBUGLEVEL < 10)
669 return;
671 if (DEBUGLEVEL < 50)
672 bcc = MIN(bcc, 512);
674 dump_data(10, (uint8 *)smb_buf(buf), bcc);
677 /*******************************************************************
678 Set the length and marker of an encrypted smb packet.
679 ********************************************************************/
681 void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num)
683 _smb_setlen(buf,len);
685 SCVAL(buf,4,0xFF);
686 SCVAL(buf,5,'E');
687 SSVAL(buf,6,enc_ctx_num);
690 /*******************************************************************
691 Set the length and marker of an smb packet.
692 ********************************************************************/
694 void smb_setlen(char *buf,int len)
696 _smb_setlen(buf,len);
698 SCVAL(buf,4,0xFF);
699 SCVAL(buf,5,'S');
700 SCVAL(buf,6,'M');
701 SCVAL(buf,7,'B');
704 /*******************************************************************
705 Setup only the byte count for a smb message.
706 ********************************************************************/
708 int set_message_bcc(char *buf,int num_bytes)
710 int num_words = CVAL(buf,smb_wct);
711 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
712 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
713 return (smb_size + num_words*2 + num_bytes);
716 /*******************************************************************
717 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
718 Return the bytes added
719 ********************************************************************/
721 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
723 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
724 uint8 *tmp;
726 if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
727 DEBUG(0, ("talloc failed\n"));
728 return -1;
730 *outbuf = tmp;
732 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
733 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
734 return blob.length;
737 /*******************************************************************
738 Reduce a file name, removing .. elements.
739 ********************************************************************/
741 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
743 char *p = NULL;
744 char *str = NULL;
746 DEBUG(3,("dos_clean_name [%s]\n",s));
748 /* remove any double slashes */
749 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
750 if (!str) {
751 return NULL;
754 /* Remove leading .\\ characters */
755 if(strncmp(str, ".\\", 2) == 0) {
756 trim_string(str, ".\\", NULL);
757 if(*str == 0) {
758 str = talloc_strdup(ctx, ".\\");
759 if (!str) {
760 return NULL;
765 while ((p = strstr_m(str,"\\..\\")) != NULL) {
766 char *s1;
768 *p = 0;
769 s1 = p+3;
771 if ((p=strrchr_m(str,'\\')) != NULL) {
772 *p = 0;
773 } else {
774 *str = 0;
776 str = talloc_asprintf(ctx,
777 "%s%s",
778 str,
779 s1);
780 if (!str) {
781 return NULL;
785 trim_string(str,NULL,"\\..");
786 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
789 /*******************************************************************
790 Reduce a file name, removing .. elements.
791 ********************************************************************/
793 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
795 char *p = NULL;
796 char *str = NULL;
798 DEBUG(3,("unix_clean_name [%s]\n",s));
800 /* remove any double slashes */
801 str = talloc_all_string_sub(ctx, s, "//","/");
802 if (!str) {
803 return NULL;
806 /* Remove leading ./ characters */
807 if(strncmp(str, "./", 2) == 0) {
808 trim_string(str, "./", NULL);
809 if(*str == 0) {
810 str = talloc_strdup(ctx, "./");
811 if (!str) {
812 return NULL;
817 while ((p = strstr_m(str,"/../")) != NULL) {
818 char *s1;
820 *p = 0;
821 s1 = p+3;
823 if ((p=strrchr_m(str,'/')) != NULL) {
824 *p = 0;
825 } else {
826 *str = 0;
828 str = talloc_asprintf(ctx,
829 "%s%s",
830 str,
831 s1);
832 if (!str) {
833 return NULL;
837 trim_string(str,NULL,"/..");
838 return talloc_all_string_sub(ctx, str, "/./", "/");
841 char *clean_name(TALLOC_CTX *ctx, const char *s)
843 char *str = dos_clean_name(ctx, s);
844 if (!str) {
845 return NULL;
847 return unix_clean_name(ctx, str);
850 /*******************************************************************
851 Close the low 3 fd's and open dev/null in their place.
852 ********************************************************************/
854 void close_low_fds(bool stderr_too)
856 #ifndef VALGRIND
857 int fd;
858 int i;
860 close(0);
861 close(1);
863 if (stderr_too)
864 close(2);
866 /* try and use up these file descriptors, so silly
867 library routines writing to stdout etc won't cause havoc */
868 for (i=0;i<3;i++) {
869 if (i == 2 && !stderr_too)
870 continue;
872 fd = sys_open("/dev/null",O_RDWR,0);
873 if (fd < 0)
874 fd = sys_open("/dev/null",O_WRONLY,0);
875 if (fd < 0) {
876 DEBUG(0,("Can't open /dev/null\n"));
877 return;
879 if (fd != i) {
880 DEBUG(0,("Didn't get file descriptor %d\n",i));
881 return;
884 #endif
887 /*******************************************************************
888 Write data into an fd at a given offset. Ignore seek errors.
889 ********************************************************************/
891 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
893 size_t total=0;
894 ssize_t ret;
896 if (pos == (SMB_OFF_T)-1) {
897 return write_data(fd, buffer, N);
899 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
900 while (total < N) {
901 ret = sys_pwrite(fd,buffer + total,N - total, pos);
902 if (ret == -1 && errno == ESPIPE) {
903 return write_data(fd, buffer + total,N - total);
905 if (ret == -1) {
906 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
907 return -1;
909 if (ret == 0) {
910 return total;
912 total += ret;
913 pos += ret;
915 return (ssize_t)total;
916 #else
917 /* Use lseek and write_data. */
918 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
919 if (errno != ESPIPE) {
920 return -1;
923 return write_data(fd, buffer, N);
924 #endif
927 /****************************************************************************
928 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
929 else
930 if SYSV use O_NDELAY
931 if BSD use FNDELAY
932 ****************************************************************************/
934 int set_blocking(int fd, bool set)
936 int val;
937 #ifdef O_NONBLOCK
938 #define FLAG_TO_SET O_NONBLOCK
939 #else
940 #ifdef SYSV
941 #define FLAG_TO_SET O_NDELAY
942 #else /* BSD */
943 #define FLAG_TO_SET FNDELAY
944 #endif
945 #endif
947 if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
948 return -1;
949 if(set) /* Turn blocking on - ie. clear nonblock flag */
950 val &= ~FLAG_TO_SET;
951 else
952 val |= FLAG_TO_SET;
953 return sys_fcntl_long( fd, F_SETFL, val);
954 #undef FLAG_TO_SET
957 /*******************************************************************
958 Sleep for a specified number of milliseconds.
959 ********************************************************************/
961 void smb_msleep(unsigned int t)
963 #if defined(HAVE_NANOSLEEP)
964 struct timespec tval;
965 int ret;
967 tval.tv_sec = t/1000;
968 tval.tv_nsec = 1000000*(t%1000);
970 do {
971 errno = 0;
972 ret = nanosleep(&tval, &tval);
973 } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
974 #else
975 unsigned int tdiff=0;
976 struct timeval tval,t1,t2;
977 fd_set fds;
979 GetTimeOfDay(&t1);
980 t2 = t1;
982 while (tdiff < t) {
983 tval.tv_sec = (t-tdiff)/1000;
984 tval.tv_usec = 1000*((t-tdiff)%1000);
986 /* Never wait for more than 1 sec. */
987 if (tval.tv_sec > 1) {
988 tval.tv_sec = 1;
989 tval.tv_usec = 0;
992 FD_ZERO(&fds);
993 errno = 0;
994 sys_select_intr(0,&fds,NULL,NULL,&tval);
996 GetTimeOfDay(&t2);
997 if (t2.tv_sec < t1.tv_sec) {
998 /* Someone adjusted time... */
999 t1 = t2;
1002 tdiff = TvalDiff(&t1,&t2);
1004 #endif
1007 /****************************************************************************
1008 Become a daemon, discarding the controlling terminal.
1009 ****************************************************************************/
1011 void become_daemon(bool Fork, bool no_process_group)
1013 if (Fork) {
1014 if (sys_fork()) {
1015 _exit(0);
1019 /* detach from the terminal */
1020 #ifdef HAVE_SETSID
1021 if (!no_process_group) setsid();
1022 #elif defined(TIOCNOTTY)
1023 if (!no_process_group) {
1024 int i = sys_open("/dev/tty", O_RDWR, 0);
1025 if (i != -1) {
1026 ioctl(i, (int) TIOCNOTTY, (char *)0);
1027 close(i);
1030 #endif /* HAVE_SETSID */
1032 /* Close fd's 0,1,2. Needed if started by rsh */
1033 close_low_fds(False); /* Don't close stderr, let the debug system
1034 attach it to the logfile */
1037 bool reinit_after_fork(struct messaging_context *msg_ctx,
1038 struct event_context *ev_ctx,
1039 bool parent_longlived)
1041 NTSTATUS status;
1043 /* Reset the state of the random
1044 * number generation system, so
1045 * children do not get the same random
1046 * numbers as each other */
1047 set_need_random_reseed();
1049 /* tdb needs special fork handling */
1050 if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
1051 DEBUG(0,("tdb_reopen_all failed.\n"));
1052 return false;
1055 if (ev_ctx) {
1056 event_context_reinit(ev_ctx);
1059 if (msg_ctx) {
1061 * For clustering, we need to re-init our ctdbd connection after the
1062 * fork
1064 status = messaging_reinit(msg_ctx);
1065 if (!NT_STATUS_IS_OK(status)) {
1066 DEBUG(0,("messaging_reinit() failed: %s\n",
1067 nt_errstr(status)));
1068 return false;
1072 return true;
1075 /****************************************************************************
1076 Put up a yes/no prompt.
1077 ****************************************************************************/
1079 bool yesno(const char *p)
1081 char ans[20];
1082 printf("%s",p);
1084 if (!fgets(ans,sizeof(ans)-1,stdin))
1085 return(False);
1087 if (*ans == 'y' || *ans == 'Y')
1088 return(True);
1090 return(False);
1093 #if defined(PARANOID_MALLOC_CHECKER)
1095 /****************************************************************************
1096 Internal malloc wrapper. Externally visible.
1097 ****************************************************************************/
1099 void *malloc_(size_t size)
1101 if (size == 0) {
1102 return NULL;
1104 #undef malloc
1105 return malloc(size);
1106 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
1109 /****************************************************************************
1110 Internal calloc wrapper. Not externally visible.
1111 ****************************************************************************/
1113 static void *calloc_(size_t count, size_t size)
1115 if (size == 0 || count == 0) {
1116 return NULL;
1118 #undef calloc
1119 return calloc(count, size);
1120 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
1123 /****************************************************************************
1124 Internal realloc wrapper. Not externally visible.
1125 ****************************************************************************/
1127 static void *realloc_(void *ptr, size_t size)
1129 #undef realloc
1130 return realloc(ptr, size);
1131 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
1134 #endif /* PARANOID_MALLOC_CHECKER */
1136 /****************************************************************************
1137 Type-safe malloc.
1138 ****************************************************************************/
1140 void *malloc_array(size_t el_size, unsigned int count)
1142 if (count >= MAX_ALLOC_SIZE/el_size) {
1143 return NULL;
1146 if (el_size == 0 || count == 0) {
1147 return NULL;
1149 #if defined(PARANOID_MALLOC_CHECKER)
1150 return malloc_(el_size*count);
1151 #else
1152 return malloc(el_size*count);
1153 #endif
1156 /****************************************************************************
1157 Type-safe memalign
1158 ****************************************************************************/
1160 void *memalign_array(size_t el_size, size_t align, unsigned int count)
1162 if (count >= MAX_ALLOC_SIZE/el_size) {
1163 return NULL;
1166 return sys_memalign(align, el_size*count);
1169 /****************************************************************************
1170 Type-safe calloc.
1171 ****************************************************************************/
1173 void *calloc_array(size_t size, size_t nmemb)
1175 if (nmemb >= MAX_ALLOC_SIZE/size) {
1176 return NULL;
1178 if (size == 0 || nmemb == 0) {
1179 return NULL;
1181 #if defined(PARANOID_MALLOC_CHECKER)
1182 return calloc_(nmemb, size);
1183 #else
1184 return calloc(nmemb, size);
1185 #endif
1188 /****************************************************************************
1189 Expand a pointer to be a particular size.
1190 Note that this version of Realloc has an extra parameter that decides
1191 whether to free the passed in storage on allocation failure or if the
1192 new size is zero.
1194 This is designed for use in the typical idiom of :
1196 p = SMB_REALLOC(p, size)
1197 if (!p) {
1198 return error;
1201 and not to have to keep track of the old 'p' contents to free later, nor
1202 to worry if the size parameter was zero. In the case where NULL is returned
1203 we guarentee that p has been freed.
1205 If free later semantics are desired, then pass 'free_old_on_error' as False which
1206 guarentees that the old contents are not freed on error, even if size == 0. To use
1207 this idiom use :
1209 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
1210 if (!tmp) {
1211 SAFE_FREE(p);
1212 return error;
1213 } else {
1214 p = tmp;
1217 Changes were instigated by Coverity error checking. JRA.
1218 ****************************************************************************/
1220 void *Realloc(void *p, size_t size, bool free_old_on_error)
1222 void *ret=NULL;
1224 if (size == 0) {
1225 if (free_old_on_error) {
1226 SAFE_FREE(p);
1228 DEBUG(2,("Realloc asked for 0 bytes\n"));
1229 return NULL;
1232 #if defined(PARANOID_MALLOC_CHECKER)
1233 if (!p) {
1234 ret = (void *)malloc_(size);
1235 } else {
1236 ret = (void *)realloc_(p,size);
1238 #else
1239 if (!p) {
1240 ret = (void *)malloc(size);
1241 } else {
1242 ret = (void *)realloc(p,size);
1244 #endif
1246 if (!ret) {
1247 if (free_old_on_error && p) {
1248 SAFE_FREE(p);
1250 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1253 return(ret);
1256 /****************************************************************************
1257 Type-safe realloc.
1258 ****************************************************************************/
1260 void *realloc_array(void *p, size_t el_size, unsigned int count, bool free_old_on_error)
1262 if (count >= MAX_ALLOC_SIZE/el_size) {
1263 if (free_old_on_error) {
1264 SAFE_FREE(p);
1266 return NULL;
1268 return Realloc(p, el_size*count, free_old_on_error);
1271 /****************************************************************************
1272 (Hopefully) efficient array append.
1273 ****************************************************************************/
1275 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1276 void *element, void *_array, uint32 *num_elements,
1277 ssize_t *array_size)
1279 void **array = (void **)_array;
1281 if (*array_size < 0) {
1282 return;
1285 if (*array == NULL) {
1286 if (*array_size == 0) {
1287 *array_size = 128;
1290 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1291 goto error;
1294 *array = TALLOC(mem_ctx, element_size * (*array_size));
1295 if (*array == NULL) {
1296 goto error;
1300 if (*num_elements == *array_size) {
1301 *array_size *= 2;
1303 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1304 goto error;
1307 *array = TALLOC_REALLOC(mem_ctx, *array,
1308 element_size * (*array_size));
1310 if (*array == NULL) {
1311 goto error;
1315 memcpy((char *)(*array) + element_size*(*num_elements),
1316 element, element_size);
1317 *num_elements += 1;
1319 return;
1321 error:
1322 *num_elements = 0;
1323 *array_size = -1;
1326 /****************************************************************************
1327 Free memory, checks for NULL.
1328 Use directly SAFE_FREE()
1329 Exists only because we need to pass a function pointer somewhere --SSS
1330 ****************************************************************************/
1332 void safe_free(void *p)
1334 SAFE_FREE(p);
1337 /****************************************************************************
1338 Get my own name and IP.
1339 ****************************************************************************/
1341 char *get_myname(TALLOC_CTX *ctx)
1343 char *p;
1344 char hostname[HOST_NAME_MAX];
1346 *hostname = 0;
1348 /* get my host name */
1349 if (gethostname(hostname, sizeof(hostname)) == -1) {
1350 DEBUG(0,("gethostname failed\n"));
1351 return False;
1354 /* Ensure null termination. */
1355 hostname[sizeof(hostname)-1] = '\0';
1357 /* split off any parts after an initial . */
1358 p = strchr_m(hostname,'.');
1359 if (p) {
1360 *p = 0;
1363 return talloc_strdup(ctx, hostname);
1366 /****************************************************************************
1367 Get my own domain name, or "" if we have none.
1368 ****************************************************************************/
1370 char *get_mydnsdomname(TALLOC_CTX *ctx)
1372 const char *domname;
1373 char *p;
1375 domname = get_mydnsfullname();
1376 if (!domname) {
1377 return NULL;
1380 p = strchr_m(domname, '.');
1381 if (p) {
1382 p++;
1383 return talloc_strdup(ctx, p);
1384 } else {
1385 return talloc_strdup(ctx, "");
1389 /****************************************************************************
1390 Interpret a protocol description string, with a default.
1391 ****************************************************************************/
1393 int interpret_protocol(const char *str,int def)
1395 if (strequal(str,"NT1"))
1396 return(PROTOCOL_NT1);
1397 if (strequal(str,"LANMAN2"))
1398 return(PROTOCOL_LANMAN2);
1399 if (strequal(str,"LANMAN1"))
1400 return(PROTOCOL_LANMAN1);
1401 if (strequal(str,"CORE"))
1402 return(PROTOCOL_CORE);
1403 if (strequal(str,"COREPLUS"))
1404 return(PROTOCOL_COREPLUS);
1405 if (strequal(str,"CORE+"))
1406 return(PROTOCOL_COREPLUS);
1408 DEBUG(0,("Unrecognised protocol level %s\n",str));
1410 return(def);
1414 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1415 /******************************************************************
1416 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1417 Based on a fix from <Thomas.Hepper@icem.de>.
1418 Returns a malloc'ed string.
1419 *******************************************************************/
1421 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
1423 if (*str == '-') {
1424 const char *p = str;
1425 while(*p && !isspace(*p))
1426 p++;
1427 while(*p && isspace(*p))
1428 p++;
1429 if(*p) {
1430 return talloc_strdup(ctx, p);
1433 return NULL;
1436 /*******************************************************************
1437 Patch from jkf@soton.ac.uk
1438 Split Luke's automount_server into YP lookup and string splitter
1439 so can easily implement automount_path().
1440 Returns a malloc'ed string.
1441 *******************************************************************/
1443 #ifdef WITH_NISPLUS_HOME
1444 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1446 char *value = NULL;
1448 char *nis_map = (char *)lp_nis_home_map_name();
1450 char buffer[NIS_MAXATTRVAL + 1];
1451 nis_result *result;
1452 nis_object *object;
1453 entry_obj *entry;
1455 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
1456 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1458 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1459 if (result->status != NIS_SUCCESS) {
1460 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1461 } else {
1462 object = result->objects.objects_val;
1463 if (object->zo_data.zo_type == ENTRY_OBJ) {
1464 entry = &object->zo_data.objdata_u.en_data;
1465 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1466 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1468 value = talloc_strdup(ctx,
1469 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1470 if (!value) {
1471 nis_freeresult(result);
1472 return NULL;
1474 value = talloc_string_sub(ctx,
1475 value,
1476 "&",
1477 user_name);
1481 nis_freeresult(result);
1483 if (value) {
1484 value = strip_mount_options(ctx, value);
1485 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
1486 user_name, value));
1488 return value;
1490 #else /* WITH_NISPLUS_HOME */
1492 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1494 char *value = NULL;
1496 int nis_error; /* returned by yp all functions */
1497 char *nis_result; /* yp_match inits this */
1498 int nis_result_len; /* and set this */
1499 char *nis_domain; /* yp_get_default_domain inits this */
1500 char *nis_map = (char *)lp_nis_home_map_name();
1502 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1503 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1504 return NULL;
1507 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1509 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
1510 strlen(user_name), &nis_result,
1511 &nis_result_len)) == 0) {
1512 value = talloc_strdup(ctx, nis_result);
1513 if (!value) {
1514 return NULL;
1516 value = strip_mount_options(ctx, value);
1517 } else if(nis_error == YPERR_KEY) {
1518 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1519 user_name, nis_map));
1520 DEBUG(3, ("using defaults for server and home directory\n"));
1521 } else {
1522 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1523 yperr_string(nis_error), user_name, nis_map));
1526 if (value) {
1527 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
1529 return value;
1531 #endif /* WITH_NISPLUS_HOME */
1532 #endif
1534 /****************************************************************************
1535 Check if a process exists. Does this work on all unixes?
1536 ****************************************************************************/
1538 bool process_exists(const struct server_id pid)
1540 if (procid_is_me(&pid)) {
1541 return True;
1544 if (procid_is_local(&pid)) {
1545 return (kill(pid.pid,0) == 0 || errno != ESRCH);
1548 #ifdef CLUSTER_SUPPORT
1549 return ctdbd_process_exists(messaging_ctdbd_connection(), pid.vnn,
1550 pid.pid);
1551 #else
1552 return False;
1553 #endif
1556 bool process_exists_by_pid(pid_t pid)
1558 /* Doing kill with a non-positive pid causes messages to be
1559 * sent to places we don't want. */
1560 SMB_ASSERT(pid > 0);
1561 return(kill(pid,0) == 0 || errno != ESRCH);
1564 /*******************************************************************
1565 Convert a uid into a user name.
1566 ********************************************************************/
1568 const char *uidtoname(uid_t uid)
1570 TALLOC_CTX *ctx = talloc_tos();
1571 char *name = NULL;
1572 struct passwd *pass = NULL;
1574 pass = getpwuid_alloc(ctx,uid);
1575 if (pass) {
1576 name = talloc_strdup(ctx,pass->pw_name);
1577 TALLOC_FREE(pass);
1578 } else {
1579 name = talloc_asprintf(ctx,
1580 "%ld",
1581 (long int)uid);
1583 return name;
1586 /*******************************************************************
1587 Convert a gid into a group name.
1588 ********************************************************************/
1590 char *gidtoname(gid_t gid)
1592 struct group *grp;
1594 grp = getgrgid(gid);
1595 if (grp) {
1596 return talloc_strdup(talloc_tos(), grp->gr_name);
1598 else {
1599 return talloc_asprintf(talloc_tos(),
1600 "%d",
1601 (int)gid);
1605 /*******************************************************************
1606 Convert a user name into a uid.
1607 ********************************************************************/
1609 uid_t nametouid(const char *name)
1611 struct passwd *pass;
1612 char *p;
1613 uid_t u;
1615 pass = getpwnam_alloc(NULL, name);
1616 if (pass) {
1617 u = pass->pw_uid;
1618 TALLOC_FREE(pass);
1619 return u;
1622 u = (uid_t)strtol(name, &p, 0);
1623 if ((p != name) && (*p == '\0'))
1624 return u;
1626 return (uid_t)-1;
1629 /*******************************************************************
1630 Convert a name to a gid_t if possible. Return -1 if not a group.
1631 ********************************************************************/
1633 gid_t nametogid(const char *name)
1635 struct group *grp;
1636 char *p;
1637 gid_t g;
1639 g = (gid_t)strtol(name, &p, 0);
1640 if ((p != name) && (*p == '\0'))
1641 return g;
1643 grp = sys_getgrnam(name);
1644 if (grp)
1645 return(grp->gr_gid);
1646 return (gid_t)-1;
1649 /*******************************************************************
1650 Something really nasty happened - panic !
1651 ********************************************************************/
1653 void smb_panic(const char *const why)
1655 char *cmd;
1656 int result;
1658 #ifdef DEVELOPER
1661 if (global_clobber_region_function) {
1662 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1663 global_clobber_region_function,
1664 global_clobber_region_line));
1667 #endif
1669 DEBUG(0,("PANIC (pid %llu): %s\n",
1670 (unsigned long long)sys_getpid(), why));
1671 log_stack_trace();
1673 cmd = lp_panic_action();
1674 if (cmd && *cmd) {
1675 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1676 result = system(cmd);
1678 if (result == -1)
1679 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1680 strerror(errno)));
1681 else
1682 DEBUG(0, ("smb_panic(): action returned status %d\n",
1683 WEXITSTATUS(result)));
1686 dump_core();
1689 /*******************************************************************
1690 Print a backtrace of the stack to the debug log. This function
1691 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1692 exit shortly after calling it.
1693 ********************************************************************/
1695 #ifdef HAVE_LIBUNWIND_H
1696 #include <libunwind.h>
1697 #endif
1699 #ifdef HAVE_EXECINFO_H
1700 #include <execinfo.h>
1701 #endif
1703 #ifdef HAVE_LIBEXC_H
1704 #include <libexc.h>
1705 #endif
1707 void log_stack_trace(void)
1709 #ifdef HAVE_LIBUNWIND
1710 /* Try to use libunwind before any other technique since on ia64
1711 * libunwind correctly walks the stack in more circumstances than
1712 * backtrace.
1714 unw_cursor_t cursor;
1715 unw_context_t uc;
1716 unsigned i = 0;
1718 char procname[256];
1719 unw_word_t ip, sp, off;
1721 procname[sizeof(procname) - 1] = '\0';
1723 if (unw_getcontext(&uc) != 0) {
1724 goto libunwind_failed;
1727 if (unw_init_local(&cursor, &uc) != 0) {
1728 goto libunwind_failed;
1731 DEBUG(0, ("BACKTRACE:\n"));
1733 do {
1734 ip = sp = 0;
1735 unw_get_reg(&cursor, UNW_REG_IP, &ip);
1736 unw_get_reg(&cursor, UNW_REG_SP, &sp);
1738 switch (unw_get_proc_name(&cursor,
1739 procname, sizeof(procname) - 1, &off) ) {
1740 case 0:
1741 /* Name found. */
1742 case -UNW_ENOMEM:
1743 /* Name truncated. */
1744 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1745 i, procname, (long long)off,
1746 (long long)ip, (long long) sp));
1747 break;
1748 default:
1749 /* case -UNW_ENOINFO: */
1750 /* case -UNW_EUNSPEC: */
1751 /* No symbol name found. */
1752 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1753 i, "<unknown symbol>",
1754 (long long)ip, (long long) sp));
1756 ++i;
1757 } while (unw_step(&cursor) > 0);
1759 return;
1761 libunwind_failed:
1762 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1764 #elif HAVE_BACKTRACE_SYMBOLS
1765 void *backtrace_stack[BACKTRACE_STACK_SIZE];
1766 size_t backtrace_size;
1767 char **backtrace_strings;
1769 /* get the backtrace (stack frames) */
1770 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1771 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1773 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1774 (unsigned long)backtrace_size));
1776 if (backtrace_strings) {
1777 int i;
1779 for (i = 0; i < backtrace_size; i++)
1780 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1782 /* Leak the backtrace_strings, rather than risk what free() might do */
1785 #elif HAVE_LIBEXC
1787 /* The IRIX libexc library provides an API for unwinding the stack. See
1788 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1789 * since we are about to abort anyway, it hardly matters.
1792 #define NAMESIZE 32 /* Arbitrary */
1794 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1795 char * names[BACKTRACE_STACK_SIZE];
1796 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1798 int i;
1799 int levels;
1801 ZERO_ARRAY(addrs);
1802 ZERO_ARRAY(names);
1803 ZERO_ARRAY(namebuf);
1805 /* We need to be root so we can open our /proc entry to walk
1806 * our stack. It also helps when we want to dump core.
1808 become_root();
1810 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1811 names[i] = namebuf + (i * NAMESIZE);
1814 levels = trace_back_stack(0, addrs, names,
1815 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1817 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1818 for (i = 0; i < levels; i++) {
1819 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1821 #undef NAMESIZE
1823 #else
1824 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1825 #endif
1828 /*******************************************************************
1829 A readdir wrapper which just returns the file name.
1830 ********************************************************************/
1832 const char *readdirname(SMB_STRUCT_DIR *p)
1834 SMB_STRUCT_DIRENT *ptr;
1835 char *dname;
1837 if (!p)
1838 return(NULL);
1840 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1841 if (!ptr)
1842 return(NULL);
1844 dname = ptr->d_name;
1846 #ifdef NEXT2
1847 if (telldir(p) < 0)
1848 return(NULL);
1849 #endif
1851 #ifdef HAVE_BROKEN_READDIR_NAME
1852 /* using /usr/ucb/cc is BAD */
1853 dname = dname - 2;
1854 #endif
1856 return talloc_strdup(talloc_tos(), dname);
1859 /*******************************************************************
1860 Utility function used to decide if the last component
1861 of a path matches a (possibly wildcarded) entry in a namelist.
1862 ********************************************************************/
1864 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1866 const char *last_component;
1868 /* if we have no list it's obviously not in the path */
1869 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1870 return False;
1873 DEBUG(8, ("is_in_path: %s\n", name));
1875 /* Get the last component of the unix name. */
1876 last_component = strrchr_m(name, '/');
1877 if (!last_component) {
1878 last_component = name;
1879 } else {
1880 last_component++; /* Go past '/' */
1883 for(; namelist->name != NULL; namelist++) {
1884 if(namelist->is_wild) {
1885 if (mask_match(last_component, namelist->name, case_sensitive)) {
1886 DEBUG(8,("is_in_path: mask match succeeded\n"));
1887 return True;
1889 } else {
1890 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1891 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1892 DEBUG(8,("is_in_path: match succeeded\n"));
1893 return True;
1897 DEBUG(8,("is_in_path: match not found\n"));
1898 return False;
1901 /*******************************************************************
1902 Strip a '/' separated list into an array of
1903 name_compare_enties structures suitable for
1904 passing to is_in_path(). We do this for
1905 speed so we can pre-parse all the names in the list
1906 and don't do it for each call to is_in_path().
1907 namelist is modified here and is assumed to be
1908 a copy owned by the caller.
1909 We also check if the entry contains a wildcard to
1910 remove a potentially expensive call to mask_match
1911 if possible.
1912 ********************************************************************/
1914 void set_namearray(name_compare_entry **ppname_array, char *namelist)
1916 char *name_end;
1917 char *nameptr = namelist;
1918 int num_entries = 0;
1919 int i;
1921 (*ppname_array) = NULL;
1923 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
1924 return;
1926 /* We need to make two passes over the string. The
1927 first to count the number of elements, the second
1928 to split it.
1931 while(*nameptr) {
1932 if ( *nameptr == '/' ) {
1933 /* cope with multiple (useless) /s) */
1934 nameptr++;
1935 continue;
1937 /* find the next / */
1938 name_end = strchr_m(nameptr, '/');
1940 /* oops - the last check for a / didn't find one. */
1941 if (name_end == NULL)
1942 break;
1944 /* next segment please */
1945 nameptr = name_end + 1;
1946 num_entries++;
1949 if(num_entries == 0)
1950 return;
1952 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1953 DEBUG(0,("set_namearray: malloc fail\n"));
1954 return;
1957 /* Now copy out the names */
1958 nameptr = namelist;
1959 i = 0;
1960 while(*nameptr) {
1961 if ( *nameptr == '/' ) {
1962 /* cope with multiple (useless) /s) */
1963 nameptr++;
1964 continue;
1966 /* find the next / */
1967 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1968 *name_end = 0;
1970 /* oops - the last check for a / didn't find one. */
1971 if(name_end == NULL)
1972 break;
1974 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1975 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1976 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1977 return;
1980 /* next segment please */
1981 nameptr = name_end + 1;
1982 i++;
1985 (*ppname_array)[i].name = NULL;
1987 return;
1990 /****************************************************************************
1991 Routine to free a namearray.
1992 ****************************************************************************/
1994 void free_namearray(name_compare_entry *name_array)
1996 int i;
1998 if(name_array == NULL)
1999 return;
2001 for(i=0; name_array[i].name!=NULL; i++)
2002 SAFE_FREE(name_array[i].name);
2003 SAFE_FREE(name_array);
2006 #undef DBGC_CLASS
2007 #define DBGC_CLASS DBGC_LOCKING
2009 /****************************************************************************
2010 Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
2011 is dealt with in posix.c
2012 Returns True if the lock was granted, False otherwise.
2013 ****************************************************************************/
2015 bool fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
2017 SMB_STRUCT_FLOCK lock;
2018 int ret;
2020 DEBUG(8,("fcntl_lock fd=%d op=%d offset=%.0f count=%.0f type=%d\n",
2021 fd,op,(double)offset,(double)count,type));
2023 lock.l_type = type;
2024 lock.l_whence = SEEK_SET;
2025 lock.l_start = offset;
2026 lock.l_len = count;
2027 lock.l_pid = 0;
2029 ret = sys_fcntl_ptr(fd,op,&lock);
2031 if (ret == -1) {
2032 int sav = errno;
2033 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
2034 (double)offset,(double)count,op,type,strerror(errno)));
2035 errno = sav;
2036 return False;
2039 /* everything went OK */
2040 DEBUG(8,("fcntl_lock: Lock call successful\n"));
2042 return True;
2045 /****************************************************************************
2046 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
2047 is dealt with in posix.c
2048 Returns True if we have information regarding this lock region (and returns
2049 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
2050 ****************************************************************************/
2052 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
2054 SMB_STRUCT_FLOCK lock;
2055 int ret;
2057 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
2058 fd,(double)*poffset,(double)*pcount,*ptype));
2060 lock.l_type = *ptype;
2061 lock.l_whence = SEEK_SET;
2062 lock.l_start = *poffset;
2063 lock.l_len = *pcount;
2064 lock.l_pid = 0;
2066 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
2068 if (ret == -1) {
2069 int sav = errno;
2070 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
2071 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
2072 errno = sav;
2073 return False;
2076 *ptype = lock.l_type;
2077 *poffset = lock.l_start;
2078 *pcount = lock.l_len;
2079 *ppid = lock.l_pid;
2081 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
2082 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
2083 return True;
2086 #undef DBGC_CLASS
2087 #define DBGC_CLASS DBGC_ALL
2089 /*******************************************************************
2090 Is the name specified one of my netbios names.
2091 Returns true if it is equal, false otherwise.
2092 ********************************************************************/
2094 bool is_myname(const char *s)
2096 int n;
2097 bool ret = False;
2099 for (n=0; my_netbios_names(n); n++) {
2100 if (strequal(my_netbios_names(n), s)) {
2101 ret=True;
2102 break;
2105 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2106 return(ret);
2109 /*******************************************************************
2110 Is the name specified our workgroup/domain.
2111 Returns true if it is equal, false otherwise.
2112 ********************************************************************/
2114 bool is_myworkgroup(const char *s)
2116 bool ret = False;
2118 if (strequal(s, lp_workgroup())) {
2119 ret=True;
2122 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
2123 return(ret);
2126 /*******************************************************************
2127 we distinguish between 2K and XP by the "Native Lan Manager" string
2128 WinXP => "Windows 2002 5.1"
2129 WinXP 64bit => "Windows XP 5.2"
2130 Win2k => "Windows 2000 5.0"
2131 NT4 => "Windows NT 4.0"
2132 Win9x => "Windows 4.0"
2133 Windows 2003 doesn't set the native lan manager string but
2134 they do set the domain to "Windows 2003 5.2" (probably a bug).
2135 ********************************************************************/
2137 void ra_lanman_string( const char *native_lanman )
2139 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
2140 set_remote_arch( RA_WINXP );
2141 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
2142 set_remote_arch( RA_WINXP64 );
2143 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
2144 set_remote_arch( RA_WIN2K3 );
2147 static const char *remote_arch_str;
2149 const char *get_remote_arch_str(void)
2151 if (!remote_arch_str) {
2152 return "UNKNOWN";
2154 return remote_arch_str;
2157 /*******************************************************************
2158 Set the horrid remote_arch string based on an enum.
2159 ********************************************************************/
2161 void set_remote_arch(enum remote_arch_types type)
2163 ra_type = type;
2164 switch( type ) {
2165 case RA_WFWG:
2166 remote_arch_str = "WfWg";
2167 break;
2168 case RA_OS2:
2169 remote_arch_str = "OS2";
2170 break;
2171 case RA_WIN95:
2172 remote_arch_str = "Win95";
2173 break;
2174 case RA_WINNT:
2175 remote_arch_str = "WinNT";
2176 break;
2177 case RA_WIN2K:
2178 remote_arch_str = "Win2K";
2179 break;
2180 case RA_WINXP:
2181 remote_arch_str = "WinXP";
2182 break;
2183 case RA_WINXP64:
2184 remote_arch_str = "WinXP64";
2185 break;
2186 case RA_WIN2K3:
2187 remote_arch_str = "Win2K3";
2188 break;
2189 case RA_VISTA:
2190 remote_arch_str = "Vista";
2191 break;
2192 case RA_SAMBA:
2193 remote_arch_str = "Samba";
2194 break;
2195 case RA_CIFSFS:
2196 remote_arch_str = "CIFSFS";
2197 break;
2198 default:
2199 ra_type = RA_UNKNOWN;
2200 remote_arch_str = "UNKNOWN";
2201 break;
2204 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
2205 remote_arch_str));
2208 /*******************************************************************
2209 Get the remote_arch type.
2210 ********************************************************************/
2212 enum remote_arch_types get_remote_arch(void)
2214 return ra_type;
2217 void print_asc(int level, const unsigned char *buf,int len)
2219 int i;
2220 for (i=0;i<len;i++)
2221 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2224 void dump_data(int level, const unsigned char *buf1,int len)
2226 const unsigned char *buf = (const unsigned char *)buf1;
2227 int i=0;
2228 if (len<=0) return;
2230 if (!DEBUGLVL(level)) return;
2232 DEBUGADD(level,("[%03X] ",i));
2233 for (i=0;i<len;) {
2234 DEBUGADD(level,("%02X ",(int)buf[i]));
2235 i++;
2236 if (i%8 == 0) DEBUGADD(level,(" "));
2237 if (i%16 == 0) {
2238 print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2239 print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2240 if (i<len) DEBUGADD(level,("[%03X] ",i));
2243 if (i%16) {
2244 int n;
2245 n = 16 - (i%16);
2246 DEBUGADD(level,(" "));
2247 if (n>8) DEBUGADD(level,(" "));
2248 while (n--) DEBUGADD(level,(" "));
2249 n = MIN(8,i%16);
2250 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2251 n = (i%16) - n;
2252 if (n>0) print_asc(level,&buf[i-n],n);
2253 DEBUGADD(level,("\n"));
2257 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2259 #ifdef DEBUG_PASSWORD
2260 DEBUG(11, ("%s", msg));
2261 if (data != NULL && len > 0)
2263 dump_data(11, data, len);
2265 #endif
2268 const char *tab_depth(int level, int depth)
2270 if( CHECK_DEBUGLVL(level) ) {
2271 dbgtext("%*s", depth*4, "");
2273 return "";
2276 /*****************************************************************************
2277 Provide a checksum on a string
2279 Input: s - the null-terminated character string for which the checksum
2280 will be calculated.
2282 Output: The checksum value calculated for s.
2283 *****************************************************************************/
2285 int str_checksum(const char *s)
2287 int res = 0;
2288 int c;
2289 int i=0;
2291 while(*s) {
2292 c = *s;
2293 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2294 s++;
2295 i++;
2297 return(res);
2300 /*****************************************************************
2301 Zero a memory area then free it. Used to catch bugs faster.
2302 *****************************************************************/
2304 void zero_free(void *p, size_t size)
2306 memset(p, 0, size);
2307 SAFE_FREE(p);
2310 /*****************************************************************
2311 Set our open file limit to a requested max and return the limit.
2312 *****************************************************************/
2314 int set_maxfiles(int requested_max)
2316 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2317 struct rlimit rlp;
2318 int saved_current_limit;
2320 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2321 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2322 strerror(errno) ));
2323 /* just guess... */
2324 return requested_max;
2328 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2329 * account for the extra fd we need
2330 * as well as the log files and standard
2331 * handles etc. Save the limit we want to set in case
2332 * we are running on an OS that doesn't support this limit (AIX)
2333 * which always returns RLIM_INFINITY for rlp.rlim_max.
2336 /* Try raising the hard (max) limit to the requested amount. */
2338 #if defined(RLIM_INFINITY)
2339 if (rlp.rlim_max != RLIM_INFINITY) {
2340 int orig_max = rlp.rlim_max;
2342 if ( rlp.rlim_max < requested_max )
2343 rlp.rlim_max = requested_max;
2345 /* This failing is not an error - many systems (Linux) don't
2346 support our default request of 10,000 open files. JRA. */
2348 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2349 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2350 (int)rlp.rlim_max, strerror(errno) ));
2352 /* Set failed - restore original value from get. */
2353 rlp.rlim_max = orig_max;
2356 #endif
2358 /* Now try setting the soft (current) limit. */
2360 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2362 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2363 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2364 (int)rlp.rlim_cur, strerror(errno) ));
2365 /* just guess... */
2366 return saved_current_limit;
2369 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2370 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2371 strerror(errno) ));
2372 /* just guess... */
2373 return saved_current_limit;
2376 #if defined(RLIM_INFINITY)
2377 if(rlp.rlim_cur == RLIM_INFINITY)
2378 return saved_current_limit;
2379 #endif
2381 if((int)rlp.rlim_cur > saved_current_limit)
2382 return saved_current_limit;
2384 return rlp.rlim_cur;
2385 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2387 * No way to know - just guess...
2389 return requested_max;
2390 #endif
2393 /*****************************************************************
2394 Possibly replace mkstemp if it is broken.
2395 *****************************************************************/
2397 int smb_mkstemp(char *name_template)
2399 #if HAVE_SECURE_MKSTEMP
2400 return mkstemp(name_template);
2401 #else
2402 /* have a reasonable go at emulating it. Hope that
2403 the system mktemp() isn't completly hopeless */
2404 char *p = mktemp(name_template);
2405 if (!p)
2406 return -1;
2407 return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2408 #endif
2411 /*****************************************************************
2412 malloc that aborts with smb_panic on fail or zero size.
2413 *****************************************************************/
2415 void *smb_xmalloc_array(size_t size, unsigned int count)
2417 void *p;
2418 if (size == 0) {
2419 smb_panic("smb_xmalloc_array: called with zero size");
2421 if (count >= MAX_ALLOC_SIZE/size) {
2422 smb_panic("smb_xmalloc_array: alloc size too large");
2424 if ((p = SMB_MALLOC(size*count)) == NULL) {
2425 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2426 (unsigned long)size, (unsigned long)count));
2427 smb_panic("smb_xmalloc_array: malloc failed");
2429 return p;
2433 Memdup with smb_panic on fail.
2436 void *smb_xmemdup(const void *p, size_t size)
2438 void *p2;
2439 p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2440 memcpy(p2, p, size);
2441 return p2;
2445 strdup that aborts on malloc fail.
2448 char *smb_xstrdup(const char *s)
2450 #if defined(PARANOID_MALLOC_CHECKER)
2451 #ifdef strdup
2452 #undef strdup
2453 #endif
2454 #endif
2456 #ifndef HAVE_STRDUP
2457 #define strdup rep_strdup
2458 #endif
2460 char *s1 = strdup(s);
2461 #if defined(PARANOID_MALLOC_CHECKER)
2462 #ifdef strdup
2463 #undef strdup
2464 #endif
2465 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2466 #endif
2467 if (!s1) {
2468 smb_panic("smb_xstrdup: malloc failed");
2470 return s1;
2475 strndup that aborts on malloc fail.
2478 char *smb_xstrndup(const char *s, size_t n)
2480 #if defined(PARANOID_MALLOC_CHECKER)
2481 #ifdef strndup
2482 #undef strndup
2483 #endif
2484 #endif
2486 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
2487 #undef HAVE_STRNDUP
2488 #define strndup rep_strndup
2489 #endif
2491 char *s1 = strndup(s, n);
2492 #if defined(PARANOID_MALLOC_CHECKER)
2493 #ifdef strndup
2494 #undef strndup
2495 #endif
2496 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2497 #endif
2498 if (!s1) {
2499 smb_panic("smb_xstrndup: malloc failed");
2501 return s1;
2505 vasprintf that aborts on malloc fail
2508 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2510 int n;
2511 va_list ap2;
2513 VA_COPY(ap2, ap);
2515 n = vasprintf(ptr, format, ap2);
2516 if (n == -1 || ! *ptr) {
2517 smb_panic("smb_xvasprintf: out of memory");
2519 va_end(ap2);
2520 return n;
2523 /*****************************************************************
2524 Like strdup but for memory.
2525 *****************************************************************/
2527 void *memdup(const void *p, size_t size)
2529 void *p2;
2530 if (size == 0)
2531 return NULL;
2532 p2 = SMB_MALLOC(size);
2533 if (!p2)
2534 return NULL;
2535 memcpy(p2, p, size);
2536 return p2;
2539 /*****************************************************************
2540 Get local hostname and cache result.
2541 *****************************************************************/
2543 char *myhostname(void)
2545 static char *ret;
2546 if (ret == NULL) {
2547 /* This is cached forever so
2548 * use NULL talloc ctx. */
2549 ret = get_myname(NULL);
2551 return ret;
2554 /*****************************************************************
2555 A useful function for returning a path in the Samba pid directory.
2556 *****************************************************************/
2558 static char *xx_path(const char *name, const char *rootpath)
2560 char *fname = NULL;
2562 fname = talloc_strdup(talloc_tos(), rootpath);
2563 if (!fname) {
2564 return NULL;
2566 trim_string(fname,"","/");
2568 if (!directory_exist(fname,NULL)) {
2569 mkdir(fname,0755);
2572 return talloc_asprintf(talloc_tos(),
2573 "%s/%s",
2574 fname,
2575 name);
2578 /*****************************************************************
2579 A useful function for returning a path in the Samba lock directory.
2580 *****************************************************************/
2582 char *lock_path(const char *name)
2584 return xx_path(name, lp_lockdir());
2587 /*****************************************************************
2588 A useful function for returning a path in the Samba pid directory.
2589 *****************************************************************/
2591 char *pid_path(const char *name)
2593 return xx_path(name, lp_piddir());
2597 * @brief Returns an absolute path to a file in the Samba lib directory.
2599 * @param name File to find, relative to LIBDIR.
2601 * @retval Pointer to a string containing the full path.
2604 char *lib_path(const char *name)
2606 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
2610 * @brief Returns an absolute path to a file in the Samba data directory.
2612 * @param name File to find, relative to CODEPAGEDIR.
2614 * @retval Pointer to a talloc'ed string containing the full path.
2617 char *data_path(const char *name)
2619 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
2622 /*****************************************************************
2623 a useful function for returning a path in the Samba state directory
2624 *****************************************************************/
2626 char *state_path(const char *name)
2628 return xx_path(name, get_dyn_STATEDIR());
2632 * @brief Returns the platform specific shared library extension.
2634 * @retval Pointer to a const char * containing the extension.
2637 const char *shlib_ext(void)
2639 return get_dyn_SHLIBEXT();
2642 /*******************************************************************
2643 Given a filename - get its directory name
2644 NB: Returned in static storage. Caveats:
2645 o If caller wishes to preserve, they should copy.
2646 ********************************************************************/
2648 char *parent_dirname(const char *path)
2650 char *parent;
2652 if (!parent_dirname_talloc(talloc_tos(), path, &parent, NULL)) {
2653 return NULL;
2656 return parent;
2659 bool parent_dirname_talloc(TALLOC_CTX *mem_ctx, const char *dir,
2660 char **parent, const char **name)
2662 char *p;
2663 ptrdiff_t len;
2665 p = strrchr_m(dir, '/'); /* Find final '/', if any */
2667 if (p == NULL) {
2668 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2669 return False;
2671 if (name) {
2672 *name = "";
2674 return True;
2677 len = p-dir;
2679 if (!(*parent = TALLOC_ARRAY(mem_ctx, char, len+1))) {
2680 return False;
2682 memcpy(*parent, dir, len);
2683 (*parent)[len] = '\0';
2685 if (name) {
2686 *name = p+1;
2688 return True;
2691 /*******************************************************************
2692 Determine if a pattern contains any Microsoft wildcard characters.
2693 *******************************************************************/
2695 bool ms_has_wild(const char *s)
2697 char c;
2699 if (lp_posix_pathnames()) {
2700 /* With posix pathnames no characters are wild. */
2701 return False;
2704 while ((c = *s++)) {
2705 switch (c) {
2706 case '*':
2707 case '?':
2708 case '<':
2709 case '>':
2710 case '"':
2711 return True;
2714 return False;
2717 bool ms_has_wild_w(const smb_ucs2_t *s)
2719 smb_ucs2_t c;
2720 if (!s) return False;
2721 while ((c = *s++)) {
2722 switch (c) {
2723 case UCS2_CHAR('*'):
2724 case UCS2_CHAR('?'):
2725 case UCS2_CHAR('<'):
2726 case UCS2_CHAR('>'):
2727 case UCS2_CHAR('"'):
2728 return True;
2731 return False;
2734 /*******************************************************************
2735 A wrapper that handles case sensitivity and the special handling
2736 of the ".." name.
2737 *******************************************************************/
2739 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
2741 if (strcmp(string,"..") == 0)
2742 string = ".";
2743 if (strcmp(pattern,".") == 0)
2744 return False;
2746 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2749 /*******************************************************************
2750 A wrapper that handles case sensitivity and the special handling
2751 of the ".." name. Varient that is only called by old search code which requires
2752 pattern translation.
2753 *******************************************************************/
2755 bool mask_match_search(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, True, is_case_sensitive) == 0;
2765 /*******************************************************************
2766 A wrapper that handles a list of patters and calls mask_match()
2767 on each. Returns True if any of the patterns match.
2768 *******************************************************************/
2770 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
2772 while (listLen-- > 0) {
2773 if (mask_match(string, *list++, is_case_sensitive))
2774 return True;
2776 return False;
2779 /*********************************************************
2780 Recursive routine that is called by unix_wild_match.
2781 *********************************************************/
2783 static bool unix_do_match(const char *regexp, const char *str)
2785 const char *p;
2787 for( p = regexp; *p && *str; ) {
2789 switch(*p) {
2790 case '?':
2791 str++;
2792 p++;
2793 break;
2795 case '*':
2798 * Look for a character matching
2799 * the one after the '*'.
2801 p++;
2802 if(!*p)
2803 return true; /* Automatic match */
2804 while(*str) {
2806 while(*str && (*p != *str))
2807 str++;
2810 * Patch from weidel@multichart.de. In the case of the regexp
2811 * '*XX*' we want to ensure there are at least 2 'X' characters
2812 * in the string after the '*' for a match to be made.
2816 int matchcount=0;
2819 * Eat all the characters that match, but count how many there were.
2822 while(*str && (*p == *str)) {
2823 str++;
2824 matchcount++;
2828 * Now check that if the regexp had n identical characters that
2829 * matchcount had at least that many matches.
2832 while ( *(p+1) && (*(p+1) == *p)) {
2833 p++;
2834 matchcount--;
2837 if ( matchcount <= 0 )
2838 return false;
2841 str--; /* We've eaten the match char after the '*' */
2843 if(unix_do_match(p, str))
2844 return true;
2846 if(!*str)
2847 return false;
2848 else
2849 str++;
2851 return false;
2853 default:
2854 if(*str != *p)
2855 return false;
2856 str++;
2857 p++;
2858 break;
2862 if(!*p && !*str)
2863 return true;
2865 if (!*p && str[0] == '.' && str[1] == 0)
2866 return true;
2868 if (!*str && *p == '?') {
2869 while (*p == '?')
2870 p++;
2871 return(!*p);
2874 if(!*str && (*p == '*' && p[1] == '\0'))
2875 return true;
2877 return false;
2880 /*******************************************************************
2881 Simple case insensitive interface to a UNIX wildcard matcher.
2882 Returns True if match, False if not.
2883 *******************************************************************/
2885 bool unix_wild_match(const char *pattern, const char *string)
2887 TALLOC_CTX *ctx = talloc_stackframe();
2888 char *p2;
2889 char *s2;
2890 char *p;
2891 bool ret = false;
2893 p2 = talloc_strdup(ctx,pattern);
2894 s2 = talloc_strdup(ctx,string);
2895 if (!p2 || !s2) {
2896 TALLOC_FREE(ctx);
2897 return false;
2899 strlower_m(p2);
2900 strlower_m(s2);
2902 /* Remove any *? and ** from the pattern as they are meaningless */
2903 for(p = p2; *p; p++) {
2904 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
2905 memmove(&p[1], &p[2], strlen(&p[2])+1);
2909 if (strequal(p2,"*")) {
2910 TALLOC_FREE(ctx);
2911 return true;
2914 ret = unix_do_match(p2, s2);
2915 TALLOC_FREE(ctx);
2916 return ret;
2919 /**********************************************************************
2920 Converts a name to a fully qualified domain name.
2921 Returns true if lookup succeeded, false if not (then fqdn is set to name)
2922 Note we deliberately use gethostbyname here, not getaddrinfo as we want
2923 to examine the h_aliases and I don't know how to do that with getaddrinfo.
2924 ***********************************************************************/
2926 bool name_to_fqdn(fstring fqdn, const char *name)
2928 char *full = NULL;
2929 struct hostent *hp = gethostbyname(name);
2931 if (!hp || !hp->h_name || !*hp->h_name) {
2932 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2933 fstrcpy(fqdn, name);
2934 return false;
2937 /* Find out if the fqdn is returned as an alias
2938 * to cope with /etc/hosts files where the first
2939 * name is not the fqdn but the short name */
2940 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2941 int i;
2942 for (i = 0; hp->h_aliases[i]; i++) {
2943 if (strchr_m(hp->h_aliases[i], '.')) {
2944 full = hp->h_aliases[i];
2945 break;
2949 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2950 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2951 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2952 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
2953 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
2954 full = hp->h_name;
2956 if (!full) {
2957 full = hp->h_name;
2960 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2961 fstrcpy(fqdn, full);
2962 return true;
2965 /**********************************************************************
2966 Extension to talloc_get_type: Abort on type mismatch
2967 ***********************************************************************/
2969 void *talloc_check_name_abort(const void *ptr, const char *name)
2971 void *result;
2973 result = talloc_check_name(ptr, name);
2974 if (result != NULL)
2975 return result;
2977 DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2978 name, talloc_get_name(ptr)));
2979 smb_panic("talloc type mismatch");
2980 /* Keep the compiler happy */
2981 return NULL;
2984 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2986 switch (share_access & ~FILE_SHARE_DELETE) {
2987 case FILE_SHARE_NONE:
2988 return DENY_ALL;
2989 case FILE_SHARE_READ:
2990 return DENY_WRITE;
2991 case FILE_SHARE_WRITE:
2992 return DENY_READ;
2993 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2994 return DENY_NONE;
2996 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2997 return DENY_DOS;
2998 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2999 return DENY_FCB;
3002 return (uint32)-1;
3005 pid_t procid_to_pid(const struct server_id *proc)
3007 return proc->pid;
3010 static uint32 my_vnn = NONCLUSTER_VNN;
3012 void set_my_vnn(uint32 vnn)
3014 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
3015 my_vnn = vnn;
3018 uint32 get_my_vnn(void)
3020 return my_vnn;
3023 struct server_id pid_to_procid(pid_t pid)
3025 struct server_id result;
3026 result.pid = pid;
3027 #ifdef CLUSTER_SUPPORT
3028 result.vnn = my_vnn;
3029 #endif
3030 return result;
3033 struct server_id procid_self(void)
3035 return pid_to_procid(sys_getpid());
3038 struct server_id server_id_self(void)
3040 return procid_self();
3043 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
3045 if (p1->pid != p2->pid)
3046 return False;
3047 #ifdef CLUSTER_SUPPORT
3048 if (p1->vnn != p2->vnn)
3049 return False;
3050 #endif
3051 return True;
3054 bool cluster_id_equal(const struct server_id *id1,
3055 const struct server_id *id2)
3057 return procid_equal(id1, id2);
3060 bool procid_is_me(const struct server_id *pid)
3062 if (pid->pid != sys_getpid())
3063 return False;
3064 #ifdef CLUSTER_SUPPORT
3065 if (pid->vnn != my_vnn)
3066 return False;
3067 #endif
3068 return True;
3071 struct server_id interpret_pid(const char *pid_string)
3073 #ifdef CLUSTER_SUPPORT
3074 unsigned int vnn, pid;
3075 struct server_id result;
3076 if (sscanf(pid_string, "%u:%u", &vnn, &pid) == 2) {
3077 result.vnn = vnn;
3078 result.pid = pid;
3080 else if (sscanf(pid_string, "%u", &pid) == 1) {
3081 result.vnn = NONCLUSTER_VNN;
3082 result.pid = pid;
3084 else {
3085 result.vnn = NONCLUSTER_VNN;
3086 result.pid = -1;
3088 return result;
3089 #else
3090 return pid_to_procid(atoi(pid_string));
3091 #endif
3094 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
3096 #ifdef CLUSTER_SUPPORT
3097 if (pid->vnn == NONCLUSTER_VNN) {
3098 return talloc_asprintf(mem_ctx,
3099 "%d",
3100 (int)pid->pid);
3102 else {
3103 return talloc_asprintf(mem_ctx,
3104 "%u:%d",
3105 (unsigned)pid->vnn,
3106 (int)pid->pid);
3108 #else
3109 return talloc_asprintf(mem_ctx,
3110 "%d",
3111 (int)pid->pid);
3112 #endif
3115 char *procid_str_static(const struct server_id *pid)
3117 return procid_str(talloc_tos(), pid);
3120 bool procid_valid(const struct server_id *pid)
3122 return (pid->pid != -1);
3125 bool procid_is_local(const struct server_id *pid)
3127 #ifdef CLUSTER_SUPPORT
3128 return pid->vnn == my_vnn;
3129 #else
3130 return True;
3131 #endif
3134 int this_is_smp(void)
3136 #if defined(HAVE_SYSCONF)
3138 #if defined(SYSCONF_SC_NPROC_ONLN)
3139 return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
3140 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3141 return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
3142 #else
3143 return 0;
3144 #endif
3146 #else
3147 return 0;
3148 #endif
3151 /****************************************************************
3152 Check if an offset into a buffer is safe.
3153 If this returns True it's safe to indirect into the byte at
3154 pointer ptr+off.
3155 ****************************************************************/
3157 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3159 const char *end_base = buf_base + buf_len;
3160 char *end_ptr = ptr + off;
3162 if (!buf_base || !ptr) {
3163 return False;
3166 if (end_base < buf_base || end_ptr < ptr) {
3167 return False; /* wrap. */
3170 if (end_ptr < end_base) {
3171 return True;
3173 return False;
3176 /****************************************************************
3177 Return a safe pointer into a buffer, or NULL.
3178 ****************************************************************/
3180 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3182 return is_offset_safe(buf_base, buf_len, ptr, off) ?
3183 ptr + off : NULL;
3186 /****************************************************************
3187 Return a safe pointer into a string within a buffer, or NULL.
3188 ****************************************************************/
3190 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3192 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
3193 return NULL;
3195 /* Check if a valid string exists at this offset. */
3196 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
3197 return NULL;
3199 return ptr + off;
3202 /****************************************************************
3203 Return an SVAL at a pointer, or failval if beyond the end.
3204 ****************************************************************/
3206 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3209 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
3210 * NOT ptr[2].
3212 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
3213 return failval;
3215 return SVAL(ptr,off);
3218 /****************************************************************
3219 Return an IVAL at a pointer, or failval if beyond the end.
3220 ****************************************************************/
3222 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3225 * Note we use off+3 here, not off+4 as IVAL accesses
3226 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
3228 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
3229 return failval;
3231 return IVAL(ptr,off);
3234 /****************************************************************
3235 Split DOM\user into DOM and user. Do not mix with winbind variants of that
3236 call (they take care of winbind separator and other winbind specific settings).
3237 ****************************************************************/
3239 void split_domain_user(TALLOC_CTX *mem_ctx,
3240 const char *full_name,
3241 char **domain,
3242 char **user)
3244 const char *p = NULL;
3246 p = strchr_m(full_name, '\\');
3248 if (p != NULL) {
3249 *domain = talloc_strndup(mem_ctx, full_name,
3250 PTR_DIFF(p, full_name));
3251 *user = talloc_strdup(mem_ctx, p+1);
3252 } else {
3253 *domain = talloc_strdup(mem_ctx, "");
3254 *user = talloc_strdup(mem_ctx, full_name);
3258 #if 0
3260 Disable these now we have checked all code paths and ensured
3261 NULL returns on zero request. JRA.
3263 /****************************************************************
3264 talloc wrapper functions that guarentee a null pointer return
3265 if size == 0.
3266 ****************************************************************/
3268 #ifndef MAX_TALLOC_SIZE
3269 #define MAX_TALLOC_SIZE 0x10000000
3270 #endif
3273 * talloc and zero memory.
3274 * - returns NULL if size is zero.
3277 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
3279 void *p;
3281 if (size == 0) {
3282 return NULL;
3285 p = talloc_named_const(ctx, size, name);
3287 if (p) {
3288 memset(p, '\0', size);
3291 return p;
3295 * memdup with a talloc.
3296 * - returns NULL if size is zero.
3299 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
3301 void *newp;
3303 if (size == 0) {
3304 return NULL;
3307 newp = talloc_named_const(t, size, name);
3308 if (newp) {
3309 memcpy(newp, p, size);
3312 return newp;
3316 * alloc an array, checking for integer overflow in the array size.
3317 * - returns NULL if count or el_size are zero.
3320 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3322 if (count >= MAX_TALLOC_SIZE/el_size) {
3323 return NULL;
3326 if (el_size == 0 || count == 0) {
3327 return NULL;
3330 return talloc_named_const(ctx, el_size * count, name);
3334 * alloc an zero array, checking for integer overflow in the array size
3335 * - returns NULL if count or el_size are zero.
3338 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3340 if (count >= MAX_TALLOC_SIZE/el_size) {
3341 return NULL;
3344 if (el_size == 0 || count == 0) {
3345 return NULL;
3348 return _talloc_zero(ctx, el_size * count, name);
3352 * Talloc wrapper that returns NULL if size == 0.
3354 void *talloc_zeronull(const void *context, size_t size, const char *name)
3356 if (size == 0) {
3357 return NULL;
3359 return talloc_named_const(context, size, name);
3361 #endif
3363 /* Split a path name into filename and stream name components. Canonicalise
3364 * such that an implicit $DATA token is always explicit.
3366 * The "specification" of this function can be found in the
3367 * run_local_stream_name() function in torture.c, I've tried those
3368 * combinations against a W2k3 server.
3371 NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
3372 char **pbase, char **pstream)
3374 char *base = NULL;
3375 char *stream = NULL;
3376 char *sname; /* stream name */
3377 const char *stype; /* stream type */
3379 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
3381 sname = strchr_m(fname, ':');
3383 if (lp_posix_pathnames() || (sname == NULL)) {
3384 if (pbase != NULL) {
3385 base = talloc_strdup(mem_ctx, fname);
3386 NT_STATUS_HAVE_NO_MEMORY(base);
3388 goto done;
3391 if (pbase != NULL) {
3392 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
3393 NT_STATUS_HAVE_NO_MEMORY(base);
3396 sname += 1;
3398 stype = strchr_m(sname, ':');
3400 if (stype == NULL) {
3401 sname = talloc_strdup(mem_ctx, sname);
3402 stype = "$DATA";
3404 else {
3405 if (StrCaseCmp(stype, ":$DATA") != 0) {
3407 * If there is an explicit stream type, so far we only
3408 * allow $DATA. Is there anything else allowed? -- vl
3410 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
3411 TALLOC_FREE(base);
3412 return NT_STATUS_OBJECT_NAME_INVALID;
3414 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
3415 stype += 1;
3418 if (sname == NULL) {
3419 TALLOC_FREE(base);
3420 return NT_STATUS_NO_MEMORY;
3423 if (sname[0] == '\0') {
3425 * no stream name, so no stream
3427 goto done;
3430 if (pstream != NULL) {
3431 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
3432 if (stream == NULL) {
3433 TALLOC_FREE(sname);
3434 TALLOC_FREE(base);
3435 return NT_STATUS_NO_MEMORY;
3438 * upper-case the type field
3440 strupper_m(strchr_m(stream, ':')+1);
3443 done:
3444 if (pbase != NULL) {
3445 *pbase = base;
3447 if (pstream != NULL) {
3448 *pstream = stream;
3450 return NT_STATUS_OK;
3453 bool is_valid_policy_hnd(const POLICY_HND *hnd)
3455 POLICY_HND tmp;
3456 ZERO_STRUCT(tmp);
3457 return (memcmp(&tmp, hnd, sizeof(tmp)) != 0);
3460 /****************************************************************
3461 strip off leading '\\' from a hostname
3462 ****************************************************************/
3464 const char *strip_hostname(const char *s)
3466 if (!s) {
3467 return NULL;
3470 if (strlen_m(s) < 3) {
3471 return s;
3474 if (s[0] == '\\') s++;
3475 if (s[0] == '\\') s++;
3477 return s;