2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2007
6 Copyright (C) Simo Sorce 2001
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) James Peach 2006
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "system/passwd.h"
26 #include "system/filesys.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/util_pw.h"
31 #include <ccan/hash/hash.h>
32 #include "libcli/security/security.h"
34 #ifdef HAVE_SYS_PRCTL_H
35 #include <sys/prctl.h>
38 /* Max allowable allococation - 256mb - 0x10000000 */
39 #define MAX_ALLOC_SIZE (1024*1024*256)
41 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
42 #ifdef WITH_NISPLUS_HOME
43 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
45 * The following lines are needed due to buggy include files
46 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
47 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
48 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
49 * an enum in /usr/include/rpcsvc/nis.h.
56 #if defined(GROUP_OBJ)
60 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
62 #include <rpcsvc/nis.h>
64 #endif /* WITH_NISPLUS_HOME */
65 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
67 static enum protocol_types Protocol = PROTOCOL_COREPLUS;
69 enum protocol_types get_Protocol(void)
74 void set_Protocol(enum protocol_types p)
79 static enum remote_arch_types ra_type = RA_UNKNOWN;
81 void gfree_all( void )
90 /*******************************************************************
91 Check if a file exists - call vfs_file_exist for samba files.
92 ********************************************************************/
94 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf,
95 bool fake_dir_create_times)
101 if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
104 return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
107 /*******************************************************************
108 Check if a unix domain socket exists - call vfs_file_exist for samba files.
109 ********************************************************************/
111 bool socket_exist(const char *fname)
114 if (sys_stat(fname, &st, false) != 0)
117 return S_ISSOCK(st.st_ex_mode);
120 /*******************************************************************
121 Returns the size in bytes of the named given the stat struct.
122 ********************************************************************/
124 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
126 return sbuf->st_ex_size;
129 /*******************************************************************
130 Returns the size in bytes of the named file.
131 ********************************************************************/
133 SMB_OFF_T get_file_size(char *file_name)
137 if (sys_stat(file_name, &buf, false) != 0)
138 return (SMB_OFF_T)-1;
139 return get_file_size_stat(&buf);
142 /*******************************************************************
143 Show a smb message structure.
144 ********************************************************************/
146 void show_msg(const char *buf)
154 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
156 (int)CVAL(buf,smb_com),
157 (int)CVAL(buf,smb_rcls),
158 (int)CVAL(buf,smb_reh),
159 (int)SVAL(buf,smb_err),
160 (int)CVAL(buf,smb_flg),
161 (int)SVAL(buf,smb_flg2)));
162 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
163 (int)SVAL(buf,smb_tid),
164 (int)SVAL(buf,smb_pid),
165 (int)SVAL(buf,smb_uid),
166 (int)SVAL(buf,smb_mid)));
167 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
169 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
170 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
171 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
173 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
175 DEBUGADD(5,("smb_bcc=%d\n",bcc));
183 dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
186 /*******************************************************************
187 Set the length and marker of an smb packet.
188 ********************************************************************/
190 void smb_setlen(char *buf,int len)
192 _smb_setlen(buf,len);
200 /*******************************************************************
201 Setup only the byte count for a smb message.
202 ********************************************************************/
204 int set_message_bcc(char *buf,int num_bytes)
206 int num_words = CVAL(buf,smb_wct);
207 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
208 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
209 return (smb_size + num_words*2 + num_bytes);
212 /*******************************************************************
213 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
214 Return the bytes added
215 ********************************************************************/
217 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
219 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
222 if (!(tmp = talloc_realloc(NULL, *outbuf, uint8, newlen))) {
223 DEBUG(0, ("talloc failed\n"));
228 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
229 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
233 /*******************************************************************
234 Reduce a file name, removing .. elements.
235 ********************************************************************/
237 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
242 DEBUG(3,("dos_clean_name [%s]\n",s));
244 /* remove any double slashes */
245 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
250 /* Remove leading .\\ characters */
251 if(strncmp(str, ".\\", 2) == 0) {
252 trim_string(str, ".\\", NULL);
254 str = talloc_strdup(ctx, ".\\");
261 while ((p = strstr_m(str,"\\..\\")) != NULL) {
267 if ((p=strrchr_m(str,'\\')) != NULL) {
272 str = talloc_asprintf(ctx,
281 trim_string(str,NULL,"\\..");
282 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
285 /*******************************************************************
286 Reduce a file name, removing .. elements.
287 ********************************************************************/
289 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
294 DEBUG(3,("unix_clean_name [%s]\n",s));
296 /* remove any double slashes */
297 str = talloc_all_string_sub(ctx, s, "//","/");
302 /* Remove leading ./ characters */
303 if(strncmp(str, "./", 2) == 0) {
304 trim_string(str, "./", NULL);
306 str = talloc_strdup(ctx, "./");
313 while ((p = strstr_m(str,"/../")) != NULL) {
319 if ((p=strrchr_m(str,'/')) != NULL) {
324 str = talloc_asprintf(ctx,
333 trim_string(str,NULL,"/..");
334 return talloc_all_string_sub(ctx, str, "/./", "/");
337 char *clean_name(TALLOC_CTX *ctx, const char *s)
339 char *str = dos_clean_name(ctx, s);
343 return unix_clean_name(ctx, str);
346 /*******************************************************************
347 Write data into an fd at a given offset. Ignore seek errors.
348 ********************************************************************/
350 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
355 if (pos == (SMB_OFF_T)-1) {
356 return write_data(fd, buffer, N);
358 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
360 ret = sys_pwrite(fd,buffer + total,N - total, pos);
361 if (ret == -1 && errno == ESPIPE) {
362 return write_data(fd, buffer + total,N - total);
365 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
374 return (ssize_t)total;
376 /* Use lseek and write_data. */
377 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
378 if (errno != ESPIPE) {
382 return write_data(fd, buffer, N);
387 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
388 struct event_context *ev_ctx,
390 bool parent_longlived)
392 NTSTATUS status = NT_STATUS_OK;
394 /* Reset the state of the random
395 * number generation system, so
396 * children do not get the same random
397 * numbers as each other */
398 set_need_random_reseed();
400 /* tdb needs special fork handling */
401 if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
402 DEBUG(0,("tdb_reopen_all failed.\n"));
403 status = NT_STATUS_OPEN_FAILED;
407 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
408 smb_panic(__location__ ": Failed to re-initialise event context");
413 * For clustering, we need to re-init our ctdbd connection after the
416 status = messaging_reinit(msg_ctx, id);
417 if (!NT_STATUS_IS_OK(status)) {
418 DEBUG(0,("messaging_reinit() failed: %s\n",
426 /****************************************************************************
427 (Hopefully) efficient array append.
428 ****************************************************************************/
430 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
431 void *element, void *_array, uint32 *num_elements,
434 void **array = (void **)_array;
436 if (*array_size < 0) {
440 if (*array == NULL) {
441 if (*array_size == 0) {
445 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
449 *array = TALLOC(mem_ctx, element_size * (*array_size));
450 if (*array == NULL) {
455 if (*num_elements == *array_size) {
458 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
462 *array = TALLOC_REALLOC(mem_ctx, *array,
463 element_size * (*array_size));
465 if (*array == NULL) {
470 memcpy((char *)(*array) + element_size*(*num_elements),
471 element, element_size);
481 /****************************************************************************
482 Get my own domain name, or "" if we have none.
483 ****************************************************************************/
485 char *get_mydnsdomname(TALLOC_CTX *ctx)
490 domname = get_mydnsfullname();
495 p = strchr_m(domname, '.');
498 return talloc_strdup(ctx, p);
500 return talloc_strdup(ctx, "");
504 /****************************************************************************
505 Interpret a protocol description string, with a default.
506 ****************************************************************************/
508 int interpret_protocol(const char *str,int def)
510 if (strequal(str,"NT1"))
511 return(PROTOCOL_NT1);
512 if (strequal(str,"LANMAN2"))
513 return(PROTOCOL_LANMAN2);
514 if (strequal(str,"LANMAN1"))
515 return(PROTOCOL_LANMAN1);
516 if (strequal(str,"CORE"))
517 return(PROTOCOL_CORE);
518 if (strequal(str,"COREPLUS"))
519 return(PROTOCOL_COREPLUS);
520 if (strequal(str,"CORE+"))
521 return(PROTOCOL_COREPLUS);
523 DEBUG(0,("Unrecognised protocol level %s\n",str));
529 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
530 /******************************************************************
531 Remove any mount options such as -rsize=2048,wsize=2048 etc.
532 Based on a fix from <Thomas.Hepper@icem.de>.
533 Returns a malloc'ed string.
534 *******************************************************************/
536 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
540 while(*p && !isspace(*p))
542 while(*p && isspace(*p))
545 return talloc_strdup(ctx, p);
551 /*******************************************************************
552 Patch from jkf@soton.ac.uk
553 Split Luke's automount_server into YP lookup and string splitter
554 so can easily implement automount_path().
555 Returns a malloc'ed string.
556 *******************************************************************/
558 #ifdef WITH_NISPLUS_HOME
559 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
563 char *nis_map = (char *)lp_nis_home_map_name();
565 char buffer[NIS_MAXATTRVAL + 1];
570 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
571 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
573 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
574 if (result->status != NIS_SUCCESS) {
575 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
577 object = result->objects.objects_val;
578 if (object->zo_data.zo_type == ENTRY_OBJ) {
579 entry = &object->zo_data.objdata_u.en_data;
580 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
581 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
583 value = talloc_strdup(ctx,
584 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
586 nis_freeresult(result);
589 value = talloc_string_sub(ctx,
596 nis_freeresult(result);
599 value = strip_mount_options(ctx, value);
600 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
605 #else /* WITH_NISPLUS_HOME */
607 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
611 int nis_error; /* returned by yp all functions */
612 char *nis_result; /* yp_match inits this */
613 int nis_result_len; /* and set this */
614 char *nis_domain; /* yp_get_default_domain inits this */
615 char *nis_map = (char *)lp_nis_home_map_name();
617 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
618 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
622 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
624 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
625 strlen(user_name), &nis_result,
626 &nis_result_len)) == 0) {
627 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
628 nis_result[nis_result_len] = '\0';
630 value = talloc_strdup(ctx, nis_result);
634 value = strip_mount_options(ctx, value);
635 } else if(nis_error == YPERR_KEY) {
636 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
637 user_name, nis_map));
638 DEBUG(3, ("using defaults for server and home directory\n"));
640 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
641 yperr_string(nis_error), user_name, nis_map));
645 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
649 #endif /* WITH_NISPLUS_HOME */
652 /****************************************************************************
653 Check if a process exists. Does this work on all unixes?
654 ****************************************************************************/
656 bool process_exists(const struct server_id pid)
658 if (procid_is_me(&pid)) {
662 if (procid_is_local(&pid)) {
663 return (kill(pid.pid,0) == 0 || errno != ESRCH);
666 #ifdef CLUSTER_SUPPORT
667 return ctdbd_process_exists(messaging_ctdbd_connection(),
674 /*******************************************************************
675 Convert a uid into a user name.
676 ********************************************************************/
678 const char *uidtoname(uid_t uid)
680 TALLOC_CTX *ctx = talloc_tos();
682 struct passwd *pass = NULL;
684 pass = getpwuid_alloc(ctx,uid);
686 name = talloc_strdup(ctx,pass->pw_name);
689 name = talloc_asprintf(ctx,
696 /*******************************************************************
697 Convert a gid into a group name.
698 ********************************************************************/
700 char *gidtoname(gid_t gid)
706 return talloc_strdup(talloc_tos(), grp->gr_name);
709 return talloc_asprintf(talloc_tos(),
715 /*******************************************************************
716 Convert a user name into a uid.
717 ********************************************************************/
719 uid_t nametouid(const char *name)
725 pass = Get_Pwnam_alloc(talloc_tos(), name);
732 u = (uid_t)strtol(name, &p, 0);
733 if ((p != name) && (*p == '\0'))
739 /*******************************************************************
740 Convert a name to a gid_t if possible. Return -1 if not a group.
741 ********************************************************************/
743 gid_t nametogid(const char *name)
749 g = (gid_t)strtol(name, &p, 0);
750 if ((p != name) && (*p == '\0'))
753 grp = sys_getgrnam(name);
759 /*******************************************************************
760 Something really nasty happened - panic !
761 ********************************************************************/
763 void smb_panic_s3(const char *why)
768 DEBUG(0,("PANIC (pid %llu): %s\n",
769 (unsigned long long)sys_getpid(), why));
772 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
774 * Make sure all children can attach a debugger.
776 prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
779 cmd = lp_panic_action();
781 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
782 result = system(cmd);
785 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
788 DEBUG(0, ("smb_panic(): action returned status %d\n",
789 WEXITSTATUS(result)));
795 /*******************************************************************
796 Print a backtrace of the stack to the debug log. This function
797 DELIBERATELY LEAKS MEMORY. The expectation is that you should
798 exit shortly after calling it.
799 ********************************************************************/
801 #ifdef HAVE_LIBUNWIND_H
802 #include <libunwind.h>
805 #ifdef HAVE_EXECINFO_H
806 #include <execinfo.h>
813 void log_stack_trace(void)
815 #ifdef HAVE_LIBUNWIND
816 /* Try to use libunwind before any other technique since on ia64
817 * libunwind correctly walks the stack in more circumstances than
825 unw_word_t ip, sp, off;
827 procname[sizeof(procname) - 1] = '\0';
829 if (unw_getcontext(&uc) != 0) {
830 goto libunwind_failed;
833 if (unw_init_local(&cursor, &uc) != 0) {
834 goto libunwind_failed;
837 DEBUG(0, ("BACKTRACE:\n"));
841 unw_get_reg(&cursor, UNW_REG_IP, &ip);
842 unw_get_reg(&cursor, UNW_REG_SP, &sp);
844 switch (unw_get_proc_name(&cursor,
845 procname, sizeof(procname) - 1, &off) ) {
849 /* Name truncated. */
850 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
851 i, procname, (long long)off,
852 (long long)ip, (long long) sp));
855 /* case -UNW_ENOINFO: */
856 /* case -UNW_EUNSPEC: */
857 /* No symbol name found. */
858 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
859 i, "<unknown symbol>",
860 (long long)ip, (long long) sp));
863 } while (unw_step(&cursor) > 0);
868 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
870 #elif HAVE_BACKTRACE_SYMBOLS
871 void *backtrace_stack[BACKTRACE_STACK_SIZE];
872 size_t backtrace_size;
873 char **backtrace_strings;
875 /* get the backtrace (stack frames) */
876 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
877 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
879 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
880 (unsigned long)backtrace_size));
882 if (backtrace_strings) {
885 for (i = 0; i < backtrace_size; i++)
886 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
888 /* Leak the backtrace_strings, rather than risk what free() might do */
893 /* The IRIX libexc library provides an API for unwinding the stack. See
894 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
895 * since we are about to abort anyway, it hardly matters.
898 #define NAMESIZE 32 /* Arbitrary */
900 __uint64_t addrs[BACKTRACE_STACK_SIZE];
901 char * names[BACKTRACE_STACK_SIZE];
902 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
911 /* We need to be root so we can open our /proc entry to walk
912 * our stack. It also helps when we want to dump core.
916 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
917 names[i] = namebuf + (i * NAMESIZE);
920 levels = trace_back_stack(0, addrs, names,
921 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
923 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
924 for (i = 0; i < levels; i++) {
925 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
930 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
934 /*******************************************************************
935 A readdir wrapper which just returns the file name.
936 ********************************************************************/
938 const char *readdirname(SMB_STRUCT_DIR *p)
940 SMB_STRUCT_DIRENT *ptr;
946 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
957 #ifdef HAVE_BROKEN_READDIR_NAME
958 /* using /usr/ucb/cc is BAD */
962 return talloc_strdup(talloc_tos(), dname);
965 /*******************************************************************
966 Utility function used to decide if the last component
967 of a path matches a (possibly wildcarded) entry in a namelist.
968 ********************************************************************/
970 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
972 const char *last_component;
974 /* if we have no list it's obviously not in the path */
975 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
979 DEBUG(8, ("is_in_path: %s\n", name));
981 /* Get the last component of the unix name. */
982 last_component = strrchr_m(name, '/');
983 if (!last_component) {
984 last_component = name;
986 last_component++; /* Go past '/' */
989 for(; namelist->name != NULL; namelist++) {
990 if(namelist->is_wild) {
991 if (mask_match(last_component, namelist->name, case_sensitive)) {
992 DEBUG(8,("is_in_path: mask match succeeded\n"));
996 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
997 (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
998 DEBUG(8,("is_in_path: match succeeded\n"));
1003 DEBUG(8,("is_in_path: match not found\n"));
1007 /*******************************************************************
1008 Strip a '/' separated list into an array of
1009 name_compare_enties structures suitable for
1010 passing to is_in_path(). We do this for
1011 speed so we can pre-parse all the names in the list
1012 and don't do it for each call to is_in_path().
1013 We also check if the entry contains a wildcard to
1014 remove a potentially expensive call to mask_match
1016 ********************************************************************/
1018 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1023 int num_entries = 0;
1026 (*ppname_array) = NULL;
1028 if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0')))
1031 namelist = talloc_strdup(talloc_tos(), namelist_in);
1032 if (namelist == NULL) {
1033 DEBUG(0,("set_namearray: talloc fail\n"));
1038 /* We need to make two passes over the string. The
1039 first to count the number of elements, the second
1044 if ( *nameptr == '/' ) {
1045 /* cope with multiple (useless) /s) */
1049 /* anything left? */
1050 if ( *nameptr == '\0' )
1053 /* find the next '/' or consume remaining */
1054 name_end = strchr_m(nameptr, '/');
1055 if (name_end == NULL)
1056 name_end = (char *)nameptr + strlen(nameptr);
1058 /* next segment please */
1059 nameptr = name_end + 1;
1063 if(num_entries == 0) {
1064 talloc_free(namelist);
1068 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1069 DEBUG(0,("set_namearray: malloc fail\n"));
1070 talloc_free(namelist);
1074 /* Now copy out the names */
1078 if ( *nameptr == '/' ) {
1079 /* cope with multiple (useless) /s) */
1083 /* anything left? */
1084 if ( *nameptr == '\0' )
1087 /* find the next '/' or consume remaining */
1088 name_end = strchr_m(nameptr, '/');
1092 name_end = nameptr + strlen(nameptr);
1094 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1095 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1096 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1097 talloc_free(namelist);
1101 /* next segment please */
1102 nameptr = name_end + 1;
1106 (*ppname_array)[i].name = NULL;
1108 talloc_free(namelist);
1113 #define DBGC_CLASS DBGC_LOCKING
1115 /****************************************************************************
1116 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1117 is dealt with in posix.c
1118 Returns True if we have information regarding this lock region (and returns
1119 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1120 ****************************************************************************/
1122 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1124 SMB_STRUCT_FLOCK lock;
1127 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1128 fd,(double)*poffset,(double)*pcount,*ptype));
1130 lock.l_type = *ptype;
1131 lock.l_whence = SEEK_SET;
1132 lock.l_start = *poffset;
1133 lock.l_len = *pcount;
1136 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1140 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1141 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1146 *ptype = lock.l_type;
1147 *poffset = lock.l_start;
1148 *pcount = lock.l_len;
1151 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1152 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1157 #define DBGC_CLASS DBGC_ALL
1159 /*******************************************************************
1160 Is the name specified one of my netbios names.
1161 Returns true if it is equal, false otherwise.
1162 ********************************************************************/
1164 bool is_myname(const char *s)
1169 for (n=0; my_netbios_names(n); n++) {
1170 if (strequal(my_netbios_names(n), s)) {
1175 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1179 /*******************************************************************
1180 Is the name specified our workgroup/domain.
1181 Returns true if it is equal, false otherwise.
1182 ********************************************************************/
1184 bool is_myworkgroup(const char *s)
1188 if (strequal(s, lp_workgroup())) {
1192 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1196 /*******************************************************************
1197 we distinguish between 2K and XP by the "Native Lan Manager" string
1198 WinXP => "Windows 2002 5.1"
1199 WinXP 64bit => "Windows XP 5.2"
1200 Win2k => "Windows 2000 5.0"
1201 NT4 => "Windows NT 4.0"
1202 Win9x => "Windows 4.0"
1203 Windows 2003 doesn't set the native lan manager string but
1204 they do set the domain to "Windows 2003 5.2" (probably a bug).
1205 ********************************************************************/
1207 void ra_lanman_string( const char *native_lanman )
1209 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1210 set_remote_arch( RA_WINXP );
1211 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1212 set_remote_arch( RA_WINXP64 );
1213 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1214 set_remote_arch( RA_WIN2K3 );
1217 static const char *remote_arch_str;
1219 const char *get_remote_arch_str(void)
1221 if (!remote_arch_str) {
1224 return remote_arch_str;
1227 /*******************************************************************
1228 Set the horrid remote_arch string based on an enum.
1229 ********************************************************************/
1231 void set_remote_arch(enum remote_arch_types type)
1236 remote_arch_str = "WfWg";
1239 remote_arch_str = "OS2";
1242 remote_arch_str = "Win95";
1245 remote_arch_str = "WinNT";
1248 remote_arch_str = "Win2K";
1251 remote_arch_str = "WinXP";
1254 remote_arch_str = "WinXP64";
1257 remote_arch_str = "Win2K3";
1260 remote_arch_str = "Vista";
1263 remote_arch_str = "Samba";
1266 remote_arch_str = "CIFSFS";
1269 remote_arch_str = "OSX";
1272 ra_type = RA_UNKNOWN;
1273 remote_arch_str = "UNKNOWN";
1277 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1281 /*******************************************************************
1282 Get the remote_arch type.
1283 ********************************************************************/
1285 enum remote_arch_types get_remote_arch(void)
1290 const char *tab_depth(int level, int depth)
1292 if( CHECK_DEBUGLVL(level) ) {
1293 dbgtext("%*s", depth*4, "");
1298 /*****************************************************************************
1299 Provide a checksum on a string
1301 Input: s - the null-terminated character string for which the checksum
1304 Output: The checksum value calculated for s.
1305 *****************************************************************************/
1307 int str_checksum(const char *s)
1311 return hash(s, strlen(s), 0);
1314 /*****************************************************************
1315 Zero a memory area then free it. Used to catch bugs faster.
1316 *****************************************************************/
1318 void zero_free(void *p, size_t size)
1324 /*****************************************************************
1325 Set our open file limit to a requested max and return the limit.
1326 *****************************************************************/
1328 int set_maxfiles(int requested_max)
1330 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1332 int saved_current_limit;
1334 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1335 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1338 return requested_max;
1342 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1343 * account for the extra fd we need
1344 * as well as the log files and standard
1345 * handles etc. Save the limit we want to set in case
1346 * we are running on an OS that doesn't support this limit (AIX)
1347 * which always returns RLIM_INFINITY for rlp.rlim_max.
1350 /* Try raising the hard (max) limit to the requested amount. */
1352 #if defined(RLIM_INFINITY)
1353 if (rlp.rlim_max != RLIM_INFINITY) {
1354 int orig_max = rlp.rlim_max;
1356 if ( rlp.rlim_max < requested_max )
1357 rlp.rlim_max = requested_max;
1359 /* This failing is not an error - many systems (Linux) don't
1360 support our default request of 10,000 open files. JRA. */
1362 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1363 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1364 (int)rlp.rlim_max, strerror(errno) ));
1366 /* Set failed - restore original value from get. */
1367 rlp.rlim_max = orig_max;
1372 /* Now try setting the soft (current) limit. */
1374 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1376 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1377 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1378 (int)rlp.rlim_cur, strerror(errno) ));
1380 return saved_current_limit;
1383 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1384 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1387 return saved_current_limit;
1390 #if defined(RLIM_INFINITY)
1391 if(rlp.rlim_cur == RLIM_INFINITY)
1392 return saved_current_limit;
1395 if((int)rlp.rlim_cur > saved_current_limit)
1396 return saved_current_limit;
1398 return rlp.rlim_cur;
1399 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1401 * No way to know - just guess...
1403 return requested_max;
1407 /*****************************************************************
1408 malloc that aborts with smb_panic on fail or zero size.
1409 *****************************************************************/
1411 void *smb_xmalloc_array(size_t size, unsigned int count)
1415 smb_panic("smb_xmalloc_array: called with zero size");
1417 if (count >= MAX_ALLOC_SIZE/size) {
1418 smb_panic("smb_xmalloc_array: alloc size too large");
1420 if ((p = SMB_MALLOC(size*count)) == NULL) {
1421 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1422 (unsigned long)size, (unsigned long)count));
1423 smb_panic("smb_xmalloc_array: malloc failed");
1429 vasprintf that aborts on malloc fail
1432 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1439 n = vasprintf(ptr, format, ap2);
1441 if (n == -1 || ! *ptr) {
1442 smb_panic("smb_xvasprintf: out of memory");
1447 /*****************************************************************
1448 Get local hostname and cache result.
1449 *****************************************************************/
1451 char *myhostname(void)
1455 ret = get_myname(NULL);
1460 /*****************************************************************
1461 Get local hostname and cache result.
1462 *****************************************************************/
1464 char *myhostname_upper(void)
1469 name = get_myname(talloc_tos());
1470 ret = strupper_talloc(NULL, name);
1477 * @brief Returns an absolute path to a file concatenating the provided
1478 * @a rootpath and @a basename
1480 * @param name Filename, relative to @a rootpath
1482 * @retval Pointer to a string containing the full path.
1485 static char *xx_path(const char *name, const char *rootpath)
1489 fname = talloc_strdup(talloc_tos(), rootpath);
1493 trim_string(fname,"","/");
1495 if (!directory_exist(fname)) {
1496 if (!mkdir(fname,0755))
1497 DEBUG(1, ("Unable to create directory %s for file %s. "
1498 "Error was %s\n", fname, name, strerror(errno)));
1501 return talloc_asprintf(talloc_tos(),
1508 * @brief Returns an absolute path to a file in the Samba lock directory.
1510 * @param name File to find, relative to LOCKDIR.
1512 * @retval Pointer to a talloc'ed string containing the full path.
1515 char *lock_path(const char *name)
1517 return xx_path(name, lp_lockdir());
1521 * @brief Returns an absolute path to a file in the Samba pid directory.
1523 * @param name File to find, relative to PIDDIR.
1525 * @retval Pointer to a talloc'ed string containing the full path.
1528 char *pid_path(const char *name)
1530 return xx_path(name, lp_piddir());
1534 * @brief Returns an absolute path to a file in the Samba state directory.
1536 * @param name File to find, relative to STATEDIR.
1538 * @retval Pointer to a talloc'ed string containing the full path.
1541 char *state_path(const char *name)
1543 return xx_path(name, lp_statedir());
1547 * @brief Returns an absolute path to a file in the Samba cache directory.
1549 * @param name File to find, relative to CACHEDIR.
1551 * @retval Pointer to a talloc'ed string containing the full path.
1554 char *cache_path(const char *name)
1556 return xx_path(name, lp_cachedir());
1559 /*******************************************************************
1560 Given a filename - get its directory name
1561 ********************************************************************/
1563 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1569 p = strrchr_m(dir, '/'); /* Find final '/', if any */
1572 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1583 if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
1586 (*parent)[len] = '\0';
1594 /*******************************************************************
1595 Determine if a pattern contains any Microsoft wildcard characters.
1596 *******************************************************************/
1598 bool ms_has_wild(const char *s)
1602 if (lp_posix_pathnames()) {
1603 /* With posix pathnames no characters are wild. */
1607 while ((c = *s++)) {
1620 bool ms_has_wild_w(const smb_ucs2_t *s)
1623 if (!s) return False;
1624 while ((c = *s++)) {
1626 case UCS2_CHAR('*'):
1627 case UCS2_CHAR('?'):
1628 case UCS2_CHAR('<'):
1629 case UCS2_CHAR('>'):
1630 case UCS2_CHAR('"'):
1637 /*******************************************************************
1638 A wrapper that handles case sensitivity and the special handling
1640 *******************************************************************/
1642 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1644 if (ISDOTDOT(string))
1649 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
1652 /*******************************************************************
1653 A wrapper that handles case sensitivity and the special handling
1654 of the ".." name. Varient that is only called by old search code which requires
1655 pattern translation.
1656 *******************************************************************/
1658 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
1660 if (ISDOTDOT(string))
1665 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
1668 /*******************************************************************
1669 A wrapper that handles a list of patters and calls mask_match()
1670 on each. Returns True if any of the patterns match.
1671 *******************************************************************/
1673 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
1675 while (listLen-- > 0) {
1676 if (mask_match(string, *list++, is_case_sensitive))
1682 /*********************************************************
1683 Recursive routine that is called by unix_wild_match.
1684 *********************************************************/
1686 static bool unix_do_match(const char *regexp, const char *str)
1690 for( p = regexp; *p && *str; ) {
1701 * Look for a character matching
1702 * the one after the '*'.
1706 return true; /* Automatic match */
1709 while(*str && (*p != *str))
1713 * Patch from weidel@multichart.de. In the case of the regexp
1714 * '*XX*' we want to ensure there are at least 2 'X' characters
1715 * in the string after the '*' for a match to be made.
1722 * Eat all the characters that match, but count how many there were.
1725 while(*str && (*p == *str)) {
1731 * Now check that if the regexp had n identical characters that
1732 * matchcount had at least that many matches.
1735 while ( *(p+1) && (*(p+1) == *p)) {
1740 if ( matchcount <= 0 )
1744 str--; /* We've eaten the match char after the '*' */
1746 if(unix_do_match(p, str))
1768 if (!*p && str[0] == '.' && str[1] == 0)
1771 if (!*str && *p == '?') {
1777 if(!*str && (*p == '*' && p[1] == '\0'))
1783 /*******************************************************************
1784 Simple case insensitive interface to a UNIX wildcard matcher.
1785 Returns True if match, False if not.
1786 *******************************************************************/
1788 bool unix_wild_match(const char *pattern, const char *string)
1790 TALLOC_CTX *ctx = talloc_stackframe();
1796 p2 = talloc_strdup(ctx,pattern);
1797 s2 = talloc_strdup(ctx,string);
1805 /* Remove any *? and ** from the pattern as they are meaningless */
1806 for(p = p2; *p; p++) {
1807 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1808 memmove(&p[1], &p[2], strlen(&p[2])+1);
1812 if (strequal(p2,"*")) {
1817 ret = unix_do_match(p2, s2);
1822 /**********************************************************************
1823 Converts a name to a fully qualified domain name.
1824 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1825 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1826 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1827 ***********************************************************************/
1829 bool name_to_fqdn(fstring fqdn, const char *name)
1832 struct hostent *hp = gethostbyname(name);
1834 if (!hp || !hp->h_name || !*hp->h_name) {
1835 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1836 fstrcpy(fqdn, name);
1840 /* Find out if the fqdn is returned as an alias
1841 * to cope with /etc/hosts files where the first
1842 * name is not the fqdn but the short name */
1843 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1845 for (i = 0; hp->h_aliases[i]; i++) {
1846 if (strchr_m(hp->h_aliases[i], '.')) {
1847 full = hp->h_aliases[i];
1852 if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1853 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1854 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1855 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1856 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1863 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1864 fstrcpy(fqdn, full);
1868 /**********************************************************************
1869 Append a DATA_BLOB to a talloc'ed object
1870 ***********************************************************************/
1872 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1874 size_t old_size = 0;
1877 if (blob.length == 0) {
1882 old_size = talloc_get_size(buf);
1885 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1886 if (result == NULL) {
1890 memcpy(result + old_size, blob.data, blob.length);
1894 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1896 switch (share_access & ~FILE_SHARE_DELETE) {
1897 case FILE_SHARE_NONE:
1899 case FILE_SHARE_READ:
1901 case FILE_SHARE_WRITE:
1903 case FILE_SHARE_READ|FILE_SHARE_WRITE:
1906 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
1908 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
1915 pid_t procid_to_pid(const struct server_id *proc)
1920 static uint32 my_vnn = NONCLUSTER_VNN;
1922 void set_my_vnn(uint32 vnn)
1924 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
1928 uint32 get_my_vnn(void)
1933 static uint64_t my_unique_id = 0;
1935 void set_my_unique_id(uint64_t unique_id)
1937 my_unique_id = unique_id;
1940 struct server_id pid_to_procid(pid_t pid)
1942 struct server_id result;
1945 result.unique_id = my_unique_id;
1946 result.vnn = my_vnn;
1950 struct server_id procid_self(void)
1952 return pid_to_procid(sys_getpid());
1955 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
1957 if (p1->pid != p2->pid)
1959 if (p1->task_id != p2->task_id)
1961 if (p1->vnn != p2->vnn)
1966 bool cluster_id_equal(const struct server_id *id1,
1967 const struct server_id *id2)
1969 return procid_equal(id1, id2);
1972 bool procid_is_me(const struct server_id *pid)
1974 if (pid->pid != sys_getpid())
1976 if (pid->task_id != 0)
1978 if (pid->vnn != my_vnn)
1983 struct server_id interpret_pid(const char *pid_string)
1985 struct server_id result;
1986 unsigned long long pid;
1987 unsigned int vnn, task_id = 0;
1989 ZERO_STRUCT(result);
1991 /* We accept various forms with 1, 2 or 3 component forms
1992 * because the server_id_str() can print different forms, and
1993 * we want backwards compatibility for scripts that may call
1995 if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
1998 result.task_id = task_id;
1999 } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
2003 } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
2004 result.vnn = get_my_vnn();
2006 result.task_id = task_id;
2007 } else if (sscanf(pid_string, "%llu", &pid) == 1) {
2008 result.vnn = get_my_vnn();
2011 result.vnn = NONCLUSTER_VNN;
2012 result.pid = (uint64_t)-1;
2017 char *procid_str_static(const struct server_id *pid)
2019 return server_id_str(talloc_tos(), pid);
2022 bool procid_valid(const struct server_id *pid)
2024 return (pid->pid != (uint64_t)-1);
2027 bool procid_is_local(const struct server_id *pid)
2029 return pid->vnn == my_vnn;
2032 /****************************************************************
2033 Check if offset/length fit into bufsize. Should probably be
2034 merged with is_offset_safe, but this would require a rewrite
2035 of lanman.c. Later :-)
2036 ****************************************************************/
2038 bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
2040 if ((offset + length < offset) || (offset + length < length)) {
2044 if ((offset > bufsize) || (offset + length > bufsize)) {
2051 /****************************************************************
2052 Check if an offset into a buffer is safe.
2053 If this returns True it's safe to indirect into the byte at
2055 ****************************************************************/
2057 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2059 const char *end_base = buf_base + buf_len;
2060 char *end_ptr = ptr + off;
2062 if (!buf_base || !ptr) {
2066 if (end_base < buf_base || end_ptr < ptr) {
2067 return False; /* wrap. */
2070 if (end_ptr < end_base) {
2076 /****************************************************************
2077 Return a safe pointer into a buffer, or NULL.
2078 ****************************************************************/
2080 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2082 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2086 /****************************************************************
2087 Return a safe pointer into a string within a buffer, or NULL.
2088 ****************************************************************/
2090 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2092 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2095 /* Check if a valid string exists at this offset. */
2096 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2102 /****************************************************************
2103 Return an SVAL at a pointer, or failval if beyond the end.
2104 ****************************************************************/
2106 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2109 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2112 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2115 return SVAL(ptr,off);
2118 /****************************************************************
2119 Return an IVAL at a pointer, or failval if beyond the end.
2120 ****************************************************************/
2122 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2125 * Note we use off+3 here, not off+4 as IVAL accesses
2126 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2128 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2131 return IVAL(ptr,off);
2134 /****************************************************************
2135 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2136 call (they take care of winbind separator and other winbind specific settings).
2137 ****************************************************************/
2139 void split_domain_user(TALLOC_CTX *mem_ctx,
2140 const char *full_name,
2144 const char *p = NULL;
2146 p = strchr_m(full_name, '\\');
2149 *domain = talloc_strndup(mem_ctx, full_name,
2150 PTR_DIFF(p, full_name));
2151 *user = talloc_strdup(mem_ctx, p+1);
2153 *domain = talloc_strdup(mem_ctx, "");
2154 *user = talloc_strdup(mem_ctx, full_name);
2158 /****************************************************************
2159 strip off leading '\\' from a hostname
2160 ****************************************************************/
2162 const char *strip_hostname(const char *s)
2168 if (strlen_m(s) < 3) {
2172 if (s[0] == '\\') s++;
2173 if (s[0] == '\\') s++;
2178 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2179 struct tevent_context *ev,
2182 bool ret = tevent_req_poll(req, ev);
2184 *status = map_nt_error_from_unix(errno);
2189 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2191 if (!NT_STATUS_IS_OK(err1)) {
2195 if (!NT_STATUS_IS_OK(err2)) {
2202 int timeval_to_msec(struct timeval t)
2204 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2207 /*******************************************************************
2208 Check a given DOS pathname is valid for a share.
2209 ********************************************************************/
2211 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2215 if (!dos_pathname) {
2219 ptr = talloc_strdup(ctx, dos_pathname);
2223 /* Convert any '\' paths to '/' */
2225 ptr = unix_clean_name(ctx, ptr);
2230 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2231 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2234 /* Only absolute paths allowed. */
2241 /*******************************************************************
2242 Return True if the filename is one of the special executable types.
2243 ********************************************************************/
2245 bool is_executable(const char *fname)
2247 if ((fname = strrchr_m(fname,'.'))) {
2248 if (strequal(fname,".com") ||
2249 strequal(fname,".dll") ||
2250 strequal(fname,".exe") ||
2251 strequal(fname,".sym")) {
2258 /****************************************************************************
2259 Open a file with a share mode - old openX method - map into NTCreate.
2260 ****************************************************************************/
2262 bool map_open_params_to_ntcreate(const char *smb_base_fname,
2263 int deny_mode, int open_func,
2264 uint32 *paccess_mask,
2265 uint32 *pshare_mode,
2266 uint32 *pcreate_disposition,
2267 uint32 *pcreate_options,
2268 uint32_t *pprivate_flags)
2272 uint32 create_disposition;
2273 uint32 create_options = FILE_NON_DIRECTORY_FILE;
2274 uint32_t private_flags = 0;
2276 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2277 "open_func = 0x%x\n",
2278 smb_base_fname, (unsigned int)deny_mode,
2279 (unsigned int)open_func ));
2281 /* Create the NT compatible access_mask. */
2282 switch (GET_OPENX_MODE(deny_mode)) {
2283 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
2284 case DOS_OPEN_RDONLY:
2285 access_mask = FILE_GENERIC_READ;
2287 case DOS_OPEN_WRONLY:
2288 access_mask = FILE_GENERIC_WRITE;
2292 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
2295 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2296 (unsigned int)GET_OPENX_MODE(deny_mode)));
2300 /* Create the NT compatible create_disposition. */
2301 switch (open_func) {
2302 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
2303 create_disposition = FILE_CREATE;
2306 case OPENX_FILE_EXISTS_OPEN:
2307 create_disposition = FILE_OPEN;
2310 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
2311 create_disposition = FILE_OPEN_IF;
2314 case OPENX_FILE_EXISTS_TRUNCATE:
2315 create_disposition = FILE_OVERWRITE;
2318 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
2319 create_disposition = FILE_OVERWRITE_IF;
2323 /* From samba4 - to be confirmed. */
2324 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
2325 create_disposition = FILE_CREATE;
2328 DEBUG(10,("map_open_params_to_ntcreate: bad "
2329 "open_func 0x%x\n", (unsigned int)open_func));
2333 /* Create the NT compatible share modes. */
2334 switch (GET_DENY_MODE(deny_mode)) {
2336 share_mode = FILE_SHARE_NONE;
2340 share_mode = FILE_SHARE_READ;
2344 share_mode = FILE_SHARE_WRITE;
2348 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2352 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
2353 if (is_executable(smb_base_fname)) {
2354 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2356 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
2357 share_mode = FILE_SHARE_READ;
2359 share_mode = FILE_SHARE_NONE;
2365 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
2366 share_mode = FILE_SHARE_NONE;
2370 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2371 (unsigned int)GET_DENY_MODE(deny_mode) ));
2375 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2376 "share_mode = 0x%x, create_disposition = 0x%x, "
2377 "create_options = 0x%x private_flags = 0x%x\n",
2379 (unsigned int)access_mask,
2380 (unsigned int)share_mode,
2381 (unsigned int)create_disposition,
2382 (unsigned int)create_options,
2383 (unsigned int)private_flags));
2386 *paccess_mask = access_mask;
2389 *pshare_mode = share_mode;
2391 if (pcreate_disposition) {
2392 *pcreate_disposition = create_disposition;
2394 if (pcreate_options) {
2395 *pcreate_options = create_options;
2397 if (pprivate_flags) {
2398 *pprivate_flags = private_flags;
2406 void init_modules(void)
2408 /* FIXME: This can cause undefined symbol errors :
2409 * smb_register_vfs() isn't available in nmbd, for example */
2410 if(lp_preload_modules())
2411 smb_load_modules(lp_preload_modules());