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 #include "lib/sys_rw.h"
35 #include "lib/sys_rw_data.h"
37 #ifdef HAVE_SYS_PRCTL_H
38 #include <sys/prctl.h>
41 /* Max allowable allococation - 256mb - 0x10000000 */
42 #define MAX_ALLOC_SIZE (1024*1024*256)
44 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
45 #ifdef WITH_NISPLUS_HOME
46 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
48 * The following lines are needed due to buggy include files
49 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
50 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
51 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
52 * an enum in /usr/include/rpcsvc/nis.h.
59 #if defined(GROUP_OBJ)
63 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
65 #include <rpcsvc/nis.h>
67 #endif /* WITH_NISPLUS_HOME */
68 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
70 static enum protocol_types Protocol
= PROTOCOL_COREPLUS
;
72 enum protocol_types
get_Protocol(void)
77 void set_Protocol(enum protocol_types p
)
82 static enum remote_arch_types ra_type
= RA_UNKNOWN
;
84 void gfree_all( void )
93 /*******************************************************************
94 Check if a file exists - call vfs_file_exist for samba files.
95 ********************************************************************/
97 bool file_exist_stat(const char *fname
,SMB_STRUCT_STAT
*sbuf
,
98 bool fake_dir_create_times
)
104 if (sys_stat(fname
, sbuf
, fake_dir_create_times
) != 0)
107 return((S_ISREG(sbuf
->st_ex_mode
)) || (S_ISFIFO(sbuf
->st_ex_mode
)));
110 /*******************************************************************
111 Check if a unix domain socket exists - call vfs_file_exist for samba files.
112 ********************************************************************/
114 bool socket_exist(const char *fname
)
117 if (sys_stat(fname
, &st
, false) != 0)
120 return S_ISSOCK(st
.st_ex_mode
);
123 /*******************************************************************
124 Returns the size in bytes of the named given the stat struct.
125 ********************************************************************/
127 uint64_t get_file_size_stat(const SMB_STRUCT_STAT
*sbuf
)
129 return sbuf
->st_ex_size
;
132 /****************************************************************************
133 Check two stats have identical dev and ino fields.
134 ****************************************************************************/
136 bool check_same_dev_ino(const SMB_STRUCT_STAT
*sbuf1
,
137 const SMB_STRUCT_STAT
*sbuf2
)
139 if (sbuf1
->st_ex_dev
!= sbuf2
->st_ex_dev
||
140 sbuf1
->st_ex_ino
!= sbuf2
->st_ex_ino
) {
146 /****************************************************************************
147 Check if a stat struct is identical for use.
148 ****************************************************************************/
150 bool check_same_stat(const SMB_STRUCT_STAT
*sbuf1
,
151 const SMB_STRUCT_STAT
*sbuf2
)
153 if (sbuf1
->st_ex_uid
!= sbuf2
->st_ex_uid
||
154 sbuf1
->st_ex_gid
!= sbuf2
->st_ex_gid
||
155 !check_same_dev_ino(sbuf1
, sbuf2
)) {
161 /*******************************************************************
162 Show a smb message structure.
163 ********************************************************************/
165 void show_msg(const char *buf
)
173 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
175 (int)CVAL(buf
,smb_com
),
176 (int)CVAL(buf
,smb_rcls
),
177 (int)CVAL(buf
,smb_reh
),
178 (int)SVAL(buf
,smb_err
),
179 (int)CVAL(buf
,smb_flg
),
180 (int)SVAL(buf
,smb_flg2
)));
181 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
182 (int)SVAL(buf
,smb_tid
),
183 (int)SVAL(buf
,smb_pid
),
184 (int)SVAL(buf
,smb_uid
),
185 (int)SVAL(buf
,smb_mid
)));
186 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf
,smb_wct
)));
188 for (i
=0;i
<(int)CVAL(buf
,smb_wct
);i
++)
189 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i
,
190 SVAL(buf
,smb_vwv
+2*i
),SVAL(buf
,smb_vwv
+2*i
)));
192 bcc
= (int)SVAL(buf
,smb_vwv
+2*(CVAL(buf
,smb_wct
)));
194 DEBUGADD(5,("smb_bcc=%d\n",bcc
));
202 dump_data(10, (const uint8
*)smb_buf_const(buf
), bcc
);
205 /*******************************************************************
206 Setup only the byte count for a smb message.
207 ********************************************************************/
209 int set_message_bcc(char *buf
,int num_bytes
)
211 int num_words
= CVAL(buf
,smb_wct
);
212 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
213 _smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
214 return (smb_size
+ num_words
*2 + num_bytes
);
217 /*******************************************************************
218 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
219 Return the bytes added
220 ********************************************************************/
222 ssize_t
message_push_blob(uint8
**outbuf
, DATA_BLOB blob
)
224 size_t newlen
= smb_len(*outbuf
) + 4 + blob
.length
;
227 if (!(tmp
= talloc_realloc(NULL
, *outbuf
, uint8
, newlen
))) {
228 DEBUG(0, ("talloc failed\n"));
233 memcpy(tmp
+ smb_len(tmp
) + 4, blob
.data
, blob
.length
);
234 set_message_bcc((char *)tmp
, smb_buflen(tmp
) + blob
.length
);
238 /*******************************************************************
239 Reduce a file name, removing .. elements.
240 ********************************************************************/
242 static char *dos_clean_name(TALLOC_CTX
*ctx
, const char *s
)
247 DEBUG(3,("dos_clean_name [%s]\n",s
));
249 /* remove any double slashes */
250 str
= talloc_all_string_sub(ctx
, s
, "\\\\", "\\");
255 /* Remove leading .\\ characters */
256 if(strncmp(str
, ".\\", 2) == 0) {
257 trim_string(str
, ".\\", NULL
);
259 str
= talloc_strdup(ctx
, ".\\");
266 while ((p
= strstr_m(str
,"\\..\\")) != NULL
) {
272 if ((p
=strrchr_m(str
,'\\')) != NULL
) {
277 str
= talloc_asprintf(ctx
,
286 trim_string(str
,NULL
,"\\..");
287 return talloc_all_string_sub(ctx
, str
, "\\.\\", "\\");
290 /*******************************************************************
291 Reduce a file name, removing .. elements.
292 ********************************************************************/
294 char *unix_clean_name(TALLOC_CTX
*ctx
, const char *s
)
299 DEBUG(3,("unix_clean_name [%s]\n",s
));
301 /* remove any double slashes */
302 str
= talloc_all_string_sub(ctx
, s
, "//","/");
307 /* Remove leading ./ characters */
308 if(strncmp(str
, "./", 2) == 0) {
309 trim_string(str
, "./", NULL
);
311 str
= talloc_strdup(ctx
, "./");
318 while ((p
= strstr_m(str
,"/../")) != NULL
) {
324 if ((p
=strrchr_m(str
,'/')) != NULL
) {
329 str
= talloc_asprintf(ctx
,
338 trim_string(str
,NULL
,"/..");
339 return talloc_all_string_sub(ctx
, str
, "/./", "/");
342 char *clean_name(TALLOC_CTX
*ctx
, const char *s
)
344 char *str
= dos_clean_name(ctx
, s
);
348 return unix_clean_name(ctx
, str
);
351 /*******************************************************************
352 Write data into an fd at a given offset. Ignore seek errors.
353 ********************************************************************/
355 ssize_t
write_data_at_offset(int fd
, const char *buffer
, size_t N
, off_t pos
)
360 if (pos
== (off_t
)-1) {
361 return write_data(fd
, buffer
, N
);
363 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
365 ret
= sys_pwrite(fd
,buffer
+ total
,N
- total
, pos
);
366 if (ret
== -1 && errno
== ESPIPE
) {
367 return write_data(fd
, buffer
+ total
,N
- total
);
370 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno
) ));
379 return (ssize_t
)total
;
381 /* Use lseek and write_data. */
382 if (lseek(fd
, pos
, SEEK_SET
) == -1) {
383 if (errno
!= ESPIPE
) {
387 return write_data(fd
, buffer
, N
);
391 static int reinit_after_fork_pipe
[2] = { -1, -1 };
393 NTSTATUS
init_before_fork(void)
397 ret
= pipe(reinit_after_fork_pipe
);
401 status
= map_nt_error_from_unix_common(errno
);
403 DEBUG(0, ("Error creating child_pipe: %s\n",
413 * Detect died parent by detecting EOF on the pipe
415 static void reinit_after_fork_pipe_handler(struct tevent_context
*ev
,
416 struct tevent_fd
*fde
,
422 if (sys_read(reinit_after_fork_pipe
[0], &c
, 1) != 1) {
424 * we have reached EOF on stdin, which means the
425 * parent has exited. Shutdown the server
427 (void)kill(getpid(), SIGTERM
);
432 NTSTATUS
reinit_after_fork(struct messaging_context
*msg_ctx
,
433 struct tevent_context
*ev_ctx
,
434 bool parent_longlived
)
436 NTSTATUS status
= NT_STATUS_OK
;
438 if (reinit_after_fork_pipe
[1] != -1) {
439 close(reinit_after_fork_pipe
[1]);
440 reinit_after_fork_pipe
[1] = -1;
443 /* Reset the state of the random
444 * number generation system, so
445 * children do not get the same random
446 * numbers as each other */
447 set_need_random_reseed();
449 /* tdb needs special fork handling */
450 if (tdb_reopen_all(parent_longlived
? 1 : 0) != 0) {
451 DEBUG(0,("tdb_reopen_all failed.\n"));
452 status
= NT_STATUS_OPEN_FAILED
;
456 if (ev_ctx
!= NULL
) {
457 tevent_set_trace_callback(ev_ctx
, NULL
, NULL
);
458 if (tevent_re_initialise(ev_ctx
) != 0) {
459 smb_panic(__location__
": Failed to re-initialise event context");
463 if (reinit_after_fork_pipe
[0] != -1) {
464 struct tevent_fd
*fde
;
466 fde
= tevent_add_fd(ev_ctx
, ev_ctx
/* TALLOC_CTX */,
467 reinit_after_fork_pipe
[0], TEVENT_FD_READ
,
468 reinit_after_fork_pipe_handler
, NULL
);
470 smb_panic(__location__
": Failed to add reinit_after_fork pipe event");
476 * For clustering, we need to re-init our ctdbd connection after the
479 status
= messaging_reinit(msg_ctx
);
480 if (!NT_STATUS_IS_OK(status
)) {
481 DEBUG(0,("messaging_reinit() failed: %s\n",
489 /****************************************************************************
490 (Hopefully) efficient array append.
491 ****************************************************************************/
493 void add_to_large_array(TALLOC_CTX
*mem_ctx
, size_t element_size
,
494 void *element
, void *_array
, uint32
*num_elements
,
497 void **array
= (void **)_array
;
499 if (*array_size
< 0) {
503 if (*array
== NULL
) {
504 if (*array_size
== 0) {
508 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
512 *array
= TALLOC(mem_ctx
, element_size
* (*array_size
));
513 if (*array
== NULL
) {
518 if (*num_elements
== *array_size
) {
521 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
525 *array
= TALLOC_REALLOC(mem_ctx
, *array
,
526 element_size
* (*array_size
));
528 if (*array
== NULL
) {
533 memcpy((char *)(*array
) + element_size
*(*num_elements
),
534 element
, element_size
);
544 /****************************************************************************
545 Get my own domain name, or "" if we have none.
546 ****************************************************************************/
548 char *get_mydnsdomname(TALLOC_CTX
*ctx
)
553 domname
= get_mydnsfullname();
558 p
= strchr_m(domname
, '.');
561 return talloc_strdup(ctx
, p
);
563 return talloc_strdup(ctx
, "");
567 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
568 /******************************************************************
569 Remove any mount options such as -rsize=2048,wsize=2048 etc.
570 Based on a fix from <Thomas.Hepper@icem.de>.
571 Returns a malloc'ed string.
572 *******************************************************************/
574 static char *strip_mount_options(TALLOC_CTX
*ctx
, const char *str
)
578 while(*p
&& !isspace(*p
))
580 while(*p
&& isspace(*p
))
583 return talloc_strdup(ctx
, p
);
589 /*******************************************************************
590 Patch from jkf@soton.ac.uk
591 Split Luke's automount_server into YP lookup and string splitter
592 so can easily implement automount_path().
593 Returns a malloc'ed string.
594 *******************************************************************/
596 #ifdef WITH_NISPLUS_HOME
597 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
601 char *nis_map
= (char *)lp_homedir_map();
603 char buffer
[NIS_MAXATTRVAL
+ 1];
608 snprintf(buffer
, sizeof(buffer
), "[key=%s],%s", user_name
, nis_map
);
609 DEBUG(5, ("NIS+ querystring: %s\n", buffer
));
611 if (result
= nis_list(buffer
, FOLLOW_PATH
|EXPAND_NAME
|HARD_LOOKUP
, NULL
, NULL
)) {
612 if (result
->status
!= NIS_SUCCESS
) {
613 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result
->status
)));
615 object
= result
->objects
.objects_val
;
616 if (object
->zo_data
.zo_type
== ENTRY_OBJ
) {
617 entry
= &object
->zo_data
.objdata_u
.en_data
;
618 DEBUG(5, ("NIS+ entry type: %s\n", entry
->en_type
));
619 DEBUG(3, ("NIS+ result: %s\n", entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
));
621 value
= talloc_strdup(ctx
,
622 entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
);
624 nis_freeresult(result
);
627 value
= talloc_string_sub(ctx
,
634 nis_freeresult(result
);
637 value
= strip_mount_options(ctx
, value
);
638 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
643 #else /* WITH_NISPLUS_HOME */
645 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
649 int nis_error
; /* returned by yp all functions */
650 char *nis_result
; /* yp_match inits this */
651 int nis_result_len
; /* and set this */
652 char *nis_domain
; /* yp_get_default_domain inits this */
653 char *nis_map
= lp_homedir_map(talloc_tos());
655 if ((nis_error
= yp_get_default_domain(&nis_domain
)) != 0) {
656 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error
)));
660 DEBUG(5, ("NIS Domain: %s\n", nis_domain
));
662 if ((nis_error
= yp_match(nis_domain
, nis_map
, user_name
,
663 strlen(user_name
), &nis_result
,
664 &nis_result_len
)) == 0) {
665 if (nis_result_len
> 0 && nis_result
[nis_result_len
] == '\n') {
666 nis_result
[nis_result_len
] = '\0';
668 value
= talloc_strdup(ctx
, nis_result
);
672 value
= strip_mount_options(ctx
, value
);
673 } else if(nis_error
== YPERR_KEY
) {
674 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
675 user_name
, nis_map
));
676 DEBUG(3, ("using defaults for server and home directory\n"));
678 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
679 yperr_string(nis_error
), user_name
, nis_map
));
683 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name
, value
));
687 #endif /* WITH_NISPLUS_HOME */
690 bool process_exists(const struct server_id pid
)
692 return serverid_exists(&pid
);
695 /*******************************************************************
696 Convert a uid into a user name.
697 ********************************************************************/
699 const char *uidtoname(uid_t uid
)
701 TALLOC_CTX
*ctx
= talloc_tos();
703 struct passwd
*pass
= NULL
;
705 pass
= getpwuid_alloc(ctx
,uid
);
707 name
= talloc_strdup(ctx
,pass
->pw_name
);
710 name
= talloc_asprintf(ctx
,
717 /*******************************************************************
718 Convert a gid into a group name.
719 ********************************************************************/
721 char *gidtoname(gid_t gid
)
727 return talloc_strdup(talloc_tos(), grp
->gr_name
);
730 return talloc_asprintf(talloc_tos(),
736 /*******************************************************************
737 Convert a user name into a uid.
738 ********************************************************************/
740 uid_t
nametouid(const char *name
)
746 pass
= Get_Pwnam_alloc(talloc_tos(), name
);
753 u
= (uid_t
)strtol(name
, &p
, 0);
754 if ((p
!= name
) && (*p
== '\0'))
760 /*******************************************************************
761 Convert a name to a gid_t if possible. Return -1 if not a group.
762 ********************************************************************/
764 gid_t
nametogid(const char *name
)
770 g
= (gid_t
)strtol(name
, &p
, 0);
771 if ((p
!= name
) && (*p
== '\0'))
774 grp
= getgrnam(name
);
780 /*******************************************************************
781 Something really nasty happened - panic !
782 ********************************************************************/
784 void smb_panic_s3(const char *why
)
789 DEBUG(0,("PANIC (pid %llu): %s\n",
790 (unsigned long long)getpid(), why
));
793 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
795 * Make sure all children can attach a debugger.
797 prctl(PR_SET_PTRACER
, getpid(), 0, 0, 0);
800 cmd
= lp_panic_action(talloc_tos());
802 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd
));
803 result
= system(cmd
);
806 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
809 DEBUG(0, ("smb_panic(): action returned status %d\n",
810 WEXITSTATUS(result
)));
816 /*******************************************************************
817 Print a backtrace of the stack to the debug log. This function
818 DELIBERATELY LEAKS MEMORY. The expectation is that you should
819 exit shortly after calling it.
820 ********************************************************************/
822 #ifdef HAVE_LIBUNWIND_H
823 #include <libunwind.h>
826 #ifdef HAVE_EXECINFO_H
827 #include <execinfo.h>
834 void log_stack_trace(void)
836 #ifdef HAVE_LIBUNWIND
837 /* Try to use libunwind before any other technique since on ia64
838 * libunwind correctly walks the stack in more circumstances than
846 unw_word_t ip
, sp
, off
;
848 procname
[sizeof(procname
) - 1] = '\0';
850 if (unw_getcontext(&uc
) != 0) {
851 goto libunwind_failed
;
854 if (unw_init_local(&cursor
, &uc
) != 0) {
855 goto libunwind_failed
;
858 DEBUG(0, ("BACKTRACE:\n"));
862 unw_get_reg(&cursor
, UNW_REG_IP
, &ip
);
863 unw_get_reg(&cursor
, UNW_REG_SP
, &sp
);
865 switch (unw_get_proc_name(&cursor
,
866 procname
, sizeof(procname
) - 1, &off
) ) {
870 /* Name truncated. */
871 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
872 i
, procname
, (long long)off
,
873 (long long)ip
, (long long) sp
));
876 /* case -UNW_ENOINFO: */
877 /* case -UNW_EUNSPEC: */
878 /* No symbol name found. */
879 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
880 i
, "<unknown symbol>",
881 (long long)ip
, (long long) sp
));
884 } while (unw_step(&cursor
) > 0);
889 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
891 #elif HAVE_BACKTRACE_SYMBOLS
892 void *backtrace_stack
[BACKTRACE_STACK_SIZE
];
893 size_t backtrace_size
;
894 char **backtrace_strings
;
896 /* get the backtrace (stack frames) */
897 backtrace_size
= backtrace(backtrace_stack
,BACKTRACE_STACK_SIZE
);
898 backtrace_strings
= backtrace_symbols(backtrace_stack
, backtrace_size
);
900 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
901 (unsigned long)backtrace_size
));
903 if (backtrace_strings
) {
906 for (i
= 0; i
< backtrace_size
; i
++)
907 DEBUGADD(0, (" #%u %s\n", i
, backtrace_strings
[i
]));
909 /* Leak the backtrace_strings, rather than risk what free() might do */
914 /* The IRIX libexc library provides an API for unwinding the stack. See
915 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
916 * since we are about to abort anyway, it hardly matters.
919 #define NAMESIZE 32 /* Arbitrary */
921 __uint64_t addrs
[BACKTRACE_STACK_SIZE
];
922 char * names
[BACKTRACE_STACK_SIZE
];
923 char namebuf
[BACKTRACE_STACK_SIZE
* NAMESIZE
];
932 /* We need to be root so we can open our /proc entry to walk
933 * our stack. It also helps when we want to dump core.
937 for (i
= 0; i
< BACKTRACE_STACK_SIZE
; i
++) {
938 names
[i
] = namebuf
+ (i
* NAMESIZE
);
941 levels
= trace_back_stack(0, addrs
, names
,
942 BACKTRACE_STACK_SIZE
, NAMESIZE
- 1);
944 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels
));
945 for (i
= 0; i
< levels
; i
++) {
946 DEBUGADD(0, (" #%d 0x%llx %s\n", i
, addrs
[i
], names
[i
]));
951 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
955 /*******************************************************************
956 A readdir wrapper which just returns the file name.
957 ********************************************************************/
959 const char *readdirname(DIR *p
)
967 ptr
= (struct dirent
*)readdir(p
);
978 #ifdef HAVE_BROKEN_READDIR_NAME
979 /* using /usr/ucb/cc is BAD */
983 return talloc_strdup(talloc_tos(), dname
);
986 /*******************************************************************
987 Utility function used to decide if the last component
988 of a path matches a (possibly wildcarded) entry in a namelist.
989 ********************************************************************/
991 bool is_in_path(const char *name
, name_compare_entry
*namelist
, bool case_sensitive
)
993 const char *last_component
;
995 /* if we have no list it's obviously not in the path */
996 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
))) {
1000 DEBUG(8, ("is_in_path: %s\n", name
));
1002 /* Get the last component of the unix name. */
1003 last_component
= strrchr_m(name
, '/');
1004 if (!last_component
) {
1005 last_component
= name
;
1007 last_component
++; /* Go past '/' */
1010 for(; namelist
->name
!= NULL
; namelist
++) {
1011 if(namelist
->is_wild
) {
1012 if (mask_match(last_component
, namelist
->name
, case_sensitive
)) {
1013 DEBUG(8,("is_in_path: mask match succeeded\n"));
1017 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
1018 (!case_sensitive
&& (strcasecmp_m(last_component
, namelist
->name
) == 0))) {
1019 DEBUG(8,("is_in_path: match succeeded\n"));
1024 DEBUG(8,("is_in_path: match not found\n"));
1028 /*******************************************************************
1029 Strip a '/' separated list into an array of
1030 name_compare_enties structures suitable for
1031 passing to is_in_path(). We do this for
1032 speed so we can pre-parse all the names in the list
1033 and don't do it for each call to is_in_path().
1034 We also check if the entry contains a wildcard to
1035 remove a potentially expensive call to mask_match
1037 ********************************************************************/
1039 void set_namearray(name_compare_entry
**ppname_array
, const char *namelist_in
)
1045 int num_entries
= 0;
1048 (*ppname_array
) = NULL
;
1050 if((namelist_in
== NULL
) || ((namelist_in
!= NULL
) && (*namelist_in
== '\0')))
1053 namelist
= talloc_strdup(talloc_tos(), namelist_in
);
1054 if (namelist
== NULL
) {
1055 DEBUG(0,("set_namearray: talloc fail\n"));
1060 namelist_end
= &namelist
[strlen(namelist
)];
1062 /* We need to make two passes over the string. The
1063 first to count the number of elements, the second
1067 while(nameptr
<= namelist_end
) {
1068 if ( *nameptr
== '/' ) {
1069 /* cope with multiple (useless) /s) */
1073 /* anything left? */
1074 if ( *nameptr
== '\0' )
1077 /* find the next '/' or consume remaining */
1078 name_end
= strchr_m(nameptr
, '/');
1079 if (name_end
== NULL
) {
1080 /* Point nameptr at the terminating '\0' */
1081 nameptr
+= strlen(nameptr
);
1083 /* next segment please */
1084 nameptr
= name_end
+ 1;
1089 if(num_entries
== 0) {
1090 talloc_free(namelist
);
1094 if(( (*ppname_array
) = SMB_MALLOC_ARRAY(name_compare_entry
, num_entries
+ 1)) == NULL
) {
1095 DEBUG(0,("set_namearray: malloc fail\n"));
1096 talloc_free(namelist
);
1100 /* Now copy out the names */
1103 while(nameptr
<= namelist_end
) {
1104 if ( *nameptr
== '/' ) {
1105 /* cope with multiple (useless) /s) */
1109 /* anything left? */
1110 if ( *nameptr
== '\0' )
1113 /* find the next '/' or consume remaining */
1114 name_end
= strchr_m(nameptr
, '/');
1115 if (name_end
!= NULL
) {
1119 (*ppname_array
)[i
].is_wild
= ms_has_wild(nameptr
);
1120 if(((*ppname_array
)[i
].name
= SMB_STRDUP(nameptr
)) == NULL
) {
1121 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1122 talloc_free(namelist
);
1126 if (name_end
== NULL
) {
1127 /* Point nameptr at the terminating '\0' */
1128 nameptr
+= strlen(nameptr
);
1130 /* next segment please */
1131 nameptr
= name_end
+ 1;
1136 (*ppname_array
)[i
].name
= NULL
;
1138 talloc_free(namelist
);
1143 #define DBGC_CLASS DBGC_LOCKING
1145 /****************************************************************************
1146 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1147 is dealt with in posix.c
1148 Returns True if we have information regarding this lock region (and returns
1149 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1150 ****************************************************************************/
1152 bool fcntl_getlock(int fd
, off_t
*poffset
, off_t
*pcount
, int *ptype
, pid_t
*ppid
)
1157 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1158 fd
,(double)*poffset
,(double)*pcount
,*ptype
));
1160 lock
.l_type
= *ptype
;
1161 lock
.l_whence
= SEEK_SET
;
1162 lock
.l_start
= *poffset
;
1163 lock
.l_len
= *pcount
;
1166 ret
= sys_fcntl_ptr(fd
,F_GETLK
,&lock
);
1170 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1171 (double)*poffset
,(double)*pcount
,*ptype
,strerror(errno
)));
1176 *ptype
= lock
.l_type
;
1177 *poffset
= lock
.l_start
;
1178 *pcount
= lock
.l_len
;
1181 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1182 fd
, (int)lock
.l_type
, (unsigned int)lock
.l_pid
));
1187 #define DBGC_CLASS DBGC_ALL
1189 /*******************************************************************
1190 Is the name specified one of my netbios names.
1191 Returns true if it is equal, false otherwise.
1192 ********************************************************************/
1194 bool is_myname(const char *s
)
1199 for (n
=0; my_netbios_names(n
); n
++) {
1200 if (strequal(my_netbios_names(n
), s
)) {
1205 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));
1209 /*******************************************************************
1210 we distinguish between 2K and XP by the "Native Lan Manager" string
1211 WinXP => "Windows 2002 5.1"
1212 WinXP 64bit => "Windows XP 5.2"
1213 Win2k => "Windows 2000 5.0"
1214 NT4 => "Windows NT 4.0"
1215 Win9x => "Windows 4.0"
1216 Windows 2003 doesn't set the native lan manager string but
1217 they do set the domain to "Windows 2003 5.2" (probably a bug).
1218 ********************************************************************/
1220 void ra_lanman_string( const char *native_lanman
)
1222 if ( strcmp( native_lanman
, "Windows 2002 5.1" ) == 0 )
1223 set_remote_arch( RA_WINXP
);
1224 else if ( strcmp( native_lanman
, "Windows XP 5.2" ) == 0 )
1225 set_remote_arch( RA_WINXP64
);
1226 else if ( strcmp( native_lanman
, "Windows Server 2003 5.2" ) == 0 )
1227 set_remote_arch( RA_WIN2K3
);
1230 static const char *remote_arch_str
;
1232 const char *get_remote_arch_str(void)
1234 if (!remote_arch_str
) {
1237 return remote_arch_str
;
1240 /*******************************************************************
1241 Set the horrid remote_arch string based on an enum.
1242 ********************************************************************/
1244 void set_remote_arch(enum remote_arch_types type
)
1249 remote_arch_str
= "WfWg";
1252 remote_arch_str
= "OS2";
1255 remote_arch_str
= "Win95";
1258 remote_arch_str
= "WinNT";
1261 remote_arch_str
= "Win2K";
1264 remote_arch_str
= "WinXP";
1267 remote_arch_str
= "WinXP64";
1270 remote_arch_str
= "Win2K3";
1273 remote_arch_str
= "Vista";
1276 remote_arch_str
= "Samba";
1279 remote_arch_str
= "CIFSFS";
1282 remote_arch_str
= "OSX";
1285 ra_type
= RA_UNKNOWN
;
1286 remote_arch_str
= "UNKNOWN";
1290 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1294 /*******************************************************************
1295 Get the remote_arch type.
1296 ********************************************************************/
1298 enum remote_arch_types
get_remote_arch(void)
1303 const char *tab_depth(int level
, int depth
)
1305 if( CHECK_DEBUGLVL(level
) ) {
1306 dbgtext("%*s", depth
*4, "");
1311 /*****************************************************************************
1312 Provide a checksum on a string
1314 Input: s - the null-terminated character string for which the checksum
1317 Output: The checksum value calculated for s.
1318 *****************************************************************************/
1320 int str_checksum(const char *s
)
1324 return hash(s
, strlen(s
), 0);
1327 /*****************************************************************
1328 Zero a memory area then free it. Used to catch bugs faster.
1329 *****************************************************************/
1331 void zero_free(void *p
, size_t size
)
1337 /*****************************************************************
1338 Set our open file limit to a requested max and return the limit.
1339 *****************************************************************/
1341 int set_maxfiles(int requested_max
)
1343 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1345 int saved_current_limit
;
1347 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
1348 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1351 return requested_max
;
1355 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1356 * account for the extra fd we need
1357 * as well as the log files and standard
1358 * handles etc. Save the limit we want to set in case
1359 * we are running on an OS that doesn't support this limit (AIX)
1360 * which always returns RLIM_INFINITY for rlp.rlim_max.
1363 /* Try raising the hard (max) limit to the requested amount. */
1365 #if defined(RLIM_INFINITY)
1366 if (rlp
.rlim_max
!= RLIM_INFINITY
) {
1367 int orig_max
= rlp
.rlim_max
;
1369 if ( rlp
.rlim_max
< requested_max
)
1370 rlp
.rlim_max
= requested_max
;
1372 /* This failing is not an error - many systems (Linux) don't
1373 support our default request of 10,000 open files. JRA. */
1375 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
1376 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1377 (int)rlp
.rlim_max
, strerror(errno
) ));
1379 /* Set failed - restore original value from get. */
1380 rlp
.rlim_max
= orig_max
;
1385 /* Now try setting the soft (current) limit. */
1387 saved_current_limit
= rlp
.rlim_cur
= MIN(requested_max
,rlp
.rlim_max
);
1389 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
1390 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1391 (int)rlp
.rlim_cur
, strerror(errno
) ));
1393 return saved_current_limit
;
1396 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
1397 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1400 return saved_current_limit
;
1403 #if defined(RLIM_INFINITY)
1404 if(rlp
.rlim_cur
== RLIM_INFINITY
)
1405 return saved_current_limit
;
1408 if((int)rlp
.rlim_cur
> saved_current_limit
)
1409 return saved_current_limit
;
1411 return rlp
.rlim_cur
;
1412 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1414 * No way to know - just guess...
1416 return requested_max
;
1420 /*****************************************************************
1421 malloc that aborts with smb_panic on fail or zero size.
1422 *****************************************************************/
1424 void *smb_xmalloc_array(size_t size
, unsigned int count
)
1428 smb_panic("smb_xmalloc_array: called with zero size");
1430 if (count
>= MAX_ALLOC_SIZE
/size
) {
1431 smb_panic("smb_xmalloc_array: alloc size too large");
1433 if ((p
= SMB_MALLOC(size
*count
)) == NULL
) {
1434 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1435 (unsigned long)size
, (unsigned long)count
));
1436 smb_panic("smb_xmalloc_array: malloc failed");
1442 vasprintf that aborts on malloc fail
1445 int smb_xvasprintf(char **ptr
, const char *format
, va_list ap
)
1452 n
= vasprintf(ptr
, format
, ap2
);
1454 if (n
== -1 || ! *ptr
) {
1455 smb_panic("smb_xvasprintf: out of memory");
1460 /*****************************************************************
1461 Get local hostname and cache result.
1462 *****************************************************************/
1464 char *myhostname(void)
1468 ret
= get_myname(NULL
);
1473 /*****************************************************************
1474 Get local hostname and cache result.
1475 *****************************************************************/
1477 char *myhostname_upper(void)
1481 char *name
= get_myname(NULL
);
1485 ret
= strupper_talloc(NULL
, name
);
1492 * @brief Returns an absolute path to a file concatenating the provided
1493 * @a rootpath and @a basename
1495 * @param name Filename, relative to @a rootpath
1497 * @retval Pointer to a string containing the full path.
1500 static char *xx_path(const char *name
, const char *rootpath
)
1504 fname
= talloc_strdup(talloc_tos(), rootpath
);
1508 trim_string(fname
,"","/");
1510 if (!directory_exist(fname
)) {
1511 if (mkdir(fname
,0755) == -1) {
1512 /* Did someone else win the race ? */
1513 if (errno
!= EEXIST
) {
1514 DEBUG(1, ("Unable to create directory %s for file %s. "
1515 "Error was %s\n", fname
, name
, strerror(errno
)));
1521 return talloc_asprintf_append(fname
, "/%s", name
);
1525 * @brief Returns an absolute path to a file in the Samba lock directory.
1527 * @param name File to find, relative to LOCKDIR.
1529 * @retval Pointer to a talloc'ed string containing the full path.
1532 char *lock_path(const char *name
)
1534 return xx_path(name
, lp_lock_directory());
1538 * @brief Returns an absolute path to a file in the Samba state directory.
1540 * @param name File to find, relative to STATEDIR.
1542 * @retval Pointer to a talloc'ed string containing the full path.
1545 char *state_path(const char *name
)
1547 return xx_path(name
, lp_state_directory());
1551 * @brief Returns an absolute path to a file in the Samba cache directory.
1553 * @param name File to find, relative to CACHEDIR.
1555 * @retval Pointer to a talloc'ed string containing the full path.
1558 char *cache_path(const char *name
)
1560 return xx_path(name
, lp_cache_directory());
1563 /*******************************************************************
1564 Given a filename - get its directory name
1565 ********************************************************************/
1567 bool parent_dirname(TALLOC_CTX
*mem_ctx
, const char *dir
, char **parent
,
1573 p
= strrchr_m(dir
, '/'); /* Find final '/', if any */
1576 if (!(*parent
= talloc_strdup(mem_ctx
, "."))) {
1587 if (!(*parent
= (char *)talloc_memdup(mem_ctx
, dir
, len
+1))) {
1590 (*parent
)[len
] = '\0';
1598 /*******************************************************************
1599 Determine if a pattern contains any Microsoft wildcard characters.
1600 *******************************************************************/
1602 bool ms_has_wild(const char *s
)
1606 if (lp_posix_pathnames()) {
1607 /* With posix pathnames no characters are wild. */
1611 while ((c
= *s
++)) {
1624 bool ms_has_wild_w(const smb_ucs2_t
*s
)
1627 if (!s
) return False
;
1628 while ((c
= *s
++)) {
1630 case UCS2_CHAR('*'):
1631 case UCS2_CHAR('?'):
1632 case UCS2_CHAR('<'):
1633 case UCS2_CHAR('>'):
1634 case UCS2_CHAR('"'):
1641 /*******************************************************************
1642 A wrapper that handles case sensitivity and the special handling
1644 *******************************************************************/
1646 bool mask_match(const char *string
, const char *pattern
, bool is_case_sensitive
)
1648 if (ISDOTDOT(string
))
1653 return ms_fnmatch(pattern
, string
, Protocol
<= PROTOCOL_LANMAN2
, is_case_sensitive
) == 0;
1656 /*******************************************************************
1657 A wrapper that handles case sensitivity and the special handling
1658 of the ".." name. Varient that is only called by old search code which requires
1659 pattern translation.
1660 *******************************************************************/
1662 bool mask_match_search(const char *string
, const char *pattern
, bool is_case_sensitive
)
1664 if (ISDOTDOT(string
))
1669 return ms_fnmatch(pattern
, string
, True
, is_case_sensitive
) == 0;
1672 /*******************************************************************
1673 A wrapper that handles a list of patters and calls mask_match()
1674 on each. Returns True if any of the patterns match.
1675 *******************************************************************/
1677 bool mask_match_list(const char *string
, char **list
, int listLen
, bool is_case_sensitive
)
1679 while (listLen
-- > 0) {
1680 if (mask_match(string
, *list
++, is_case_sensitive
))
1686 /*********************************************************
1687 Recursive routine that is called by unix_wild_match.
1688 *********************************************************/
1690 static bool unix_do_match(const char *regexp
, const char *str
)
1694 for( p
= regexp
; *p
&& *str
; ) {
1705 * Look for a character matching
1706 * the one after the '*'.
1710 return true; /* Automatic match */
1713 while(*str
&& (*p
!= *str
))
1717 * Patch from weidel@multichart.de. In the case of the regexp
1718 * '*XX*' we want to ensure there are at least 2 'X' characters
1719 * in the string after the '*' for a match to be made.
1726 * Eat all the characters that match, but count how many there were.
1729 while(*str
&& (*p
== *str
)) {
1735 * Now check that if the regexp had n identical characters that
1736 * matchcount had at least that many matches.
1739 while ( *(p
+1) && (*(p
+1) == *p
)) {
1744 if ( matchcount
<= 0 )
1748 str
--; /* We've eaten the match char after the '*' */
1750 if(unix_do_match(p
, str
))
1772 if (!*p
&& str
[0] == '.' && str
[1] == 0)
1775 if (!*str
&& *p
== '?') {
1781 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
1787 /*******************************************************************
1788 Simple case insensitive interface to a UNIX wildcard matcher.
1789 Returns True if match, False if not.
1790 *******************************************************************/
1792 bool unix_wild_match(const char *pattern
, const char *string
)
1794 TALLOC_CTX
*ctx
= talloc_stackframe();
1800 p2
= talloc_strdup(ctx
,pattern
);
1801 s2
= talloc_strdup(ctx
,string
);
1806 if (!strlower_m(p2
)) {
1810 if (!strlower_m(s2
)) {
1815 /* Remove any *? and ** from the pattern as they are meaningless */
1816 for(p
= p2
; *p
; p
++) {
1817 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*')) {
1818 memmove(&p
[1], &p
[2], strlen(&p
[2])+1);
1822 if (strequal(p2
,"*")) {
1827 ret
= unix_do_match(p2
, s2
);
1832 /**********************************************************************
1833 Converts a name to a fully qualified domain name.
1834 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1835 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1836 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1837 ***********************************************************************/
1839 bool name_to_fqdn(fstring fqdn
, const char *name
)
1842 struct hostent
*hp
= gethostbyname(name
);
1844 if (!hp
|| !hp
->h_name
|| !*hp
->h_name
) {
1845 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name
));
1846 fstrcpy(fqdn
, name
);
1850 /* Find out if the fqdn is returned as an alias
1851 * to cope with /etc/hosts files where the first
1852 * name is not the fqdn but the short name */
1853 if (hp
->h_aliases
&& (! strchr_m(hp
->h_name
, '.'))) {
1855 for (i
= 0; hp
->h_aliases
[i
]; i
++) {
1856 if (strchr_m(hp
->h_aliases
[i
], '.')) {
1857 full
= hp
->h_aliases
[i
];
1862 if (full
&& (strcasecmp_m(full
, "localhost.localdomain") == 0)) {
1863 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1864 DEBUGADD(1, (" Specifying the machine hostname for address 127.0.0.1 may lead\n"));
1865 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1866 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1873 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name
, full
));
1874 fstrcpy(fqdn
, full
);
1878 /**********************************************************************
1879 Append a DATA_BLOB to a talloc'ed object
1880 ***********************************************************************/
1882 void *talloc_append_blob(TALLOC_CTX
*mem_ctx
, void *buf
, DATA_BLOB blob
)
1884 size_t old_size
= 0;
1887 if (blob
.length
== 0) {
1892 old_size
= talloc_get_size(buf
);
1895 result
= (char *)TALLOC_REALLOC(mem_ctx
, buf
, old_size
+ blob
.length
);
1896 if (result
== NULL
) {
1900 memcpy(result
+ old_size
, blob
.data
, blob
.length
);
1904 uint32
map_share_mode_to_deny_mode(uint32 share_access
, uint32 private_options
)
1906 switch (share_access
& ~FILE_SHARE_DELETE
) {
1907 case FILE_SHARE_NONE
:
1909 case FILE_SHARE_READ
:
1911 case FILE_SHARE_WRITE
:
1913 case FILE_SHARE_READ
|FILE_SHARE_WRITE
:
1916 if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) {
1918 } else if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
) {
1925 pid_t
procid_to_pid(const struct server_id
*proc
)
1930 static uint32 my_vnn
= NONCLUSTER_VNN
;
1932 void set_my_vnn(uint32 vnn
)
1934 DEBUG(10, ("vnn pid %d = %u\n", (int)getpid(), (unsigned int)vnn
));
1938 uint32
get_my_vnn(void)
1943 static uint64_t my_unique_id
= 0;
1945 void set_my_unique_id(uint64_t unique_id
)
1947 my_unique_id
= unique_id
;
1950 struct server_id
pid_to_procid(pid_t pid
)
1952 struct server_id result
;
1955 result
.unique_id
= my_unique_id
;
1956 result
.vnn
= my_vnn
;
1960 struct server_id
procid_self(void)
1962 return pid_to_procid(getpid());
1965 bool procid_is_me(const struct server_id
*pid
)
1967 if (pid
->pid
!= getpid())
1969 if (pid
->task_id
!= 0)
1971 if (pid
->vnn
!= my_vnn
)
1976 struct server_id
interpret_pid(const char *pid_string
)
1978 return server_id_from_string(get_my_vnn(), pid_string
);
1981 char *procid_str_static(const struct server_id
*pid
)
1983 return server_id_str(talloc_tos(), pid
);
1986 bool procid_valid(const struct server_id
*pid
)
1988 return (pid
->pid
!= (uint64_t)-1);
1991 bool procid_is_local(const struct server_id
*pid
)
1993 return pid
->vnn
== my_vnn
;
1996 /****************************************************************
1997 Check if an offset into a buffer is safe.
1998 If this returns True it's safe to indirect into the byte at
2000 ****************************************************************/
2002 bool is_offset_safe(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2004 const char *end_base
= buf_base
+ buf_len
;
2005 char *end_ptr
= ptr
+ off
;
2007 if (!buf_base
|| !ptr
) {
2011 if (end_base
< buf_base
|| end_ptr
< ptr
) {
2012 return False
; /* wrap. */
2015 if (end_ptr
< end_base
) {
2021 /****************************************************************
2022 Return a safe pointer into a buffer, or NULL.
2023 ****************************************************************/
2025 char *get_safe_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2027 return is_offset_safe(buf_base
, buf_len
, ptr
, off
) ?
2031 /****************************************************************
2032 Return a safe pointer into a string within a buffer, or NULL.
2033 ****************************************************************/
2035 char *get_safe_str_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2037 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
)) {
2040 /* Check if a valid string exists at this offset. */
2041 if (skip_string(buf_base
,buf_len
, ptr
+ off
) == NULL
) {
2047 /****************************************************************
2048 Return an SVAL at a pointer, or failval if beyond the end.
2049 ****************************************************************/
2051 int get_safe_SVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2054 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2057 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+1)) {
2060 return SVAL(ptr
,off
);
2063 /****************************************************************
2064 Return an IVAL at a pointer, or failval if beyond the end.
2065 ****************************************************************/
2067 int get_safe_IVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2070 * Note we use off+3 here, not off+4 as IVAL accesses
2071 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2073 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+3)) {
2076 return IVAL(ptr
,off
);
2079 /****************************************************************
2080 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2081 call (they take care of winbind separator and other winbind specific settings).
2082 ****************************************************************/
2084 void split_domain_user(TALLOC_CTX
*mem_ctx
,
2085 const char *full_name
,
2089 const char *p
= NULL
;
2091 p
= strchr_m(full_name
, '\\');
2094 *domain
= talloc_strndup(mem_ctx
, full_name
,
2095 PTR_DIFF(p
, full_name
));
2096 *user
= talloc_strdup(mem_ctx
, p
+1);
2098 *domain
= talloc_strdup(mem_ctx
, "");
2099 *user
= talloc_strdup(mem_ctx
, full_name
);
2103 /****************************************************************
2104 strip off leading '\\' from a hostname
2105 ****************************************************************/
2107 const char *strip_hostname(const char *s
)
2113 if (strlen_m(s
) < 3) {
2117 if (s
[0] == '\\') s
++;
2118 if (s
[0] == '\\') s
++;
2123 bool any_nt_status_not_ok(NTSTATUS err1
, NTSTATUS err2
, NTSTATUS
*result
)
2125 if (!NT_STATUS_IS_OK(err1
)) {
2129 if (!NT_STATUS_IS_OK(err2
)) {
2136 int timeval_to_msec(struct timeval t
)
2138 return t
.tv_sec
* 1000 + (t
.tv_usec
+999) / 1000;
2141 /*******************************************************************
2142 Check a given DOS pathname is valid for a share.
2143 ********************************************************************/
2145 char *valid_share_pathname(TALLOC_CTX
*ctx
, const char *dos_pathname
)
2149 if (!dos_pathname
) {
2153 ptr
= talloc_strdup(ctx
, dos_pathname
);
2157 /* Convert any '\' paths to '/' */
2159 ptr
= unix_clean_name(ctx
, ptr
);
2164 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2165 if (strlen(ptr
) > 2 && ptr
[1] == ':' && ptr
[0] != '/')
2168 /* Only absolute paths allowed. */
2175 /*******************************************************************
2176 Return True if the filename is one of the special executable types.
2177 ********************************************************************/
2179 bool is_executable(const char *fname
)
2181 if ((fname
= strrchr_m(fname
,'.'))) {
2182 if (strequal(fname
,".com") ||
2183 strequal(fname
,".dll") ||
2184 strequal(fname
,".exe") ||
2185 strequal(fname
,".sym")) {
2192 /****************************************************************************
2193 Open a file with a share mode - old openX method - map into NTCreate.
2194 ****************************************************************************/
2196 bool map_open_params_to_ntcreate(const char *smb_base_fname
,
2197 int deny_mode
, int open_func
,
2198 uint32
*paccess_mask
,
2199 uint32
*pshare_mode
,
2200 uint32
*pcreate_disposition
,
2201 uint32
*pcreate_options
,
2202 uint32_t *pprivate_flags
)
2206 uint32 create_disposition
;
2207 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
2208 uint32_t private_flags
= 0;
2210 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2211 "open_func = 0x%x\n",
2212 smb_base_fname
, (unsigned int)deny_mode
,
2213 (unsigned int)open_func
));
2215 /* Create the NT compatible access_mask. */
2216 switch (GET_OPENX_MODE(deny_mode
)) {
2217 case DOS_OPEN_EXEC
: /* Implies read-only - used to be FILE_READ_DATA */
2218 case DOS_OPEN_RDONLY
:
2219 access_mask
= FILE_GENERIC_READ
;
2221 case DOS_OPEN_WRONLY
:
2222 access_mask
= FILE_GENERIC_WRITE
;
2226 access_mask
= FILE_GENERIC_READ
|FILE_GENERIC_WRITE
;
2229 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2230 (unsigned int)GET_OPENX_MODE(deny_mode
)));
2234 /* Create the NT compatible create_disposition. */
2235 switch (open_func
) {
2236 case OPENX_FILE_EXISTS_FAIL
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2237 create_disposition
= FILE_CREATE
;
2240 case OPENX_FILE_EXISTS_OPEN
:
2241 create_disposition
= FILE_OPEN
;
2244 case OPENX_FILE_EXISTS_OPEN
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2245 create_disposition
= FILE_OPEN_IF
;
2248 case OPENX_FILE_EXISTS_TRUNCATE
:
2249 create_disposition
= FILE_OVERWRITE
;
2252 case OPENX_FILE_EXISTS_TRUNCATE
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2253 create_disposition
= FILE_OVERWRITE_IF
;
2257 /* From samba4 - to be confirmed. */
2258 if (GET_OPENX_MODE(deny_mode
) == DOS_OPEN_EXEC
) {
2259 create_disposition
= FILE_CREATE
;
2262 DEBUG(10,("map_open_params_to_ntcreate: bad "
2263 "open_func 0x%x\n", (unsigned int)open_func
));
2267 /* Create the NT compatible share modes. */
2268 switch (GET_DENY_MODE(deny_mode
)) {
2270 share_mode
= FILE_SHARE_NONE
;
2274 share_mode
= FILE_SHARE_READ
;
2278 share_mode
= FILE_SHARE_WRITE
;
2282 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
2286 private_flags
|= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
;
2287 if (is_executable(smb_base_fname
)) {
2288 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
2290 if (GET_OPENX_MODE(deny_mode
) == DOS_OPEN_RDONLY
) {
2291 share_mode
= FILE_SHARE_READ
;
2293 share_mode
= FILE_SHARE_NONE
;
2299 private_flags
|= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
;
2300 share_mode
= FILE_SHARE_NONE
;
2304 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2305 (unsigned int)GET_DENY_MODE(deny_mode
) ));
2309 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2310 "share_mode = 0x%x, create_disposition = 0x%x, "
2311 "create_options = 0x%x private_flags = 0x%x\n",
2313 (unsigned int)access_mask
,
2314 (unsigned int)share_mode
,
2315 (unsigned int)create_disposition
,
2316 (unsigned int)create_options
,
2317 (unsigned int)private_flags
));
2320 *paccess_mask
= access_mask
;
2323 *pshare_mode
= share_mode
;
2325 if (pcreate_disposition
) {
2326 *pcreate_disposition
= create_disposition
;
2328 if (pcreate_options
) {
2329 *pcreate_options
= create_options
;
2331 if (pprivate_flags
) {
2332 *pprivate_flags
= private_flags
;
2339 /*************************************************************************
2340 Return a talloced copy of a struct security_unix_token. NULL on fail.
2341 *************************************************************************/
2343 struct security_unix_token
*copy_unix_token(TALLOC_CTX
*ctx
, const struct security_unix_token
*tok
)
2345 struct security_unix_token
*cpy
;
2347 cpy
= talloc(ctx
, struct security_unix_token
);
2352 cpy
->uid
= tok
->uid
;
2353 cpy
->gid
= tok
->gid
;
2354 cpy
->ngroups
= tok
->ngroups
;
2356 /* Make this a talloc child of cpy. */
2357 cpy
->groups
= (gid_t
*)talloc_memdup(
2358 cpy
, tok
->groups
, tok
->ngroups
* sizeof(gid_t
));
2369 /****************************************************************************
2370 Check that a file matches a particular file type.
2371 ****************************************************************************/
2373 bool dir_check_ftype(uint32_t mode
, uint32_t dirtype
)
2377 /* Check the "may have" search bits. */
2378 if (((mode
& ~dirtype
) &
2379 (FILE_ATTRIBUTE_HIDDEN
|
2380 FILE_ATTRIBUTE_SYSTEM
|
2381 FILE_ATTRIBUTE_DIRECTORY
)) != 0) {
2385 /* Check the "must have" bits,
2386 which are the may have bits shifted eight */
2387 /* If must have bit is set, the file/dir can
2388 not be returned in search unless the matching
2389 file attribute is set */
2390 mask
= ((dirtype
>> 8) & (FILE_ATTRIBUTE_DIRECTORY
|
2391 FILE_ATTRIBUTE_ARCHIVE
|
2392 FILE_ATTRIBUTE_READONLY
|
2393 FILE_ATTRIBUTE_HIDDEN
|
2394 FILE_ATTRIBUTE_SYSTEM
)); /* & 0x37 */
2396 if((mask
& (mode
& (FILE_ATTRIBUTE_DIRECTORY
|
2397 FILE_ATTRIBUTE_ARCHIVE
|
2398 FILE_ATTRIBUTE_READONLY
|
2399 FILE_ATTRIBUTE_HIDDEN
|
2400 FILE_ATTRIBUTE_SYSTEM
))) == mask
) {
2401 /* check if matching attribute present */