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
,
375 bool parent_longlived
)
377 NTSTATUS status
= NT_STATUS_OK
;
379 /* Reset the state of the random
380 * number generation system, so
381 * children do not get the same random
382 * numbers as each other */
383 set_need_random_reseed();
385 /* tdb needs special fork handling */
386 if (tdb_reopen_all(parent_longlived
? 1 : 0) != 0) {
387 DEBUG(0,("tdb_reopen_all failed.\n"));
388 status
= NT_STATUS_OPEN_FAILED
;
392 if (ev_ctx
&& tevent_re_initialise(ev_ctx
) != 0) {
393 smb_panic(__location__
": Failed to re-initialise event context");
398 * For clustering, we need to re-init our ctdbd connection after the
401 status
= messaging_reinit(msg_ctx
);
402 if (!NT_STATUS_IS_OK(status
)) {
403 DEBUG(0,("messaging_reinit() failed: %s\n",
411 /****************************************************************************
412 (Hopefully) efficient array append.
413 ****************************************************************************/
415 void add_to_large_array(TALLOC_CTX
*mem_ctx
, size_t element_size
,
416 void *element
, void *_array
, uint32
*num_elements
,
419 void **array
= (void **)_array
;
421 if (*array_size
< 0) {
425 if (*array
== NULL
) {
426 if (*array_size
== 0) {
430 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
434 *array
= TALLOC(mem_ctx
, element_size
* (*array_size
));
435 if (*array
== NULL
) {
440 if (*num_elements
== *array_size
) {
443 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
447 *array
= TALLOC_REALLOC(mem_ctx
, *array
,
448 element_size
* (*array_size
));
450 if (*array
== NULL
) {
455 memcpy((char *)(*array
) + element_size
*(*num_elements
),
456 element
, element_size
);
466 /****************************************************************************
467 Get my own domain name, or "" if we have none.
468 ****************************************************************************/
470 char *get_mydnsdomname(TALLOC_CTX
*ctx
)
475 domname
= get_mydnsfullname();
480 p
= strchr_m(domname
, '.');
483 return talloc_strdup(ctx
, p
);
485 return talloc_strdup(ctx
, "");
489 /****************************************************************************
490 Interpret a protocol description string, with a default.
491 ****************************************************************************/
493 int interpret_protocol(const char *str
,int def
)
495 if (strequal(str
,"NT1"))
496 return(PROTOCOL_NT1
);
497 if (strequal(str
,"LANMAN2"))
498 return(PROTOCOL_LANMAN2
);
499 if (strequal(str
,"LANMAN1"))
500 return(PROTOCOL_LANMAN1
);
501 if (strequal(str
,"CORE"))
502 return(PROTOCOL_CORE
);
503 if (strequal(str
,"COREPLUS"))
504 return(PROTOCOL_COREPLUS
);
505 if (strequal(str
,"CORE+"))
506 return(PROTOCOL_COREPLUS
);
508 DEBUG(0,("Unrecognised protocol level %s\n",str
));
514 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
515 /******************************************************************
516 Remove any mount options such as -rsize=2048,wsize=2048 etc.
517 Based on a fix from <Thomas.Hepper@icem.de>.
518 Returns a malloc'ed string.
519 *******************************************************************/
521 static char *strip_mount_options(TALLOC_CTX
*ctx
, const char *str
)
525 while(*p
&& !isspace(*p
))
527 while(*p
&& isspace(*p
))
530 return talloc_strdup(ctx
, p
);
536 /*******************************************************************
537 Patch from jkf@soton.ac.uk
538 Split Luke's automount_server into YP lookup and string splitter
539 so can easily implement automount_path().
540 Returns a malloc'ed string.
541 *******************************************************************/
543 #ifdef WITH_NISPLUS_HOME
544 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
548 char *nis_map
= (char *)lp_nis_home_map_name();
550 char buffer
[NIS_MAXATTRVAL
+ 1];
555 snprintf(buffer
, sizeof(buffer
), "[key=%s],%s", user_name
, nis_map
);
556 DEBUG(5, ("NIS+ querystring: %s\n", buffer
));
558 if (result
= nis_list(buffer
, FOLLOW_PATH
|EXPAND_NAME
|HARD_LOOKUP
, NULL
, NULL
)) {
559 if (result
->status
!= NIS_SUCCESS
) {
560 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result
->status
)));
562 object
= result
->objects
.objects_val
;
563 if (object
->zo_data
.zo_type
== ENTRY_OBJ
) {
564 entry
= &object
->zo_data
.objdata_u
.en_data
;
565 DEBUG(5, ("NIS+ entry type: %s\n", entry
->en_type
));
566 DEBUG(3, ("NIS+ result: %s\n", entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
));
568 value
= talloc_strdup(ctx
,
569 entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
);
571 nis_freeresult(result
);
574 value
= talloc_string_sub(ctx
,
581 nis_freeresult(result
);
584 value
= strip_mount_options(ctx
, value
);
585 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
590 #else /* WITH_NISPLUS_HOME */
592 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
596 int nis_error
; /* returned by yp all functions */
597 char *nis_result
; /* yp_match inits this */
598 int nis_result_len
; /* and set this */
599 char *nis_domain
; /* yp_get_default_domain inits this */
600 char *nis_map
= (char *)lp_nis_home_map_name();
602 if ((nis_error
= yp_get_default_domain(&nis_domain
)) != 0) {
603 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error
)));
607 DEBUG(5, ("NIS Domain: %s\n", nis_domain
));
609 if ((nis_error
= yp_match(nis_domain
, nis_map
, user_name
,
610 strlen(user_name
), &nis_result
,
611 &nis_result_len
)) == 0) {
612 if (nis_result_len
> 0 && nis_result
[nis_result_len
] == '\n') {
613 nis_result
[nis_result_len
] = '\0';
615 value
= talloc_strdup(ctx
, nis_result
);
619 value
= strip_mount_options(ctx
, value
);
620 } else if(nis_error
== YPERR_KEY
) {
621 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
622 user_name
, nis_map
));
623 DEBUG(3, ("using defaults for server and home directory\n"));
625 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
626 yperr_string(nis_error
), user_name
, nis_map
));
630 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name
, value
));
634 #endif /* WITH_NISPLUS_HOME */
637 /****************************************************************************
638 Check if a process exists. Does this work on all unixes?
639 ****************************************************************************/
641 bool process_exists(const struct server_id pid
)
643 if (procid_is_me(&pid
)) {
647 if (procid_is_local(&pid
)) {
648 return (kill(pid
.pid
,0) == 0 || errno
!= ESRCH
);
651 #ifdef CLUSTER_SUPPORT
652 return ctdbd_process_exists(messaging_ctdbd_connection(),
659 bool processes_exist(const struct server_id
*pids
, int num_pids
,
662 struct server_id
*remote_pids
= NULL
;
663 int *remote_idx
= NULL
;
664 bool *remote_results
= NULL
;
665 int i
, num_remote_pids
;
668 remote_pids
= talloc_array(talloc_tos(), struct server_id
, num_pids
);
669 if (remote_pids
== NULL
) {
672 remote_idx
= talloc_array(talloc_tos(), int, num_pids
);
673 if (remote_idx
== NULL
) {
676 remote_results
= talloc_array(talloc_tos(), bool, num_pids
);
677 if (remote_results
== NULL
) {
683 for (i
=0; i
<num_pids
; i
++) {
684 if (procid_is_me(&pids
[i
])) {
688 if (procid_is_local(&pids
[i
])) {
689 results
[i
] = ((kill(pids
[i
].pid
,0) == 0) ||
694 remote_pids
[num_remote_pids
] = pids
[i
];
695 remote_idx
[num_remote_pids
] = i
;
696 num_remote_pids
+= 1;
699 if (num_remote_pids
!= 0) {
700 #ifdef CLUSTER_SUPPORT
701 if (!ctdb_processes_exist(messaging_ctdbd_connection(),
702 remote_pids
, num_remote_pids
,
707 for (i
=0; i
<num_remote_pids
; i
++) {
708 remote_results
[i
] = false;
712 for (i
=0; i
<num_remote_pids
; i
++) {
713 results
[remote_idx
[i
]] = remote_results
[i
];
719 TALLOC_FREE(remote_results
);
720 TALLOC_FREE(remote_idx
);
721 TALLOC_FREE(remote_pids
);
725 /*******************************************************************
726 Convert a uid into a user name.
727 ********************************************************************/
729 const char *uidtoname(uid_t uid
)
731 TALLOC_CTX
*ctx
= talloc_tos();
733 struct passwd
*pass
= NULL
;
735 pass
= getpwuid_alloc(ctx
,uid
);
737 name
= talloc_strdup(ctx
,pass
->pw_name
);
740 name
= talloc_asprintf(ctx
,
747 /*******************************************************************
748 Convert a gid into a group name.
749 ********************************************************************/
751 char *gidtoname(gid_t gid
)
757 return talloc_strdup(talloc_tos(), grp
->gr_name
);
760 return talloc_asprintf(talloc_tos(),
766 /*******************************************************************
767 Convert a user name into a uid.
768 ********************************************************************/
770 uid_t
nametouid(const char *name
)
776 pass
= Get_Pwnam_alloc(talloc_tos(), name
);
783 u
= (uid_t
)strtol(name
, &p
, 0);
784 if ((p
!= name
) && (*p
== '\0'))
790 /*******************************************************************
791 Convert a name to a gid_t if possible. Return -1 if not a group.
792 ********************************************************************/
794 gid_t
nametogid(const char *name
)
800 g
= (gid_t
)strtol(name
, &p
, 0);
801 if ((p
!= name
) && (*p
== '\0'))
804 grp
= sys_getgrnam(name
);
810 /*******************************************************************
811 Something really nasty happened - panic !
812 ********************************************************************/
814 void smb_panic_s3(const char *why
)
819 DEBUG(0,("PANIC (pid %llu): %s\n",
820 (unsigned long long)sys_getpid(), why
));
823 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
825 * Make sure all children can attach a debugger.
827 prctl(PR_SET_PTRACER
, getpid(), 0, 0, 0);
830 cmd
= lp_panic_action();
832 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd
));
833 result
= system(cmd
);
836 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
839 DEBUG(0, ("smb_panic(): action returned status %d\n",
840 WEXITSTATUS(result
)));
846 /*******************************************************************
847 Print a backtrace of the stack to the debug log. This function
848 DELIBERATELY LEAKS MEMORY. The expectation is that you should
849 exit shortly after calling it.
850 ********************************************************************/
852 #ifdef HAVE_LIBUNWIND_H
853 #include <libunwind.h>
856 #ifdef HAVE_EXECINFO_H
857 #include <execinfo.h>
864 void log_stack_trace(void)
866 #ifdef HAVE_LIBUNWIND
867 /* Try to use libunwind before any other technique since on ia64
868 * libunwind correctly walks the stack in more circumstances than
876 unw_word_t ip
, sp
, off
;
878 procname
[sizeof(procname
) - 1] = '\0';
880 if (unw_getcontext(&uc
) != 0) {
881 goto libunwind_failed
;
884 if (unw_init_local(&cursor
, &uc
) != 0) {
885 goto libunwind_failed
;
888 DEBUG(0, ("BACKTRACE:\n"));
892 unw_get_reg(&cursor
, UNW_REG_IP
, &ip
);
893 unw_get_reg(&cursor
, UNW_REG_SP
, &sp
);
895 switch (unw_get_proc_name(&cursor
,
896 procname
, sizeof(procname
) - 1, &off
) ) {
900 /* Name truncated. */
901 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
902 i
, procname
, (long long)off
,
903 (long long)ip
, (long long) sp
));
906 /* case -UNW_ENOINFO: */
907 /* case -UNW_EUNSPEC: */
908 /* No symbol name found. */
909 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
910 i
, "<unknown symbol>",
911 (long long)ip
, (long long) sp
));
914 } while (unw_step(&cursor
) > 0);
919 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
921 #elif HAVE_BACKTRACE_SYMBOLS
922 void *backtrace_stack
[BACKTRACE_STACK_SIZE
];
923 size_t backtrace_size
;
924 char **backtrace_strings
;
926 /* get the backtrace (stack frames) */
927 backtrace_size
= backtrace(backtrace_stack
,BACKTRACE_STACK_SIZE
);
928 backtrace_strings
= backtrace_symbols(backtrace_stack
, backtrace_size
);
930 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
931 (unsigned long)backtrace_size
));
933 if (backtrace_strings
) {
936 for (i
= 0; i
< backtrace_size
; i
++)
937 DEBUGADD(0, (" #%u %s\n", i
, backtrace_strings
[i
]));
939 /* Leak the backtrace_strings, rather than risk what free() might do */
944 /* The IRIX libexc library provides an API for unwinding the stack. See
945 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
946 * since we are about to abort anyway, it hardly matters.
949 #define NAMESIZE 32 /* Arbitrary */
951 __uint64_t addrs
[BACKTRACE_STACK_SIZE
];
952 char * names
[BACKTRACE_STACK_SIZE
];
953 char namebuf
[BACKTRACE_STACK_SIZE
* NAMESIZE
];
962 /* We need to be root so we can open our /proc entry to walk
963 * our stack. It also helps when we want to dump core.
967 for (i
= 0; i
< BACKTRACE_STACK_SIZE
; i
++) {
968 names
[i
] = namebuf
+ (i
* NAMESIZE
);
971 levels
= trace_back_stack(0, addrs
, names
,
972 BACKTRACE_STACK_SIZE
, NAMESIZE
- 1);
974 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels
));
975 for (i
= 0; i
< levels
; i
++) {
976 DEBUGADD(0, (" #%d 0x%llx %s\n", i
, addrs
[i
], names
[i
]));
981 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
985 /*******************************************************************
986 A readdir wrapper which just returns the file name.
987 ********************************************************************/
989 const char *readdirname(SMB_STRUCT_DIR
*p
)
991 SMB_STRUCT_DIRENT
*ptr
;
997 ptr
= (SMB_STRUCT_DIRENT
*)sys_readdir(p
);
1001 dname
= ptr
->d_name
;
1008 #ifdef HAVE_BROKEN_READDIR_NAME
1009 /* using /usr/ucb/cc is BAD */
1013 return talloc_strdup(talloc_tos(), dname
);
1016 /*******************************************************************
1017 Utility function used to decide if the last component
1018 of a path matches a (possibly wildcarded) entry in a namelist.
1019 ********************************************************************/
1021 bool is_in_path(const char *name
, name_compare_entry
*namelist
, bool case_sensitive
)
1023 const char *last_component
;
1025 /* if we have no list it's obviously not in the path */
1026 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
))) {
1030 DEBUG(8, ("is_in_path: %s\n", name
));
1032 /* Get the last component of the unix name. */
1033 last_component
= strrchr_m(name
, '/');
1034 if (!last_component
) {
1035 last_component
= name
;
1037 last_component
++; /* Go past '/' */
1040 for(; namelist
->name
!= NULL
; namelist
++) {
1041 if(namelist
->is_wild
) {
1042 if (mask_match(last_component
, namelist
->name
, case_sensitive
)) {
1043 DEBUG(8,("is_in_path: mask match succeeded\n"));
1047 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
1048 (!case_sensitive
&& (strcasecmp_m(last_component
, namelist
->name
) == 0))) {
1049 DEBUG(8,("is_in_path: match succeeded\n"));
1054 DEBUG(8,("is_in_path: match not found\n"));
1058 /*******************************************************************
1059 Strip a '/' separated list into an array of
1060 name_compare_enties structures suitable for
1061 passing to is_in_path(). We do this for
1062 speed so we can pre-parse all the names in the list
1063 and don't do it for each call to is_in_path().
1064 We also check if the entry contains a wildcard to
1065 remove a potentially expensive call to mask_match
1067 ********************************************************************/
1069 void set_namearray(name_compare_entry
**ppname_array
, const char *namelist_in
)
1074 int num_entries
= 0;
1077 (*ppname_array
) = NULL
;
1079 if((namelist_in
== NULL
) || ((namelist_in
!= NULL
) && (*namelist_in
== '\0')))
1082 namelist
= talloc_strdup(talloc_tos(), namelist_in
);
1083 if (namelist
== NULL
) {
1084 DEBUG(0,("set_namearray: talloc fail\n"));
1089 /* We need to make two passes over the string. The
1090 first to count the number of elements, the second
1095 if ( *nameptr
== '/' ) {
1096 /* cope with multiple (useless) /s) */
1100 /* anything left? */
1101 if ( *nameptr
== '\0' )
1104 /* find the next '/' or consume remaining */
1105 name_end
= strchr_m(nameptr
, '/');
1106 if (name_end
== NULL
)
1107 name_end
= (char *)nameptr
+ strlen(nameptr
);
1109 /* next segment please */
1110 nameptr
= name_end
+ 1;
1114 if(num_entries
== 0) {
1115 talloc_free(namelist
);
1119 if(( (*ppname_array
) = SMB_MALLOC_ARRAY(name_compare_entry
, num_entries
+ 1)) == NULL
) {
1120 DEBUG(0,("set_namearray: malloc fail\n"));
1121 talloc_free(namelist
);
1125 /* Now copy out the names */
1129 if ( *nameptr
== '/' ) {
1130 /* cope with multiple (useless) /s) */
1134 /* anything left? */
1135 if ( *nameptr
== '\0' )
1138 /* find the next '/' or consume remaining */
1139 name_end
= strchr_m(nameptr
, '/');
1143 name_end
= nameptr
+ strlen(nameptr
);
1145 (*ppname_array
)[i
].is_wild
= ms_has_wild(nameptr
);
1146 if(((*ppname_array
)[i
].name
= SMB_STRDUP(nameptr
)) == NULL
) {
1147 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1148 talloc_free(namelist
);
1152 /* next segment please */
1153 nameptr
= name_end
+ 1;
1157 (*ppname_array
)[i
].name
= NULL
;
1159 talloc_free(namelist
);
1164 #define DBGC_CLASS DBGC_LOCKING
1166 /****************************************************************************
1167 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1168 is dealt with in posix.c
1169 Returns True if we have information regarding this lock region (and returns
1170 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1171 ****************************************************************************/
1173 bool fcntl_getlock(int fd
, SMB_OFF_T
*poffset
, SMB_OFF_T
*pcount
, int *ptype
, pid_t
*ppid
)
1175 SMB_STRUCT_FLOCK lock
;
1178 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1179 fd
,(double)*poffset
,(double)*pcount
,*ptype
));
1181 lock
.l_type
= *ptype
;
1182 lock
.l_whence
= SEEK_SET
;
1183 lock
.l_start
= *poffset
;
1184 lock
.l_len
= *pcount
;
1187 ret
= sys_fcntl_ptr(fd
,SMB_F_GETLK
,&lock
);
1191 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1192 (double)*poffset
,(double)*pcount
,*ptype
,strerror(errno
)));
1197 *ptype
= lock
.l_type
;
1198 *poffset
= lock
.l_start
;
1199 *pcount
= lock
.l_len
;
1202 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1203 fd
, (int)lock
.l_type
, (unsigned int)lock
.l_pid
));
1208 #define DBGC_CLASS DBGC_ALL
1210 /*******************************************************************
1211 Is the name specified one of my netbios names.
1212 Returns true if it is equal, false otherwise.
1213 ********************************************************************/
1215 bool is_myname(const char *s
)
1220 for (n
=0; my_netbios_names(n
); n
++) {
1221 if (strequal(my_netbios_names(n
), s
)) {
1226 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));
1230 /*******************************************************************
1231 Is the name specified our workgroup/domain.
1232 Returns true if it is equal, false otherwise.
1233 ********************************************************************/
1235 bool is_myworkgroup(const char *s
)
1239 if (strequal(s
, lp_workgroup())) {
1243 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s
, ret
));
1247 /*******************************************************************
1248 we distinguish between 2K and XP by the "Native Lan Manager" string
1249 WinXP => "Windows 2002 5.1"
1250 WinXP 64bit => "Windows XP 5.2"
1251 Win2k => "Windows 2000 5.0"
1252 NT4 => "Windows NT 4.0"
1253 Win9x => "Windows 4.0"
1254 Windows 2003 doesn't set the native lan manager string but
1255 they do set the domain to "Windows 2003 5.2" (probably a bug).
1256 ********************************************************************/
1258 void ra_lanman_string( const char *native_lanman
)
1260 if ( strcmp( native_lanman
, "Windows 2002 5.1" ) == 0 )
1261 set_remote_arch( RA_WINXP
);
1262 else if ( strcmp( native_lanman
, "Windows XP 5.2" ) == 0 )
1263 set_remote_arch( RA_WINXP64
);
1264 else if ( strcmp( native_lanman
, "Windows Server 2003 5.2" ) == 0 )
1265 set_remote_arch( RA_WIN2K3
);
1268 static const char *remote_arch_str
;
1270 const char *get_remote_arch_str(void)
1272 if (!remote_arch_str
) {
1275 return remote_arch_str
;
1278 /*******************************************************************
1279 Set the horrid remote_arch string based on an enum.
1280 ********************************************************************/
1282 void set_remote_arch(enum remote_arch_types type
)
1287 remote_arch_str
= "WfWg";
1290 remote_arch_str
= "OS2";
1293 remote_arch_str
= "Win95";
1296 remote_arch_str
= "WinNT";
1299 remote_arch_str
= "Win2K";
1302 remote_arch_str
= "WinXP";
1305 remote_arch_str
= "WinXP64";
1308 remote_arch_str
= "Win2K3";
1311 remote_arch_str
= "Vista";
1314 remote_arch_str
= "Samba";
1317 remote_arch_str
= "CIFSFS";
1320 remote_arch_str
= "OSX";
1323 ra_type
= RA_UNKNOWN
;
1324 remote_arch_str
= "UNKNOWN";
1328 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1332 /*******************************************************************
1333 Get the remote_arch type.
1334 ********************************************************************/
1336 enum remote_arch_types
get_remote_arch(void)
1341 const char *tab_depth(int level
, int depth
)
1343 if( CHECK_DEBUGLVL(level
) ) {
1344 dbgtext("%*s", depth
*4, "");
1349 /*****************************************************************************
1350 Provide a checksum on a string
1352 Input: s - the null-terminated character string for which the checksum
1355 Output: The checksum value calculated for s.
1356 *****************************************************************************/
1358 int str_checksum(const char *s
)
1362 return hash(s
, strlen(s
), 0);
1365 /*****************************************************************
1366 Zero a memory area then free it. Used to catch bugs faster.
1367 *****************************************************************/
1369 void zero_free(void *p
, size_t size
)
1375 /*****************************************************************
1376 Set our open file limit to a requested max and return the limit.
1377 *****************************************************************/
1379 int set_maxfiles(int requested_max
)
1381 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1383 int saved_current_limit
;
1385 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
1386 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1389 return requested_max
;
1393 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1394 * account for the extra fd we need
1395 * as well as the log files and standard
1396 * handles etc. Save the limit we want to set in case
1397 * we are running on an OS that doesn't support this limit (AIX)
1398 * which always returns RLIM_INFINITY for rlp.rlim_max.
1401 /* Try raising the hard (max) limit to the requested amount. */
1403 #if defined(RLIM_INFINITY)
1404 if (rlp
.rlim_max
!= RLIM_INFINITY
) {
1405 int orig_max
= rlp
.rlim_max
;
1407 if ( rlp
.rlim_max
< requested_max
)
1408 rlp
.rlim_max
= requested_max
;
1410 /* This failing is not an error - many systems (Linux) don't
1411 support our default request of 10,000 open files. JRA. */
1413 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
1414 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1415 (int)rlp
.rlim_max
, strerror(errno
) ));
1417 /* Set failed - restore original value from get. */
1418 rlp
.rlim_max
= orig_max
;
1423 /* Now try setting the soft (current) limit. */
1425 saved_current_limit
= rlp
.rlim_cur
= MIN(requested_max
,rlp
.rlim_max
);
1427 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
1428 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1429 (int)rlp
.rlim_cur
, strerror(errno
) ));
1431 return saved_current_limit
;
1434 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
1435 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1438 return saved_current_limit
;
1441 #if defined(RLIM_INFINITY)
1442 if(rlp
.rlim_cur
== RLIM_INFINITY
)
1443 return saved_current_limit
;
1446 if((int)rlp
.rlim_cur
> saved_current_limit
)
1447 return saved_current_limit
;
1449 return rlp
.rlim_cur
;
1450 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1452 * No way to know - just guess...
1454 return requested_max
;
1458 /*****************************************************************
1459 malloc that aborts with smb_panic on fail or zero size.
1460 *****************************************************************/
1462 void *smb_xmalloc_array(size_t size
, unsigned int count
)
1466 smb_panic("smb_xmalloc_array: called with zero size");
1468 if (count
>= MAX_ALLOC_SIZE
/size
) {
1469 smb_panic("smb_xmalloc_array: alloc size too large");
1471 if ((p
= SMB_MALLOC(size
*count
)) == NULL
) {
1472 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1473 (unsigned long)size
, (unsigned long)count
));
1474 smb_panic("smb_xmalloc_array: malloc failed");
1480 vasprintf that aborts on malloc fail
1483 int smb_xvasprintf(char **ptr
, const char *format
, va_list ap
)
1490 n
= vasprintf(ptr
, format
, ap2
);
1492 if (n
== -1 || ! *ptr
) {
1493 smb_panic("smb_xvasprintf: out of memory");
1498 /*****************************************************************
1499 Get local hostname and cache result.
1500 *****************************************************************/
1502 char *myhostname(void)
1506 ret
= get_myname(NULL
);
1511 /*****************************************************************
1512 Get local hostname and cache result.
1513 *****************************************************************/
1515 char *myhostname_upper(void)
1520 name
= get_myname(talloc_tos());
1521 ret
= strupper_talloc(NULL
, name
);
1528 * @brief Returns an absolute path to a file concatenating the provided
1529 * @a rootpath and @a basename
1531 * @param name Filename, relative to @a rootpath
1533 * @retval Pointer to a string containing the full path.
1536 static char *xx_path(const char *name
, const char *rootpath
)
1540 fname
= talloc_strdup(talloc_tos(), rootpath
);
1544 trim_string(fname
,"","/");
1546 if (!directory_exist(fname
)) {
1547 if (!mkdir(fname
,0755))
1548 DEBUG(1, ("Unable to create directory %s for file %s. "
1549 "Error was %s\n", fname
, name
, strerror(errno
)));
1552 return talloc_asprintf(talloc_tos(),
1559 * @brief Returns an absolute path to a file in the Samba lock directory.
1561 * @param name File to find, relative to LOCKDIR.
1563 * @retval Pointer to a talloc'ed string containing the full path.
1566 char *lock_path(const char *name
)
1568 return xx_path(name
, lp_lockdir());
1572 * @brief Returns an absolute path to a file in the Samba pid directory.
1574 * @param name File to find, relative to PIDDIR.
1576 * @retval Pointer to a talloc'ed string containing the full path.
1579 char *pid_path(const char *name
)
1581 return xx_path(name
, lp_piddir());
1585 * @brief Returns an absolute path to a file in the Samba state directory.
1587 * @param name File to find, relative to STATEDIR.
1589 * @retval Pointer to a talloc'ed string containing the full path.
1592 char *state_path(const char *name
)
1594 return xx_path(name
, lp_statedir());
1598 * @brief Returns an absolute path to a file in the Samba cache directory.
1600 * @param name File to find, relative to CACHEDIR.
1602 * @retval Pointer to a talloc'ed string containing the full path.
1605 char *cache_path(const char *name
)
1607 return xx_path(name
, lp_cachedir());
1610 /*******************************************************************
1611 Given a filename - get its directory name
1612 ********************************************************************/
1614 bool parent_dirname(TALLOC_CTX
*mem_ctx
, const char *dir
, char **parent
,
1620 p
= strrchr_m(dir
, '/'); /* Find final '/', if any */
1623 if (!(*parent
= talloc_strdup(mem_ctx
, "."))) {
1634 if (!(*parent
= (char *)talloc_memdup(mem_ctx
, dir
, len
+1))) {
1637 (*parent
)[len
] = '\0';
1645 /*******************************************************************
1646 Determine if a pattern contains any Microsoft wildcard characters.
1647 *******************************************************************/
1649 bool ms_has_wild(const char *s
)
1653 if (lp_posix_pathnames()) {
1654 /* With posix pathnames no characters are wild. */
1658 while ((c
= *s
++)) {
1671 bool ms_has_wild_w(const smb_ucs2_t
*s
)
1674 if (!s
) return False
;
1675 while ((c
= *s
++)) {
1677 case UCS2_CHAR('*'):
1678 case UCS2_CHAR('?'):
1679 case UCS2_CHAR('<'):
1680 case UCS2_CHAR('>'):
1681 case UCS2_CHAR('"'):
1688 /*******************************************************************
1689 A wrapper that handles case sensitivity and the special handling
1691 *******************************************************************/
1693 bool mask_match(const char *string
, const char *pattern
, bool is_case_sensitive
)
1695 if (ISDOTDOT(string
))
1700 return ms_fnmatch(pattern
, string
, Protocol
<= PROTOCOL_LANMAN2
, is_case_sensitive
) == 0;
1703 /*******************************************************************
1704 A wrapper that handles case sensitivity and the special handling
1705 of the ".." name. Varient that is only called by old search code which requires
1706 pattern translation.
1707 *******************************************************************/
1709 bool mask_match_search(const char *string
, const char *pattern
, bool is_case_sensitive
)
1711 if (ISDOTDOT(string
))
1716 return ms_fnmatch(pattern
, string
, True
, is_case_sensitive
) == 0;
1719 /*******************************************************************
1720 A wrapper that handles a list of patters and calls mask_match()
1721 on each. Returns True if any of the patterns match.
1722 *******************************************************************/
1724 bool mask_match_list(const char *string
, char **list
, int listLen
, bool is_case_sensitive
)
1726 while (listLen
-- > 0) {
1727 if (mask_match(string
, *list
++, is_case_sensitive
))
1733 /*********************************************************
1734 Recursive routine that is called by unix_wild_match.
1735 *********************************************************/
1737 static bool unix_do_match(const char *regexp
, const char *str
)
1741 for( p
= regexp
; *p
&& *str
; ) {
1752 * Look for a character matching
1753 * the one after the '*'.
1757 return true; /* Automatic match */
1760 while(*str
&& (*p
!= *str
))
1764 * Patch from weidel@multichart.de. In the case of the regexp
1765 * '*XX*' we want to ensure there are at least 2 'X' characters
1766 * in the string after the '*' for a match to be made.
1773 * Eat all the characters that match, but count how many there were.
1776 while(*str
&& (*p
== *str
)) {
1782 * Now check that if the regexp had n identical characters that
1783 * matchcount had at least that many matches.
1786 while ( *(p
+1) && (*(p
+1) == *p
)) {
1791 if ( matchcount
<= 0 )
1795 str
--; /* We've eaten the match char after the '*' */
1797 if(unix_do_match(p
, str
))
1819 if (!*p
&& str
[0] == '.' && str
[1] == 0)
1822 if (!*str
&& *p
== '?') {
1828 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
1834 /*******************************************************************
1835 Simple case insensitive interface to a UNIX wildcard matcher.
1836 Returns True if match, False if not.
1837 *******************************************************************/
1839 bool unix_wild_match(const char *pattern
, const char *string
)
1841 TALLOC_CTX
*ctx
= talloc_stackframe();
1847 p2
= talloc_strdup(ctx
,pattern
);
1848 s2
= talloc_strdup(ctx
,string
);
1856 /* Remove any *? and ** from the pattern as they are meaningless */
1857 for(p
= p2
; *p
; p
++) {
1858 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*')) {
1859 memmove(&p
[1], &p
[2], strlen(&p
[2])+1);
1863 if (strequal(p2
,"*")) {
1868 ret
= unix_do_match(p2
, s2
);
1873 /**********************************************************************
1874 Converts a name to a fully qualified domain name.
1875 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1876 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1877 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1878 ***********************************************************************/
1880 bool name_to_fqdn(fstring fqdn
, const char *name
)
1883 struct hostent
*hp
= gethostbyname(name
);
1885 if (!hp
|| !hp
->h_name
|| !*hp
->h_name
) {
1886 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name
));
1887 fstrcpy(fqdn
, name
);
1891 /* Find out if the fqdn is returned as an alias
1892 * to cope with /etc/hosts files where the first
1893 * name is not the fqdn but the short name */
1894 if (hp
->h_aliases
&& (! strchr_m(hp
->h_name
, '.'))) {
1896 for (i
= 0; hp
->h_aliases
[i
]; i
++) {
1897 if (strchr_m(hp
->h_aliases
[i
], '.')) {
1898 full
= hp
->h_aliases
[i
];
1903 if (full
&& (strcasecmp_m(full
, "localhost.localdomain") == 0)) {
1904 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1905 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1906 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1907 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1914 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name
, full
));
1915 fstrcpy(fqdn
, full
);
1919 /**********************************************************************
1920 Append a DATA_BLOB to a talloc'ed object
1921 ***********************************************************************/
1923 void *talloc_append_blob(TALLOC_CTX
*mem_ctx
, void *buf
, DATA_BLOB blob
)
1925 size_t old_size
= 0;
1928 if (blob
.length
== 0) {
1933 old_size
= talloc_get_size(buf
);
1936 result
= (char *)TALLOC_REALLOC(mem_ctx
, buf
, old_size
+ blob
.length
);
1937 if (result
== NULL
) {
1941 memcpy(result
+ old_size
, blob
.data
, blob
.length
);
1945 uint32
map_share_mode_to_deny_mode(uint32 share_access
, uint32 private_options
)
1947 switch (share_access
& ~FILE_SHARE_DELETE
) {
1948 case FILE_SHARE_NONE
:
1950 case FILE_SHARE_READ
:
1952 case FILE_SHARE_WRITE
:
1954 case FILE_SHARE_READ
|FILE_SHARE_WRITE
:
1957 if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) {
1959 } else if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
) {
1966 pid_t
procid_to_pid(const struct server_id
*proc
)
1971 static uint32 my_vnn
= NONCLUSTER_VNN
;
1973 void set_my_vnn(uint32 vnn
)
1975 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn
));
1979 uint32
get_my_vnn(void)
1984 static uint64_t my_unique_id
= 0;
1986 void set_my_unique_id(uint64_t unique_id
)
1988 my_unique_id
= unique_id
;
1991 struct server_id
pid_to_procid(pid_t pid
)
1993 struct server_id result
;
1996 result
.unique_id
= my_unique_id
;
1997 result
.vnn
= my_vnn
;
2001 struct server_id
procid_self(void)
2003 return pid_to_procid(sys_getpid());
2006 bool procid_equal(const struct server_id
*p1
, const struct server_id
*p2
)
2008 if (p1
->pid
!= p2
->pid
)
2010 if (p1
->task_id
!= p2
->task_id
)
2012 if (p1
->vnn
!= p2
->vnn
)
2017 bool cluster_id_equal(const struct server_id
*id1
,
2018 const struct server_id
*id2
)
2020 return procid_equal(id1
, id2
);
2023 bool procid_is_me(const struct server_id
*pid
)
2025 if (pid
->pid
!= sys_getpid())
2027 if (pid
->task_id
!= 0)
2029 if (pid
->vnn
!= my_vnn
)
2034 struct server_id
interpret_pid(const char *pid_string
)
2036 struct server_id result
;
2037 unsigned long long pid
;
2038 unsigned int vnn
, task_id
= 0;
2040 ZERO_STRUCT(result
);
2042 /* We accept various forms with 1, 2 or 3 component forms
2043 * because the server_id_str() can print different forms, and
2044 * we want backwards compatibility for scripts that may call
2046 if (sscanf(pid_string
, "%u:%llu.%u", &vnn
, &pid
, &task_id
) == 3) {
2049 result
.task_id
= task_id
;
2050 } else if (sscanf(pid_string
, "%u:%llu", &vnn
, &pid
) == 2) {
2054 } else if (sscanf(pid_string
, "%llu.%u", &pid
, &task_id
) == 2) {
2055 result
.vnn
= get_my_vnn();
2057 result
.task_id
= task_id
;
2058 } else if (sscanf(pid_string
, "%llu", &pid
) == 1) {
2059 result
.vnn
= get_my_vnn();
2062 result
.vnn
= NONCLUSTER_VNN
;
2063 result
.pid
= (uint64_t)-1;
2068 char *procid_str_static(const struct server_id
*pid
)
2070 return server_id_str(talloc_tos(), pid
);
2073 bool procid_valid(const struct server_id
*pid
)
2075 return (pid
->pid
!= (uint64_t)-1);
2078 bool procid_is_local(const struct server_id
*pid
)
2080 return pid
->vnn
== my_vnn
;
2083 /****************************************************************
2084 Check if an offset into a buffer is safe.
2085 If this returns True it's safe to indirect into the byte at
2087 ****************************************************************/
2089 bool is_offset_safe(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2091 const char *end_base
= buf_base
+ buf_len
;
2092 char *end_ptr
= ptr
+ off
;
2094 if (!buf_base
|| !ptr
) {
2098 if (end_base
< buf_base
|| end_ptr
< ptr
) {
2099 return False
; /* wrap. */
2102 if (end_ptr
< end_base
) {
2108 /****************************************************************
2109 Return a safe pointer into a buffer, or NULL.
2110 ****************************************************************/
2112 char *get_safe_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2114 return is_offset_safe(buf_base
, buf_len
, ptr
, off
) ?
2118 /****************************************************************
2119 Return a safe pointer into a string within a buffer, or NULL.
2120 ****************************************************************/
2122 char *get_safe_str_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2124 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
)) {
2127 /* Check if a valid string exists at this offset. */
2128 if (skip_string(buf_base
,buf_len
, ptr
+ off
) == NULL
) {
2134 /****************************************************************
2135 Return an SVAL at a pointer, or failval if beyond the end.
2136 ****************************************************************/
2138 int get_safe_SVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2141 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2144 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+1)) {
2147 return SVAL(ptr
,off
);
2150 /****************************************************************
2151 Return an IVAL at a pointer, or failval if beyond the end.
2152 ****************************************************************/
2154 int get_safe_IVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2157 * Note we use off+3 here, not off+4 as IVAL accesses
2158 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2160 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+3)) {
2163 return IVAL(ptr
,off
);
2166 /****************************************************************
2167 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2168 call (they take care of winbind separator and other winbind specific settings).
2169 ****************************************************************/
2171 void split_domain_user(TALLOC_CTX
*mem_ctx
,
2172 const char *full_name
,
2176 const char *p
= NULL
;
2178 p
= strchr_m(full_name
, '\\');
2181 *domain
= talloc_strndup(mem_ctx
, full_name
,
2182 PTR_DIFF(p
, full_name
));
2183 *user
= talloc_strdup(mem_ctx
, p
+1);
2185 *domain
= talloc_strdup(mem_ctx
, "");
2186 *user
= talloc_strdup(mem_ctx
, full_name
);
2190 /****************************************************************
2191 strip off leading '\\' from a hostname
2192 ****************************************************************/
2194 const char *strip_hostname(const char *s
)
2200 if (strlen_m(s
) < 3) {
2204 if (s
[0] == '\\') s
++;
2205 if (s
[0] == '\\') s
++;
2210 bool tevent_req_poll_ntstatus(struct tevent_req
*req
,
2211 struct tevent_context
*ev
,
2214 bool ret
= tevent_req_poll(req
, ev
);
2216 *status
= map_nt_error_from_unix(errno
);
2221 bool any_nt_status_not_ok(NTSTATUS err1
, NTSTATUS err2
, NTSTATUS
*result
)
2223 if (!NT_STATUS_IS_OK(err1
)) {
2227 if (!NT_STATUS_IS_OK(err2
)) {
2234 int timeval_to_msec(struct timeval t
)
2236 return t
.tv_sec
* 1000 + (t
.tv_usec
+999) / 1000;
2239 /*******************************************************************
2240 Check a given DOS pathname is valid for a share.
2241 ********************************************************************/
2243 char *valid_share_pathname(TALLOC_CTX
*ctx
, const char *dos_pathname
)
2247 if (!dos_pathname
) {
2251 ptr
= talloc_strdup(ctx
, dos_pathname
);
2255 /* Convert any '\' paths to '/' */
2257 ptr
= unix_clean_name(ctx
, ptr
);
2262 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2263 if (strlen(ptr
) > 2 && ptr
[1] == ':' && ptr
[0] != '/')
2266 /* Only absolute paths allowed. */
2273 /*******************************************************************
2274 Return True if the filename is one of the special executable types.
2275 ********************************************************************/
2277 bool is_executable(const char *fname
)
2279 if ((fname
= strrchr_m(fname
,'.'))) {
2280 if (strequal(fname
,".com") ||
2281 strequal(fname
,".dll") ||
2282 strequal(fname
,".exe") ||
2283 strequal(fname
,".sym")) {
2290 /****************************************************************************
2291 Open a file with a share mode - old openX method - map into NTCreate.
2292 ****************************************************************************/
2294 bool map_open_params_to_ntcreate(const char *smb_base_fname
,
2295 int deny_mode
, int open_func
,
2296 uint32
*paccess_mask
,
2297 uint32
*pshare_mode
,
2298 uint32
*pcreate_disposition
,
2299 uint32
*pcreate_options
,
2300 uint32_t *pprivate_flags
)
2304 uint32 create_disposition
;
2305 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
2306 uint32_t private_flags
= 0;
2308 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2309 "open_func = 0x%x\n",
2310 smb_base_fname
, (unsigned int)deny_mode
,
2311 (unsigned int)open_func
));
2313 /* Create the NT compatible access_mask. */
2314 switch (GET_OPENX_MODE(deny_mode
)) {
2315 case DOS_OPEN_EXEC
: /* Implies read-only - used to be FILE_READ_DATA */
2316 case DOS_OPEN_RDONLY
:
2317 access_mask
= FILE_GENERIC_READ
;
2319 case DOS_OPEN_WRONLY
:
2320 access_mask
= FILE_GENERIC_WRITE
;
2324 access_mask
= FILE_GENERIC_READ
|FILE_GENERIC_WRITE
;
2327 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2328 (unsigned int)GET_OPENX_MODE(deny_mode
)));
2332 /* Create the NT compatible create_disposition. */
2333 switch (open_func
) {
2334 case OPENX_FILE_EXISTS_FAIL
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2335 create_disposition
= FILE_CREATE
;
2338 case OPENX_FILE_EXISTS_OPEN
:
2339 create_disposition
= FILE_OPEN
;
2342 case OPENX_FILE_EXISTS_OPEN
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2343 create_disposition
= FILE_OPEN_IF
;
2346 case OPENX_FILE_EXISTS_TRUNCATE
:
2347 create_disposition
= FILE_OVERWRITE
;
2350 case OPENX_FILE_EXISTS_TRUNCATE
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2351 create_disposition
= FILE_OVERWRITE_IF
;
2355 /* From samba4 - to be confirmed. */
2356 if (GET_OPENX_MODE(deny_mode
) == DOS_OPEN_EXEC
) {
2357 create_disposition
= FILE_CREATE
;
2360 DEBUG(10,("map_open_params_to_ntcreate: bad "
2361 "open_func 0x%x\n", (unsigned int)open_func
));
2365 /* Create the NT compatible share modes. */
2366 switch (GET_DENY_MODE(deny_mode
)) {
2368 share_mode
= FILE_SHARE_NONE
;
2372 share_mode
= FILE_SHARE_READ
;
2376 share_mode
= FILE_SHARE_WRITE
;
2380 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
2384 private_flags
|= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
;
2385 if (is_executable(smb_base_fname
)) {
2386 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
2388 if (GET_OPENX_MODE(deny_mode
) == DOS_OPEN_RDONLY
) {
2389 share_mode
= FILE_SHARE_READ
;
2391 share_mode
= FILE_SHARE_NONE
;
2397 private_flags
|= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
;
2398 share_mode
= FILE_SHARE_NONE
;
2402 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2403 (unsigned int)GET_DENY_MODE(deny_mode
) ));
2407 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2408 "share_mode = 0x%x, create_disposition = 0x%x, "
2409 "create_options = 0x%x private_flags = 0x%x\n",
2411 (unsigned int)access_mask
,
2412 (unsigned int)share_mode
,
2413 (unsigned int)create_disposition
,
2414 (unsigned int)create_options
,
2415 (unsigned int)private_flags
));
2418 *paccess_mask
= access_mask
;
2421 *pshare_mode
= share_mode
;
2423 if (pcreate_disposition
) {
2424 *pcreate_disposition
= create_disposition
;
2426 if (pcreate_options
) {
2427 *pcreate_options
= create_options
;
2429 if (pprivate_flags
) {
2430 *pprivate_flags
= private_flags
;
2438 void init_modules(void)
2440 /* FIXME: This can cause undefined symbol errors :
2441 * smb_register_vfs() isn't available in nmbd, for example */
2442 if(lp_preload_modules())
2443 smb_load_modules(lp_preload_modules());