docs: Improve description of the share commands in man smb.conf.
[Samba/gebeck_regimport.git] / source3 / lib / util.c
blob08ea5add7a559a0bf83c02fae6ea99c5c7d7397e
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2007
6 Copyright (C) Simo Sorce 2001
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) James Peach 2006
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
26 extern char *global_clobber_region_function;
27 extern unsigned int global_clobber_region_line;
29 /* Max allowable allococation - 256mb - 0x10000000 */
30 #define MAX_ALLOC_SIZE (1024*1024*256)
32 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
33 #ifdef WITH_NISPLUS_HOME
34 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
36 * The following lines are needed due to buggy include files
37 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
38 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
39 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
40 * an enum in /usr/include/rpcsvc/nis.h.
43 #if defined(GROUP)
44 #undef GROUP
45 #endif
47 #if defined(GROUP_OBJ)
48 #undef GROUP_OBJ
49 #endif
51 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
53 #include <rpcsvc/nis.h>
55 #endif /* WITH_NISPLUS_HOME */
56 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
58 enum protocol_types Protocol = PROTOCOL_COREPLUS;
60 /* this is used by the chaining code */
61 int chain_size = 0;
63 static enum remote_arch_types ra_type = RA_UNKNOWN;
65 /***********************************************************************
66 Definitions for all names.
67 ***********************************************************************/
69 static char *smb_myname;
70 static char *smb_myworkgroup;
71 static char *smb_scope;
72 static int smb_num_netbios_names;
73 static char **smb_my_netbios_names;
75 /***********************************************************************
76 Allocate and set myname. Ensure upper case.
77 ***********************************************************************/
79 bool set_global_myname(const char *myname)
81 SAFE_FREE(smb_myname);
82 smb_myname = SMB_STRDUP(myname);
83 if (!smb_myname)
84 return False;
85 strupper_m(smb_myname);
86 return True;
89 const char *global_myname(void)
91 return smb_myname;
94 /***********************************************************************
95 Allocate and set myworkgroup. Ensure upper case.
96 ***********************************************************************/
98 bool set_global_myworkgroup(const char *myworkgroup)
100 SAFE_FREE(smb_myworkgroup);
101 smb_myworkgroup = SMB_STRDUP(myworkgroup);
102 if (!smb_myworkgroup)
103 return False;
104 strupper_m(smb_myworkgroup);
105 return True;
108 const char *lp_workgroup(void)
110 return smb_myworkgroup;
113 /***********************************************************************
114 Allocate and set scope. Ensure upper case.
115 ***********************************************************************/
117 bool set_global_scope(const char *scope)
119 SAFE_FREE(smb_scope);
120 smb_scope = SMB_STRDUP(scope);
121 if (!smb_scope)
122 return False;
123 strupper_m(smb_scope);
124 return True;
127 /*********************************************************************
128 Ensure scope is never null string.
129 *********************************************************************/
131 const char *global_scope(void)
133 if (!smb_scope)
134 set_global_scope("");
135 return smb_scope;
138 static void free_netbios_names_array(void)
140 int i;
142 for (i = 0; i < smb_num_netbios_names; i++)
143 SAFE_FREE(smb_my_netbios_names[i]);
145 SAFE_FREE(smb_my_netbios_names);
146 smb_num_netbios_names = 0;
149 static bool allocate_my_netbios_names_array(size_t number)
151 free_netbios_names_array();
153 smb_num_netbios_names = number + 1;
154 smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
156 if (!smb_my_netbios_names)
157 return False;
159 memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
160 return True;
163 static bool set_my_netbios_names(const char *name, int i)
165 SAFE_FREE(smb_my_netbios_names[i]);
167 smb_my_netbios_names[i] = SMB_STRDUP(name);
168 if (!smb_my_netbios_names[i])
169 return False;
170 strupper_m(smb_my_netbios_names[i]);
171 return True;
174 /***********************************************************************
175 Free memory allocated to global objects
176 ***********************************************************************/
178 void gfree_names(void)
180 SAFE_FREE( smb_myname );
181 SAFE_FREE( smb_myworkgroup );
182 SAFE_FREE( smb_scope );
183 free_netbios_names_array();
184 free_local_machine_name();
187 void gfree_all( void )
189 gfree_names();
190 gfree_loadparm();
191 gfree_case_tables();
192 gfree_charcnv();
193 gfree_interfaces();
194 gfree_debugsyms();
197 const char *my_netbios_names(int i)
199 return smb_my_netbios_names[i];
202 bool set_netbios_aliases(const char **str_array)
204 size_t namecount;
206 /* Work out the max number of netbios aliases that we have */
207 for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
210 if ( global_myname() && *global_myname())
211 namecount++;
213 /* Allocate space for the netbios aliases */
214 if (!allocate_my_netbios_names_array(namecount))
215 return False;
217 /* Use the global_myname string first */
218 namecount=0;
219 if ( global_myname() && *global_myname()) {
220 set_my_netbios_names( global_myname(), namecount );
221 namecount++;
224 if (str_array) {
225 size_t i;
226 for ( i = 0; str_array[i] != NULL; i++) {
227 size_t n;
228 bool duplicate = False;
230 /* Look for duplicates */
231 for( n=0; n<namecount; n++ ) {
232 if( strequal( str_array[i], my_netbios_names(n) ) ) {
233 duplicate = True;
234 break;
237 if (!duplicate) {
238 if (!set_my_netbios_names(str_array[i], namecount))
239 return False;
240 namecount++;
244 return True;
247 /****************************************************************************
248 Common name initialization code.
249 ****************************************************************************/
251 bool init_names(void)
253 int n;
255 if (global_myname() == NULL || *global_myname() == '\0') {
256 if (!set_global_myname(myhostname())) {
257 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
258 return False;
262 if (!set_netbios_aliases(lp_netbios_aliases())) {
263 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
264 return False;
267 set_local_machine_name(global_myname(),false);
269 DEBUG( 5, ("Netbios name list:-\n") );
270 for( n=0; my_netbios_names(n); n++ ) {
271 DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",
272 n, my_netbios_names(n) ) );
275 return( True );
278 /**************************************************************************n
279 Code to cope with username/password auth options from the commandline.
280 Used mainly in client tools.
281 ****************************************************************************/
283 struct user_auth_info *user_auth_info_init(TALLOC_CTX *mem_ctx)
285 struct user_auth_info *result;
287 result = TALLOC_ZERO_P(mem_ctx, struct user_auth_info);
288 if (result == NULL) {
289 return NULL;
292 result->signing_state = Undefined;
293 return result;
296 const char *get_cmdline_auth_info_username(struct user_auth_info *auth_info)
298 if (!auth_info->username) {
299 return "";
301 return auth_info->username;
304 void set_cmdline_auth_info_username(struct user_auth_info *auth_info,
305 const char *username)
307 TALLOC_FREE(auth_info->username);
308 auth_info->username = talloc_strdup(auth_info, username);
309 if (!auth_info->username) {
310 exit(ENOMEM);
314 const char *get_cmdline_auth_info_password(struct user_auth_info *auth_info)
316 if (!auth_info->password) {
317 return "";
319 return auth_info->password;
322 void set_cmdline_auth_info_password(struct user_auth_info *auth_info,
323 const char *password)
325 TALLOC_FREE(auth_info->password);
326 auth_info->password = talloc_strdup(auth_info, password);
327 if (!auth_info->password) {
328 exit(ENOMEM);
330 auth_info->got_pass = true;
333 bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info,
334 const char *arg)
336 auth_info->signing_state = -1;
337 if (strequal(arg, "off") || strequal(arg, "no") ||
338 strequal(arg, "false")) {
339 auth_info->signing_state = false;
340 } else if (strequal(arg, "on") || strequal(arg, "yes") ||
341 strequal(arg, "true") || strequal(arg, "auto")) {
342 auth_info->signing_state = true;
343 } else if (strequal(arg, "force") || strequal(arg, "required") ||
344 strequal(arg, "forced")) {
345 auth_info->signing_state = Required;
346 } else {
347 return false;
349 return true;
352 int get_cmdline_auth_info_signing_state(struct user_auth_info *auth_info)
354 return auth_info->signing_state;
357 void set_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info,
358 bool b)
360 auth_info->use_kerberos = b;
363 bool get_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info)
365 return auth_info->use_kerberos;
368 /* This should only be used by lib/popt_common.c JRA */
369 void set_cmdline_auth_info_use_krb5_ticket(struct user_auth_info *auth_info)
371 auth_info->use_kerberos = true;
372 auth_info->got_pass = true;
375 /* This should only be used by lib/popt_common.c JRA */
376 void set_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info)
378 auth_info->smb_encrypt = true;
381 void set_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info)
383 auth_info->use_machine_account = true;
386 bool get_cmdline_auth_info_got_pass(struct user_auth_info *auth_info)
388 return auth_info->got_pass;
391 bool get_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info)
393 return auth_info->smb_encrypt;
396 bool get_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info)
398 return auth_info->use_machine_account;
401 struct user_auth_info *get_cmdline_auth_info_copy(TALLOC_CTX *mem_ctx,
402 struct user_auth_info *src)
404 struct user_auth_info *result;
406 result = user_auth_info_init(mem_ctx);
407 if (result == NULL) {
408 return NULL;
411 *result = *src;
413 result->username = talloc_strdup(
414 result, get_cmdline_auth_info_username(src));
415 result->password = talloc_strdup(
416 result, get_cmdline_auth_info_password(src));
417 if ((result->username == NULL) || (result->password == NULL)) {
418 TALLOC_FREE(result);
419 return NULL;
422 return result;
425 bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info *auth_info)
427 char *pass = NULL;
428 char *account = NULL;
430 if (!get_cmdline_auth_info_use_machine_account(auth_info)) {
431 return false;
434 if (!secrets_init()) {
435 d_printf("ERROR: Unable to open secrets database\n");
436 return false;
439 if (asprintf(&account, "%s$@%s", global_myname(), lp_realm()) < 0) {
440 return false;
443 pass = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
444 if (!pass) {
445 d_printf("ERROR: Unable to fetch machine password for "
446 "%s in domain %s\n",
447 account, lp_workgroup());
448 SAFE_FREE(account);
449 return false;
452 set_cmdline_auth_info_username(auth_info, account);
453 set_cmdline_auth_info_password(auth_info, pass);
455 SAFE_FREE(account);
456 SAFE_FREE(pass);
458 return true;
461 /****************************************************************************
462 Add a gid to an array of gids if it's not already there.
463 ****************************************************************************/
465 bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
466 gid_t **gids, size_t *num_gids)
468 int i;
470 if ((*num_gids != 0) && (*gids == NULL)) {
472 * A former call to this routine has failed to allocate memory
474 return False;
477 for (i=0; i<*num_gids; i++) {
478 if ((*gids)[i] == gid) {
479 return True;
483 *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1);
484 if (*gids == NULL) {
485 *num_gids = 0;
486 return False;
489 (*gids)[*num_gids] = gid;
490 *num_gids += 1;
491 return True;
494 /*******************************************************************
495 Check if a file exists - call vfs_file_exist for samba files.
496 ********************************************************************/
498 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
500 SMB_STRUCT_STAT st;
501 if (!sbuf)
502 sbuf = &st;
504 if (sys_stat(fname,sbuf) != 0)
505 return(False);
507 return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
510 /*******************************************************************
511 Check if a unix domain socket exists - call vfs_file_exist for samba files.
512 ********************************************************************/
514 bool socket_exist(const char *fname)
516 SMB_STRUCT_STAT st;
517 if (sys_stat(fname,&st) != 0)
518 return(False);
520 return S_ISSOCK(st.st_mode);
523 /*******************************************************************
524 Check if a directory exists.
525 ********************************************************************/
527 bool directory_exist_stat(char *dname,SMB_STRUCT_STAT *st)
529 SMB_STRUCT_STAT st2;
530 bool ret;
532 if (!st)
533 st = &st2;
535 if (sys_stat(dname,st) != 0)
536 return(False);
538 ret = S_ISDIR(st->st_mode);
539 if(!ret)
540 errno = ENOTDIR;
541 return ret;
544 /*******************************************************************
545 Returns the size in bytes of the named file.
546 ********************************************************************/
548 SMB_OFF_T get_file_size(char *file_name)
550 SMB_STRUCT_STAT buf;
551 buf.st_size = 0;
552 if(sys_stat(file_name,&buf) != 0)
553 return (SMB_OFF_T)-1;
554 return(buf.st_size);
557 /*******************************************************************
558 Return a string representing an attribute for a file.
559 ********************************************************************/
561 char *attrib_string(uint16 mode)
563 fstring attrstr;
565 attrstr[0] = 0;
567 if (mode & aVOLID) fstrcat(attrstr,"V");
568 if (mode & aDIR) fstrcat(attrstr,"D");
569 if (mode & aARCH) fstrcat(attrstr,"A");
570 if (mode & aHIDDEN) fstrcat(attrstr,"H");
571 if (mode & aSYSTEM) fstrcat(attrstr,"S");
572 if (mode & aRONLY) fstrcat(attrstr,"R");
574 return talloc_strdup(talloc_tos(), attrstr);
577 /*******************************************************************
578 Show a smb message structure.
579 ********************************************************************/
581 void show_msg(char *buf)
583 int i;
584 int bcc=0;
586 if (!DEBUGLVL(5))
587 return;
589 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
590 smb_len(buf),
591 (int)CVAL(buf,smb_com),
592 (int)CVAL(buf,smb_rcls),
593 (int)CVAL(buf,smb_reh),
594 (int)SVAL(buf,smb_err),
595 (int)CVAL(buf,smb_flg),
596 (int)SVAL(buf,smb_flg2)));
597 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
598 (int)SVAL(buf,smb_tid),
599 (int)SVAL(buf,smb_pid),
600 (int)SVAL(buf,smb_uid),
601 (int)SVAL(buf,smb_mid)));
602 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
604 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
605 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
606 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
608 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
610 DEBUGADD(5,("smb_bcc=%d\n",bcc));
612 if (DEBUGLEVEL < 10)
613 return;
615 if (DEBUGLEVEL < 50)
616 bcc = MIN(bcc, 512);
618 dump_data(10, (uint8 *)smb_buf(buf), bcc);
621 /*******************************************************************
622 Set the length and marker of an encrypted smb packet.
623 ********************************************************************/
625 void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num)
627 _smb_setlen(buf,len);
629 SCVAL(buf,4,0xFF);
630 SCVAL(buf,5,'E');
631 SSVAL(buf,6,enc_ctx_num);
634 /*******************************************************************
635 Set the length and marker of an smb packet.
636 ********************************************************************/
638 void smb_setlen(char *buf,int len)
640 _smb_setlen(buf,len);
642 SCVAL(buf,4,0xFF);
643 SCVAL(buf,5,'S');
644 SCVAL(buf,6,'M');
645 SCVAL(buf,7,'B');
648 /*******************************************************************
649 Setup only the byte count for a smb message.
650 ********************************************************************/
652 int set_message_bcc(char *buf,int num_bytes)
654 int num_words = CVAL(buf,smb_wct);
655 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
656 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
657 return (smb_size + num_words*2 + num_bytes);
660 /*******************************************************************
661 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
662 Return the bytes added
663 ********************************************************************/
665 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
667 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
668 uint8 *tmp;
670 if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
671 DEBUG(0, ("talloc failed\n"));
672 return -1;
674 *outbuf = tmp;
676 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
677 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
678 return blob.length;
681 /*******************************************************************
682 Reduce a file name, removing .. elements.
683 ********************************************************************/
685 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
687 char *p = NULL;
688 char *str = NULL;
690 DEBUG(3,("dos_clean_name [%s]\n",s));
692 /* remove any double slashes */
693 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
694 if (!str) {
695 return NULL;
698 /* Remove leading .\\ characters */
699 if(strncmp(str, ".\\", 2) == 0) {
700 trim_string(str, ".\\", NULL);
701 if(*str == 0) {
702 str = talloc_strdup(ctx, ".\\");
703 if (!str) {
704 return NULL;
709 while ((p = strstr_m(str,"\\..\\")) != NULL) {
710 char *s1;
712 *p = 0;
713 s1 = p+3;
715 if ((p=strrchr_m(str,'\\')) != NULL) {
716 *p = 0;
717 } else {
718 *str = 0;
720 str = talloc_asprintf(ctx,
721 "%s%s",
722 str,
723 s1);
724 if (!str) {
725 return NULL;
729 trim_string(str,NULL,"\\..");
730 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
733 /*******************************************************************
734 Reduce a file name, removing .. elements.
735 ********************************************************************/
737 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
739 char *p = NULL;
740 char *str = NULL;
742 DEBUG(3,("unix_clean_name [%s]\n",s));
744 /* remove any double slashes */
745 str = talloc_all_string_sub(ctx, s, "//","/");
746 if (!str) {
747 return NULL;
750 /* Remove leading ./ characters */
751 if(strncmp(str, "./", 2) == 0) {
752 trim_string(str, "./", NULL);
753 if(*str == 0) {
754 str = talloc_strdup(ctx, "./");
755 if (!str) {
756 return NULL;
761 while ((p = strstr_m(str,"/../")) != NULL) {
762 char *s1;
764 *p = 0;
765 s1 = p+3;
767 if ((p=strrchr_m(str,'/')) != NULL) {
768 *p = 0;
769 } else {
770 *str = 0;
772 str = talloc_asprintf(ctx,
773 "%s%s",
774 str,
775 s1);
776 if (!str) {
777 return NULL;
781 trim_string(str,NULL,"/..");
782 return talloc_all_string_sub(ctx, str, "/./", "/");
785 char *clean_name(TALLOC_CTX *ctx, const char *s)
787 char *str = dos_clean_name(ctx, s);
788 if (!str) {
789 return NULL;
791 return unix_clean_name(ctx, str);
794 /*******************************************************************
795 Close the low 3 fd's and open dev/null in their place.
796 ********************************************************************/
798 void close_low_fds(bool stderr_too)
800 #ifndef VALGRIND
801 int fd;
802 int i;
804 close(0);
805 close(1);
807 if (stderr_too)
808 close(2);
810 /* try and use up these file descriptors, so silly
811 library routines writing to stdout etc won't cause havoc */
812 for (i=0;i<3;i++) {
813 if (i == 2 && !stderr_too)
814 continue;
816 fd = sys_open("/dev/null",O_RDWR,0);
817 if (fd < 0)
818 fd = sys_open("/dev/null",O_WRONLY,0);
819 if (fd < 0) {
820 DEBUG(0,("Can't open /dev/null\n"));
821 return;
823 if (fd != i) {
824 DEBUG(0,("Didn't get file descriptor %d\n",i));
825 return;
828 #endif
831 /*******************************************************************
832 Write data into an fd at a given offset. Ignore seek errors.
833 ********************************************************************/
835 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
837 size_t total=0;
838 ssize_t ret;
840 if (pos == (SMB_OFF_T)-1) {
841 return write_data(fd, buffer, N);
843 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
844 while (total < N) {
845 ret = sys_pwrite(fd,buffer + total,N - total, pos);
846 if (ret == -1 && errno == ESPIPE) {
847 return write_data(fd, buffer + total,N - total);
849 if (ret == -1) {
850 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
851 return -1;
853 if (ret == 0) {
854 return total;
856 total += ret;
857 pos += ret;
859 return (ssize_t)total;
860 #else
861 /* Use lseek and write_data. */
862 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
863 if (errno != ESPIPE) {
864 return -1;
867 return write_data(fd, buffer, N);
868 #endif
871 /*******************************************************************
872 Sleep for a specified number of milliseconds.
873 ********************************************************************/
875 void smb_msleep(unsigned int t)
877 #if defined(HAVE_NANOSLEEP)
878 struct timespec tval;
879 int ret;
881 tval.tv_sec = t/1000;
882 tval.tv_nsec = 1000000*(t%1000);
884 do {
885 errno = 0;
886 ret = nanosleep(&tval, &tval);
887 } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
888 #else
889 unsigned int tdiff=0;
890 struct timeval tval,t1,t2;
891 fd_set fds;
893 GetTimeOfDay(&t1);
894 t2 = t1;
896 while (tdiff < t) {
897 tval.tv_sec = (t-tdiff)/1000;
898 tval.tv_usec = 1000*((t-tdiff)%1000);
900 /* Never wait for more than 1 sec. */
901 if (tval.tv_sec > 1) {
902 tval.tv_sec = 1;
903 tval.tv_usec = 0;
906 FD_ZERO(&fds);
907 errno = 0;
908 sys_select_intr(0,&fds,NULL,NULL,&tval);
910 GetTimeOfDay(&t2);
911 if (t2.tv_sec < t1.tv_sec) {
912 /* Someone adjusted time... */
913 t1 = t2;
916 tdiff = TvalDiff(&t1,&t2);
918 #endif
921 /****************************************************************************
922 Become a daemon, discarding the controlling terminal.
923 ****************************************************************************/
925 void become_daemon(bool Fork, bool no_process_group)
927 if (Fork) {
928 if (sys_fork()) {
929 _exit(0);
933 /* detach from the terminal */
934 #ifdef HAVE_SETSID
935 if (!no_process_group) setsid();
936 #elif defined(TIOCNOTTY)
937 if (!no_process_group) {
938 int i = sys_open("/dev/tty", O_RDWR, 0);
939 if (i != -1) {
940 ioctl(i, (int) TIOCNOTTY, (char *)0);
941 close(i);
944 #endif /* HAVE_SETSID */
946 /* Close fd's 0,1,2. Needed if started by rsh */
947 close_low_fds(False); /* Don't close stderr, let the debug system
948 attach it to the logfile */
951 bool reinit_after_fork(struct messaging_context *msg_ctx,
952 struct event_context *ev_ctx,
953 bool parent_longlived)
955 NTSTATUS status;
957 /* Reset the state of the random
958 * number generation system, so
959 * children do not get the same random
960 * numbers as each other */
961 set_need_random_reseed();
963 /* tdb needs special fork handling */
964 if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
965 DEBUG(0,("tdb_reopen_all failed.\n"));
966 return false;
970 * For clustering, we need to re-init our ctdbd connection after the
971 * fork
973 status = messaging_reinit(msg_ctx);
974 if (!NT_STATUS_IS_OK(status)) {
975 DEBUG(0,("messaging_reinit() failed: %s\n",
976 nt_errstr(status)));
977 return false;
980 event_context_reinit(ev_ctx);
982 return true;
985 /****************************************************************************
986 Put up a yes/no prompt.
987 ****************************************************************************/
989 bool yesno(const char *p)
991 char ans[20];
992 printf("%s",p);
994 if (!fgets(ans,sizeof(ans)-1,stdin))
995 return(False);
997 if (*ans == 'y' || *ans == 'Y')
998 return(True);
1000 return(False);
1003 #if defined(PARANOID_MALLOC_CHECKER)
1005 /****************************************************************************
1006 Internal malloc wrapper. Externally visible.
1007 ****************************************************************************/
1009 void *malloc_(size_t size)
1011 if (size == 0) {
1012 return NULL;
1014 #undef malloc
1015 return malloc(size);
1016 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
1019 /****************************************************************************
1020 Internal calloc wrapper. Not externally visible.
1021 ****************************************************************************/
1023 static void *calloc_(size_t count, size_t size)
1025 if (size == 0 || count == 0) {
1026 return NULL;
1028 #undef calloc
1029 return calloc(count, size);
1030 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
1033 /****************************************************************************
1034 Internal realloc wrapper. Not externally visible.
1035 ****************************************************************************/
1037 static void *realloc_(void *ptr, size_t size)
1039 #undef realloc
1040 return realloc(ptr, size);
1041 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
1044 #endif /* PARANOID_MALLOC_CHECKER */
1046 /****************************************************************************
1047 Type-safe memalign
1048 ****************************************************************************/
1050 void *memalign_array(size_t el_size, size_t align, unsigned int count)
1052 if (count >= MAX_ALLOC_SIZE/el_size) {
1053 return NULL;
1056 return sys_memalign(align, el_size*count);
1059 /****************************************************************************
1060 Type-safe calloc.
1061 ****************************************************************************/
1063 void *calloc_array(size_t size, size_t nmemb)
1065 if (nmemb >= MAX_ALLOC_SIZE/size) {
1066 return NULL;
1068 if (size == 0 || nmemb == 0) {
1069 return NULL;
1071 #if defined(PARANOID_MALLOC_CHECKER)
1072 return calloc_(nmemb, size);
1073 #else
1074 return calloc(nmemb, size);
1075 #endif
1078 /****************************************************************************
1079 Expand a pointer to be a particular size.
1080 Note that this version of Realloc has an extra parameter that decides
1081 whether to free the passed in storage on allocation failure or if the
1082 new size is zero.
1084 This is designed for use in the typical idiom of :
1086 p = SMB_REALLOC(p, size)
1087 if (!p) {
1088 return error;
1091 and not to have to keep track of the old 'p' contents to free later, nor
1092 to worry if the size parameter was zero. In the case where NULL is returned
1093 we guarentee that p has been freed.
1095 If free later semantics are desired, then pass 'free_old_on_error' as False which
1096 guarentees that the old contents are not freed on error, even if size == 0. To use
1097 this idiom use :
1099 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
1100 if (!tmp) {
1101 SAFE_FREE(p);
1102 return error;
1103 } else {
1104 p = tmp;
1107 Changes were instigated by Coverity error checking. JRA.
1108 ****************************************************************************/
1110 void *Realloc(void *p, size_t size, bool free_old_on_error)
1112 void *ret=NULL;
1114 if (size == 0) {
1115 if (free_old_on_error) {
1116 SAFE_FREE(p);
1118 DEBUG(2,("Realloc asked for 0 bytes\n"));
1119 return NULL;
1122 #if defined(PARANOID_MALLOC_CHECKER)
1123 if (!p) {
1124 ret = (void *)malloc_(size);
1125 } else {
1126 ret = (void *)realloc_(p,size);
1128 #else
1129 if (!p) {
1130 ret = (void *)malloc(size);
1131 } else {
1132 ret = (void *)realloc(p,size);
1134 #endif
1136 if (!ret) {
1137 if (free_old_on_error && p) {
1138 SAFE_FREE(p);
1140 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1143 return(ret);
1146 /****************************************************************************
1147 (Hopefully) efficient array append.
1148 ****************************************************************************/
1150 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1151 void *element, void *_array, uint32 *num_elements,
1152 ssize_t *array_size)
1154 void **array = (void **)_array;
1156 if (*array_size < 0) {
1157 return;
1160 if (*array == NULL) {
1161 if (*array_size == 0) {
1162 *array_size = 128;
1165 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1166 goto error;
1169 *array = TALLOC(mem_ctx, element_size * (*array_size));
1170 if (*array == NULL) {
1171 goto error;
1175 if (*num_elements == *array_size) {
1176 *array_size *= 2;
1178 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1179 goto error;
1182 *array = TALLOC_REALLOC(mem_ctx, *array,
1183 element_size * (*array_size));
1185 if (*array == NULL) {
1186 goto error;
1190 memcpy((char *)(*array) + element_size*(*num_elements),
1191 element, element_size);
1192 *num_elements += 1;
1194 return;
1196 error:
1197 *num_elements = 0;
1198 *array_size = -1;
1201 /****************************************************************************
1202 Get my own name and IP.
1203 ****************************************************************************/
1205 char *talloc_get_myname(TALLOC_CTX *ctx)
1207 char *p;
1208 char hostname[HOST_NAME_MAX];
1210 *hostname = 0;
1212 /* get my host name */
1213 if (gethostname(hostname, sizeof(hostname)) == -1) {
1214 DEBUG(0,("gethostname failed\n"));
1215 return False;
1218 /* Ensure null termination. */
1219 hostname[sizeof(hostname)-1] = '\0';
1221 /* split off any parts after an initial . */
1222 p = strchr_m(hostname,'.');
1223 if (p) {
1224 *p = 0;
1227 return talloc_strdup(ctx, hostname);
1230 /****************************************************************************
1231 Get my own domain name, or "" if we have none.
1232 ****************************************************************************/
1234 char *get_mydnsdomname(TALLOC_CTX *ctx)
1236 const char *domname;
1237 char *p;
1239 domname = get_mydnsfullname();
1240 if (!domname) {
1241 return NULL;
1244 p = strchr_m(domname, '.');
1245 if (p) {
1246 p++;
1247 return talloc_strdup(ctx, p);
1248 } else {
1249 return talloc_strdup(ctx, "");
1253 /****************************************************************************
1254 Interpret a protocol description string, with a default.
1255 ****************************************************************************/
1257 int interpret_protocol(const char *str,int def)
1259 if (strequal(str,"NT1"))
1260 return(PROTOCOL_NT1);
1261 if (strequal(str,"LANMAN2"))
1262 return(PROTOCOL_LANMAN2);
1263 if (strequal(str,"LANMAN1"))
1264 return(PROTOCOL_LANMAN1);
1265 if (strequal(str,"CORE"))
1266 return(PROTOCOL_CORE);
1267 if (strequal(str,"COREPLUS"))
1268 return(PROTOCOL_COREPLUS);
1269 if (strequal(str,"CORE+"))
1270 return(PROTOCOL_COREPLUS);
1272 DEBUG(0,("Unrecognised protocol level %s\n",str));
1274 return(def);
1278 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1279 /******************************************************************
1280 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1281 Based on a fix from <Thomas.Hepper@icem.de>.
1282 Returns a malloc'ed string.
1283 *******************************************************************/
1285 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
1287 if (*str == '-') {
1288 const char *p = str;
1289 while(*p && !isspace(*p))
1290 p++;
1291 while(*p && isspace(*p))
1292 p++;
1293 if(*p) {
1294 return talloc_strdup(ctx, p);
1297 return NULL;
1300 /*******************************************************************
1301 Patch from jkf@soton.ac.uk
1302 Split Luke's automount_server into YP lookup and string splitter
1303 so can easily implement automount_path().
1304 Returns a malloc'ed string.
1305 *******************************************************************/
1307 #ifdef WITH_NISPLUS_HOME
1308 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1310 char *value = NULL;
1312 char *nis_map = (char *)lp_nis_home_map_name();
1314 char buffer[NIS_MAXATTRVAL + 1];
1315 nis_result *result;
1316 nis_object *object;
1317 entry_obj *entry;
1319 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
1320 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1322 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1323 if (result->status != NIS_SUCCESS) {
1324 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1325 } else {
1326 object = result->objects.objects_val;
1327 if (object->zo_data.zo_type == ENTRY_OBJ) {
1328 entry = &object->zo_data.objdata_u.en_data;
1329 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1330 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1332 value = talloc_strdup(ctx,
1333 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1334 if (!value) {
1335 nis_freeresult(result);
1336 return NULL;
1338 value = talloc_string_sub(ctx,
1339 value,
1340 "&",
1341 user_name);
1345 nis_freeresult(result);
1347 if (value) {
1348 value = strip_mount_options(ctx, value);
1349 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
1350 user_name, value));
1352 return value;
1354 #else /* WITH_NISPLUS_HOME */
1356 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1358 char *value = NULL;
1360 int nis_error; /* returned by yp all functions */
1361 char *nis_result; /* yp_match inits this */
1362 int nis_result_len; /* and set this */
1363 char *nis_domain; /* yp_get_default_domain inits this */
1364 char *nis_map = (char *)lp_nis_home_map_name();
1366 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1367 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1368 return NULL;
1371 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1373 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
1374 strlen(user_name), &nis_result,
1375 &nis_result_len)) == 0) {
1376 value = talloc_strdup(ctx, nis_result);
1377 if (!value) {
1378 return NULL;
1380 value = strip_mount_options(ctx, value);
1381 } else if(nis_error == YPERR_KEY) {
1382 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1383 user_name, nis_map));
1384 DEBUG(3, ("using defaults for server and home directory\n"));
1385 } else {
1386 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1387 yperr_string(nis_error), user_name, nis_map));
1390 if (value) {
1391 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
1393 return value;
1395 #endif /* WITH_NISPLUS_HOME */
1396 #endif
1398 /****************************************************************************
1399 Check if a process exists. Does this work on all unixes?
1400 ****************************************************************************/
1402 bool process_exists(const struct server_id pid)
1404 if (procid_is_me(&pid)) {
1405 return True;
1408 if (procid_is_local(&pid)) {
1409 return (kill(pid.pid,0) == 0 || errno != ESRCH);
1412 #ifdef CLUSTER_SUPPORT
1413 return ctdbd_process_exists(messaging_ctdbd_connection(), pid.vnn,
1414 pid.pid);
1415 #else
1416 return False;
1417 #endif
1420 /*******************************************************************
1421 Convert a uid into a user name.
1422 ********************************************************************/
1424 const char *uidtoname(uid_t uid)
1426 TALLOC_CTX *ctx = talloc_tos();
1427 char *name = NULL;
1428 struct passwd *pass = NULL;
1430 pass = getpwuid_alloc(ctx,uid);
1431 if (pass) {
1432 name = talloc_strdup(ctx,pass->pw_name);
1433 TALLOC_FREE(pass);
1434 } else {
1435 name = talloc_asprintf(ctx,
1436 "%ld",
1437 (long int)uid);
1439 return name;
1442 /*******************************************************************
1443 Convert a gid into a group name.
1444 ********************************************************************/
1446 char *gidtoname(gid_t gid)
1448 struct group *grp;
1450 grp = getgrgid(gid);
1451 if (grp) {
1452 return talloc_strdup(talloc_tos(), grp->gr_name);
1454 else {
1455 return talloc_asprintf(talloc_tos(),
1456 "%d",
1457 (int)gid);
1461 /*******************************************************************
1462 Convert a user name into a uid.
1463 ********************************************************************/
1465 uid_t nametouid(const char *name)
1467 struct passwd *pass;
1468 char *p;
1469 uid_t u;
1471 pass = getpwnam_alloc(talloc_autofree_context(), name);
1472 if (pass) {
1473 u = pass->pw_uid;
1474 TALLOC_FREE(pass);
1475 return u;
1478 u = (uid_t)strtol(name, &p, 0);
1479 if ((p != name) && (*p == '\0'))
1480 return u;
1482 return (uid_t)-1;
1485 /*******************************************************************
1486 Convert a name to a gid_t if possible. Return -1 if not a group.
1487 ********************************************************************/
1489 gid_t nametogid(const char *name)
1491 struct group *grp;
1492 char *p;
1493 gid_t g;
1495 g = (gid_t)strtol(name, &p, 0);
1496 if ((p != name) && (*p == '\0'))
1497 return g;
1499 grp = sys_getgrnam(name);
1500 if (grp)
1501 return(grp->gr_gid);
1502 return (gid_t)-1;
1505 /*******************************************************************
1506 Something really nasty happened - panic !
1507 ********************************************************************/
1509 void smb_panic(const char *const why)
1511 char *cmd;
1512 int result;
1514 #ifdef DEVELOPER
1517 if (global_clobber_region_function) {
1518 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1519 global_clobber_region_function,
1520 global_clobber_region_line));
1523 #endif
1525 DEBUG(0,("PANIC (pid %llu): %s\n",
1526 (unsigned long long)sys_getpid(), why));
1527 log_stack_trace();
1529 cmd = lp_panic_action();
1530 if (cmd && *cmd) {
1531 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1532 result = system(cmd);
1534 if (result == -1)
1535 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1536 strerror(errno)));
1537 else
1538 DEBUG(0, ("smb_panic(): action returned status %d\n",
1539 WEXITSTATUS(result)));
1542 dump_core();
1545 /*******************************************************************
1546 Print a backtrace of the stack to the debug log. This function
1547 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1548 exit shortly after calling it.
1549 ********************************************************************/
1551 #ifdef HAVE_LIBUNWIND_H
1552 #include <libunwind.h>
1553 #endif
1555 #ifdef HAVE_EXECINFO_H
1556 #include <execinfo.h>
1557 #endif
1559 #ifdef HAVE_LIBEXC_H
1560 #include <libexc.h>
1561 #endif
1563 void log_stack_trace(void)
1565 #ifdef HAVE_LIBUNWIND
1566 /* Try to use libunwind before any other technique since on ia64
1567 * libunwind correctly walks the stack in more circumstances than
1568 * backtrace.
1570 unw_cursor_t cursor;
1571 unw_context_t uc;
1572 unsigned i = 0;
1574 char procname[256];
1575 unw_word_t ip, sp, off;
1577 procname[sizeof(procname) - 1] = '\0';
1579 if (unw_getcontext(&uc) != 0) {
1580 goto libunwind_failed;
1583 if (unw_init_local(&cursor, &uc) != 0) {
1584 goto libunwind_failed;
1587 DEBUG(0, ("BACKTRACE:\n"));
1589 do {
1590 ip = sp = 0;
1591 unw_get_reg(&cursor, UNW_REG_IP, &ip);
1592 unw_get_reg(&cursor, UNW_REG_SP, &sp);
1594 switch (unw_get_proc_name(&cursor,
1595 procname, sizeof(procname) - 1, &off) ) {
1596 case 0:
1597 /* Name found. */
1598 case -UNW_ENOMEM:
1599 /* Name truncated. */
1600 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1601 i, procname, (long long)off,
1602 (long long)ip, (long long) sp));
1603 break;
1604 default:
1605 /* case -UNW_ENOINFO: */
1606 /* case -UNW_EUNSPEC: */
1607 /* No symbol name found. */
1608 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1609 i, "<unknown symbol>",
1610 (long long)ip, (long long) sp));
1612 ++i;
1613 } while (unw_step(&cursor) > 0);
1615 return;
1617 libunwind_failed:
1618 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1620 #elif HAVE_BACKTRACE_SYMBOLS
1621 void *backtrace_stack[BACKTRACE_STACK_SIZE];
1622 size_t backtrace_size;
1623 char **backtrace_strings;
1625 /* get the backtrace (stack frames) */
1626 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1627 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1629 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1630 (unsigned long)backtrace_size));
1632 if (backtrace_strings) {
1633 int i;
1635 for (i = 0; i < backtrace_size; i++)
1636 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1638 /* Leak the backtrace_strings, rather than risk what free() might do */
1641 #elif HAVE_LIBEXC
1643 /* The IRIX libexc library provides an API for unwinding the stack. See
1644 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1645 * since we are about to abort anyway, it hardly matters.
1648 #define NAMESIZE 32 /* Arbitrary */
1650 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1651 char * names[BACKTRACE_STACK_SIZE];
1652 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1654 int i;
1655 int levels;
1657 ZERO_ARRAY(addrs);
1658 ZERO_ARRAY(names);
1659 ZERO_ARRAY(namebuf);
1661 /* We need to be root so we can open our /proc entry to walk
1662 * our stack. It also helps when we want to dump core.
1664 become_root();
1666 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1667 names[i] = namebuf + (i * NAMESIZE);
1670 levels = trace_back_stack(0, addrs, names,
1671 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1673 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1674 for (i = 0; i < levels; i++) {
1675 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1677 #undef NAMESIZE
1679 #else
1680 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1681 #endif
1684 /*******************************************************************
1685 A readdir wrapper which just returns the file name.
1686 ********************************************************************/
1688 const char *readdirname(SMB_STRUCT_DIR *p)
1690 SMB_STRUCT_DIRENT *ptr;
1691 char *dname;
1693 if (!p)
1694 return(NULL);
1696 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1697 if (!ptr)
1698 return(NULL);
1700 dname = ptr->d_name;
1702 #ifdef NEXT2
1703 if (telldir(p) < 0)
1704 return(NULL);
1705 #endif
1707 #ifdef HAVE_BROKEN_READDIR_NAME
1708 /* using /usr/ucb/cc is BAD */
1709 dname = dname - 2;
1710 #endif
1712 return talloc_strdup(talloc_tos(), dname);
1715 /*******************************************************************
1716 Utility function used to decide if the last component
1717 of a path matches a (possibly wildcarded) entry in a namelist.
1718 ********************************************************************/
1720 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1722 const char *last_component;
1724 /* if we have no list it's obviously not in the path */
1725 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1726 return False;
1729 DEBUG(8, ("is_in_path: %s\n", name));
1731 /* Get the last component of the unix name. */
1732 last_component = strrchr_m(name, '/');
1733 if (!last_component) {
1734 last_component = name;
1735 } else {
1736 last_component++; /* Go past '/' */
1739 for(; namelist->name != NULL; namelist++) {
1740 if(namelist->is_wild) {
1741 if (mask_match(last_component, namelist->name, case_sensitive)) {
1742 DEBUG(8,("is_in_path: mask match succeeded\n"));
1743 return True;
1745 } else {
1746 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1747 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1748 DEBUG(8,("is_in_path: match succeeded\n"));
1749 return True;
1753 DEBUG(8,("is_in_path: match not found\n"));
1754 return False;
1757 /*******************************************************************
1758 Strip a '/' separated list into an array of
1759 name_compare_enties structures suitable for
1760 passing to is_in_path(). We do this for
1761 speed so we can pre-parse all the names in the list
1762 and don't do it for each call to is_in_path().
1763 namelist is modified here and is assumed to be
1764 a copy owned by the caller.
1765 We also check if the entry contains a wildcard to
1766 remove a potentially expensive call to mask_match
1767 if possible.
1768 ********************************************************************/
1770 void set_namearray(name_compare_entry **ppname_array, const char *namelist)
1772 char *name_end;
1773 const char *nameptr = namelist;
1774 int num_entries = 0;
1775 int i;
1777 (*ppname_array) = NULL;
1779 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
1780 return;
1782 /* We need to make two passes over the string. The
1783 first to count the number of elements, the second
1784 to split it.
1787 while(*nameptr) {
1788 if ( *nameptr == '/' ) {
1789 /* cope with multiple (useless) /s) */
1790 nameptr++;
1791 continue;
1793 /* find the next / */
1794 name_end = strchr_m(nameptr, '/');
1796 /* oops - the last check for a / didn't find one. */
1797 if (name_end == NULL)
1798 break;
1800 /* next segment please */
1801 nameptr = name_end + 1;
1802 num_entries++;
1805 if(num_entries == 0)
1806 return;
1808 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1809 DEBUG(0,("set_namearray: malloc fail\n"));
1810 return;
1813 /* Now copy out the names */
1814 nameptr = namelist;
1815 i = 0;
1816 while(*nameptr) {
1817 if ( *nameptr == '/' ) {
1818 /* cope with multiple (useless) /s) */
1819 nameptr++;
1820 continue;
1822 /* find the next / */
1823 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1824 *name_end = 0;
1826 /* oops - the last check for a / didn't find one. */
1827 if(name_end == NULL)
1828 break;
1830 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1831 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1832 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1833 return;
1836 /* next segment please */
1837 nameptr = name_end + 1;
1838 i++;
1841 (*ppname_array)[i].name = NULL;
1843 return;
1846 /****************************************************************************
1847 Routine to free a namearray.
1848 ****************************************************************************/
1850 void free_namearray(name_compare_entry *name_array)
1852 int i;
1854 if(name_array == NULL)
1855 return;
1857 for(i=0; name_array[i].name!=NULL; i++)
1858 SAFE_FREE(name_array[i].name);
1859 SAFE_FREE(name_array);
1862 #undef DBGC_CLASS
1863 #define DBGC_CLASS DBGC_LOCKING
1865 /****************************************************************************
1866 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1867 is dealt with in posix.c
1868 Returns True if we have information regarding this lock region (and returns
1869 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1870 ****************************************************************************/
1872 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1874 SMB_STRUCT_FLOCK lock;
1875 int ret;
1877 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1878 fd,(double)*poffset,(double)*pcount,*ptype));
1880 lock.l_type = *ptype;
1881 lock.l_whence = SEEK_SET;
1882 lock.l_start = *poffset;
1883 lock.l_len = *pcount;
1884 lock.l_pid = 0;
1886 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1888 if (ret == -1) {
1889 int sav = errno;
1890 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1891 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1892 errno = sav;
1893 return False;
1896 *ptype = lock.l_type;
1897 *poffset = lock.l_start;
1898 *pcount = lock.l_len;
1899 *ppid = lock.l_pid;
1901 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1902 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1903 return True;
1906 #undef DBGC_CLASS
1907 #define DBGC_CLASS DBGC_ALL
1909 /*******************************************************************
1910 Is the name specified one of my netbios names.
1911 Returns true if it is equal, false otherwise.
1912 ********************************************************************/
1914 bool is_myname(const char *s)
1916 int n;
1917 bool ret = False;
1919 for (n=0; my_netbios_names(n); n++) {
1920 if (strequal(my_netbios_names(n), s)) {
1921 ret=True;
1922 break;
1925 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1926 return(ret);
1929 /*******************************************************************
1930 Is the name specified our workgroup/domain.
1931 Returns true if it is equal, false otherwise.
1932 ********************************************************************/
1934 bool is_myworkgroup(const char *s)
1936 bool ret = False;
1938 if (strequal(s, lp_workgroup())) {
1939 ret=True;
1942 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1943 return(ret);
1946 /*******************************************************************
1947 we distinguish between 2K and XP by the "Native Lan Manager" string
1948 WinXP => "Windows 2002 5.1"
1949 WinXP 64bit => "Windows XP 5.2"
1950 Win2k => "Windows 2000 5.0"
1951 NT4 => "Windows NT 4.0"
1952 Win9x => "Windows 4.0"
1953 Windows 2003 doesn't set the native lan manager string but
1954 they do set the domain to "Windows 2003 5.2" (probably a bug).
1955 ********************************************************************/
1957 void ra_lanman_string( const char *native_lanman )
1959 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1960 set_remote_arch( RA_WINXP );
1961 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1962 set_remote_arch( RA_WINXP64 );
1963 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1964 set_remote_arch( RA_WIN2K3 );
1967 static const char *remote_arch_str;
1969 const char *get_remote_arch_str(void)
1971 if (!remote_arch_str) {
1972 return "UNKNOWN";
1974 return remote_arch_str;
1977 /*******************************************************************
1978 Set the horrid remote_arch string based on an enum.
1979 ********************************************************************/
1981 void set_remote_arch(enum remote_arch_types type)
1983 ra_type = type;
1984 switch( type ) {
1985 case RA_WFWG:
1986 remote_arch_str = "WfWg";
1987 break;
1988 case RA_OS2:
1989 remote_arch_str = "OS2";
1990 break;
1991 case RA_WIN95:
1992 remote_arch_str = "Win95";
1993 break;
1994 case RA_WINNT:
1995 remote_arch_str = "WinNT";
1996 break;
1997 case RA_WIN2K:
1998 remote_arch_str = "Win2K";
1999 break;
2000 case RA_WINXP:
2001 remote_arch_str = "WinXP";
2002 break;
2003 case RA_WINXP64:
2004 remote_arch_str = "WinXP64";
2005 break;
2006 case RA_WIN2K3:
2007 remote_arch_str = "Win2K3";
2008 break;
2009 case RA_VISTA:
2010 remote_arch_str = "Vista";
2011 break;
2012 case RA_SAMBA:
2013 remote_arch_str = "Samba";
2014 break;
2015 case RA_CIFSFS:
2016 remote_arch_str = "CIFSFS";
2017 break;
2018 default:
2019 ra_type = RA_UNKNOWN;
2020 remote_arch_str = "UNKNOWN";
2021 break;
2024 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
2025 remote_arch_str));
2028 /*******************************************************************
2029 Get the remote_arch type.
2030 ********************************************************************/
2032 enum remote_arch_types get_remote_arch(void)
2034 return ra_type;
2037 const char *tab_depth(int level, int depth)
2039 if( CHECK_DEBUGLVL(level) ) {
2040 dbgtext("%*s", depth*4, "");
2042 return "";
2045 /*****************************************************************************
2046 Provide a checksum on a string
2048 Input: s - the null-terminated character string for which the checksum
2049 will be calculated.
2051 Output: The checksum value calculated for s.
2052 *****************************************************************************/
2054 int str_checksum(const char *s)
2056 int res = 0;
2057 int c;
2058 int i=0;
2060 while(*s) {
2061 c = *s;
2062 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2063 s++;
2064 i++;
2066 return(res);
2069 /*****************************************************************
2070 Zero a memory area then free it. Used to catch bugs faster.
2071 *****************************************************************/
2073 void zero_free(void *p, size_t size)
2075 memset(p, 0, size);
2076 SAFE_FREE(p);
2079 /*****************************************************************
2080 Set our open file limit to a requested max and return the limit.
2081 *****************************************************************/
2083 int set_maxfiles(int requested_max)
2085 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2086 struct rlimit rlp;
2087 int saved_current_limit;
2089 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2090 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2091 strerror(errno) ));
2092 /* just guess... */
2093 return requested_max;
2097 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2098 * account for the extra fd we need
2099 * as well as the log files and standard
2100 * handles etc. Save the limit we want to set in case
2101 * we are running on an OS that doesn't support this limit (AIX)
2102 * which always returns RLIM_INFINITY for rlp.rlim_max.
2105 /* Try raising the hard (max) limit to the requested amount. */
2107 #if defined(RLIM_INFINITY)
2108 if (rlp.rlim_max != RLIM_INFINITY) {
2109 int orig_max = rlp.rlim_max;
2111 if ( rlp.rlim_max < requested_max )
2112 rlp.rlim_max = requested_max;
2114 /* This failing is not an error - many systems (Linux) don't
2115 support our default request of 10,000 open files. JRA. */
2117 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2118 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2119 (int)rlp.rlim_max, strerror(errno) ));
2121 /* Set failed - restore original value from get. */
2122 rlp.rlim_max = orig_max;
2125 #endif
2127 /* Now try setting the soft (current) limit. */
2129 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2131 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2132 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2133 (int)rlp.rlim_cur, strerror(errno) ));
2134 /* just guess... */
2135 return saved_current_limit;
2138 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2139 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2140 strerror(errno) ));
2141 /* just guess... */
2142 return saved_current_limit;
2145 #if defined(RLIM_INFINITY)
2146 if(rlp.rlim_cur == RLIM_INFINITY)
2147 return saved_current_limit;
2148 #endif
2150 if((int)rlp.rlim_cur > saved_current_limit)
2151 return saved_current_limit;
2153 return rlp.rlim_cur;
2154 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2156 * No way to know - just guess...
2158 return requested_max;
2159 #endif
2162 /*****************************************************************
2163 Possibly replace mkstemp if it is broken.
2164 *****************************************************************/
2166 int smb_mkstemp(char *name_template)
2168 #if HAVE_SECURE_MKSTEMP
2169 return mkstemp(name_template);
2170 #else
2171 /* have a reasonable go at emulating it. Hope that
2172 the system mktemp() isn't completly hopeless */
2173 char *p = mktemp(name_template);
2174 if (!p)
2175 return -1;
2176 return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2177 #endif
2180 /*****************************************************************
2181 malloc that aborts with smb_panic on fail or zero size.
2182 *****************************************************************/
2184 void *smb_xmalloc_array(size_t size, unsigned int count)
2186 void *p;
2187 if (size == 0) {
2188 smb_panic("smb_xmalloc_array: called with zero size");
2190 if (count >= MAX_ALLOC_SIZE/size) {
2191 smb_panic("smb_xmalloc_array: alloc size too large");
2193 if ((p = SMB_MALLOC(size*count)) == NULL) {
2194 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2195 (unsigned long)size, (unsigned long)count));
2196 smb_panic("smb_xmalloc_array: malloc failed");
2198 return p;
2202 vasprintf that aborts on malloc fail
2205 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2207 int n;
2208 va_list ap2;
2210 va_copy(ap2, ap);
2212 n = vasprintf(ptr, format, ap2);
2213 if (n == -1 || ! *ptr) {
2214 smb_panic("smb_xvasprintf: out of memory");
2216 va_end(ap2);
2217 return n;
2220 /*****************************************************************
2221 Get local hostname and cache result.
2222 *****************************************************************/
2224 char *myhostname(void)
2226 static char *ret;
2227 if (ret == NULL) {
2228 /* This is cached forever so
2229 * use talloc_autofree_context() ctx. */
2230 ret = talloc_get_myname(talloc_autofree_context());
2232 return ret;
2235 /*****************************************************************
2236 A useful function for returning a path in the Samba pid directory.
2237 *****************************************************************/
2239 static char *xx_path(const char *name, const char *rootpath)
2241 char *fname = NULL;
2243 fname = talloc_strdup(talloc_tos(), rootpath);
2244 if (!fname) {
2245 return NULL;
2247 trim_string(fname,"","/");
2249 if (!directory_exist(fname)) {
2250 mkdir(fname,0755);
2253 return talloc_asprintf(talloc_tos(),
2254 "%s/%s",
2255 fname,
2256 name);
2259 /*****************************************************************
2260 A useful function for returning a path in the Samba lock directory.
2261 *****************************************************************/
2263 char *lock_path(const char *name)
2265 return xx_path(name, lp_lockdir());
2268 /*****************************************************************
2269 A useful function for returning a path in the Samba pid directory.
2270 *****************************************************************/
2272 char *pid_path(const char *name)
2274 return xx_path(name, lp_piddir());
2278 * @brief Returns an absolute path to a file in the Samba lib directory.
2280 * @param name File to find, relative to LIBDIR.
2282 * @retval Pointer to a string containing the full path.
2285 char *lib_path(const char *name)
2287 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
2291 * @brief Returns an absolute path to a file in the Samba modules directory.
2293 * @param name File to find, relative to MODULESDIR.
2295 * @retval Pointer to a string containing the full path.
2298 char *modules_path(const char *name)
2300 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_MODULESDIR(), name);
2304 * @brief Returns an absolute path to a file in the Samba data directory.
2306 * @param name File to find, relative to CODEPAGEDIR.
2308 * @retval Pointer to a talloc'ed string containing the full path.
2311 char *data_path(const char *name)
2313 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
2316 /*****************************************************************
2317 a useful function for returning a path in the Samba state directory
2318 *****************************************************************/
2320 char *state_path(const char *name)
2322 return xx_path(name, get_dyn_STATEDIR());
2326 * @brief Returns the platform specific shared library extension.
2328 * @retval Pointer to a const char * containing the extension.
2331 const char *shlib_ext(void)
2333 return get_dyn_SHLIBEXT();
2336 /*******************************************************************
2337 Given a filename - get its directory name
2338 ********************************************************************/
2340 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
2341 const char **name)
2343 char *p;
2344 ptrdiff_t len;
2346 p = strrchr_m(dir, '/'); /* Find final '/', if any */
2348 if (p == NULL) {
2349 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2350 return False;
2352 if (name) {
2353 *name = "";
2355 return True;
2358 len = p-dir;
2360 if (!(*parent = (char *)TALLOC_MEMDUP(mem_ctx, dir, len+1))) {
2361 return False;
2363 (*parent)[len] = '\0';
2365 if (name) {
2366 *name = p+1;
2368 return True;
2371 /*******************************************************************
2372 Determine if a pattern contains any Microsoft wildcard characters.
2373 *******************************************************************/
2375 bool ms_has_wild(const char *s)
2377 char c;
2379 if (lp_posix_pathnames()) {
2380 /* With posix pathnames no characters are wild. */
2381 return False;
2384 while ((c = *s++)) {
2385 switch (c) {
2386 case '*':
2387 case '?':
2388 case '<':
2389 case '>':
2390 case '"':
2391 return True;
2394 return False;
2397 bool ms_has_wild_w(const smb_ucs2_t *s)
2399 smb_ucs2_t c;
2400 if (!s) return False;
2401 while ((c = *s++)) {
2402 switch (c) {
2403 case UCS2_CHAR('*'):
2404 case UCS2_CHAR('?'):
2405 case UCS2_CHAR('<'):
2406 case UCS2_CHAR('>'):
2407 case UCS2_CHAR('"'):
2408 return True;
2411 return False;
2414 /*******************************************************************
2415 A wrapper that handles case sensitivity and the special handling
2416 of the ".." name.
2417 *******************************************************************/
2419 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
2421 if (strcmp(string,"..") == 0)
2422 string = ".";
2423 if (strcmp(pattern,".") == 0)
2424 return False;
2426 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2429 /*******************************************************************
2430 A wrapper that handles case sensitivity and the special handling
2431 of the ".." name. Varient that is only called by old search code which requires
2432 pattern translation.
2433 *******************************************************************/
2435 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
2437 if (strcmp(string,"..") == 0)
2438 string = ".";
2439 if (strcmp(pattern,".") == 0)
2440 return False;
2442 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2445 /*******************************************************************
2446 A wrapper that handles a list of patters and calls mask_match()
2447 on each. Returns True if any of the patterns match.
2448 *******************************************************************/
2450 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
2452 while (listLen-- > 0) {
2453 if (mask_match(string, *list++, is_case_sensitive))
2454 return True;
2456 return False;
2459 /*********************************************************
2460 Recursive routine that is called by unix_wild_match.
2461 *********************************************************/
2463 static bool unix_do_match(const char *regexp, const char *str)
2465 const char *p;
2467 for( p = regexp; *p && *str; ) {
2469 switch(*p) {
2470 case '?':
2471 str++;
2472 p++;
2473 break;
2475 case '*':
2478 * Look for a character matching
2479 * the one after the '*'.
2481 p++;
2482 if(!*p)
2483 return true; /* Automatic match */
2484 while(*str) {
2486 while(*str && (*p != *str))
2487 str++;
2490 * Patch from weidel@multichart.de. In the case of the regexp
2491 * '*XX*' we want to ensure there are at least 2 'X' characters
2492 * in the string after the '*' for a match to be made.
2496 int matchcount=0;
2499 * Eat all the characters that match, but count how many there were.
2502 while(*str && (*p == *str)) {
2503 str++;
2504 matchcount++;
2508 * Now check that if the regexp had n identical characters that
2509 * matchcount had at least that many matches.
2512 while ( *(p+1) && (*(p+1) == *p)) {
2513 p++;
2514 matchcount--;
2517 if ( matchcount <= 0 )
2518 return false;
2521 str--; /* We've eaten the match char after the '*' */
2523 if(unix_do_match(p, str))
2524 return true;
2526 if(!*str)
2527 return false;
2528 else
2529 str++;
2531 return false;
2533 default:
2534 if(*str != *p)
2535 return false;
2536 str++;
2537 p++;
2538 break;
2542 if(!*p && !*str)
2543 return true;
2545 if (!*p && str[0] == '.' && str[1] == 0)
2546 return true;
2548 if (!*str && *p == '?') {
2549 while (*p == '?')
2550 p++;
2551 return(!*p);
2554 if(!*str && (*p == '*' && p[1] == '\0'))
2555 return true;
2557 return false;
2560 /*******************************************************************
2561 Simple case insensitive interface to a UNIX wildcard matcher.
2562 Returns True if match, False if not.
2563 *******************************************************************/
2565 bool unix_wild_match(const char *pattern, const char *string)
2567 TALLOC_CTX *ctx = talloc_stackframe();
2568 char *p2;
2569 char *s2;
2570 char *p;
2571 bool ret = false;
2573 p2 = talloc_strdup(ctx,pattern);
2574 s2 = talloc_strdup(ctx,string);
2575 if (!p2 || !s2) {
2576 TALLOC_FREE(ctx);
2577 return false;
2579 strlower_m(p2);
2580 strlower_m(s2);
2582 /* Remove any *? and ** from the pattern as they are meaningless */
2583 for(p = p2; *p; p++) {
2584 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
2585 memmove(&p[1], &p[2], strlen(&p[2])+1);
2589 if (strequal(p2,"*")) {
2590 TALLOC_FREE(ctx);
2591 return true;
2594 ret = unix_do_match(p2, s2);
2595 TALLOC_FREE(ctx);
2596 return ret;
2599 /**********************************************************************
2600 Converts a name to a fully qualified domain name.
2601 Returns true if lookup succeeded, false if not (then fqdn is set to name)
2602 Note we deliberately use gethostbyname here, not getaddrinfo as we want
2603 to examine the h_aliases and I don't know how to do that with getaddrinfo.
2604 ***********************************************************************/
2606 bool name_to_fqdn(fstring fqdn, const char *name)
2608 char *full = NULL;
2609 struct hostent *hp = gethostbyname(name);
2611 if (!hp || !hp->h_name || !*hp->h_name) {
2612 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2613 fstrcpy(fqdn, name);
2614 return false;
2617 /* Find out if the fqdn is returned as an alias
2618 * to cope with /etc/hosts files where the first
2619 * name is not the fqdn but the short name */
2620 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2621 int i;
2622 for (i = 0; hp->h_aliases[i]; i++) {
2623 if (strchr_m(hp->h_aliases[i], '.')) {
2624 full = hp->h_aliases[i];
2625 break;
2629 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2630 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2631 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2632 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
2633 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
2634 full = hp->h_name;
2636 if (!full) {
2637 full = hp->h_name;
2640 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2641 fstrcpy(fqdn, full);
2642 return true;
2645 /**********************************************************************
2646 Append a DATA_BLOB to a talloc'ed object
2647 ***********************************************************************/
2649 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
2651 size_t old_size = 0;
2652 char *result;
2654 if (blob.length == 0) {
2655 return buf;
2658 if (buf != NULL) {
2659 old_size = talloc_get_size(buf);
2662 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
2663 if (result == NULL) {
2664 return NULL;
2667 memcpy(result + old_size, blob.data, blob.length);
2668 return result;
2671 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2673 switch (share_access & ~FILE_SHARE_DELETE) {
2674 case FILE_SHARE_NONE:
2675 return DENY_ALL;
2676 case FILE_SHARE_READ:
2677 return DENY_WRITE;
2678 case FILE_SHARE_WRITE:
2679 return DENY_READ;
2680 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2681 return DENY_NONE;
2683 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2684 return DENY_DOS;
2685 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2686 return DENY_FCB;
2689 return (uint32)-1;
2692 pid_t procid_to_pid(const struct server_id *proc)
2694 return proc->pid;
2697 static uint32 my_vnn = NONCLUSTER_VNN;
2699 void set_my_vnn(uint32 vnn)
2701 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
2702 my_vnn = vnn;
2705 uint32 get_my_vnn(void)
2707 return my_vnn;
2710 struct server_id pid_to_procid(pid_t pid)
2712 struct server_id result;
2713 result.pid = pid;
2714 #ifdef CLUSTER_SUPPORT
2715 result.vnn = my_vnn;
2716 #endif
2717 return result;
2720 struct server_id procid_self(void)
2722 return pid_to_procid(sys_getpid());
2725 struct server_id server_id_self(void)
2727 return procid_self();
2730 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
2732 if (p1->pid != p2->pid)
2733 return False;
2734 #ifdef CLUSTER_SUPPORT
2735 if (p1->vnn != p2->vnn)
2736 return False;
2737 #endif
2738 return True;
2741 bool cluster_id_equal(const struct server_id *id1,
2742 const struct server_id *id2)
2744 return procid_equal(id1, id2);
2747 bool procid_is_me(const struct server_id *pid)
2749 if (pid->pid != sys_getpid())
2750 return False;
2751 #ifdef CLUSTER_SUPPORT
2752 if (pid->vnn != my_vnn)
2753 return False;
2754 #endif
2755 return True;
2758 struct server_id interpret_pid(const char *pid_string)
2760 #ifdef CLUSTER_SUPPORT
2761 unsigned int vnn, pid;
2762 struct server_id result;
2763 if (sscanf(pid_string, "%u:%u", &vnn, &pid) == 2) {
2764 result.vnn = vnn;
2765 result.pid = pid;
2767 else if (sscanf(pid_string, "%u", &pid) == 1) {
2768 result.vnn = get_my_vnn();
2769 result.pid = pid;
2771 else {
2772 result.vnn = NONCLUSTER_VNN;
2773 result.pid = -1;
2775 return result;
2776 #else
2777 return pid_to_procid(atoi(pid_string));
2778 #endif
2781 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
2783 #ifdef CLUSTER_SUPPORT
2784 if (pid->vnn == NONCLUSTER_VNN) {
2785 return talloc_asprintf(mem_ctx,
2786 "%d",
2787 (int)pid->pid);
2789 else {
2790 return talloc_asprintf(mem_ctx,
2791 "%u:%d",
2792 (unsigned)pid->vnn,
2793 (int)pid->pid);
2795 #else
2796 return talloc_asprintf(mem_ctx,
2797 "%d",
2798 (int)pid->pid);
2799 #endif
2802 char *procid_str_static(const struct server_id *pid)
2804 return procid_str(talloc_tos(), pid);
2807 bool procid_valid(const struct server_id *pid)
2809 return (pid->pid != -1);
2812 bool procid_is_local(const struct server_id *pid)
2814 #ifdef CLUSTER_SUPPORT
2815 return pid->vnn == my_vnn;
2816 #else
2817 return True;
2818 #endif
2821 int this_is_smp(void)
2823 #if defined(HAVE_SYSCONF)
2825 #if defined(SYSCONF_SC_NPROC_ONLN)
2826 return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
2827 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
2828 return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
2829 #else
2830 return 0;
2831 #endif
2833 #else
2834 return 0;
2835 #endif
2838 /****************************************************************
2839 Check if offset/length fit into bufsize. Should probably be
2840 merged with is_offset_safe, but this would require a rewrite
2841 of lanman.c. Later :-)
2842 ****************************************************************/
2844 bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
2846 if ((offset + length < offset) || (offset + length < length)) {
2847 /* wrap */
2848 return true;
2850 if ((offset > bufsize) || (offset + length > bufsize)) {
2851 /* overflow */
2852 return true;
2854 return false;
2857 /****************************************************************
2858 Check if an offset into a buffer is safe.
2859 If this returns True it's safe to indirect into the byte at
2860 pointer ptr+off.
2861 ****************************************************************/
2863 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2865 const char *end_base = buf_base + buf_len;
2866 char *end_ptr = ptr + off;
2868 if (!buf_base || !ptr) {
2869 return False;
2872 if (end_base < buf_base || end_ptr < ptr) {
2873 return False; /* wrap. */
2876 if (end_ptr < end_base) {
2877 return True;
2879 return False;
2882 /****************************************************************
2883 Return a safe pointer into a buffer, or NULL.
2884 ****************************************************************/
2886 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2888 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2889 ptr + off : NULL;
2892 /****************************************************************
2893 Return a safe pointer into a string within a buffer, or NULL.
2894 ****************************************************************/
2896 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2898 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2899 return NULL;
2901 /* Check if a valid string exists at this offset. */
2902 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2903 return NULL;
2905 return ptr + off;
2908 /****************************************************************
2909 Return an SVAL at a pointer, or failval if beyond the end.
2910 ****************************************************************/
2912 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2915 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2916 * NOT ptr[2].
2918 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2919 return failval;
2921 return SVAL(ptr,off);
2924 /****************************************************************
2925 Return an IVAL at a pointer, or failval if beyond the end.
2926 ****************************************************************/
2928 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2931 * Note we use off+3 here, not off+4 as IVAL accesses
2932 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2934 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2935 return failval;
2937 return IVAL(ptr,off);
2940 /****************************************************************
2941 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2942 call (they take care of winbind separator and other winbind specific settings).
2943 ****************************************************************/
2945 void split_domain_user(TALLOC_CTX *mem_ctx,
2946 const char *full_name,
2947 char **domain,
2948 char **user)
2950 const char *p = NULL;
2952 p = strchr_m(full_name, '\\');
2954 if (p != NULL) {
2955 *domain = talloc_strndup(mem_ctx, full_name,
2956 PTR_DIFF(p, full_name));
2957 *user = talloc_strdup(mem_ctx, p+1);
2958 } else {
2959 *domain = talloc_strdup(mem_ctx, "");
2960 *user = talloc_strdup(mem_ctx, full_name);
2964 #if 0
2966 Disable these now we have checked all code paths and ensured
2967 NULL returns on zero request. JRA.
2969 /****************************************************************
2970 talloc wrapper functions that guarentee a null pointer return
2971 if size == 0.
2972 ****************************************************************/
2974 #ifndef MAX_TALLOC_SIZE
2975 #define MAX_TALLOC_SIZE 0x10000000
2976 #endif
2979 * talloc and zero memory.
2980 * - returns NULL if size is zero.
2983 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
2985 void *p;
2987 if (size == 0) {
2988 return NULL;
2991 p = talloc_named_const(ctx, size, name);
2993 if (p) {
2994 memset(p, '\0', size);
2997 return p;
3001 * memdup with a talloc.
3002 * - returns NULL if size is zero.
3005 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
3007 void *newp;
3009 if (size == 0) {
3010 return NULL;
3013 newp = talloc_named_const(t, size, name);
3014 if (newp) {
3015 memcpy(newp, p, size);
3018 return newp;
3022 * alloc an array, checking for integer overflow in the array size.
3023 * - returns NULL if count or el_size are zero.
3026 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3028 if (count >= MAX_TALLOC_SIZE/el_size) {
3029 return NULL;
3032 if (el_size == 0 || count == 0) {
3033 return NULL;
3036 return talloc_named_const(ctx, el_size * count, name);
3040 * alloc an zero array, checking for integer overflow in the array size
3041 * - returns NULL if count or el_size are zero.
3044 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3046 if (count >= MAX_TALLOC_SIZE/el_size) {
3047 return NULL;
3050 if (el_size == 0 || count == 0) {
3051 return NULL;
3054 return _talloc_zero(ctx, el_size * count, name);
3058 * Talloc wrapper that returns NULL if size == 0.
3060 void *talloc_zeronull(const void *context, size_t size, const char *name)
3062 if (size == 0) {
3063 return NULL;
3065 return talloc_named_const(context, size, name);
3067 #endif
3069 /* Split a path name into filename and stream name components. Canonicalise
3070 * such that an implicit $DATA token is always explicit.
3072 * The "specification" of this function can be found in the
3073 * run_local_stream_name() function in torture.c, I've tried those
3074 * combinations against a W2k3 server.
3077 NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
3078 char **pbase, char **pstream)
3080 char *base = NULL;
3081 char *stream = NULL;
3082 char *sname; /* stream name */
3083 const char *stype; /* stream type */
3085 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
3087 sname = strchr_m(fname, ':');
3089 if (lp_posix_pathnames() || (sname == NULL)) {
3090 if (pbase != NULL) {
3091 base = talloc_strdup(mem_ctx, fname);
3092 NT_STATUS_HAVE_NO_MEMORY(base);
3094 goto done;
3097 if (pbase != NULL) {
3098 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
3099 NT_STATUS_HAVE_NO_MEMORY(base);
3102 sname += 1;
3104 stype = strchr_m(sname, ':');
3106 if (stype == NULL) {
3107 sname = talloc_strdup(mem_ctx, sname);
3108 stype = "$DATA";
3110 else {
3111 if (StrCaseCmp(stype, ":$DATA") != 0) {
3113 * If there is an explicit stream type, so far we only
3114 * allow $DATA. Is there anything else allowed? -- vl
3116 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
3117 TALLOC_FREE(base);
3118 return NT_STATUS_OBJECT_NAME_INVALID;
3120 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
3121 stype += 1;
3124 if (sname == NULL) {
3125 TALLOC_FREE(base);
3126 return NT_STATUS_NO_MEMORY;
3129 if (sname[0] == '\0') {
3131 * no stream name, so no stream
3133 goto done;
3136 if (pstream != NULL) {
3137 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
3138 if (stream == NULL) {
3139 TALLOC_FREE(sname);
3140 TALLOC_FREE(base);
3141 return NT_STATUS_NO_MEMORY;
3144 * upper-case the type field
3146 strupper_m(strchr_m(stream, ':')+1);
3149 done:
3150 if (pbase != NULL) {
3151 *pbase = base;
3153 if (pstream != NULL) {
3154 *pstream = stream;
3156 return NT_STATUS_OK;
3159 bool is_valid_policy_hnd(const POLICY_HND *hnd)
3161 POLICY_HND tmp;
3162 ZERO_STRUCT(tmp);
3163 return (memcmp(&tmp, hnd, sizeof(tmp)) != 0);
3166 bool policy_hnd_equal(const struct policy_handle *hnd1,
3167 const struct policy_handle *hnd2)
3169 if (!hnd1 || !hnd2) {
3170 return false;
3173 return (memcmp(hnd1, hnd2, sizeof(*hnd1)) == 0);
3176 /****************************************************************
3177 strip off leading '\\' from a hostname
3178 ****************************************************************/
3180 const char *strip_hostname(const char *s)
3182 if (!s) {
3183 return NULL;
3186 if (strlen_m(s) < 3) {
3187 return s;
3190 if (s[0] == '\\') s++;
3191 if (s[0] == '\\') s++;
3193 return s;