Re-structure Volker's patch to "Fix trans2findfirst for the large directory optimizat...
[Samba.git] / source / lib / util.c
blobdafaf03d56e4da3a45534a4ba6d49d67e615f8ad
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 bool parent_longlived)
1040 NTSTATUS status;
1042 /* Reset the state of the random
1043 * number generation system, so
1044 * children do not get the same random
1045 * numbers as each other */
1046 set_need_random_reseed();
1048 /* tdb needs special fork handling */
1049 if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
1050 DEBUG(0,("tdb_reopen_all failed.\n"));
1051 return false;
1055 * For clustering, we need to re-init our ctdbd connection after the
1056 * fork
1058 status = messaging_reinit(msg_ctx);
1059 if (!NT_STATUS_IS_OK(status)) {
1060 DEBUG(0,("messaging_reinit() failed: %s\n",
1061 nt_errstr(status)));
1062 return false;
1065 return true;
1068 /****************************************************************************
1069 Put up a yes/no prompt.
1070 ****************************************************************************/
1072 bool yesno(const char *p)
1074 char ans[20];
1075 printf("%s",p);
1077 if (!fgets(ans,sizeof(ans)-1,stdin))
1078 return(False);
1080 if (*ans == 'y' || *ans == 'Y')
1081 return(True);
1083 return(False);
1086 #if defined(PARANOID_MALLOC_CHECKER)
1088 /****************************************************************************
1089 Internal malloc wrapper. Externally visible.
1090 ****************************************************************************/
1092 void *malloc_(size_t size)
1094 if (size == 0) {
1095 return NULL;
1097 #undef malloc
1098 return malloc(size);
1099 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
1102 /****************************************************************************
1103 Internal calloc wrapper. Not externally visible.
1104 ****************************************************************************/
1106 static void *calloc_(size_t count, size_t size)
1108 if (size == 0 || count == 0) {
1109 return NULL;
1111 #undef calloc
1112 return calloc(count, size);
1113 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
1116 /****************************************************************************
1117 Internal realloc wrapper. Not externally visible.
1118 ****************************************************************************/
1120 static void *realloc_(void *ptr, size_t size)
1122 #undef realloc
1123 return realloc(ptr, size);
1124 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
1127 #endif /* PARANOID_MALLOC_CHECKER */
1129 /****************************************************************************
1130 Type-safe malloc.
1131 ****************************************************************************/
1133 void *malloc_array(size_t el_size, unsigned int count)
1135 if (count >= MAX_ALLOC_SIZE/el_size) {
1136 return NULL;
1139 if (el_size == 0 || count == 0) {
1140 return NULL;
1142 #if defined(PARANOID_MALLOC_CHECKER)
1143 return malloc_(el_size*count);
1144 #else
1145 return malloc(el_size*count);
1146 #endif
1149 /****************************************************************************
1150 Type-safe memalign
1151 ****************************************************************************/
1153 void *memalign_array(size_t el_size, size_t align, unsigned int count)
1155 if (count >= MAX_ALLOC_SIZE/el_size) {
1156 return NULL;
1159 return sys_memalign(align, el_size*count);
1162 /****************************************************************************
1163 Type-safe calloc.
1164 ****************************************************************************/
1166 void *calloc_array(size_t size, size_t nmemb)
1168 if (nmemb >= MAX_ALLOC_SIZE/size) {
1169 return NULL;
1171 if (size == 0 || nmemb == 0) {
1172 return NULL;
1174 #if defined(PARANOID_MALLOC_CHECKER)
1175 return calloc_(nmemb, size);
1176 #else
1177 return calloc(nmemb, size);
1178 #endif
1181 /****************************************************************************
1182 Expand a pointer to be a particular size.
1183 Note that this version of Realloc has an extra parameter that decides
1184 whether to free the passed in storage on allocation failure or if the
1185 new size is zero.
1187 This is designed for use in the typical idiom of :
1189 p = SMB_REALLOC(p, size)
1190 if (!p) {
1191 return error;
1194 and not to have to keep track of the old 'p' contents to free later, nor
1195 to worry if the size parameter was zero. In the case where NULL is returned
1196 we guarentee that p has been freed.
1198 If free later semantics are desired, then pass 'free_old_on_error' as False which
1199 guarentees that the old contents are not freed on error, even if size == 0. To use
1200 this idiom use :
1202 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
1203 if (!tmp) {
1204 SAFE_FREE(p);
1205 return error;
1206 } else {
1207 p = tmp;
1210 Changes were instigated by Coverity error checking. JRA.
1211 ****************************************************************************/
1213 void *Realloc(void *p, size_t size, bool free_old_on_error)
1215 void *ret=NULL;
1217 if (size == 0) {
1218 if (free_old_on_error) {
1219 SAFE_FREE(p);
1221 DEBUG(2,("Realloc asked for 0 bytes\n"));
1222 return NULL;
1225 #if defined(PARANOID_MALLOC_CHECKER)
1226 if (!p) {
1227 ret = (void *)malloc_(size);
1228 } else {
1229 ret = (void *)realloc_(p,size);
1231 #else
1232 if (!p) {
1233 ret = (void *)malloc(size);
1234 } else {
1235 ret = (void *)realloc(p,size);
1237 #endif
1239 if (!ret) {
1240 if (free_old_on_error && p) {
1241 SAFE_FREE(p);
1243 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1246 return(ret);
1249 /****************************************************************************
1250 Type-safe realloc.
1251 ****************************************************************************/
1253 void *realloc_array(void *p, size_t el_size, unsigned int count, bool free_old_on_error)
1255 if (count >= MAX_ALLOC_SIZE/el_size) {
1256 if (free_old_on_error) {
1257 SAFE_FREE(p);
1259 return NULL;
1261 return Realloc(p, el_size*count, free_old_on_error);
1264 /****************************************************************************
1265 (Hopefully) efficient array append.
1266 ****************************************************************************/
1268 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1269 void *element, void *_array, uint32 *num_elements,
1270 ssize_t *array_size)
1272 void **array = (void **)_array;
1274 if (*array_size < 0) {
1275 return;
1278 if (*array == NULL) {
1279 if (*array_size == 0) {
1280 *array_size = 128;
1283 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1284 goto error;
1287 *array = TALLOC(mem_ctx, element_size * (*array_size));
1288 if (*array == NULL) {
1289 goto error;
1293 if (*num_elements == *array_size) {
1294 *array_size *= 2;
1296 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1297 goto error;
1300 *array = TALLOC_REALLOC(mem_ctx, *array,
1301 element_size * (*array_size));
1303 if (*array == NULL) {
1304 goto error;
1308 memcpy((char *)(*array) + element_size*(*num_elements),
1309 element, element_size);
1310 *num_elements += 1;
1312 return;
1314 error:
1315 *num_elements = 0;
1316 *array_size = -1;
1319 /****************************************************************************
1320 Free memory, checks for NULL.
1321 Use directly SAFE_FREE()
1322 Exists only because we need to pass a function pointer somewhere --SSS
1323 ****************************************************************************/
1325 void safe_free(void *p)
1327 SAFE_FREE(p);
1330 /****************************************************************************
1331 Get my own name and IP.
1332 ****************************************************************************/
1334 char *get_myname(TALLOC_CTX *ctx)
1336 char *p;
1337 char hostname[HOST_NAME_MAX];
1339 *hostname = 0;
1341 /* get my host name */
1342 if (gethostname(hostname, sizeof(hostname)) == -1) {
1343 DEBUG(0,("gethostname failed\n"));
1344 return False;
1347 /* Ensure null termination. */
1348 hostname[sizeof(hostname)-1] = '\0';
1350 /* split off any parts after an initial . */
1351 p = strchr_m(hostname,'.');
1352 if (p) {
1353 *p = 0;
1356 return talloc_strdup(ctx, hostname);
1359 /****************************************************************************
1360 Get my own domain name, or "" if we have none.
1361 ****************************************************************************/
1363 char *get_mydnsdomname(TALLOC_CTX *ctx)
1365 const char *domname;
1366 char *p;
1368 domname = get_mydnsfullname();
1369 if (!domname) {
1370 return NULL;
1373 p = strchr_m(domname, '.');
1374 if (p) {
1375 p++;
1376 return talloc_strdup(ctx, p);
1377 } else {
1378 return talloc_strdup(ctx, "");
1382 /****************************************************************************
1383 Interpret a protocol description string, with a default.
1384 ****************************************************************************/
1386 int interpret_protocol(const char *str,int def)
1388 if (strequal(str,"NT1"))
1389 return(PROTOCOL_NT1);
1390 if (strequal(str,"LANMAN2"))
1391 return(PROTOCOL_LANMAN2);
1392 if (strequal(str,"LANMAN1"))
1393 return(PROTOCOL_LANMAN1);
1394 if (strequal(str,"CORE"))
1395 return(PROTOCOL_CORE);
1396 if (strequal(str,"COREPLUS"))
1397 return(PROTOCOL_COREPLUS);
1398 if (strequal(str,"CORE+"))
1399 return(PROTOCOL_COREPLUS);
1401 DEBUG(0,("Unrecognised protocol level %s\n",str));
1403 return(def);
1407 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1408 /******************************************************************
1409 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1410 Based on a fix from <Thomas.Hepper@icem.de>.
1411 Returns a malloc'ed string.
1412 *******************************************************************/
1414 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
1416 if (*str == '-') {
1417 const char *p = str;
1418 while(*p && !isspace(*p))
1419 p++;
1420 while(*p && isspace(*p))
1421 p++;
1422 if(*p) {
1423 return talloc_strdup(ctx, p);
1426 return NULL;
1429 /*******************************************************************
1430 Patch from jkf@soton.ac.uk
1431 Split Luke's automount_server into YP lookup and string splitter
1432 so can easily implement automount_path().
1433 Returns a malloc'ed string.
1434 *******************************************************************/
1436 #ifdef WITH_NISPLUS_HOME
1437 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1439 char *value = NULL;
1441 char *nis_map = (char *)lp_nis_home_map_name();
1443 char buffer[NIS_MAXATTRVAL + 1];
1444 nis_result *result;
1445 nis_object *object;
1446 entry_obj *entry;
1448 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
1449 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1451 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1452 if (result->status != NIS_SUCCESS) {
1453 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1454 } else {
1455 object = result->objects.objects_val;
1456 if (object->zo_data.zo_type == ENTRY_OBJ) {
1457 entry = &object->zo_data.objdata_u.en_data;
1458 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1459 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1461 value = talloc_strdup(ctx,
1462 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1463 if (!value) {
1464 nis_freeresult(result);
1465 return NULL;
1467 value = talloc_string_sub(ctx,
1468 value,
1469 "&",
1470 user_name);
1474 nis_freeresult(result);
1476 if (value) {
1477 value = strip_mount_options(ctx, value);
1478 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
1479 user_name, value));
1481 return value;
1483 #else /* WITH_NISPLUS_HOME */
1485 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1487 char *value = NULL;
1489 int nis_error; /* returned by yp all functions */
1490 char *nis_result; /* yp_match inits this */
1491 int nis_result_len; /* and set this */
1492 char *nis_domain; /* yp_get_default_domain inits this */
1493 char *nis_map = (char *)lp_nis_home_map_name();
1495 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1496 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1497 return NULL;
1500 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1502 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
1503 strlen(user_name), &nis_result,
1504 &nis_result_len)) == 0) {
1505 value = talloc_strdup(ctx, nis_result);
1506 if (!value) {
1507 return NULL;
1509 value = strip_mount_options(ctx, value);
1510 } else if(nis_error == YPERR_KEY) {
1511 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1512 user_name, nis_map));
1513 DEBUG(3, ("using defaults for server and home directory\n"));
1514 } else {
1515 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1516 yperr_string(nis_error), user_name, nis_map));
1519 if (value) {
1520 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
1522 return value;
1524 #endif /* WITH_NISPLUS_HOME */
1525 #endif
1527 /****************************************************************************
1528 Check if a process exists. Does this work on all unixes?
1529 ****************************************************************************/
1531 bool process_exists(const struct server_id pid)
1533 if (procid_is_me(&pid)) {
1534 return True;
1537 if (procid_is_local(&pid)) {
1538 return (kill(pid.pid,0) == 0 || errno != ESRCH);
1541 #ifdef CLUSTER_SUPPORT
1542 return ctdbd_process_exists(messaging_ctdbd_connection(), pid.vnn,
1543 pid.pid);
1544 #else
1545 return False;
1546 #endif
1549 bool process_exists_by_pid(pid_t pid)
1551 /* Doing kill with a non-positive pid causes messages to be
1552 * sent to places we don't want. */
1553 SMB_ASSERT(pid > 0);
1554 return(kill(pid,0) == 0 || errno != ESRCH);
1557 /*******************************************************************
1558 Convert a uid into a user name.
1559 ********************************************************************/
1561 const char *uidtoname(uid_t uid)
1563 TALLOC_CTX *ctx = talloc_tos();
1564 char *name = NULL;
1565 struct passwd *pass = NULL;
1567 pass = getpwuid_alloc(ctx,uid);
1568 if (pass) {
1569 name = talloc_strdup(ctx,pass->pw_name);
1570 TALLOC_FREE(pass);
1571 } else {
1572 name = talloc_asprintf(ctx,
1573 "%ld",
1574 (long int)uid);
1576 return name;
1579 /*******************************************************************
1580 Convert a gid into a group name.
1581 ********************************************************************/
1583 char *gidtoname(gid_t gid)
1585 struct group *grp;
1587 grp = getgrgid(gid);
1588 if (grp) {
1589 return talloc_strdup(talloc_tos(), grp->gr_name);
1591 else {
1592 return talloc_asprintf(talloc_tos(),
1593 "%d",
1594 (int)gid);
1598 /*******************************************************************
1599 Convert a user name into a uid.
1600 ********************************************************************/
1602 uid_t nametouid(const char *name)
1604 struct passwd *pass;
1605 char *p;
1606 uid_t u;
1608 pass = getpwnam_alloc(NULL, name);
1609 if (pass) {
1610 u = pass->pw_uid;
1611 TALLOC_FREE(pass);
1612 return u;
1615 u = (uid_t)strtol(name, &p, 0);
1616 if ((p != name) && (*p == '\0'))
1617 return u;
1619 return (uid_t)-1;
1622 /*******************************************************************
1623 Convert a name to a gid_t if possible. Return -1 if not a group.
1624 ********************************************************************/
1626 gid_t nametogid(const char *name)
1628 struct group *grp;
1629 char *p;
1630 gid_t g;
1632 g = (gid_t)strtol(name, &p, 0);
1633 if ((p != name) && (*p == '\0'))
1634 return g;
1636 grp = sys_getgrnam(name);
1637 if (grp)
1638 return(grp->gr_gid);
1639 return (gid_t)-1;
1642 /*******************************************************************
1643 Something really nasty happened - panic !
1644 ********************************************************************/
1646 void smb_panic(const char *const why)
1648 char *cmd;
1649 int result;
1651 #ifdef DEVELOPER
1654 if (global_clobber_region_function) {
1655 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1656 global_clobber_region_function,
1657 global_clobber_region_line));
1660 #endif
1662 DEBUG(0,("PANIC (pid %llu): %s\n",
1663 (unsigned long long)sys_getpid(), why));
1664 log_stack_trace();
1666 cmd = lp_panic_action();
1667 if (cmd && *cmd) {
1668 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1669 result = system(cmd);
1671 if (result == -1)
1672 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1673 strerror(errno)));
1674 else
1675 DEBUG(0, ("smb_panic(): action returned status %d\n",
1676 WEXITSTATUS(result)));
1679 dump_core();
1682 /*******************************************************************
1683 Print a backtrace of the stack to the debug log. This function
1684 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1685 exit shortly after calling it.
1686 ********************************************************************/
1688 #ifdef HAVE_LIBUNWIND_H
1689 #include <libunwind.h>
1690 #endif
1692 #ifdef HAVE_EXECINFO_H
1693 #include <execinfo.h>
1694 #endif
1696 #ifdef HAVE_LIBEXC_H
1697 #include <libexc.h>
1698 #endif
1700 void log_stack_trace(void)
1702 #ifdef HAVE_LIBUNWIND
1703 /* Try to use libunwind before any other technique since on ia64
1704 * libunwind correctly walks the stack in more circumstances than
1705 * backtrace.
1707 unw_cursor_t cursor;
1708 unw_context_t uc;
1709 unsigned i = 0;
1711 char procname[256];
1712 unw_word_t ip, sp, off;
1714 procname[sizeof(procname) - 1] = '\0';
1716 if (unw_getcontext(&uc) != 0) {
1717 goto libunwind_failed;
1720 if (unw_init_local(&cursor, &uc) != 0) {
1721 goto libunwind_failed;
1724 DEBUG(0, ("BACKTRACE:\n"));
1726 do {
1727 ip = sp = 0;
1728 unw_get_reg(&cursor, UNW_REG_IP, &ip);
1729 unw_get_reg(&cursor, UNW_REG_SP, &sp);
1731 switch (unw_get_proc_name(&cursor,
1732 procname, sizeof(procname) - 1, &off) ) {
1733 case 0:
1734 /* Name found. */
1735 case -UNW_ENOMEM:
1736 /* Name truncated. */
1737 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1738 i, procname, (long long)off,
1739 (long long)ip, (long long) sp));
1740 break;
1741 default:
1742 /* case -UNW_ENOINFO: */
1743 /* case -UNW_EUNSPEC: */
1744 /* No symbol name found. */
1745 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1746 i, "<unknown symbol>",
1747 (long long)ip, (long long) sp));
1749 ++i;
1750 } while (unw_step(&cursor) > 0);
1752 return;
1754 libunwind_failed:
1755 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1757 #elif HAVE_BACKTRACE_SYMBOLS
1758 void *backtrace_stack[BACKTRACE_STACK_SIZE];
1759 size_t backtrace_size;
1760 char **backtrace_strings;
1762 /* get the backtrace (stack frames) */
1763 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1764 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1766 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1767 (unsigned long)backtrace_size));
1769 if (backtrace_strings) {
1770 int i;
1772 for (i = 0; i < backtrace_size; i++)
1773 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1775 /* Leak the backtrace_strings, rather than risk what free() might do */
1778 #elif HAVE_LIBEXC
1780 /* The IRIX libexc library provides an API for unwinding the stack. See
1781 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1782 * since we are about to abort anyway, it hardly matters.
1785 #define NAMESIZE 32 /* Arbitrary */
1787 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1788 char * names[BACKTRACE_STACK_SIZE];
1789 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1791 int i;
1792 int levels;
1794 ZERO_ARRAY(addrs);
1795 ZERO_ARRAY(names);
1796 ZERO_ARRAY(namebuf);
1798 /* We need to be root so we can open our /proc entry to walk
1799 * our stack. It also helps when we want to dump core.
1801 become_root();
1803 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1804 names[i] = namebuf + (i * NAMESIZE);
1807 levels = trace_back_stack(0, addrs, names,
1808 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1810 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1811 for (i = 0; i < levels; i++) {
1812 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1814 #undef NAMESIZE
1816 #else
1817 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1818 #endif
1821 /*******************************************************************
1822 A readdir wrapper which just returns the file name.
1823 ********************************************************************/
1825 const char *readdirname(SMB_STRUCT_DIR *p)
1827 SMB_STRUCT_DIRENT *ptr;
1828 char *dname;
1830 if (!p)
1831 return(NULL);
1833 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1834 if (!ptr)
1835 return(NULL);
1837 dname = ptr->d_name;
1839 #ifdef NEXT2
1840 if (telldir(p) < 0)
1841 return(NULL);
1842 #endif
1844 #ifdef HAVE_BROKEN_READDIR_NAME
1845 /* using /usr/ucb/cc is BAD */
1846 dname = dname - 2;
1847 #endif
1849 return talloc_strdup(talloc_tos(), dname);
1852 /*******************************************************************
1853 Utility function used to decide if the last component
1854 of a path matches a (possibly wildcarded) entry in a namelist.
1855 ********************************************************************/
1857 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1859 const char *last_component;
1861 /* if we have no list it's obviously not in the path */
1862 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1863 return False;
1866 DEBUG(8, ("is_in_path: %s\n", name));
1868 /* Get the last component of the unix name. */
1869 last_component = strrchr_m(name, '/');
1870 if (!last_component) {
1871 last_component = name;
1872 } else {
1873 last_component++; /* Go past '/' */
1876 for(; namelist->name != NULL; namelist++) {
1877 if(namelist->is_wild) {
1878 if (mask_match(last_component, namelist->name, case_sensitive)) {
1879 DEBUG(8,("is_in_path: mask match succeeded\n"));
1880 return True;
1882 } else {
1883 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1884 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1885 DEBUG(8,("is_in_path: match succeeded\n"));
1886 return True;
1890 DEBUG(8,("is_in_path: match not found\n"));
1891 return False;
1894 /*******************************************************************
1895 Strip a '/' separated list into an array of
1896 name_compare_enties structures suitable for
1897 passing to is_in_path(). We do this for
1898 speed so we can pre-parse all the names in the list
1899 and don't do it for each call to is_in_path().
1900 namelist is modified here and is assumed to be
1901 a copy owned by the caller.
1902 We also check if the entry contains a wildcard to
1903 remove a potentially expensive call to mask_match
1904 if possible.
1905 ********************************************************************/
1907 void set_namearray(name_compare_entry **ppname_array, char *namelist)
1909 char *name_end;
1910 char *nameptr = namelist;
1911 int num_entries = 0;
1912 int i;
1914 (*ppname_array) = NULL;
1916 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
1917 return;
1919 /* We need to make two passes over the string. The
1920 first to count the number of elements, the second
1921 to split it.
1924 while(*nameptr) {
1925 if ( *nameptr == '/' ) {
1926 /* cope with multiple (useless) /s) */
1927 nameptr++;
1928 continue;
1930 /* find the next / */
1931 name_end = strchr_m(nameptr, '/');
1933 /* oops - the last check for a / didn't find one. */
1934 if (name_end == NULL)
1935 break;
1937 /* next segment please */
1938 nameptr = name_end + 1;
1939 num_entries++;
1942 if(num_entries == 0)
1943 return;
1945 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1946 DEBUG(0,("set_namearray: malloc fail\n"));
1947 return;
1950 /* Now copy out the names */
1951 nameptr = namelist;
1952 i = 0;
1953 while(*nameptr) {
1954 if ( *nameptr == '/' ) {
1955 /* cope with multiple (useless) /s) */
1956 nameptr++;
1957 continue;
1959 /* find the next / */
1960 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1961 *name_end = 0;
1963 /* oops - the last check for a / didn't find one. */
1964 if(name_end == NULL)
1965 break;
1967 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1968 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1969 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1970 return;
1973 /* next segment please */
1974 nameptr = name_end + 1;
1975 i++;
1978 (*ppname_array)[i].name = NULL;
1980 return;
1983 /****************************************************************************
1984 Routine to free a namearray.
1985 ****************************************************************************/
1987 void free_namearray(name_compare_entry *name_array)
1989 int i;
1991 if(name_array == NULL)
1992 return;
1994 for(i=0; name_array[i].name!=NULL; i++)
1995 SAFE_FREE(name_array[i].name);
1996 SAFE_FREE(name_array);
1999 #undef DBGC_CLASS
2000 #define DBGC_CLASS DBGC_LOCKING
2002 /****************************************************************************
2003 Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
2004 is dealt with in posix.c
2005 Returns True if the lock was granted, False otherwise.
2006 ****************************************************************************/
2008 bool fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
2010 SMB_STRUCT_FLOCK lock;
2011 int ret;
2013 DEBUG(8,("fcntl_lock fd=%d op=%d offset=%.0f count=%.0f type=%d\n",
2014 fd,op,(double)offset,(double)count,type));
2016 lock.l_type = type;
2017 lock.l_whence = SEEK_SET;
2018 lock.l_start = offset;
2019 lock.l_len = count;
2020 lock.l_pid = 0;
2022 ret = sys_fcntl_ptr(fd,op,&lock);
2024 if (ret == -1) {
2025 int sav = errno;
2026 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
2027 (double)offset,(double)count,op,type,strerror(errno)));
2028 errno = sav;
2029 return False;
2032 /* everything went OK */
2033 DEBUG(8,("fcntl_lock: Lock call successful\n"));
2035 return True;
2038 /****************************************************************************
2039 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
2040 is dealt with in posix.c
2041 Returns True if we have information regarding this lock region (and returns
2042 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
2043 ****************************************************************************/
2045 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
2047 SMB_STRUCT_FLOCK lock;
2048 int ret;
2050 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
2051 fd,(double)*poffset,(double)*pcount,*ptype));
2053 lock.l_type = *ptype;
2054 lock.l_whence = SEEK_SET;
2055 lock.l_start = *poffset;
2056 lock.l_len = *pcount;
2057 lock.l_pid = 0;
2059 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
2061 if (ret == -1) {
2062 int sav = errno;
2063 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
2064 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
2065 errno = sav;
2066 return False;
2069 *ptype = lock.l_type;
2070 *poffset = lock.l_start;
2071 *pcount = lock.l_len;
2072 *ppid = lock.l_pid;
2074 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
2075 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
2076 return True;
2079 #undef DBGC_CLASS
2080 #define DBGC_CLASS DBGC_ALL
2082 /*******************************************************************
2083 Is the name specified one of my netbios names.
2084 Returns true if it is equal, false otherwise.
2085 ********************************************************************/
2087 bool is_myname(const char *s)
2089 int n;
2090 bool ret = False;
2092 for (n=0; my_netbios_names(n); n++) {
2093 if (strequal(my_netbios_names(n), s)) {
2094 ret=True;
2095 break;
2098 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2099 return(ret);
2102 /*******************************************************************
2103 Is the name specified our workgroup/domain.
2104 Returns true if it is equal, false otherwise.
2105 ********************************************************************/
2107 bool is_myworkgroup(const char *s)
2109 bool ret = False;
2111 if (strequal(s, lp_workgroup())) {
2112 ret=True;
2115 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
2116 return(ret);
2119 /*******************************************************************
2120 we distinguish between 2K and XP by the "Native Lan Manager" string
2121 WinXP => "Windows 2002 5.1"
2122 WinXP 64bit => "Windows XP 5.2"
2123 Win2k => "Windows 2000 5.0"
2124 NT4 => "Windows NT 4.0"
2125 Win9x => "Windows 4.0"
2126 Windows 2003 doesn't set the native lan manager string but
2127 they do set the domain to "Windows 2003 5.2" (probably a bug).
2128 ********************************************************************/
2130 void ra_lanman_string( const char *native_lanman )
2132 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
2133 set_remote_arch( RA_WINXP );
2134 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
2135 set_remote_arch( RA_WINXP64 );
2136 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
2137 set_remote_arch( RA_WIN2K3 );
2140 static const char *remote_arch_str;
2142 const char *get_remote_arch_str(void)
2144 if (!remote_arch_str) {
2145 return "UNKNOWN";
2147 return remote_arch_str;
2150 /*******************************************************************
2151 Set the horrid remote_arch string based on an enum.
2152 ********************************************************************/
2154 void set_remote_arch(enum remote_arch_types type)
2156 ra_type = type;
2157 switch( type ) {
2158 case RA_WFWG:
2159 remote_arch_str = "WfWg";
2160 break;
2161 case RA_OS2:
2162 remote_arch_str = "OS2";
2163 break;
2164 case RA_WIN95:
2165 remote_arch_str = "Win95";
2166 break;
2167 case RA_WINNT:
2168 remote_arch_str = "WinNT";
2169 break;
2170 case RA_WIN2K:
2171 remote_arch_str = "Win2K";
2172 break;
2173 case RA_WINXP:
2174 remote_arch_str = "WinXP";
2175 break;
2176 case RA_WINXP64:
2177 remote_arch_str = "WinXP64";
2178 break;
2179 case RA_WIN2K3:
2180 remote_arch_str = "Win2K3";
2181 break;
2182 case RA_VISTA:
2183 remote_arch_str = "Vista";
2184 break;
2185 case RA_SAMBA:
2186 remote_arch_str = "Samba";
2187 break;
2188 case RA_CIFSFS:
2189 remote_arch_str = "CIFSFS";
2190 break;
2191 default:
2192 ra_type = RA_UNKNOWN;
2193 remote_arch_str = "UNKNOWN";
2194 break;
2197 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
2198 remote_arch_str));
2201 /*******************************************************************
2202 Get the remote_arch type.
2203 ********************************************************************/
2205 enum remote_arch_types get_remote_arch(void)
2207 return ra_type;
2210 void print_asc(int level, const unsigned char *buf,int len)
2212 int i;
2213 for (i=0;i<len;i++)
2214 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2217 void dump_data(int level, const unsigned char *buf1,int len)
2219 const unsigned char *buf = (const unsigned char *)buf1;
2220 int i=0;
2221 if (len<=0) return;
2223 if (!DEBUGLVL(level)) return;
2225 DEBUGADD(level,("[%03X] ",i));
2226 for (i=0;i<len;) {
2227 DEBUGADD(level,("%02X ",(int)buf[i]));
2228 i++;
2229 if (i%8 == 0) DEBUGADD(level,(" "));
2230 if (i%16 == 0) {
2231 print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2232 print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2233 if (i<len) DEBUGADD(level,("[%03X] ",i));
2236 if (i%16) {
2237 int n;
2238 n = 16 - (i%16);
2239 DEBUGADD(level,(" "));
2240 if (n>8) DEBUGADD(level,(" "));
2241 while (n--) DEBUGADD(level,(" "));
2242 n = MIN(8,i%16);
2243 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2244 n = (i%16) - n;
2245 if (n>0) print_asc(level,&buf[i-n],n);
2246 DEBUGADD(level,("\n"));
2250 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2252 #ifdef DEBUG_PASSWORD
2253 DEBUG(11, ("%s", msg));
2254 if (data != NULL && len > 0)
2256 dump_data(11, data, len);
2258 #endif
2261 const char *tab_depth(int level, int depth)
2263 if( CHECK_DEBUGLVL(level) ) {
2264 dbgtext("%*s", depth*4, "");
2266 return "";
2269 /*****************************************************************************
2270 Provide a checksum on a string
2272 Input: s - the null-terminated character string for which the checksum
2273 will be calculated.
2275 Output: The checksum value calculated for s.
2276 *****************************************************************************/
2278 int str_checksum(const char *s)
2280 int res = 0;
2281 int c;
2282 int i=0;
2284 while(*s) {
2285 c = *s;
2286 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2287 s++;
2288 i++;
2290 return(res);
2293 /*****************************************************************
2294 Zero a memory area then free it. Used to catch bugs faster.
2295 *****************************************************************/
2297 void zero_free(void *p, size_t size)
2299 memset(p, 0, size);
2300 SAFE_FREE(p);
2303 /*****************************************************************
2304 Set our open file limit to a requested max and return the limit.
2305 *****************************************************************/
2307 int set_maxfiles(int requested_max)
2309 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2310 struct rlimit rlp;
2311 int saved_current_limit;
2313 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2314 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2315 strerror(errno) ));
2316 /* just guess... */
2317 return requested_max;
2321 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2322 * account for the extra fd we need
2323 * as well as the log files and standard
2324 * handles etc. Save the limit we want to set in case
2325 * we are running on an OS that doesn't support this limit (AIX)
2326 * which always returns RLIM_INFINITY for rlp.rlim_max.
2329 /* Try raising the hard (max) limit to the requested amount. */
2331 #if defined(RLIM_INFINITY)
2332 if (rlp.rlim_max != RLIM_INFINITY) {
2333 int orig_max = rlp.rlim_max;
2335 if ( rlp.rlim_max < requested_max )
2336 rlp.rlim_max = requested_max;
2338 /* This failing is not an error - many systems (Linux) don't
2339 support our default request of 10,000 open files. JRA. */
2341 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2342 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2343 (int)rlp.rlim_max, strerror(errno) ));
2345 /* Set failed - restore original value from get. */
2346 rlp.rlim_max = orig_max;
2349 #endif
2351 /* Now try setting the soft (current) limit. */
2353 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2355 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2356 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2357 (int)rlp.rlim_cur, strerror(errno) ));
2358 /* just guess... */
2359 return saved_current_limit;
2362 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2363 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2364 strerror(errno) ));
2365 /* just guess... */
2366 return saved_current_limit;
2369 #if defined(RLIM_INFINITY)
2370 if(rlp.rlim_cur == RLIM_INFINITY)
2371 return saved_current_limit;
2372 #endif
2374 if((int)rlp.rlim_cur > saved_current_limit)
2375 return saved_current_limit;
2377 return rlp.rlim_cur;
2378 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2380 * No way to know - just guess...
2382 return requested_max;
2383 #endif
2386 /*****************************************************************
2387 Possibly replace mkstemp if it is broken.
2388 *****************************************************************/
2390 int smb_mkstemp(char *name_template)
2392 #if HAVE_SECURE_MKSTEMP
2393 return mkstemp(name_template);
2394 #else
2395 /* have a reasonable go at emulating it. Hope that
2396 the system mktemp() isn't completly hopeless */
2397 char *p = mktemp(name_template);
2398 if (!p)
2399 return -1;
2400 return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2401 #endif
2404 /*****************************************************************
2405 malloc that aborts with smb_panic on fail or zero size.
2406 *****************************************************************/
2408 void *smb_xmalloc_array(size_t size, unsigned int count)
2410 void *p;
2411 if (size == 0) {
2412 smb_panic("smb_xmalloc_array: called with zero size");
2414 if (count >= MAX_ALLOC_SIZE/size) {
2415 smb_panic("smb_xmalloc_array: alloc size too large");
2417 if ((p = SMB_MALLOC(size*count)) == NULL) {
2418 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2419 (unsigned long)size, (unsigned long)count));
2420 smb_panic("smb_xmalloc_array: malloc failed");
2422 return p;
2426 Memdup with smb_panic on fail.
2429 void *smb_xmemdup(const void *p, size_t size)
2431 void *p2;
2432 p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2433 memcpy(p2, p, size);
2434 return p2;
2438 strdup that aborts on malloc fail.
2441 char *smb_xstrdup(const char *s)
2443 #if defined(PARANOID_MALLOC_CHECKER)
2444 #ifdef strdup
2445 #undef strdup
2446 #endif
2447 #endif
2449 #ifndef HAVE_STRDUP
2450 #define strdup rep_strdup
2451 #endif
2453 char *s1 = strdup(s);
2454 #if defined(PARANOID_MALLOC_CHECKER)
2455 #ifdef strdup
2456 #undef strdup
2457 #endif
2458 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2459 #endif
2460 if (!s1) {
2461 smb_panic("smb_xstrdup: malloc failed");
2463 return s1;
2468 strndup that aborts on malloc fail.
2471 char *smb_xstrndup(const char *s, size_t n)
2473 #if defined(PARANOID_MALLOC_CHECKER)
2474 #ifdef strndup
2475 #undef strndup
2476 #endif
2477 #endif
2479 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
2480 #undef HAVE_STRNDUP
2481 #define strndup rep_strndup
2482 #endif
2484 char *s1 = strndup(s, n);
2485 #if defined(PARANOID_MALLOC_CHECKER)
2486 #ifdef strndup
2487 #undef strndup
2488 #endif
2489 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2490 #endif
2491 if (!s1) {
2492 smb_panic("smb_xstrndup: malloc failed");
2494 return s1;
2498 vasprintf that aborts on malloc fail
2501 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2503 int n;
2504 va_list ap2;
2506 VA_COPY(ap2, ap);
2508 n = vasprintf(ptr, format, ap2);
2509 if (n == -1 || ! *ptr) {
2510 smb_panic("smb_xvasprintf: out of memory");
2512 va_end(ap2);
2513 return n;
2516 /*****************************************************************
2517 Like strdup but for memory.
2518 *****************************************************************/
2520 void *memdup(const void *p, size_t size)
2522 void *p2;
2523 if (size == 0)
2524 return NULL;
2525 p2 = SMB_MALLOC(size);
2526 if (!p2)
2527 return NULL;
2528 memcpy(p2, p, size);
2529 return p2;
2532 /*****************************************************************
2533 Get local hostname and cache result.
2534 *****************************************************************/
2536 char *myhostname(void)
2538 static char *ret;
2539 if (ret == NULL) {
2540 /* This is cached forever so
2541 * use NULL talloc ctx. */
2542 ret = get_myname(NULL);
2544 return ret;
2547 /*****************************************************************
2548 A useful function for returning a path in the Samba pid directory.
2549 *****************************************************************/
2551 static char *xx_path(const char *name, const char *rootpath)
2553 char *fname = NULL;
2555 fname = talloc_strdup(talloc_tos(), rootpath);
2556 if (!fname) {
2557 return NULL;
2559 trim_string(fname,"","/");
2561 if (!directory_exist(fname,NULL)) {
2562 mkdir(fname,0755);
2565 return talloc_asprintf(talloc_tos(),
2566 "%s/%s",
2567 fname,
2568 name);
2571 /*****************************************************************
2572 A useful function for returning a path in the Samba lock directory.
2573 *****************************************************************/
2575 char *lock_path(const char *name)
2577 return xx_path(name, lp_lockdir());
2580 /*****************************************************************
2581 A useful function for returning a path in the Samba pid directory.
2582 *****************************************************************/
2584 char *pid_path(const char *name)
2586 return xx_path(name, lp_piddir());
2590 * @brief Returns an absolute path to a file in the Samba lib directory.
2592 * @param name File to find, relative to LIBDIR.
2594 * @retval Pointer to a string containing the full path.
2597 char *lib_path(const char *name)
2599 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
2603 * @brief Returns an absolute path to a file in the Samba data directory.
2605 * @param name File to find, relative to CODEPAGEDIR.
2607 * @retval Pointer to a talloc'ed string containing the full path.
2610 char *data_path(const char *name)
2612 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
2615 /*****************************************************************
2616 a useful function for returning a path in the Samba state directory
2617 *****************************************************************/
2619 char *state_path(const char *name)
2621 return xx_path(name, get_dyn_STATEDIR());
2625 * @brief Returns the platform specific shared library extension.
2627 * @retval Pointer to a const char * containing the extension.
2630 const char *shlib_ext(void)
2632 return get_dyn_SHLIBEXT();
2635 /*******************************************************************
2636 Given a filename - get its directory name
2637 NB: Returned in static storage. Caveats:
2638 o If caller wishes to preserve, they should copy.
2639 ********************************************************************/
2641 char *parent_dirname(const char *path)
2643 char *parent;
2645 if (!parent_dirname_talloc(talloc_tos(), path, &parent, NULL)) {
2646 return NULL;
2649 return parent;
2652 bool parent_dirname_talloc(TALLOC_CTX *mem_ctx, const char *dir,
2653 char **parent, const char **name)
2655 char *p;
2656 ptrdiff_t len;
2658 p = strrchr_m(dir, '/'); /* Find final '/', if any */
2660 if (p == NULL) {
2661 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2662 return False;
2664 if (name) {
2665 *name = "";
2667 return True;
2670 len = p-dir;
2672 if (!(*parent = TALLOC_ARRAY(mem_ctx, char, len+1))) {
2673 return False;
2675 memcpy(*parent, dir, len);
2676 (*parent)[len] = '\0';
2678 if (name) {
2679 *name = p+1;
2681 return True;
2684 /*******************************************************************
2685 Determine if a pattern contains any Microsoft wildcard characters.
2686 *******************************************************************/
2688 bool ms_has_wild(const char *s)
2690 char c;
2692 if (lp_posix_pathnames()) {
2693 /* With posix pathnames no characters are wild. */
2694 return False;
2697 while ((c = *s++)) {
2698 switch (c) {
2699 case '*':
2700 case '?':
2701 case '<':
2702 case '>':
2703 case '"':
2704 return True;
2707 return False;
2710 bool ms_has_wild_w(const smb_ucs2_t *s)
2712 smb_ucs2_t c;
2713 if (!s) return False;
2714 while ((c = *s++)) {
2715 switch (c) {
2716 case UCS2_CHAR('*'):
2717 case UCS2_CHAR('?'):
2718 case UCS2_CHAR('<'):
2719 case UCS2_CHAR('>'):
2720 case UCS2_CHAR('"'):
2721 return True;
2724 return False;
2727 /*******************************************************************
2728 A wrapper that handles case sensitivity and the special handling
2729 of the ".." name.
2730 *******************************************************************/
2732 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
2734 if (strcmp(string,"..") == 0)
2735 string = ".";
2736 if (strcmp(pattern,".") == 0)
2737 return False;
2739 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2742 /*******************************************************************
2743 A wrapper that handles case sensitivity and the special handling
2744 of the ".." name. Varient that is only called by old search code which requires
2745 pattern translation.
2746 *******************************************************************/
2748 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
2750 if (strcmp(string,"..") == 0)
2751 string = ".";
2752 if (strcmp(pattern,".") == 0)
2753 return False;
2755 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2758 /*******************************************************************
2759 A wrapper that handles a list of patters and calls mask_match()
2760 on each. Returns True if any of the patterns match.
2761 *******************************************************************/
2763 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
2765 while (listLen-- > 0) {
2766 if (mask_match(string, *list++, is_case_sensitive))
2767 return True;
2769 return False;
2772 /*********************************************************
2773 Recursive routine that is called by unix_wild_match.
2774 *********************************************************/
2776 static bool unix_do_match(const char *regexp, const char *str)
2778 const char *p;
2780 for( p = regexp; *p && *str; ) {
2782 switch(*p) {
2783 case '?':
2784 str++;
2785 p++;
2786 break;
2788 case '*':
2791 * Look for a character matching
2792 * the one after the '*'.
2794 p++;
2795 if(!*p)
2796 return true; /* Automatic match */
2797 while(*str) {
2799 while(*str && (*p != *str))
2800 str++;
2803 * Patch from weidel@multichart.de. In the case of the regexp
2804 * '*XX*' we want to ensure there are at least 2 'X' characters
2805 * in the string after the '*' for a match to be made.
2809 int matchcount=0;
2812 * Eat all the characters that match, but count how many there were.
2815 while(*str && (*p == *str)) {
2816 str++;
2817 matchcount++;
2821 * Now check that if the regexp had n identical characters that
2822 * matchcount had at least that many matches.
2825 while ( *(p+1) && (*(p+1) == *p)) {
2826 p++;
2827 matchcount--;
2830 if ( matchcount <= 0 )
2831 return false;
2834 str--; /* We've eaten the match char after the '*' */
2836 if(unix_do_match(p, str))
2837 return true;
2839 if(!*str)
2840 return false;
2841 else
2842 str++;
2844 return false;
2846 default:
2847 if(*str != *p)
2848 return false;
2849 str++;
2850 p++;
2851 break;
2855 if(!*p && !*str)
2856 return true;
2858 if (!*p && str[0] == '.' && str[1] == 0)
2859 return true;
2861 if (!*str && *p == '?') {
2862 while (*p == '?')
2863 p++;
2864 return(!*p);
2867 if(!*str && (*p == '*' && p[1] == '\0'))
2868 return true;
2870 return false;
2873 /*******************************************************************
2874 Simple case insensitive interface to a UNIX wildcard matcher.
2875 Returns True if match, False if not.
2876 *******************************************************************/
2878 bool unix_wild_match(const char *pattern, const char *string)
2880 TALLOC_CTX *ctx = talloc_stackframe();
2881 char *p2;
2882 char *s2;
2883 char *p;
2884 bool ret = false;
2886 p2 = talloc_strdup(ctx,pattern);
2887 s2 = talloc_strdup(ctx,string);
2888 if (!p2 || !s2) {
2889 TALLOC_FREE(ctx);
2890 return false;
2892 strlower_m(p2);
2893 strlower_m(s2);
2895 /* Remove any *? and ** from the pattern as they are meaningless */
2896 for(p = p2; *p; p++) {
2897 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
2898 memmove(&p[1], &p[2], strlen(&p[2])+1);
2902 if (strequal(p2,"*")) {
2903 TALLOC_FREE(ctx);
2904 return true;
2907 ret = unix_do_match(p2, s2);
2908 TALLOC_FREE(ctx);
2909 return ret;
2912 /**********************************************************************
2913 Converts a name to a fully qualified domain name.
2914 Returns true if lookup succeeded, false if not (then fqdn is set to name)
2915 Note we deliberately use gethostbyname here, not getaddrinfo as we want
2916 to examine the h_aliases and I don't know how to do that with getaddrinfo.
2917 ***********************************************************************/
2919 bool name_to_fqdn(fstring fqdn, const char *name)
2921 char *full = NULL;
2922 struct hostent *hp = gethostbyname(name);
2924 if (!hp || !hp->h_name || !*hp->h_name) {
2925 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2926 fstrcpy(fqdn, name);
2927 return false;
2930 /* Find out if the fqdn is returned as an alias
2931 * to cope with /etc/hosts files where the first
2932 * name is not the fqdn but the short name */
2933 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2934 int i;
2935 for (i = 0; hp->h_aliases[i]; i++) {
2936 if (strchr_m(hp->h_aliases[i], '.')) {
2937 full = hp->h_aliases[i];
2938 break;
2942 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2943 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2944 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2945 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
2946 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
2947 full = hp->h_name;
2949 if (!full) {
2950 full = hp->h_name;
2953 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2954 fstrcpy(fqdn, full);
2955 return true;
2958 /**********************************************************************
2959 Extension to talloc_get_type: Abort on type mismatch
2960 ***********************************************************************/
2962 void *talloc_check_name_abort(const void *ptr, const char *name)
2964 void *result;
2966 result = talloc_check_name(ptr, name);
2967 if (result != NULL)
2968 return result;
2970 DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2971 name, talloc_get_name(ptr)));
2972 smb_panic("talloc type mismatch");
2973 /* Keep the compiler happy */
2974 return NULL;
2977 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2979 switch (share_access & ~FILE_SHARE_DELETE) {
2980 case FILE_SHARE_NONE:
2981 return DENY_ALL;
2982 case FILE_SHARE_READ:
2983 return DENY_WRITE;
2984 case FILE_SHARE_WRITE:
2985 return DENY_READ;
2986 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2987 return DENY_NONE;
2989 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2990 return DENY_DOS;
2991 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2992 return DENY_FCB;
2995 return (uint32)-1;
2998 pid_t procid_to_pid(const struct server_id *proc)
3000 return proc->pid;
3003 static uint32 my_vnn = NONCLUSTER_VNN;
3005 void set_my_vnn(uint32 vnn)
3007 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
3008 my_vnn = vnn;
3011 uint32 get_my_vnn(void)
3013 return my_vnn;
3016 struct server_id pid_to_procid(pid_t pid)
3018 struct server_id result;
3019 result.pid = pid;
3020 #ifdef CLUSTER_SUPPORT
3021 result.vnn = my_vnn;
3022 #endif
3023 return result;
3026 struct server_id procid_self(void)
3028 return pid_to_procid(sys_getpid());
3031 struct server_id server_id_self(void)
3033 return procid_self();
3036 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
3038 if (p1->pid != p2->pid)
3039 return False;
3040 #ifdef CLUSTER_SUPPORT
3041 if (p1->vnn != p2->vnn)
3042 return False;
3043 #endif
3044 return True;
3047 bool cluster_id_equal(const struct server_id *id1,
3048 const struct server_id *id2)
3050 return procid_equal(id1, id2);
3053 bool procid_is_me(const struct server_id *pid)
3055 if (pid->pid != sys_getpid())
3056 return False;
3057 #ifdef CLUSTER_SUPPORT
3058 if (pid->vnn != my_vnn)
3059 return False;
3060 #endif
3061 return True;
3064 struct server_id interpret_pid(const char *pid_string)
3066 #ifdef CLUSTER_SUPPORT
3067 unsigned int vnn, pid;
3068 struct server_id result;
3069 if (sscanf(pid_string, "%u:%u", &vnn, &pid) == 2) {
3070 result.vnn = vnn;
3071 result.pid = pid;
3073 else if (sscanf(pid_string, "%u", &pid) == 1) {
3074 result.vnn = NONCLUSTER_VNN;
3075 result.pid = pid;
3077 else {
3078 result.vnn = NONCLUSTER_VNN;
3079 result.pid = -1;
3081 return result;
3082 #else
3083 return pid_to_procid(atoi(pid_string));
3084 #endif
3087 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
3089 #ifdef CLUSTER_SUPPORT
3090 if (pid->vnn == NONCLUSTER_VNN) {
3091 return talloc_asprintf(mem_ctx,
3092 "%d",
3093 (int)pid->pid);
3095 else {
3096 return talloc_asprintf(mem_ctx,
3097 "%u:%d",
3098 (unsigned)pid->vnn,
3099 (int)pid->pid);
3101 #else
3102 return talloc_asprintf(mem_ctx,
3103 "%d",
3104 (int)pid->pid);
3105 #endif
3108 char *procid_str_static(const struct server_id *pid)
3110 return procid_str(talloc_tos(), pid);
3113 bool procid_valid(const struct server_id *pid)
3115 return (pid->pid != -1);
3118 bool procid_is_local(const struct server_id *pid)
3120 #ifdef CLUSTER_SUPPORT
3121 return pid->vnn == my_vnn;
3122 #else
3123 return True;
3124 #endif
3127 int this_is_smp(void)
3129 #if defined(HAVE_SYSCONF)
3131 #if defined(SYSCONF_SC_NPROC_ONLN)
3132 return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
3133 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3134 return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
3135 #else
3136 return 0;
3137 #endif
3139 #else
3140 return 0;
3141 #endif
3144 /****************************************************************
3145 Check if an offset into a buffer is safe.
3146 If this returns True it's safe to indirect into the byte at
3147 pointer ptr+off.
3148 ****************************************************************/
3150 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3152 const char *end_base = buf_base + buf_len;
3153 char *end_ptr = ptr + off;
3155 if (!buf_base || !ptr) {
3156 return False;
3159 if (end_base < buf_base || end_ptr < ptr) {
3160 return False; /* wrap. */
3163 if (end_ptr < end_base) {
3164 return True;
3166 return False;
3169 /****************************************************************
3170 Return a safe pointer into a buffer, or NULL.
3171 ****************************************************************/
3173 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3175 return is_offset_safe(buf_base, buf_len, ptr, off) ?
3176 ptr + off : NULL;
3179 /****************************************************************
3180 Return a safe pointer into a string within a buffer, or NULL.
3181 ****************************************************************/
3183 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3185 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
3186 return NULL;
3188 /* Check if a valid string exists at this offset. */
3189 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
3190 return NULL;
3192 return ptr + off;
3195 /****************************************************************
3196 Return an SVAL at a pointer, or failval if beyond the end.
3197 ****************************************************************/
3199 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3202 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
3203 * NOT ptr[2].
3205 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
3206 return failval;
3208 return SVAL(ptr,off);
3211 /****************************************************************
3212 Return an IVAL at a pointer, or failval if beyond the end.
3213 ****************************************************************/
3215 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3218 * Note we use off+3 here, not off+4 as IVAL accesses
3219 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
3221 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
3222 return failval;
3224 return IVAL(ptr,off);
3227 /****************************************************************
3228 Split DOM\user into DOM and user. Do not mix with winbind variants of that
3229 call (they take care of winbind separator and other winbind specific settings).
3230 ****************************************************************/
3232 void split_domain_user(TALLOC_CTX *mem_ctx,
3233 const char *full_name,
3234 char **domain,
3235 char **user)
3237 const char *p = NULL;
3239 p = strchr_m(full_name, '\\');
3241 if (p != NULL) {
3242 *domain = talloc_strndup(mem_ctx, full_name,
3243 PTR_DIFF(p, full_name));
3244 *user = talloc_strdup(mem_ctx, p+1);
3245 } else {
3246 *domain = talloc_strdup(mem_ctx, "");
3247 *user = talloc_strdup(mem_ctx, full_name);
3251 #if 0
3253 Disable these now we have checked all code paths and ensured
3254 NULL returns on zero request. JRA.
3256 /****************************************************************
3257 talloc wrapper functions that guarentee a null pointer return
3258 if size == 0.
3259 ****************************************************************/
3261 #ifndef MAX_TALLOC_SIZE
3262 #define MAX_TALLOC_SIZE 0x10000000
3263 #endif
3266 * talloc and zero memory.
3267 * - returns NULL if size is zero.
3270 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
3272 void *p;
3274 if (size == 0) {
3275 return NULL;
3278 p = talloc_named_const(ctx, size, name);
3280 if (p) {
3281 memset(p, '\0', size);
3284 return p;
3288 * memdup with a talloc.
3289 * - returns NULL if size is zero.
3292 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
3294 void *newp;
3296 if (size == 0) {
3297 return NULL;
3300 newp = talloc_named_const(t, size, name);
3301 if (newp) {
3302 memcpy(newp, p, size);
3305 return newp;
3309 * alloc an array, checking for integer overflow in the array size.
3310 * - returns NULL if count or el_size are zero.
3313 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3315 if (count >= MAX_TALLOC_SIZE/el_size) {
3316 return NULL;
3319 if (el_size == 0 || count == 0) {
3320 return NULL;
3323 return talloc_named_const(ctx, el_size * count, name);
3327 * alloc an zero array, checking for integer overflow in the array size
3328 * - returns NULL if count or el_size are zero.
3331 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3333 if (count >= MAX_TALLOC_SIZE/el_size) {
3334 return NULL;
3337 if (el_size == 0 || count == 0) {
3338 return NULL;
3341 return _talloc_zero(ctx, el_size * count, name);
3345 * Talloc wrapper that returns NULL if size == 0.
3347 void *talloc_zeronull(const void *context, size_t size, const char *name)
3349 if (size == 0) {
3350 return NULL;
3352 return talloc_named_const(context, size, name);
3354 #endif
3356 /* Split a path name into filename and stream name components. Canonicalise
3357 * such that an implicit $DATA token is always explicit.
3359 * The "specification" of this function can be found in the
3360 * run_local_stream_name() function in torture.c, I've tried those
3361 * combinations against a W2k3 server.
3364 NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
3365 char **pbase, char **pstream)
3367 char *base = NULL;
3368 char *stream = NULL;
3369 char *sname; /* stream name */
3370 const char *stype; /* stream type */
3372 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
3374 sname = strchr_m(fname, ':');
3376 if (lp_posix_pathnames() || (sname == NULL)) {
3377 if (pbase != NULL) {
3378 base = talloc_strdup(mem_ctx, fname);
3379 NT_STATUS_HAVE_NO_MEMORY(base);
3381 goto done;
3384 if (pbase != NULL) {
3385 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
3386 NT_STATUS_HAVE_NO_MEMORY(base);
3389 sname += 1;
3391 stype = strchr_m(sname, ':');
3393 if (stype == NULL) {
3394 sname = talloc_strdup(mem_ctx, sname);
3395 stype = "$DATA";
3397 else {
3398 if (StrCaseCmp(stype, ":$DATA") != 0) {
3400 * If there is an explicit stream type, so far we only
3401 * allow $DATA. Is there anything else allowed? -- vl
3403 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
3404 TALLOC_FREE(base);
3405 return NT_STATUS_OBJECT_NAME_INVALID;
3407 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
3408 stype += 1;
3411 if (sname == NULL) {
3412 TALLOC_FREE(base);
3413 return NT_STATUS_NO_MEMORY;
3416 if (sname[0] == '\0') {
3418 * no stream name, so no stream
3420 goto done;
3423 if (pstream != NULL) {
3424 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
3425 if (stream == NULL) {
3426 TALLOC_FREE(sname);
3427 TALLOC_FREE(base);
3428 return NT_STATUS_NO_MEMORY;
3431 * upper-case the type field
3433 strupper_m(strchr_m(stream, ':')+1);
3436 done:
3437 if (pbase != NULL) {
3438 *pbase = base;
3440 if (pstream != NULL) {
3441 *pstream = stream;
3443 return NT_STATUS_OK;
3446 bool is_valid_policy_hnd(const POLICY_HND *hnd)
3448 POLICY_HND tmp;
3449 ZERO_STRUCT(tmp);
3450 return (memcmp(&tmp, hnd, sizeof(tmp)) != 0);
3453 /****************************************************************
3454 strip off leading '\\' from a hostname
3455 ****************************************************************/
3457 const char *strip_hostname(const char *s)
3459 if (!s) {
3460 return NULL;
3463 if (strlen_m(s) < 3) {
3464 return s;
3467 if (s[0] == '\\') s++;
3468 if (s[0] == '\\') s++;
3470 return s;