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 static enum protocol_types Protocol
= PROTOCOL_COREPLUS
;
60 enum protocol_types
get_Protocol(void)
65 void set_Protocol(enum protocol_types p
)
70 static enum remote_arch_types ra_type
= RA_UNKNOWN
;
72 /***********************************************************************
73 Definitions for all names.
74 ***********************************************************************/
76 static char *smb_myname
;
77 static char *smb_myworkgroup
;
78 static char *smb_scope
;
79 static int smb_num_netbios_names
;
80 static char **smb_my_netbios_names
;
82 /***********************************************************************
83 Allocate and set myname. Ensure upper case.
84 ***********************************************************************/
86 bool set_global_myname(const char *myname
)
88 SAFE_FREE(smb_myname
);
89 smb_myname
= SMB_STRDUP(myname
);
92 strupper_m(smb_myname
);
96 const char *global_myname(void)
101 /***********************************************************************
102 Allocate and set myworkgroup. Ensure upper case.
103 ***********************************************************************/
105 bool set_global_myworkgroup(const char *myworkgroup
)
107 SAFE_FREE(smb_myworkgroup
);
108 smb_myworkgroup
= SMB_STRDUP(myworkgroup
);
109 if (!smb_myworkgroup
)
111 strupper_m(smb_myworkgroup
);
115 const char *lp_workgroup(void)
117 return smb_myworkgroup
;
120 /***********************************************************************
121 Allocate and set scope. Ensure upper case.
122 ***********************************************************************/
124 bool set_global_scope(const char *scope
)
126 SAFE_FREE(smb_scope
);
127 smb_scope
= SMB_STRDUP(scope
);
130 strupper_m(smb_scope
);
134 /*********************************************************************
135 Ensure scope is never null string.
136 *********************************************************************/
138 const char *global_scope(void)
141 set_global_scope("");
145 static void free_netbios_names_array(void)
149 for (i
= 0; i
< smb_num_netbios_names
; i
++)
150 SAFE_FREE(smb_my_netbios_names
[i
]);
152 SAFE_FREE(smb_my_netbios_names
);
153 smb_num_netbios_names
= 0;
156 static bool allocate_my_netbios_names_array(size_t number
)
158 free_netbios_names_array();
160 smb_num_netbios_names
= number
+ 1;
161 smb_my_netbios_names
= SMB_MALLOC_ARRAY( char *, smb_num_netbios_names
);
163 if (!smb_my_netbios_names
)
166 memset(smb_my_netbios_names
, '\0', sizeof(char *) * smb_num_netbios_names
);
170 static bool set_my_netbios_names(const char *name
, int i
)
172 SAFE_FREE(smb_my_netbios_names
[i
]);
174 smb_my_netbios_names
[i
] = SMB_STRDUP(name
);
175 if (!smb_my_netbios_names
[i
])
177 strupper_m(smb_my_netbios_names
[i
]);
181 /***********************************************************************
182 Free memory allocated to global objects
183 ***********************************************************************/
185 void gfree_names(void)
187 SAFE_FREE( smb_myname
);
188 SAFE_FREE( smb_myworkgroup
);
189 SAFE_FREE( smb_scope
);
190 free_netbios_names_array();
191 free_local_machine_name();
194 void gfree_all( void )
204 const char *my_netbios_names(int i
)
206 return smb_my_netbios_names
[i
];
209 bool set_netbios_aliases(const char **str_array
)
213 /* Work out the max number of netbios aliases that we have */
214 for( namecount
=0; str_array
&& (str_array
[namecount
] != NULL
); namecount
++ )
217 if ( global_myname() && *global_myname())
220 /* Allocate space for the netbios aliases */
221 if (!allocate_my_netbios_names_array(namecount
))
224 /* Use the global_myname string first */
226 if ( global_myname() && *global_myname()) {
227 set_my_netbios_names( global_myname(), namecount
);
233 for ( i
= 0; str_array
[i
] != NULL
; i
++) {
235 bool duplicate
= False
;
237 /* Look for duplicates */
238 for( n
=0; n
<namecount
; n
++ ) {
239 if( strequal( str_array
[i
], my_netbios_names(n
) ) ) {
245 if (!set_my_netbios_names(str_array
[i
], namecount
))
254 /****************************************************************************
255 Common name initialization code.
256 ****************************************************************************/
258 bool init_names(void)
262 if (global_myname() == NULL
|| *global_myname() == '\0') {
263 if (!set_global_myname(myhostname())) {
264 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
269 if (!set_netbios_aliases(lp_netbios_aliases())) {
270 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
274 set_local_machine_name(global_myname(),false);
276 DEBUG( 5, ("Netbios name list:-\n") );
277 for( n
=0; my_netbios_names(n
); n
++ ) {
278 DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",
279 n
, my_netbios_names(n
) ) );
285 /**************************************************************************n
286 Code to cope with username/password auth options from the commandline.
287 Used mainly in client tools.
288 ****************************************************************************/
290 struct user_auth_info
*user_auth_info_init(TALLOC_CTX
*mem_ctx
)
292 struct user_auth_info
*result
;
294 result
= TALLOC_ZERO_P(mem_ctx
, struct user_auth_info
);
295 if (result
== NULL
) {
299 result
->signing_state
= Undefined
;
303 const char *get_cmdline_auth_info_username(const struct user_auth_info
*auth_info
)
305 if (!auth_info
->username
) {
308 return auth_info
->username
;
311 void set_cmdline_auth_info_username(struct user_auth_info
*auth_info
,
312 const char *username
)
314 TALLOC_FREE(auth_info
->username
);
315 auth_info
->username
= talloc_strdup(auth_info
, username
);
316 if (!auth_info
->username
) {
321 const char *get_cmdline_auth_info_domain(const struct user_auth_info
*auth_info
)
323 if (!auth_info
->domain
) {
326 return auth_info
->domain
;
329 void set_cmdline_auth_info_domain(struct user_auth_info
*auth_info
,
332 TALLOC_FREE(auth_info
->domain
);
333 auth_info
->domain
= talloc_strdup(auth_info
, domain
);
334 if (!auth_info
->domain
) {
339 const char *get_cmdline_auth_info_password(const struct user_auth_info
*auth_info
)
341 if (!auth_info
->password
) {
344 return auth_info
->password
;
347 void set_cmdline_auth_info_password(struct user_auth_info
*auth_info
,
348 const char *password
)
350 TALLOC_FREE(auth_info
->password
);
351 if (password
== NULL
) {
354 auth_info
->password
= talloc_strdup(auth_info
, password
);
355 if (!auth_info
->password
) {
358 auth_info
->got_pass
= true;
361 bool set_cmdline_auth_info_signing_state(struct user_auth_info
*auth_info
,
364 auth_info
->signing_state
= -1;
365 if (strequal(arg
, "off") || strequal(arg
, "no") ||
366 strequal(arg
, "false")) {
367 auth_info
->signing_state
= false;
368 } else if (strequal(arg
, "on") || strequal(arg
, "yes") ||
369 strequal(arg
, "true") || strequal(arg
, "auto")) {
370 auth_info
->signing_state
= true;
371 } else if (strequal(arg
, "force") || strequal(arg
, "required") ||
372 strequal(arg
, "forced")) {
373 auth_info
->signing_state
= Required
;
380 int get_cmdline_auth_info_signing_state(const struct user_auth_info
*auth_info
)
382 return auth_info
->signing_state
;
385 void set_cmdline_auth_info_use_kerberos(struct user_auth_info
*auth_info
,
388 auth_info
->use_kerberos
= b
;
391 bool get_cmdline_auth_info_use_kerberos(const struct user_auth_info
*auth_info
)
393 return auth_info
->use_kerberos
;
396 void set_cmdline_auth_info_fallback_after_kerberos(struct user_auth_info
*auth_info
,
399 auth_info
->fallback_after_kerberos
= b
;
402 bool get_cmdline_auth_info_fallback_after_kerberos(const struct user_auth_info
*auth_info
)
404 return auth_info
->fallback_after_kerberos
;
407 /* This should only be used by lib/popt_common.c JRA */
408 void set_cmdline_auth_info_use_krb5_ticket(struct user_auth_info
*auth_info
)
410 auth_info
->use_kerberos
= true;
411 auth_info
->got_pass
= true;
414 /* This should only be used by lib/popt_common.c JRA */
415 void set_cmdline_auth_info_smb_encrypt(struct user_auth_info
*auth_info
)
417 auth_info
->smb_encrypt
= true;
420 void set_cmdline_auth_info_use_machine_account(struct user_auth_info
*auth_info
)
422 auth_info
->use_machine_account
= true;
425 bool get_cmdline_auth_info_got_pass(const struct user_auth_info
*auth_info
)
427 return auth_info
->got_pass
;
430 bool get_cmdline_auth_info_smb_encrypt(const struct user_auth_info
*auth_info
)
432 return auth_info
->smb_encrypt
;
435 bool get_cmdline_auth_info_use_machine_account(const struct user_auth_info
*auth_info
)
437 return auth_info
->use_machine_account
;
440 struct user_auth_info
*get_cmdline_auth_info_copy(TALLOC_CTX
*mem_ctx
,
441 const struct user_auth_info
*src
)
443 struct user_auth_info
*result
;
445 result
= user_auth_info_init(mem_ctx
);
446 if (result
== NULL
) {
452 result
->username
= talloc_strdup(
453 result
, get_cmdline_auth_info_username(src
));
454 result
->password
= talloc_strdup(
455 result
, get_cmdline_auth_info_password(src
));
456 if ((result
->username
== NULL
) || (result
->password
== NULL
)) {
464 bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info
*auth_info
)
467 char *account
= NULL
;
469 if (!get_cmdline_auth_info_use_machine_account(auth_info
)) {
473 if (!secrets_init()) {
474 d_printf("ERROR: Unable to open secrets database\n");
478 if (asprintf(&account
, "%s$@%s", global_myname(), lp_realm()) < 0) {
482 pass
= secrets_fetch_machine_password(lp_workgroup(), NULL
, NULL
);
484 d_printf("ERROR: Unable to fetch machine password for "
486 account
, lp_workgroup());
491 set_cmdline_auth_info_username(auth_info
, account
);
492 set_cmdline_auth_info_password(auth_info
, pass
);
500 /****************************************************************************
501 Ensure we have a password if one not given.
502 ****************************************************************************/
504 void set_cmdline_auth_info_getpass(struct user_auth_info
*auth_info
)
510 if (get_cmdline_auth_info_got_pass(auth_info
) ||
511 get_cmdline_auth_info_use_kerberos(auth_info
)) {
512 /* Already got one... */
516 frame
= talloc_stackframe();
517 label
= talloc_asprintf(frame
, "Enter %s's password: ",
518 get_cmdline_auth_info_username(auth_info
));
519 pass
= getpass(label
);
521 set_cmdline_auth_info_password(auth_info
, pass
);
526 /*******************************************************************
527 Check if a file exists - call vfs_file_exist for samba files.
528 ********************************************************************/
530 bool file_exist_stat(const char *fname
,SMB_STRUCT_STAT
*sbuf
,
531 bool fake_dir_create_times
)
537 if (sys_stat(fname
, sbuf
, fake_dir_create_times
) != 0)
540 return((S_ISREG(sbuf
->st_ex_mode
)) || (S_ISFIFO(sbuf
->st_ex_mode
)));
543 /*******************************************************************
544 Check if a unix domain socket exists - call vfs_file_exist for samba files.
545 ********************************************************************/
547 bool socket_exist(const char *fname
)
550 if (sys_stat(fname
, &st
, false) != 0)
553 return S_ISSOCK(st
.st_ex_mode
);
556 /*******************************************************************
557 Returns the size in bytes of the named given the stat struct.
558 ********************************************************************/
560 uint64_t get_file_size_stat(const SMB_STRUCT_STAT
*sbuf
)
562 return sbuf
->st_ex_size
;
565 /*******************************************************************
566 Returns the size in bytes of the named file.
567 ********************************************************************/
569 SMB_OFF_T
get_file_size(char *file_name
)
573 if (sys_stat(file_name
, &buf
, false) != 0)
574 return (SMB_OFF_T
)-1;
575 return get_file_size_stat(&buf
);
578 /*******************************************************************
579 Return a string representing an attribute for a file.
580 ********************************************************************/
582 char *attrib_string(uint16 mode
)
588 if (mode
& aVOLID
) fstrcat(attrstr
,"V");
589 if (mode
& aDIR
) fstrcat(attrstr
,"D");
590 if (mode
& aARCH
) fstrcat(attrstr
,"A");
591 if (mode
& aHIDDEN
) fstrcat(attrstr
,"H");
592 if (mode
& aSYSTEM
) fstrcat(attrstr
,"S");
593 if (mode
& aRONLY
) fstrcat(attrstr
,"R");
595 return talloc_strdup(talloc_tos(), attrstr
);
598 /*******************************************************************
599 Show a smb message structure.
600 ********************************************************************/
602 void show_msg(char *buf
)
610 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
612 (int)CVAL(buf
,smb_com
),
613 (int)CVAL(buf
,smb_rcls
),
614 (int)CVAL(buf
,smb_reh
),
615 (int)SVAL(buf
,smb_err
),
616 (int)CVAL(buf
,smb_flg
),
617 (int)SVAL(buf
,smb_flg2
)));
618 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
619 (int)SVAL(buf
,smb_tid
),
620 (int)SVAL(buf
,smb_pid
),
621 (int)SVAL(buf
,smb_uid
),
622 (int)SVAL(buf
,smb_mid
)));
623 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf
,smb_wct
)));
625 for (i
=0;i
<(int)CVAL(buf
,smb_wct
);i
++)
626 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i
,
627 SVAL(buf
,smb_vwv
+2*i
),SVAL(buf
,smb_vwv
+2*i
)));
629 bcc
= (int)SVAL(buf
,smb_vwv
+2*(CVAL(buf
,smb_wct
)));
631 DEBUGADD(5,("smb_bcc=%d\n",bcc
));
639 dump_data(10, (uint8
*)smb_buf(buf
), bcc
);
642 /*******************************************************************
643 Set the length and marker of an encrypted smb packet.
644 ********************************************************************/
646 void smb_set_enclen(char *buf
,int len
,uint16 enc_ctx_num
)
648 _smb_setlen(buf
,len
);
652 SSVAL(buf
,6,enc_ctx_num
);
655 /*******************************************************************
656 Set the length and marker of an smb packet.
657 ********************************************************************/
659 void smb_setlen(char *buf
,int len
)
661 _smb_setlen(buf
,len
);
669 /*******************************************************************
670 Setup only the byte count for a smb message.
671 ********************************************************************/
673 int set_message_bcc(char *buf
,int num_bytes
)
675 int num_words
= CVAL(buf
,smb_wct
);
676 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
677 _smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
678 return (smb_size
+ num_words
*2 + num_bytes
);
681 /*******************************************************************
682 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
683 Return the bytes added
684 ********************************************************************/
686 ssize_t
message_push_blob(uint8
**outbuf
, DATA_BLOB blob
)
688 size_t newlen
= smb_len(*outbuf
) + 4 + blob
.length
;
691 if (!(tmp
= TALLOC_REALLOC_ARRAY(NULL
, *outbuf
, uint8
, newlen
))) {
692 DEBUG(0, ("talloc failed\n"));
697 memcpy(tmp
+ smb_len(tmp
) + 4, blob
.data
, blob
.length
);
698 set_message_bcc((char *)tmp
, smb_buflen(tmp
) + blob
.length
);
702 /*******************************************************************
703 Reduce a file name, removing .. elements.
704 ********************************************************************/
706 static char *dos_clean_name(TALLOC_CTX
*ctx
, const char *s
)
711 DEBUG(3,("dos_clean_name [%s]\n",s
));
713 /* remove any double slashes */
714 str
= talloc_all_string_sub(ctx
, s
, "\\\\", "\\");
719 /* Remove leading .\\ characters */
720 if(strncmp(str
, ".\\", 2) == 0) {
721 trim_string(str
, ".\\", NULL
);
723 str
= talloc_strdup(ctx
, ".\\");
730 while ((p
= strstr_m(str
,"\\..\\")) != NULL
) {
736 if ((p
=strrchr_m(str
,'\\')) != NULL
) {
741 str
= talloc_asprintf(ctx
,
750 trim_string(str
,NULL
,"\\..");
751 return talloc_all_string_sub(ctx
, str
, "\\.\\", "\\");
754 /*******************************************************************
755 Reduce a file name, removing .. elements.
756 ********************************************************************/
758 char *unix_clean_name(TALLOC_CTX
*ctx
, const char *s
)
763 DEBUG(3,("unix_clean_name [%s]\n",s
));
765 /* remove any double slashes */
766 str
= talloc_all_string_sub(ctx
, s
, "//","/");
771 /* Remove leading ./ characters */
772 if(strncmp(str
, "./", 2) == 0) {
773 trim_string(str
, "./", NULL
);
775 str
= talloc_strdup(ctx
, "./");
782 while ((p
= strstr_m(str
,"/../")) != NULL
) {
788 if ((p
=strrchr_m(str
,'/')) != NULL
) {
793 str
= talloc_asprintf(ctx
,
802 trim_string(str
,NULL
,"/..");
803 return talloc_all_string_sub(ctx
, str
, "/./", "/");
806 char *clean_name(TALLOC_CTX
*ctx
, const char *s
)
808 char *str
= dos_clean_name(ctx
, s
);
812 return unix_clean_name(ctx
, str
);
815 /*******************************************************************
816 Write data into an fd at a given offset. Ignore seek errors.
817 ********************************************************************/
819 ssize_t
write_data_at_offset(int fd
, const char *buffer
, size_t N
, SMB_OFF_T pos
)
824 if (pos
== (SMB_OFF_T
)-1) {
825 return write_data(fd
, buffer
, N
);
827 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
829 ret
= sys_pwrite(fd
,buffer
+ total
,N
- total
, pos
);
830 if (ret
== -1 && errno
== ESPIPE
) {
831 return write_data(fd
, buffer
+ total
,N
- total
);
834 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno
) ));
843 return (ssize_t
)total
;
845 /* Use lseek and write_data. */
846 if (sys_lseek(fd
, pos
, SEEK_SET
) == -1) {
847 if (errno
!= ESPIPE
) {
851 return write_data(fd
, buffer
, N
);
855 /*******************************************************************
856 Sleep for a specified number of milliseconds.
857 ********************************************************************/
859 void smb_msleep(unsigned int t
)
861 #if defined(HAVE_NANOSLEEP)
862 struct timespec tval
;
865 tval
.tv_sec
= t
/1000;
866 tval
.tv_nsec
= 1000000*(t
%1000);
870 ret
= nanosleep(&tval
, &tval
);
871 } while (ret
< 0 && errno
== EINTR
&& (tval
.tv_sec
> 0 || tval
.tv_nsec
> 0));
873 unsigned int tdiff
=0;
874 struct timeval tval
,t1
,t2
;
881 tval
.tv_sec
= (t
-tdiff
)/1000;
882 tval
.tv_usec
= 1000*((t
-tdiff
)%1000);
884 /* Never wait for more than 1 sec. */
885 if (tval
.tv_sec
> 1) {
892 sys_select_intr(0,&fds
,NULL
,NULL
,&tval
);
895 if (t2
.tv_sec
< t1
.tv_sec
) {
896 /* Someone adjusted time... */
900 tdiff
= TvalDiff(&t1
,&t2
);
905 NTSTATUS
reinit_after_fork(struct messaging_context
*msg_ctx
,
906 struct event_context
*ev_ctx
,
907 bool parent_longlived
)
909 NTSTATUS status
= NT_STATUS_OK
;
911 /* Reset the state of the random
912 * number generation system, so
913 * children do not get the same random
914 * numbers as each other */
915 set_need_random_reseed();
917 /* tdb needs special fork handling */
918 if (tdb_reopen_all(parent_longlived
? 1 : 0) == -1) {
919 DEBUG(0,("tdb_reopen_all failed.\n"));
920 status
= NT_STATUS_OPEN_FAILED
;
925 event_context_reinit(ev_ctx
);
930 * For clustering, we need to re-init our ctdbd connection after the
933 status
= messaging_reinit(msg_ctx
);
934 if (!NT_STATUS_IS_OK(status
)) {
935 DEBUG(0,("messaging_reinit() failed: %s\n",
943 /****************************************************************************
944 Put up a yes/no prompt.
945 ****************************************************************************/
947 bool yesno(const char *p
)
952 if (!fgets(ans
,sizeof(ans
)-1,stdin
))
955 if (*ans
== 'y' || *ans
== 'Y')
961 #if defined(PARANOID_MALLOC_CHECKER)
963 /****************************************************************************
964 Internal malloc wrapper. Externally visible.
965 ****************************************************************************/
967 void *malloc_(size_t size
)
974 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
977 /****************************************************************************
978 Internal calloc wrapper. Not externally visible.
979 ****************************************************************************/
981 static void *calloc_(size_t count
, size_t size
)
983 if (size
== 0 || count
== 0) {
987 return calloc(count
, size
);
988 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
991 /****************************************************************************
992 Internal realloc wrapper. Not externally visible.
993 ****************************************************************************/
995 static void *realloc_(void *ptr
, size_t size
)
998 return realloc(ptr
, size
);
999 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
1002 #endif /* PARANOID_MALLOC_CHECKER */
1004 /****************************************************************************
1006 ****************************************************************************/
1008 void *memalign_array(size_t el_size
, size_t align
, unsigned int count
)
1010 if (count
>= MAX_ALLOC_SIZE
/el_size
) {
1014 return sys_memalign(align
, el_size
*count
);
1017 /****************************************************************************
1019 ****************************************************************************/
1021 void *calloc_array(size_t size
, size_t nmemb
)
1023 if (nmemb
>= MAX_ALLOC_SIZE
/size
) {
1026 if (size
== 0 || nmemb
== 0) {
1029 #if defined(PARANOID_MALLOC_CHECKER)
1030 return calloc_(nmemb
, size
);
1032 return calloc(nmemb
, size
);
1036 /****************************************************************************
1037 Expand a pointer to be a particular size.
1038 Note that this version of Realloc has an extra parameter that decides
1039 whether to free the passed in storage on allocation failure or if the
1042 This is designed for use in the typical idiom of :
1044 p = SMB_REALLOC(p, size)
1049 and not to have to keep track of the old 'p' contents to free later, nor
1050 to worry if the size parameter was zero. In the case where NULL is returned
1051 we guarentee that p has been freed.
1053 If free later semantics are desired, then pass 'free_old_on_error' as False which
1054 guarentees that the old contents are not freed on error, even if size == 0. To use
1057 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
1065 Changes were instigated by Coverity error checking. JRA.
1066 ****************************************************************************/
1068 void *Realloc(void *p
, size_t size
, bool free_old_on_error
)
1073 if (free_old_on_error
) {
1076 DEBUG(2,("Realloc asked for 0 bytes\n"));
1080 #if defined(PARANOID_MALLOC_CHECKER)
1082 ret
= (void *)malloc_(size
);
1084 ret
= (void *)realloc_(p
,size
);
1088 ret
= (void *)malloc(size
);
1090 ret
= (void *)realloc(p
,size
);
1095 if (free_old_on_error
&& p
) {
1098 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size
));
1104 /****************************************************************************
1105 (Hopefully) efficient array append.
1106 ****************************************************************************/
1108 void add_to_large_array(TALLOC_CTX
*mem_ctx
, size_t element_size
,
1109 void *element
, void *_array
, uint32
*num_elements
,
1110 ssize_t
*array_size
)
1112 void **array
= (void **)_array
;
1114 if (*array_size
< 0) {
1118 if (*array
== NULL
) {
1119 if (*array_size
== 0) {
1123 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
1127 *array
= TALLOC(mem_ctx
, element_size
* (*array_size
));
1128 if (*array
== NULL
) {
1133 if (*num_elements
== *array_size
) {
1136 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
1140 *array
= TALLOC_REALLOC(mem_ctx
, *array
,
1141 element_size
* (*array_size
));
1143 if (*array
== NULL
) {
1148 memcpy((char *)(*array
) + element_size
*(*num_elements
),
1149 element
, element_size
);
1159 /****************************************************************************
1160 Get my own domain name, or "" if we have none.
1161 ****************************************************************************/
1163 char *get_mydnsdomname(TALLOC_CTX
*ctx
)
1165 const char *domname
;
1168 domname
= get_mydnsfullname();
1173 p
= strchr_m(domname
, '.');
1176 return talloc_strdup(ctx
, p
);
1178 return talloc_strdup(ctx
, "");
1182 /****************************************************************************
1183 Interpret a protocol description string, with a default.
1184 ****************************************************************************/
1186 int interpret_protocol(const char *str
,int def
)
1188 if (strequal(str
,"NT1"))
1189 return(PROTOCOL_NT1
);
1190 if (strequal(str
,"LANMAN2"))
1191 return(PROTOCOL_LANMAN2
);
1192 if (strequal(str
,"LANMAN1"))
1193 return(PROTOCOL_LANMAN1
);
1194 if (strequal(str
,"CORE"))
1195 return(PROTOCOL_CORE
);
1196 if (strequal(str
,"COREPLUS"))
1197 return(PROTOCOL_COREPLUS
);
1198 if (strequal(str
,"CORE+"))
1199 return(PROTOCOL_COREPLUS
);
1201 DEBUG(0,("Unrecognised protocol level %s\n",str
));
1207 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1208 /******************************************************************
1209 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1210 Based on a fix from <Thomas.Hepper@icem.de>.
1211 Returns a malloc'ed string.
1212 *******************************************************************/
1214 static char *strip_mount_options(TALLOC_CTX
*ctx
, const char *str
)
1217 const char *p
= str
;
1218 while(*p
&& !isspace(*p
))
1220 while(*p
&& isspace(*p
))
1223 return talloc_strdup(ctx
, p
);
1229 /*******************************************************************
1230 Patch from jkf@soton.ac.uk
1231 Split Luke's automount_server into YP lookup and string splitter
1232 so can easily implement automount_path().
1233 Returns a malloc'ed string.
1234 *******************************************************************/
1236 #ifdef WITH_NISPLUS_HOME
1237 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
1241 char *nis_map
= (char *)lp_nis_home_map_name();
1243 char buffer
[NIS_MAXATTRVAL
+ 1];
1248 snprintf(buffer
, sizeof(buffer
), "[key=%s],%s", user_name
, nis_map
);
1249 DEBUG(5, ("NIS+ querystring: %s\n", buffer
));
1251 if (result
= nis_list(buffer
, FOLLOW_PATH
|EXPAND_NAME
|HARD_LOOKUP
, NULL
, NULL
)) {
1252 if (result
->status
!= NIS_SUCCESS
) {
1253 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result
->status
)));
1255 object
= result
->objects
.objects_val
;
1256 if (object
->zo_data
.zo_type
== ENTRY_OBJ
) {
1257 entry
= &object
->zo_data
.objdata_u
.en_data
;
1258 DEBUG(5, ("NIS+ entry type: %s\n", entry
->en_type
));
1259 DEBUG(3, ("NIS+ result: %s\n", entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
));
1261 value
= talloc_strdup(ctx
,
1262 entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
);
1264 nis_freeresult(result
);
1267 value
= talloc_string_sub(ctx
,
1274 nis_freeresult(result
);
1277 value
= strip_mount_options(ctx
, value
);
1278 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
1283 #else /* WITH_NISPLUS_HOME */
1285 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
1289 int nis_error
; /* returned by yp all functions */
1290 char *nis_result
; /* yp_match inits this */
1291 int nis_result_len
; /* and set this */
1292 char *nis_domain
; /* yp_get_default_domain inits this */
1293 char *nis_map
= (char *)lp_nis_home_map_name();
1295 if ((nis_error
= yp_get_default_domain(&nis_domain
)) != 0) {
1296 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error
)));
1300 DEBUG(5, ("NIS Domain: %s\n", nis_domain
));
1302 if ((nis_error
= yp_match(nis_domain
, nis_map
, user_name
,
1303 strlen(user_name
), &nis_result
,
1304 &nis_result_len
)) == 0) {
1305 value
= talloc_strdup(ctx
, nis_result
);
1309 value
= strip_mount_options(ctx
, value
);
1310 } else if(nis_error
== YPERR_KEY
) {
1311 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1312 user_name
, nis_map
));
1313 DEBUG(3, ("using defaults for server and home directory\n"));
1315 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1316 yperr_string(nis_error
), user_name
, nis_map
));
1320 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name
, value
));
1324 #endif /* WITH_NISPLUS_HOME */
1327 /****************************************************************************
1328 Check if a process exists. Does this work on all unixes?
1329 ****************************************************************************/
1331 bool process_exists(const struct server_id pid
)
1333 if (procid_is_me(&pid
)) {
1337 if (procid_is_local(&pid
)) {
1338 return (kill(pid
.pid
,0) == 0 || errno
!= ESRCH
);
1341 #ifdef CLUSTER_SUPPORT
1342 return ctdbd_process_exists(messaging_ctdbd_connection(), pid
.vnn
,
1349 /*******************************************************************
1350 Convert a uid into a user name.
1351 ********************************************************************/
1353 const char *uidtoname(uid_t uid
)
1355 TALLOC_CTX
*ctx
= talloc_tos();
1357 struct passwd
*pass
= NULL
;
1359 pass
= getpwuid_alloc(ctx
,uid
);
1361 name
= talloc_strdup(ctx
,pass
->pw_name
);
1364 name
= talloc_asprintf(ctx
,
1371 /*******************************************************************
1372 Convert a gid into a group name.
1373 ********************************************************************/
1375 char *gidtoname(gid_t gid
)
1379 grp
= getgrgid(gid
);
1381 return talloc_strdup(talloc_tos(), grp
->gr_name
);
1384 return talloc_asprintf(talloc_tos(),
1390 /*******************************************************************
1391 Convert a user name into a uid.
1392 ********************************************************************/
1394 uid_t
nametouid(const char *name
)
1396 struct passwd
*pass
;
1400 pass
= getpwnam_alloc(talloc_autofree_context(), name
);
1407 u
= (uid_t
)strtol(name
, &p
, 0);
1408 if ((p
!= name
) && (*p
== '\0'))
1414 /*******************************************************************
1415 Convert a name to a gid_t if possible. Return -1 if not a group.
1416 ********************************************************************/
1418 gid_t
nametogid(const char *name
)
1424 g
= (gid_t
)strtol(name
, &p
, 0);
1425 if ((p
!= name
) && (*p
== '\0'))
1428 grp
= sys_getgrnam(name
);
1430 return(grp
->gr_gid
);
1434 /*******************************************************************
1435 Something really nasty happened - panic !
1436 ********************************************************************/
1438 void smb_panic(const char *const why
)
1446 if (global_clobber_region_function
) {
1447 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1448 global_clobber_region_function
,
1449 global_clobber_region_line
));
1454 DEBUG(0,("PANIC (pid %llu): %s\n",
1455 (unsigned long long)sys_getpid(), why
));
1458 cmd
= lp_panic_action();
1460 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd
));
1461 result
= system(cmd
);
1464 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1467 DEBUG(0, ("smb_panic(): action returned status %d\n",
1468 WEXITSTATUS(result
)));
1474 /*******************************************************************
1475 Print a backtrace of the stack to the debug log. This function
1476 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1477 exit shortly after calling it.
1478 ********************************************************************/
1480 #ifdef HAVE_LIBUNWIND_H
1481 #include <libunwind.h>
1484 #ifdef HAVE_EXECINFO_H
1485 #include <execinfo.h>
1488 #ifdef HAVE_LIBEXC_H
1492 void log_stack_trace(void)
1494 #ifdef HAVE_LIBUNWIND
1495 /* Try to use libunwind before any other technique since on ia64
1496 * libunwind correctly walks the stack in more circumstances than
1499 unw_cursor_t cursor
;
1504 unw_word_t ip
, sp
, off
;
1506 procname
[sizeof(procname
) - 1] = '\0';
1508 if (unw_getcontext(&uc
) != 0) {
1509 goto libunwind_failed
;
1512 if (unw_init_local(&cursor
, &uc
) != 0) {
1513 goto libunwind_failed
;
1516 DEBUG(0, ("BACKTRACE:\n"));
1520 unw_get_reg(&cursor
, UNW_REG_IP
, &ip
);
1521 unw_get_reg(&cursor
, UNW_REG_SP
, &sp
);
1523 switch (unw_get_proc_name(&cursor
,
1524 procname
, sizeof(procname
) - 1, &off
) ) {
1528 /* Name truncated. */
1529 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1530 i
, procname
, (long long)off
,
1531 (long long)ip
, (long long) sp
));
1534 /* case -UNW_ENOINFO: */
1535 /* case -UNW_EUNSPEC: */
1536 /* No symbol name found. */
1537 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1538 i
, "<unknown symbol>",
1539 (long long)ip
, (long long) sp
));
1542 } while (unw_step(&cursor
) > 0);
1547 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1549 #elif HAVE_BACKTRACE_SYMBOLS
1550 void *backtrace_stack
[BACKTRACE_STACK_SIZE
];
1551 size_t backtrace_size
;
1552 char **backtrace_strings
;
1554 /* get the backtrace (stack frames) */
1555 backtrace_size
= backtrace(backtrace_stack
,BACKTRACE_STACK_SIZE
);
1556 backtrace_strings
= backtrace_symbols(backtrace_stack
, backtrace_size
);
1558 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1559 (unsigned long)backtrace_size
));
1561 if (backtrace_strings
) {
1564 for (i
= 0; i
< backtrace_size
; i
++)
1565 DEBUGADD(0, (" #%u %s\n", i
, backtrace_strings
[i
]));
1567 /* Leak the backtrace_strings, rather than risk what free() might do */
1572 /* The IRIX libexc library provides an API for unwinding the stack. See
1573 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1574 * since we are about to abort anyway, it hardly matters.
1577 #define NAMESIZE 32 /* Arbitrary */
1579 __uint64_t addrs
[BACKTRACE_STACK_SIZE
];
1580 char * names
[BACKTRACE_STACK_SIZE
];
1581 char namebuf
[BACKTRACE_STACK_SIZE
* NAMESIZE
];
1588 ZERO_ARRAY(namebuf
);
1590 /* We need to be root so we can open our /proc entry to walk
1591 * our stack. It also helps when we want to dump core.
1595 for (i
= 0; i
< BACKTRACE_STACK_SIZE
; i
++) {
1596 names
[i
] = namebuf
+ (i
* NAMESIZE
);
1599 levels
= trace_back_stack(0, addrs
, names
,
1600 BACKTRACE_STACK_SIZE
, NAMESIZE
- 1);
1602 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels
));
1603 for (i
= 0; i
< levels
; i
++) {
1604 DEBUGADD(0, (" #%d 0x%llx %s\n", i
, addrs
[i
], names
[i
]));
1609 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1613 /*******************************************************************
1614 A readdir wrapper which just returns the file name.
1615 ********************************************************************/
1617 const char *readdirname(SMB_STRUCT_DIR
*p
)
1619 SMB_STRUCT_DIRENT
*ptr
;
1625 ptr
= (SMB_STRUCT_DIRENT
*)sys_readdir(p
);
1629 dname
= ptr
->d_name
;
1636 #ifdef HAVE_BROKEN_READDIR_NAME
1637 /* using /usr/ucb/cc is BAD */
1641 return talloc_strdup(talloc_tos(), dname
);
1644 /*******************************************************************
1645 Utility function used to decide if the last component
1646 of a path matches a (possibly wildcarded) entry in a namelist.
1647 ********************************************************************/
1649 bool is_in_path(const char *name
, name_compare_entry
*namelist
, bool case_sensitive
)
1651 const char *last_component
;
1653 /* if we have no list it's obviously not in the path */
1654 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
))) {
1658 DEBUG(8, ("is_in_path: %s\n", name
));
1660 /* Get the last component of the unix name. */
1661 last_component
= strrchr_m(name
, '/');
1662 if (!last_component
) {
1663 last_component
= name
;
1665 last_component
++; /* Go past '/' */
1668 for(; namelist
->name
!= NULL
; namelist
++) {
1669 if(namelist
->is_wild
) {
1670 if (mask_match(last_component
, namelist
->name
, case_sensitive
)) {
1671 DEBUG(8,("is_in_path: mask match succeeded\n"));
1675 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
1676 (!case_sensitive
&& (StrCaseCmp(last_component
, namelist
->name
) == 0))) {
1677 DEBUG(8,("is_in_path: match succeeded\n"));
1682 DEBUG(8,("is_in_path: match not found\n"));
1686 /*******************************************************************
1687 Strip a '/' separated list into an array of
1688 name_compare_enties structures suitable for
1689 passing to is_in_path(). We do this for
1690 speed so we can pre-parse all the names in the list
1691 and don't do it for each call to is_in_path().
1692 namelist is modified here and is assumed to be
1693 a copy owned by the caller.
1694 We also check if the entry contains a wildcard to
1695 remove a potentially expensive call to mask_match
1697 ********************************************************************/
1699 void set_namearray(name_compare_entry
**ppname_array
, const char *namelist
)
1702 char *nameptr
= (char *)namelist
;
1703 int num_entries
= 0;
1706 (*ppname_array
) = NULL
;
1708 if((nameptr
== NULL
) || ((nameptr
!= NULL
) && (*nameptr
== '\0')))
1711 /* We need to make two passes over the string. The
1712 first to count the number of elements, the second
1717 if ( *nameptr
== '/' ) {
1718 /* cope with multiple (useless) /s) */
1722 /* anything left? */
1723 if ( *nameptr
== '\0' )
1726 /* find the next '/' or consume remaining */
1727 name_end
= strchr_m(nameptr
, '/');
1728 if (name_end
== NULL
)
1729 name_end
= (char *)nameptr
+ strlen(nameptr
);
1731 /* next segment please */
1732 nameptr
= name_end
+ 1;
1736 if(num_entries
== 0)
1739 if(( (*ppname_array
) = SMB_MALLOC_ARRAY(name_compare_entry
, num_entries
+ 1)) == NULL
) {
1740 DEBUG(0,("set_namearray: malloc fail\n"));
1744 /* Now copy out the names */
1745 nameptr
= (char *)namelist
;
1748 if ( *nameptr
== '/' ) {
1749 /* cope with multiple (useless) /s) */
1753 /* anything left? */
1754 if ( *nameptr
== '\0' )
1757 /* find the next '/' or consume remaining */
1758 name_end
= strchr_m(nameptr
, '/');
1762 name_end
= nameptr
+ strlen(nameptr
);
1764 (*ppname_array
)[i
].is_wild
= ms_has_wild(nameptr
);
1765 if(((*ppname_array
)[i
].name
= SMB_STRDUP(nameptr
)) == NULL
) {
1766 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1770 /* next segment please */
1771 nameptr
= name_end
+ 1;
1775 (*ppname_array
)[i
].name
= NULL
;
1780 /****************************************************************************
1781 Routine to free a namearray.
1782 ****************************************************************************/
1784 void free_namearray(name_compare_entry
*name_array
)
1788 if(name_array
== NULL
)
1791 for(i
=0; name_array
[i
].name
!=NULL
; i
++)
1792 SAFE_FREE(name_array
[i
].name
);
1793 SAFE_FREE(name_array
);
1797 #define DBGC_CLASS DBGC_LOCKING
1799 /****************************************************************************
1800 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1801 is dealt with in posix.c
1802 Returns True if we have information regarding this lock region (and returns
1803 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1804 ****************************************************************************/
1806 bool fcntl_getlock(int fd
, SMB_OFF_T
*poffset
, SMB_OFF_T
*pcount
, int *ptype
, pid_t
*ppid
)
1808 SMB_STRUCT_FLOCK lock
;
1811 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1812 fd
,(double)*poffset
,(double)*pcount
,*ptype
));
1814 lock
.l_type
= *ptype
;
1815 lock
.l_whence
= SEEK_SET
;
1816 lock
.l_start
= *poffset
;
1817 lock
.l_len
= *pcount
;
1820 ret
= sys_fcntl_ptr(fd
,SMB_F_GETLK
,&lock
);
1824 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1825 (double)*poffset
,(double)*pcount
,*ptype
,strerror(errno
)));
1830 *ptype
= lock
.l_type
;
1831 *poffset
= lock
.l_start
;
1832 *pcount
= lock
.l_len
;
1835 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1836 fd
, (int)lock
.l_type
, (unsigned int)lock
.l_pid
));
1841 #define DBGC_CLASS DBGC_ALL
1843 /*******************************************************************
1844 Is the name specified one of my netbios names.
1845 Returns true if it is equal, false otherwise.
1846 ********************************************************************/
1848 bool is_myname(const char *s
)
1853 for (n
=0; my_netbios_names(n
); n
++) {
1854 if (strequal(my_netbios_names(n
), s
)) {
1859 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));
1863 /*******************************************************************
1864 Is the name specified our workgroup/domain.
1865 Returns true if it is equal, false otherwise.
1866 ********************************************************************/
1868 bool is_myworkgroup(const char *s
)
1872 if (strequal(s
, lp_workgroup())) {
1876 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s
, ret
));
1880 /*******************************************************************
1881 we distinguish between 2K and XP by the "Native Lan Manager" string
1882 WinXP => "Windows 2002 5.1"
1883 WinXP 64bit => "Windows XP 5.2"
1884 Win2k => "Windows 2000 5.0"
1885 NT4 => "Windows NT 4.0"
1886 Win9x => "Windows 4.0"
1887 Windows 2003 doesn't set the native lan manager string but
1888 they do set the domain to "Windows 2003 5.2" (probably a bug).
1889 ********************************************************************/
1891 void ra_lanman_string( const char *native_lanman
)
1893 if ( strcmp( native_lanman
, "Windows 2002 5.1" ) == 0 )
1894 set_remote_arch( RA_WINXP
);
1895 else if ( strcmp( native_lanman
, "Windows XP 5.2" ) == 0 )
1896 set_remote_arch( RA_WINXP64
);
1897 else if ( strcmp( native_lanman
, "Windows Server 2003 5.2" ) == 0 )
1898 set_remote_arch( RA_WIN2K3
);
1901 static const char *remote_arch_str
;
1903 const char *get_remote_arch_str(void)
1905 if (!remote_arch_str
) {
1908 return remote_arch_str
;
1911 /*******************************************************************
1912 Set the horrid remote_arch string based on an enum.
1913 ********************************************************************/
1915 void set_remote_arch(enum remote_arch_types type
)
1920 remote_arch_str
= "WfWg";
1923 remote_arch_str
= "OS2";
1926 remote_arch_str
= "Win95";
1929 remote_arch_str
= "WinNT";
1932 remote_arch_str
= "Win2K";
1935 remote_arch_str
= "WinXP";
1938 remote_arch_str
= "WinXP64";
1941 remote_arch_str
= "Win2K3";
1944 remote_arch_str
= "Vista";
1947 remote_arch_str
= "Samba";
1950 remote_arch_str
= "CIFSFS";
1953 ra_type
= RA_UNKNOWN
;
1954 remote_arch_str
= "UNKNOWN";
1958 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1962 /*******************************************************************
1963 Get the remote_arch type.
1964 ********************************************************************/
1966 enum remote_arch_types
get_remote_arch(void)
1971 const char *tab_depth(int level
, int depth
)
1973 if( CHECK_DEBUGLVL(level
) ) {
1974 dbgtext("%*s", depth
*4, "");
1979 /*****************************************************************************
1980 Provide a checksum on a string
1982 Input: s - the null-terminated character string for which the checksum
1985 Output: The checksum value calculated for s.
1986 *****************************************************************************/
1988 int str_checksum(const char *s
)
1996 res
^= (c
<< (i
% 15)) ^ (c
>> (15-(i
%15)));
2003 /*****************************************************************
2004 Zero a memory area then free it. Used to catch bugs faster.
2005 *****************************************************************/
2007 void zero_free(void *p
, size_t size
)
2013 /*****************************************************************
2014 Set our open file limit to a requested max and return the limit.
2015 *****************************************************************/
2017 int set_maxfiles(int requested_max
)
2019 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2021 int saved_current_limit
;
2023 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
2024 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2027 return requested_max
;
2031 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2032 * account for the extra fd we need
2033 * as well as the log files and standard
2034 * handles etc. Save the limit we want to set in case
2035 * we are running on an OS that doesn't support this limit (AIX)
2036 * which always returns RLIM_INFINITY for rlp.rlim_max.
2039 /* Try raising the hard (max) limit to the requested amount. */
2041 #if defined(RLIM_INFINITY)
2042 if (rlp
.rlim_max
!= RLIM_INFINITY
) {
2043 int orig_max
= rlp
.rlim_max
;
2045 if ( rlp
.rlim_max
< requested_max
)
2046 rlp
.rlim_max
= requested_max
;
2048 /* This failing is not an error - many systems (Linux) don't
2049 support our default request of 10,000 open files. JRA. */
2051 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
2052 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2053 (int)rlp
.rlim_max
, strerror(errno
) ));
2055 /* Set failed - restore original value from get. */
2056 rlp
.rlim_max
= orig_max
;
2061 /* Now try setting the soft (current) limit. */
2063 saved_current_limit
= rlp
.rlim_cur
= MIN(requested_max
,rlp
.rlim_max
);
2065 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
2066 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2067 (int)rlp
.rlim_cur
, strerror(errno
) ));
2069 return saved_current_limit
;
2072 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
2073 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2076 return saved_current_limit
;
2079 #if defined(RLIM_INFINITY)
2080 if(rlp
.rlim_cur
== RLIM_INFINITY
)
2081 return saved_current_limit
;
2084 if((int)rlp
.rlim_cur
> saved_current_limit
)
2085 return saved_current_limit
;
2087 return rlp
.rlim_cur
;
2088 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2090 * No way to know - just guess...
2092 return requested_max
;
2096 /*****************************************************************
2097 malloc that aborts with smb_panic on fail or zero size.
2098 *****************************************************************/
2100 void *smb_xmalloc_array(size_t size
, unsigned int count
)
2104 smb_panic("smb_xmalloc_array: called with zero size");
2106 if (count
>= MAX_ALLOC_SIZE
/size
) {
2107 smb_panic("smb_xmalloc_array: alloc size too large");
2109 if ((p
= SMB_MALLOC(size
*count
)) == NULL
) {
2110 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2111 (unsigned long)size
, (unsigned long)count
));
2112 smb_panic("smb_xmalloc_array: malloc failed");
2118 vasprintf that aborts on malloc fail
2121 int smb_xvasprintf(char **ptr
, const char *format
, va_list ap
)
2128 n
= vasprintf(ptr
, format
, ap2
);
2130 if (n
== -1 || ! *ptr
) {
2131 smb_panic("smb_xvasprintf: out of memory");
2136 /*****************************************************************
2137 Get local hostname and cache result.
2138 *****************************************************************/
2140 char *myhostname(void)
2144 /* This is cached forever so
2145 * use talloc_autofree_context() ctx. */
2146 ret
= get_myname(talloc_autofree_context());
2152 * @brief Returns an absolute path to a file concatenating the provided
2153 * @a rootpath and @a basename
2155 * @param name Filename, relative to @a rootpath
2157 * @retval Pointer to a string containing the full path.
2160 static char *xx_path(const char *name
, const char *rootpath
)
2164 fname
= talloc_strdup(talloc_tos(), rootpath
);
2168 trim_string(fname
,"","/");
2170 if (!directory_exist(fname
)) {
2171 if (!mkdir(fname
,0755))
2172 DEBUG(1, ("Unable to create directory %s for file %s. "
2173 "Error was %s\n", fname
, name
, strerror(errno
)));
2176 return talloc_asprintf(talloc_tos(),
2183 * @brief Returns an absolute path to a file in the Samba lock directory.
2185 * @param name File to find, relative to LOCKDIR.
2187 * @retval Pointer to a talloc'ed string containing the full path.
2190 char *lock_path(const char *name
)
2192 return xx_path(name
, lp_lockdir());
2196 * @brief Returns an absolute path to a file in the Samba pid directory.
2198 * @param name File to find, relative to PIDDIR.
2200 * @retval Pointer to a talloc'ed string containing the full path.
2203 char *pid_path(const char *name
)
2205 return xx_path(name
, lp_piddir());
2209 * @brief Returns an absolute path to a file in the Samba lib directory.
2211 * @param name File to find, relative to LIBDIR.
2213 * @retval Pointer to a string containing the full path.
2216 char *lib_path(const char *name
)
2218 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name
);
2222 * @brief Returns an absolute path to a file in the Samba modules directory.
2224 * @param name File to find, relative to MODULESDIR.
2226 * @retval Pointer to a string containing the full path.
2229 char *modules_path(const char *name
)
2231 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_MODULESDIR(), name
);
2235 * @brief Returns an absolute path to a file in the Samba data directory.
2237 * @param name File to find, relative to CODEPAGEDIR.
2239 * @retval Pointer to a talloc'ed string containing the full path.
2242 char *data_path(const char *name
)
2244 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name
);
2248 * @brief Returns an absolute path to a file in the Samba state directory.
2250 * @param name File to find, relative to STATEDIR.
2252 * @retval Pointer to a talloc'ed string containing the full path.
2255 char *state_path(const char *name
)
2257 return xx_path(name
, lp_statedir());
2261 * @brief Returns an absolute path to a file in the Samba cache directory.
2263 * @param name File to find, relative to CACHEDIR.
2265 * @retval Pointer to a talloc'ed string containing the full path.
2268 char *cache_path(const char *name
)
2270 return xx_path(name
, lp_cachedir());
2274 * @brief Returns the platform specific shared library extension.
2276 * @retval Pointer to a const char * containing the extension.
2279 const char *shlib_ext(void)
2281 return get_dyn_SHLIBEXT();
2284 /*******************************************************************
2285 Given a filename - get its directory name
2286 ********************************************************************/
2288 bool parent_dirname(TALLOC_CTX
*mem_ctx
, const char *dir
, char **parent
,
2294 p
= strrchr_m(dir
, '/'); /* Find final '/', if any */
2297 if (!(*parent
= talloc_strdup(mem_ctx
, "."))) {
2308 if (!(*parent
= (char *)TALLOC_MEMDUP(mem_ctx
, dir
, len
+1))) {
2311 (*parent
)[len
] = '\0';
2319 /*******************************************************************
2320 Determine if a pattern contains any Microsoft wildcard characters.
2321 *******************************************************************/
2323 bool ms_has_wild(const char *s
)
2327 if (lp_posix_pathnames()) {
2328 /* With posix pathnames no characters are wild. */
2332 while ((c
= *s
++)) {
2345 bool ms_has_wild_w(const smb_ucs2_t
*s
)
2348 if (!s
) return False
;
2349 while ((c
= *s
++)) {
2351 case UCS2_CHAR('*'):
2352 case UCS2_CHAR('?'):
2353 case UCS2_CHAR('<'):
2354 case UCS2_CHAR('>'):
2355 case UCS2_CHAR('"'):
2362 /*******************************************************************
2363 A wrapper that handles case sensitivity and the special handling
2365 *******************************************************************/
2367 bool mask_match(const char *string
, const char *pattern
, bool is_case_sensitive
)
2369 if (ISDOTDOT(string
))
2374 return ms_fnmatch(pattern
, string
, Protocol
<= PROTOCOL_LANMAN2
, is_case_sensitive
) == 0;
2377 /*******************************************************************
2378 A wrapper that handles case sensitivity and the special handling
2379 of the ".." name. Varient that is only called by old search code which requires
2380 pattern translation.
2381 *******************************************************************/
2383 bool mask_match_search(const char *string
, const char *pattern
, bool is_case_sensitive
)
2385 if (ISDOTDOT(string
))
2390 return ms_fnmatch(pattern
, string
, True
, is_case_sensitive
) == 0;
2393 /*******************************************************************
2394 A wrapper that handles a list of patters and calls mask_match()
2395 on each. Returns True if any of the patterns match.
2396 *******************************************************************/
2398 bool mask_match_list(const char *string
, char **list
, int listLen
, bool is_case_sensitive
)
2400 while (listLen
-- > 0) {
2401 if (mask_match(string
, *list
++, is_case_sensitive
))
2407 /*********************************************************
2408 Recursive routine that is called by unix_wild_match.
2409 *********************************************************/
2411 static bool unix_do_match(const char *regexp
, const char *str
)
2415 for( p
= regexp
; *p
&& *str
; ) {
2426 * Look for a character matching
2427 * the one after the '*'.
2431 return true; /* Automatic match */
2434 while(*str
&& (*p
!= *str
))
2438 * Patch from weidel@multichart.de. In the case of the regexp
2439 * '*XX*' we want to ensure there are at least 2 'X' characters
2440 * in the string after the '*' for a match to be made.
2447 * Eat all the characters that match, but count how many there were.
2450 while(*str
&& (*p
== *str
)) {
2456 * Now check that if the regexp had n identical characters that
2457 * matchcount had at least that many matches.
2460 while ( *(p
+1) && (*(p
+1) == *p
)) {
2465 if ( matchcount
<= 0 )
2469 str
--; /* We've eaten the match char after the '*' */
2471 if(unix_do_match(p
, str
))
2493 if (!*p
&& str
[0] == '.' && str
[1] == 0)
2496 if (!*str
&& *p
== '?') {
2502 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
2508 /*******************************************************************
2509 Simple case insensitive interface to a UNIX wildcard matcher.
2510 Returns True if match, False if not.
2511 *******************************************************************/
2513 bool unix_wild_match(const char *pattern
, const char *string
)
2515 TALLOC_CTX
*ctx
= talloc_stackframe();
2521 p2
= talloc_strdup(ctx
,pattern
);
2522 s2
= talloc_strdup(ctx
,string
);
2530 /* Remove any *? and ** from the pattern as they are meaningless */
2531 for(p
= p2
; *p
; p
++) {
2532 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*')) {
2533 memmove(&p
[1], &p
[2], strlen(&p
[2])+1);
2537 if (strequal(p2
,"*")) {
2542 ret
= unix_do_match(p2
, s2
);
2547 /**********************************************************************
2548 Converts a name to a fully qualified domain name.
2549 Returns true if lookup succeeded, false if not (then fqdn is set to name)
2550 Note we deliberately use gethostbyname here, not getaddrinfo as we want
2551 to examine the h_aliases and I don't know how to do that with getaddrinfo.
2552 ***********************************************************************/
2554 bool name_to_fqdn(fstring fqdn
, const char *name
)
2557 struct hostent
*hp
= gethostbyname(name
);
2559 if (!hp
|| !hp
->h_name
|| !*hp
->h_name
) {
2560 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name
));
2561 fstrcpy(fqdn
, name
);
2565 /* Find out if the fqdn is returned as an alias
2566 * to cope with /etc/hosts files where the first
2567 * name is not the fqdn but the short name */
2568 if (hp
->h_aliases
&& (! strchr_m(hp
->h_name
, '.'))) {
2570 for (i
= 0; hp
->h_aliases
[i
]; i
++) {
2571 if (strchr_m(hp
->h_aliases
[i
], '.')) {
2572 full
= hp
->h_aliases
[i
];
2577 if (full
&& (StrCaseCmp(full
, "localhost.localdomain") == 0)) {
2578 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2579 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2580 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
2581 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
2588 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name
, full
));
2589 fstrcpy(fqdn
, full
);
2593 /**********************************************************************
2594 Append a DATA_BLOB to a talloc'ed object
2595 ***********************************************************************/
2597 void *talloc_append_blob(TALLOC_CTX
*mem_ctx
, void *buf
, DATA_BLOB blob
)
2599 size_t old_size
= 0;
2602 if (blob
.length
== 0) {
2607 old_size
= talloc_get_size(buf
);
2610 result
= (char *)TALLOC_REALLOC(mem_ctx
, buf
, old_size
+ blob
.length
);
2611 if (result
== NULL
) {
2615 memcpy(result
+ old_size
, blob
.data
, blob
.length
);
2619 uint32
map_share_mode_to_deny_mode(uint32 share_access
, uint32 private_options
)
2621 switch (share_access
& ~FILE_SHARE_DELETE
) {
2622 case FILE_SHARE_NONE
:
2624 case FILE_SHARE_READ
:
2626 case FILE_SHARE_WRITE
:
2628 case FILE_SHARE_READ
|FILE_SHARE_WRITE
:
2631 if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) {
2633 } else if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
) {
2640 pid_t
procid_to_pid(const struct server_id
*proc
)
2645 static uint32 my_vnn
= NONCLUSTER_VNN
;
2647 void set_my_vnn(uint32 vnn
)
2649 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn
));
2653 uint32
get_my_vnn(void)
2658 struct server_id
pid_to_procid(pid_t pid
)
2660 struct server_id result
;
2662 #ifdef CLUSTER_SUPPORT
2663 result
.vnn
= my_vnn
;
2668 struct server_id
procid_self(void)
2670 return pid_to_procid(sys_getpid());
2673 struct server_id
server_id_self(void)
2675 return procid_self();
2678 bool procid_equal(const struct server_id
*p1
, const struct server_id
*p2
)
2680 if (p1
->pid
!= p2
->pid
)
2682 #ifdef CLUSTER_SUPPORT
2683 if (p1
->vnn
!= p2
->vnn
)
2689 bool cluster_id_equal(const struct server_id
*id1
,
2690 const struct server_id
*id2
)
2692 return procid_equal(id1
, id2
);
2695 bool procid_is_me(const struct server_id
*pid
)
2697 if (pid
->pid
!= sys_getpid())
2699 #ifdef CLUSTER_SUPPORT
2700 if (pid
->vnn
!= my_vnn
)
2706 struct server_id
interpret_pid(const char *pid_string
)
2708 struct server_id result
;
2710 #ifdef CLUSTER_SUPPORT
2712 if (sscanf(pid_string
, "%u:%d", &vnn
, &pid
) == 2) {
2716 else if (sscanf(pid_string
, "%d", &pid
) == 1) {
2717 result
.vnn
= get_my_vnn();
2721 result
.vnn
= NONCLUSTER_VNN
;
2725 if (sscanf(pid_string
, "%d", &pid
) != 1) {
2731 /* Assigning to result.pid may have overflowed
2732 Map negative pid to -1: i.e. error */
2733 if (result
.pid
< 0) {
2739 char *procid_str(TALLOC_CTX
*mem_ctx
, const struct server_id
*pid
)
2741 #ifdef CLUSTER_SUPPORT
2742 if (pid
->vnn
== NONCLUSTER_VNN
) {
2743 return talloc_asprintf(mem_ctx
,
2748 return talloc_asprintf(mem_ctx
,
2754 return talloc_asprintf(mem_ctx
,
2760 char *procid_str_static(const struct server_id
*pid
)
2762 return procid_str(talloc_tos(), pid
);
2765 bool procid_valid(const struct server_id
*pid
)
2767 return (pid
->pid
!= -1);
2770 bool procid_is_local(const struct server_id
*pid
)
2772 #ifdef CLUSTER_SUPPORT
2773 return pid
->vnn
== my_vnn
;
2779 int this_is_smp(void)
2781 #if defined(HAVE_SYSCONF)
2783 #if defined(SYSCONF_SC_NPROC_ONLN)
2784 return (sysconf(_SC_NPROC_ONLN
) > 1) ? 1 : 0;
2785 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
2786 return (sysconf(_SC_NPROCESSORS_ONLN
) > 1) ? 1 : 0;
2796 /****************************************************************
2797 Check if offset/length fit into bufsize. Should probably be
2798 merged with is_offset_safe, but this would require a rewrite
2799 of lanman.c. Later :-)
2800 ****************************************************************/
2802 bool trans_oob(uint32_t bufsize
, uint32_t offset
, uint32_t length
)
2804 if ((offset
+ length
< offset
) || (offset
+ length
< length
)) {
2808 if ((offset
> bufsize
) || (offset
+ length
> bufsize
)) {
2815 /****************************************************************
2816 Check if an offset into a buffer is safe.
2817 If this returns True it's safe to indirect into the byte at
2819 ****************************************************************/
2821 bool is_offset_safe(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2823 const char *end_base
= buf_base
+ buf_len
;
2824 char *end_ptr
= ptr
+ off
;
2826 if (!buf_base
|| !ptr
) {
2830 if (end_base
< buf_base
|| end_ptr
< ptr
) {
2831 return False
; /* wrap. */
2834 if (end_ptr
< end_base
) {
2840 /****************************************************************
2841 Return a safe pointer into a buffer, or NULL.
2842 ****************************************************************/
2844 char *get_safe_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2846 return is_offset_safe(buf_base
, buf_len
, ptr
, off
) ?
2850 /****************************************************************
2851 Return a safe pointer into a string within a buffer, or NULL.
2852 ****************************************************************/
2854 char *get_safe_str_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2856 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
)) {
2859 /* Check if a valid string exists at this offset. */
2860 if (skip_string(buf_base
,buf_len
, ptr
+ off
) == NULL
) {
2866 /****************************************************************
2867 Return an SVAL at a pointer, or failval if beyond the end.
2868 ****************************************************************/
2870 int get_safe_SVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2873 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2876 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+1)) {
2879 return SVAL(ptr
,off
);
2882 /****************************************************************
2883 Return an IVAL at a pointer, or failval if beyond the end.
2884 ****************************************************************/
2886 int get_safe_IVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2889 * Note we use off+3 here, not off+4 as IVAL accesses
2890 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2892 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+3)) {
2895 return IVAL(ptr
,off
);
2898 /****************************************************************
2899 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2900 call (they take care of winbind separator and other winbind specific settings).
2901 ****************************************************************/
2903 void split_domain_user(TALLOC_CTX
*mem_ctx
,
2904 const char *full_name
,
2908 const char *p
= NULL
;
2910 p
= strchr_m(full_name
, '\\');
2913 *domain
= talloc_strndup(mem_ctx
, full_name
,
2914 PTR_DIFF(p
, full_name
));
2915 *user
= talloc_strdup(mem_ctx
, p
+1);
2917 *domain
= talloc_strdup(mem_ctx
, "");
2918 *user
= talloc_strdup(mem_ctx
, full_name
);
2924 Disable these now we have checked all code paths
and ensured
2925 NULL returns on zero request
. JRA
.
2927 /****************************************************************
2928 talloc wrapper functions that guarentee a null pointer return
2930 ****************************************************************/
2932 #ifndef MAX_TALLOC_SIZE
2933 #define MAX_TALLOC_SIZE 0x10000000
2937 * talloc and zero memory.
2938 * - returns NULL if size is zero.
2941 void *_talloc_zero_zeronull(const void *ctx
, size_t size
, const char *name
)
2949 p
= talloc_named_const(ctx
, size
, name
);
2952 memset(p
, '\0', size
);
2959 * memdup with a talloc.
2960 * - returns NULL if size is zero.
2963 void *_talloc_memdup_zeronull(const void *t
, const void *p
, size_t size
, const char *name
)
2971 newp
= talloc_named_const(t
, size
, name
);
2973 memcpy(newp
, p
, size
);
2980 * alloc an array, checking for integer overflow in the array size.
2981 * - returns NULL if count or el_size are zero.
2984 void *_talloc_array_zeronull(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
2986 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
2990 if (el_size
== 0 || count
== 0) {
2994 return talloc_named_const(ctx
, el_size
* count
, name
);
2998 * alloc an zero array, checking for integer overflow in the array size
2999 * - returns NULL if count or el_size are zero.
3002 void *_talloc_zero_array_zeronull(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
3004 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
3008 if (el_size
== 0 || count
== 0) {
3012 return _talloc_zero(ctx
, el_size
* count
, name
);
3016 * Talloc wrapper that returns NULL if size == 0.
3018 void *talloc_zeronull(const void *context
, size_t size
, const char *name
)
3023 return talloc_named_const(context
, size
, name
);
3027 bool is_valid_policy_hnd(const struct policy_handle
*hnd
)
3029 struct policy_handle tmp
;
3031 return (memcmp(&tmp
, hnd
, sizeof(tmp
)) != 0);
3034 bool policy_hnd_equal(const struct policy_handle
*hnd1
,
3035 const struct policy_handle
*hnd2
)
3037 if (!hnd1
|| !hnd2
) {
3041 return (memcmp(hnd1
, hnd2
, sizeof(*hnd1
)) == 0);
3044 /****************************************************************
3045 strip off leading '\\' from a hostname
3046 ****************************************************************/
3048 const char *strip_hostname(const char *s
)
3054 if (strlen_m(s
) < 3) {
3058 if (s
[0] == '\\') s
++;
3059 if (s
[0] == '\\') s
++;
3064 bool tevent_req_poll_ntstatus(struct tevent_req
*req
,
3065 struct tevent_context
*ev
,
3068 bool ret
= tevent_req_poll(req
, ev
);
3070 *status
= map_nt_error_from_unix(errno
);