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/>.
25 #include "system/passwd.h"
26 #include "system/filesys.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/util_pw.h"
31 #include <ccan/hash/hash.h>
32 #include "libcli/security/security.h"
34 #ifdef HAVE_SYS_PRCTL_H
35 #include <sys/prctl.h>
38 /* Max allowable allococation - 256mb - 0x10000000 */
39 #define MAX_ALLOC_SIZE (1024*1024*256)
41 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
42 #ifdef WITH_NISPLUS_HOME
43 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
45 * The following lines are needed due to buggy include files
46 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
47 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
48 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
49 * an enum in /usr/include/rpcsvc/nis.h.
56 #if defined(GROUP_OBJ)
60 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
62 #include <rpcsvc/nis.h>
64 #endif /* WITH_NISPLUS_HOME */
65 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
67 static enum protocol_types Protocol
= PROTOCOL_COREPLUS
;
69 enum protocol_types
get_Protocol(void)
74 void set_Protocol(enum protocol_types p
)
79 static enum remote_arch_types ra_type
= RA_UNKNOWN
;
81 void gfree_all( void )
90 /*******************************************************************
91 Check if a file exists - call vfs_file_exist for samba files.
92 ********************************************************************/
94 bool file_exist_stat(const char *fname
,SMB_STRUCT_STAT
*sbuf
,
95 bool fake_dir_create_times
)
101 if (sys_stat(fname
, sbuf
, fake_dir_create_times
) != 0)
104 return((S_ISREG(sbuf
->st_ex_mode
)) || (S_ISFIFO(sbuf
->st_ex_mode
)));
107 /*******************************************************************
108 Check if a unix domain socket exists - call vfs_file_exist for samba files.
109 ********************************************************************/
111 bool socket_exist(const char *fname
)
114 if (sys_stat(fname
, &st
, false) != 0)
117 return S_ISSOCK(st
.st_ex_mode
);
120 /*******************************************************************
121 Returns the size in bytes of the named given the stat struct.
122 ********************************************************************/
124 uint64_t get_file_size_stat(const SMB_STRUCT_STAT
*sbuf
)
126 return sbuf
->st_ex_size
;
129 /*******************************************************************
130 Show a smb message structure.
131 ********************************************************************/
133 void show_msg(const char *buf
)
141 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
143 (int)CVAL(buf
,smb_com
),
144 (int)CVAL(buf
,smb_rcls
),
145 (int)CVAL(buf
,smb_reh
),
146 (int)SVAL(buf
,smb_err
),
147 (int)CVAL(buf
,smb_flg
),
148 (int)SVAL(buf
,smb_flg2
)));
149 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
150 (int)SVAL(buf
,smb_tid
),
151 (int)SVAL(buf
,smb_pid
),
152 (int)SVAL(buf
,smb_uid
),
153 (int)SVAL(buf
,smb_mid
)));
154 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf
,smb_wct
)));
156 for (i
=0;i
<(int)CVAL(buf
,smb_wct
);i
++)
157 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i
,
158 SVAL(buf
,smb_vwv
+2*i
),SVAL(buf
,smb_vwv
+2*i
)));
160 bcc
= (int)SVAL(buf
,smb_vwv
+2*(CVAL(buf
,smb_wct
)));
162 DEBUGADD(5,("smb_bcc=%d\n",bcc
));
170 dump_data(10, (const uint8
*)smb_buf_const(buf
), bcc
);
173 /*******************************************************************
174 Setup only the byte count for a smb message.
175 ********************************************************************/
177 int set_message_bcc(char *buf
,int num_bytes
)
179 int num_words
= CVAL(buf
,smb_wct
);
180 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
181 _smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
182 return (smb_size
+ num_words
*2 + num_bytes
);
185 /*******************************************************************
186 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
187 Return the bytes added
188 ********************************************************************/
190 ssize_t
message_push_blob(uint8
**outbuf
, DATA_BLOB blob
)
192 size_t newlen
= smb_len(*outbuf
) + 4 + blob
.length
;
195 if (!(tmp
= talloc_realloc(NULL
, *outbuf
, uint8
, newlen
))) {
196 DEBUG(0, ("talloc failed\n"));
201 memcpy(tmp
+ smb_len(tmp
) + 4, blob
.data
, blob
.length
);
202 set_message_bcc((char *)tmp
, smb_buflen(tmp
) + blob
.length
);
206 /*******************************************************************
207 Reduce a file name, removing .. elements.
208 ********************************************************************/
210 static char *dos_clean_name(TALLOC_CTX
*ctx
, const char *s
)
215 DEBUG(3,("dos_clean_name [%s]\n",s
));
217 /* remove any double slashes */
218 str
= talloc_all_string_sub(ctx
, s
, "\\\\", "\\");
223 /* Remove leading .\\ characters */
224 if(strncmp(str
, ".\\", 2) == 0) {
225 trim_string(str
, ".\\", NULL
);
227 str
= talloc_strdup(ctx
, ".\\");
234 while ((p
= strstr_m(str
,"\\..\\")) != NULL
) {
240 if ((p
=strrchr_m(str
,'\\')) != NULL
) {
245 str
= talloc_asprintf(ctx
,
254 trim_string(str
,NULL
,"\\..");
255 return talloc_all_string_sub(ctx
, str
, "\\.\\", "\\");
258 /*******************************************************************
259 Reduce a file name, removing .. elements.
260 ********************************************************************/
262 char *unix_clean_name(TALLOC_CTX
*ctx
, const char *s
)
267 DEBUG(3,("unix_clean_name [%s]\n",s
));
269 /* remove any double slashes */
270 str
= talloc_all_string_sub(ctx
, s
, "//","/");
275 /* Remove leading ./ characters */
276 if(strncmp(str
, "./", 2) == 0) {
277 trim_string(str
, "./", NULL
);
279 str
= talloc_strdup(ctx
, "./");
286 while ((p
= strstr_m(str
,"/../")) != NULL
) {
292 if ((p
=strrchr_m(str
,'/')) != NULL
) {
297 str
= talloc_asprintf(ctx
,
306 trim_string(str
,NULL
,"/..");
307 return talloc_all_string_sub(ctx
, str
, "/./", "/");
310 char *clean_name(TALLOC_CTX
*ctx
, const char *s
)
312 char *str
= dos_clean_name(ctx
, s
);
316 return unix_clean_name(ctx
, str
);
319 /*******************************************************************
320 Write data into an fd at a given offset. Ignore seek errors.
321 ********************************************************************/
323 ssize_t
write_data_at_offset(int fd
, const char *buffer
, size_t N
, SMB_OFF_T pos
)
328 if (pos
== (SMB_OFF_T
)-1) {
329 return write_data(fd
, buffer
, N
);
331 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
333 ret
= sys_pwrite(fd
,buffer
+ total
,N
- total
, pos
);
334 if (ret
== -1 && errno
== ESPIPE
) {
335 return write_data(fd
, buffer
+ total
,N
- total
);
338 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno
) ));
347 return (ssize_t
)total
;
349 /* Use lseek and write_data. */
350 if (lseek(fd
, pos
, SEEK_SET
) == -1) {
351 if (errno
!= ESPIPE
) {
355 return write_data(fd
, buffer
, N
);
359 static int reinit_after_fork_pipe
[2] = { -1, -1 };
361 NTSTATUS
init_before_fork(void)
365 ret
= pipe(reinit_after_fork_pipe
);
369 status
= map_nt_error_from_unix_common(errno
);
371 DEBUG(0, ("Error creating child_pipe: %s\n",
381 * Detect died parent by detecting EOF on the pipe
383 static void reinit_after_fork_pipe_handler(struct tevent_context
*ev
,
384 struct tevent_fd
*fde
,
390 if (sys_read(reinit_after_fork_pipe
[0], &c
, 1) != 1) {
392 * we have reached EOF on stdin, which means the
393 * parent has exited. Shutdown the server
395 (void)kill(getpid(), SIGTERM
);
400 NTSTATUS
reinit_after_fork(struct messaging_context
*msg_ctx
,
401 struct event_context
*ev_ctx
,
402 bool parent_longlived
)
404 NTSTATUS status
= NT_STATUS_OK
;
406 if (reinit_after_fork_pipe
[1] != -1) {
407 close(reinit_after_fork_pipe
[1]);
408 reinit_after_fork_pipe
[1] = -1;
411 /* Reset the state of the random
412 * number generation system, so
413 * children do not get the same random
414 * numbers as each other */
415 set_need_random_reseed();
417 /* tdb needs special fork handling */
418 if (tdb_reopen_all(parent_longlived
? 1 : 0) != 0) {
419 DEBUG(0,("tdb_reopen_all failed.\n"));
420 status
= NT_STATUS_OPEN_FAILED
;
424 if (ev_ctx
&& tevent_re_initialise(ev_ctx
) != 0) {
425 smb_panic(__location__
": Failed to re-initialise event context");
428 if (reinit_after_fork_pipe
[0] != -1) {
429 struct tevent_fd
*fde
;
431 fde
= tevent_add_fd(ev_ctx
, ev_ctx
/* TALLOC_CTX */,
432 reinit_after_fork_pipe
[0], TEVENT_FD_READ
,
433 reinit_after_fork_pipe_handler
, NULL
);
435 smb_panic(__location__
": Failed to add reinit_after_fork pipe event");
441 * For clustering, we need to re-init our ctdbd connection after the
444 status
= messaging_reinit(msg_ctx
);
445 if (!NT_STATUS_IS_OK(status
)) {
446 DEBUG(0,("messaging_reinit() failed: %s\n",
454 /****************************************************************************
455 (Hopefully) efficient array append.
456 ****************************************************************************/
458 void add_to_large_array(TALLOC_CTX
*mem_ctx
, size_t element_size
,
459 void *element
, void *_array
, uint32
*num_elements
,
462 void **array
= (void **)_array
;
464 if (*array_size
< 0) {
468 if (*array
== NULL
) {
469 if (*array_size
== 0) {
473 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
477 *array
= TALLOC(mem_ctx
, element_size
* (*array_size
));
478 if (*array
== NULL
) {
483 if (*num_elements
== *array_size
) {
486 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
490 *array
= TALLOC_REALLOC(mem_ctx
, *array
,
491 element_size
* (*array_size
));
493 if (*array
== NULL
) {
498 memcpy((char *)(*array
) + element_size
*(*num_elements
),
499 element
, element_size
);
509 /****************************************************************************
510 Get my own domain name, or "" if we have none.
511 ****************************************************************************/
513 char *get_mydnsdomname(TALLOC_CTX
*ctx
)
518 domname
= get_mydnsfullname();
523 p
= strchr_m(domname
, '.');
526 return talloc_strdup(ctx
, p
);
528 return talloc_strdup(ctx
, "");
532 /****************************************************************************
533 Interpret a protocol description string, with a default.
534 ****************************************************************************/
536 int interpret_protocol(const char *str
,int def
)
538 if (strequal(str
,"NT1"))
539 return(PROTOCOL_NT1
);
540 if (strequal(str
,"LANMAN2"))
541 return(PROTOCOL_LANMAN2
);
542 if (strequal(str
,"LANMAN1"))
543 return(PROTOCOL_LANMAN1
);
544 if (strequal(str
,"CORE"))
545 return(PROTOCOL_CORE
);
546 if (strequal(str
,"COREPLUS"))
547 return(PROTOCOL_COREPLUS
);
548 if (strequal(str
,"CORE+"))
549 return(PROTOCOL_COREPLUS
);
551 DEBUG(0,("Unrecognised protocol level %s\n",str
));
557 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
558 /******************************************************************
559 Remove any mount options such as -rsize=2048,wsize=2048 etc.
560 Based on a fix from <Thomas.Hepper@icem.de>.
561 Returns a malloc'ed string.
562 *******************************************************************/
564 static char *strip_mount_options(TALLOC_CTX
*ctx
, const char *str
)
568 while(*p
&& !isspace(*p
))
570 while(*p
&& isspace(*p
))
573 return talloc_strdup(ctx
, p
);
579 /*******************************************************************
580 Patch from jkf@soton.ac.uk
581 Split Luke's automount_server into YP lookup and string splitter
582 so can easily implement automount_path().
583 Returns a malloc'ed string.
584 *******************************************************************/
586 #ifdef WITH_NISPLUS_HOME
587 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
591 char *nis_map
= (char *)lp_nis_home_map_name();
593 char buffer
[NIS_MAXATTRVAL
+ 1];
598 snprintf(buffer
, sizeof(buffer
), "[key=%s],%s", user_name
, nis_map
);
599 DEBUG(5, ("NIS+ querystring: %s\n", buffer
));
601 if (result
= nis_list(buffer
, FOLLOW_PATH
|EXPAND_NAME
|HARD_LOOKUP
, NULL
, NULL
)) {
602 if (result
->status
!= NIS_SUCCESS
) {
603 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result
->status
)));
605 object
= result
->objects
.objects_val
;
606 if (object
->zo_data
.zo_type
== ENTRY_OBJ
) {
607 entry
= &object
->zo_data
.objdata_u
.en_data
;
608 DEBUG(5, ("NIS+ entry type: %s\n", entry
->en_type
));
609 DEBUG(3, ("NIS+ result: %s\n", entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
));
611 value
= talloc_strdup(ctx
,
612 entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
);
614 nis_freeresult(result
);
617 value
= talloc_string_sub(ctx
,
624 nis_freeresult(result
);
627 value
= strip_mount_options(ctx
, value
);
628 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
633 #else /* WITH_NISPLUS_HOME */
635 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
639 int nis_error
; /* returned by yp all functions */
640 char *nis_result
; /* yp_match inits this */
641 int nis_result_len
; /* and set this */
642 char *nis_domain
; /* yp_get_default_domain inits this */
643 char *nis_map
= (char *)lp_nis_home_map_name();
645 if ((nis_error
= yp_get_default_domain(&nis_domain
)) != 0) {
646 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error
)));
650 DEBUG(5, ("NIS Domain: %s\n", nis_domain
));
652 if ((nis_error
= yp_match(nis_domain
, nis_map
, user_name
,
653 strlen(user_name
), &nis_result
,
654 &nis_result_len
)) == 0) {
655 if (nis_result_len
> 0 && nis_result
[nis_result_len
] == '\n') {
656 nis_result
[nis_result_len
] = '\0';
658 value
= talloc_strdup(ctx
, nis_result
);
662 value
= strip_mount_options(ctx
, value
);
663 } else if(nis_error
== YPERR_KEY
) {
664 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
665 user_name
, nis_map
));
666 DEBUG(3, ("using defaults for server and home directory\n"));
668 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
669 yperr_string(nis_error
), user_name
, nis_map
));
673 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name
, value
));
677 #endif /* WITH_NISPLUS_HOME */
680 /****************************************************************************
681 Check if a process exists. Does this work on all unixes?
682 ****************************************************************************/
684 bool process_exists(const struct server_id pid
)
686 if (procid_is_me(&pid
)) {
690 if (procid_is_local(&pid
)) {
691 return (kill(pid
.pid
,0) == 0 || errno
!= ESRCH
);
694 #ifdef CLUSTER_SUPPORT
695 return ctdbd_process_exists(messaging_ctdbd_connection(),
702 bool processes_exist(const struct server_id
*pids
, int num_pids
,
705 struct server_id
*remote_pids
= NULL
;
706 int *remote_idx
= NULL
;
707 bool *remote_results
= NULL
;
708 int i
, num_remote_pids
;
711 remote_pids
= talloc_array(talloc_tos(), struct server_id
, num_pids
);
712 if (remote_pids
== NULL
) {
715 remote_idx
= talloc_array(talloc_tos(), int, num_pids
);
716 if (remote_idx
== NULL
) {
719 remote_results
= talloc_array(talloc_tos(), bool, num_pids
);
720 if (remote_results
== NULL
) {
726 for (i
=0; i
<num_pids
; i
++) {
727 if (procid_is_me(&pids
[i
])) {
731 if (procid_is_local(&pids
[i
])) {
732 results
[i
] = ((kill(pids
[i
].pid
,0) == 0) ||
737 remote_pids
[num_remote_pids
] = pids
[i
];
738 remote_idx
[num_remote_pids
] = i
;
739 num_remote_pids
+= 1;
742 if (num_remote_pids
!= 0) {
743 #ifdef CLUSTER_SUPPORT
744 if (!ctdb_processes_exist(messaging_ctdbd_connection(),
745 remote_pids
, num_remote_pids
,
750 for (i
=0; i
<num_remote_pids
; i
++) {
751 remote_results
[i
] = false;
755 for (i
=0; i
<num_remote_pids
; i
++) {
756 results
[remote_idx
[i
]] = remote_results
[i
];
762 TALLOC_FREE(remote_results
);
763 TALLOC_FREE(remote_idx
);
764 TALLOC_FREE(remote_pids
);
768 /*******************************************************************
769 Convert a uid into a user name.
770 ********************************************************************/
772 const char *uidtoname(uid_t uid
)
774 TALLOC_CTX
*ctx
= talloc_tos();
776 struct passwd
*pass
= NULL
;
778 pass
= getpwuid_alloc(ctx
,uid
);
780 name
= talloc_strdup(ctx
,pass
->pw_name
);
783 name
= talloc_asprintf(ctx
,
790 /*******************************************************************
791 Convert a gid into a group name.
792 ********************************************************************/
794 char *gidtoname(gid_t gid
)
800 return talloc_strdup(talloc_tos(), grp
->gr_name
);
803 return talloc_asprintf(talloc_tos(),
809 /*******************************************************************
810 Convert a user name into a uid.
811 ********************************************************************/
813 uid_t
nametouid(const char *name
)
819 pass
= Get_Pwnam_alloc(talloc_tos(), name
);
826 u
= (uid_t
)strtol(name
, &p
, 0);
827 if ((p
!= name
) && (*p
== '\0'))
833 /*******************************************************************
834 Convert a name to a gid_t if possible. Return -1 if not a group.
835 ********************************************************************/
837 gid_t
nametogid(const char *name
)
843 g
= (gid_t
)strtol(name
, &p
, 0);
844 if ((p
!= name
) && (*p
== '\0'))
847 grp
= getgrnam(name
);
853 /*******************************************************************
854 Something really nasty happened - panic !
855 ********************************************************************/
857 void smb_panic_s3(const char *why
)
862 DEBUG(0,("PANIC (pid %llu): %s\n",
863 (unsigned long long)getpid(), why
));
866 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
868 * Make sure all children can attach a debugger.
870 prctl(PR_SET_PTRACER
, getpid(), 0, 0, 0);
873 cmd
= lp_panic_action();
875 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd
));
876 result
= system(cmd
);
879 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
882 DEBUG(0, ("smb_panic(): action returned status %d\n",
883 WEXITSTATUS(result
)));
889 /*******************************************************************
890 Print a backtrace of the stack to the debug log. This function
891 DELIBERATELY LEAKS MEMORY. The expectation is that you should
892 exit shortly after calling it.
893 ********************************************************************/
895 #ifdef HAVE_LIBUNWIND_H
896 #include <libunwind.h>
899 #ifdef HAVE_EXECINFO_H
900 #include <execinfo.h>
907 void log_stack_trace(void)
909 #ifdef HAVE_LIBUNWIND
910 /* Try to use libunwind before any other technique since on ia64
911 * libunwind correctly walks the stack in more circumstances than
919 unw_word_t ip
, sp
, off
;
921 procname
[sizeof(procname
) - 1] = '\0';
923 if (unw_getcontext(&uc
) != 0) {
924 goto libunwind_failed
;
927 if (unw_init_local(&cursor
, &uc
) != 0) {
928 goto libunwind_failed
;
931 DEBUG(0, ("BACKTRACE:\n"));
935 unw_get_reg(&cursor
, UNW_REG_IP
, &ip
);
936 unw_get_reg(&cursor
, UNW_REG_SP
, &sp
);
938 switch (unw_get_proc_name(&cursor
,
939 procname
, sizeof(procname
) - 1, &off
) ) {
943 /* Name truncated. */
944 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
945 i
, procname
, (long long)off
,
946 (long long)ip
, (long long) sp
));
949 /* case -UNW_ENOINFO: */
950 /* case -UNW_EUNSPEC: */
951 /* No symbol name found. */
952 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
953 i
, "<unknown symbol>",
954 (long long)ip
, (long long) sp
));
957 } while (unw_step(&cursor
) > 0);
962 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
964 #elif HAVE_BACKTRACE_SYMBOLS
965 void *backtrace_stack
[BACKTRACE_STACK_SIZE
];
966 size_t backtrace_size
;
967 char **backtrace_strings
;
969 /* get the backtrace (stack frames) */
970 backtrace_size
= backtrace(backtrace_stack
,BACKTRACE_STACK_SIZE
);
971 backtrace_strings
= backtrace_symbols(backtrace_stack
, backtrace_size
);
973 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
974 (unsigned long)backtrace_size
));
976 if (backtrace_strings
) {
979 for (i
= 0; i
< backtrace_size
; i
++)
980 DEBUGADD(0, (" #%u %s\n", i
, backtrace_strings
[i
]));
982 /* Leak the backtrace_strings, rather than risk what free() might do */
987 /* The IRIX libexc library provides an API for unwinding the stack. See
988 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
989 * since we are about to abort anyway, it hardly matters.
992 #define NAMESIZE 32 /* Arbitrary */
994 __uint64_t addrs
[BACKTRACE_STACK_SIZE
];
995 char * names
[BACKTRACE_STACK_SIZE
];
996 char namebuf
[BACKTRACE_STACK_SIZE
* NAMESIZE
];
1003 ZERO_ARRAY(namebuf
);
1005 /* We need to be root so we can open our /proc entry to walk
1006 * our stack. It also helps when we want to dump core.
1010 for (i
= 0; i
< BACKTRACE_STACK_SIZE
; i
++) {
1011 names
[i
] = namebuf
+ (i
* NAMESIZE
);
1014 levels
= trace_back_stack(0, addrs
, names
,
1015 BACKTRACE_STACK_SIZE
, NAMESIZE
- 1);
1017 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels
));
1018 for (i
= 0; i
< levels
; i
++) {
1019 DEBUGADD(0, (" #%d 0x%llx %s\n", i
, addrs
[i
], names
[i
]));
1024 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1028 /*******************************************************************
1029 A readdir wrapper which just returns the file name.
1030 ********************************************************************/
1032 const char *readdirname(SMB_STRUCT_DIR
*p
)
1040 ptr
= (struct dirent
*)readdir(p
);
1044 dname
= ptr
->d_name
;
1051 #ifdef HAVE_BROKEN_READDIR_NAME
1052 /* using /usr/ucb/cc is BAD */
1056 return talloc_strdup(talloc_tos(), dname
);
1059 /*******************************************************************
1060 Utility function used to decide if the last component
1061 of a path matches a (possibly wildcarded) entry in a namelist.
1062 ********************************************************************/
1064 bool is_in_path(const char *name
, name_compare_entry
*namelist
, bool case_sensitive
)
1066 const char *last_component
;
1068 /* if we have no list it's obviously not in the path */
1069 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
))) {
1073 DEBUG(8, ("is_in_path: %s\n", name
));
1075 /* Get the last component of the unix name. */
1076 last_component
= strrchr_m(name
, '/');
1077 if (!last_component
) {
1078 last_component
= name
;
1080 last_component
++; /* Go past '/' */
1083 for(; namelist
->name
!= NULL
; namelist
++) {
1084 if(namelist
->is_wild
) {
1085 if (mask_match(last_component
, namelist
->name
, case_sensitive
)) {
1086 DEBUG(8,("is_in_path: mask match succeeded\n"));
1090 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
1091 (!case_sensitive
&& (strcasecmp_m(last_component
, namelist
->name
) == 0))) {
1092 DEBUG(8,("is_in_path: match succeeded\n"));
1097 DEBUG(8,("is_in_path: match not found\n"));
1101 /*******************************************************************
1102 Strip a '/' separated list into an array of
1103 name_compare_enties structures suitable for
1104 passing to is_in_path(). We do this for
1105 speed so we can pre-parse all the names in the list
1106 and don't do it for each call to is_in_path().
1107 We also check if the entry contains a wildcard to
1108 remove a potentially expensive call to mask_match
1110 ********************************************************************/
1112 void set_namearray(name_compare_entry
**ppname_array
, const char *namelist_in
)
1117 int num_entries
= 0;
1120 (*ppname_array
) = NULL
;
1122 if((namelist_in
== NULL
) || ((namelist_in
!= NULL
) && (*namelist_in
== '\0')))
1125 namelist
= talloc_strdup(talloc_tos(), namelist_in
);
1126 if (namelist
== NULL
) {
1127 DEBUG(0,("set_namearray: talloc fail\n"));
1132 /* We need to make two passes over the string. The
1133 first to count the number of elements, the second
1138 if ( *nameptr
== '/' ) {
1139 /* cope with multiple (useless) /s) */
1143 /* anything left? */
1144 if ( *nameptr
== '\0' )
1147 /* find the next '/' or consume remaining */
1148 name_end
= strchr_m(nameptr
, '/');
1149 if (name_end
== NULL
)
1150 name_end
= (char *)nameptr
+ strlen(nameptr
);
1152 /* next segment please */
1153 nameptr
= name_end
+ 1;
1157 if(num_entries
== 0) {
1158 talloc_free(namelist
);
1162 if(( (*ppname_array
) = SMB_MALLOC_ARRAY(name_compare_entry
, num_entries
+ 1)) == NULL
) {
1163 DEBUG(0,("set_namearray: malloc fail\n"));
1164 talloc_free(namelist
);
1168 /* Now copy out the names */
1172 if ( *nameptr
== '/' ) {
1173 /* cope with multiple (useless) /s) */
1177 /* anything left? */
1178 if ( *nameptr
== '\0' )
1181 /* find the next '/' or consume remaining */
1182 name_end
= strchr_m(nameptr
, '/');
1186 name_end
= nameptr
+ strlen(nameptr
);
1188 (*ppname_array
)[i
].is_wild
= ms_has_wild(nameptr
);
1189 if(((*ppname_array
)[i
].name
= SMB_STRDUP(nameptr
)) == NULL
) {
1190 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1191 talloc_free(namelist
);
1195 /* next segment please */
1196 nameptr
= name_end
+ 1;
1200 (*ppname_array
)[i
].name
= NULL
;
1202 talloc_free(namelist
);
1207 #define DBGC_CLASS DBGC_LOCKING
1209 /****************************************************************************
1210 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1211 is dealt with in posix.c
1212 Returns True if we have information regarding this lock region (and returns
1213 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1214 ****************************************************************************/
1216 bool fcntl_getlock(int fd
, SMB_OFF_T
*poffset
, SMB_OFF_T
*pcount
, int *ptype
, pid_t
*ppid
)
1218 SMB_STRUCT_FLOCK lock
;
1221 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1222 fd
,(double)*poffset
,(double)*pcount
,*ptype
));
1224 lock
.l_type
= *ptype
;
1225 lock
.l_whence
= SEEK_SET
;
1226 lock
.l_start
= *poffset
;
1227 lock
.l_len
= *pcount
;
1230 ret
= sys_fcntl_ptr(fd
,SMB_F_GETLK
,&lock
);
1234 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1235 (double)*poffset
,(double)*pcount
,*ptype
,strerror(errno
)));
1240 *ptype
= lock
.l_type
;
1241 *poffset
= lock
.l_start
;
1242 *pcount
= lock
.l_len
;
1245 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1246 fd
, (int)lock
.l_type
, (unsigned int)lock
.l_pid
));
1251 #define DBGC_CLASS DBGC_ALL
1253 /*******************************************************************
1254 Is the name specified one of my netbios names.
1255 Returns true if it is equal, false otherwise.
1256 ********************************************************************/
1258 bool is_myname(const char *s
)
1263 for (n
=0; my_netbios_names(n
); n
++) {
1264 if (strequal(my_netbios_names(n
), s
)) {
1269 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));
1273 /*******************************************************************
1274 we distinguish between 2K and XP by the "Native Lan Manager" string
1275 WinXP => "Windows 2002 5.1"
1276 WinXP 64bit => "Windows XP 5.2"
1277 Win2k => "Windows 2000 5.0"
1278 NT4 => "Windows NT 4.0"
1279 Win9x => "Windows 4.0"
1280 Windows 2003 doesn't set the native lan manager string but
1281 they do set the domain to "Windows 2003 5.2" (probably a bug).
1282 ********************************************************************/
1284 void ra_lanman_string( const char *native_lanman
)
1286 if ( strcmp( native_lanman
, "Windows 2002 5.1" ) == 0 )
1287 set_remote_arch( RA_WINXP
);
1288 else if ( strcmp( native_lanman
, "Windows XP 5.2" ) == 0 )
1289 set_remote_arch( RA_WINXP64
);
1290 else if ( strcmp( native_lanman
, "Windows Server 2003 5.2" ) == 0 )
1291 set_remote_arch( RA_WIN2K3
);
1294 static const char *remote_arch_str
;
1296 const char *get_remote_arch_str(void)
1298 if (!remote_arch_str
) {
1301 return remote_arch_str
;
1304 /*******************************************************************
1305 Set the horrid remote_arch string based on an enum.
1306 ********************************************************************/
1308 void set_remote_arch(enum remote_arch_types type
)
1313 remote_arch_str
= "WfWg";
1316 remote_arch_str
= "OS2";
1319 remote_arch_str
= "Win95";
1322 remote_arch_str
= "WinNT";
1325 remote_arch_str
= "Win2K";
1328 remote_arch_str
= "WinXP";
1331 remote_arch_str
= "WinXP64";
1334 remote_arch_str
= "Win2K3";
1337 remote_arch_str
= "Vista";
1340 remote_arch_str
= "Samba";
1343 remote_arch_str
= "CIFSFS";
1346 remote_arch_str
= "OSX";
1349 ra_type
= RA_UNKNOWN
;
1350 remote_arch_str
= "UNKNOWN";
1354 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1358 /*******************************************************************
1359 Get the remote_arch type.
1360 ********************************************************************/
1362 enum remote_arch_types
get_remote_arch(void)
1367 const char *tab_depth(int level
, int depth
)
1369 if( CHECK_DEBUGLVL(level
) ) {
1370 dbgtext("%*s", depth
*4, "");
1375 /*****************************************************************************
1376 Provide a checksum on a string
1378 Input: s - the null-terminated character string for which the checksum
1381 Output: The checksum value calculated for s.
1382 *****************************************************************************/
1384 int str_checksum(const char *s
)
1388 return hash(s
, strlen(s
), 0);
1391 /*****************************************************************
1392 Zero a memory area then free it. Used to catch bugs faster.
1393 *****************************************************************/
1395 void zero_free(void *p
, size_t size
)
1401 /*****************************************************************
1402 Set our open file limit to a requested max and return the limit.
1403 *****************************************************************/
1405 int set_maxfiles(int requested_max
)
1407 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1409 int saved_current_limit
;
1411 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
1412 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1415 return requested_max
;
1419 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1420 * account for the extra fd we need
1421 * as well as the log files and standard
1422 * handles etc. Save the limit we want to set in case
1423 * we are running on an OS that doesn't support this limit (AIX)
1424 * which always returns RLIM_INFINITY for rlp.rlim_max.
1427 /* Try raising the hard (max) limit to the requested amount. */
1429 #if defined(RLIM_INFINITY)
1430 if (rlp
.rlim_max
!= RLIM_INFINITY
) {
1431 int orig_max
= rlp
.rlim_max
;
1433 if ( rlp
.rlim_max
< requested_max
)
1434 rlp
.rlim_max
= requested_max
;
1436 /* This failing is not an error - many systems (Linux) don't
1437 support our default request of 10,000 open files. JRA. */
1439 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
1440 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1441 (int)rlp
.rlim_max
, strerror(errno
) ));
1443 /* Set failed - restore original value from get. */
1444 rlp
.rlim_max
= orig_max
;
1449 /* Now try setting the soft (current) limit. */
1451 saved_current_limit
= rlp
.rlim_cur
= MIN(requested_max
,rlp
.rlim_max
);
1453 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
1454 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1455 (int)rlp
.rlim_cur
, strerror(errno
) ));
1457 return saved_current_limit
;
1460 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
1461 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1464 return saved_current_limit
;
1467 #if defined(RLIM_INFINITY)
1468 if(rlp
.rlim_cur
== RLIM_INFINITY
)
1469 return saved_current_limit
;
1472 if((int)rlp
.rlim_cur
> saved_current_limit
)
1473 return saved_current_limit
;
1475 return rlp
.rlim_cur
;
1476 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1478 * No way to know - just guess...
1480 return requested_max
;
1484 /*****************************************************************
1485 malloc that aborts with smb_panic on fail or zero size.
1486 *****************************************************************/
1488 void *smb_xmalloc_array(size_t size
, unsigned int count
)
1492 smb_panic("smb_xmalloc_array: called with zero size");
1494 if (count
>= MAX_ALLOC_SIZE
/size
) {
1495 smb_panic("smb_xmalloc_array: alloc size too large");
1497 if ((p
= SMB_MALLOC(size
*count
)) == NULL
) {
1498 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1499 (unsigned long)size
, (unsigned long)count
));
1500 smb_panic("smb_xmalloc_array: malloc failed");
1506 vasprintf that aborts on malloc fail
1509 int smb_xvasprintf(char **ptr
, const char *format
, va_list ap
)
1516 n
= vasprintf(ptr
, format
, ap2
);
1518 if (n
== -1 || ! *ptr
) {
1519 smb_panic("smb_xvasprintf: out of memory");
1524 /*****************************************************************
1525 Get local hostname and cache result.
1526 *****************************************************************/
1528 char *myhostname(void)
1532 ret
= get_myname(NULL
);
1537 /*****************************************************************
1538 Get local hostname and cache result.
1539 *****************************************************************/
1541 char *myhostname_upper(void)
1546 name
= get_myname(talloc_tos());
1547 ret
= strupper_talloc(NULL
, name
);
1554 * @brief Returns an absolute path to a file concatenating the provided
1555 * @a rootpath and @a basename
1557 * @param name Filename, relative to @a rootpath
1559 * @retval Pointer to a string containing the full path.
1562 static char *xx_path(const char *name
, const char *rootpath
)
1566 fname
= talloc_strdup(talloc_tos(), rootpath
);
1570 trim_string(fname
,"","/");
1572 if (!directory_exist(fname
)) {
1573 if (!mkdir(fname
,0755))
1574 DEBUG(1, ("Unable to create directory %s for file %s. "
1575 "Error was %s\n", fname
, name
, strerror(errno
)));
1578 return talloc_asprintf(talloc_tos(),
1585 * @brief Returns an absolute path to a file in the Samba lock directory.
1587 * @param name File to find, relative to LOCKDIR.
1589 * @retval Pointer to a talloc'ed string containing the full path.
1592 char *lock_path(const char *name
)
1594 return xx_path(name
, lp_lockdir());
1598 * @brief Returns an absolute path to a file in the Samba state directory.
1600 * @param name File to find, relative to STATEDIR.
1602 * @retval Pointer to a talloc'ed string containing the full path.
1605 char *state_path(const char *name
)
1607 return xx_path(name
, lp_statedir());
1611 * @brief Returns an absolute path to a file in the Samba cache directory.
1613 * @param name File to find, relative to CACHEDIR.
1615 * @retval Pointer to a talloc'ed string containing the full path.
1618 char *cache_path(const char *name
)
1620 return xx_path(name
, lp_cachedir());
1623 /*******************************************************************
1624 Given a filename - get its directory name
1625 ********************************************************************/
1627 bool parent_dirname(TALLOC_CTX
*mem_ctx
, const char *dir
, char **parent
,
1633 p
= strrchr_m(dir
, '/'); /* Find final '/', if any */
1636 if (!(*parent
= talloc_strdup(mem_ctx
, "."))) {
1647 if (!(*parent
= (char *)talloc_memdup(mem_ctx
, dir
, len
+1))) {
1650 (*parent
)[len
] = '\0';
1658 /*******************************************************************
1659 Determine if a pattern contains any Microsoft wildcard characters.
1660 *******************************************************************/
1662 bool ms_has_wild(const char *s
)
1666 if (lp_posix_pathnames()) {
1667 /* With posix pathnames no characters are wild. */
1671 while ((c
= *s
++)) {
1684 bool ms_has_wild_w(const smb_ucs2_t
*s
)
1687 if (!s
) return False
;
1688 while ((c
= *s
++)) {
1690 case UCS2_CHAR('*'):
1691 case UCS2_CHAR('?'):
1692 case UCS2_CHAR('<'):
1693 case UCS2_CHAR('>'):
1694 case UCS2_CHAR('"'):
1701 /*******************************************************************
1702 A wrapper that handles case sensitivity and the special handling
1704 *******************************************************************/
1706 bool mask_match(const char *string
, const char *pattern
, bool is_case_sensitive
)
1708 if (ISDOTDOT(string
))
1713 return ms_fnmatch(pattern
, string
, Protocol
<= PROTOCOL_LANMAN2
, is_case_sensitive
) == 0;
1716 /*******************************************************************
1717 A wrapper that handles case sensitivity and the special handling
1718 of the ".." name. Varient that is only called by old search code which requires
1719 pattern translation.
1720 *******************************************************************/
1722 bool mask_match_search(const char *string
, const char *pattern
, bool is_case_sensitive
)
1724 if (ISDOTDOT(string
))
1729 return ms_fnmatch(pattern
, string
, True
, is_case_sensitive
) == 0;
1732 /*******************************************************************
1733 A wrapper that handles a list of patters and calls mask_match()
1734 on each. Returns True if any of the patterns match.
1735 *******************************************************************/
1737 bool mask_match_list(const char *string
, char **list
, int listLen
, bool is_case_sensitive
)
1739 while (listLen
-- > 0) {
1740 if (mask_match(string
, *list
++, is_case_sensitive
))
1746 /*********************************************************
1747 Recursive routine that is called by unix_wild_match.
1748 *********************************************************/
1750 static bool unix_do_match(const char *regexp
, const char *str
)
1754 for( p
= regexp
; *p
&& *str
; ) {
1765 * Look for a character matching
1766 * the one after the '*'.
1770 return true; /* Automatic match */
1773 while(*str
&& (*p
!= *str
))
1777 * Patch from weidel@multichart.de. In the case of the regexp
1778 * '*XX*' we want to ensure there are at least 2 'X' characters
1779 * in the string after the '*' for a match to be made.
1786 * Eat all the characters that match, but count how many there were.
1789 while(*str
&& (*p
== *str
)) {
1795 * Now check that if the regexp had n identical characters that
1796 * matchcount had at least that many matches.
1799 while ( *(p
+1) && (*(p
+1) == *p
)) {
1804 if ( matchcount
<= 0 )
1808 str
--; /* We've eaten the match char after the '*' */
1810 if(unix_do_match(p
, str
))
1832 if (!*p
&& str
[0] == '.' && str
[1] == 0)
1835 if (!*str
&& *p
== '?') {
1841 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
1847 /*******************************************************************
1848 Simple case insensitive interface to a UNIX wildcard matcher.
1849 Returns True if match, False if not.
1850 *******************************************************************/
1852 bool unix_wild_match(const char *pattern
, const char *string
)
1854 TALLOC_CTX
*ctx
= talloc_stackframe();
1860 p2
= talloc_strdup(ctx
,pattern
);
1861 s2
= talloc_strdup(ctx
,string
);
1869 /* Remove any *? and ** from the pattern as they are meaningless */
1870 for(p
= p2
; *p
; p
++) {
1871 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*')) {
1872 memmove(&p
[1], &p
[2], strlen(&p
[2])+1);
1876 if (strequal(p2
,"*")) {
1881 ret
= unix_do_match(p2
, s2
);
1886 /**********************************************************************
1887 Converts a name to a fully qualified domain name.
1888 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1889 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1890 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1891 ***********************************************************************/
1893 bool name_to_fqdn(fstring fqdn
, const char *name
)
1896 struct hostent
*hp
= gethostbyname(name
);
1898 if (!hp
|| !hp
->h_name
|| !*hp
->h_name
) {
1899 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name
));
1900 fstrcpy(fqdn
, name
);
1904 /* Find out if the fqdn is returned as an alias
1905 * to cope with /etc/hosts files where the first
1906 * name is not the fqdn but the short name */
1907 if (hp
->h_aliases
&& (! strchr_m(hp
->h_name
, '.'))) {
1909 for (i
= 0; hp
->h_aliases
[i
]; i
++) {
1910 if (strchr_m(hp
->h_aliases
[i
], '.')) {
1911 full
= hp
->h_aliases
[i
];
1916 if (full
&& (strcasecmp_m(full
, "localhost.localdomain") == 0)) {
1917 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1918 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1919 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1920 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1927 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name
, full
));
1928 fstrcpy(fqdn
, full
);
1932 /**********************************************************************
1933 Append a DATA_BLOB to a talloc'ed object
1934 ***********************************************************************/
1936 void *talloc_append_blob(TALLOC_CTX
*mem_ctx
, void *buf
, DATA_BLOB blob
)
1938 size_t old_size
= 0;
1941 if (blob
.length
== 0) {
1946 old_size
= talloc_get_size(buf
);
1949 result
= (char *)TALLOC_REALLOC(mem_ctx
, buf
, old_size
+ blob
.length
);
1950 if (result
== NULL
) {
1954 memcpy(result
+ old_size
, blob
.data
, blob
.length
);
1958 uint32
map_share_mode_to_deny_mode(uint32 share_access
, uint32 private_options
)
1960 switch (share_access
& ~FILE_SHARE_DELETE
) {
1961 case FILE_SHARE_NONE
:
1963 case FILE_SHARE_READ
:
1965 case FILE_SHARE_WRITE
:
1967 case FILE_SHARE_READ
|FILE_SHARE_WRITE
:
1970 if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) {
1972 } else if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
) {
1979 pid_t
procid_to_pid(const struct server_id
*proc
)
1984 static uint32 my_vnn
= NONCLUSTER_VNN
;
1986 void set_my_vnn(uint32 vnn
)
1988 DEBUG(10, ("vnn pid %d = %u\n", (int)getpid(), (unsigned int)vnn
));
1992 uint32
get_my_vnn(void)
1997 static uint64_t my_unique_id
= 0;
1999 void set_my_unique_id(uint64_t unique_id
)
2001 my_unique_id
= unique_id
;
2004 struct server_id
pid_to_procid(pid_t pid
)
2006 struct server_id result
;
2009 result
.unique_id
= my_unique_id
;
2010 result
.vnn
= my_vnn
;
2014 struct server_id
procid_self(void)
2016 return pid_to_procid(getpid());
2019 bool procid_equal(const struct server_id
*p1
, const struct server_id
*p2
)
2021 if (p1
->pid
!= p2
->pid
)
2023 if (p1
->task_id
!= p2
->task_id
)
2025 if (p1
->vnn
!= p2
->vnn
)
2030 bool cluster_id_equal(const struct server_id
*id1
,
2031 const struct server_id
*id2
)
2033 return procid_equal(id1
, id2
);
2036 bool procid_is_me(const struct server_id
*pid
)
2038 if (pid
->pid
!= getpid())
2040 if (pid
->task_id
!= 0)
2042 if (pid
->vnn
!= my_vnn
)
2047 struct server_id
interpret_pid(const char *pid_string
)
2049 struct server_id result
;
2050 unsigned long long pid
;
2051 unsigned int vnn
, task_id
= 0;
2053 ZERO_STRUCT(result
);
2055 /* We accept various forms with 1, 2 or 3 component forms
2056 * because the server_id_str() can print different forms, and
2057 * we want backwards compatibility for scripts that may call
2059 if (sscanf(pid_string
, "%u:%llu.%u", &vnn
, &pid
, &task_id
) == 3) {
2062 result
.task_id
= task_id
;
2063 } else if (sscanf(pid_string
, "%u:%llu", &vnn
, &pid
) == 2) {
2067 } else if (sscanf(pid_string
, "%llu.%u", &pid
, &task_id
) == 2) {
2068 result
.vnn
= get_my_vnn();
2070 result
.task_id
= task_id
;
2071 } else if (sscanf(pid_string
, "%llu", &pid
) == 1) {
2072 result
.vnn
= get_my_vnn();
2075 result
.vnn
= NONCLUSTER_VNN
;
2076 result
.pid
= (uint64_t)-1;
2081 char *procid_str_static(const struct server_id
*pid
)
2083 return server_id_str(talloc_tos(), pid
);
2086 bool procid_valid(const struct server_id
*pid
)
2088 return (pid
->pid
!= (uint64_t)-1);
2091 bool procid_is_local(const struct server_id
*pid
)
2093 return pid
->vnn
== my_vnn
;
2096 /****************************************************************
2097 Check if an offset into a buffer is safe.
2098 If this returns True it's safe to indirect into the byte at
2100 ****************************************************************/
2102 bool is_offset_safe(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2104 const char *end_base
= buf_base
+ buf_len
;
2105 char *end_ptr
= ptr
+ off
;
2107 if (!buf_base
|| !ptr
) {
2111 if (end_base
< buf_base
|| end_ptr
< ptr
) {
2112 return False
; /* wrap. */
2115 if (end_ptr
< end_base
) {
2121 /****************************************************************
2122 Return a safe pointer into a buffer, or NULL.
2123 ****************************************************************/
2125 char *get_safe_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2127 return is_offset_safe(buf_base
, buf_len
, ptr
, off
) ?
2131 /****************************************************************
2132 Return a safe pointer into a string within a buffer, or NULL.
2133 ****************************************************************/
2135 char *get_safe_str_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2137 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
)) {
2140 /* Check if a valid string exists at this offset. */
2141 if (skip_string(buf_base
,buf_len
, ptr
+ off
) == NULL
) {
2147 /****************************************************************
2148 Return an SVAL at a pointer, or failval if beyond the end.
2149 ****************************************************************/
2151 int get_safe_SVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2154 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2157 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+1)) {
2160 return SVAL(ptr
,off
);
2163 /****************************************************************
2164 Return an IVAL at a pointer, or failval if beyond the end.
2165 ****************************************************************/
2167 int get_safe_IVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2170 * Note we use off+3 here, not off+4 as IVAL accesses
2171 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2173 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+3)) {
2176 return IVAL(ptr
,off
);
2179 /****************************************************************
2180 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2181 call (they take care of winbind separator and other winbind specific settings).
2182 ****************************************************************/
2184 void split_domain_user(TALLOC_CTX
*mem_ctx
,
2185 const char *full_name
,
2189 const char *p
= NULL
;
2191 p
= strchr_m(full_name
, '\\');
2194 *domain
= talloc_strndup(mem_ctx
, full_name
,
2195 PTR_DIFF(p
, full_name
));
2196 *user
= talloc_strdup(mem_ctx
, p
+1);
2198 *domain
= talloc_strdup(mem_ctx
, "");
2199 *user
= talloc_strdup(mem_ctx
, full_name
);
2203 /****************************************************************
2204 strip off leading '\\' from a hostname
2205 ****************************************************************/
2207 const char *strip_hostname(const char *s
)
2213 if (strlen_m(s
) < 3) {
2217 if (s
[0] == '\\') s
++;
2218 if (s
[0] == '\\') s
++;
2223 bool tevent_req_poll_ntstatus(struct tevent_req
*req
,
2224 struct tevent_context
*ev
,
2227 bool ret
= tevent_req_poll(req
, ev
);
2229 *status
= map_nt_error_from_unix(errno
);
2234 bool any_nt_status_not_ok(NTSTATUS err1
, NTSTATUS err2
, NTSTATUS
*result
)
2236 if (!NT_STATUS_IS_OK(err1
)) {
2240 if (!NT_STATUS_IS_OK(err2
)) {
2247 int timeval_to_msec(struct timeval t
)
2249 return t
.tv_sec
* 1000 + (t
.tv_usec
+999) / 1000;
2252 /*******************************************************************
2253 Check a given DOS pathname is valid for a share.
2254 ********************************************************************/
2256 char *valid_share_pathname(TALLOC_CTX
*ctx
, const char *dos_pathname
)
2260 if (!dos_pathname
) {
2264 ptr
= talloc_strdup(ctx
, dos_pathname
);
2268 /* Convert any '\' paths to '/' */
2270 ptr
= unix_clean_name(ctx
, ptr
);
2275 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2276 if (strlen(ptr
) > 2 && ptr
[1] == ':' && ptr
[0] != '/')
2279 /* Only absolute paths allowed. */
2286 /*******************************************************************
2287 Return True if the filename is one of the special executable types.
2288 ********************************************************************/
2290 bool is_executable(const char *fname
)
2292 if ((fname
= strrchr_m(fname
,'.'))) {
2293 if (strequal(fname
,".com") ||
2294 strequal(fname
,".dll") ||
2295 strequal(fname
,".exe") ||
2296 strequal(fname
,".sym")) {
2303 /****************************************************************************
2304 Open a file with a share mode - old openX method - map into NTCreate.
2305 ****************************************************************************/
2307 bool map_open_params_to_ntcreate(const char *smb_base_fname
,
2308 int deny_mode
, int open_func
,
2309 uint32
*paccess_mask
,
2310 uint32
*pshare_mode
,
2311 uint32
*pcreate_disposition
,
2312 uint32
*pcreate_options
,
2313 uint32_t *pprivate_flags
)
2317 uint32 create_disposition
;
2318 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
2319 uint32_t private_flags
= 0;
2321 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2322 "open_func = 0x%x\n",
2323 smb_base_fname
, (unsigned int)deny_mode
,
2324 (unsigned int)open_func
));
2326 /* Create the NT compatible access_mask. */
2327 switch (GET_OPENX_MODE(deny_mode
)) {
2328 case DOS_OPEN_EXEC
: /* Implies read-only - used to be FILE_READ_DATA */
2329 case DOS_OPEN_RDONLY
:
2330 access_mask
= FILE_GENERIC_READ
;
2332 case DOS_OPEN_WRONLY
:
2333 access_mask
= FILE_GENERIC_WRITE
;
2337 access_mask
= FILE_GENERIC_READ
|FILE_GENERIC_WRITE
;
2340 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2341 (unsigned int)GET_OPENX_MODE(deny_mode
)));
2345 /* Create the NT compatible create_disposition. */
2346 switch (open_func
) {
2347 case OPENX_FILE_EXISTS_FAIL
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2348 create_disposition
= FILE_CREATE
;
2351 case OPENX_FILE_EXISTS_OPEN
:
2352 create_disposition
= FILE_OPEN
;
2355 case OPENX_FILE_EXISTS_OPEN
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2356 create_disposition
= FILE_OPEN_IF
;
2359 case OPENX_FILE_EXISTS_TRUNCATE
:
2360 create_disposition
= FILE_OVERWRITE
;
2363 case OPENX_FILE_EXISTS_TRUNCATE
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2364 create_disposition
= FILE_OVERWRITE_IF
;
2368 /* From samba4 - to be confirmed. */
2369 if (GET_OPENX_MODE(deny_mode
) == DOS_OPEN_EXEC
) {
2370 create_disposition
= FILE_CREATE
;
2373 DEBUG(10,("map_open_params_to_ntcreate: bad "
2374 "open_func 0x%x\n", (unsigned int)open_func
));
2378 /* Create the NT compatible share modes. */
2379 switch (GET_DENY_MODE(deny_mode
)) {
2381 share_mode
= FILE_SHARE_NONE
;
2385 share_mode
= FILE_SHARE_READ
;
2389 share_mode
= FILE_SHARE_WRITE
;
2393 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
2397 private_flags
|= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
;
2398 if (is_executable(smb_base_fname
)) {
2399 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
2401 if (GET_OPENX_MODE(deny_mode
) == DOS_OPEN_RDONLY
) {
2402 share_mode
= FILE_SHARE_READ
;
2404 share_mode
= FILE_SHARE_NONE
;
2410 private_flags
|= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
;
2411 share_mode
= FILE_SHARE_NONE
;
2415 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2416 (unsigned int)GET_DENY_MODE(deny_mode
) ));
2420 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2421 "share_mode = 0x%x, create_disposition = 0x%x, "
2422 "create_options = 0x%x private_flags = 0x%x\n",
2424 (unsigned int)access_mask
,
2425 (unsigned int)share_mode
,
2426 (unsigned int)create_disposition
,
2427 (unsigned int)create_options
,
2428 (unsigned int)private_flags
));
2431 *paccess_mask
= access_mask
;
2434 *pshare_mode
= share_mode
;
2436 if (pcreate_disposition
) {
2437 *pcreate_disposition
= create_disposition
;
2439 if (pcreate_options
) {
2440 *pcreate_options
= create_options
;
2442 if (pprivate_flags
) {
2443 *pprivate_flags
= private_flags
;