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 Returns the size in bytes of the named file.
131 ********************************************************************/
133 SMB_OFF_T
get_file_size(char *file_name
)
137 if (sys_stat(file_name
, &buf
, false) != 0)
138 return (SMB_OFF_T
)-1;
139 return get_file_size_stat(&buf
);
142 /*******************************************************************
143 Show a smb message structure.
144 ********************************************************************/
146 void show_msg(const char *buf
)
154 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
156 (int)CVAL(buf
,smb_com
),
157 (int)CVAL(buf
,smb_rcls
),
158 (int)CVAL(buf
,smb_reh
),
159 (int)SVAL(buf
,smb_err
),
160 (int)CVAL(buf
,smb_flg
),
161 (int)SVAL(buf
,smb_flg2
)));
162 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
163 (int)SVAL(buf
,smb_tid
),
164 (int)SVAL(buf
,smb_pid
),
165 (int)SVAL(buf
,smb_uid
),
166 (int)SVAL(buf
,smb_mid
)));
167 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf
,smb_wct
)));
169 for (i
=0;i
<(int)CVAL(buf
,smb_wct
);i
++)
170 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i
,
171 SVAL(buf
,smb_vwv
+2*i
),SVAL(buf
,smb_vwv
+2*i
)));
173 bcc
= (int)SVAL(buf
,smb_vwv
+2*(CVAL(buf
,smb_wct
)));
175 DEBUGADD(5,("smb_bcc=%d\n",bcc
));
183 dump_data(10, (const uint8
*)smb_buf_const(buf
), bcc
);
186 /*******************************************************************
187 Setup only the byte count for a smb message.
188 ********************************************************************/
190 int set_message_bcc(char *buf
,int num_bytes
)
192 int num_words
= CVAL(buf
,smb_wct
);
193 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
194 _smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
195 return (smb_size
+ num_words
*2 + num_bytes
);
198 /*******************************************************************
199 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
200 Return the bytes added
201 ********************************************************************/
203 ssize_t
message_push_blob(uint8
**outbuf
, DATA_BLOB blob
)
205 size_t newlen
= smb_len(*outbuf
) + 4 + blob
.length
;
208 if (!(tmp
= talloc_realloc(NULL
, *outbuf
, uint8
, newlen
))) {
209 DEBUG(0, ("talloc failed\n"));
214 memcpy(tmp
+ smb_len(tmp
) + 4, blob
.data
, blob
.length
);
215 set_message_bcc((char *)tmp
, smb_buflen(tmp
) + blob
.length
);
219 /*******************************************************************
220 Reduce a file name, removing .. elements.
221 ********************************************************************/
223 static char *dos_clean_name(TALLOC_CTX
*ctx
, const char *s
)
228 DEBUG(3,("dos_clean_name [%s]\n",s
));
230 /* remove any double slashes */
231 str
= talloc_all_string_sub(ctx
, s
, "\\\\", "\\");
236 /* Remove leading .\\ characters */
237 if(strncmp(str
, ".\\", 2) == 0) {
238 trim_string(str
, ".\\", NULL
);
240 str
= talloc_strdup(ctx
, ".\\");
247 while ((p
= strstr_m(str
,"\\..\\")) != NULL
) {
253 if ((p
=strrchr_m(str
,'\\')) != NULL
) {
258 str
= talloc_asprintf(ctx
,
267 trim_string(str
,NULL
,"\\..");
268 return talloc_all_string_sub(ctx
, str
, "\\.\\", "\\");
271 /*******************************************************************
272 Reduce a file name, removing .. elements.
273 ********************************************************************/
275 char *unix_clean_name(TALLOC_CTX
*ctx
, const char *s
)
280 DEBUG(3,("unix_clean_name [%s]\n",s
));
282 /* remove any double slashes */
283 str
= talloc_all_string_sub(ctx
, s
, "//","/");
288 /* Remove leading ./ characters */
289 if(strncmp(str
, "./", 2) == 0) {
290 trim_string(str
, "./", NULL
);
292 str
= talloc_strdup(ctx
, "./");
299 while ((p
= strstr_m(str
,"/../")) != NULL
) {
305 if ((p
=strrchr_m(str
,'/')) != NULL
) {
310 str
= talloc_asprintf(ctx
,
319 trim_string(str
,NULL
,"/..");
320 return talloc_all_string_sub(ctx
, str
, "/./", "/");
323 char *clean_name(TALLOC_CTX
*ctx
, const char *s
)
325 char *str
= dos_clean_name(ctx
, s
);
329 return unix_clean_name(ctx
, str
);
332 /*******************************************************************
333 Write data into an fd at a given offset. Ignore seek errors.
334 ********************************************************************/
336 ssize_t
write_data_at_offset(int fd
, const char *buffer
, size_t N
, SMB_OFF_T pos
)
341 if (pos
== (SMB_OFF_T
)-1) {
342 return write_data(fd
, buffer
, N
);
344 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
346 ret
= sys_pwrite(fd
,buffer
+ total
,N
- total
, pos
);
347 if (ret
== -1 && errno
== ESPIPE
) {
348 return write_data(fd
, buffer
+ total
,N
- total
);
351 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno
) ));
360 return (ssize_t
)total
;
362 /* Use lseek and write_data. */
363 if (sys_lseek(fd
, pos
, SEEK_SET
) == -1) {
364 if (errno
!= ESPIPE
) {
368 return write_data(fd
, buffer
, N
);
373 NTSTATUS
reinit_after_fork(struct messaging_context
*msg_ctx
,
374 struct event_context
*ev_ctx
,
376 bool parent_longlived
)
378 NTSTATUS status
= NT_STATUS_OK
;
380 /* Reset the state of the random
381 * number generation system, so
382 * children do not get the same random
383 * numbers as each other */
384 set_need_random_reseed();
386 /* tdb needs special fork handling */
387 if (tdb_reopen_all(parent_longlived
? 1 : 0) != 0) {
388 DEBUG(0,("tdb_reopen_all failed.\n"));
389 status
= NT_STATUS_OPEN_FAILED
;
393 if (ev_ctx
&& tevent_re_initialise(ev_ctx
) != 0) {
394 smb_panic(__location__
": Failed to re-initialise event context");
399 * For clustering, we need to re-init our ctdbd connection after the
402 status
= messaging_reinit(msg_ctx
, id
);
403 if (!NT_STATUS_IS_OK(status
)) {
404 DEBUG(0,("messaging_reinit() failed: %s\n",
412 /****************************************************************************
413 (Hopefully) efficient array append.
414 ****************************************************************************/
416 void add_to_large_array(TALLOC_CTX
*mem_ctx
, size_t element_size
,
417 void *element
, void *_array
, uint32
*num_elements
,
420 void **array
= (void **)_array
;
422 if (*array_size
< 0) {
426 if (*array
== NULL
) {
427 if (*array_size
== 0) {
431 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
435 *array
= TALLOC(mem_ctx
, element_size
* (*array_size
));
436 if (*array
== NULL
) {
441 if (*num_elements
== *array_size
) {
444 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
448 *array
= TALLOC_REALLOC(mem_ctx
, *array
,
449 element_size
* (*array_size
));
451 if (*array
== NULL
) {
456 memcpy((char *)(*array
) + element_size
*(*num_elements
),
457 element
, element_size
);
467 /****************************************************************************
468 Get my own domain name, or "" if we have none.
469 ****************************************************************************/
471 char *get_mydnsdomname(TALLOC_CTX
*ctx
)
476 domname
= get_mydnsfullname();
481 p
= strchr_m(domname
, '.');
484 return talloc_strdup(ctx
, p
);
486 return talloc_strdup(ctx
, "");
490 /****************************************************************************
491 Interpret a protocol description string, with a default.
492 ****************************************************************************/
494 int interpret_protocol(const char *str
,int def
)
496 if (strequal(str
,"NT1"))
497 return(PROTOCOL_NT1
);
498 if (strequal(str
,"LANMAN2"))
499 return(PROTOCOL_LANMAN2
);
500 if (strequal(str
,"LANMAN1"))
501 return(PROTOCOL_LANMAN1
);
502 if (strequal(str
,"CORE"))
503 return(PROTOCOL_CORE
);
504 if (strequal(str
,"COREPLUS"))
505 return(PROTOCOL_COREPLUS
);
506 if (strequal(str
,"CORE+"))
507 return(PROTOCOL_COREPLUS
);
509 DEBUG(0,("Unrecognised protocol level %s\n",str
));
515 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
516 /******************************************************************
517 Remove any mount options such as -rsize=2048,wsize=2048 etc.
518 Based on a fix from <Thomas.Hepper@icem.de>.
519 Returns a malloc'ed string.
520 *******************************************************************/
522 static char *strip_mount_options(TALLOC_CTX
*ctx
, const char *str
)
526 while(*p
&& !isspace(*p
))
528 while(*p
&& isspace(*p
))
531 return talloc_strdup(ctx
, p
);
537 /*******************************************************************
538 Patch from jkf@soton.ac.uk
539 Split Luke's automount_server into YP lookup and string splitter
540 so can easily implement automount_path().
541 Returns a malloc'ed string.
542 *******************************************************************/
544 #ifdef WITH_NISPLUS_HOME
545 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
549 char *nis_map
= (char *)lp_nis_home_map_name();
551 char buffer
[NIS_MAXATTRVAL
+ 1];
556 snprintf(buffer
, sizeof(buffer
), "[key=%s],%s", user_name
, nis_map
);
557 DEBUG(5, ("NIS+ querystring: %s\n", buffer
));
559 if (result
= nis_list(buffer
, FOLLOW_PATH
|EXPAND_NAME
|HARD_LOOKUP
, NULL
, NULL
)) {
560 if (result
->status
!= NIS_SUCCESS
) {
561 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result
->status
)));
563 object
= result
->objects
.objects_val
;
564 if (object
->zo_data
.zo_type
== ENTRY_OBJ
) {
565 entry
= &object
->zo_data
.objdata_u
.en_data
;
566 DEBUG(5, ("NIS+ entry type: %s\n", entry
->en_type
));
567 DEBUG(3, ("NIS+ result: %s\n", entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
));
569 value
= talloc_strdup(ctx
,
570 entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
);
572 nis_freeresult(result
);
575 value
= talloc_string_sub(ctx
,
582 nis_freeresult(result
);
585 value
= strip_mount_options(ctx
, value
);
586 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
591 #else /* WITH_NISPLUS_HOME */
593 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
597 int nis_error
; /* returned by yp all functions */
598 char *nis_result
; /* yp_match inits this */
599 int nis_result_len
; /* and set this */
600 char *nis_domain
; /* yp_get_default_domain inits this */
601 char *nis_map
= (char *)lp_nis_home_map_name();
603 if ((nis_error
= yp_get_default_domain(&nis_domain
)) != 0) {
604 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error
)));
608 DEBUG(5, ("NIS Domain: %s\n", nis_domain
));
610 if ((nis_error
= yp_match(nis_domain
, nis_map
, user_name
,
611 strlen(user_name
), &nis_result
,
612 &nis_result_len
)) == 0) {
613 if (nis_result_len
> 0 && nis_result
[nis_result_len
] == '\n') {
614 nis_result
[nis_result_len
] = '\0';
616 value
= talloc_strdup(ctx
, nis_result
);
620 value
= strip_mount_options(ctx
, value
);
621 } else if(nis_error
== YPERR_KEY
) {
622 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
623 user_name
, nis_map
));
624 DEBUG(3, ("using defaults for server and home directory\n"));
626 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
627 yperr_string(nis_error
), user_name
, nis_map
));
631 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name
, value
));
635 #endif /* WITH_NISPLUS_HOME */
638 /****************************************************************************
639 Check if a process exists. Does this work on all unixes?
640 ****************************************************************************/
642 bool process_exists(const struct server_id pid
)
644 if (procid_is_me(&pid
)) {
648 if (procid_is_local(&pid
)) {
649 return (kill(pid
.pid
,0) == 0 || errno
!= ESRCH
);
652 #ifdef CLUSTER_SUPPORT
653 return ctdbd_process_exists(messaging_ctdbd_connection(),
660 bool processes_exist(const struct server_id
*pids
, int num_pids
,
663 struct server_id
*remote_pids
= NULL
;
664 int *remote_idx
= NULL
;
665 bool *remote_results
= NULL
;
666 int i
, num_remote_pids
;
669 remote_pids
= talloc_array(talloc_tos(), struct server_id
, num_pids
);
670 if (remote_pids
== NULL
) {
673 remote_idx
= talloc_array(talloc_tos(), int, num_pids
);
674 if (remote_idx
== NULL
) {
677 remote_results
= talloc_array(talloc_tos(), bool, num_pids
);
678 if (remote_results
== NULL
) {
684 for (i
=0; i
<num_pids
; i
++) {
685 if (procid_is_me(&pids
[i
])) {
689 if (procid_is_local(&pids
[i
])) {
690 results
[i
] = ((kill(pids
[i
].pid
,0) == 0) ||
695 remote_pids
[num_remote_pids
] = pids
[i
];
696 remote_idx
[num_remote_pids
] = i
;
697 num_remote_pids
+= 1;
700 if (num_remote_pids
!= 0) {
701 #ifdef CLUSTER_SUPPORT
702 if (!ctdb_processes_exist(messaging_ctdbd_connection(),
703 remote_pids
, num_remote_pids
,
708 for (i
=0; i
<num_remote_pids
; i
++) {
709 remote_results
[i
] = false;
713 for (i
=0; i
<num_remote_pids
; i
++) {
714 results
[remote_idx
[i
]] = remote_results
[i
];
720 TALLOC_FREE(remote_results
);
721 TALLOC_FREE(remote_idx
);
722 TALLOC_FREE(remote_pids
);
726 /*******************************************************************
727 Convert a uid into a user name.
728 ********************************************************************/
730 const char *uidtoname(uid_t uid
)
732 TALLOC_CTX
*ctx
= talloc_tos();
734 struct passwd
*pass
= NULL
;
736 pass
= getpwuid_alloc(ctx
,uid
);
738 name
= talloc_strdup(ctx
,pass
->pw_name
);
741 name
= talloc_asprintf(ctx
,
748 /*******************************************************************
749 Convert a gid into a group name.
750 ********************************************************************/
752 char *gidtoname(gid_t gid
)
758 return talloc_strdup(talloc_tos(), grp
->gr_name
);
761 return talloc_asprintf(talloc_tos(),
767 /*******************************************************************
768 Convert a user name into a uid.
769 ********************************************************************/
771 uid_t
nametouid(const char *name
)
777 pass
= Get_Pwnam_alloc(talloc_tos(), name
);
784 u
= (uid_t
)strtol(name
, &p
, 0);
785 if ((p
!= name
) && (*p
== '\0'))
791 /*******************************************************************
792 Convert a name to a gid_t if possible. Return -1 if not a group.
793 ********************************************************************/
795 gid_t
nametogid(const char *name
)
801 g
= (gid_t
)strtol(name
, &p
, 0);
802 if ((p
!= name
) && (*p
== '\0'))
805 grp
= sys_getgrnam(name
);
811 /*******************************************************************
812 Something really nasty happened - panic !
813 ********************************************************************/
815 void smb_panic_s3(const char *why
)
820 DEBUG(0,("PANIC (pid %llu): %s\n",
821 (unsigned long long)sys_getpid(), why
));
824 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
826 * Make sure all children can attach a debugger.
828 prctl(PR_SET_PTRACER
, getpid(), 0, 0, 0);
831 cmd
= lp_panic_action();
833 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd
));
834 result
= system(cmd
);
837 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
840 DEBUG(0, ("smb_panic(): action returned status %d\n",
841 WEXITSTATUS(result
)));
847 /*******************************************************************
848 Print a backtrace of the stack to the debug log. This function
849 DELIBERATELY LEAKS MEMORY. The expectation is that you should
850 exit shortly after calling it.
851 ********************************************************************/
853 #ifdef HAVE_LIBUNWIND_H
854 #include <libunwind.h>
857 #ifdef HAVE_EXECINFO_H
858 #include <execinfo.h>
865 void log_stack_trace(void)
867 #ifdef HAVE_LIBUNWIND
868 /* Try to use libunwind before any other technique since on ia64
869 * libunwind correctly walks the stack in more circumstances than
877 unw_word_t ip
, sp
, off
;
879 procname
[sizeof(procname
) - 1] = '\0';
881 if (unw_getcontext(&uc
) != 0) {
882 goto libunwind_failed
;
885 if (unw_init_local(&cursor
, &uc
) != 0) {
886 goto libunwind_failed
;
889 DEBUG(0, ("BACKTRACE:\n"));
893 unw_get_reg(&cursor
, UNW_REG_IP
, &ip
);
894 unw_get_reg(&cursor
, UNW_REG_SP
, &sp
);
896 switch (unw_get_proc_name(&cursor
,
897 procname
, sizeof(procname
) - 1, &off
) ) {
901 /* Name truncated. */
902 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
903 i
, procname
, (long long)off
,
904 (long long)ip
, (long long) sp
));
907 /* case -UNW_ENOINFO: */
908 /* case -UNW_EUNSPEC: */
909 /* No symbol name found. */
910 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
911 i
, "<unknown symbol>",
912 (long long)ip
, (long long) sp
));
915 } while (unw_step(&cursor
) > 0);
920 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
922 #elif HAVE_BACKTRACE_SYMBOLS
923 void *backtrace_stack
[BACKTRACE_STACK_SIZE
];
924 size_t backtrace_size
;
925 char **backtrace_strings
;
927 /* get the backtrace (stack frames) */
928 backtrace_size
= backtrace(backtrace_stack
,BACKTRACE_STACK_SIZE
);
929 backtrace_strings
= backtrace_symbols(backtrace_stack
, backtrace_size
);
931 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
932 (unsigned long)backtrace_size
));
934 if (backtrace_strings
) {
937 for (i
= 0; i
< backtrace_size
; i
++)
938 DEBUGADD(0, (" #%u %s\n", i
, backtrace_strings
[i
]));
940 /* Leak the backtrace_strings, rather than risk what free() might do */
945 /* The IRIX libexc library provides an API for unwinding the stack. See
946 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
947 * since we are about to abort anyway, it hardly matters.
950 #define NAMESIZE 32 /* Arbitrary */
952 __uint64_t addrs
[BACKTRACE_STACK_SIZE
];
953 char * names
[BACKTRACE_STACK_SIZE
];
954 char namebuf
[BACKTRACE_STACK_SIZE
* NAMESIZE
];
963 /* We need to be root so we can open our /proc entry to walk
964 * our stack. It also helps when we want to dump core.
968 for (i
= 0; i
< BACKTRACE_STACK_SIZE
; i
++) {
969 names
[i
] = namebuf
+ (i
* NAMESIZE
);
972 levels
= trace_back_stack(0, addrs
, names
,
973 BACKTRACE_STACK_SIZE
, NAMESIZE
- 1);
975 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels
));
976 for (i
= 0; i
< levels
; i
++) {
977 DEBUGADD(0, (" #%d 0x%llx %s\n", i
, addrs
[i
], names
[i
]));
982 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
986 /*******************************************************************
987 A readdir wrapper which just returns the file name.
988 ********************************************************************/
990 const char *readdirname(SMB_STRUCT_DIR
*p
)
992 SMB_STRUCT_DIRENT
*ptr
;
998 ptr
= (SMB_STRUCT_DIRENT
*)sys_readdir(p
);
1002 dname
= ptr
->d_name
;
1009 #ifdef HAVE_BROKEN_READDIR_NAME
1010 /* using /usr/ucb/cc is BAD */
1014 return talloc_strdup(talloc_tos(), dname
);
1017 /*******************************************************************
1018 Utility function used to decide if the last component
1019 of a path matches a (possibly wildcarded) entry in a namelist.
1020 ********************************************************************/
1022 bool is_in_path(const char *name
, name_compare_entry
*namelist
, bool case_sensitive
)
1024 const char *last_component
;
1026 /* if we have no list it's obviously not in the path */
1027 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
))) {
1031 DEBUG(8, ("is_in_path: %s\n", name
));
1033 /* Get the last component of the unix name. */
1034 last_component
= strrchr_m(name
, '/');
1035 if (!last_component
) {
1036 last_component
= name
;
1038 last_component
++; /* Go past '/' */
1041 for(; namelist
->name
!= NULL
; namelist
++) {
1042 if(namelist
->is_wild
) {
1043 if (mask_match(last_component
, namelist
->name
, case_sensitive
)) {
1044 DEBUG(8,("is_in_path: mask match succeeded\n"));
1048 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
1049 (!case_sensitive
&& (strcasecmp_m(last_component
, namelist
->name
) == 0))) {
1050 DEBUG(8,("is_in_path: match succeeded\n"));
1055 DEBUG(8,("is_in_path: match not found\n"));
1059 /*******************************************************************
1060 Strip a '/' separated list into an array of
1061 name_compare_enties structures suitable for
1062 passing to is_in_path(). We do this for
1063 speed so we can pre-parse all the names in the list
1064 and don't do it for each call to is_in_path().
1065 We also check if the entry contains a wildcard to
1066 remove a potentially expensive call to mask_match
1068 ********************************************************************/
1070 void set_namearray(name_compare_entry
**ppname_array
, const char *namelist_in
)
1075 int num_entries
= 0;
1078 (*ppname_array
) = NULL
;
1080 if((namelist_in
== NULL
) || ((namelist_in
!= NULL
) && (*namelist_in
== '\0')))
1083 namelist
= talloc_strdup(talloc_tos(), namelist_in
);
1084 if (namelist
== NULL
) {
1085 DEBUG(0,("set_namearray: talloc fail\n"));
1090 /* We need to make two passes over the string. The
1091 first to count the number of elements, the second
1096 if ( *nameptr
== '/' ) {
1097 /* cope with multiple (useless) /s) */
1101 /* anything left? */
1102 if ( *nameptr
== '\0' )
1105 /* find the next '/' or consume remaining */
1106 name_end
= strchr_m(nameptr
, '/');
1107 if (name_end
== NULL
)
1108 name_end
= (char *)nameptr
+ strlen(nameptr
);
1110 /* next segment please */
1111 nameptr
= name_end
+ 1;
1115 if(num_entries
== 0) {
1116 talloc_free(namelist
);
1120 if(( (*ppname_array
) = SMB_MALLOC_ARRAY(name_compare_entry
, num_entries
+ 1)) == NULL
) {
1121 DEBUG(0,("set_namearray: malloc fail\n"));
1122 talloc_free(namelist
);
1126 /* Now copy out the names */
1130 if ( *nameptr
== '/' ) {
1131 /* cope with multiple (useless) /s) */
1135 /* anything left? */
1136 if ( *nameptr
== '\0' )
1139 /* find the next '/' or consume remaining */
1140 name_end
= strchr_m(nameptr
, '/');
1144 name_end
= nameptr
+ strlen(nameptr
);
1146 (*ppname_array
)[i
].is_wild
= ms_has_wild(nameptr
);
1147 if(((*ppname_array
)[i
].name
= SMB_STRDUP(nameptr
)) == NULL
) {
1148 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1149 talloc_free(namelist
);
1153 /* next segment please */
1154 nameptr
= name_end
+ 1;
1158 (*ppname_array
)[i
].name
= NULL
;
1160 talloc_free(namelist
);
1165 #define DBGC_CLASS DBGC_LOCKING
1167 /****************************************************************************
1168 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1169 is dealt with in posix.c
1170 Returns True if we have information regarding this lock region (and returns
1171 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1172 ****************************************************************************/
1174 bool fcntl_getlock(int fd
, SMB_OFF_T
*poffset
, SMB_OFF_T
*pcount
, int *ptype
, pid_t
*ppid
)
1176 SMB_STRUCT_FLOCK lock
;
1179 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1180 fd
,(double)*poffset
,(double)*pcount
,*ptype
));
1182 lock
.l_type
= *ptype
;
1183 lock
.l_whence
= SEEK_SET
;
1184 lock
.l_start
= *poffset
;
1185 lock
.l_len
= *pcount
;
1188 ret
= sys_fcntl_ptr(fd
,SMB_F_GETLK
,&lock
);
1192 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1193 (double)*poffset
,(double)*pcount
,*ptype
,strerror(errno
)));
1198 *ptype
= lock
.l_type
;
1199 *poffset
= lock
.l_start
;
1200 *pcount
= lock
.l_len
;
1203 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1204 fd
, (int)lock
.l_type
, (unsigned int)lock
.l_pid
));
1209 #define DBGC_CLASS DBGC_ALL
1211 /*******************************************************************
1212 Is the name specified one of my netbios names.
1213 Returns true if it is equal, false otherwise.
1214 ********************************************************************/
1216 bool is_myname(const char *s
)
1221 for (n
=0; my_netbios_names(n
); n
++) {
1222 if (strequal(my_netbios_names(n
), s
)) {
1227 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));
1231 /*******************************************************************
1232 Is the name specified our workgroup/domain.
1233 Returns true if it is equal, false otherwise.
1234 ********************************************************************/
1236 bool is_myworkgroup(const char *s
)
1240 if (strequal(s
, lp_workgroup())) {
1244 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s
, ret
));
1248 /*******************************************************************
1249 we distinguish between 2K and XP by the "Native Lan Manager" string
1250 WinXP => "Windows 2002 5.1"
1251 WinXP 64bit => "Windows XP 5.2"
1252 Win2k => "Windows 2000 5.0"
1253 NT4 => "Windows NT 4.0"
1254 Win9x => "Windows 4.0"
1255 Windows 2003 doesn't set the native lan manager string but
1256 they do set the domain to "Windows 2003 5.2" (probably a bug).
1257 ********************************************************************/
1259 void ra_lanman_string( const char *native_lanman
)
1261 if ( strcmp( native_lanman
, "Windows 2002 5.1" ) == 0 )
1262 set_remote_arch( RA_WINXP
);
1263 else if ( strcmp( native_lanman
, "Windows XP 5.2" ) == 0 )
1264 set_remote_arch( RA_WINXP64
);
1265 else if ( strcmp( native_lanman
, "Windows Server 2003 5.2" ) == 0 )
1266 set_remote_arch( RA_WIN2K3
);
1269 static const char *remote_arch_str
;
1271 const char *get_remote_arch_str(void)
1273 if (!remote_arch_str
) {
1276 return remote_arch_str
;
1279 /*******************************************************************
1280 Set the horrid remote_arch string based on an enum.
1281 ********************************************************************/
1283 void set_remote_arch(enum remote_arch_types type
)
1288 remote_arch_str
= "WfWg";
1291 remote_arch_str
= "OS2";
1294 remote_arch_str
= "Win95";
1297 remote_arch_str
= "WinNT";
1300 remote_arch_str
= "Win2K";
1303 remote_arch_str
= "WinXP";
1306 remote_arch_str
= "WinXP64";
1309 remote_arch_str
= "Win2K3";
1312 remote_arch_str
= "Vista";
1315 remote_arch_str
= "Samba";
1318 remote_arch_str
= "CIFSFS";
1321 remote_arch_str
= "OSX";
1324 ra_type
= RA_UNKNOWN
;
1325 remote_arch_str
= "UNKNOWN";
1329 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1333 /*******************************************************************
1334 Get the remote_arch type.
1335 ********************************************************************/
1337 enum remote_arch_types
get_remote_arch(void)
1342 const char *tab_depth(int level
, int depth
)
1344 if( CHECK_DEBUGLVL(level
) ) {
1345 dbgtext("%*s", depth
*4, "");
1350 /*****************************************************************************
1351 Provide a checksum on a string
1353 Input: s - the null-terminated character string for which the checksum
1356 Output: The checksum value calculated for s.
1357 *****************************************************************************/
1359 int str_checksum(const char *s
)
1363 return hash(s
, strlen(s
), 0);
1366 /*****************************************************************
1367 Zero a memory area then free it. Used to catch bugs faster.
1368 *****************************************************************/
1370 void zero_free(void *p
, size_t size
)
1376 /*****************************************************************
1377 Set our open file limit to a requested max and return the limit.
1378 *****************************************************************/
1380 int set_maxfiles(int requested_max
)
1382 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1384 int saved_current_limit
;
1386 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
1387 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1390 return requested_max
;
1394 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1395 * account for the extra fd we need
1396 * as well as the log files and standard
1397 * handles etc. Save the limit we want to set in case
1398 * we are running on an OS that doesn't support this limit (AIX)
1399 * which always returns RLIM_INFINITY for rlp.rlim_max.
1402 /* Try raising the hard (max) limit to the requested amount. */
1404 #if defined(RLIM_INFINITY)
1405 if (rlp
.rlim_max
!= RLIM_INFINITY
) {
1406 int orig_max
= rlp
.rlim_max
;
1408 if ( rlp
.rlim_max
< requested_max
)
1409 rlp
.rlim_max
= requested_max
;
1411 /* This failing is not an error - many systems (Linux) don't
1412 support our default request of 10,000 open files. JRA. */
1414 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
1415 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1416 (int)rlp
.rlim_max
, strerror(errno
) ));
1418 /* Set failed - restore original value from get. */
1419 rlp
.rlim_max
= orig_max
;
1424 /* Now try setting the soft (current) limit. */
1426 saved_current_limit
= rlp
.rlim_cur
= MIN(requested_max
,rlp
.rlim_max
);
1428 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
1429 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1430 (int)rlp
.rlim_cur
, strerror(errno
) ));
1432 return saved_current_limit
;
1435 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
1436 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1439 return saved_current_limit
;
1442 #if defined(RLIM_INFINITY)
1443 if(rlp
.rlim_cur
== RLIM_INFINITY
)
1444 return saved_current_limit
;
1447 if((int)rlp
.rlim_cur
> saved_current_limit
)
1448 return saved_current_limit
;
1450 return rlp
.rlim_cur
;
1451 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1453 * No way to know - just guess...
1455 return requested_max
;
1459 /*****************************************************************
1460 malloc that aborts with smb_panic on fail or zero size.
1461 *****************************************************************/
1463 void *smb_xmalloc_array(size_t size
, unsigned int count
)
1467 smb_panic("smb_xmalloc_array: called with zero size");
1469 if (count
>= MAX_ALLOC_SIZE
/size
) {
1470 smb_panic("smb_xmalloc_array: alloc size too large");
1472 if ((p
= SMB_MALLOC(size
*count
)) == NULL
) {
1473 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1474 (unsigned long)size
, (unsigned long)count
));
1475 smb_panic("smb_xmalloc_array: malloc failed");
1481 vasprintf that aborts on malloc fail
1484 int smb_xvasprintf(char **ptr
, const char *format
, va_list ap
)
1491 n
= vasprintf(ptr
, format
, ap2
);
1493 if (n
== -1 || ! *ptr
) {
1494 smb_panic("smb_xvasprintf: out of memory");
1499 /*****************************************************************
1500 Get local hostname and cache result.
1501 *****************************************************************/
1503 char *myhostname(void)
1507 ret
= get_myname(NULL
);
1512 /*****************************************************************
1513 Get local hostname and cache result.
1514 *****************************************************************/
1516 char *myhostname_upper(void)
1521 name
= get_myname(talloc_tos());
1522 ret
= strupper_talloc(NULL
, name
);
1529 * @brief Returns an absolute path to a file concatenating the provided
1530 * @a rootpath and @a basename
1532 * @param name Filename, relative to @a rootpath
1534 * @retval Pointer to a string containing the full path.
1537 static char *xx_path(const char *name
, const char *rootpath
)
1541 fname
= talloc_strdup(talloc_tos(), rootpath
);
1545 trim_string(fname
,"","/");
1547 if (!directory_exist(fname
)) {
1548 if (!mkdir(fname
,0755))
1549 DEBUG(1, ("Unable to create directory %s for file %s. "
1550 "Error was %s\n", fname
, name
, strerror(errno
)));
1553 return talloc_asprintf(talloc_tos(),
1560 * @brief Returns an absolute path to a file in the Samba lock directory.
1562 * @param name File to find, relative to LOCKDIR.
1564 * @retval Pointer to a talloc'ed string containing the full path.
1567 char *lock_path(const char *name
)
1569 return xx_path(name
, lp_lockdir());
1573 * @brief Returns an absolute path to a file in the Samba pid directory.
1575 * @param name File to find, relative to PIDDIR.
1577 * @retval Pointer to a talloc'ed string containing the full path.
1580 char *pid_path(const char *name
)
1582 return xx_path(name
, lp_piddir());
1586 * @brief Returns an absolute path to a file in the Samba state directory.
1588 * @param name File to find, relative to STATEDIR.
1590 * @retval Pointer to a talloc'ed string containing the full path.
1593 char *state_path(const char *name
)
1595 return xx_path(name
, lp_statedir());
1599 * @brief Returns an absolute path to a file in the Samba cache directory.
1601 * @param name File to find, relative to CACHEDIR.
1603 * @retval Pointer to a talloc'ed string containing the full path.
1606 char *cache_path(const char *name
)
1608 return xx_path(name
, lp_cachedir());
1611 /*******************************************************************
1612 Given a filename - get its directory name
1613 ********************************************************************/
1615 bool parent_dirname(TALLOC_CTX
*mem_ctx
, const char *dir
, char **parent
,
1621 p
= strrchr_m(dir
, '/'); /* Find final '/', if any */
1624 if (!(*parent
= talloc_strdup(mem_ctx
, "."))) {
1635 if (!(*parent
= (char *)talloc_memdup(mem_ctx
, dir
, len
+1))) {
1638 (*parent
)[len
] = '\0';
1646 /*******************************************************************
1647 Determine if a pattern contains any Microsoft wildcard characters.
1648 *******************************************************************/
1650 bool ms_has_wild(const char *s
)
1654 if (lp_posix_pathnames()) {
1655 /* With posix pathnames no characters are wild. */
1659 while ((c
= *s
++)) {
1672 bool ms_has_wild_w(const smb_ucs2_t
*s
)
1675 if (!s
) return False
;
1676 while ((c
= *s
++)) {
1678 case UCS2_CHAR('*'):
1679 case UCS2_CHAR('?'):
1680 case UCS2_CHAR('<'):
1681 case UCS2_CHAR('>'):
1682 case UCS2_CHAR('"'):
1689 /*******************************************************************
1690 A wrapper that handles case sensitivity and the special handling
1692 *******************************************************************/
1694 bool mask_match(const char *string
, const char *pattern
, bool is_case_sensitive
)
1696 if (ISDOTDOT(string
))
1701 return ms_fnmatch(pattern
, string
, Protocol
<= PROTOCOL_LANMAN2
, is_case_sensitive
) == 0;
1704 /*******************************************************************
1705 A wrapper that handles case sensitivity and the special handling
1706 of the ".." name. Varient that is only called by old search code which requires
1707 pattern translation.
1708 *******************************************************************/
1710 bool mask_match_search(const char *string
, const char *pattern
, bool is_case_sensitive
)
1712 if (ISDOTDOT(string
))
1717 return ms_fnmatch(pattern
, string
, True
, is_case_sensitive
) == 0;
1720 /*******************************************************************
1721 A wrapper that handles a list of patters and calls mask_match()
1722 on each. Returns True if any of the patterns match.
1723 *******************************************************************/
1725 bool mask_match_list(const char *string
, char **list
, int listLen
, bool is_case_sensitive
)
1727 while (listLen
-- > 0) {
1728 if (mask_match(string
, *list
++, is_case_sensitive
))
1734 /*********************************************************
1735 Recursive routine that is called by unix_wild_match.
1736 *********************************************************/
1738 static bool unix_do_match(const char *regexp
, const char *str
)
1742 for( p
= regexp
; *p
&& *str
; ) {
1753 * Look for a character matching
1754 * the one after the '*'.
1758 return true; /* Automatic match */
1761 while(*str
&& (*p
!= *str
))
1765 * Patch from weidel@multichart.de. In the case of the regexp
1766 * '*XX*' we want to ensure there are at least 2 'X' characters
1767 * in the string after the '*' for a match to be made.
1774 * Eat all the characters that match, but count how many there were.
1777 while(*str
&& (*p
== *str
)) {
1783 * Now check that if the regexp had n identical characters that
1784 * matchcount had at least that many matches.
1787 while ( *(p
+1) && (*(p
+1) == *p
)) {
1792 if ( matchcount
<= 0 )
1796 str
--; /* We've eaten the match char after the '*' */
1798 if(unix_do_match(p
, str
))
1820 if (!*p
&& str
[0] == '.' && str
[1] == 0)
1823 if (!*str
&& *p
== '?') {
1829 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
1835 /*******************************************************************
1836 Simple case insensitive interface to a UNIX wildcard matcher.
1837 Returns True if match, False if not.
1838 *******************************************************************/
1840 bool unix_wild_match(const char *pattern
, const char *string
)
1842 TALLOC_CTX
*ctx
= talloc_stackframe();
1848 p2
= talloc_strdup(ctx
,pattern
);
1849 s2
= talloc_strdup(ctx
,string
);
1857 /* Remove any *? and ** from the pattern as they are meaningless */
1858 for(p
= p2
; *p
; p
++) {
1859 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*')) {
1860 memmove(&p
[1], &p
[2], strlen(&p
[2])+1);
1864 if (strequal(p2
,"*")) {
1869 ret
= unix_do_match(p2
, s2
);
1874 /**********************************************************************
1875 Converts a name to a fully qualified domain name.
1876 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1877 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1878 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1879 ***********************************************************************/
1881 bool name_to_fqdn(fstring fqdn
, const char *name
)
1884 struct hostent
*hp
= gethostbyname(name
);
1886 if (!hp
|| !hp
->h_name
|| !*hp
->h_name
) {
1887 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name
));
1888 fstrcpy(fqdn
, name
);
1892 /* Find out if the fqdn is returned as an alias
1893 * to cope with /etc/hosts files where the first
1894 * name is not the fqdn but the short name */
1895 if (hp
->h_aliases
&& (! strchr_m(hp
->h_name
, '.'))) {
1897 for (i
= 0; hp
->h_aliases
[i
]; i
++) {
1898 if (strchr_m(hp
->h_aliases
[i
], '.')) {
1899 full
= hp
->h_aliases
[i
];
1904 if (full
&& (strcasecmp_m(full
, "localhost.localdomain") == 0)) {
1905 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1906 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1907 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1908 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1915 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name
, full
));
1916 fstrcpy(fqdn
, full
);
1920 /**********************************************************************
1921 Append a DATA_BLOB to a talloc'ed object
1922 ***********************************************************************/
1924 void *talloc_append_blob(TALLOC_CTX
*mem_ctx
, void *buf
, DATA_BLOB blob
)
1926 size_t old_size
= 0;
1929 if (blob
.length
== 0) {
1934 old_size
= talloc_get_size(buf
);
1937 result
= (char *)TALLOC_REALLOC(mem_ctx
, buf
, old_size
+ blob
.length
);
1938 if (result
== NULL
) {
1942 memcpy(result
+ old_size
, blob
.data
, blob
.length
);
1946 uint32
map_share_mode_to_deny_mode(uint32 share_access
, uint32 private_options
)
1948 switch (share_access
& ~FILE_SHARE_DELETE
) {
1949 case FILE_SHARE_NONE
:
1951 case FILE_SHARE_READ
:
1953 case FILE_SHARE_WRITE
:
1955 case FILE_SHARE_READ
|FILE_SHARE_WRITE
:
1958 if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) {
1960 } else if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
) {
1967 pid_t
procid_to_pid(const struct server_id
*proc
)
1972 static uint32 my_vnn
= NONCLUSTER_VNN
;
1974 void set_my_vnn(uint32 vnn
)
1976 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn
));
1980 uint32
get_my_vnn(void)
1985 static uint64_t my_unique_id
= 0;
1987 void set_my_unique_id(uint64_t unique_id
)
1989 my_unique_id
= unique_id
;
1992 struct server_id
pid_to_procid(pid_t pid
)
1994 struct server_id result
;
1997 result
.unique_id
= my_unique_id
;
1998 result
.vnn
= my_vnn
;
2002 struct server_id
procid_self(void)
2004 return pid_to_procid(sys_getpid());
2007 bool procid_equal(const struct server_id
*p1
, const struct server_id
*p2
)
2009 if (p1
->pid
!= p2
->pid
)
2011 if (p1
->task_id
!= p2
->task_id
)
2013 if (p1
->vnn
!= p2
->vnn
)
2018 bool cluster_id_equal(const struct server_id
*id1
,
2019 const struct server_id
*id2
)
2021 return procid_equal(id1
, id2
);
2024 bool procid_is_me(const struct server_id
*pid
)
2026 if (pid
->pid
!= sys_getpid())
2028 if (pid
->task_id
!= 0)
2030 if (pid
->vnn
!= my_vnn
)
2035 struct server_id
interpret_pid(const char *pid_string
)
2037 struct server_id result
;
2038 unsigned long long pid
;
2039 unsigned int vnn
, task_id
= 0;
2041 ZERO_STRUCT(result
);
2043 /* We accept various forms with 1, 2 or 3 component forms
2044 * because the server_id_str() can print different forms, and
2045 * we want backwards compatibility for scripts that may call
2047 if (sscanf(pid_string
, "%u:%llu.%u", &vnn
, &pid
, &task_id
) == 3) {
2050 result
.task_id
= task_id
;
2051 } else if (sscanf(pid_string
, "%u:%llu", &vnn
, &pid
) == 2) {
2055 } else if (sscanf(pid_string
, "%llu.%u", &pid
, &task_id
) == 2) {
2056 result
.vnn
= get_my_vnn();
2058 result
.task_id
= task_id
;
2059 } else if (sscanf(pid_string
, "%llu", &pid
) == 1) {
2060 result
.vnn
= get_my_vnn();
2063 result
.vnn
= NONCLUSTER_VNN
;
2064 result
.pid
= (uint64_t)-1;
2069 char *procid_str_static(const struct server_id
*pid
)
2071 return server_id_str(talloc_tos(), pid
);
2074 bool procid_valid(const struct server_id
*pid
)
2076 return (pid
->pid
!= (uint64_t)-1);
2079 bool procid_is_local(const struct server_id
*pid
)
2081 return pid
->vnn
== my_vnn
;
2084 /****************************************************************
2085 Check if an offset into a buffer is safe.
2086 If this returns True it's safe to indirect into the byte at
2088 ****************************************************************/
2090 bool is_offset_safe(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2092 const char *end_base
= buf_base
+ buf_len
;
2093 char *end_ptr
= ptr
+ off
;
2095 if (!buf_base
|| !ptr
) {
2099 if (end_base
< buf_base
|| end_ptr
< ptr
) {
2100 return False
; /* wrap. */
2103 if (end_ptr
< end_base
) {
2109 /****************************************************************
2110 Return a safe pointer into a buffer, or NULL.
2111 ****************************************************************/
2113 char *get_safe_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2115 return is_offset_safe(buf_base
, buf_len
, ptr
, off
) ?
2119 /****************************************************************
2120 Return a safe pointer into a string within a buffer, or NULL.
2121 ****************************************************************/
2123 char *get_safe_str_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2125 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
)) {
2128 /* Check if a valid string exists at this offset. */
2129 if (skip_string(buf_base
,buf_len
, ptr
+ off
) == NULL
) {
2135 /****************************************************************
2136 Return an SVAL at a pointer, or failval if beyond the end.
2137 ****************************************************************/
2139 int get_safe_SVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2142 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2145 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+1)) {
2148 return SVAL(ptr
,off
);
2151 /****************************************************************
2152 Return an IVAL at a pointer, or failval if beyond the end.
2153 ****************************************************************/
2155 int get_safe_IVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2158 * Note we use off+3 here, not off+4 as IVAL accesses
2159 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2161 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+3)) {
2164 return IVAL(ptr
,off
);
2167 /****************************************************************
2168 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2169 call (they take care of winbind separator and other winbind specific settings).
2170 ****************************************************************/
2172 void split_domain_user(TALLOC_CTX
*mem_ctx
,
2173 const char *full_name
,
2177 const char *p
= NULL
;
2179 p
= strchr_m(full_name
, '\\');
2182 *domain
= talloc_strndup(mem_ctx
, full_name
,
2183 PTR_DIFF(p
, full_name
));
2184 *user
= talloc_strdup(mem_ctx
, p
+1);
2186 *domain
= talloc_strdup(mem_ctx
, "");
2187 *user
= talloc_strdup(mem_ctx
, full_name
);
2191 /****************************************************************
2192 strip off leading '\\' from a hostname
2193 ****************************************************************/
2195 const char *strip_hostname(const char *s
)
2201 if (strlen_m(s
) < 3) {
2205 if (s
[0] == '\\') s
++;
2206 if (s
[0] == '\\') s
++;
2211 bool tevent_req_poll_ntstatus(struct tevent_req
*req
,
2212 struct tevent_context
*ev
,
2215 bool ret
= tevent_req_poll(req
, ev
);
2217 *status
= map_nt_error_from_unix(errno
);
2222 bool any_nt_status_not_ok(NTSTATUS err1
, NTSTATUS err2
, NTSTATUS
*result
)
2224 if (!NT_STATUS_IS_OK(err1
)) {
2228 if (!NT_STATUS_IS_OK(err2
)) {
2235 int timeval_to_msec(struct timeval t
)
2237 return t
.tv_sec
* 1000 + (t
.tv_usec
+999) / 1000;
2240 /*******************************************************************
2241 Check a given DOS pathname is valid for a share.
2242 ********************************************************************/
2244 char *valid_share_pathname(TALLOC_CTX
*ctx
, const char *dos_pathname
)
2248 if (!dos_pathname
) {
2252 ptr
= talloc_strdup(ctx
, dos_pathname
);
2256 /* Convert any '\' paths to '/' */
2258 ptr
= unix_clean_name(ctx
, ptr
);
2263 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2264 if (strlen(ptr
) > 2 && ptr
[1] == ':' && ptr
[0] != '/')
2267 /* Only absolute paths allowed. */
2274 /*******************************************************************
2275 Return True if the filename is one of the special executable types.
2276 ********************************************************************/
2278 bool is_executable(const char *fname
)
2280 if ((fname
= strrchr_m(fname
,'.'))) {
2281 if (strequal(fname
,".com") ||
2282 strequal(fname
,".dll") ||
2283 strequal(fname
,".exe") ||
2284 strequal(fname
,".sym")) {
2291 /****************************************************************************
2292 Open a file with a share mode - old openX method - map into NTCreate.
2293 ****************************************************************************/
2295 bool map_open_params_to_ntcreate(const char *smb_base_fname
,
2296 int deny_mode
, int open_func
,
2297 uint32
*paccess_mask
,
2298 uint32
*pshare_mode
,
2299 uint32
*pcreate_disposition
,
2300 uint32
*pcreate_options
,
2301 uint32_t *pprivate_flags
)
2305 uint32 create_disposition
;
2306 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
2307 uint32_t private_flags
= 0;
2309 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2310 "open_func = 0x%x\n",
2311 smb_base_fname
, (unsigned int)deny_mode
,
2312 (unsigned int)open_func
));
2314 /* Create the NT compatible access_mask. */
2315 switch (GET_OPENX_MODE(deny_mode
)) {
2316 case DOS_OPEN_EXEC
: /* Implies read-only - used to be FILE_READ_DATA */
2317 case DOS_OPEN_RDONLY
:
2318 access_mask
= FILE_GENERIC_READ
;
2320 case DOS_OPEN_WRONLY
:
2321 access_mask
= FILE_GENERIC_WRITE
;
2325 access_mask
= FILE_GENERIC_READ
|FILE_GENERIC_WRITE
;
2328 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2329 (unsigned int)GET_OPENX_MODE(deny_mode
)));
2333 /* Create the NT compatible create_disposition. */
2334 switch (open_func
) {
2335 case OPENX_FILE_EXISTS_FAIL
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2336 create_disposition
= FILE_CREATE
;
2339 case OPENX_FILE_EXISTS_OPEN
:
2340 create_disposition
= FILE_OPEN
;
2343 case OPENX_FILE_EXISTS_OPEN
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2344 create_disposition
= FILE_OPEN_IF
;
2347 case OPENX_FILE_EXISTS_TRUNCATE
:
2348 create_disposition
= FILE_OVERWRITE
;
2351 case OPENX_FILE_EXISTS_TRUNCATE
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2352 create_disposition
= FILE_OVERWRITE_IF
;
2356 /* From samba4 - to be confirmed. */
2357 if (GET_OPENX_MODE(deny_mode
) == DOS_OPEN_EXEC
) {
2358 create_disposition
= FILE_CREATE
;
2361 DEBUG(10,("map_open_params_to_ntcreate: bad "
2362 "open_func 0x%x\n", (unsigned int)open_func
));
2366 /* Create the NT compatible share modes. */
2367 switch (GET_DENY_MODE(deny_mode
)) {
2369 share_mode
= FILE_SHARE_NONE
;
2373 share_mode
= FILE_SHARE_READ
;
2377 share_mode
= FILE_SHARE_WRITE
;
2381 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
2385 private_flags
|= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
;
2386 if (is_executable(smb_base_fname
)) {
2387 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
2389 if (GET_OPENX_MODE(deny_mode
) == DOS_OPEN_RDONLY
) {
2390 share_mode
= FILE_SHARE_READ
;
2392 share_mode
= FILE_SHARE_NONE
;
2398 private_flags
|= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
;
2399 share_mode
= FILE_SHARE_NONE
;
2403 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2404 (unsigned int)GET_DENY_MODE(deny_mode
) ));
2408 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2409 "share_mode = 0x%x, create_disposition = 0x%x, "
2410 "create_options = 0x%x private_flags = 0x%x\n",
2412 (unsigned int)access_mask
,
2413 (unsigned int)share_mode
,
2414 (unsigned int)create_disposition
,
2415 (unsigned int)create_options
,
2416 (unsigned int)private_flags
));
2419 *paccess_mask
= access_mask
;
2422 *pshare_mode
= share_mode
;
2424 if (pcreate_disposition
) {
2425 *pcreate_disposition
= create_disposition
;
2427 if (pcreate_options
) {
2428 *pcreate_options
= create_options
;
2430 if (pprivate_flags
) {
2431 *pprivate_flags
= private_flags
;
2439 void init_modules(void)
2441 /* FIXME: This can cause undefined symbol errors :
2442 * smb_register_vfs() isn't available in nmbd, for example */
2443 if(lp_preload_modules())
2444 smb_load_modules(lp_preload_modules());