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/>.
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.
47 #if defined(GROUP_OBJ)
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 */
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
);
85 strupper_m(smb_myname
);
89 const char *global_myname(void)
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
)
104 strupper_m(smb_myworkgroup
);
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
);
123 strupper_m(smb_scope
);
127 /*********************************************************************
128 Ensure scope is never null string.
129 *********************************************************************/
131 const char *global_scope(void)
134 set_global_scope("");
138 static void free_netbios_names_array(void)
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
)
159 memset(smb_my_netbios_names
, '\0', sizeof(char *) * smb_num_netbios_names
);
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
])
170 strupper_m(smb_my_netbios_names
[i
]);
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 )
197 const char *my_netbios_names(int i
)
199 return smb_my_netbios_names
[i
];
202 bool set_netbios_aliases(const char **str_array
)
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())
213 /* Allocate space for the netbios aliases */
214 if (!allocate_my_netbios_names_array(namecount
))
217 /* Use the global_myname string first */
219 if ( global_myname() && *global_myname()) {
220 set_my_netbios_names( global_myname(), namecount
);
226 for ( i
= 0; str_array
[i
] != NULL
; i
++) {
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
) ) ) {
238 if (!set_my_netbios_names(str_array
[i
], namecount
))
247 /****************************************************************************
248 Common name initialization code.
249 ****************************************************************************/
251 bool init_names(void)
255 if (global_myname() == NULL
|| *global_myname() == '\0') {
256 if (!set_global_myname(myhostname())) {
257 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
262 if (!set_netbios_aliases(lp_netbios_aliases())) {
263 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
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
) ) );
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
) {
292 result
->signing_state
= Undefined
;
296 const char *get_cmdline_auth_info_username(struct user_auth_info
*auth_info
)
298 if (!auth_info
->username
) {
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
) {
314 const char *get_cmdline_auth_info_password(struct user_auth_info
*auth_info
)
316 if (!auth_info
->password
) {
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
) {
330 auth_info
->got_pass
= true;
333 bool set_cmdline_auth_info_signing_state(struct user_auth_info
*auth_info
,
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
;
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
,
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
) {
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
)) {
425 bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info
*auth_info
)
428 char *account
= NULL
;
430 if (!get_cmdline_auth_info_use_machine_account(auth_info
)) {
434 if (!secrets_init()) {
435 d_printf("ERROR: Unable to open secrets database\n");
439 if (asprintf(&account
, "%s$@%s", global_myname(), lp_realm()) < 0) {
443 pass
= secrets_fetch_machine_password(lp_workgroup(), NULL
, NULL
);
445 d_printf("ERROR: Unable to fetch machine password for "
447 account
, lp_workgroup());
452 set_cmdline_auth_info_username(auth_info
, account
);
453 set_cmdline_auth_info_password(auth_info
, pass
);
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
)
470 if ((*num_gids
!= 0) && (*gids
== NULL
)) {
472 * A former call to this routine has failed to allocate memory
477 for (i
=0; i
<*num_gids
; i
++) {
478 if ((*gids
)[i
] == gid
) {
483 *gids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *gids
, gid_t
, *num_gids
+1);
489 (*gids
)[*num_gids
] = gid
;
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
)
504 if (sys_stat(fname
,sbuf
) != 0)
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
)
517 if (sys_stat(fname
,&st
) != 0)
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
)
535 if (sys_stat(dname
,st
) != 0)
538 ret
= S_ISDIR(st
->st_mode
);
544 /*******************************************************************
545 Returns the size in bytes of the named given the stat struct.
546 ********************************************************************/
548 uint64_t get_file_size_stat(const SMB_STRUCT_STAT
*sbuf
)
550 return sbuf
->st_size
;
553 /*******************************************************************
554 Returns the size in bytes of the named file.
555 ********************************************************************/
557 SMB_OFF_T
get_file_size(char *file_name
)
561 if(sys_stat(file_name
,&buf
) != 0)
562 return (SMB_OFF_T
)-1;
563 return get_file_size_stat(&buf
);
566 /*******************************************************************
567 Return a string representing an attribute for a file.
568 ********************************************************************/
570 char *attrib_string(uint16 mode
)
576 if (mode
& aVOLID
) fstrcat(attrstr
,"V");
577 if (mode
& aDIR
) fstrcat(attrstr
,"D");
578 if (mode
& aARCH
) fstrcat(attrstr
,"A");
579 if (mode
& aHIDDEN
) fstrcat(attrstr
,"H");
580 if (mode
& aSYSTEM
) fstrcat(attrstr
,"S");
581 if (mode
& aRONLY
) fstrcat(attrstr
,"R");
583 return talloc_strdup(talloc_tos(), attrstr
);
586 /*******************************************************************
587 Show a smb message structure.
588 ********************************************************************/
590 void show_msg(char *buf
)
598 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
600 (int)CVAL(buf
,smb_com
),
601 (int)CVAL(buf
,smb_rcls
),
602 (int)CVAL(buf
,smb_reh
),
603 (int)SVAL(buf
,smb_err
),
604 (int)CVAL(buf
,smb_flg
),
605 (int)SVAL(buf
,smb_flg2
)));
606 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
607 (int)SVAL(buf
,smb_tid
),
608 (int)SVAL(buf
,smb_pid
),
609 (int)SVAL(buf
,smb_uid
),
610 (int)SVAL(buf
,smb_mid
)));
611 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf
,smb_wct
)));
613 for (i
=0;i
<(int)CVAL(buf
,smb_wct
);i
++)
614 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i
,
615 SVAL(buf
,smb_vwv
+2*i
),SVAL(buf
,smb_vwv
+2*i
)));
617 bcc
= (int)SVAL(buf
,smb_vwv
+2*(CVAL(buf
,smb_wct
)));
619 DEBUGADD(5,("smb_bcc=%d\n",bcc
));
627 dump_data(10, (uint8
*)smb_buf(buf
), bcc
);
630 /*******************************************************************
631 Set the length and marker of an encrypted smb packet.
632 ********************************************************************/
634 void smb_set_enclen(char *buf
,int len
,uint16 enc_ctx_num
)
636 _smb_setlen(buf
,len
);
640 SSVAL(buf
,6,enc_ctx_num
);
643 /*******************************************************************
644 Set the length and marker of an smb packet.
645 ********************************************************************/
647 void smb_setlen(char *buf
,int len
)
649 _smb_setlen(buf
,len
);
657 /*******************************************************************
658 Setup only the byte count for a smb message.
659 ********************************************************************/
661 int set_message_bcc(char *buf
,int num_bytes
)
663 int num_words
= CVAL(buf
,smb_wct
);
664 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
665 _smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
666 return (smb_size
+ num_words
*2 + num_bytes
);
669 /*******************************************************************
670 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
671 Return the bytes added
672 ********************************************************************/
674 ssize_t
message_push_blob(uint8
**outbuf
, DATA_BLOB blob
)
676 size_t newlen
= smb_len(*outbuf
) + 4 + blob
.length
;
679 if (!(tmp
= TALLOC_REALLOC_ARRAY(NULL
, *outbuf
, uint8
, newlen
))) {
680 DEBUG(0, ("talloc failed\n"));
685 memcpy(tmp
+ smb_len(tmp
) + 4, blob
.data
, blob
.length
);
686 set_message_bcc((char *)tmp
, smb_buflen(tmp
) + blob
.length
);
690 /*******************************************************************
691 Reduce a file name, removing .. elements.
692 ********************************************************************/
694 static char *dos_clean_name(TALLOC_CTX
*ctx
, const char *s
)
699 DEBUG(3,("dos_clean_name [%s]\n",s
));
701 /* remove any double slashes */
702 str
= talloc_all_string_sub(ctx
, s
, "\\\\", "\\");
707 /* Remove leading .\\ characters */
708 if(strncmp(str
, ".\\", 2) == 0) {
709 trim_string(str
, ".\\", NULL
);
711 str
= talloc_strdup(ctx
, ".\\");
718 while ((p
= strstr_m(str
,"\\..\\")) != NULL
) {
724 if ((p
=strrchr_m(str
,'\\')) != NULL
) {
729 str
= talloc_asprintf(ctx
,
738 trim_string(str
,NULL
,"\\..");
739 return talloc_all_string_sub(ctx
, str
, "\\.\\", "\\");
742 /*******************************************************************
743 Reduce a file name, removing .. elements.
744 ********************************************************************/
746 char *unix_clean_name(TALLOC_CTX
*ctx
, const char *s
)
751 DEBUG(3,("unix_clean_name [%s]\n",s
));
753 /* remove any double slashes */
754 str
= talloc_all_string_sub(ctx
, s
, "//","/");
759 /* Remove leading ./ characters */
760 if(strncmp(str
, "./", 2) == 0) {
761 trim_string(str
, "./", NULL
);
763 str
= talloc_strdup(ctx
, "./");
770 while ((p
= strstr_m(str
,"/../")) != NULL
) {
776 if ((p
=strrchr_m(str
,'/')) != NULL
) {
781 str
= talloc_asprintf(ctx
,
790 trim_string(str
,NULL
,"/..");
791 return talloc_all_string_sub(ctx
, str
, "/./", "/");
794 char *clean_name(TALLOC_CTX
*ctx
, const char *s
)
796 char *str
= dos_clean_name(ctx
, s
);
800 return unix_clean_name(ctx
, str
);
803 /*******************************************************************
804 Close the low 3 fd's and open dev/null in their place.
805 ********************************************************************/
807 void close_low_fds(bool stderr_too
)
819 /* try and use up these file descriptors, so silly
820 library routines writing to stdout etc won't cause havoc */
822 if (i
== 2 && !stderr_too
)
825 fd
= sys_open("/dev/null",O_RDWR
,0);
827 fd
= sys_open("/dev/null",O_WRONLY
,0);
829 DEBUG(0,("Can't open /dev/null\n"));
833 DEBUG(0,("Didn't get file descriptor %d\n",i
));
840 /*******************************************************************
841 Write data into an fd at a given offset. Ignore seek errors.
842 ********************************************************************/
844 ssize_t
write_data_at_offset(int fd
, const char *buffer
, size_t N
, SMB_OFF_T pos
)
849 if (pos
== (SMB_OFF_T
)-1) {
850 return write_data(fd
, buffer
, N
);
852 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
854 ret
= sys_pwrite(fd
,buffer
+ total
,N
- total
, pos
);
855 if (ret
== -1 && errno
== ESPIPE
) {
856 return write_data(fd
, buffer
+ total
,N
- total
);
859 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno
) ));
868 return (ssize_t
)total
;
870 /* Use lseek and write_data. */
871 if (sys_lseek(fd
, pos
, SEEK_SET
) == -1) {
872 if (errno
!= ESPIPE
) {
876 return write_data(fd
, buffer
, N
);
880 /*******************************************************************
881 Sleep for a specified number of milliseconds.
882 ********************************************************************/
884 void smb_msleep(unsigned int t
)
886 #if defined(HAVE_NANOSLEEP)
887 struct timespec tval
;
890 tval
.tv_sec
= t
/1000;
891 tval
.tv_nsec
= 1000000*(t
%1000);
895 ret
= nanosleep(&tval
, &tval
);
896 } while (ret
< 0 && errno
== EINTR
&& (tval
.tv_sec
> 0 || tval
.tv_nsec
> 0));
898 unsigned int tdiff
=0;
899 struct timeval tval
,t1
,t2
;
906 tval
.tv_sec
= (t
-tdiff
)/1000;
907 tval
.tv_usec
= 1000*((t
-tdiff
)%1000);
909 /* Never wait for more than 1 sec. */
910 if (tval
.tv_sec
> 1) {
917 sys_select_intr(0,&fds
,NULL
,NULL
,&tval
);
920 if (t2
.tv_sec
< t1
.tv_sec
) {
921 /* Someone adjusted time... */
925 tdiff
= TvalDiff(&t1
,&t2
);
930 /****************************************************************************
931 Become a daemon, discarding the controlling terminal.
932 ****************************************************************************/
934 void become_daemon(bool Fork
, bool no_process_group
)
942 /* detach from the terminal */
944 if (!no_process_group
) setsid();
945 #elif defined(TIOCNOTTY)
946 if (!no_process_group
) {
947 int i
= sys_open("/dev/tty", O_RDWR
, 0);
949 ioctl(i
, (int) TIOCNOTTY
, (char *)0);
953 #endif /* HAVE_SETSID */
955 /* Close fd's 0,1,2. Needed if started by rsh */
956 close_low_fds(False
); /* Don't close stderr, let the debug system
957 attach it to the logfile */
960 bool reinit_after_fork(struct messaging_context
*msg_ctx
,
961 struct event_context
*ev_ctx
,
962 bool parent_longlived
)
966 /* Reset the state of the random
967 * number generation system, so
968 * children do not get the same random
969 * numbers as each other */
970 set_need_random_reseed();
972 /* tdb needs special fork handling */
973 if (tdb_reopen_all(parent_longlived
? 1 : 0) == -1) {
974 DEBUG(0,("tdb_reopen_all failed.\n"));
979 event_context_reinit(ev_ctx
);
984 * For clustering, we need to re-init our ctdbd connection after the
987 status
= messaging_reinit(msg_ctx
);
988 if (!NT_STATUS_IS_OK(status
)) {
989 DEBUG(0,("messaging_reinit() failed: %s\n",
998 /****************************************************************************
999 Put up a yes/no prompt.
1000 ****************************************************************************/
1002 bool yesno(const char *p
)
1007 if (!fgets(ans
,sizeof(ans
)-1,stdin
))
1010 if (*ans
== 'y' || *ans
== 'Y')
1016 #if defined(PARANOID_MALLOC_CHECKER)
1018 /****************************************************************************
1019 Internal malloc wrapper. Externally visible.
1020 ****************************************************************************/
1022 void *malloc_(size_t size
)
1028 return malloc(size
);
1029 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
1032 /****************************************************************************
1033 Internal calloc wrapper. Not externally visible.
1034 ****************************************************************************/
1036 static void *calloc_(size_t count
, size_t size
)
1038 if (size
== 0 || count
== 0) {
1042 return calloc(count
, size
);
1043 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
1046 /****************************************************************************
1047 Internal realloc wrapper. Not externally visible.
1048 ****************************************************************************/
1050 static void *realloc_(void *ptr
, size_t size
)
1053 return realloc(ptr
, size
);
1054 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
1057 #endif /* PARANOID_MALLOC_CHECKER */
1059 /****************************************************************************
1061 ****************************************************************************/
1063 void *memalign_array(size_t el_size
, size_t align
, unsigned int count
)
1065 if (count
>= MAX_ALLOC_SIZE
/el_size
) {
1069 return sys_memalign(align
, el_size
*count
);
1072 /****************************************************************************
1074 ****************************************************************************/
1076 void *calloc_array(size_t size
, size_t nmemb
)
1078 if (nmemb
>= MAX_ALLOC_SIZE
/size
) {
1081 if (size
== 0 || nmemb
== 0) {
1084 #if defined(PARANOID_MALLOC_CHECKER)
1085 return calloc_(nmemb
, size
);
1087 return calloc(nmemb
, size
);
1091 /****************************************************************************
1092 Expand a pointer to be a particular size.
1093 Note that this version of Realloc has an extra parameter that decides
1094 whether to free the passed in storage on allocation failure or if the
1097 This is designed for use in the typical idiom of :
1099 p = SMB_REALLOC(p, size)
1104 and not to have to keep track of the old 'p' contents to free later, nor
1105 to worry if the size parameter was zero. In the case where NULL is returned
1106 we guarentee that p has been freed.
1108 If free later semantics are desired, then pass 'free_old_on_error' as False which
1109 guarentees that the old contents are not freed on error, even if size == 0. To use
1112 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
1120 Changes were instigated by Coverity error checking. JRA.
1121 ****************************************************************************/
1123 void *Realloc(void *p
, size_t size
, bool free_old_on_error
)
1128 if (free_old_on_error
) {
1131 DEBUG(2,("Realloc asked for 0 bytes\n"));
1135 #if defined(PARANOID_MALLOC_CHECKER)
1137 ret
= (void *)malloc_(size
);
1139 ret
= (void *)realloc_(p
,size
);
1143 ret
= (void *)malloc(size
);
1145 ret
= (void *)realloc(p
,size
);
1150 if (free_old_on_error
&& p
) {
1153 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size
));
1159 /****************************************************************************
1160 (Hopefully) efficient array append.
1161 ****************************************************************************/
1163 void add_to_large_array(TALLOC_CTX
*mem_ctx
, size_t element_size
,
1164 void *element
, void *_array
, uint32
*num_elements
,
1165 ssize_t
*array_size
)
1167 void **array
= (void **)_array
;
1169 if (*array_size
< 0) {
1173 if (*array
== NULL
) {
1174 if (*array_size
== 0) {
1178 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
1182 *array
= TALLOC(mem_ctx
, element_size
* (*array_size
));
1183 if (*array
== NULL
) {
1188 if (*num_elements
== *array_size
) {
1191 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
1195 *array
= TALLOC_REALLOC(mem_ctx
, *array
,
1196 element_size
* (*array_size
));
1198 if (*array
== NULL
) {
1203 memcpy((char *)(*array
) + element_size
*(*num_elements
),
1204 element
, element_size
);
1214 /****************************************************************************
1215 Get my own name and IP.
1216 ****************************************************************************/
1218 char *talloc_get_myname(TALLOC_CTX
*ctx
)
1221 char hostname
[HOST_NAME_MAX
];
1225 /* get my host name */
1226 if (gethostname(hostname
, sizeof(hostname
)) == -1) {
1227 DEBUG(0,("gethostname failed\n"));
1231 /* Ensure null termination. */
1232 hostname
[sizeof(hostname
)-1] = '\0';
1234 /* split off any parts after an initial . */
1235 p
= strchr_m(hostname
,'.');
1240 return talloc_strdup(ctx
, hostname
);
1243 /****************************************************************************
1244 Get my own domain name, or "" if we have none.
1245 ****************************************************************************/
1247 char *get_mydnsdomname(TALLOC_CTX
*ctx
)
1249 const char *domname
;
1252 domname
= get_mydnsfullname();
1257 p
= strchr_m(domname
, '.');
1260 return talloc_strdup(ctx
, p
);
1262 return talloc_strdup(ctx
, "");
1266 /****************************************************************************
1267 Interpret a protocol description string, with a default.
1268 ****************************************************************************/
1270 int interpret_protocol(const char *str
,int def
)
1272 if (strequal(str
,"NT1"))
1273 return(PROTOCOL_NT1
);
1274 if (strequal(str
,"LANMAN2"))
1275 return(PROTOCOL_LANMAN2
);
1276 if (strequal(str
,"LANMAN1"))
1277 return(PROTOCOL_LANMAN1
);
1278 if (strequal(str
,"CORE"))
1279 return(PROTOCOL_CORE
);
1280 if (strequal(str
,"COREPLUS"))
1281 return(PROTOCOL_COREPLUS
);
1282 if (strequal(str
,"CORE+"))
1283 return(PROTOCOL_COREPLUS
);
1285 DEBUG(0,("Unrecognised protocol level %s\n",str
));
1291 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1292 /******************************************************************
1293 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1294 Based on a fix from <Thomas.Hepper@icem.de>.
1295 Returns a malloc'ed string.
1296 *******************************************************************/
1298 static char *strip_mount_options(TALLOC_CTX
*ctx
, const char *str
)
1301 const char *p
= str
;
1302 while(*p
&& !isspace(*p
))
1304 while(*p
&& isspace(*p
))
1307 return talloc_strdup(ctx
, p
);
1313 /*******************************************************************
1314 Patch from jkf@soton.ac.uk
1315 Split Luke's automount_server into YP lookup and string splitter
1316 so can easily implement automount_path().
1317 Returns a malloc'ed string.
1318 *******************************************************************/
1320 #ifdef WITH_NISPLUS_HOME
1321 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
1325 char *nis_map
= (char *)lp_nis_home_map_name();
1327 char buffer
[NIS_MAXATTRVAL
+ 1];
1332 snprintf(buffer
, sizeof(buffer
), "[key=%s],%s", user_name
, nis_map
);
1333 DEBUG(5, ("NIS+ querystring: %s\n", buffer
));
1335 if (result
= nis_list(buffer
, FOLLOW_PATH
|EXPAND_NAME
|HARD_LOOKUP
, NULL
, NULL
)) {
1336 if (result
->status
!= NIS_SUCCESS
) {
1337 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result
->status
)));
1339 object
= result
->objects
.objects_val
;
1340 if (object
->zo_data
.zo_type
== ENTRY_OBJ
) {
1341 entry
= &object
->zo_data
.objdata_u
.en_data
;
1342 DEBUG(5, ("NIS+ entry type: %s\n", entry
->en_type
));
1343 DEBUG(3, ("NIS+ result: %s\n", entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
));
1345 value
= talloc_strdup(ctx
,
1346 entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
);
1348 nis_freeresult(result
);
1351 value
= talloc_string_sub(ctx
,
1358 nis_freeresult(result
);
1361 value
= strip_mount_options(ctx
, value
);
1362 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
1367 #else /* WITH_NISPLUS_HOME */
1369 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
1373 int nis_error
; /* returned by yp all functions */
1374 char *nis_result
; /* yp_match inits this */
1375 int nis_result_len
; /* and set this */
1376 char *nis_domain
; /* yp_get_default_domain inits this */
1377 char *nis_map
= (char *)lp_nis_home_map_name();
1379 if ((nis_error
= yp_get_default_domain(&nis_domain
)) != 0) {
1380 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error
)));
1384 DEBUG(5, ("NIS Domain: %s\n", nis_domain
));
1386 if ((nis_error
= yp_match(nis_domain
, nis_map
, user_name
,
1387 strlen(user_name
), &nis_result
,
1388 &nis_result_len
)) == 0) {
1389 value
= talloc_strdup(ctx
, nis_result
);
1393 value
= strip_mount_options(ctx
, value
);
1394 } else if(nis_error
== YPERR_KEY
) {
1395 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1396 user_name
, nis_map
));
1397 DEBUG(3, ("using defaults for server and home directory\n"));
1399 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1400 yperr_string(nis_error
), user_name
, nis_map
));
1404 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name
, value
));
1408 #endif /* WITH_NISPLUS_HOME */
1411 /****************************************************************************
1412 Check if a process exists. Does this work on all unixes?
1413 ****************************************************************************/
1415 bool process_exists(const struct server_id pid
)
1417 if (procid_is_me(&pid
)) {
1421 if (procid_is_local(&pid
)) {
1422 return (kill(pid
.pid
,0) == 0 || errno
!= ESRCH
);
1425 #ifdef CLUSTER_SUPPORT
1426 return ctdbd_process_exists(messaging_ctdbd_connection(), pid
.vnn
,
1433 /*******************************************************************
1434 Convert a uid into a user name.
1435 ********************************************************************/
1437 const char *uidtoname(uid_t uid
)
1439 TALLOC_CTX
*ctx
= talloc_tos();
1441 struct passwd
*pass
= NULL
;
1443 pass
= getpwuid_alloc(ctx
,uid
);
1445 name
= talloc_strdup(ctx
,pass
->pw_name
);
1448 name
= talloc_asprintf(ctx
,
1455 /*******************************************************************
1456 Convert a gid into a group name.
1457 ********************************************************************/
1459 char *gidtoname(gid_t gid
)
1463 grp
= getgrgid(gid
);
1465 return talloc_strdup(talloc_tos(), grp
->gr_name
);
1468 return talloc_asprintf(talloc_tos(),
1474 /*******************************************************************
1475 Convert a user name into a uid.
1476 ********************************************************************/
1478 uid_t
nametouid(const char *name
)
1480 struct passwd
*pass
;
1484 pass
= getpwnam_alloc(talloc_autofree_context(), name
);
1491 u
= (uid_t
)strtol(name
, &p
, 0);
1492 if ((p
!= name
) && (*p
== '\0'))
1498 /*******************************************************************
1499 Convert a name to a gid_t if possible. Return -1 if not a group.
1500 ********************************************************************/
1502 gid_t
nametogid(const char *name
)
1508 g
= (gid_t
)strtol(name
, &p
, 0);
1509 if ((p
!= name
) && (*p
== '\0'))
1512 grp
= sys_getgrnam(name
);
1514 return(grp
->gr_gid
);
1518 /*******************************************************************
1519 Something really nasty happened - panic !
1520 ********************************************************************/
1522 void smb_panic(const char *const why
)
1530 if (global_clobber_region_function
) {
1531 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1532 global_clobber_region_function
,
1533 global_clobber_region_line
));
1538 DEBUG(0,("PANIC (pid %llu): %s\n",
1539 (unsigned long long)sys_getpid(), why
));
1542 cmd
= lp_panic_action();
1544 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd
));
1545 result
= system(cmd
);
1548 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1551 DEBUG(0, ("smb_panic(): action returned status %d\n",
1552 WEXITSTATUS(result
)));
1558 /*******************************************************************
1559 Print a backtrace of the stack to the debug log. This function
1560 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1561 exit shortly after calling it.
1562 ********************************************************************/
1564 #ifdef HAVE_LIBUNWIND_H
1565 #include <libunwind.h>
1568 #ifdef HAVE_EXECINFO_H
1569 #include <execinfo.h>
1572 #ifdef HAVE_LIBEXC_H
1576 void log_stack_trace(void)
1578 #ifdef HAVE_LIBUNWIND
1579 /* Try to use libunwind before any other technique since on ia64
1580 * libunwind correctly walks the stack in more circumstances than
1583 unw_cursor_t cursor
;
1588 unw_word_t ip
, sp
, off
;
1590 procname
[sizeof(procname
) - 1] = '\0';
1592 if (unw_getcontext(&uc
) != 0) {
1593 goto libunwind_failed
;
1596 if (unw_init_local(&cursor
, &uc
) != 0) {
1597 goto libunwind_failed
;
1600 DEBUG(0, ("BACKTRACE:\n"));
1604 unw_get_reg(&cursor
, UNW_REG_IP
, &ip
);
1605 unw_get_reg(&cursor
, UNW_REG_SP
, &sp
);
1607 switch (unw_get_proc_name(&cursor
,
1608 procname
, sizeof(procname
) - 1, &off
) ) {
1612 /* Name truncated. */
1613 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1614 i
, procname
, (long long)off
,
1615 (long long)ip
, (long long) sp
));
1618 /* case -UNW_ENOINFO: */
1619 /* case -UNW_EUNSPEC: */
1620 /* No symbol name found. */
1621 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1622 i
, "<unknown symbol>",
1623 (long long)ip
, (long long) sp
));
1626 } while (unw_step(&cursor
) > 0);
1631 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1633 #elif HAVE_BACKTRACE_SYMBOLS
1634 void *backtrace_stack
[BACKTRACE_STACK_SIZE
];
1635 size_t backtrace_size
;
1636 char **backtrace_strings
;
1638 /* get the backtrace (stack frames) */
1639 backtrace_size
= backtrace(backtrace_stack
,BACKTRACE_STACK_SIZE
);
1640 backtrace_strings
= backtrace_symbols(backtrace_stack
, backtrace_size
);
1642 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1643 (unsigned long)backtrace_size
));
1645 if (backtrace_strings
) {
1648 for (i
= 0; i
< backtrace_size
; i
++)
1649 DEBUGADD(0, (" #%u %s\n", i
, backtrace_strings
[i
]));
1651 /* Leak the backtrace_strings, rather than risk what free() might do */
1656 /* The IRIX libexc library provides an API for unwinding the stack. See
1657 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1658 * since we are about to abort anyway, it hardly matters.
1661 #define NAMESIZE 32 /* Arbitrary */
1663 __uint64_t addrs
[BACKTRACE_STACK_SIZE
];
1664 char * names
[BACKTRACE_STACK_SIZE
];
1665 char namebuf
[BACKTRACE_STACK_SIZE
* NAMESIZE
];
1672 ZERO_ARRAY(namebuf
);
1674 /* We need to be root so we can open our /proc entry to walk
1675 * our stack. It also helps when we want to dump core.
1679 for (i
= 0; i
< BACKTRACE_STACK_SIZE
; i
++) {
1680 names
[i
] = namebuf
+ (i
* NAMESIZE
);
1683 levels
= trace_back_stack(0, addrs
, names
,
1684 BACKTRACE_STACK_SIZE
, NAMESIZE
- 1);
1686 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels
));
1687 for (i
= 0; i
< levels
; i
++) {
1688 DEBUGADD(0, (" #%d 0x%llx %s\n", i
, addrs
[i
], names
[i
]));
1693 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1697 /*******************************************************************
1698 A readdir wrapper which just returns the file name.
1699 ********************************************************************/
1701 const char *readdirname(SMB_STRUCT_DIR
*p
)
1703 SMB_STRUCT_DIRENT
*ptr
;
1709 ptr
= (SMB_STRUCT_DIRENT
*)sys_readdir(p
);
1713 dname
= ptr
->d_name
;
1720 #ifdef HAVE_BROKEN_READDIR_NAME
1721 /* using /usr/ucb/cc is BAD */
1725 return talloc_strdup(talloc_tos(), dname
);
1728 /*******************************************************************
1729 Utility function used to decide if the last component
1730 of a path matches a (possibly wildcarded) entry in a namelist.
1731 ********************************************************************/
1733 bool is_in_path(const char *name
, name_compare_entry
*namelist
, bool case_sensitive
)
1735 const char *last_component
;
1737 /* if we have no list it's obviously not in the path */
1738 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
))) {
1742 DEBUG(8, ("is_in_path: %s\n", name
));
1744 /* Get the last component of the unix name. */
1745 last_component
= strrchr_m(name
, '/');
1746 if (!last_component
) {
1747 last_component
= name
;
1749 last_component
++; /* Go past '/' */
1752 for(; namelist
->name
!= NULL
; namelist
++) {
1753 if(namelist
->is_wild
) {
1754 if (mask_match(last_component
, namelist
->name
, case_sensitive
)) {
1755 DEBUG(8,("is_in_path: mask match succeeded\n"));
1759 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
1760 (!case_sensitive
&& (StrCaseCmp(last_component
, namelist
->name
) == 0))) {
1761 DEBUG(8,("is_in_path: match succeeded\n"));
1766 DEBUG(8,("is_in_path: match not found\n"));
1770 /*******************************************************************
1771 Strip a '/' separated list into an array of
1772 name_compare_enties structures suitable for
1773 passing to is_in_path(). We do this for
1774 speed so we can pre-parse all the names in the list
1775 and don't do it for each call to is_in_path().
1776 namelist is modified here and is assumed to be
1777 a copy owned by the caller.
1778 We also check if the entry contains a wildcard to
1779 remove a potentially expensive call to mask_match
1781 ********************************************************************/
1783 void set_namearray(name_compare_entry
**ppname_array
, const char *namelist
)
1786 const char *nameptr
= namelist
;
1787 int num_entries
= 0;
1790 (*ppname_array
) = NULL
;
1792 if((nameptr
== NULL
) || ((nameptr
!= NULL
) && (*nameptr
== '\0')))
1795 /* We need to make two passes over the string. The
1796 first to count the number of elements, the second
1801 if ( *nameptr
== '/' ) {
1802 /* cope with multiple (useless) /s) */
1806 /* find the next / */
1807 name_end
= strchr_m(nameptr
, '/');
1809 /* oops - the last check for a / didn't find one. */
1810 if (name_end
== NULL
)
1813 /* next segment please */
1814 nameptr
= name_end
+ 1;
1818 if(num_entries
== 0)
1821 if(( (*ppname_array
) = SMB_MALLOC_ARRAY(name_compare_entry
, num_entries
+ 1)) == NULL
) {
1822 DEBUG(0,("set_namearray: malloc fail\n"));
1826 /* Now copy out the names */
1830 if ( *nameptr
== '/' ) {
1831 /* cope with multiple (useless) /s) */
1835 /* find the next / */
1836 if ((name_end
= strchr_m(nameptr
, '/')) != NULL
)
1839 /* oops - the last check for a / didn't find one. */
1840 if(name_end
== NULL
)
1843 (*ppname_array
)[i
].is_wild
= ms_has_wild(nameptr
);
1844 if(((*ppname_array
)[i
].name
= SMB_STRDUP(nameptr
)) == NULL
) {
1845 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1849 /* next segment please */
1850 nameptr
= name_end
+ 1;
1854 (*ppname_array
)[i
].name
= NULL
;
1859 /****************************************************************************
1860 Routine to free a namearray.
1861 ****************************************************************************/
1863 void free_namearray(name_compare_entry
*name_array
)
1867 if(name_array
== NULL
)
1870 for(i
=0; name_array
[i
].name
!=NULL
; i
++)
1871 SAFE_FREE(name_array
[i
].name
);
1872 SAFE_FREE(name_array
);
1876 #define DBGC_CLASS DBGC_LOCKING
1878 /****************************************************************************
1879 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1880 is dealt with in posix.c
1881 Returns True if we have information regarding this lock region (and returns
1882 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1883 ****************************************************************************/
1885 bool fcntl_getlock(int fd
, SMB_OFF_T
*poffset
, SMB_OFF_T
*pcount
, int *ptype
, pid_t
*ppid
)
1887 SMB_STRUCT_FLOCK lock
;
1890 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1891 fd
,(double)*poffset
,(double)*pcount
,*ptype
));
1893 lock
.l_type
= *ptype
;
1894 lock
.l_whence
= SEEK_SET
;
1895 lock
.l_start
= *poffset
;
1896 lock
.l_len
= *pcount
;
1899 ret
= sys_fcntl_ptr(fd
,SMB_F_GETLK
,&lock
);
1903 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1904 (double)*poffset
,(double)*pcount
,*ptype
,strerror(errno
)));
1909 *ptype
= lock
.l_type
;
1910 *poffset
= lock
.l_start
;
1911 *pcount
= lock
.l_len
;
1914 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1915 fd
, (int)lock
.l_type
, (unsigned int)lock
.l_pid
));
1920 #define DBGC_CLASS DBGC_ALL
1922 /*******************************************************************
1923 Is the name specified one of my netbios names.
1924 Returns true if it is equal, false otherwise.
1925 ********************************************************************/
1927 bool is_myname(const char *s
)
1932 for (n
=0; my_netbios_names(n
); n
++) {
1933 if (strequal(my_netbios_names(n
), s
)) {
1938 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));
1942 /*******************************************************************
1943 Is the name specified our workgroup/domain.
1944 Returns true if it is equal, false otherwise.
1945 ********************************************************************/
1947 bool is_myworkgroup(const char *s
)
1951 if (strequal(s
, lp_workgroup())) {
1955 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s
, ret
));
1959 /*******************************************************************
1960 we distinguish between 2K and XP by the "Native Lan Manager" string
1961 WinXP => "Windows 2002 5.1"
1962 WinXP 64bit => "Windows XP 5.2"
1963 Win2k => "Windows 2000 5.0"
1964 NT4 => "Windows NT 4.0"
1965 Win9x => "Windows 4.0"
1966 Windows 2003 doesn't set the native lan manager string but
1967 they do set the domain to "Windows 2003 5.2" (probably a bug).
1968 ********************************************************************/
1970 void ra_lanman_string( const char *native_lanman
)
1972 if ( strcmp( native_lanman
, "Windows 2002 5.1" ) == 0 )
1973 set_remote_arch( RA_WINXP
);
1974 else if ( strcmp( native_lanman
, "Windows XP 5.2" ) == 0 )
1975 set_remote_arch( RA_WINXP64
);
1976 else if ( strcmp( native_lanman
, "Windows Server 2003 5.2" ) == 0 )
1977 set_remote_arch( RA_WIN2K3
);
1980 static const char *remote_arch_str
;
1982 const char *get_remote_arch_str(void)
1984 if (!remote_arch_str
) {
1987 return remote_arch_str
;
1990 /*******************************************************************
1991 Set the horrid remote_arch string based on an enum.
1992 ********************************************************************/
1994 void set_remote_arch(enum remote_arch_types type
)
1999 remote_arch_str
= "WfWg";
2002 remote_arch_str
= "OS2";
2005 remote_arch_str
= "Win95";
2008 remote_arch_str
= "WinNT";
2011 remote_arch_str
= "Win2K";
2014 remote_arch_str
= "WinXP";
2017 remote_arch_str
= "WinXP64";
2020 remote_arch_str
= "Win2K3";
2023 remote_arch_str
= "Vista";
2026 remote_arch_str
= "Samba";
2029 remote_arch_str
= "CIFSFS";
2032 ra_type
= RA_UNKNOWN
;
2033 remote_arch_str
= "UNKNOWN";
2037 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
2041 /*******************************************************************
2042 Get the remote_arch type.
2043 ********************************************************************/
2045 enum remote_arch_types
get_remote_arch(void)
2050 const char *tab_depth(int level
, int depth
)
2052 if( CHECK_DEBUGLVL(level
) ) {
2053 dbgtext("%*s", depth
*4, "");
2058 /*****************************************************************************
2059 Provide a checksum on a string
2061 Input: s - the null-terminated character string for which the checksum
2064 Output: The checksum value calculated for s.
2065 *****************************************************************************/
2067 int str_checksum(const char *s
)
2075 res
^= (c
<< (i
% 15)) ^ (c
>> (15-(i
%15)));
2082 /*****************************************************************
2083 Zero a memory area then free it. Used to catch bugs faster.
2084 *****************************************************************/
2086 void zero_free(void *p
, size_t size
)
2092 /*****************************************************************
2093 Set our open file limit to a requested max and return the limit.
2094 *****************************************************************/
2096 int set_maxfiles(int requested_max
)
2098 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2100 int saved_current_limit
;
2102 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
2103 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2106 return requested_max
;
2110 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2111 * account for the extra fd we need
2112 * as well as the log files and standard
2113 * handles etc. Save the limit we want to set in case
2114 * we are running on an OS that doesn't support this limit (AIX)
2115 * which always returns RLIM_INFINITY for rlp.rlim_max.
2118 /* Try raising the hard (max) limit to the requested amount. */
2120 #if defined(RLIM_INFINITY)
2121 if (rlp
.rlim_max
!= RLIM_INFINITY
) {
2122 int orig_max
= rlp
.rlim_max
;
2124 if ( rlp
.rlim_max
< requested_max
)
2125 rlp
.rlim_max
= requested_max
;
2127 /* This failing is not an error - many systems (Linux) don't
2128 support our default request of 10,000 open files. JRA. */
2130 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
2131 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2132 (int)rlp
.rlim_max
, strerror(errno
) ));
2134 /* Set failed - restore original value from get. */
2135 rlp
.rlim_max
= orig_max
;
2140 /* Now try setting the soft (current) limit. */
2142 saved_current_limit
= rlp
.rlim_cur
= MIN(requested_max
,rlp
.rlim_max
);
2144 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
2145 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2146 (int)rlp
.rlim_cur
, strerror(errno
) ));
2148 return saved_current_limit
;
2151 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
2152 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2155 return saved_current_limit
;
2158 #if defined(RLIM_INFINITY)
2159 if(rlp
.rlim_cur
== RLIM_INFINITY
)
2160 return saved_current_limit
;
2163 if((int)rlp
.rlim_cur
> saved_current_limit
)
2164 return saved_current_limit
;
2166 return rlp
.rlim_cur
;
2167 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2169 * No way to know - just guess...
2171 return requested_max
;
2175 /*****************************************************************
2176 Possibly replace mkstemp if it is broken.
2177 *****************************************************************/
2179 int smb_mkstemp(char *name_template
)
2181 #if HAVE_SECURE_MKSTEMP
2182 return mkstemp(name_template
);
2184 /* have a reasonable go at emulating it. Hope that
2185 the system mktemp() isn't completly hopeless */
2186 char *p
= mktemp(name_template
);
2189 return open(p
, O_CREAT
|O_EXCL
|O_RDWR
, 0600);
2193 /*****************************************************************
2194 malloc that aborts with smb_panic on fail or zero size.
2195 *****************************************************************/
2197 void *smb_xmalloc_array(size_t size
, unsigned int count
)
2201 smb_panic("smb_xmalloc_array: called with zero size");
2203 if (count
>= MAX_ALLOC_SIZE
/size
) {
2204 smb_panic("smb_xmalloc_array: alloc size too large");
2206 if ((p
= SMB_MALLOC(size
*count
)) == NULL
) {
2207 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2208 (unsigned long)size
, (unsigned long)count
));
2209 smb_panic("smb_xmalloc_array: malloc failed");
2215 vasprintf that aborts on malloc fail
2218 int smb_xvasprintf(char **ptr
, const char *format
, va_list ap
)
2225 n
= vasprintf(ptr
, format
, ap2
);
2226 if (n
== -1 || ! *ptr
) {
2227 smb_panic("smb_xvasprintf: out of memory");
2233 /*****************************************************************
2234 Get local hostname and cache result.
2235 *****************************************************************/
2237 char *myhostname(void)
2241 /* This is cached forever so
2242 * use talloc_autofree_context() ctx. */
2243 ret
= talloc_get_myname(talloc_autofree_context());
2249 * @brief Returns an absolute path to a file concatenating the provided
2250 * @a rootpath and @a basename
2252 * @param name Filename, relative to @a rootpath
2254 * @retval Pointer to a string containing the full path.
2257 static char *xx_path(const char *name
, const char *rootpath
)
2261 fname
= talloc_strdup(talloc_tos(), rootpath
);
2265 trim_string(fname
,"","/");
2267 if (!directory_exist(fname
)) {
2268 if (!mkdir(fname
,0755))
2269 DEBUG(1, ("Unable to create directory %s for file %s. "
2270 "Error was %s\n", fname
, name
, strerror(errno
)));
2273 return talloc_asprintf(talloc_tos(),
2280 * @brief Returns an absolute path to a file in the Samba lock directory.
2282 * @param name File to find, relative to LOCKDIR.
2284 * @retval Pointer to a talloc'ed string containing the full path.
2287 char *lock_path(const char *name
)
2289 return xx_path(name
, lp_lockdir());
2293 * @brief Returns an absolute path to a file in the Samba pid directory.
2295 * @param name File to find, relative to PIDDIR.
2297 * @retval Pointer to a talloc'ed string containing the full path.
2300 char *pid_path(const char *name
)
2302 return xx_path(name
, lp_piddir());
2306 * @brief Returns an absolute path to a file in the Samba lib directory.
2308 * @param name File to find, relative to LIBDIR.
2310 * @retval Pointer to a string containing the full path.
2313 char *lib_path(const char *name
)
2315 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name
);
2319 * @brief Returns an absolute path to a file in the Samba modules directory.
2321 * @param name File to find, relative to MODULESDIR.
2323 * @retval Pointer to a string containing the full path.
2326 char *modules_path(const char *name
)
2328 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_MODULESDIR(), name
);
2332 * @brief Returns an absolute path to a file in the Samba data directory.
2334 * @param name File to find, relative to CODEPAGEDIR.
2336 * @retval Pointer to a talloc'ed string containing the full path.
2339 char *data_path(const char *name
)
2341 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name
);
2345 * @brief Returns an absolute path to a file in the Samba state directory.
2347 * @param name File to find, relative to STATEDIR.
2349 * @retval Pointer to a talloc'ed string containing the full path.
2352 char *state_path(const char *name
)
2354 return xx_path(name
, lp_statedir());
2358 * @brief Returns an absolute path to a file in the Samba cache directory.
2360 * @param name File to find, relative to CACHEDIR.
2362 * @retval Pointer to a talloc'ed string containing the full path.
2365 char *cache_path(const char *name
)
2367 return xx_path(name
, lp_cachedir());
2371 * @brief Returns the platform specific shared library extension.
2373 * @retval Pointer to a const char * containing the extension.
2376 const char *shlib_ext(void)
2378 return get_dyn_SHLIBEXT();
2381 /*******************************************************************
2382 Given a filename - get its directory name
2383 ********************************************************************/
2385 bool parent_dirname(TALLOC_CTX
*mem_ctx
, const char *dir
, char **parent
,
2391 p
= strrchr_m(dir
, '/'); /* Find final '/', if any */
2394 if (!(*parent
= talloc_strdup(mem_ctx
, "."))) {
2405 if (!(*parent
= (char *)TALLOC_MEMDUP(mem_ctx
, dir
, len
+1))) {
2408 (*parent
)[len
] = '\0';
2416 /*******************************************************************
2417 Determine if a pattern contains any Microsoft wildcard characters.
2418 *******************************************************************/
2420 bool ms_has_wild(const char *s
)
2424 if (lp_posix_pathnames()) {
2425 /* With posix pathnames no characters are wild. */
2429 while ((c
= *s
++)) {
2442 bool ms_has_wild_w(const smb_ucs2_t
*s
)
2445 if (!s
) return False
;
2446 while ((c
= *s
++)) {
2448 case UCS2_CHAR('*'):
2449 case UCS2_CHAR('?'):
2450 case UCS2_CHAR('<'):
2451 case UCS2_CHAR('>'):
2452 case UCS2_CHAR('"'):
2459 /*******************************************************************
2460 A wrapper that handles case sensitivity and the special handling
2462 *******************************************************************/
2464 bool mask_match(const char *string
, const char *pattern
, bool is_case_sensitive
)
2466 if (strcmp(string
,"..") == 0)
2468 if (strcmp(pattern
,".") == 0)
2471 return ms_fnmatch(pattern
, string
, Protocol
<= PROTOCOL_LANMAN2
, is_case_sensitive
) == 0;
2474 /*******************************************************************
2475 A wrapper that handles case sensitivity and the special handling
2476 of the ".." name. Varient that is only called by old search code which requires
2477 pattern translation.
2478 *******************************************************************/
2480 bool mask_match_search(const char *string
, const char *pattern
, bool is_case_sensitive
)
2482 if (strcmp(string
,"..") == 0)
2484 if (strcmp(pattern
,".") == 0)
2487 return ms_fnmatch(pattern
, string
, True
, is_case_sensitive
) == 0;
2490 /*******************************************************************
2491 A wrapper that handles a list of patters and calls mask_match()
2492 on each. Returns True if any of the patterns match.
2493 *******************************************************************/
2495 bool mask_match_list(const char *string
, char **list
, int listLen
, bool is_case_sensitive
)
2497 while (listLen
-- > 0) {
2498 if (mask_match(string
, *list
++, is_case_sensitive
))
2504 /*********************************************************
2505 Recursive routine that is called by unix_wild_match.
2506 *********************************************************/
2508 static bool unix_do_match(const char *regexp
, const char *str
)
2512 for( p
= regexp
; *p
&& *str
; ) {
2523 * Look for a character matching
2524 * the one after the '*'.
2528 return true; /* Automatic match */
2531 while(*str
&& (*p
!= *str
))
2535 * Patch from weidel@multichart.de. In the case of the regexp
2536 * '*XX*' we want to ensure there are at least 2 'X' characters
2537 * in the string after the '*' for a match to be made.
2544 * Eat all the characters that match, but count how many there were.
2547 while(*str
&& (*p
== *str
)) {
2553 * Now check that if the regexp had n identical characters that
2554 * matchcount had at least that many matches.
2557 while ( *(p
+1) && (*(p
+1) == *p
)) {
2562 if ( matchcount
<= 0 )
2566 str
--; /* We've eaten the match char after the '*' */
2568 if(unix_do_match(p
, str
))
2590 if (!*p
&& str
[0] == '.' && str
[1] == 0)
2593 if (!*str
&& *p
== '?') {
2599 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
2605 /*******************************************************************
2606 Simple case insensitive interface to a UNIX wildcard matcher.
2607 Returns True if match, False if not.
2608 *******************************************************************/
2610 bool unix_wild_match(const char *pattern
, const char *string
)
2612 TALLOC_CTX
*ctx
= talloc_stackframe();
2618 p2
= talloc_strdup(ctx
,pattern
);
2619 s2
= talloc_strdup(ctx
,string
);
2627 /* Remove any *? and ** from the pattern as they are meaningless */
2628 for(p
= p2
; *p
; p
++) {
2629 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*')) {
2630 memmove(&p
[1], &p
[2], strlen(&p
[2])+1);
2634 if (strequal(p2
,"*")) {
2639 ret
= unix_do_match(p2
, s2
);
2644 /**********************************************************************
2645 Converts a name to a fully qualified domain name.
2646 Returns true if lookup succeeded, false if not (then fqdn is set to name)
2647 Note we deliberately use gethostbyname here, not getaddrinfo as we want
2648 to examine the h_aliases and I don't know how to do that with getaddrinfo.
2649 ***********************************************************************/
2651 bool name_to_fqdn(fstring fqdn
, const char *name
)
2654 struct hostent
*hp
= gethostbyname(name
);
2656 if (!hp
|| !hp
->h_name
|| !*hp
->h_name
) {
2657 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name
));
2658 fstrcpy(fqdn
, name
);
2662 /* Find out if the fqdn is returned as an alias
2663 * to cope with /etc/hosts files where the first
2664 * name is not the fqdn but the short name */
2665 if (hp
->h_aliases
&& (! strchr_m(hp
->h_name
, '.'))) {
2667 for (i
= 0; hp
->h_aliases
[i
]; i
++) {
2668 if (strchr_m(hp
->h_aliases
[i
], '.')) {
2669 full
= hp
->h_aliases
[i
];
2674 if (full
&& (StrCaseCmp(full
, "localhost.localdomain") == 0)) {
2675 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2676 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2677 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
2678 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
2685 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name
, full
));
2686 fstrcpy(fqdn
, full
);
2690 /**********************************************************************
2691 Append a DATA_BLOB to a talloc'ed object
2692 ***********************************************************************/
2694 void *talloc_append_blob(TALLOC_CTX
*mem_ctx
, void *buf
, DATA_BLOB blob
)
2696 size_t old_size
= 0;
2699 if (blob
.length
== 0) {
2704 old_size
= talloc_get_size(buf
);
2707 result
= (char *)TALLOC_REALLOC(mem_ctx
, buf
, old_size
+ blob
.length
);
2708 if (result
== NULL
) {
2712 memcpy(result
+ old_size
, blob
.data
, blob
.length
);
2716 uint32
map_share_mode_to_deny_mode(uint32 share_access
, uint32 private_options
)
2718 switch (share_access
& ~FILE_SHARE_DELETE
) {
2719 case FILE_SHARE_NONE
:
2721 case FILE_SHARE_READ
:
2723 case FILE_SHARE_WRITE
:
2725 case FILE_SHARE_READ
|FILE_SHARE_WRITE
:
2728 if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) {
2730 } else if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
) {
2737 pid_t
procid_to_pid(const struct server_id
*proc
)
2742 static uint32 my_vnn
= NONCLUSTER_VNN
;
2744 void set_my_vnn(uint32 vnn
)
2746 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn
));
2750 uint32
get_my_vnn(void)
2755 struct server_id
pid_to_procid(pid_t pid
)
2757 struct server_id result
;
2759 #ifdef CLUSTER_SUPPORT
2760 result
.vnn
= my_vnn
;
2765 struct server_id
procid_self(void)
2767 return pid_to_procid(sys_getpid());
2770 struct server_id
server_id_self(void)
2772 return procid_self();
2775 bool procid_equal(const struct server_id
*p1
, const struct server_id
*p2
)
2777 if (p1
->pid
!= p2
->pid
)
2779 #ifdef CLUSTER_SUPPORT
2780 if (p1
->vnn
!= p2
->vnn
)
2786 bool cluster_id_equal(const struct server_id
*id1
,
2787 const struct server_id
*id2
)
2789 return procid_equal(id1
, id2
);
2792 bool procid_is_me(const struct server_id
*pid
)
2794 if (pid
->pid
!= sys_getpid())
2796 #ifdef CLUSTER_SUPPORT
2797 if (pid
->vnn
!= my_vnn
)
2803 struct server_id
interpret_pid(const char *pid_string
)
2805 #ifdef CLUSTER_SUPPORT
2806 unsigned int vnn
, pid
;
2807 struct server_id result
;
2808 if (sscanf(pid_string
, "%u:%u", &vnn
, &pid
) == 2) {
2812 else if (sscanf(pid_string
, "%u", &pid
) == 1) {
2813 result
.vnn
= get_my_vnn();
2817 result
.vnn
= NONCLUSTER_VNN
;
2822 return pid_to_procid(atoi(pid_string
));
2826 char *procid_str(TALLOC_CTX
*mem_ctx
, const struct server_id
*pid
)
2828 #ifdef CLUSTER_SUPPORT
2829 if (pid
->vnn
== NONCLUSTER_VNN
) {
2830 return talloc_asprintf(mem_ctx
,
2835 return talloc_asprintf(mem_ctx
,
2841 return talloc_asprintf(mem_ctx
,
2847 char *procid_str_static(const struct server_id
*pid
)
2849 return procid_str(talloc_tos(), pid
);
2852 bool procid_valid(const struct server_id
*pid
)
2854 return (pid
->pid
!= -1);
2857 bool procid_is_local(const struct server_id
*pid
)
2859 #ifdef CLUSTER_SUPPORT
2860 return pid
->vnn
== my_vnn
;
2866 int this_is_smp(void)
2868 #if defined(HAVE_SYSCONF)
2870 #if defined(SYSCONF_SC_NPROC_ONLN)
2871 return (sysconf(_SC_NPROC_ONLN
) > 1) ? 1 : 0;
2872 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
2873 return (sysconf(_SC_NPROCESSORS_ONLN
) > 1) ? 1 : 0;
2883 /****************************************************************
2884 Check if offset/length fit into bufsize. Should probably be
2885 merged with is_offset_safe, but this would require a rewrite
2886 of lanman.c. Later :-)
2887 ****************************************************************/
2889 bool trans_oob(uint32_t bufsize
, uint32_t offset
, uint32_t length
)
2891 if ((offset
+ length
< offset
) || (offset
+ length
< length
)) {
2895 if ((offset
> bufsize
) || (offset
+ length
> bufsize
)) {
2902 /****************************************************************
2903 Check if an offset into a buffer is safe.
2904 If this returns True it's safe to indirect into the byte at
2906 ****************************************************************/
2908 bool is_offset_safe(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2910 const char *end_base
= buf_base
+ buf_len
;
2911 char *end_ptr
= ptr
+ off
;
2913 if (!buf_base
|| !ptr
) {
2917 if (end_base
< buf_base
|| end_ptr
< ptr
) {
2918 return False
; /* wrap. */
2921 if (end_ptr
< end_base
) {
2927 /****************************************************************
2928 Return a safe pointer into a buffer, or NULL.
2929 ****************************************************************/
2931 char *get_safe_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2933 return is_offset_safe(buf_base
, buf_len
, ptr
, off
) ?
2937 /****************************************************************
2938 Return a safe pointer into a string within a buffer, or NULL.
2939 ****************************************************************/
2941 char *get_safe_str_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2943 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
)) {
2946 /* Check if a valid string exists at this offset. */
2947 if (skip_string(buf_base
,buf_len
, ptr
+ off
) == NULL
) {
2953 /****************************************************************
2954 Return an SVAL at a pointer, or failval if beyond the end.
2955 ****************************************************************/
2957 int get_safe_SVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2960 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2963 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+1)) {
2966 return SVAL(ptr
,off
);
2969 /****************************************************************
2970 Return an IVAL at a pointer, or failval if beyond the end.
2971 ****************************************************************/
2973 int get_safe_IVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2976 * Note we use off+3 here, not off+4 as IVAL accesses
2977 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2979 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+3)) {
2982 return IVAL(ptr
,off
);
2985 /****************************************************************
2986 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2987 call (they take care of winbind separator and other winbind specific settings).
2988 ****************************************************************/
2990 void split_domain_user(TALLOC_CTX
*mem_ctx
,
2991 const char *full_name
,
2995 const char *p
= NULL
;
2997 p
= strchr_m(full_name
, '\\');
3000 *domain
= talloc_strndup(mem_ctx
, full_name
,
3001 PTR_DIFF(p
, full_name
));
3002 *user
= talloc_strdup(mem_ctx
, p
+1);
3004 *domain
= talloc_strdup(mem_ctx
, "");
3005 *user
= talloc_strdup(mem_ctx
, full_name
);
3011 Disable these now we have checked all code paths
and ensured
3012 NULL returns on zero request
. JRA
.
3014 /****************************************************************
3015 talloc wrapper functions that guarentee a null pointer return
3017 ****************************************************************/
3019 #ifndef MAX_TALLOC_SIZE
3020 #define MAX_TALLOC_SIZE 0x10000000
3024 * talloc and zero memory.
3025 * - returns NULL if size is zero.
3028 void *_talloc_zero_zeronull(const void *ctx
, size_t size
, const char *name
)
3036 p
= talloc_named_const(ctx
, size
, name
);
3039 memset(p
, '\0', size
);
3046 * memdup with a talloc.
3047 * - returns NULL if size is zero.
3050 void *_talloc_memdup_zeronull(const void *t
, const void *p
, size_t size
, const char *name
)
3058 newp
= talloc_named_const(t
, size
, name
);
3060 memcpy(newp
, p
, size
);
3067 * alloc an array, checking for integer overflow in the array size.
3068 * - returns NULL if count or el_size are zero.
3071 void *_talloc_array_zeronull(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
3073 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
3077 if (el_size
== 0 || count
== 0) {
3081 return talloc_named_const(ctx
, el_size
* count
, name
);
3085 * alloc an zero array, checking for integer overflow in the array size
3086 * - returns NULL if count or el_size are zero.
3089 void *_talloc_zero_array_zeronull(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
3091 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
3095 if (el_size
== 0 || count
== 0) {
3099 return _talloc_zero(ctx
, el_size
* count
, name
);
3103 * Talloc wrapper that returns NULL if size == 0.
3105 void *talloc_zeronull(const void *context
, size_t size
, const char *name
)
3110 return talloc_named_const(context
, size
, name
);
3114 /* Split a path name into filename and stream name components. Canonicalise
3115 * such that an implicit $DATA token is always explicit.
3117 * The "specification" of this function can be found in the
3118 * run_local_stream_name() function in torture.c, I've tried those
3119 * combinations against a W2k3 server.
3122 NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
3123 char **pbase
, char **pstream
)
3126 char *stream
= NULL
;
3127 char *sname
; /* stream name */
3128 const char *stype
; /* stream type */
3130 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
3132 sname
= strchr_m(fname
, ':');
3134 if (lp_posix_pathnames() || (sname
== NULL
)) {
3135 if (pbase
!= NULL
) {
3136 base
= talloc_strdup(mem_ctx
, fname
);
3137 NT_STATUS_HAVE_NO_MEMORY(base
);
3142 if (pbase
!= NULL
) {
3143 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
3144 NT_STATUS_HAVE_NO_MEMORY(base
);
3149 stype
= strchr_m(sname
, ':');
3151 if (stype
== NULL
) {
3152 sname
= talloc_strdup(mem_ctx
, sname
);
3156 if (StrCaseCmp(stype
, ":$DATA") != 0) {
3158 * If there is an explicit stream type, so far we only
3159 * allow $DATA. Is there anything else allowed? -- vl
3161 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
3163 return NT_STATUS_OBJECT_NAME_INVALID
;
3165 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
3169 if (sname
== NULL
) {
3171 return NT_STATUS_NO_MEMORY
;
3174 if (sname
[0] == '\0') {
3176 * no stream name, so no stream
3181 if (pstream
!= NULL
) {
3182 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
3183 if (stream
== NULL
) {
3186 return NT_STATUS_NO_MEMORY
;
3189 * upper-case the type field
3191 strupper_m(strchr_m(stream
, ':')+1);
3195 if (pbase
!= NULL
) {
3198 if (pstream
!= NULL
) {
3201 return NT_STATUS_OK
;
3204 bool is_valid_policy_hnd(const POLICY_HND
*hnd
)
3208 return (memcmp(&tmp
, hnd
, sizeof(tmp
)) != 0);
3211 bool policy_hnd_equal(const struct policy_handle
*hnd1
,
3212 const struct policy_handle
*hnd2
)
3214 if (!hnd1
|| !hnd2
) {
3218 return (memcmp(hnd1
, hnd2
, sizeof(*hnd1
)) == 0);
3221 /****************************************************************
3222 strip off leading '\\' from a hostname
3223 ****************************************************************/
3225 const char *strip_hostname(const char *s
)
3231 if (strlen_m(s
) < 3) {
3235 if (s
[0] == '\\') s
++;
3236 if (s
[0] == '\\') s
++;