s3:include: make smb_setlen() a macro
[Samba/gebeck_regimport.git] / source3 / lib / util.c
blob8157c0ffd0d2c6005bde8f3d6d050931d8fc206b
1 /*
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/>.
24 #include "includes.h"
25 #include "system/passwd.h"
26 #include "system/filesys.h"
27 #include "util_tdb.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/util_pw.h"
30 #include "messages.h"
31 #include <ccan/hash/hash.h>
32 #include "libcli/security/security.h"
34 #ifdef HAVE_SYS_PRCTL_H
35 #include <sys/prctl.h>
36 #endif
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.
52 #if defined(GROUP)
53 #undef GROUP
54 #endif
56 #if defined(GROUP_OBJ)
57 #undef GROUP_OBJ
58 #endif
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)
71 return Protocol;
74 void set_Protocol(enum protocol_types p)
76 Protocol = p;
79 static enum remote_arch_types ra_type = RA_UNKNOWN;
81 void gfree_all( void )
83 gfree_names();
84 gfree_loadparm();
85 gfree_charcnv();
86 gfree_interfaces();
87 gfree_debugsyms();
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)
97 SMB_STRUCT_STAT st;
98 if (!sbuf)
99 sbuf = &st;
101 if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
102 return(False);
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)
113 SMB_STRUCT_STAT st;
114 if (sys_stat(fname, &st, false) != 0)
115 return(False);
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)
135 SMB_STRUCT_STAT buf;
136 buf.st_ex_size = 0;
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)
148 int i;
149 int bcc=0;
151 if (!DEBUGLVL(5))
152 return;
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",
155 smb_len(buf),
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));
177 if (DEBUGLEVEL < 10)
178 return;
180 if (DEBUGLEVEL < 50)
181 bcc = MIN(bcc, 512);
183 dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
186 /*******************************************************************
187 Setup only the byte count for a smb message.
188 ********************************************************************/
190 int set_message_bcc(char *buf,int num_bytes)
192 int num_words = CVAL(buf,smb_wct);
193 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
194 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
195 return (smb_size + num_words*2 + num_bytes);
198 /*******************************************************************
199 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
200 Return the bytes added
201 ********************************************************************/
203 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
205 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
206 uint8 *tmp;
208 if (!(tmp = talloc_realloc(NULL, *outbuf, uint8, newlen))) {
209 DEBUG(0, ("talloc failed\n"));
210 return -1;
212 *outbuf = tmp;
214 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
215 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
216 return blob.length;
219 /*******************************************************************
220 Reduce a file name, removing .. elements.
221 ********************************************************************/
223 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
225 char *p = NULL;
226 char *str = NULL;
228 DEBUG(3,("dos_clean_name [%s]\n",s));
230 /* remove any double slashes */
231 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
232 if (!str) {
233 return NULL;
236 /* Remove leading .\\ characters */
237 if(strncmp(str, ".\\", 2) == 0) {
238 trim_string(str, ".\\", NULL);
239 if(*str == 0) {
240 str = talloc_strdup(ctx, ".\\");
241 if (!str) {
242 return NULL;
247 while ((p = strstr_m(str,"\\..\\")) != NULL) {
248 char *s1;
250 *p = 0;
251 s1 = p+3;
253 if ((p=strrchr_m(str,'\\')) != NULL) {
254 *p = 0;
255 } else {
256 *str = 0;
258 str = talloc_asprintf(ctx,
259 "%s%s",
260 str,
261 s1);
262 if (!str) {
263 return NULL;
267 trim_string(str,NULL,"\\..");
268 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
271 /*******************************************************************
272 Reduce a file name, removing .. elements.
273 ********************************************************************/
275 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
277 char *p = NULL;
278 char *str = NULL;
280 DEBUG(3,("unix_clean_name [%s]\n",s));
282 /* remove any double slashes */
283 str = talloc_all_string_sub(ctx, s, "//","/");
284 if (!str) {
285 return NULL;
288 /* Remove leading ./ characters */
289 if(strncmp(str, "./", 2) == 0) {
290 trim_string(str, "./", NULL);
291 if(*str == 0) {
292 str = talloc_strdup(ctx, "./");
293 if (!str) {
294 return NULL;
299 while ((p = strstr_m(str,"/../")) != NULL) {
300 char *s1;
302 *p = 0;
303 s1 = p+3;
305 if ((p=strrchr_m(str,'/')) != NULL) {
306 *p = 0;
307 } else {
308 *str = 0;
310 str = talloc_asprintf(ctx,
311 "%s%s",
312 str,
313 s1);
314 if (!str) {
315 return NULL;
319 trim_string(str,NULL,"/..");
320 return talloc_all_string_sub(ctx, str, "/./", "/");
323 char *clean_name(TALLOC_CTX *ctx, const char *s)
325 char *str = dos_clean_name(ctx, s);
326 if (!str) {
327 return NULL;
329 return unix_clean_name(ctx, str);
332 /*******************************************************************
333 Write data into an fd at a given offset. Ignore seek errors.
334 ********************************************************************/
336 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
338 size_t total=0;
339 ssize_t ret;
341 if (pos == (SMB_OFF_T)-1) {
342 return write_data(fd, buffer, N);
344 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
345 while (total < N) {
346 ret = sys_pwrite(fd,buffer + total,N - total, pos);
347 if (ret == -1 && errno == ESPIPE) {
348 return write_data(fd, buffer + total,N - total);
350 if (ret == -1) {
351 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
352 return -1;
354 if (ret == 0) {
355 return total;
357 total += ret;
358 pos += ret;
360 return (ssize_t)total;
361 #else
362 /* Use lseek and write_data. */
363 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
364 if (errno != ESPIPE) {
365 return -1;
368 return write_data(fd, buffer, N);
369 #endif
373 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
374 struct event_context *ev_ctx,
375 struct server_id id,
376 bool parent_longlived)
378 NTSTATUS status = NT_STATUS_OK;
380 /* Reset the state of the random
381 * number generation system, so
382 * children do not get the same random
383 * numbers as each other */
384 set_need_random_reseed();
386 /* tdb needs special fork handling */
387 if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
388 DEBUG(0,("tdb_reopen_all failed.\n"));
389 status = NT_STATUS_OPEN_FAILED;
390 goto done;
393 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
394 smb_panic(__location__ ": Failed to re-initialise event context");
397 if (msg_ctx) {
399 * For clustering, we need to re-init our ctdbd connection after the
400 * fork
402 status = messaging_reinit(msg_ctx, id);
403 if (!NT_STATUS_IS_OK(status)) {
404 DEBUG(0,("messaging_reinit() failed: %s\n",
405 nt_errstr(status)));
408 done:
409 return status;
412 /****************************************************************************
413 (Hopefully) efficient array append.
414 ****************************************************************************/
416 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
417 void *element, void *_array, uint32 *num_elements,
418 ssize_t *array_size)
420 void **array = (void **)_array;
422 if (*array_size < 0) {
423 return;
426 if (*array == NULL) {
427 if (*array_size == 0) {
428 *array_size = 128;
431 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
432 goto error;
435 *array = TALLOC(mem_ctx, element_size * (*array_size));
436 if (*array == NULL) {
437 goto error;
441 if (*num_elements == *array_size) {
442 *array_size *= 2;
444 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
445 goto error;
448 *array = TALLOC_REALLOC(mem_ctx, *array,
449 element_size * (*array_size));
451 if (*array == NULL) {
452 goto error;
456 memcpy((char *)(*array) + element_size*(*num_elements),
457 element, element_size);
458 *num_elements += 1;
460 return;
462 error:
463 *num_elements = 0;
464 *array_size = -1;
467 /****************************************************************************
468 Get my own domain name, or "" if we have none.
469 ****************************************************************************/
471 char *get_mydnsdomname(TALLOC_CTX *ctx)
473 const char *domname;
474 char *p;
476 domname = get_mydnsfullname();
477 if (!domname) {
478 return NULL;
481 p = strchr_m(domname, '.');
482 if (p) {
483 p++;
484 return talloc_strdup(ctx, p);
485 } else {
486 return talloc_strdup(ctx, "");
490 /****************************************************************************
491 Interpret a protocol description string, with a default.
492 ****************************************************************************/
494 int interpret_protocol(const char *str,int def)
496 if (strequal(str,"NT1"))
497 return(PROTOCOL_NT1);
498 if (strequal(str,"LANMAN2"))
499 return(PROTOCOL_LANMAN2);
500 if (strequal(str,"LANMAN1"))
501 return(PROTOCOL_LANMAN1);
502 if (strequal(str,"CORE"))
503 return(PROTOCOL_CORE);
504 if (strequal(str,"COREPLUS"))
505 return(PROTOCOL_COREPLUS);
506 if (strequal(str,"CORE+"))
507 return(PROTOCOL_COREPLUS);
509 DEBUG(0,("Unrecognised protocol level %s\n",str));
511 return(def);
515 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
516 /******************************************************************
517 Remove any mount options such as -rsize=2048,wsize=2048 etc.
518 Based on a fix from <Thomas.Hepper@icem.de>.
519 Returns a malloc'ed string.
520 *******************************************************************/
522 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
524 if (*str == '-') {
525 const char *p = str;
526 while(*p && !isspace(*p))
527 p++;
528 while(*p && isspace(*p))
529 p++;
530 if(*p) {
531 return talloc_strdup(ctx, p);
534 return NULL;
537 /*******************************************************************
538 Patch from jkf@soton.ac.uk
539 Split Luke's automount_server into YP lookup and string splitter
540 so can easily implement automount_path().
541 Returns a malloc'ed string.
542 *******************************************************************/
544 #ifdef WITH_NISPLUS_HOME
545 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
547 char *value = NULL;
549 char *nis_map = (char *)lp_nis_home_map_name();
551 char buffer[NIS_MAXATTRVAL + 1];
552 nis_result *result;
553 nis_object *object;
554 entry_obj *entry;
556 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
557 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
559 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
560 if (result->status != NIS_SUCCESS) {
561 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
562 } else {
563 object = result->objects.objects_val;
564 if (object->zo_data.zo_type == ENTRY_OBJ) {
565 entry = &object->zo_data.objdata_u.en_data;
566 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
567 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
569 value = talloc_strdup(ctx,
570 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
571 if (!value) {
572 nis_freeresult(result);
573 return NULL;
575 value = talloc_string_sub(ctx,
576 value,
577 "&",
578 user_name);
582 nis_freeresult(result);
584 if (value) {
585 value = strip_mount_options(ctx, value);
586 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
587 user_name, value));
589 return value;
591 #else /* WITH_NISPLUS_HOME */
593 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
595 char *value = NULL;
597 int nis_error; /* returned by yp all functions */
598 char *nis_result; /* yp_match inits this */
599 int nis_result_len; /* and set this */
600 char *nis_domain; /* yp_get_default_domain inits this */
601 char *nis_map = (char *)lp_nis_home_map_name();
603 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
604 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
605 return NULL;
608 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
610 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
611 strlen(user_name), &nis_result,
612 &nis_result_len)) == 0) {
613 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
614 nis_result[nis_result_len] = '\0';
616 value = talloc_strdup(ctx, nis_result);
617 if (!value) {
618 return NULL;
620 value = strip_mount_options(ctx, value);
621 } else if(nis_error == YPERR_KEY) {
622 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
623 user_name, nis_map));
624 DEBUG(3, ("using defaults for server and home directory\n"));
625 } else {
626 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
627 yperr_string(nis_error), user_name, nis_map));
630 if (value) {
631 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
633 return value;
635 #endif /* WITH_NISPLUS_HOME */
636 #endif
638 /****************************************************************************
639 Check if a process exists. Does this work on all unixes?
640 ****************************************************************************/
642 bool process_exists(const struct server_id pid)
644 if (procid_is_me(&pid)) {
645 return True;
648 if (procid_is_local(&pid)) {
649 return (kill(pid.pid,0) == 0 || errno != ESRCH);
652 #ifdef CLUSTER_SUPPORT
653 return ctdbd_process_exists(messaging_ctdbd_connection(),
654 pid.vnn, pid.pid);
655 #else
656 return False;
657 #endif
660 /*******************************************************************
661 Convert a uid into a user name.
662 ********************************************************************/
664 const char *uidtoname(uid_t uid)
666 TALLOC_CTX *ctx = talloc_tos();
667 char *name = NULL;
668 struct passwd *pass = NULL;
670 pass = getpwuid_alloc(ctx,uid);
671 if (pass) {
672 name = talloc_strdup(ctx,pass->pw_name);
673 TALLOC_FREE(pass);
674 } else {
675 name = talloc_asprintf(ctx,
676 "%ld",
677 (long int)uid);
679 return name;
682 /*******************************************************************
683 Convert a gid into a group name.
684 ********************************************************************/
686 char *gidtoname(gid_t gid)
688 struct group *grp;
690 grp = getgrgid(gid);
691 if (grp) {
692 return talloc_strdup(talloc_tos(), grp->gr_name);
694 else {
695 return talloc_asprintf(talloc_tos(),
696 "%d",
697 (int)gid);
701 /*******************************************************************
702 Convert a user name into a uid.
703 ********************************************************************/
705 uid_t nametouid(const char *name)
707 struct passwd *pass;
708 char *p;
709 uid_t u;
711 pass = Get_Pwnam_alloc(talloc_tos(), name);
712 if (pass) {
713 u = pass->pw_uid;
714 TALLOC_FREE(pass);
715 return u;
718 u = (uid_t)strtol(name, &p, 0);
719 if ((p != name) && (*p == '\0'))
720 return u;
722 return (uid_t)-1;
725 /*******************************************************************
726 Convert a name to a gid_t if possible. Return -1 if not a group.
727 ********************************************************************/
729 gid_t nametogid(const char *name)
731 struct group *grp;
732 char *p;
733 gid_t g;
735 g = (gid_t)strtol(name, &p, 0);
736 if ((p != name) && (*p == '\0'))
737 return g;
739 grp = sys_getgrnam(name);
740 if (grp)
741 return(grp->gr_gid);
742 return (gid_t)-1;
745 /*******************************************************************
746 Something really nasty happened - panic !
747 ********************************************************************/
749 void smb_panic_s3(const char *why)
751 char *cmd;
752 int result;
754 DEBUG(0,("PANIC (pid %llu): %s\n",
755 (unsigned long long)sys_getpid(), why));
756 log_stack_trace();
758 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
760 * Make sure all children can attach a debugger.
762 prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
763 #endif
765 cmd = lp_panic_action();
766 if (cmd && *cmd) {
767 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
768 result = system(cmd);
770 if (result == -1)
771 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
772 strerror(errno)));
773 else
774 DEBUG(0, ("smb_panic(): action returned status %d\n",
775 WEXITSTATUS(result)));
778 dump_core();
781 /*******************************************************************
782 Print a backtrace of the stack to the debug log. This function
783 DELIBERATELY LEAKS MEMORY. The expectation is that you should
784 exit shortly after calling it.
785 ********************************************************************/
787 #ifdef HAVE_LIBUNWIND_H
788 #include <libunwind.h>
789 #endif
791 #ifdef HAVE_EXECINFO_H
792 #include <execinfo.h>
793 #endif
795 #ifdef HAVE_LIBEXC_H
796 #include <libexc.h>
797 #endif
799 void log_stack_trace(void)
801 #ifdef HAVE_LIBUNWIND
802 /* Try to use libunwind before any other technique since on ia64
803 * libunwind correctly walks the stack in more circumstances than
804 * backtrace.
806 unw_cursor_t cursor;
807 unw_context_t uc;
808 unsigned i = 0;
810 char procname[256];
811 unw_word_t ip, sp, off;
813 procname[sizeof(procname) - 1] = '\0';
815 if (unw_getcontext(&uc) != 0) {
816 goto libunwind_failed;
819 if (unw_init_local(&cursor, &uc) != 0) {
820 goto libunwind_failed;
823 DEBUG(0, ("BACKTRACE:\n"));
825 do {
826 ip = sp = 0;
827 unw_get_reg(&cursor, UNW_REG_IP, &ip);
828 unw_get_reg(&cursor, UNW_REG_SP, &sp);
830 switch (unw_get_proc_name(&cursor,
831 procname, sizeof(procname) - 1, &off) ) {
832 case 0:
833 /* Name found. */
834 case -UNW_ENOMEM:
835 /* Name truncated. */
836 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
837 i, procname, (long long)off,
838 (long long)ip, (long long) sp));
839 break;
840 default:
841 /* case -UNW_ENOINFO: */
842 /* case -UNW_EUNSPEC: */
843 /* No symbol name found. */
844 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
845 i, "<unknown symbol>",
846 (long long)ip, (long long) sp));
848 ++i;
849 } while (unw_step(&cursor) > 0);
851 return;
853 libunwind_failed:
854 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
856 #elif HAVE_BACKTRACE_SYMBOLS
857 void *backtrace_stack[BACKTRACE_STACK_SIZE];
858 size_t backtrace_size;
859 char **backtrace_strings;
861 /* get the backtrace (stack frames) */
862 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
863 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
865 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
866 (unsigned long)backtrace_size));
868 if (backtrace_strings) {
869 int i;
871 for (i = 0; i < backtrace_size; i++)
872 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
874 /* Leak the backtrace_strings, rather than risk what free() might do */
877 #elif HAVE_LIBEXC
879 /* The IRIX libexc library provides an API for unwinding the stack. See
880 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
881 * since we are about to abort anyway, it hardly matters.
884 #define NAMESIZE 32 /* Arbitrary */
886 __uint64_t addrs[BACKTRACE_STACK_SIZE];
887 char * names[BACKTRACE_STACK_SIZE];
888 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
890 int i;
891 int levels;
893 ZERO_ARRAY(addrs);
894 ZERO_ARRAY(names);
895 ZERO_ARRAY(namebuf);
897 /* We need to be root so we can open our /proc entry to walk
898 * our stack. It also helps when we want to dump core.
900 become_root();
902 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
903 names[i] = namebuf + (i * NAMESIZE);
906 levels = trace_back_stack(0, addrs, names,
907 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
909 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
910 for (i = 0; i < levels; i++) {
911 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
913 #undef NAMESIZE
915 #else
916 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
917 #endif
920 /*******************************************************************
921 A readdir wrapper which just returns the file name.
922 ********************************************************************/
924 const char *readdirname(SMB_STRUCT_DIR *p)
926 SMB_STRUCT_DIRENT *ptr;
927 char *dname;
929 if (!p)
930 return(NULL);
932 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
933 if (!ptr)
934 return(NULL);
936 dname = ptr->d_name;
938 #ifdef NEXT2
939 if (telldir(p) < 0)
940 return(NULL);
941 #endif
943 #ifdef HAVE_BROKEN_READDIR_NAME
944 /* using /usr/ucb/cc is BAD */
945 dname = dname - 2;
946 #endif
948 return talloc_strdup(talloc_tos(), dname);
951 /*******************************************************************
952 Utility function used to decide if the last component
953 of a path matches a (possibly wildcarded) entry in a namelist.
954 ********************************************************************/
956 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
958 const char *last_component;
960 /* if we have no list it's obviously not in the path */
961 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
962 return False;
965 DEBUG(8, ("is_in_path: %s\n", name));
967 /* Get the last component of the unix name. */
968 last_component = strrchr_m(name, '/');
969 if (!last_component) {
970 last_component = name;
971 } else {
972 last_component++; /* Go past '/' */
975 for(; namelist->name != NULL; namelist++) {
976 if(namelist->is_wild) {
977 if (mask_match(last_component, namelist->name, case_sensitive)) {
978 DEBUG(8,("is_in_path: mask match succeeded\n"));
979 return True;
981 } else {
982 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
983 (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
984 DEBUG(8,("is_in_path: match succeeded\n"));
985 return True;
989 DEBUG(8,("is_in_path: match not found\n"));
990 return False;
993 /*******************************************************************
994 Strip a '/' separated list into an array of
995 name_compare_enties structures suitable for
996 passing to is_in_path(). We do this for
997 speed so we can pre-parse all the names in the list
998 and don't do it for each call to is_in_path().
999 We also check if the entry contains a wildcard to
1000 remove a potentially expensive call to mask_match
1001 if possible.
1002 ********************************************************************/
1004 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1006 char *name_end;
1007 char *namelist;
1008 char *nameptr;
1009 int num_entries = 0;
1010 int i;
1012 (*ppname_array) = NULL;
1014 if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0')))
1015 return;
1017 namelist = talloc_strdup(talloc_tos(), namelist_in);
1018 if (namelist == NULL) {
1019 DEBUG(0,("set_namearray: talloc fail\n"));
1020 return;
1022 nameptr = namelist;
1024 /* We need to make two passes over the string. The
1025 first to count the number of elements, the second
1026 to split it.
1029 while(*nameptr) {
1030 if ( *nameptr == '/' ) {
1031 /* cope with multiple (useless) /s) */
1032 nameptr++;
1033 continue;
1035 /* anything left? */
1036 if ( *nameptr == '\0' )
1037 break;
1039 /* find the next '/' or consume remaining */
1040 name_end = strchr_m(nameptr, '/');
1041 if (name_end == NULL)
1042 name_end = (char *)nameptr + strlen(nameptr);
1044 /* next segment please */
1045 nameptr = name_end + 1;
1046 num_entries++;
1049 if(num_entries == 0) {
1050 talloc_free(namelist);
1051 return;
1054 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1055 DEBUG(0,("set_namearray: malloc fail\n"));
1056 talloc_free(namelist);
1057 return;
1060 /* Now copy out the names */
1061 nameptr = namelist;
1062 i = 0;
1063 while(*nameptr) {
1064 if ( *nameptr == '/' ) {
1065 /* cope with multiple (useless) /s) */
1066 nameptr++;
1067 continue;
1069 /* anything left? */
1070 if ( *nameptr == '\0' )
1071 break;
1073 /* find the next '/' or consume remaining */
1074 name_end = strchr_m(nameptr, '/');
1075 if (name_end)
1076 *name_end = '\0';
1077 else
1078 name_end = nameptr + strlen(nameptr);
1080 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1081 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1082 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1083 talloc_free(namelist);
1084 return;
1087 /* next segment please */
1088 nameptr = name_end + 1;
1089 i++;
1092 (*ppname_array)[i].name = NULL;
1094 talloc_free(namelist);
1095 return;
1098 #undef DBGC_CLASS
1099 #define DBGC_CLASS DBGC_LOCKING
1101 /****************************************************************************
1102 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1103 is dealt with in posix.c
1104 Returns True if we have information regarding this lock region (and returns
1105 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1106 ****************************************************************************/
1108 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1110 SMB_STRUCT_FLOCK lock;
1111 int ret;
1113 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1114 fd,(double)*poffset,(double)*pcount,*ptype));
1116 lock.l_type = *ptype;
1117 lock.l_whence = SEEK_SET;
1118 lock.l_start = *poffset;
1119 lock.l_len = *pcount;
1120 lock.l_pid = 0;
1122 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1124 if (ret == -1) {
1125 int sav = errno;
1126 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1127 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1128 errno = sav;
1129 return False;
1132 *ptype = lock.l_type;
1133 *poffset = lock.l_start;
1134 *pcount = lock.l_len;
1135 *ppid = lock.l_pid;
1137 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1138 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1139 return True;
1142 #undef DBGC_CLASS
1143 #define DBGC_CLASS DBGC_ALL
1145 /*******************************************************************
1146 Is the name specified one of my netbios names.
1147 Returns true if it is equal, false otherwise.
1148 ********************************************************************/
1150 bool is_myname(const char *s)
1152 int n;
1153 bool ret = False;
1155 for (n=0; my_netbios_names(n); n++) {
1156 if (strequal(my_netbios_names(n), s)) {
1157 ret=True;
1158 break;
1161 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1162 return(ret);
1165 /*******************************************************************
1166 Is the name specified our workgroup/domain.
1167 Returns true if it is equal, false otherwise.
1168 ********************************************************************/
1170 bool is_myworkgroup(const char *s)
1172 bool ret = False;
1174 if (strequal(s, lp_workgroup())) {
1175 ret=True;
1178 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1179 return(ret);
1182 /*******************************************************************
1183 we distinguish between 2K and XP by the "Native Lan Manager" string
1184 WinXP => "Windows 2002 5.1"
1185 WinXP 64bit => "Windows XP 5.2"
1186 Win2k => "Windows 2000 5.0"
1187 NT4 => "Windows NT 4.0"
1188 Win9x => "Windows 4.0"
1189 Windows 2003 doesn't set the native lan manager string but
1190 they do set the domain to "Windows 2003 5.2" (probably a bug).
1191 ********************************************************************/
1193 void ra_lanman_string( const char *native_lanman )
1195 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1196 set_remote_arch( RA_WINXP );
1197 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1198 set_remote_arch( RA_WINXP64 );
1199 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1200 set_remote_arch( RA_WIN2K3 );
1203 static const char *remote_arch_str;
1205 const char *get_remote_arch_str(void)
1207 if (!remote_arch_str) {
1208 return "UNKNOWN";
1210 return remote_arch_str;
1213 /*******************************************************************
1214 Set the horrid remote_arch string based on an enum.
1215 ********************************************************************/
1217 void set_remote_arch(enum remote_arch_types type)
1219 ra_type = type;
1220 switch( type ) {
1221 case RA_WFWG:
1222 remote_arch_str = "WfWg";
1223 break;
1224 case RA_OS2:
1225 remote_arch_str = "OS2";
1226 break;
1227 case RA_WIN95:
1228 remote_arch_str = "Win95";
1229 break;
1230 case RA_WINNT:
1231 remote_arch_str = "WinNT";
1232 break;
1233 case RA_WIN2K:
1234 remote_arch_str = "Win2K";
1235 break;
1236 case RA_WINXP:
1237 remote_arch_str = "WinXP";
1238 break;
1239 case RA_WINXP64:
1240 remote_arch_str = "WinXP64";
1241 break;
1242 case RA_WIN2K3:
1243 remote_arch_str = "Win2K3";
1244 break;
1245 case RA_VISTA:
1246 remote_arch_str = "Vista";
1247 break;
1248 case RA_SAMBA:
1249 remote_arch_str = "Samba";
1250 break;
1251 case RA_CIFSFS:
1252 remote_arch_str = "CIFSFS";
1253 break;
1254 case RA_OSX:
1255 remote_arch_str = "OSX";
1256 break;
1257 default:
1258 ra_type = RA_UNKNOWN;
1259 remote_arch_str = "UNKNOWN";
1260 break;
1263 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1264 remote_arch_str));
1267 /*******************************************************************
1268 Get the remote_arch type.
1269 ********************************************************************/
1271 enum remote_arch_types get_remote_arch(void)
1273 return ra_type;
1276 const char *tab_depth(int level, int depth)
1278 if( CHECK_DEBUGLVL(level) ) {
1279 dbgtext("%*s", depth*4, "");
1281 return "";
1284 /*****************************************************************************
1285 Provide a checksum on a string
1287 Input: s - the null-terminated character string for which the checksum
1288 will be calculated.
1290 Output: The checksum value calculated for s.
1291 *****************************************************************************/
1293 int str_checksum(const char *s)
1295 if (s == NULL)
1296 return 0;
1297 return hash(s, strlen(s), 0);
1300 /*****************************************************************
1301 Zero a memory area then free it. Used to catch bugs faster.
1302 *****************************************************************/
1304 void zero_free(void *p, size_t size)
1306 memset(p, 0, size);
1307 SAFE_FREE(p);
1310 /*****************************************************************
1311 Set our open file limit to a requested max and return the limit.
1312 *****************************************************************/
1314 int set_maxfiles(int requested_max)
1316 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1317 struct rlimit rlp;
1318 int saved_current_limit;
1320 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1321 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1322 strerror(errno) ));
1323 /* just guess... */
1324 return requested_max;
1328 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1329 * account for the extra fd we need
1330 * as well as the log files and standard
1331 * handles etc. Save the limit we want to set in case
1332 * we are running on an OS that doesn't support this limit (AIX)
1333 * which always returns RLIM_INFINITY for rlp.rlim_max.
1336 /* Try raising the hard (max) limit to the requested amount. */
1338 #if defined(RLIM_INFINITY)
1339 if (rlp.rlim_max != RLIM_INFINITY) {
1340 int orig_max = rlp.rlim_max;
1342 if ( rlp.rlim_max < requested_max )
1343 rlp.rlim_max = requested_max;
1345 /* This failing is not an error - many systems (Linux) don't
1346 support our default request of 10,000 open files. JRA. */
1348 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1349 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1350 (int)rlp.rlim_max, strerror(errno) ));
1352 /* Set failed - restore original value from get. */
1353 rlp.rlim_max = orig_max;
1356 #endif
1358 /* Now try setting the soft (current) limit. */
1360 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1362 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1363 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1364 (int)rlp.rlim_cur, strerror(errno) ));
1365 /* just guess... */
1366 return saved_current_limit;
1369 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1370 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1371 strerror(errno) ));
1372 /* just guess... */
1373 return saved_current_limit;
1376 #if defined(RLIM_INFINITY)
1377 if(rlp.rlim_cur == RLIM_INFINITY)
1378 return saved_current_limit;
1379 #endif
1381 if((int)rlp.rlim_cur > saved_current_limit)
1382 return saved_current_limit;
1384 return rlp.rlim_cur;
1385 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1387 * No way to know - just guess...
1389 return requested_max;
1390 #endif
1393 /*****************************************************************
1394 malloc that aborts with smb_panic on fail or zero size.
1395 *****************************************************************/
1397 void *smb_xmalloc_array(size_t size, unsigned int count)
1399 void *p;
1400 if (size == 0) {
1401 smb_panic("smb_xmalloc_array: called with zero size");
1403 if (count >= MAX_ALLOC_SIZE/size) {
1404 smb_panic("smb_xmalloc_array: alloc size too large");
1406 if ((p = SMB_MALLOC(size*count)) == NULL) {
1407 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1408 (unsigned long)size, (unsigned long)count));
1409 smb_panic("smb_xmalloc_array: malloc failed");
1411 return p;
1415 vasprintf that aborts on malloc fail
1418 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1420 int n;
1421 va_list ap2;
1423 va_copy(ap2, ap);
1425 n = vasprintf(ptr, format, ap2);
1426 va_end(ap2);
1427 if (n == -1 || ! *ptr) {
1428 smb_panic("smb_xvasprintf: out of memory");
1430 return n;
1433 /*****************************************************************
1434 Get local hostname and cache result.
1435 *****************************************************************/
1437 char *myhostname(void)
1439 static char *ret;
1440 if (ret == NULL) {
1441 ret = get_myname(NULL);
1443 return ret;
1446 /*****************************************************************
1447 Get local hostname and cache result.
1448 *****************************************************************/
1450 char *myhostname_upper(void)
1452 char *name;
1453 static char *ret;
1454 if (ret == NULL) {
1455 name = get_myname(talloc_tos());
1456 ret = strupper_talloc(NULL, name);
1457 talloc_free(name);
1459 return ret;
1463 * @brief Returns an absolute path to a file concatenating the provided
1464 * @a rootpath and @a basename
1466 * @param name Filename, relative to @a rootpath
1468 * @retval Pointer to a string containing the full path.
1471 static char *xx_path(const char *name, const char *rootpath)
1473 char *fname = NULL;
1475 fname = talloc_strdup(talloc_tos(), rootpath);
1476 if (!fname) {
1477 return NULL;
1479 trim_string(fname,"","/");
1481 if (!directory_exist(fname)) {
1482 if (!mkdir(fname,0755))
1483 DEBUG(1, ("Unable to create directory %s for file %s. "
1484 "Error was %s\n", fname, name, strerror(errno)));
1487 return talloc_asprintf(talloc_tos(),
1488 "%s/%s",
1489 fname,
1490 name);
1494 * @brief Returns an absolute path to a file in the Samba lock directory.
1496 * @param name File to find, relative to LOCKDIR.
1498 * @retval Pointer to a talloc'ed string containing the full path.
1501 char *lock_path(const char *name)
1503 return xx_path(name, lp_lockdir());
1507 * @brief Returns an absolute path to a file in the Samba pid directory.
1509 * @param name File to find, relative to PIDDIR.
1511 * @retval Pointer to a talloc'ed string containing the full path.
1514 char *pid_path(const char *name)
1516 return xx_path(name, lp_piddir());
1520 * @brief Returns an absolute path to a file in the Samba state directory.
1522 * @param name File to find, relative to STATEDIR.
1524 * @retval Pointer to a talloc'ed string containing the full path.
1527 char *state_path(const char *name)
1529 return xx_path(name, lp_statedir());
1533 * @brief Returns an absolute path to a file in the Samba cache directory.
1535 * @param name File to find, relative to CACHEDIR.
1537 * @retval Pointer to a talloc'ed string containing the full path.
1540 char *cache_path(const char *name)
1542 return xx_path(name, lp_cachedir());
1545 /*******************************************************************
1546 Given a filename - get its directory name
1547 ********************************************************************/
1549 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1550 const char **name)
1552 char *p;
1553 ptrdiff_t len;
1555 p = strrchr_m(dir, '/'); /* Find final '/', if any */
1557 if (p == NULL) {
1558 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1559 return False;
1561 if (name) {
1562 *name = dir;
1564 return True;
1567 len = p-dir;
1569 if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
1570 return False;
1572 (*parent)[len] = '\0';
1574 if (name) {
1575 *name = p+1;
1577 return True;
1580 /*******************************************************************
1581 Determine if a pattern contains any Microsoft wildcard characters.
1582 *******************************************************************/
1584 bool ms_has_wild(const char *s)
1586 char c;
1588 if (lp_posix_pathnames()) {
1589 /* With posix pathnames no characters are wild. */
1590 return False;
1593 while ((c = *s++)) {
1594 switch (c) {
1595 case '*':
1596 case '?':
1597 case '<':
1598 case '>':
1599 case '"':
1600 return True;
1603 return False;
1606 bool ms_has_wild_w(const smb_ucs2_t *s)
1608 smb_ucs2_t c;
1609 if (!s) return False;
1610 while ((c = *s++)) {
1611 switch (c) {
1612 case UCS2_CHAR('*'):
1613 case UCS2_CHAR('?'):
1614 case UCS2_CHAR('<'):
1615 case UCS2_CHAR('>'):
1616 case UCS2_CHAR('"'):
1617 return True;
1620 return False;
1623 /*******************************************************************
1624 A wrapper that handles case sensitivity and the special handling
1625 of the ".." name.
1626 *******************************************************************/
1628 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1630 if (ISDOTDOT(string))
1631 string = ".";
1632 if (ISDOT(pattern))
1633 return False;
1635 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
1638 /*******************************************************************
1639 A wrapper that handles case sensitivity and the special handling
1640 of the ".." name. Varient that is only called by old search code which requires
1641 pattern translation.
1642 *******************************************************************/
1644 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
1646 if (ISDOTDOT(string))
1647 string = ".";
1648 if (ISDOT(pattern))
1649 return False;
1651 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
1654 /*******************************************************************
1655 A wrapper that handles a list of patters and calls mask_match()
1656 on each. Returns True if any of the patterns match.
1657 *******************************************************************/
1659 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
1661 while (listLen-- > 0) {
1662 if (mask_match(string, *list++, is_case_sensitive))
1663 return True;
1665 return False;
1668 /*********************************************************
1669 Recursive routine that is called by unix_wild_match.
1670 *********************************************************/
1672 static bool unix_do_match(const char *regexp, const char *str)
1674 const char *p;
1676 for( p = regexp; *p && *str; ) {
1678 switch(*p) {
1679 case '?':
1680 str++;
1681 p++;
1682 break;
1684 case '*':
1687 * Look for a character matching
1688 * the one after the '*'.
1690 p++;
1691 if(!*p)
1692 return true; /* Automatic match */
1693 while(*str) {
1695 while(*str && (*p != *str))
1696 str++;
1699 * Patch from weidel@multichart.de. In the case of the regexp
1700 * '*XX*' we want to ensure there are at least 2 'X' characters
1701 * in the string after the '*' for a match to be made.
1705 int matchcount=0;
1708 * Eat all the characters that match, but count how many there were.
1711 while(*str && (*p == *str)) {
1712 str++;
1713 matchcount++;
1717 * Now check that if the regexp had n identical characters that
1718 * matchcount had at least that many matches.
1721 while ( *(p+1) && (*(p+1) == *p)) {
1722 p++;
1723 matchcount--;
1726 if ( matchcount <= 0 )
1727 return false;
1730 str--; /* We've eaten the match char after the '*' */
1732 if(unix_do_match(p, str))
1733 return true;
1735 if(!*str)
1736 return false;
1737 else
1738 str++;
1740 return false;
1742 default:
1743 if(*str != *p)
1744 return false;
1745 str++;
1746 p++;
1747 break;
1751 if(!*p && !*str)
1752 return true;
1754 if (!*p && str[0] == '.' && str[1] == 0)
1755 return true;
1757 if (!*str && *p == '?') {
1758 while (*p == '?')
1759 p++;
1760 return(!*p);
1763 if(!*str && (*p == '*' && p[1] == '\0'))
1764 return true;
1766 return false;
1769 /*******************************************************************
1770 Simple case insensitive interface to a UNIX wildcard matcher.
1771 Returns True if match, False if not.
1772 *******************************************************************/
1774 bool unix_wild_match(const char *pattern, const char *string)
1776 TALLOC_CTX *ctx = talloc_stackframe();
1777 char *p2;
1778 char *s2;
1779 char *p;
1780 bool ret = false;
1782 p2 = talloc_strdup(ctx,pattern);
1783 s2 = talloc_strdup(ctx,string);
1784 if (!p2 || !s2) {
1785 TALLOC_FREE(ctx);
1786 return false;
1788 strlower_m(p2);
1789 strlower_m(s2);
1791 /* Remove any *? and ** from the pattern as they are meaningless */
1792 for(p = p2; *p; p++) {
1793 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1794 memmove(&p[1], &p[2], strlen(&p[2])+1);
1798 if (strequal(p2,"*")) {
1799 TALLOC_FREE(ctx);
1800 return true;
1803 ret = unix_do_match(p2, s2);
1804 TALLOC_FREE(ctx);
1805 return ret;
1808 /**********************************************************************
1809 Converts a name to a fully qualified domain name.
1810 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1811 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1812 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1813 ***********************************************************************/
1815 bool name_to_fqdn(fstring fqdn, const char *name)
1817 char *full = NULL;
1818 struct hostent *hp = gethostbyname(name);
1820 if (!hp || !hp->h_name || !*hp->h_name) {
1821 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1822 fstrcpy(fqdn, name);
1823 return false;
1826 /* Find out if the fqdn is returned as an alias
1827 * to cope with /etc/hosts files where the first
1828 * name is not the fqdn but the short name */
1829 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1830 int i;
1831 for (i = 0; hp->h_aliases[i]; i++) {
1832 if (strchr_m(hp->h_aliases[i], '.')) {
1833 full = hp->h_aliases[i];
1834 break;
1838 if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1839 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1840 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1841 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1842 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1843 full = hp->h_name;
1845 if (!full) {
1846 full = hp->h_name;
1849 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1850 fstrcpy(fqdn, full);
1851 return true;
1854 /**********************************************************************
1855 Append a DATA_BLOB to a talloc'ed object
1856 ***********************************************************************/
1858 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1860 size_t old_size = 0;
1861 char *result;
1863 if (blob.length == 0) {
1864 return buf;
1867 if (buf != NULL) {
1868 old_size = talloc_get_size(buf);
1871 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1872 if (result == NULL) {
1873 return NULL;
1876 memcpy(result + old_size, blob.data, blob.length);
1877 return result;
1880 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1882 switch (share_access & ~FILE_SHARE_DELETE) {
1883 case FILE_SHARE_NONE:
1884 return DENY_ALL;
1885 case FILE_SHARE_READ:
1886 return DENY_WRITE;
1887 case FILE_SHARE_WRITE:
1888 return DENY_READ;
1889 case FILE_SHARE_READ|FILE_SHARE_WRITE:
1890 return DENY_NONE;
1892 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
1893 return DENY_DOS;
1894 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
1895 return DENY_FCB;
1898 return (uint32)-1;
1901 pid_t procid_to_pid(const struct server_id *proc)
1903 return proc->pid;
1906 static uint32 my_vnn = NONCLUSTER_VNN;
1908 void set_my_vnn(uint32 vnn)
1910 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
1911 my_vnn = vnn;
1914 uint32 get_my_vnn(void)
1916 return my_vnn;
1919 static uint64_t my_unique_id = 0;
1921 void set_my_unique_id(uint64_t unique_id)
1923 my_unique_id = unique_id;
1926 struct server_id pid_to_procid(pid_t pid)
1928 struct server_id result;
1929 result.pid = pid;
1930 result.task_id = 0;
1931 result.unique_id = my_unique_id;
1932 result.vnn = my_vnn;
1933 return result;
1936 struct server_id procid_self(void)
1938 return pid_to_procid(sys_getpid());
1941 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
1943 if (p1->pid != p2->pid)
1944 return False;
1945 if (p1->task_id != p2->task_id)
1946 return False;
1947 if (p1->vnn != p2->vnn)
1948 return False;
1949 return True;
1952 bool cluster_id_equal(const struct server_id *id1,
1953 const struct server_id *id2)
1955 return procid_equal(id1, id2);
1958 bool procid_is_me(const struct server_id *pid)
1960 if (pid->pid != sys_getpid())
1961 return False;
1962 if (pid->task_id != 0)
1963 return False;
1964 if (pid->vnn != my_vnn)
1965 return False;
1966 return True;
1969 struct server_id interpret_pid(const char *pid_string)
1971 struct server_id result;
1972 unsigned long long pid;
1973 unsigned int vnn, task_id = 0;
1975 ZERO_STRUCT(result);
1977 /* We accept various forms with 1, 2 or 3 component forms
1978 * because the server_id_str() can print different forms, and
1979 * we want backwards compatibility for scripts that may call
1980 * smbclient. */
1981 if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
1982 result.vnn = vnn;
1983 result.pid = pid;
1984 result.task_id = task_id;
1985 } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
1986 result.vnn = vnn;
1987 result.pid = pid;
1988 result.task_id = 0;
1989 } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
1990 result.vnn = get_my_vnn();
1991 result.pid = pid;
1992 result.task_id = task_id;
1993 } else if (sscanf(pid_string, "%llu", &pid) == 1) {
1994 result.vnn = get_my_vnn();
1995 result.pid = pid;
1996 } else {
1997 result.vnn = NONCLUSTER_VNN;
1998 result.pid = (uint64_t)-1;
2000 return result;
2003 char *procid_str_static(const struct server_id *pid)
2005 return server_id_str(talloc_tos(), pid);
2008 bool procid_valid(const struct server_id *pid)
2010 return (pid->pid != (uint64_t)-1);
2013 bool procid_is_local(const struct server_id *pid)
2015 return pid->vnn == my_vnn;
2018 /****************************************************************
2019 Check if offset/length fit into bufsize. Should probably be
2020 merged with is_offset_safe, but this would require a rewrite
2021 of lanman.c. Later :-)
2022 ****************************************************************/
2024 bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
2026 if ((offset + length < offset) || (offset + length < length)) {
2027 /* wrap */
2028 return true;
2030 if ((offset > bufsize) || (offset + length > bufsize)) {
2031 /* overflow */
2032 return true;
2034 return false;
2037 /****************************************************************
2038 Check if an offset into a buffer is safe.
2039 If this returns True it's safe to indirect into the byte at
2040 pointer ptr+off.
2041 ****************************************************************/
2043 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2045 const char *end_base = buf_base + buf_len;
2046 char *end_ptr = ptr + off;
2048 if (!buf_base || !ptr) {
2049 return False;
2052 if (end_base < buf_base || end_ptr < ptr) {
2053 return False; /* wrap. */
2056 if (end_ptr < end_base) {
2057 return True;
2059 return False;
2062 /****************************************************************
2063 Return a safe pointer into a buffer, or NULL.
2064 ****************************************************************/
2066 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2068 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2069 ptr + off : NULL;
2072 /****************************************************************
2073 Return a safe pointer into a string within a buffer, or NULL.
2074 ****************************************************************/
2076 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2078 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2079 return NULL;
2081 /* Check if a valid string exists at this offset. */
2082 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2083 return NULL;
2085 return ptr + off;
2088 /****************************************************************
2089 Return an SVAL at a pointer, or failval if beyond the end.
2090 ****************************************************************/
2092 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2095 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2096 * NOT ptr[2].
2098 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2099 return failval;
2101 return SVAL(ptr,off);
2104 /****************************************************************
2105 Return an IVAL at a pointer, or failval if beyond the end.
2106 ****************************************************************/
2108 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2111 * Note we use off+3 here, not off+4 as IVAL accesses
2112 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2114 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2115 return failval;
2117 return IVAL(ptr,off);
2120 /****************************************************************
2121 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2122 call (they take care of winbind separator and other winbind specific settings).
2123 ****************************************************************/
2125 void split_domain_user(TALLOC_CTX *mem_ctx,
2126 const char *full_name,
2127 char **domain,
2128 char **user)
2130 const char *p = NULL;
2132 p = strchr_m(full_name, '\\');
2134 if (p != NULL) {
2135 *domain = talloc_strndup(mem_ctx, full_name,
2136 PTR_DIFF(p, full_name));
2137 *user = talloc_strdup(mem_ctx, p+1);
2138 } else {
2139 *domain = talloc_strdup(mem_ctx, "");
2140 *user = talloc_strdup(mem_ctx, full_name);
2144 /****************************************************************
2145 strip off leading '\\' from a hostname
2146 ****************************************************************/
2148 const char *strip_hostname(const char *s)
2150 if (!s) {
2151 return NULL;
2154 if (strlen_m(s) < 3) {
2155 return s;
2158 if (s[0] == '\\') s++;
2159 if (s[0] == '\\') s++;
2161 return s;
2164 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2165 struct tevent_context *ev,
2166 NTSTATUS *status)
2168 bool ret = tevent_req_poll(req, ev);
2169 if (!ret) {
2170 *status = map_nt_error_from_unix(errno);
2172 return ret;
2175 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2177 if (!NT_STATUS_IS_OK(err1)) {
2178 *result = err1;
2179 return true;
2181 if (!NT_STATUS_IS_OK(err2)) {
2182 *result = err2;
2183 return true;
2185 return false;
2188 int timeval_to_msec(struct timeval t)
2190 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2193 /*******************************************************************
2194 Check a given DOS pathname is valid for a share.
2195 ********************************************************************/
2197 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2199 char *ptr = NULL;
2201 if (!dos_pathname) {
2202 return NULL;
2205 ptr = talloc_strdup(ctx, dos_pathname);
2206 if (!ptr) {
2207 return NULL;
2209 /* Convert any '\' paths to '/' */
2210 unix_format(ptr);
2211 ptr = unix_clean_name(ctx, ptr);
2212 if (!ptr) {
2213 return NULL;
2216 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2217 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2218 ptr += 2;
2220 /* Only absolute paths allowed. */
2221 if (*ptr != '/')
2222 return NULL;
2224 return ptr;
2227 /*******************************************************************
2228 Return True if the filename is one of the special executable types.
2229 ********************************************************************/
2231 bool is_executable(const char *fname)
2233 if ((fname = strrchr_m(fname,'.'))) {
2234 if (strequal(fname,".com") ||
2235 strequal(fname,".dll") ||
2236 strequal(fname,".exe") ||
2237 strequal(fname,".sym")) {
2238 return True;
2241 return False;
2244 /****************************************************************************
2245 Open a file with a share mode - old openX method - map into NTCreate.
2246 ****************************************************************************/
2248 bool map_open_params_to_ntcreate(const char *smb_base_fname,
2249 int deny_mode, int open_func,
2250 uint32 *paccess_mask,
2251 uint32 *pshare_mode,
2252 uint32 *pcreate_disposition,
2253 uint32 *pcreate_options,
2254 uint32_t *pprivate_flags)
2256 uint32 access_mask;
2257 uint32 share_mode;
2258 uint32 create_disposition;
2259 uint32 create_options = FILE_NON_DIRECTORY_FILE;
2260 uint32_t private_flags = 0;
2262 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2263 "open_func = 0x%x\n",
2264 smb_base_fname, (unsigned int)deny_mode,
2265 (unsigned int)open_func ));
2267 /* Create the NT compatible access_mask. */
2268 switch (GET_OPENX_MODE(deny_mode)) {
2269 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
2270 case DOS_OPEN_RDONLY:
2271 access_mask = FILE_GENERIC_READ;
2272 break;
2273 case DOS_OPEN_WRONLY:
2274 access_mask = FILE_GENERIC_WRITE;
2275 break;
2276 case DOS_OPEN_RDWR:
2277 case DOS_OPEN_FCB:
2278 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
2279 break;
2280 default:
2281 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2282 (unsigned int)GET_OPENX_MODE(deny_mode)));
2283 return False;
2286 /* Create the NT compatible create_disposition. */
2287 switch (open_func) {
2288 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
2289 create_disposition = FILE_CREATE;
2290 break;
2292 case OPENX_FILE_EXISTS_OPEN:
2293 create_disposition = FILE_OPEN;
2294 break;
2296 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
2297 create_disposition = FILE_OPEN_IF;
2298 break;
2300 case OPENX_FILE_EXISTS_TRUNCATE:
2301 create_disposition = FILE_OVERWRITE;
2302 break;
2304 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
2305 create_disposition = FILE_OVERWRITE_IF;
2306 break;
2308 default:
2309 /* From samba4 - to be confirmed. */
2310 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
2311 create_disposition = FILE_CREATE;
2312 break;
2314 DEBUG(10,("map_open_params_to_ntcreate: bad "
2315 "open_func 0x%x\n", (unsigned int)open_func));
2316 return False;
2319 /* Create the NT compatible share modes. */
2320 switch (GET_DENY_MODE(deny_mode)) {
2321 case DENY_ALL:
2322 share_mode = FILE_SHARE_NONE;
2323 break;
2325 case DENY_WRITE:
2326 share_mode = FILE_SHARE_READ;
2327 break;
2329 case DENY_READ:
2330 share_mode = FILE_SHARE_WRITE;
2331 break;
2333 case DENY_NONE:
2334 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2335 break;
2337 case DENY_DOS:
2338 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
2339 if (is_executable(smb_base_fname)) {
2340 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2341 } else {
2342 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
2343 share_mode = FILE_SHARE_READ;
2344 } else {
2345 share_mode = FILE_SHARE_NONE;
2348 break;
2350 case DENY_FCB:
2351 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
2352 share_mode = FILE_SHARE_NONE;
2353 break;
2355 default:
2356 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2357 (unsigned int)GET_DENY_MODE(deny_mode) ));
2358 return False;
2361 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2362 "share_mode = 0x%x, create_disposition = 0x%x, "
2363 "create_options = 0x%x private_flags = 0x%x\n",
2364 smb_base_fname,
2365 (unsigned int)access_mask,
2366 (unsigned int)share_mode,
2367 (unsigned int)create_disposition,
2368 (unsigned int)create_options,
2369 (unsigned int)private_flags));
2371 if (paccess_mask) {
2372 *paccess_mask = access_mask;
2374 if (pshare_mode) {
2375 *pshare_mode = share_mode;
2377 if (pcreate_disposition) {
2378 *pcreate_disposition = create_disposition;
2380 if (pcreate_options) {
2381 *pcreate_options = create_options;
2383 if (pprivate_flags) {
2384 *pprivate_flags = private_flags;
2387 return True;
2392 void init_modules(void)
2394 /* FIXME: This can cause undefined symbol errors :
2395 * smb_register_vfs() isn't available in nmbd, for example */
2396 if(lp_preload_modules())
2397 smb_load_modules(lp_preload_modules());