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"
35 #ifdef HAVE_SYS_PRCTL_H
36 #include <sys/prctl.h>
39 /* Max allowable allococation - 256mb - 0x10000000 */
40 #define MAX_ALLOC_SIZE (1024*1024*256)
42 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
43 #ifdef WITH_NISPLUS_HOME
44 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
46 * The following lines are needed due to buggy include files
47 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
48 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
49 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
50 * an enum in /usr/include/rpcsvc/nis.h.
57 #if defined(GROUP_OBJ)
61 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
63 #include <rpcsvc/nis.h>
65 #endif /* WITH_NISPLUS_HOME */
66 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
68 static enum protocol_types Protocol
= PROTOCOL_COREPLUS
;
70 enum protocol_types
get_Protocol(void)
75 void set_Protocol(enum protocol_types p
)
80 static enum remote_arch_types ra_type
= RA_UNKNOWN
;
82 void gfree_all( void )
91 /*******************************************************************
92 Check if a file exists - call vfs_file_exist for samba files.
93 ********************************************************************/
95 bool file_exist_stat(const char *fname
,SMB_STRUCT_STAT
*sbuf
,
96 bool fake_dir_create_times
)
102 if (sys_stat(fname
, sbuf
, fake_dir_create_times
) != 0)
105 return((S_ISREG(sbuf
->st_ex_mode
)) || (S_ISFIFO(sbuf
->st_ex_mode
)));
108 /*******************************************************************
109 Check if a unix domain socket exists - call vfs_file_exist for samba files.
110 ********************************************************************/
112 bool socket_exist(const char *fname
)
115 if (sys_stat(fname
, &st
, false) != 0)
118 return S_ISSOCK(st
.st_ex_mode
);
121 /*******************************************************************
122 Returns the size in bytes of the named given the stat struct.
123 ********************************************************************/
125 uint64_t get_file_size_stat(const SMB_STRUCT_STAT
*sbuf
)
127 return sbuf
->st_ex_size
;
130 /****************************************************************************
131 Check two stats have identical dev and ino fields.
132 ****************************************************************************/
134 bool check_same_dev_ino(const SMB_STRUCT_STAT
*sbuf1
,
135 const SMB_STRUCT_STAT
*sbuf2
)
137 if (sbuf1
->st_ex_dev
!= sbuf2
->st_ex_dev
||
138 sbuf1
->st_ex_ino
!= sbuf2
->st_ex_ino
) {
144 /****************************************************************************
145 Check if a stat struct is identical for use.
146 ****************************************************************************/
148 bool check_same_stat(const SMB_STRUCT_STAT
*sbuf1
,
149 const SMB_STRUCT_STAT
*sbuf2
)
151 if (sbuf1
->st_ex_uid
!= sbuf2
->st_ex_uid
||
152 sbuf1
->st_ex_gid
!= sbuf2
->st_ex_gid
||
153 !check_same_dev_ino(sbuf1
, sbuf2
)) {
159 /*******************************************************************
160 Show a smb message structure.
161 ********************************************************************/
163 void show_msg(const char *buf
)
171 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
173 (int)CVAL(buf
,smb_com
),
174 (int)CVAL(buf
,smb_rcls
),
175 (int)CVAL(buf
,smb_reh
),
176 (int)SVAL(buf
,smb_err
),
177 (int)CVAL(buf
,smb_flg
),
178 (int)SVAL(buf
,smb_flg2
)));
179 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
180 (int)SVAL(buf
,smb_tid
),
181 (int)SVAL(buf
,smb_pid
),
182 (int)SVAL(buf
,smb_uid
),
183 (int)SVAL(buf
,smb_mid
)));
184 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf
,smb_wct
)));
186 for (i
=0;i
<(int)CVAL(buf
,smb_wct
);i
++)
187 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i
,
188 SVAL(buf
,smb_vwv
+2*i
),SVAL(buf
,smb_vwv
+2*i
)));
190 bcc
= (int)SVAL(buf
,smb_vwv
+2*(CVAL(buf
,smb_wct
)));
192 DEBUGADD(5,("smb_bcc=%d\n",bcc
));
200 dump_data(10, (const uint8
*)smb_buf_const(buf
), bcc
);
203 /*******************************************************************
204 Setup only the byte count for a smb message.
205 ********************************************************************/
207 int set_message_bcc(char *buf
,int num_bytes
)
209 int num_words
= CVAL(buf
,smb_wct
);
210 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
211 _smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
212 return (smb_size
+ num_words
*2 + num_bytes
);
215 /*******************************************************************
216 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
217 Return the bytes added
218 ********************************************************************/
220 ssize_t
message_push_blob(uint8
**outbuf
, DATA_BLOB blob
)
222 size_t newlen
= smb_len(*outbuf
) + 4 + blob
.length
;
225 if (!(tmp
= talloc_realloc(NULL
, *outbuf
, uint8
, newlen
))) {
226 DEBUG(0, ("talloc failed\n"));
231 memcpy(tmp
+ smb_len(tmp
) + 4, blob
.data
, blob
.length
);
232 set_message_bcc((char *)tmp
, smb_buflen(tmp
) + blob
.length
);
236 /*******************************************************************
237 Reduce a file name, removing .. elements.
238 ********************************************************************/
240 static char *dos_clean_name(TALLOC_CTX
*ctx
, const char *s
)
245 DEBUG(3,("dos_clean_name [%s]\n",s
));
247 /* remove any double slashes */
248 str
= talloc_all_string_sub(ctx
, s
, "\\\\", "\\");
253 /* Remove leading .\\ characters */
254 if(strncmp(str
, ".\\", 2) == 0) {
255 trim_string(str
, ".\\", NULL
);
257 str
= talloc_strdup(ctx
, ".\\");
264 while ((p
= strstr_m(str
,"\\..\\")) != NULL
) {
270 if ((p
=strrchr_m(str
,'\\')) != NULL
) {
275 str
= talloc_asprintf(ctx
,
284 trim_string(str
,NULL
,"\\..");
285 return talloc_all_string_sub(ctx
, str
, "\\.\\", "\\");
288 /*******************************************************************
289 Reduce a file name, removing .. elements.
290 ********************************************************************/
292 char *unix_clean_name(TALLOC_CTX
*ctx
, const char *s
)
297 DEBUG(3,("unix_clean_name [%s]\n",s
));
299 /* remove any double slashes */
300 str
= talloc_all_string_sub(ctx
, s
, "//","/");
305 /* Remove leading ./ characters */
306 if(strncmp(str
, "./", 2) == 0) {
307 trim_string(str
, "./", NULL
);
309 str
= talloc_strdup(ctx
, "./");
316 while ((p
= strstr_m(str
,"/../")) != NULL
) {
322 if ((p
=strrchr_m(str
,'/')) != NULL
) {
327 str
= talloc_asprintf(ctx
,
336 trim_string(str
,NULL
,"/..");
337 return talloc_all_string_sub(ctx
, str
, "/./", "/");
340 char *clean_name(TALLOC_CTX
*ctx
, const char *s
)
342 char *str
= dos_clean_name(ctx
, s
);
346 return unix_clean_name(ctx
, str
);
349 /*******************************************************************
350 Write data into an fd at a given offset. Ignore seek errors.
351 ********************************************************************/
353 ssize_t
write_data_at_offset(int fd
, const char *buffer
, size_t N
, off_t pos
)
358 if (pos
== (off_t
)-1) {
359 return write_data(fd
, buffer
, N
);
361 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
363 ret
= sys_pwrite(fd
,buffer
+ total
,N
- total
, pos
);
364 if (ret
== -1 && errno
== ESPIPE
) {
365 return write_data(fd
, buffer
+ total
,N
- total
);
368 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno
) ));
377 return (ssize_t
)total
;
379 /* Use lseek and write_data. */
380 if (lseek(fd
, pos
, SEEK_SET
) == -1) {
381 if (errno
!= ESPIPE
) {
385 return write_data(fd
, buffer
, N
);
389 static int reinit_after_fork_pipe
[2] = { -1, -1 };
391 NTSTATUS
init_before_fork(void)
395 ret
= pipe(reinit_after_fork_pipe
);
399 status
= map_nt_error_from_unix_common(errno
);
401 DEBUG(0, ("Error creating child_pipe: %s\n",
411 * Detect died parent by detecting EOF on the pipe
413 static void reinit_after_fork_pipe_handler(struct tevent_context
*ev
,
414 struct tevent_fd
*fde
,
420 if (sys_read(reinit_after_fork_pipe
[0], &c
, 1) != 1) {
422 * we have reached EOF on stdin, which means the
423 * parent has exited. Shutdown the server
425 (void)kill(getpid(), SIGTERM
);
430 NTSTATUS
reinit_after_fork(struct messaging_context
*msg_ctx
,
431 struct tevent_context
*ev_ctx
,
432 bool parent_longlived
)
434 NTSTATUS status
= NT_STATUS_OK
;
436 if (reinit_after_fork_pipe
[1] != -1) {
437 close(reinit_after_fork_pipe
[1]);
438 reinit_after_fork_pipe
[1] = -1;
441 /* Reset the state of the random
442 * number generation system, so
443 * children do not get the same random
444 * numbers as each other */
445 set_need_random_reseed();
447 /* tdb needs special fork handling */
448 if (tdb_reopen_all(parent_longlived
? 1 : 0) != 0) {
449 DEBUG(0,("tdb_reopen_all failed.\n"));
450 status
= NT_STATUS_OPEN_FAILED
;
454 if (ev_ctx
&& tevent_re_initialise(ev_ctx
) != 0) {
455 smb_panic(__location__
": Failed to re-initialise event context");
458 if (reinit_after_fork_pipe
[0] != -1) {
459 struct tevent_fd
*fde
;
461 fde
= tevent_add_fd(ev_ctx
, ev_ctx
/* TALLOC_CTX */,
462 reinit_after_fork_pipe
[0], TEVENT_FD_READ
,
463 reinit_after_fork_pipe_handler
, NULL
);
465 smb_panic(__location__
": Failed to add reinit_after_fork pipe event");
471 * For clustering, we need to re-init our ctdbd connection after the
474 status
= messaging_reinit(msg_ctx
);
475 if (!NT_STATUS_IS_OK(status
)) {
476 DEBUG(0,("messaging_reinit() failed: %s\n",
484 /****************************************************************************
485 (Hopefully) efficient array append.
486 ****************************************************************************/
488 void add_to_large_array(TALLOC_CTX
*mem_ctx
, size_t element_size
,
489 void *element
, void *_array
, uint32
*num_elements
,
492 void **array
= (void **)_array
;
494 if (*array_size
< 0) {
498 if (*array
== NULL
) {
499 if (*array_size
== 0) {
503 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
507 *array
= TALLOC(mem_ctx
, element_size
* (*array_size
));
508 if (*array
== NULL
) {
513 if (*num_elements
== *array_size
) {
516 if (*array_size
>= MAX_ALLOC_SIZE
/element_size
) {
520 *array
= TALLOC_REALLOC(mem_ctx
, *array
,
521 element_size
* (*array_size
));
523 if (*array
== NULL
) {
528 memcpy((char *)(*array
) + element_size
*(*num_elements
),
529 element
, element_size
);
539 /****************************************************************************
540 Get my own domain name, or "" if we have none.
541 ****************************************************************************/
543 char *get_mydnsdomname(TALLOC_CTX
*ctx
)
548 domname
= get_mydnsfullname();
553 p
= strchr_m(domname
, '.');
556 return talloc_strdup(ctx
, p
);
558 return talloc_strdup(ctx
, "");
562 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
563 /******************************************************************
564 Remove any mount options such as -rsize=2048,wsize=2048 etc.
565 Based on a fix from <Thomas.Hepper@icem.de>.
566 Returns a malloc'ed string.
567 *******************************************************************/
569 static char *strip_mount_options(TALLOC_CTX
*ctx
, const char *str
)
573 while(*p
&& !isspace(*p
))
575 while(*p
&& isspace(*p
))
578 return talloc_strdup(ctx
, p
);
584 /*******************************************************************
585 Patch from jkf@soton.ac.uk
586 Split Luke's automount_server into YP lookup and string splitter
587 so can easily implement automount_path().
588 Returns a malloc'ed string.
589 *******************************************************************/
591 #ifdef WITH_NISPLUS_HOME
592 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
596 char *nis_map
= (char *)lp_homedir_map();
598 char buffer
[NIS_MAXATTRVAL
+ 1];
603 snprintf(buffer
, sizeof(buffer
), "[key=%s],%s", user_name
, nis_map
);
604 DEBUG(5, ("NIS+ querystring: %s\n", buffer
));
606 if (result
= nis_list(buffer
, FOLLOW_PATH
|EXPAND_NAME
|HARD_LOOKUP
, NULL
, NULL
)) {
607 if (result
->status
!= NIS_SUCCESS
) {
608 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result
->status
)));
610 object
= result
->objects
.objects_val
;
611 if (object
->zo_data
.zo_type
== ENTRY_OBJ
) {
612 entry
= &object
->zo_data
.objdata_u
.en_data
;
613 DEBUG(5, ("NIS+ entry type: %s\n", entry
->en_type
));
614 DEBUG(3, ("NIS+ result: %s\n", entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
));
616 value
= talloc_strdup(ctx
,
617 entry
->en_cols
.en_cols_val
[1].ec_value
.ec_value_val
);
619 nis_freeresult(result
);
622 value
= talloc_string_sub(ctx
,
629 nis_freeresult(result
);
632 value
= strip_mount_options(ctx
, value
);
633 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
638 #else /* WITH_NISPLUS_HOME */
640 char *automount_lookup(TALLOC_CTX
*ctx
, const char *user_name
)
644 int nis_error
; /* returned by yp all functions */
645 char *nis_result
; /* yp_match inits this */
646 int nis_result_len
; /* and set this */
647 char *nis_domain
; /* yp_get_default_domain inits this */
648 char *nis_map
= lp_homedir_map(talloc_tos());
650 if ((nis_error
= yp_get_default_domain(&nis_domain
)) != 0) {
651 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error
)));
655 DEBUG(5, ("NIS Domain: %s\n", nis_domain
));
657 if ((nis_error
= yp_match(nis_domain
, nis_map
, user_name
,
658 strlen(user_name
), &nis_result
,
659 &nis_result_len
)) == 0) {
660 if (nis_result_len
> 0 && nis_result
[nis_result_len
] == '\n') {
661 nis_result
[nis_result_len
] = '\0';
663 value
= talloc_strdup(ctx
, nis_result
);
667 value
= strip_mount_options(ctx
, value
);
668 } else if(nis_error
== YPERR_KEY
) {
669 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
670 user_name
, nis_map
));
671 DEBUG(3, ("using defaults for server and home directory\n"));
673 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
674 yperr_string(nis_error
), user_name
, nis_map
));
678 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name
, value
));
682 #endif /* WITH_NISPLUS_HOME */
685 bool process_exists(const struct server_id pid
)
687 return serverid_exists(&pid
);
690 /*******************************************************************
691 Convert a uid into a user name.
692 ********************************************************************/
694 const char *uidtoname(uid_t uid
)
696 TALLOC_CTX
*ctx
= talloc_tos();
698 struct passwd
*pass
= NULL
;
700 pass
= getpwuid_alloc(ctx
,uid
);
702 name
= talloc_strdup(ctx
,pass
->pw_name
);
705 name
= talloc_asprintf(ctx
,
712 /*******************************************************************
713 Convert a gid into a group name.
714 ********************************************************************/
716 char *gidtoname(gid_t gid
)
722 return talloc_strdup(talloc_tos(), grp
->gr_name
);
725 return talloc_asprintf(talloc_tos(),
731 /*******************************************************************
732 Convert a user name into a uid.
733 ********************************************************************/
735 uid_t
nametouid(const char *name
)
741 pass
= Get_Pwnam_alloc(talloc_tos(), name
);
748 u
= (uid_t
)strtol(name
, &p
, 0);
749 if ((p
!= name
) && (*p
== '\0'))
755 /*******************************************************************
756 Convert a name to a gid_t if possible. Return -1 if not a group.
757 ********************************************************************/
759 gid_t
nametogid(const char *name
)
765 g
= (gid_t
)strtol(name
, &p
, 0);
766 if ((p
!= name
) && (*p
== '\0'))
769 grp
= getgrnam(name
);
775 /*******************************************************************
776 Something really nasty happened - panic !
777 ********************************************************************/
779 void smb_panic_s3(const char *why
)
784 DEBUG(0,("PANIC (pid %llu): %s\n",
785 (unsigned long long)getpid(), why
));
788 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
790 * Make sure all children can attach a debugger.
792 prctl(PR_SET_PTRACER
, getpid(), 0, 0, 0);
795 cmd
= lp_panic_action(talloc_tos());
797 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd
));
798 result
= system(cmd
);
801 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
804 DEBUG(0, ("smb_panic(): action returned status %d\n",
805 WEXITSTATUS(result
)));
811 /*******************************************************************
812 Print a backtrace of the stack to the debug log. This function
813 DELIBERATELY LEAKS MEMORY. The expectation is that you should
814 exit shortly after calling it.
815 ********************************************************************/
817 #ifdef HAVE_LIBUNWIND_H
818 #include <libunwind.h>
821 #ifdef HAVE_EXECINFO_H
822 #include <execinfo.h>
829 void log_stack_trace(void)
831 #ifdef HAVE_LIBUNWIND
832 /* Try to use libunwind before any other technique since on ia64
833 * libunwind correctly walks the stack in more circumstances than
841 unw_word_t ip
, sp
, off
;
843 procname
[sizeof(procname
) - 1] = '\0';
845 if (unw_getcontext(&uc
) != 0) {
846 goto libunwind_failed
;
849 if (unw_init_local(&cursor
, &uc
) != 0) {
850 goto libunwind_failed
;
853 DEBUG(0, ("BACKTRACE:\n"));
857 unw_get_reg(&cursor
, UNW_REG_IP
, &ip
);
858 unw_get_reg(&cursor
, UNW_REG_SP
, &sp
);
860 switch (unw_get_proc_name(&cursor
,
861 procname
, sizeof(procname
) - 1, &off
) ) {
865 /* Name truncated. */
866 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
867 i
, procname
, (long long)off
,
868 (long long)ip
, (long long) sp
));
871 /* case -UNW_ENOINFO: */
872 /* case -UNW_EUNSPEC: */
873 /* No symbol name found. */
874 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
875 i
, "<unknown symbol>",
876 (long long)ip
, (long long) sp
));
879 } while (unw_step(&cursor
) > 0);
884 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
886 #elif HAVE_BACKTRACE_SYMBOLS
887 void *backtrace_stack
[BACKTRACE_STACK_SIZE
];
888 size_t backtrace_size
;
889 char **backtrace_strings
;
891 /* get the backtrace (stack frames) */
892 backtrace_size
= backtrace(backtrace_stack
,BACKTRACE_STACK_SIZE
);
893 backtrace_strings
= backtrace_symbols(backtrace_stack
, backtrace_size
);
895 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
896 (unsigned long)backtrace_size
));
898 if (backtrace_strings
) {
901 for (i
= 0; i
< backtrace_size
; i
++)
902 DEBUGADD(0, (" #%u %s\n", i
, backtrace_strings
[i
]));
904 /* Leak the backtrace_strings, rather than risk what free() might do */
909 /* The IRIX libexc library provides an API for unwinding the stack. See
910 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
911 * since we are about to abort anyway, it hardly matters.
914 #define NAMESIZE 32 /* Arbitrary */
916 __uint64_t addrs
[BACKTRACE_STACK_SIZE
];
917 char * names
[BACKTRACE_STACK_SIZE
];
918 char namebuf
[BACKTRACE_STACK_SIZE
* NAMESIZE
];
927 /* We need to be root so we can open our /proc entry to walk
928 * our stack. It also helps when we want to dump core.
932 for (i
= 0; i
< BACKTRACE_STACK_SIZE
; i
++) {
933 names
[i
] = namebuf
+ (i
* NAMESIZE
);
936 levels
= trace_back_stack(0, addrs
, names
,
937 BACKTRACE_STACK_SIZE
, NAMESIZE
- 1);
939 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels
));
940 for (i
= 0; i
< levels
; i
++) {
941 DEBUGADD(0, (" #%d 0x%llx %s\n", i
, addrs
[i
], names
[i
]));
946 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
950 /*******************************************************************
951 A readdir wrapper which just returns the file name.
952 ********************************************************************/
954 const char *readdirname(DIR *p
)
962 ptr
= (struct dirent
*)readdir(p
);
973 #ifdef HAVE_BROKEN_READDIR_NAME
974 /* using /usr/ucb/cc is BAD */
978 return talloc_strdup(talloc_tos(), dname
);
981 /*******************************************************************
982 Utility function used to decide if the last component
983 of a path matches a (possibly wildcarded) entry in a namelist.
984 ********************************************************************/
986 bool is_in_path(const char *name
, name_compare_entry
*namelist
, bool case_sensitive
)
988 const char *last_component
;
990 /* if we have no list it's obviously not in the path */
991 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
))) {
995 DEBUG(8, ("is_in_path: %s\n", name
));
997 /* Get the last component of the unix name. */
998 last_component
= strrchr_m(name
, '/');
999 if (!last_component
) {
1000 last_component
= name
;
1002 last_component
++; /* Go past '/' */
1005 for(; namelist
->name
!= NULL
; namelist
++) {
1006 if(namelist
->is_wild
) {
1007 if (mask_match(last_component
, namelist
->name
, case_sensitive
)) {
1008 DEBUG(8,("is_in_path: mask match succeeded\n"));
1012 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
1013 (!case_sensitive
&& (strcasecmp_m(last_component
, namelist
->name
) == 0))) {
1014 DEBUG(8,("is_in_path: match succeeded\n"));
1019 DEBUG(8,("is_in_path: match not found\n"));
1023 /*******************************************************************
1024 Strip a '/' separated list into an array of
1025 name_compare_enties structures suitable for
1026 passing to is_in_path(). We do this for
1027 speed so we can pre-parse all the names in the list
1028 and don't do it for each call to is_in_path().
1029 We also check if the entry contains a wildcard to
1030 remove a potentially expensive call to mask_match
1032 ********************************************************************/
1034 void set_namearray(name_compare_entry
**ppname_array
, const char *namelist_in
)
1039 int num_entries
= 0;
1042 (*ppname_array
) = NULL
;
1044 if((namelist_in
== NULL
) || ((namelist_in
!= NULL
) && (*namelist_in
== '\0')))
1047 namelist
= talloc_strdup(talloc_tos(), namelist_in
);
1048 if (namelist
== NULL
) {
1049 DEBUG(0,("set_namearray: talloc fail\n"));
1054 /* We need to make two passes over the string. The
1055 first to count the number of elements, the second
1060 if ( *nameptr
== '/' ) {
1061 /* cope with multiple (useless) /s) */
1065 /* anything left? */
1066 if ( *nameptr
== '\0' )
1069 /* find the next '/' or consume remaining */
1070 name_end
= strchr_m(nameptr
, '/');
1071 if (name_end
== NULL
)
1072 name_end
= (char *)nameptr
+ strlen(nameptr
);
1074 /* next segment please */
1075 nameptr
= name_end
+ 1;
1079 if(num_entries
== 0) {
1080 talloc_free(namelist
);
1084 if(( (*ppname_array
) = SMB_MALLOC_ARRAY(name_compare_entry
, num_entries
+ 1)) == NULL
) {
1085 DEBUG(0,("set_namearray: malloc fail\n"));
1086 talloc_free(namelist
);
1090 /* Now copy out the names */
1094 if ( *nameptr
== '/' ) {
1095 /* cope with multiple (useless) /s) */
1099 /* anything left? */
1100 if ( *nameptr
== '\0' )
1103 /* find the next '/' or consume remaining */
1104 name_end
= strchr_m(nameptr
, '/');
1108 name_end
= nameptr
+ strlen(nameptr
);
1110 (*ppname_array
)[i
].is_wild
= ms_has_wild(nameptr
);
1111 if(((*ppname_array
)[i
].name
= SMB_STRDUP(nameptr
)) == NULL
) {
1112 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1113 talloc_free(namelist
);
1117 /* next segment please */
1118 nameptr
= name_end
+ 1;
1122 (*ppname_array
)[i
].name
= NULL
;
1124 talloc_free(namelist
);
1129 #define DBGC_CLASS DBGC_LOCKING
1131 /****************************************************************************
1132 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1133 is dealt with in posix.c
1134 Returns True if we have information regarding this lock region (and returns
1135 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1136 ****************************************************************************/
1138 bool fcntl_getlock(int fd
, off_t
*poffset
, off_t
*pcount
, int *ptype
, pid_t
*ppid
)
1143 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1144 fd
,(double)*poffset
,(double)*pcount
,*ptype
));
1146 lock
.l_type
= *ptype
;
1147 lock
.l_whence
= SEEK_SET
;
1148 lock
.l_start
= *poffset
;
1149 lock
.l_len
= *pcount
;
1152 ret
= sys_fcntl_ptr(fd
,F_GETLK
,&lock
);
1156 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1157 (double)*poffset
,(double)*pcount
,*ptype
,strerror(errno
)));
1162 *ptype
= lock
.l_type
;
1163 *poffset
= lock
.l_start
;
1164 *pcount
= lock
.l_len
;
1167 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1168 fd
, (int)lock
.l_type
, (unsigned int)lock
.l_pid
));
1173 #define DBGC_CLASS DBGC_ALL
1175 /*******************************************************************
1176 Is the name specified one of my netbios names.
1177 Returns true if it is equal, false otherwise.
1178 ********************************************************************/
1180 bool is_myname(const char *s
)
1185 for (n
=0; my_netbios_names(n
); n
++) {
1186 if (strequal(my_netbios_names(n
), s
)) {
1191 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));
1195 /*******************************************************************
1196 we distinguish between 2K and XP by the "Native Lan Manager" string
1197 WinXP => "Windows 2002 5.1"
1198 WinXP 64bit => "Windows XP 5.2"
1199 Win2k => "Windows 2000 5.0"
1200 NT4 => "Windows NT 4.0"
1201 Win9x => "Windows 4.0"
1202 Windows 2003 doesn't set the native lan manager string but
1203 they do set the domain to "Windows 2003 5.2" (probably a bug).
1204 ********************************************************************/
1206 void ra_lanman_string( const char *native_lanman
)
1208 if ( strcmp( native_lanman
, "Windows 2002 5.1" ) == 0 )
1209 set_remote_arch( RA_WINXP
);
1210 else if ( strcmp( native_lanman
, "Windows XP 5.2" ) == 0 )
1211 set_remote_arch( RA_WINXP64
);
1212 else if ( strcmp( native_lanman
, "Windows Server 2003 5.2" ) == 0 )
1213 set_remote_arch( RA_WIN2K3
);
1216 static const char *remote_arch_str
;
1218 const char *get_remote_arch_str(void)
1220 if (!remote_arch_str
) {
1223 return remote_arch_str
;
1226 /*******************************************************************
1227 Set the horrid remote_arch string based on an enum.
1228 ********************************************************************/
1230 void set_remote_arch(enum remote_arch_types type
)
1235 remote_arch_str
= "WfWg";
1238 remote_arch_str
= "OS2";
1241 remote_arch_str
= "Win95";
1244 remote_arch_str
= "WinNT";
1247 remote_arch_str
= "Win2K";
1250 remote_arch_str
= "WinXP";
1253 remote_arch_str
= "WinXP64";
1256 remote_arch_str
= "Win2K3";
1259 remote_arch_str
= "Vista";
1262 remote_arch_str
= "Samba";
1265 remote_arch_str
= "CIFSFS";
1268 remote_arch_str
= "OSX";
1271 ra_type
= RA_UNKNOWN
;
1272 remote_arch_str
= "UNKNOWN";
1276 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1280 /*******************************************************************
1281 Get the remote_arch type.
1282 ********************************************************************/
1284 enum remote_arch_types
get_remote_arch(void)
1289 const char *tab_depth(int level
, int depth
)
1291 if( CHECK_DEBUGLVL(level
) ) {
1292 dbgtext("%*s", depth
*4, "");
1297 /*****************************************************************************
1298 Provide a checksum on a string
1300 Input: s - the null-terminated character string for which the checksum
1303 Output: The checksum value calculated for s.
1304 *****************************************************************************/
1306 int str_checksum(const char *s
)
1310 return hash(s
, strlen(s
), 0);
1313 /*****************************************************************
1314 Zero a memory area then free it. Used to catch bugs faster.
1315 *****************************************************************/
1317 void zero_free(void *p
, size_t size
)
1323 /*****************************************************************
1324 Set our open file limit to a requested max and return the limit.
1325 *****************************************************************/
1327 int set_maxfiles(int requested_max
)
1329 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1331 int saved_current_limit
;
1333 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
1334 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1337 return requested_max
;
1341 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1342 * account for the extra fd we need
1343 * as well as the log files and standard
1344 * handles etc. Save the limit we want to set in case
1345 * we are running on an OS that doesn't support this limit (AIX)
1346 * which always returns RLIM_INFINITY for rlp.rlim_max.
1349 /* Try raising the hard (max) limit to the requested amount. */
1351 #if defined(RLIM_INFINITY)
1352 if (rlp
.rlim_max
!= RLIM_INFINITY
) {
1353 int orig_max
= rlp
.rlim_max
;
1355 if ( rlp
.rlim_max
< requested_max
)
1356 rlp
.rlim_max
= requested_max
;
1358 /* This failing is not an error - many systems (Linux) don't
1359 support our default request of 10,000 open files. JRA. */
1361 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
1362 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1363 (int)rlp
.rlim_max
, strerror(errno
) ));
1365 /* Set failed - restore original value from get. */
1366 rlp
.rlim_max
= orig_max
;
1371 /* Now try setting the soft (current) limit. */
1373 saved_current_limit
= rlp
.rlim_cur
= MIN(requested_max
,rlp
.rlim_max
);
1375 if(setrlimit(RLIMIT_NOFILE
, &rlp
)) {
1376 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1377 (int)rlp
.rlim_cur
, strerror(errno
) ));
1379 return saved_current_limit
;
1382 if(getrlimit(RLIMIT_NOFILE
, &rlp
)) {
1383 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1386 return saved_current_limit
;
1389 #if defined(RLIM_INFINITY)
1390 if(rlp
.rlim_cur
== RLIM_INFINITY
)
1391 return saved_current_limit
;
1394 if((int)rlp
.rlim_cur
> saved_current_limit
)
1395 return saved_current_limit
;
1397 return rlp
.rlim_cur
;
1398 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1400 * No way to know - just guess...
1402 return requested_max
;
1406 /*****************************************************************
1407 malloc that aborts with smb_panic on fail or zero size.
1408 *****************************************************************/
1410 void *smb_xmalloc_array(size_t size
, unsigned int count
)
1414 smb_panic("smb_xmalloc_array: called with zero size");
1416 if (count
>= MAX_ALLOC_SIZE
/size
) {
1417 smb_panic("smb_xmalloc_array: alloc size too large");
1419 if ((p
= SMB_MALLOC(size
*count
)) == NULL
) {
1420 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1421 (unsigned long)size
, (unsigned long)count
));
1422 smb_panic("smb_xmalloc_array: malloc failed");
1428 vasprintf that aborts on malloc fail
1431 int smb_xvasprintf(char **ptr
, const char *format
, va_list ap
)
1438 n
= vasprintf(ptr
, format
, ap2
);
1440 if (n
== -1 || ! *ptr
) {
1441 smb_panic("smb_xvasprintf: out of memory");
1446 /*****************************************************************
1447 Get local hostname and cache result.
1448 *****************************************************************/
1450 char *myhostname(void)
1454 ret
= get_myname(NULL
);
1459 /*****************************************************************
1460 Get local hostname and cache result.
1461 *****************************************************************/
1463 char *myhostname_upper(void)
1467 char *name
= get_myname(NULL
);
1471 ret
= strupper_talloc(NULL
, name
);
1478 * @brief Returns an absolute path to a file concatenating the provided
1479 * @a rootpath and @a basename
1481 * @param name Filename, relative to @a rootpath
1483 * @retval Pointer to a string containing the full path.
1486 static char *xx_path(const char *name
, const char *rootpath
)
1490 fname
= talloc_strdup(talloc_tos(), rootpath
);
1494 trim_string(fname
,"","/");
1496 if (!directory_exist(fname
)) {
1497 if (mkdir(fname
,0755) == -1) {
1498 /* Did someone else win the race ? */
1499 if (errno
!= EEXIST
) {
1500 DEBUG(1, ("Unable to create directory %s for file %s. "
1501 "Error was %s\n", fname
, name
, strerror(errno
)));
1507 return talloc_asprintf_append_buffer(fname
, "/%s", name
);
1511 * @brief Returns an absolute path to a file in the Samba lock directory.
1513 * @param name File to find, relative to LOCKDIR.
1515 * @retval Pointer to a talloc'ed string containing the full path.
1518 char *lock_path(const char *name
)
1520 return xx_path(name
, lp_lock_directory());
1524 * @brief Returns an absolute path to a file in the Samba state directory.
1526 * @param name File to find, relative to STATEDIR.
1528 * @retval Pointer to a talloc'ed string containing the full path.
1531 char *state_path(const char *name
)
1533 return xx_path(name
, lp_state_directory());
1537 * @brief Returns an absolute path to a file in the Samba cache directory.
1539 * @param name File to find, relative to CACHEDIR.
1541 * @retval Pointer to a talloc'ed string containing the full path.
1544 char *cache_path(const char *name
)
1546 return xx_path(name
, lp_cache_directory());
1549 /*******************************************************************
1550 Given a filename - get its directory name
1551 ********************************************************************/
1553 bool parent_dirname(TALLOC_CTX
*mem_ctx
, const char *dir
, char **parent
,
1559 p
= strrchr_m(dir
, '/'); /* Find final '/', if any */
1562 if (!(*parent
= talloc_strdup(mem_ctx
, "."))) {
1573 if (!(*parent
= (char *)talloc_memdup(mem_ctx
, dir
, len
+1))) {
1576 (*parent
)[len
] = '\0';
1584 /*******************************************************************
1585 Determine if a pattern contains any Microsoft wildcard characters.
1586 *******************************************************************/
1588 bool ms_has_wild(const char *s
)
1592 if (lp_posix_pathnames()) {
1593 /* With posix pathnames no characters are wild. */
1597 while ((c
= *s
++)) {
1610 bool ms_has_wild_w(const smb_ucs2_t
*s
)
1613 if (!s
) return False
;
1614 while ((c
= *s
++)) {
1616 case UCS2_CHAR('*'):
1617 case UCS2_CHAR('?'):
1618 case UCS2_CHAR('<'):
1619 case UCS2_CHAR('>'):
1620 case UCS2_CHAR('"'):
1627 /*******************************************************************
1628 A wrapper that handles case sensitivity and the special handling
1630 *******************************************************************/
1632 bool mask_match(const char *string
, const char *pattern
, bool is_case_sensitive
)
1634 if (ISDOTDOT(string
))
1639 return ms_fnmatch(pattern
, string
, Protocol
<= PROTOCOL_LANMAN2
, is_case_sensitive
) == 0;
1642 /*******************************************************************
1643 A wrapper that handles case sensitivity and the special handling
1644 of the ".." name. Varient that is only called by old search code which requires
1645 pattern translation.
1646 *******************************************************************/
1648 bool mask_match_search(const char *string
, const char *pattern
, bool is_case_sensitive
)
1650 if (ISDOTDOT(string
))
1655 return ms_fnmatch(pattern
, string
, True
, is_case_sensitive
) == 0;
1658 /*******************************************************************
1659 A wrapper that handles a list of patters and calls mask_match()
1660 on each. Returns True if any of the patterns match.
1661 *******************************************************************/
1663 bool mask_match_list(const char *string
, char **list
, int listLen
, bool is_case_sensitive
)
1665 while (listLen
-- > 0) {
1666 if (mask_match(string
, *list
++, is_case_sensitive
))
1672 /*********************************************************
1673 Recursive routine that is called by unix_wild_match.
1674 *********************************************************/
1676 static bool unix_do_match(const char *regexp
, const char *str
)
1680 for( p
= regexp
; *p
&& *str
; ) {
1691 * Look for a character matching
1692 * the one after the '*'.
1696 return true; /* Automatic match */
1699 while(*str
&& (*p
!= *str
))
1703 * Patch from weidel@multichart.de. In the case of the regexp
1704 * '*XX*' we want to ensure there are at least 2 'X' characters
1705 * in the string after the '*' for a match to be made.
1712 * Eat all the characters that match, but count how many there were.
1715 while(*str
&& (*p
== *str
)) {
1721 * Now check that if the regexp had n identical characters that
1722 * matchcount had at least that many matches.
1725 while ( *(p
+1) && (*(p
+1) == *p
)) {
1730 if ( matchcount
<= 0 )
1734 str
--; /* We've eaten the match char after the '*' */
1736 if(unix_do_match(p
, str
))
1758 if (!*p
&& str
[0] == '.' && str
[1] == 0)
1761 if (!*str
&& *p
== '?') {
1767 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
1773 /*******************************************************************
1774 Simple case insensitive interface to a UNIX wildcard matcher.
1775 Returns True if match, False if not.
1776 *******************************************************************/
1778 bool unix_wild_match(const char *pattern
, const char *string
)
1780 TALLOC_CTX
*ctx
= talloc_stackframe();
1786 p2
= talloc_strdup(ctx
,pattern
);
1787 s2
= talloc_strdup(ctx
,string
);
1792 if (!strlower_m(p2
)) {
1796 if (!strlower_m(s2
)) {
1801 /* Remove any *? and ** from the pattern as they are meaningless */
1802 for(p
= p2
; *p
; p
++) {
1803 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*')) {
1804 memmove(&p
[1], &p
[2], strlen(&p
[2])+1);
1808 if (strequal(p2
,"*")) {
1813 ret
= unix_do_match(p2
, s2
);
1818 /**********************************************************************
1819 Converts a name to a fully qualified domain name.
1820 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1821 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1822 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1823 ***********************************************************************/
1825 bool name_to_fqdn(fstring fqdn
, const char *name
)
1828 struct hostent
*hp
= gethostbyname(name
);
1830 if (!hp
|| !hp
->h_name
|| !*hp
->h_name
) {
1831 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name
));
1832 fstrcpy(fqdn
, name
);
1836 /* Find out if the fqdn is returned as an alias
1837 * to cope with /etc/hosts files where the first
1838 * name is not the fqdn but the short name */
1839 if (hp
->h_aliases
&& (! strchr_m(hp
->h_name
, '.'))) {
1841 for (i
= 0; hp
->h_aliases
[i
]; i
++) {
1842 if (strchr_m(hp
->h_aliases
[i
], '.')) {
1843 full
= hp
->h_aliases
[i
];
1848 if (full
&& (strcasecmp_m(full
, "localhost.localdomain") == 0)) {
1849 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1850 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1851 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1852 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1859 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name
, full
));
1860 fstrcpy(fqdn
, full
);
1864 /**********************************************************************
1865 Append a DATA_BLOB to a talloc'ed object
1866 ***********************************************************************/
1868 void *talloc_append_blob(TALLOC_CTX
*mem_ctx
, void *buf
, DATA_BLOB blob
)
1870 size_t old_size
= 0;
1873 if (blob
.length
== 0) {
1878 old_size
= talloc_get_size(buf
);
1881 result
= (char *)TALLOC_REALLOC(mem_ctx
, buf
, old_size
+ blob
.length
);
1882 if (result
== NULL
) {
1886 memcpy(result
+ old_size
, blob
.data
, blob
.length
);
1890 uint32
map_share_mode_to_deny_mode(uint32 share_access
, uint32 private_options
)
1892 switch (share_access
& ~FILE_SHARE_DELETE
) {
1893 case FILE_SHARE_NONE
:
1895 case FILE_SHARE_READ
:
1897 case FILE_SHARE_WRITE
:
1899 case FILE_SHARE_READ
|FILE_SHARE_WRITE
:
1902 if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) {
1904 } else if (private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
) {
1911 pid_t
procid_to_pid(const struct server_id
*proc
)
1916 static uint32 my_vnn
= NONCLUSTER_VNN
;
1918 void set_my_vnn(uint32 vnn
)
1920 DEBUG(10, ("vnn pid %d = %u\n", (int)getpid(), (unsigned int)vnn
));
1924 uint32
get_my_vnn(void)
1929 static uint64_t my_unique_id
= 0;
1931 void set_my_unique_id(uint64_t unique_id
)
1933 my_unique_id
= unique_id
;
1936 struct server_id
pid_to_procid(pid_t pid
)
1938 struct server_id result
;
1941 result
.unique_id
= my_unique_id
;
1942 result
.vnn
= my_vnn
;
1946 struct server_id
procid_self(void)
1948 return pid_to_procid(getpid());
1951 bool procid_is_me(const struct server_id
*pid
)
1953 if (pid
->pid
!= getpid())
1955 if (pid
->task_id
!= 0)
1957 if (pid
->vnn
!= my_vnn
)
1962 struct server_id
interpret_pid(const char *pid_string
)
1964 return server_id_from_string(get_my_vnn(), pid_string
);
1967 char *procid_str_static(const struct server_id
*pid
)
1969 return server_id_str(talloc_tos(), pid
);
1972 bool procid_valid(const struct server_id
*pid
)
1974 return (pid
->pid
!= (uint64_t)-1);
1977 bool procid_is_local(const struct server_id
*pid
)
1979 return pid
->vnn
== my_vnn
;
1982 /****************************************************************
1983 Check if an offset into a buffer is safe.
1984 If this returns True it's safe to indirect into the byte at
1986 ****************************************************************/
1988 bool is_offset_safe(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
1990 const char *end_base
= buf_base
+ buf_len
;
1991 char *end_ptr
= ptr
+ off
;
1993 if (!buf_base
|| !ptr
) {
1997 if (end_base
< buf_base
|| end_ptr
< ptr
) {
1998 return False
; /* wrap. */
2001 if (end_ptr
< end_base
) {
2007 /****************************************************************
2008 Return a safe pointer into a buffer, or NULL.
2009 ****************************************************************/
2011 char *get_safe_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2013 return is_offset_safe(buf_base
, buf_len
, ptr
, off
) ?
2017 /****************************************************************
2018 Return a safe pointer into a string within a buffer, or NULL.
2019 ****************************************************************/
2021 char *get_safe_str_ptr(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
)
2023 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
)) {
2026 /* Check if a valid string exists at this offset. */
2027 if (skip_string(buf_base
,buf_len
, ptr
+ off
) == NULL
) {
2033 /****************************************************************
2034 Return an SVAL at a pointer, or failval if beyond the end.
2035 ****************************************************************/
2037 int get_safe_SVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2040 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2043 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+1)) {
2046 return SVAL(ptr
,off
);
2049 /****************************************************************
2050 Return an IVAL at a pointer, or failval if beyond the end.
2051 ****************************************************************/
2053 int get_safe_IVAL(const char *buf_base
, size_t buf_len
, char *ptr
, size_t off
, int failval
)
2056 * Note we use off+3 here, not off+4 as IVAL accesses
2057 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2059 if (!is_offset_safe(buf_base
, buf_len
, ptr
, off
+3)) {
2062 return IVAL(ptr
,off
);
2065 /****************************************************************
2066 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2067 call (they take care of winbind separator and other winbind specific settings).
2068 ****************************************************************/
2070 void split_domain_user(TALLOC_CTX
*mem_ctx
,
2071 const char *full_name
,
2075 const char *p
= NULL
;
2077 p
= strchr_m(full_name
, '\\');
2080 *domain
= talloc_strndup(mem_ctx
, full_name
,
2081 PTR_DIFF(p
, full_name
));
2082 *user
= talloc_strdup(mem_ctx
, p
+1);
2084 *domain
= talloc_strdup(mem_ctx
, "");
2085 *user
= talloc_strdup(mem_ctx
, full_name
);
2089 /****************************************************************
2090 strip off leading '\\' from a hostname
2091 ****************************************************************/
2093 const char *strip_hostname(const char *s
)
2099 if (strlen_m(s
) < 3) {
2103 if (s
[0] == '\\') s
++;
2104 if (s
[0] == '\\') s
++;
2109 bool any_nt_status_not_ok(NTSTATUS err1
, NTSTATUS err2
, NTSTATUS
*result
)
2111 if (!NT_STATUS_IS_OK(err1
)) {
2115 if (!NT_STATUS_IS_OK(err2
)) {
2122 int timeval_to_msec(struct timeval t
)
2124 return t
.tv_sec
* 1000 + (t
.tv_usec
+999) / 1000;
2127 /*******************************************************************
2128 Check a given DOS pathname is valid for a share.
2129 ********************************************************************/
2131 char *valid_share_pathname(TALLOC_CTX
*ctx
, const char *dos_pathname
)
2135 if (!dos_pathname
) {
2139 ptr
= talloc_strdup(ctx
, dos_pathname
);
2143 /* Convert any '\' paths to '/' */
2145 ptr
= unix_clean_name(ctx
, ptr
);
2150 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2151 if (strlen(ptr
) > 2 && ptr
[1] == ':' && ptr
[0] != '/')
2154 /* Only absolute paths allowed. */
2161 /*******************************************************************
2162 Return True if the filename is one of the special executable types.
2163 ********************************************************************/
2165 bool is_executable(const char *fname
)
2167 if ((fname
= strrchr_m(fname
,'.'))) {
2168 if (strequal(fname
,".com") ||
2169 strequal(fname
,".dll") ||
2170 strequal(fname
,".exe") ||
2171 strequal(fname
,".sym")) {
2178 /****************************************************************************
2179 Open a file with a share mode - old openX method - map into NTCreate.
2180 ****************************************************************************/
2182 bool map_open_params_to_ntcreate(const char *smb_base_fname
,
2183 int deny_mode
, int open_func
,
2184 uint32
*paccess_mask
,
2185 uint32
*pshare_mode
,
2186 uint32
*pcreate_disposition
,
2187 uint32
*pcreate_options
,
2188 uint32_t *pprivate_flags
)
2192 uint32 create_disposition
;
2193 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
2194 uint32_t private_flags
= 0;
2196 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2197 "open_func = 0x%x\n",
2198 smb_base_fname
, (unsigned int)deny_mode
,
2199 (unsigned int)open_func
));
2201 /* Create the NT compatible access_mask. */
2202 switch (GET_OPENX_MODE(deny_mode
)) {
2203 case DOS_OPEN_EXEC
: /* Implies read-only - used to be FILE_READ_DATA */
2204 case DOS_OPEN_RDONLY
:
2205 access_mask
= FILE_GENERIC_READ
;
2207 case DOS_OPEN_WRONLY
:
2208 access_mask
= FILE_GENERIC_WRITE
;
2212 access_mask
= FILE_GENERIC_READ
|FILE_GENERIC_WRITE
;
2215 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2216 (unsigned int)GET_OPENX_MODE(deny_mode
)));
2220 /* Create the NT compatible create_disposition. */
2221 switch (open_func
) {
2222 case OPENX_FILE_EXISTS_FAIL
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2223 create_disposition
= FILE_CREATE
;
2226 case OPENX_FILE_EXISTS_OPEN
:
2227 create_disposition
= FILE_OPEN
;
2230 case OPENX_FILE_EXISTS_OPEN
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2231 create_disposition
= FILE_OPEN_IF
;
2234 case OPENX_FILE_EXISTS_TRUNCATE
:
2235 create_disposition
= FILE_OVERWRITE
;
2238 case OPENX_FILE_EXISTS_TRUNCATE
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
2239 create_disposition
= FILE_OVERWRITE_IF
;
2243 /* From samba4 - to be confirmed. */
2244 if (GET_OPENX_MODE(deny_mode
) == DOS_OPEN_EXEC
) {
2245 create_disposition
= FILE_CREATE
;
2248 DEBUG(10,("map_open_params_to_ntcreate: bad "
2249 "open_func 0x%x\n", (unsigned int)open_func
));
2253 /* Create the NT compatible share modes. */
2254 switch (GET_DENY_MODE(deny_mode
)) {
2256 share_mode
= FILE_SHARE_NONE
;
2260 share_mode
= FILE_SHARE_READ
;
2264 share_mode
= FILE_SHARE_WRITE
;
2268 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
2272 private_flags
|= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
;
2273 if (is_executable(smb_base_fname
)) {
2274 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
2276 if (GET_OPENX_MODE(deny_mode
) == DOS_OPEN_RDONLY
) {
2277 share_mode
= FILE_SHARE_READ
;
2279 share_mode
= FILE_SHARE_NONE
;
2285 private_flags
|= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
;
2286 share_mode
= FILE_SHARE_NONE
;
2290 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2291 (unsigned int)GET_DENY_MODE(deny_mode
) ));
2295 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2296 "share_mode = 0x%x, create_disposition = 0x%x, "
2297 "create_options = 0x%x private_flags = 0x%x\n",
2299 (unsigned int)access_mask
,
2300 (unsigned int)share_mode
,
2301 (unsigned int)create_disposition
,
2302 (unsigned int)create_options
,
2303 (unsigned int)private_flags
));
2306 *paccess_mask
= access_mask
;
2309 *pshare_mode
= share_mode
;
2311 if (pcreate_disposition
) {
2312 *pcreate_disposition
= create_disposition
;
2314 if (pcreate_options
) {
2315 *pcreate_options
= create_options
;
2317 if (pprivate_flags
) {
2318 *pprivate_flags
= private_flags
;
2325 /*************************************************************************
2326 Return a talloced copy of a struct security_unix_token. NULL on fail.
2327 *************************************************************************/
2329 struct security_unix_token
*copy_unix_token(TALLOC_CTX
*ctx
, const struct security_unix_token
*tok
)
2331 struct security_unix_token
*cpy
;
2333 cpy
= talloc(ctx
, struct security_unix_token
);
2338 cpy
->uid
= tok
->uid
;
2339 cpy
->gid
= tok
->gid
;
2340 cpy
->ngroups
= tok
->ngroups
;
2342 /* Make this a talloc child of cpy. */
2343 cpy
->groups
= (gid_t
*)talloc_memdup(
2344 cpy
, tok
->groups
, tok
->ngroups
* sizeof(gid_t
));
2355 /****************************************************************************
2356 Check that a file matches a particular file type.
2357 ****************************************************************************/
2359 bool dir_check_ftype(uint32_t mode
, uint32_t dirtype
)
2363 /* Check the "may have" search bits. */
2364 if (((mode
& ~dirtype
) &
2365 (FILE_ATTRIBUTE_HIDDEN
|
2366 FILE_ATTRIBUTE_SYSTEM
|
2367 FILE_ATTRIBUTE_DIRECTORY
)) != 0) {
2371 /* Check the "must have" bits,
2372 which are the may have bits shifted eight */
2373 /* If must have bit is set, the file/dir can
2374 not be returned in search unless the matching
2375 file attribute is set */
2376 mask
= ((dirtype
>> 8) & (FILE_ATTRIBUTE_DIRECTORY
|
2377 FILE_ATTRIBUTE_ARCHIVE
|
2378 FILE_ATTRIBUTE_READONLY
|
2379 FILE_ATTRIBUTE_HIDDEN
|
2380 FILE_ATTRIBUTE_SYSTEM
)); /* & 0x37 */
2382 if((mask
& (mode
& (FILE_ATTRIBUTE_DIRECTORY
|
2383 FILE_ATTRIBUTE_ARCHIVE
|
2384 FILE_ATTRIBUTE_READONLY
|
2385 FILE_ATTRIBUTE_HIDDEN
|
2386 FILE_ATTRIBUTE_SYSTEM
))) == mask
) {
2387 /* check if matching attribute present */