2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2007
6 Copyright (C) Simo Sorce 2001
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) James Peach 2006
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "system/passwd.h"
26 #include "system/filesys.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/util_pw.h"
31 #include <ccan/hash/hash.h>
32 #include "libcli/security/security.h"
34 #ifdef HAVE_SYS_PRCTL_H
35 #include <sys/prctl.h>
38 /* Max allowable allococation - 256mb - 0x10000000 */
39 #define MAX_ALLOC_SIZE (1024*1024*256)
41 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
42 #ifdef WITH_NISPLUS_HOME
43 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
45 * The following lines are needed due to buggy include files
46 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
47 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
48 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
49 * an enum in /usr/include/rpcsvc/nis.h.
56 #if defined(GROUP_OBJ)
60 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
62 #include <rpcsvc/nis.h>
64 #endif /* WITH_NISPLUS_HOME */
65 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
67 static enum protocol_types Protocol = PROTOCOL_COREPLUS;
69 enum protocol_types get_Protocol(void)
74 void set_Protocol(enum protocol_types p)
79 static enum remote_arch_types ra_type = RA_UNKNOWN;
81 void gfree_all( void )
90 /*******************************************************************
91 Check if a file exists - call vfs_file_exist for samba files.
92 ********************************************************************/
94 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf,
95 bool fake_dir_create_times)
101 if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
104 return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
107 /*******************************************************************
108 Check if a unix domain socket exists - call vfs_file_exist for samba files.
109 ********************************************************************/
111 bool socket_exist(const char *fname)
114 if (sys_stat(fname, &st, false) != 0)
117 return S_ISSOCK(st.st_ex_mode);
120 /*******************************************************************
121 Returns the size in bytes of the named given the stat struct.
122 ********************************************************************/
124 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
126 return sbuf->st_ex_size;
129 /*******************************************************************
130 Show a smb message structure.
131 ********************************************************************/
133 void show_msg(const char *buf)
141 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
143 (int)CVAL(buf,smb_com),
144 (int)CVAL(buf,smb_rcls),
145 (int)CVAL(buf,smb_reh),
146 (int)SVAL(buf,smb_err),
147 (int)CVAL(buf,smb_flg),
148 (int)SVAL(buf,smb_flg2)));
149 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
150 (int)SVAL(buf,smb_tid),
151 (int)SVAL(buf,smb_pid),
152 (int)SVAL(buf,smb_uid),
153 (int)SVAL(buf,smb_mid)));
154 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
156 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
157 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
158 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
160 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
162 DEBUGADD(5,("smb_bcc=%d\n",bcc));
170 dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
173 /*******************************************************************
174 Setup only the byte count for a smb message.
175 ********************************************************************/
177 int set_message_bcc(char *buf,int num_bytes)
179 int num_words = CVAL(buf,smb_wct);
180 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
181 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
182 return (smb_size + num_words*2 + num_bytes);
185 /*******************************************************************
186 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
187 Return the bytes added
188 ********************************************************************/
190 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
192 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
195 if (!(tmp = talloc_realloc(NULL, *outbuf, uint8, newlen))) {
196 DEBUG(0, ("talloc failed\n"));
201 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
202 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
206 /*******************************************************************
207 Reduce a file name, removing .. elements.
208 ********************************************************************/
210 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
215 DEBUG(3,("dos_clean_name [%s]\n",s));
217 /* remove any double slashes */
218 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
223 /* Remove leading .\\ characters */
224 if(strncmp(str, ".\\", 2) == 0) {
225 trim_string(str, ".\\", NULL);
227 str = talloc_strdup(ctx, ".\\");
234 while ((p = strstr_m(str,"\\..\\")) != NULL) {
240 if ((p=strrchr_m(str,'\\')) != NULL) {
245 str = talloc_asprintf(ctx,
254 trim_string(str,NULL,"\\..");
255 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
258 /*******************************************************************
259 Reduce a file name, removing .. elements.
260 ********************************************************************/
262 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
267 DEBUG(3,("unix_clean_name [%s]\n",s));
269 /* remove any double slashes */
270 str = talloc_all_string_sub(ctx, s, "//","/");
275 /* Remove leading ./ characters */
276 if(strncmp(str, "./", 2) == 0) {
277 trim_string(str, "./", NULL);
279 str = talloc_strdup(ctx, "./");
286 while ((p = strstr_m(str,"/../")) != NULL) {
292 if ((p=strrchr_m(str,'/')) != NULL) {
297 str = talloc_asprintf(ctx,
306 trim_string(str,NULL,"/..");
307 return talloc_all_string_sub(ctx, str, "/./", "/");
310 char *clean_name(TALLOC_CTX *ctx, const char *s)
312 char *str = dos_clean_name(ctx, s);
316 return unix_clean_name(ctx, str);
319 /*******************************************************************
320 Write data into an fd at a given offset. Ignore seek errors.
321 ********************************************************************/
323 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
328 if (pos == (SMB_OFF_T)-1) {
329 return write_data(fd, buffer, N);
331 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
333 ret = sys_pwrite(fd,buffer + total,N - total, pos);
334 if (ret == -1 && errno == ESPIPE) {
335 return write_data(fd, buffer + total,N - total);
338 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
347 return (ssize_t)total;
349 /* Use lseek and write_data. */
350 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
351 if (errno != ESPIPE) {
355 return write_data(fd, buffer, N);
360 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
361 struct event_context *ev_ctx,
362 bool parent_longlived)
364 NTSTATUS status = NT_STATUS_OK;
366 /* Reset the state of the random
367 * number generation system, so
368 * children do not get the same random
369 * numbers as each other */
370 set_need_random_reseed();
372 /* tdb needs special fork handling */
373 if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
374 DEBUG(0,("tdb_reopen_all failed.\n"));
375 status = NT_STATUS_OPEN_FAILED;
379 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
380 smb_panic(__location__ ": Failed to re-initialise event context");
385 * For clustering, we need to re-init our ctdbd connection after the
388 status = messaging_reinit(msg_ctx);
389 if (!NT_STATUS_IS_OK(status)) {
390 DEBUG(0,("messaging_reinit() failed: %s\n",
398 /****************************************************************************
399 (Hopefully) efficient array append.
400 ****************************************************************************/
402 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
403 void *element, void *_array, uint32 *num_elements,
406 void **array = (void **)_array;
408 if (*array_size < 0) {
412 if (*array == NULL) {
413 if (*array_size == 0) {
417 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
421 *array = TALLOC(mem_ctx, element_size * (*array_size));
422 if (*array == NULL) {
427 if (*num_elements == *array_size) {
430 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
434 *array = TALLOC_REALLOC(mem_ctx, *array,
435 element_size * (*array_size));
437 if (*array == NULL) {
442 memcpy((char *)(*array) + element_size*(*num_elements),
443 element, element_size);
453 /****************************************************************************
454 Get my own domain name, or "" if we have none.
455 ****************************************************************************/
457 char *get_mydnsdomname(TALLOC_CTX *ctx)
462 domname = get_mydnsfullname();
467 p = strchr_m(domname, '.');
470 return talloc_strdup(ctx, p);
472 return talloc_strdup(ctx, "");
476 /****************************************************************************
477 Interpret a protocol description string, with a default.
478 ****************************************************************************/
480 int interpret_protocol(const char *str,int def)
482 if (strequal(str,"NT1"))
483 return(PROTOCOL_NT1);
484 if (strequal(str,"LANMAN2"))
485 return(PROTOCOL_LANMAN2);
486 if (strequal(str,"LANMAN1"))
487 return(PROTOCOL_LANMAN1);
488 if (strequal(str,"CORE"))
489 return(PROTOCOL_CORE);
490 if (strequal(str,"COREPLUS"))
491 return(PROTOCOL_COREPLUS);
492 if (strequal(str,"CORE+"))
493 return(PROTOCOL_COREPLUS);
495 DEBUG(0,("Unrecognised protocol level %s\n",str));
501 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
502 /******************************************************************
503 Remove any mount options such as -rsize=2048,wsize=2048 etc.
504 Based on a fix from <Thomas.Hepper@icem.de>.
505 Returns a malloc'ed string.
506 *******************************************************************/
508 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
512 while(*p && !isspace(*p))
514 while(*p && isspace(*p))
517 return talloc_strdup(ctx, p);
523 /*******************************************************************
524 Patch from jkf@soton.ac.uk
525 Split Luke's automount_server into YP lookup and string splitter
526 so can easily implement automount_path().
527 Returns a malloc'ed string.
528 *******************************************************************/
530 #ifdef WITH_NISPLUS_HOME
531 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
535 char *nis_map = (char *)lp_nis_home_map_name();
537 char buffer[NIS_MAXATTRVAL + 1];
542 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
543 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
545 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
546 if (result->status != NIS_SUCCESS) {
547 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
549 object = result->objects.objects_val;
550 if (object->zo_data.zo_type == ENTRY_OBJ) {
551 entry = &object->zo_data.objdata_u.en_data;
552 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
553 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
555 value = talloc_strdup(ctx,
556 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
558 nis_freeresult(result);
561 value = talloc_string_sub(ctx,
568 nis_freeresult(result);
571 value = strip_mount_options(ctx, value);
572 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
577 #else /* WITH_NISPLUS_HOME */
579 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
583 int nis_error; /* returned by yp all functions */
584 char *nis_result; /* yp_match inits this */
585 int nis_result_len; /* and set this */
586 char *nis_domain; /* yp_get_default_domain inits this */
587 char *nis_map = (char *)lp_nis_home_map_name();
589 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
590 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
594 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
596 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
597 strlen(user_name), &nis_result,
598 &nis_result_len)) == 0) {
599 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
600 nis_result[nis_result_len] = '\0';
602 value = talloc_strdup(ctx, nis_result);
606 value = strip_mount_options(ctx, value);
607 } else if(nis_error == YPERR_KEY) {
608 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
609 user_name, nis_map));
610 DEBUG(3, ("using defaults for server and home directory\n"));
612 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
613 yperr_string(nis_error), user_name, nis_map));
617 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
621 #endif /* WITH_NISPLUS_HOME */
624 /****************************************************************************
625 Check if a process exists. Does this work on all unixes?
626 ****************************************************************************/
628 bool process_exists(const struct server_id pid)
630 if (procid_is_me(&pid)) {
634 if (procid_is_local(&pid)) {
635 return (kill(pid.pid,0) == 0 || errno != ESRCH);
638 #ifdef CLUSTER_SUPPORT
639 return ctdbd_process_exists(messaging_ctdbd_connection(),
646 bool processes_exist(const struct server_id *pids, int num_pids,
649 struct server_id *remote_pids = NULL;
650 int *remote_idx = NULL;
651 bool *remote_results = NULL;
652 int i, num_remote_pids;
655 remote_pids = talloc_array(talloc_tos(), struct server_id, num_pids);
656 if (remote_pids == NULL) {
659 remote_idx = talloc_array(talloc_tos(), int, num_pids);
660 if (remote_idx == NULL) {
663 remote_results = talloc_array(talloc_tos(), bool, num_pids);
664 if (remote_results == NULL) {
670 for (i=0; i<num_pids; i++) {
671 if (procid_is_me(&pids[i])) {
675 if (procid_is_local(&pids[i])) {
676 results[i] = ((kill(pids[i].pid,0) == 0) ||
681 remote_pids[num_remote_pids] = pids[i];
682 remote_idx[num_remote_pids] = i;
683 num_remote_pids += 1;
686 if (num_remote_pids != 0) {
687 #ifdef CLUSTER_SUPPORT
688 if (!ctdb_processes_exist(messaging_ctdbd_connection(),
689 remote_pids, num_remote_pids,
694 for (i=0; i<num_remote_pids; i++) {
695 remote_results[i] = false;
699 for (i=0; i<num_remote_pids; i++) {
700 results[remote_idx[i]] = remote_results[i];
706 TALLOC_FREE(remote_results);
707 TALLOC_FREE(remote_idx);
708 TALLOC_FREE(remote_pids);
712 /*******************************************************************
713 Convert a uid into a user name.
714 ********************************************************************/
716 const char *uidtoname(uid_t uid)
718 TALLOC_CTX *ctx = talloc_tos();
720 struct passwd *pass = NULL;
722 pass = getpwuid_alloc(ctx,uid);
724 name = talloc_strdup(ctx,pass->pw_name);
727 name = talloc_asprintf(ctx,
734 /*******************************************************************
735 Convert a gid into a group name.
736 ********************************************************************/
738 char *gidtoname(gid_t gid)
744 return talloc_strdup(talloc_tos(), grp->gr_name);
747 return talloc_asprintf(talloc_tos(),
753 /*******************************************************************
754 Convert a user name into a uid.
755 ********************************************************************/
757 uid_t nametouid(const char *name)
763 pass = Get_Pwnam_alloc(talloc_tos(), name);
770 u = (uid_t)strtol(name, &p, 0);
771 if ((p != name) && (*p == '\0'))
777 /*******************************************************************
778 Convert a name to a gid_t if possible. Return -1 if not a group.
779 ********************************************************************/
781 gid_t nametogid(const char *name)
787 g = (gid_t)strtol(name, &p, 0);
788 if ((p != name) && (*p == '\0'))
791 grp = sys_getgrnam(name);
797 /*******************************************************************
798 Something really nasty happened - panic !
799 ********************************************************************/
801 void smb_panic_s3(const char *why)
806 DEBUG(0,("PANIC (pid %llu): %s\n",
807 (unsigned long long)sys_getpid(), why));
810 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
812 * Make sure all children can attach a debugger.
814 prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
817 cmd = lp_panic_action();
819 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
820 result = system(cmd);
823 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
826 DEBUG(0, ("smb_panic(): action returned status %d\n",
827 WEXITSTATUS(result)));
833 /*******************************************************************
834 Print a backtrace of the stack to the debug log. This function
835 DELIBERATELY LEAKS MEMORY. The expectation is that you should
836 exit shortly after calling it.
837 ********************************************************************/
839 #ifdef HAVE_LIBUNWIND_H
840 #include <libunwind.h>
843 #ifdef HAVE_EXECINFO_H
844 #include <execinfo.h>
851 void log_stack_trace(void)
853 #ifdef HAVE_LIBUNWIND
854 /* Try to use libunwind before any other technique since on ia64
855 * libunwind correctly walks the stack in more circumstances than
863 unw_word_t ip, sp, off;
865 procname[sizeof(procname) - 1] = '\0';
867 if (unw_getcontext(&uc) != 0) {
868 goto libunwind_failed;
871 if (unw_init_local(&cursor, &uc) != 0) {
872 goto libunwind_failed;
875 DEBUG(0, ("BACKTRACE:\n"));
879 unw_get_reg(&cursor, UNW_REG_IP, &ip);
880 unw_get_reg(&cursor, UNW_REG_SP, &sp);
882 switch (unw_get_proc_name(&cursor,
883 procname, sizeof(procname) - 1, &off) ) {
887 /* Name truncated. */
888 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
889 i, procname, (long long)off,
890 (long long)ip, (long long) sp));
893 /* case -UNW_ENOINFO: */
894 /* case -UNW_EUNSPEC: */
895 /* No symbol name found. */
896 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
897 i, "<unknown symbol>",
898 (long long)ip, (long long) sp));
901 } while (unw_step(&cursor) > 0);
906 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
908 #elif HAVE_BACKTRACE_SYMBOLS
909 void *backtrace_stack[BACKTRACE_STACK_SIZE];
910 size_t backtrace_size;
911 char **backtrace_strings;
913 /* get the backtrace (stack frames) */
914 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
915 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
917 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
918 (unsigned long)backtrace_size));
920 if (backtrace_strings) {
923 for (i = 0; i < backtrace_size; i++)
924 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
926 /* Leak the backtrace_strings, rather than risk what free() might do */
931 /* The IRIX libexc library provides an API for unwinding the stack. See
932 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
933 * since we are about to abort anyway, it hardly matters.
936 #define NAMESIZE 32 /* Arbitrary */
938 __uint64_t addrs[BACKTRACE_STACK_SIZE];
939 char * names[BACKTRACE_STACK_SIZE];
940 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
949 /* We need to be root so we can open our /proc entry to walk
950 * our stack. It also helps when we want to dump core.
954 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
955 names[i] = namebuf + (i * NAMESIZE);
958 levels = trace_back_stack(0, addrs, names,
959 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
961 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
962 for (i = 0; i < levels; i++) {
963 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
968 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
972 /*******************************************************************
973 A readdir wrapper which just returns the file name.
974 ********************************************************************/
976 const char *readdirname(SMB_STRUCT_DIR *p)
978 SMB_STRUCT_DIRENT *ptr;
984 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
995 #ifdef HAVE_BROKEN_READDIR_NAME
996 /* using /usr/ucb/cc is BAD */
1000 return talloc_strdup(talloc_tos(), dname);
1003 /*******************************************************************
1004 Utility function used to decide if the last component
1005 of a path matches a (possibly wildcarded) entry in a namelist.
1006 ********************************************************************/
1008 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1010 const char *last_component;
1012 /* if we have no list it's obviously not in the path */
1013 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1017 DEBUG(8, ("is_in_path: %s\n", name));
1019 /* Get the last component of the unix name. */
1020 last_component = strrchr_m(name, '/');
1021 if (!last_component) {
1022 last_component = name;
1024 last_component++; /* Go past '/' */
1027 for(; namelist->name != NULL; namelist++) {
1028 if(namelist->is_wild) {
1029 if (mask_match(last_component, namelist->name, case_sensitive)) {
1030 DEBUG(8,("is_in_path: mask match succeeded\n"));
1034 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1035 (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
1036 DEBUG(8,("is_in_path: match succeeded\n"));
1041 DEBUG(8,("is_in_path: match not found\n"));
1045 /*******************************************************************
1046 Strip a '/' separated list into an array of
1047 name_compare_enties structures suitable for
1048 passing to is_in_path(). We do this for
1049 speed so we can pre-parse all the names in the list
1050 and don't do it for each call to is_in_path().
1051 We also check if the entry contains a wildcard to
1052 remove a potentially expensive call to mask_match
1054 ********************************************************************/
1056 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1061 int num_entries = 0;
1064 (*ppname_array) = NULL;
1066 if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0')))
1069 namelist = talloc_strdup(talloc_tos(), namelist_in);
1070 if (namelist == NULL) {
1071 DEBUG(0,("set_namearray: talloc fail\n"));
1076 /* We need to make two passes over the string. The
1077 first to count the number of elements, the second
1082 if ( *nameptr == '/' ) {
1083 /* cope with multiple (useless) /s) */
1087 /* anything left? */
1088 if ( *nameptr == '\0' )
1091 /* find the next '/' or consume remaining */
1092 name_end = strchr_m(nameptr, '/');
1093 if (name_end == NULL)
1094 name_end = (char *)nameptr + strlen(nameptr);
1096 /* next segment please */
1097 nameptr = name_end + 1;
1101 if(num_entries == 0) {
1102 talloc_free(namelist);
1106 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1107 DEBUG(0,("set_namearray: malloc fail\n"));
1108 talloc_free(namelist);
1112 /* Now copy out the names */
1116 if ( *nameptr == '/' ) {
1117 /* cope with multiple (useless) /s) */
1121 /* anything left? */
1122 if ( *nameptr == '\0' )
1125 /* find the next '/' or consume remaining */
1126 name_end = strchr_m(nameptr, '/');
1130 name_end = nameptr + strlen(nameptr);
1132 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1133 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1134 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1135 talloc_free(namelist);
1139 /* next segment please */
1140 nameptr = name_end + 1;
1144 (*ppname_array)[i].name = NULL;
1146 talloc_free(namelist);
1151 #define DBGC_CLASS DBGC_LOCKING
1153 /****************************************************************************
1154 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1155 is dealt with in posix.c
1156 Returns True if we have information regarding this lock region (and returns
1157 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1158 ****************************************************************************/
1160 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1162 SMB_STRUCT_FLOCK lock;
1165 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1166 fd,(double)*poffset,(double)*pcount,*ptype));
1168 lock.l_type = *ptype;
1169 lock.l_whence = SEEK_SET;
1170 lock.l_start = *poffset;
1171 lock.l_len = *pcount;
1174 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1178 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1179 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1184 *ptype = lock.l_type;
1185 *poffset = lock.l_start;
1186 *pcount = lock.l_len;
1189 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1190 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1195 #define DBGC_CLASS DBGC_ALL
1197 /*******************************************************************
1198 Is the name specified one of my netbios names.
1199 Returns true if it is equal, false otherwise.
1200 ********************************************************************/
1202 bool is_myname(const char *s)
1207 for (n=0; my_netbios_names(n); n++) {
1208 if (strequal(my_netbios_names(n), s)) {
1213 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1217 /*******************************************************************
1218 we distinguish between 2K and XP by the "Native Lan Manager" string
1219 WinXP => "Windows 2002 5.1"
1220 WinXP 64bit => "Windows XP 5.2"
1221 Win2k => "Windows 2000 5.0"
1222 NT4 => "Windows NT 4.0"
1223 Win9x => "Windows 4.0"
1224 Windows 2003 doesn't set the native lan manager string but
1225 they do set the domain to "Windows 2003 5.2" (probably a bug).
1226 ********************************************************************/
1228 void ra_lanman_string( const char *native_lanman )
1230 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1231 set_remote_arch( RA_WINXP );
1232 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1233 set_remote_arch( RA_WINXP64 );
1234 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1235 set_remote_arch( RA_WIN2K3 );
1238 static const char *remote_arch_str;
1240 const char *get_remote_arch_str(void)
1242 if (!remote_arch_str) {
1245 return remote_arch_str;
1248 /*******************************************************************
1249 Set the horrid remote_arch string based on an enum.
1250 ********************************************************************/
1252 void set_remote_arch(enum remote_arch_types type)
1257 remote_arch_str = "WfWg";
1260 remote_arch_str = "OS2";
1263 remote_arch_str = "Win95";
1266 remote_arch_str = "WinNT";
1269 remote_arch_str = "Win2K";
1272 remote_arch_str = "WinXP";
1275 remote_arch_str = "WinXP64";
1278 remote_arch_str = "Win2K3";
1281 remote_arch_str = "Vista";
1284 remote_arch_str = "Samba";
1287 remote_arch_str = "CIFSFS";
1290 remote_arch_str = "OSX";
1293 ra_type = RA_UNKNOWN;
1294 remote_arch_str = "UNKNOWN";
1298 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1302 /*******************************************************************
1303 Get the remote_arch type.
1304 ********************************************************************/
1306 enum remote_arch_types get_remote_arch(void)
1311 const char *tab_depth(int level, int depth)
1313 if( CHECK_DEBUGLVL(level) ) {
1314 dbgtext("%*s", depth*4, "");
1319 /*****************************************************************************
1320 Provide a checksum on a string
1322 Input: s - the null-terminated character string for which the checksum
1325 Output: The checksum value calculated for s.
1326 *****************************************************************************/
1328 int str_checksum(const char *s)
1332 return hash(s, strlen(s), 0);
1335 /*****************************************************************
1336 Zero a memory area then free it. Used to catch bugs faster.
1337 *****************************************************************/
1339 void zero_free(void *p, size_t size)
1345 /*****************************************************************
1346 Set our open file limit to a requested max and return the limit.
1347 *****************************************************************/
1349 int set_maxfiles(int requested_max)
1351 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1353 int saved_current_limit;
1355 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1356 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1359 return requested_max;
1363 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1364 * account for the extra fd we need
1365 * as well as the log files and standard
1366 * handles etc. Save the limit we want to set in case
1367 * we are running on an OS that doesn't support this limit (AIX)
1368 * which always returns RLIM_INFINITY for rlp.rlim_max.
1371 /* Try raising the hard (max) limit to the requested amount. */
1373 #if defined(RLIM_INFINITY)
1374 if (rlp.rlim_max != RLIM_INFINITY) {
1375 int orig_max = rlp.rlim_max;
1377 if ( rlp.rlim_max < requested_max )
1378 rlp.rlim_max = requested_max;
1380 /* This failing is not an error - many systems (Linux) don't
1381 support our default request of 10,000 open files. JRA. */
1383 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1384 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1385 (int)rlp.rlim_max, strerror(errno) ));
1387 /* Set failed - restore original value from get. */
1388 rlp.rlim_max = orig_max;
1393 /* Now try setting the soft (current) limit. */
1395 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1397 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1398 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1399 (int)rlp.rlim_cur, strerror(errno) ));
1401 return saved_current_limit;
1404 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1405 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1408 return saved_current_limit;
1411 #if defined(RLIM_INFINITY)
1412 if(rlp.rlim_cur == RLIM_INFINITY)
1413 return saved_current_limit;
1416 if((int)rlp.rlim_cur > saved_current_limit)
1417 return saved_current_limit;
1419 return rlp.rlim_cur;
1420 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1422 * No way to know - just guess...
1424 return requested_max;
1428 /*****************************************************************
1429 malloc that aborts with smb_panic on fail or zero size.
1430 *****************************************************************/
1432 void *smb_xmalloc_array(size_t size, unsigned int count)
1436 smb_panic("smb_xmalloc_array: called with zero size");
1438 if (count >= MAX_ALLOC_SIZE/size) {
1439 smb_panic("smb_xmalloc_array: alloc size too large");
1441 if ((p = SMB_MALLOC(size*count)) == NULL) {
1442 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1443 (unsigned long)size, (unsigned long)count));
1444 smb_panic("smb_xmalloc_array: malloc failed");
1450 vasprintf that aborts on malloc fail
1453 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1460 n = vasprintf(ptr, format, ap2);
1462 if (n == -1 || ! *ptr) {
1463 smb_panic("smb_xvasprintf: out of memory");
1468 /*****************************************************************
1469 Get local hostname and cache result.
1470 *****************************************************************/
1472 char *myhostname(void)
1476 ret = get_myname(NULL);
1481 /*****************************************************************
1482 Get local hostname and cache result.
1483 *****************************************************************/
1485 char *myhostname_upper(void)
1490 name = get_myname(talloc_tos());
1491 ret = strupper_talloc(NULL, name);
1498 * @brief Returns an absolute path to a file concatenating the provided
1499 * @a rootpath and @a basename
1501 * @param name Filename, relative to @a rootpath
1503 * @retval Pointer to a string containing the full path.
1506 static char *xx_path(const char *name, const char *rootpath)
1510 fname = talloc_strdup(talloc_tos(), rootpath);
1514 trim_string(fname,"","/");
1516 if (!directory_exist(fname)) {
1517 if (!mkdir(fname,0755))
1518 DEBUG(1, ("Unable to create directory %s for file %s. "
1519 "Error was %s\n", fname, name, strerror(errno)));
1522 return talloc_asprintf(talloc_tos(),
1529 * @brief Returns an absolute path to a file in the Samba lock directory.
1531 * @param name File to find, relative to LOCKDIR.
1533 * @retval Pointer to a talloc'ed string containing the full path.
1536 char *lock_path(const char *name)
1538 return xx_path(name, lp_lockdir());
1542 * @brief Returns an absolute path to a file in the Samba state directory.
1544 * @param name File to find, relative to STATEDIR.
1546 * @retval Pointer to a talloc'ed string containing the full path.
1549 char *state_path(const char *name)
1551 return xx_path(name, lp_statedir());
1555 * @brief Returns an absolute path to a file in the Samba cache directory.
1557 * @param name File to find, relative to CACHEDIR.
1559 * @retval Pointer to a talloc'ed string containing the full path.
1562 char *cache_path(const char *name)
1564 return xx_path(name, lp_cachedir());
1567 /*******************************************************************
1568 Given a filename - get its directory name
1569 ********************************************************************/
1571 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1577 p = strrchr_m(dir, '/'); /* Find final '/', if any */
1580 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1591 if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
1594 (*parent)[len] = '\0';
1602 /*******************************************************************
1603 Determine if a pattern contains any Microsoft wildcard characters.
1604 *******************************************************************/
1606 bool ms_has_wild(const char *s)
1610 if (lp_posix_pathnames()) {
1611 /* With posix pathnames no characters are wild. */
1615 while ((c = *s++)) {
1628 bool ms_has_wild_w(const smb_ucs2_t *s)
1631 if (!s) return False;
1632 while ((c = *s++)) {
1634 case UCS2_CHAR('*'):
1635 case UCS2_CHAR('?'):
1636 case UCS2_CHAR('<'):
1637 case UCS2_CHAR('>'):
1638 case UCS2_CHAR('"'):
1645 /*******************************************************************
1646 A wrapper that handles case sensitivity and the special handling
1648 *******************************************************************/
1650 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1652 if (ISDOTDOT(string))
1657 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
1660 /*******************************************************************
1661 A wrapper that handles case sensitivity and the special handling
1662 of the ".." name. Varient that is only called by old search code which requires
1663 pattern translation.
1664 *******************************************************************/
1666 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
1668 if (ISDOTDOT(string))
1673 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
1676 /*******************************************************************
1677 A wrapper that handles a list of patters and calls mask_match()
1678 on each. Returns True if any of the patterns match.
1679 *******************************************************************/
1681 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
1683 while (listLen-- > 0) {
1684 if (mask_match(string, *list++, is_case_sensitive))
1690 /*********************************************************
1691 Recursive routine that is called by unix_wild_match.
1692 *********************************************************/
1694 static bool unix_do_match(const char *regexp, const char *str)
1698 for( p = regexp; *p && *str; ) {
1709 * Look for a character matching
1710 * the one after the '*'.
1714 return true; /* Automatic match */
1717 while(*str && (*p != *str))
1721 * Patch from weidel@multichart.de. In the case of the regexp
1722 * '*XX*' we want to ensure there are at least 2 'X' characters
1723 * in the string after the '*' for a match to be made.
1730 * Eat all the characters that match, but count how many there were.
1733 while(*str && (*p == *str)) {
1739 * Now check that if the regexp had n identical characters that
1740 * matchcount had at least that many matches.
1743 while ( *(p+1) && (*(p+1) == *p)) {
1748 if ( matchcount <= 0 )
1752 str--; /* We've eaten the match char after the '*' */
1754 if(unix_do_match(p, str))
1776 if (!*p && str[0] == '.' && str[1] == 0)
1779 if (!*str && *p == '?') {
1785 if(!*str && (*p == '*' && p[1] == '\0'))
1791 /*******************************************************************
1792 Simple case insensitive interface to a UNIX wildcard matcher.
1793 Returns True if match, False if not.
1794 *******************************************************************/
1796 bool unix_wild_match(const char *pattern, const char *string)
1798 TALLOC_CTX *ctx = talloc_stackframe();
1804 p2 = talloc_strdup(ctx,pattern);
1805 s2 = talloc_strdup(ctx,string);
1813 /* Remove any *? and ** from the pattern as they are meaningless */
1814 for(p = p2; *p; p++) {
1815 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1816 memmove(&p[1], &p[2], strlen(&p[2])+1);
1820 if (strequal(p2,"*")) {
1825 ret = unix_do_match(p2, s2);
1830 /**********************************************************************
1831 Converts a name to a fully qualified domain name.
1832 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1833 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1834 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1835 ***********************************************************************/
1837 bool name_to_fqdn(fstring fqdn, const char *name)
1840 struct hostent *hp = gethostbyname(name);
1842 if (!hp || !hp->h_name || !*hp->h_name) {
1843 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1844 fstrcpy(fqdn, name);
1848 /* Find out if the fqdn is returned as an alias
1849 * to cope with /etc/hosts files where the first
1850 * name is not the fqdn but the short name */
1851 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1853 for (i = 0; hp->h_aliases[i]; i++) {
1854 if (strchr_m(hp->h_aliases[i], '.')) {
1855 full = hp->h_aliases[i];
1860 if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1861 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1862 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1863 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1864 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1871 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1872 fstrcpy(fqdn, full);
1876 /**********************************************************************
1877 Append a DATA_BLOB to a talloc'ed object
1878 ***********************************************************************/
1880 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1882 size_t old_size = 0;
1885 if (blob.length == 0) {
1890 old_size = talloc_get_size(buf);
1893 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1894 if (result == NULL) {
1898 memcpy(result + old_size, blob.data, blob.length);
1902 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1904 switch (share_access & ~FILE_SHARE_DELETE) {
1905 case FILE_SHARE_NONE:
1907 case FILE_SHARE_READ:
1909 case FILE_SHARE_WRITE:
1911 case FILE_SHARE_READ|FILE_SHARE_WRITE:
1914 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
1916 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
1923 pid_t procid_to_pid(const struct server_id *proc)
1928 static uint32 my_vnn = NONCLUSTER_VNN;
1930 void set_my_vnn(uint32 vnn)
1932 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
1936 uint32 get_my_vnn(void)
1941 static uint64_t my_unique_id = 0;
1943 void set_my_unique_id(uint64_t unique_id)
1945 my_unique_id = unique_id;
1948 struct server_id pid_to_procid(pid_t pid)
1950 struct server_id result;
1953 result.unique_id = my_unique_id;
1954 result.vnn = my_vnn;
1958 struct server_id procid_self(void)
1960 return pid_to_procid(sys_getpid());
1963 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
1965 if (p1->pid != p2->pid)
1967 if (p1->task_id != p2->task_id)
1969 if (p1->vnn != p2->vnn)
1974 bool cluster_id_equal(const struct server_id *id1,
1975 const struct server_id *id2)
1977 return procid_equal(id1, id2);
1980 bool procid_is_me(const struct server_id *pid)
1982 if (pid->pid != sys_getpid())
1984 if (pid->task_id != 0)
1986 if (pid->vnn != my_vnn)
1991 struct server_id interpret_pid(const char *pid_string)
1993 struct server_id result;
1994 unsigned long long pid;
1995 unsigned int vnn, task_id = 0;
1997 ZERO_STRUCT(result);
1999 /* We accept various forms with 1, 2 or 3 component forms
2000 * because the server_id_str() can print different forms, and
2001 * we want backwards compatibility for scripts that may call
2003 if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
2006 result.task_id = task_id;
2007 } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
2011 } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
2012 result.vnn = get_my_vnn();
2014 result.task_id = task_id;
2015 } else if (sscanf(pid_string, "%llu", &pid) == 1) {
2016 result.vnn = get_my_vnn();
2019 result.vnn = NONCLUSTER_VNN;
2020 result.pid = (uint64_t)-1;
2025 char *procid_str_static(const struct server_id *pid)
2027 return server_id_str(talloc_tos(), pid);
2030 bool procid_valid(const struct server_id *pid)
2032 return (pid->pid != (uint64_t)-1);
2035 bool procid_is_local(const struct server_id *pid)
2037 return pid->vnn == my_vnn;
2040 /****************************************************************
2041 Check if an offset into a buffer is safe.
2042 If this returns True it's safe to indirect into the byte at
2044 ****************************************************************/
2046 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2048 const char *end_base = buf_base + buf_len;
2049 char *end_ptr = ptr + off;
2051 if (!buf_base || !ptr) {
2055 if (end_base < buf_base || end_ptr < ptr) {
2056 return False; /* wrap. */
2059 if (end_ptr < end_base) {
2065 /****************************************************************
2066 Return a safe pointer into a buffer, or NULL.
2067 ****************************************************************/
2069 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2071 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2075 /****************************************************************
2076 Return a safe pointer into a string within a buffer, or NULL.
2077 ****************************************************************/
2079 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2081 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2084 /* Check if a valid string exists at this offset. */
2085 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2091 /****************************************************************
2092 Return an SVAL at a pointer, or failval if beyond the end.
2093 ****************************************************************/
2095 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2098 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2101 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2104 return SVAL(ptr,off);
2107 /****************************************************************
2108 Return an IVAL at a pointer, or failval if beyond the end.
2109 ****************************************************************/
2111 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2114 * Note we use off+3 here, not off+4 as IVAL accesses
2115 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2117 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2120 return IVAL(ptr,off);
2123 /****************************************************************
2124 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2125 call (they take care of winbind separator and other winbind specific settings).
2126 ****************************************************************/
2128 void split_domain_user(TALLOC_CTX *mem_ctx,
2129 const char *full_name,
2133 const char *p = NULL;
2135 p = strchr_m(full_name, '\\');
2138 *domain = talloc_strndup(mem_ctx, full_name,
2139 PTR_DIFF(p, full_name));
2140 *user = talloc_strdup(mem_ctx, p+1);
2142 *domain = talloc_strdup(mem_ctx, "");
2143 *user = talloc_strdup(mem_ctx, full_name);
2147 /****************************************************************
2148 strip off leading '\\' from a hostname
2149 ****************************************************************/
2151 const char *strip_hostname(const char *s)
2157 if (strlen_m(s) < 3) {
2161 if (s[0] == '\\') s++;
2162 if (s[0] == '\\') s++;
2167 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2168 struct tevent_context *ev,
2171 bool ret = tevent_req_poll(req, ev);
2173 *status = map_nt_error_from_unix(errno);
2178 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2180 if (!NT_STATUS_IS_OK(err1)) {
2184 if (!NT_STATUS_IS_OK(err2)) {
2191 int timeval_to_msec(struct timeval t)
2193 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2196 /*******************************************************************
2197 Check a given DOS pathname is valid for a share.
2198 ********************************************************************/
2200 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2204 if (!dos_pathname) {
2208 ptr = talloc_strdup(ctx, dos_pathname);
2212 /* Convert any '\' paths to '/' */
2214 ptr = unix_clean_name(ctx, ptr);
2219 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2220 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2223 /* Only absolute paths allowed. */
2230 /*******************************************************************
2231 Return True if the filename is one of the special executable types.
2232 ********************************************************************/
2234 bool is_executable(const char *fname)
2236 if ((fname = strrchr_m(fname,'.'))) {
2237 if (strequal(fname,".com") ||
2238 strequal(fname,".dll") ||
2239 strequal(fname,".exe") ||
2240 strequal(fname,".sym")) {
2247 /****************************************************************************
2248 Open a file with a share mode - old openX method - map into NTCreate.
2249 ****************************************************************************/
2251 bool map_open_params_to_ntcreate(const char *smb_base_fname,
2252 int deny_mode, int open_func,
2253 uint32 *paccess_mask,
2254 uint32 *pshare_mode,
2255 uint32 *pcreate_disposition,
2256 uint32 *pcreate_options,
2257 uint32_t *pprivate_flags)
2261 uint32 create_disposition;
2262 uint32 create_options = FILE_NON_DIRECTORY_FILE;
2263 uint32_t private_flags = 0;
2265 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2266 "open_func = 0x%x\n",
2267 smb_base_fname, (unsigned int)deny_mode,
2268 (unsigned int)open_func ));
2270 /* Create the NT compatible access_mask. */
2271 switch (GET_OPENX_MODE(deny_mode)) {
2272 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
2273 case DOS_OPEN_RDONLY:
2274 access_mask = FILE_GENERIC_READ;
2276 case DOS_OPEN_WRONLY:
2277 access_mask = FILE_GENERIC_WRITE;
2281 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
2284 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2285 (unsigned int)GET_OPENX_MODE(deny_mode)));
2289 /* Create the NT compatible create_disposition. */
2290 switch (open_func) {
2291 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
2292 create_disposition = FILE_CREATE;
2295 case OPENX_FILE_EXISTS_OPEN:
2296 create_disposition = FILE_OPEN;
2299 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
2300 create_disposition = FILE_OPEN_IF;
2303 case OPENX_FILE_EXISTS_TRUNCATE:
2304 create_disposition = FILE_OVERWRITE;
2307 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
2308 create_disposition = FILE_OVERWRITE_IF;
2312 /* From samba4 - to be confirmed. */
2313 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
2314 create_disposition = FILE_CREATE;
2317 DEBUG(10,("map_open_params_to_ntcreate: bad "
2318 "open_func 0x%x\n", (unsigned int)open_func));
2322 /* Create the NT compatible share modes. */
2323 switch (GET_DENY_MODE(deny_mode)) {
2325 share_mode = FILE_SHARE_NONE;
2329 share_mode = FILE_SHARE_READ;
2333 share_mode = FILE_SHARE_WRITE;
2337 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2341 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
2342 if (is_executable(smb_base_fname)) {
2343 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2345 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
2346 share_mode = FILE_SHARE_READ;
2348 share_mode = FILE_SHARE_NONE;
2354 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
2355 share_mode = FILE_SHARE_NONE;
2359 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2360 (unsigned int)GET_DENY_MODE(deny_mode) ));
2364 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2365 "share_mode = 0x%x, create_disposition = 0x%x, "
2366 "create_options = 0x%x private_flags = 0x%x\n",
2368 (unsigned int)access_mask,
2369 (unsigned int)share_mode,
2370 (unsigned int)create_disposition,
2371 (unsigned int)create_options,
2372 (unsigned int)private_flags));
2375 *paccess_mask = access_mask;
2378 *pshare_mode = share_mode;
2380 if (pcreate_disposition) {
2381 *pcreate_disposition = create_disposition;
2383 if (pcreate_options) {
2384 *pcreate_options = create_options;
2386 if (pprivate_flags) {
2387 *pprivate_flags = private_flags;
2395 void init_modules(void)
2397 /* FIXME: This can cause undefined symbol errors :
2398 * smb_register_vfs() isn't available in nmbd, for example */
2399 if(lp_preload_modules())
2400 smb_load_modules(lp_preload_modules());