Remove unused get_file_size() function.
[Samba/gebeck_regimport.git] / source3 / lib / util.c
blobb783c7e9c94e9b72a00ea80a64e9f326ddeef300
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 Show a smb message structure.
131 ********************************************************************/
133 void show_msg(const char *buf)
135 int i;
136 int bcc=0;
138 if (!DEBUGLVL(5))
139 return;
141 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
142 smb_len(buf),
143 (int)CVAL(buf,smb_com),
144 (int)CVAL(buf,smb_rcls),
145 (int)CVAL(buf,smb_reh),
146 (int)SVAL(buf,smb_err),
147 (int)CVAL(buf,smb_flg),
148 (int)SVAL(buf,smb_flg2)));
149 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
150 (int)SVAL(buf,smb_tid),
151 (int)SVAL(buf,smb_pid),
152 (int)SVAL(buf,smb_uid),
153 (int)SVAL(buf,smb_mid)));
154 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
156 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
157 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
158 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
160 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
162 DEBUGADD(5,("smb_bcc=%d\n",bcc));
164 if (DEBUGLEVEL < 10)
165 return;
167 if (DEBUGLEVEL < 50)
168 bcc = MIN(bcc, 512);
170 dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
173 /*******************************************************************
174 Setup only the byte count for a smb message.
175 ********************************************************************/
177 int set_message_bcc(char *buf,int num_bytes)
179 int num_words = CVAL(buf,smb_wct);
180 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
181 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
182 return (smb_size + num_words*2 + num_bytes);
185 /*******************************************************************
186 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
187 Return the bytes added
188 ********************************************************************/
190 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
192 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
193 uint8 *tmp;
195 if (!(tmp = talloc_realloc(NULL, *outbuf, uint8, newlen))) {
196 DEBUG(0, ("talloc failed\n"));
197 return -1;
199 *outbuf = tmp;
201 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
202 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
203 return blob.length;
206 /*******************************************************************
207 Reduce a file name, removing .. elements.
208 ********************************************************************/
210 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
212 char *p = NULL;
213 char *str = NULL;
215 DEBUG(3,("dos_clean_name [%s]\n",s));
217 /* remove any double slashes */
218 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
219 if (!str) {
220 return NULL;
223 /* Remove leading .\\ characters */
224 if(strncmp(str, ".\\", 2) == 0) {
225 trim_string(str, ".\\", NULL);
226 if(*str == 0) {
227 str = talloc_strdup(ctx, ".\\");
228 if (!str) {
229 return NULL;
234 while ((p = strstr_m(str,"\\..\\")) != NULL) {
235 char *s1;
237 *p = 0;
238 s1 = p+3;
240 if ((p=strrchr_m(str,'\\')) != NULL) {
241 *p = 0;
242 } else {
243 *str = 0;
245 str = talloc_asprintf(ctx,
246 "%s%s",
247 str,
248 s1);
249 if (!str) {
250 return NULL;
254 trim_string(str,NULL,"\\..");
255 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
258 /*******************************************************************
259 Reduce a file name, removing .. elements.
260 ********************************************************************/
262 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
264 char *p = NULL;
265 char *str = NULL;
267 DEBUG(3,("unix_clean_name [%s]\n",s));
269 /* remove any double slashes */
270 str = talloc_all_string_sub(ctx, s, "//","/");
271 if (!str) {
272 return NULL;
275 /* Remove leading ./ characters */
276 if(strncmp(str, "./", 2) == 0) {
277 trim_string(str, "./", NULL);
278 if(*str == 0) {
279 str = talloc_strdup(ctx, "./");
280 if (!str) {
281 return NULL;
286 while ((p = strstr_m(str,"/../")) != NULL) {
287 char *s1;
289 *p = 0;
290 s1 = p+3;
292 if ((p=strrchr_m(str,'/')) != NULL) {
293 *p = 0;
294 } else {
295 *str = 0;
297 str = talloc_asprintf(ctx,
298 "%s%s",
299 str,
300 s1);
301 if (!str) {
302 return NULL;
306 trim_string(str,NULL,"/..");
307 return talloc_all_string_sub(ctx, str, "/./", "/");
310 char *clean_name(TALLOC_CTX *ctx, const char *s)
312 char *str = dos_clean_name(ctx, s);
313 if (!str) {
314 return NULL;
316 return unix_clean_name(ctx, str);
319 /*******************************************************************
320 Write data into an fd at a given offset. Ignore seek errors.
321 ********************************************************************/
323 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
325 size_t total=0;
326 ssize_t ret;
328 if (pos == (SMB_OFF_T)-1) {
329 return write_data(fd, buffer, N);
331 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
332 while (total < N) {
333 ret = sys_pwrite(fd,buffer + total,N - total, pos);
334 if (ret == -1 && errno == ESPIPE) {
335 return write_data(fd, buffer + total,N - total);
337 if (ret == -1) {
338 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
339 return -1;
341 if (ret == 0) {
342 return total;
344 total += ret;
345 pos += ret;
347 return (ssize_t)total;
348 #else
349 /* Use lseek and write_data. */
350 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
351 if (errno != ESPIPE) {
352 return -1;
355 return write_data(fd, buffer, N);
356 #endif
360 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
361 struct event_context *ev_ctx,
362 bool parent_longlived)
364 NTSTATUS status = NT_STATUS_OK;
366 /* Reset the state of the random
367 * number generation system, so
368 * children do not get the same random
369 * numbers as each other */
370 set_need_random_reseed();
372 /* tdb needs special fork handling */
373 if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
374 DEBUG(0,("tdb_reopen_all failed.\n"));
375 status = NT_STATUS_OPEN_FAILED;
376 goto done;
379 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
380 smb_panic(__location__ ": Failed to re-initialise event context");
383 if (msg_ctx) {
385 * For clustering, we need to re-init our ctdbd connection after the
386 * fork
388 status = messaging_reinit(msg_ctx);
389 if (!NT_STATUS_IS_OK(status)) {
390 DEBUG(0,("messaging_reinit() failed: %s\n",
391 nt_errstr(status)));
394 done:
395 return status;
398 /****************************************************************************
399 (Hopefully) efficient array append.
400 ****************************************************************************/
402 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
403 void *element, void *_array, uint32 *num_elements,
404 ssize_t *array_size)
406 void **array = (void **)_array;
408 if (*array_size < 0) {
409 return;
412 if (*array == NULL) {
413 if (*array_size == 0) {
414 *array_size = 128;
417 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
418 goto error;
421 *array = TALLOC(mem_ctx, element_size * (*array_size));
422 if (*array == NULL) {
423 goto error;
427 if (*num_elements == *array_size) {
428 *array_size *= 2;
430 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
431 goto error;
434 *array = TALLOC_REALLOC(mem_ctx, *array,
435 element_size * (*array_size));
437 if (*array == NULL) {
438 goto error;
442 memcpy((char *)(*array) + element_size*(*num_elements),
443 element, element_size);
444 *num_elements += 1;
446 return;
448 error:
449 *num_elements = 0;
450 *array_size = -1;
453 /****************************************************************************
454 Get my own domain name, or "" if we have none.
455 ****************************************************************************/
457 char *get_mydnsdomname(TALLOC_CTX *ctx)
459 const char *domname;
460 char *p;
462 domname = get_mydnsfullname();
463 if (!domname) {
464 return NULL;
467 p = strchr_m(domname, '.');
468 if (p) {
469 p++;
470 return talloc_strdup(ctx, p);
471 } else {
472 return talloc_strdup(ctx, "");
476 /****************************************************************************
477 Interpret a protocol description string, with a default.
478 ****************************************************************************/
480 int interpret_protocol(const char *str,int def)
482 if (strequal(str,"NT1"))
483 return(PROTOCOL_NT1);
484 if (strequal(str,"LANMAN2"))
485 return(PROTOCOL_LANMAN2);
486 if (strequal(str,"LANMAN1"))
487 return(PROTOCOL_LANMAN1);
488 if (strequal(str,"CORE"))
489 return(PROTOCOL_CORE);
490 if (strequal(str,"COREPLUS"))
491 return(PROTOCOL_COREPLUS);
492 if (strequal(str,"CORE+"))
493 return(PROTOCOL_COREPLUS);
495 DEBUG(0,("Unrecognised protocol level %s\n",str));
497 return(def);
501 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
502 /******************************************************************
503 Remove any mount options such as -rsize=2048,wsize=2048 etc.
504 Based on a fix from <Thomas.Hepper@icem.de>.
505 Returns a malloc'ed string.
506 *******************************************************************/
508 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
510 if (*str == '-') {
511 const char *p = str;
512 while(*p && !isspace(*p))
513 p++;
514 while(*p && isspace(*p))
515 p++;
516 if(*p) {
517 return talloc_strdup(ctx, p);
520 return NULL;
523 /*******************************************************************
524 Patch from jkf@soton.ac.uk
525 Split Luke's automount_server into YP lookup and string splitter
526 so can easily implement automount_path().
527 Returns a malloc'ed string.
528 *******************************************************************/
530 #ifdef WITH_NISPLUS_HOME
531 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
533 char *value = NULL;
535 char *nis_map = (char *)lp_nis_home_map_name();
537 char buffer[NIS_MAXATTRVAL + 1];
538 nis_result *result;
539 nis_object *object;
540 entry_obj *entry;
542 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
543 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
545 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
546 if (result->status != NIS_SUCCESS) {
547 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
548 } else {
549 object = result->objects.objects_val;
550 if (object->zo_data.zo_type == ENTRY_OBJ) {
551 entry = &object->zo_data.objdata_u.en_data;
552 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
553 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
555 value = talloc_strdup(ctx,
556 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
557 if (!value) {
558 nis_freeresult(result);
559 return NULL;
561 value = talloc_string_sub(ctx,
562 value,
563 "&",
564 user_name);
568 nis_freeresult(result);
570 if (value) {
571 value = strip_mount_options(ctx, value);
572 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
573 user_name, value));
575 return value;
577 #else /* WITH_NISPLUS_HOME */
579 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
581 char *value = NULL;
583 int nis_error; /* returned by yp all functions */
584 char *nis_result; /* yp_match inits this */
585 int nis_result_len; /* and set this */
586 char *nis_domain; /* yp_get_default_domain inits this */
587 char *nis_map = (char *)lp_nis_home_map_name();
589 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
590 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
591 return NULL;
594 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
596 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
597 strlen(user_name), &nis_result,
598 &nis_result_len)) == 0) {
599 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
600 nis_result[nis_result_len] = '\0';
602 value = talloc_strdup(ctx, nis_result);
603 if (!value) {
604 return NULL;
606 value = strip_mount_options(ctx, value);
607 } else if(nis_error == YPERR_KEY) {
608 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
609 user_name, nis_map));
610 DEBUG(3, ("using defaults for server and home directory\n"));
611 } else {
612 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
613 yperr_string(nis_error), user_name, nis_map));
616 if (value) {
617 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
619 return value;
621 #endif /* WITH_NISPLUS_HOME */
622 #endif
624 /****************************************************************************
625 Check if a process exists. Does this work on all unixes?
626 ****************************************************************************/
628 bool process_exists(const struct server_id pid)
630 if (procid_is_me(&pid)) {
631 return True;
634 if (procid_is_local(&pid)) {
635 return (kill(pid.pid,0) == 0 || errno != ESRCH);
638 #ifdef CLUSTER_SUPPORT
639 return ctdbd_process_exists(messaging_ctdbd_connection(),
640 pid.vnn, pid.pid);
641 #else
642 return False;
643 #endif
646 bool processes_exist(const struct server_id *pids, int num_pids,
647 bool *results)
649 struct server_id *remote_pids = NULL;
650 int *remote_idx = NULL;
651 bool *remote_results = NULL;
652 int i, num_remote_pids;
653 bool result = false;
655 remote_pids = talloc_array(talloc_tos(), struct server_id, num_pids);
656 if (remote_pids == NULL) {
657 goto fail;
659 remote_idx = talloc_array(talloc_tos(), int, num_pids);
660 if (remote_idx == NULL) {
661 goto fail;
663 remote_results = talloc_array(talloc_tos(), bool, num_pids);
664 if (remote_results == NULL) {
665 goto fail;
668 num_remote_pids = 0;
670 for (i=0; i<num_pids; i++) {
671 if (procid_is_me(&pids[i])) {
672 results[i] = true;
673 continue;
675 if (procid_is_local(&pids[i])) {
676 results[i] = ((kill(pids[i].pid,0) == 0) ||
677 (errno != ESRCH));
678 continue;
681 remote_pids[num_remote_pids] = pids[i];
682 remote_idx[num_remote_pids] = i;
683 num_remote_pids += 1;
686 if (num_remote_pids != 0) {
687 #ifdef CLUSTER_SUPPORT
688 if (!ctdb_processes_exist(messaging_ctdbd_connection(),
689 remote_pids, num_remote_pids,
690 remote_results)) {
691 goto fail;
693 #else
694 for (i=0; i<num_remote_pids; i++) {
695 remote_results[i] = false;
697 #endif
699 for (i=0; i<num_remote_pids; i++) {
700 results[remote_idx[i]] = remote_results[i];
704 result = true;
705 fail:
706 TALLOC_FREE(remote_results);
707 TALLOC_FREE(remote_idx);
708 TALLOC_FREE(remote_pids);
709 return result;
712 /*******************************************************************
713 Convert a uid into a user name.
714 ********************************************************************/
716 const char *uidtoname(uid_t uid)
718 TALLOC_CTX *ctx = talloc_tos();
719 char *name = NULL;
720 struct passwd *pass = NULL;
722 pass = getpwuid_alloc(ctx,uid);
723 if (pass) {
724 name = talloc_strdup(ctx,pass->pw_name);
725 TALLOC_FREE(pass);
726 } else {
727 name = talloc_asprintf(ctx,
728 "%ld",
729 (long int)uid);
731 return name;
734 /*******************************************************************
735 Convert a gid into a group name.
736 ********************************************************************/
738 char *gidtoname(gid_t gid)
740 struct group *grp;
742 grp = getgrgid(gid);
743 if (grp) {
744 return talloc_strdup(talloc_tos(), grp->gr_name);
746 else {
747 return talloc_asprintf(talloc_tos(),
748 "%d",
749 (int)gid);
753 /*******************************************************************
754 Convert a user name into a uid.
755 ********************************************************************/
757 uid_t nametouid(const char *name)
759 struct passwd *pass;
760 char *p;
761 uid_t u;
763 pass = Get_Pwnam_alloc(talloc_tos(), name);
764 if (pass) {
765 u = pass->pw_uid;
766 TALLOC_FREE(pass);
767 return u;
770 u = (uid_t)strtol(name, &p, 0);
771 if ((p != name) && (*p == '\0'))
772 return u;
774 return (uid_t)-1;
777 /*******************************************************************
778 Convert a name to a gid_t if possible. Return -1 if not a group.
779 ********************************************************************/
781 gid_t nametogid(const char *name)
783 struct group *grp;
784 char *p;
785 gid_t g;
787 g = (gid_t)strtol(name, &p, 0);
788 if ((p != name) && (*p == '\0'))
789 return g;
791 grp = sys_getgrnam(name);
792 if (grp)
793 return(grp->gr_gid);
794 return (gid_t)-1;
797 /*******************************************************************
798 Something really nasty happened - panic !
799 ********************************************************************/
801 void smb_panic_s3(const char *why)
803 char *cmd;
804 int result;
806 DEBUG(0,("PANIC (pid %llu): %s\n",
807 (unsigned long long)sys_getpid(), why));
808 log_stack_trace();
810 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
812 * Make sure all children can attach a debugger.
814 prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
815 #endif
817 cmd = lp_panic_action();
818 if (cmd && *cmd) {
819 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
820 result = system(cmd);
822 if (result == -1)
823 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
824 strerror(errno)));
825 else
826 DEBUG(0, ("smb_panic(): action returned status %d\n",
827 WEXITSTATUS(result)));
830 dump_core();
833 /*******************************************************************
834 Print a backtrace of the stack to the debug log. This function
835 DELIBERATELY LEAKS MEMORY. The expectation is that you should
836 exit shortly after calling it.
837 ********************************************************************/
839 #ifdef HAVE_LIBUNWIND_H
840 #include <libunwind.h>
841 #endif
843 #ifdef HAVE_EXECINFO_H
844 #include <execinfo.h>
845 #endif
847 #ifdef HAVE_LIBEXC_H
848 #include <libexc.h>
849 #endif
851 void log_stack_trace(void)
853 #ifdef HAVE_LIBUNWIND
854 /* Try to use libunwind before any other technique since on ia64
855 * libunwind correctly walks the stack in more circumstances than
856 * backtrace.
858 unw_cursor_t cursor;
859 unw_context_t uc;
860 unsigned i = 0;
862 char procname[256];
863 unw_word_t ip, sp, off;
865 procname[sizeof(procname) - 1] = '\0';
867 if (unw_getcontext(&uc) != 0) {
868 goto libunwind_failed;
871 if (unw_init_local(&cursor, &uc) != 0) {
872 goto libunwind_failed;
875 DEBUG(0, ("BACKTRACE:\n"));
877 do {
878 ip = sp = 0;
879 unw_get_reg(&cursor, UNW_REG_IP, &ip);
880 unw_get_reg(&cursor, UNW_REG_SP, &sp);
882 switch (unw_get_proc_name(&cursor,
883 procname, sizeof(procname) - 1, &off) ) {
884 case 0:
885 /* Name found. */
886 case -UNW_ENOMEM:
887 /* Name truncated. */
888 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
889 i, procname, (long long)off,
890 (long long)ip, (long long) sp));
891 break;
892 default:
893 /* case -UNW_ENOINFO: */
894 /* case -UNW_EUNSPEC: */
895 /* No symbol name found. */
896 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
897 i, "<unknown symbol>",
898 (long long)ip, (long long) sp));
900 ++i;
901 } while (unw_step(&cursor) > 0);
903 return;
905 libunwind_failed:
906 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
908 #elif HAVE_BACKTRACE_SYMBOLS
909 void *backtrace_stack[BACKTRACE_STACK_SIZE];
910 size_t backtrace_size;
911 char **backtrace_strings;
913 /* get the backtrace (stack frames) */
914 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
915 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
917 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
918 (unsigned long)backtrace_size));
920 if (backtrace_strings) {
921 int i;
923 for (i = 0; i < backtrace_size; i++)
924 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
926 /* Leak the backtrace_strings, rather than risk what free() might do */
929 #elif HAVE_LIBEXC
931 /* The IRIX libexc library provides an API for unwinding the stack. See
932 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
933 * since we are about to abort anyway, it hardly matters.
936 #define NAMESIZE 32 /* Arbitrary */
938 __uint64_t addrs[BACKTRACE_STACK_SIZE];
939 char * names[BACKTRACE_STACK_SIZE];
940 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
942 int i;
943 int levels;
945 ZERO_ARRAY(addrs);
946 ZERO_ARRAY(names);
947 ZERO_ARRAY(namebuf);
949 /* We need to be root so we can open our /proc entry to walk
950 * our stack. It also helps when we want to dump core.
952 become_root();
954 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
955 names[i] = namebuf + (i * NAMESIZE);
958 levels = trace_back_stack(0, addrs, names,
959 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
961 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
962 for (i = 0; i < levels; i++) {
963 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
965 #undef NAMESIZE
967 #else
968 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
969 #endif
972 /*******************************************************************
973 A readdir wrapper which just returns the file name.
974 ********************************************************************/
976 const char *readdirname(SMB_STRUCT_DIR *p)
978 SMB_STRUCT_DIRENT *ptr;
979 char *dname;
981 if (!p)
982 return(NULL);
984 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
985 if (!ptr)
986 return(NULL);
988 dname = ptr->d_name;
990 #ifdef NEXT2
991 if (telldir(p) < 0)
992 return(NULL);
993 #endif
995 #ifdef HAVE_BROKEN_READDIR_NAME
996 /* using /usr/ucb/cc is BAD */
997 dname = dname - 2;
998 #endif
1000 return talloc_strdup(talloc_tos(), dname);
1003 /*******************************************************************
1004 Utility function used to decide if the last component
1005 of a path matches a (possibly wildcarded) entry in a namelist.
1006 ********************************************************************/
1008 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1010 const char *last_component;
1012 /* if we have no list it's obviously not in the path */
1013 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1014 return False;
1017 DEBUG(8, ("is_in_path: %s\n", name));
1019 /* Get the last component of the unix name. */
1020 last_component = strrchr_m(name, '/');
1021 if (!last_component) {
1022 last_component = name;
1023 } else {
1024 last_component++; /* Go past '/' */
1027 for(; namelist->name != NULL; namelist++) {
1028 if(namelist->is_wild) {
1029 if (mask_match(last_component, namelist->name, case_sensitive)) {
1030 DEBUG(8,("is_in_path: mask match succeeded\n"));
1031 return True;
1033 } else {
1034 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1035 (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
1036 DEBUG(8,("is_in_path: match succeeded\n"));
1037 return True;
1041 DEBUG(8,("is_in_path: match not found\n"));
1042 return False;
1045 /*******************************************************************
1046 Strip a '/' separated list into an array of
1047 name_compare_enties structures suitable for
1048 passing to is_in_path(). We do this for
1049 speed so we can pre-parse all the names in the list
1050 and don't do it for each call to is_in_path().
1051 We also check if the entry contains a wildcard to
1052 remove a potentially expensive call to mask_match
1053 if possible.
1054 ********************************************************************/
1056 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1058 char *name_end;
1059 char *namelist;
1060 char *nameptr;
1061 int num_entries = 0;
1062 int i;
1064 (*ppname_array) = NULL;
1066 if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0')))
1067 return;
1069 namelist = talloc_strdup(talloc_tos(), namelist_in);
1070 if (namelist == NULL) {
1071 DEBUG(0,("set_namearray: talloc fail\n"));
1072 return;
1074 nameptr = namelist;
1076 /* We need to make two passes over the string. The
1077 first to count the number of elements, the second
1078 to split it.
1081 while(*nameptr) {
1082 if ( *nameptr == '/' ) {
1083 /* cope with multiple (useless) /s) */
1084 nameptr++;
1085 continue;
1087 /* anything left? */
1088 if ( *nameptr == '\0' )
1089 break;
1091 /* find the next '/' or consume remaining */
1092 name_end = strchr_m(nameptr, '/');
1093 if (name_end == NULL)
1094 name_end = (char *)nameptr + strlen(nameptr);
1096 /* next segment please */
1097 nameptr = name_end + 1;
1098 num_entries++;
1101 if(num_entries == 0) {
1102 talloc_free(namelist);
1103 return;
1106 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1107 DEBUG(0,("set_namearray: malloc fail\n"));
1108 talloc_free(namelist);
1109 return;
1112 /* Now copy out the names */
1113 nameptr = namelist;
1114 i = 0;
1115 while(*nameptr) {
1116 if ( *nameptr == '/' ) {
1117 /* cope with multiple (useless) /s) */
1118 nameptr++;
1119 continue;
1121 /* anything left? */
1122 if ( *nameptr == '\0' )
1123 break;
1125 /* find the next '/' or consume remaining */
1126 name_end = strchr_m(nameptr, '/');
1127 if (name_end)
1128 *name_end = '\0';
1129 else
1130 name_end = nameptr + strlen(nameptr);
1132 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1133 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1134 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1135 talloc_free(namelist);
1136 return;
1139 /* next segment please */
1140 nameptr = name_end + 1;
1141 i++;
1144 (*ppname_array)[i].name = NULL;
1146 talloc_free(namelist);
1147 return;
1150 #undef DBGC_CLASS
1151 #define DBGC_CLASS DBGC_LOCKING
1153 /****************************************************************************
1154 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1155 is dealt with in posix.c
1156 Returns True if we have information regarding this lock region (and returns
1157 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1158 ****************************************************************************/
1160 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1162 SMB_STRUCT_FLOCK lock;
1163 int ret;
1165 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1166 fd,(double)*poffset,(double)*pcount,*ptype));
1168 lock.l_type = *ptype;
1169 lock.l_whence = SEEK_SET;
1170 lock.l_start = *poffset;
1171 lock.l_len = *pcount;
1172 lock.l_pid = 0;
1174 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1176 if (ret == -1) {
1177 int sav = errno;
1178 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1179 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1180 errno = sav;
1181 return False;
1184 *ptype = lock.l_type;
1185 *poffset = lock.l_start;
1186 *pcount = lock.l_len;
1187 *ppid = lock.l_pid;
1189 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1190 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1191 return True;
1194 #undef DBGC_CLASS
1195 #define DBGC_CLASS DBGC_ALL
1197 /*******************************************************************
1198 Is the name specified one of my netbios names.
1199 Returns true if it is equal, false otherwise.
1200 ********************************************************************/
1202 bool is_myname(const char *s)
1204 int n;
1205 bool ret = False;
1207 for (n=0; my_netbios_names(n); n++) {
1208 if (strequal(my_netbios_names(n), s)) {
1209 ret=True;
1210 break;
1213 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1214 return(ret);
1217 /*******************************************************************
1218 Is the name specified our workgroup/domain.
1219 Returns true if it is equal, false otherwise.
1220 ********************************************************************/
1222 bool is_myworkgroup(const char *s)
1224 bool ret = False;
1226 if (strequal(s, lp_workgroup())) {
1227 ret=True;
1230 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1231 return(ret);
1234 /*******************************************************************
1235 we distinguish between 2K and XP by the "Native Lan Manager" string
1236 WinXP => "Windows 2002 5.1"
1237 WinXP 64bit => "Windows XP 5.2"
1238 Win2k => "Windows 2000 5.0"
1239 NT4 => "Windows NT 4.0"
1240 Win9x => "Windows 4.0"
1241 Windows 2003 doesn't set the native lan manager string but
1242 they do set the domain to "Windows 2003 5.2" (probably a bug).
1243 ********************************************************************/
1245 void ra_lanman_string( const char *native_lanman )
1247 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1248 set_remote_arch( RA_WINXP );
1249 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1250 set_remote_arch( RA_WINXP64 );
1251 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1252 set_remote_arch( RA_WIN2K3 );
1255 static const char *remote_arch_str;
1257 const char *get_remote_arch_str(void)
1259 if (!remote_arch_str) {
1260 return "UNKNOWN";
1262 return remote_arch_str;
1265 /*******************************************************************
1266 Set the horrid remote_arch string based on an enum.
1267 ********************************************************************/
1269 void set_remote_arch(enum remote_arch_types type)
1271 ra_type = type;
1272 switch( type ) {
1273 case RA_WFWG:
1274 remote_arch_str = "WfWg";
1275 break;
1276 case RA_OS2:
1277 remote_arch_str = "OS2";
1278 break;
1279 case RA_WIN95:
1280 remote_arch_str = "Win95";
1281 break;
1282 case RA_WINNT:
1283 remote_arch_str = "WinNT";
1284 break;
1285 case RA_WIN2K:
1286 remote_arch_str = "Win2K";
1287 break;
1288 case RA_WINXP:
1289 remote_arch_str = "WinXP";
1290 break;
1291 case RA_WINXP64:
1292 remote_arch_str = "WinXP64";
1293 break;
1294 case RA_WIN2K3:
1295 remote_arch_str = "Win2K3";
1296 break;
1297 case RA_VISTA:
1298 remote_arch_str = "Vista";
1299 break;
1300 case RA_SAMBA:
1301 remote_arch_str = "Samba";
1302 break;
1303 case RA_CIFSFS:
1304 remote_arch_str = "CIFSFS";
1305 break;
1306 case RA_OSX:
1307 remote_arch_str = "OSX";
1308 break;
1309 default:
1310 ra_type = RA_UNKNOWN;
1311 remote_arch_str = "UNKNOWN";
1312 break;
1315 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1316 remote_arch_str));
1319 /*******************************************************************
1320 Get the remote_arch type.
1321 ********************************************************************/
1323 enum remote_arch_types get_remote_arch(void)
1325 return ra_type;
1328 const char *tab_depth(int level, int depth)
1330 if( CHECK_DEBUGLVL(level) ) {
1331 dbgtext("%*s", depth*4, "");
1333 return "";
1336 /*****************************************************************************
1337 Provide a checksum on a string
1339 Input: s - the null-terminated character string for which the checksum
1340 will be calculated.
1342 Output: The checksum value calculated for s.
1343 *****************************************************************************/
1345 int str_checksum(const char *s)
1347 if (s == NULL)
1348 return 0;
1349 return hash(s, strlen(s), 0);
1352 /*****************************************************************
1353 Zero a memory area then free it. Used to catch bugs faster.
1354 *****************************************************************/
1356 void zero_free(void *p, size_t size)
1358 memset(p, 0, size);
1359 SAFE_FREE(p);
1362 /*****************************************************************
1363 Set our open file limit to a requested max and return the limit.
1364 *****************************************************************/
1366 int set_maxfiles(int requested_max)
1368 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1369 struct rlimit rlp;
1370 int saved_current_limit;
1372 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1373 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1374 strerror(errno) ));
1375 /* just guess... */
1376 return requested_max;
1380 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1381 * account for the extra fd we need
1382 * as well as the log files and standard
1383 * handles etc. Save the limit we want to set in case
1384 * we are running on an OS that doesn't support this limit (AIX)
1385 * which always returns RLIM_INFINITY for rlp.rlim_max.
1388 /* Try raising the hard (max) limit to the requested amount. */
1390 #if defined(RLIM_INFINITY)
1391 if (rlp.rlim_max != RLIM_INFINITY) {
1392 int orig_max = rlp.rlim_max;
1394 if ( rlp.rlim_max < requested_max )
1395 rlp.rlim_max = requested_max;
1397 /* This failing is not an error - many systems (Linux) don't
1398 support our default request of 10,000 open files. JRA. */
1400 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1401 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1402 (int)rlp.rlim_max, strerror(errno) ));
1404 /* Set failed - restore original value from get. */
1405 rlp.rlim_max = orig_max;
1408 #endif
1410 /* Now try setting the soft (current) limit. */
1412 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1414 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1415 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1416 (int)rlp.rlim_cur, strerror(errno) ));
1417 /* just guess... */
1418 return saved_current_limit;
1421 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1422 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1423 strerror(errno) ));
1424 /* just guess... */
1425 return saved_current_limit;
1428 #if defined(RLIM_INFINITY)
1429 if(rlp.rlim_cur == RLIM_INFINITY)
1430 return saved_current_limit;
1431 #endif
1433 if((int)rlp.rlim_cur > saved_current_limit)
1434 return saved_current_limit;
1436 return rlp.rlim_cur;
1437 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1439 * No way to know - just guess...
1441 return requested_max;
1442 #endif
1445 /*****************************************************************
1446 malloc that aborts with smb_panic on fail or zero size.
1447 *****************************************************************/
1449 void *smb_xmalloc_array(size_t size, unsigned int count)
1451 void *p;
1452 if (size == 0) {
1453 smb_panic("smb_xmalloc_array: called with zero size");
1455 if (count >= MAX_ALLOC_SIZE/size) {
1456 smb_panic("smb_xmalloc_array: alloc size too large");
1458 if ((p = SMB_MALLOC(size*count)) == NULL) {
1459 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1460 (unsigned long)size, (unsigned long)count));
1461 smb_panic("smb_xmalloc_array: malloc failed");
1463 return p;
1467 vasprintf that aborts on malloc fail
1470 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1472 int n;
1473 va_list ap2;
1475 va_copy(ap2, ap);
1477 n = vasprintf(ptr, format, ap2);
1478 va_end(ap2);
1479 if (n == -1 || ! *ptr) {
1480 smb_panic("smb_xvasprintf: out of memory");
1482 return n;
1485 /*****************************************************************
1486 Get local hostname and cache result.
1487 *****************************************************************/
1489 char *myhostname(void)
1491 static char *ret;
1492 if (ret == NULL) {
1493 ret = get_myname(NULL);
1495 return ret;
1498 /*****************************************************************
1499 Get local hostname and cache result.
1500 *****************************************************************/
1502 char *myhostname_upper(void)
1504 char *name;
1505 static char *ret;
1506 if (ret == NULL) {
1507 name = get_myname(talloc_tos());
1508 ret = strupper_talloc(NULL, name);
1509 talloc_free(name);
1511 return ret;
1515 * @brief Returns an absolute path to a file concatenating the provided
1516 * @a rootpath and @a basename
1518 * @param name Filename, relative to @a rootpath
1520 * @retval Pointer to a string containing the full path.
1523 static char *xx_path(const char *name, const char *rootpath)
1525 char *fname = NULL;
1527 fname = talloc_strdup(talloc_tos(), rootpath);
1528 if (!fname) {
1529 return NULL;
1531 trim_string(fname,"","/");
1533 if (!directory_exist(fname)) {
1534 if (!mkdir(fname,0755))
1535 DEBUG(1, ("Unable to create directory %s for file %s. "
1536 "Error was %s\n", fname, name, strerror(errno)));
1539 return talloc_asprintf(talloc_tos(),
1540 "%s/%s",
1541 fname,
1542 name);
1546 * @brief Returns an absolute path to a file in the Samba lock directory.
1548 * @param name File to find, relative to LOCKDIR.
1550 * @retval Pointer to a talloc'ed string containing the full path.
1553 char *lock_path(const char *name)
1555 return xx_path(name, lp_lockdir());
1559 * @brief Returns an absolute path to a file in the Samba pid directory.
1561 * @param name File to find, relative to PIDDIR.
1563 * @retval Pointer to a talloc'ed string containing the full path.
1566 char *pid_path(const char *name)
1568 return xx_path(name, lp_piddir());
1572 * @brief Returns an absolute path to a file in the Samba state directory.
1574 * @param name File to find, relative to STATEDIR.
1576 * @retval Pointer to a talloc'ed string containing the full path.
1579 char *state_path(const char *name)
1581 return xx_path(name, lp_statedir());
1585 * @brief Returns an absolute path to a file in the Samba cache directory.
1587 * @param name File to find, relative to CACHEDIR.
1589 * @retval Pointer to a talloc'ed string containing the full path.
1592 char *cache_path(const char *name)
1594 return xx_path(name, lp_cachedir());
1597 /*******************************************************************
1598 Given a filename - get its directory name
1599 ********************************************************************/
1601 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1602 const char **name)
1604 char *p;
1605 ptrdiff_t len;
1607 p = strrchr_m(dir, '/'); /* Find final '/', if any */
1609 if (p == NULL) {
1610 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1611 return False;
1613 if (name) {
1614 *name = dir;
1616 return True;
1619 len = p-dir;
1621 if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
1622 return False;
1624 (*parent)[len] = '\0';
1626 if (name) {
1627 *name = p+1;
1629 return True;
1632 /*******************************************************************
1633 Determine if a pattern contains any Microsoft wildcard characters.
1634 *******************************************************************/
1636 bool ms_has_wild(const char *s)
1638 char c;
1640 if (lp_posix_pathnames()) {
1641 /* With posix pathnames no characters are wild. */
1642 return False;
1645 while ((c = *s++)) {
1646 switch (c) {
1647 case '*':
1648 case '?':
1649 case '<':
1650 case '>':
1651 case '"':
1652 return True;
1655 return False;
1658 bool ms_has_wild_w(const smb_ucs2_t *s)
1660 smb_ucs2_t c;
1661 if (!s) return False;
1662 while ((c = *s++)) {
1663 switch (c) {
1664 case UCS2_CHAR('*'):
1665 case UCS2_CHAR('?'):
1666 case UCS2_CHAR('<'):
1667 case UCS2_CHAR('>'):
1668 case UCS2_CHAR('"'):
1669 return True;
1672 return False;
1675 /*******************************************************************
1676 A wrapper that handles case sensitivity and the special handling
1677 of the ".." name.
1678 *******************************************************************/
1680 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1682 if (ISDOTDOT(string))
1683 string = ".";
1684 if (ISDOT(pattern))
1685 return False;
1687 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
1690 /*******************************************************************
1691 A wrapper that handles case sensitivity and the special handling
1692 of the ".." name. Varient that is only called by old search code which requires
1693 pattern translation.
1694 *******************************************************************/
1696 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
1698 if (ISDOTDOT(string))
1699 string = ".";
1700 if (ISDOT(pattern))
1701 return False;
1703 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
1706 /*******************************************************************
1707 A wrapper that handles a list of patters and calls mask_match()
1708 on each. Returns True if any of the patterns match.
1709 *******************************************************************/
1711 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
1713 while (listLen-- > 0) {
1714 if (mask_match(string, *list++, is_case_sensitive))
1715 return True;
1717 return False;
1720 /*********************************************************
1721 Recursive routine that is called by unix_wild_match.
1722 *********************************************************/
1724 static bool unix_do_match(const char *regexp, const char *str)
1726 const char *p;
1728 for( p = regexp; *p && *str; ) {
1730 switch(*p) {
1731 case '?':
1732 str++;
1733 p++;
1734 break;
1736 case '*':
1739 * Look for a character matching
1740 * the one after the '*'.
1742 p++;
1743 if(!*p)
1744 return true; /* Automatic match */
1745 while(*str) {
1747 while(*str && (*p != *str))
1748 str++;
1751 * Patch from weidel@multichart.de. In the case of the regexp
1752 * '*XX*' we want to ensure there are at least 2 'X' characters
1753 * in the string after the '*' for a match to be made.
1757 int matchcount=0;
1760 * Eat all the characters that match, but count how many there were.
1763 while(*str && (*p == *str)) {
1764 str++;
1765 matchcount++;
1769 * Now check that if the regexp had n identical characters that
1770 * matchcount had at least that many matches.
1773 while ( *(p+1) && (*(p+1) == *p)) {
1774 p++;
1775 matchcount--;
1778 if ( matchcount <= 0 )
1779 return false;
1782 str--; /* We've eaten the match char after the '*' */
1784 if(unix_do_match(p, str))
1785 return true;
1787 if(!*str)
1788 return false;
1789 else
1790 str++;
1792 return false;
1794 default:
1795 if(*str != *p)
1796 return false;
1797 str++;
1798 p++;
1799 break;
1803 if(!*p && !*str)
1804 return true;
1806 if (!*p && str[0] == '.' && str[1] == 0)
1807 return true;
1809 if (!*str && *p == '?') {
1810 while (*p == '?')
1811 p++;
1812 return(!*p);
1815 if(!*str && (*p == '*' && p[1] == '\0'))
1816 return true;
1818 return false;
1821 /*******************************************************************
1822 Simple case insensitive interface to a UNIX wildcard matcher.
1823 Returns True if match, False if not.
1824 *******************************************************************/
1826 bool unix_wild_match(const char *pattern, const char *string)
1828 TALLOC_CTX *ctx = talloc_stackframe();
1829 char *p2;
1830 char *s2;
1831 char *p;
1832 bool ret = false;
1834 p2 = talloc_strdup(ctx,pattern);
1835 s2 = talloc_strdup(ctx,string);
1836 if (!p2 || !s2) {
1837 TALLOC_FREE(ctx);
1838 return false;
1840 strlower_m(p2);
1841 strlower_m(s2);
1843 /* Remove any *? and ** from the pattern as they are meaningless */
1844 for(p = p2; *p; p++) {
1845 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1846 memmove(&p[1], &p[2], strlen(&p[2])+1);
1850 if (strequal(p2,"*")) {
1851 TALLOC_FREE(ctx);
1852 return true;
1855 ret = unix_do_match(p2, s2);
1856 TALLOC_FREE(ctx);
1857 return ret;
1860 /**********************************************************************
1861 Converts a name to a fully qualified domain name.
1862 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1863 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1864 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1865 ***********************************************************************/
1867 bool name_to_fqdn(fstring fqdn, const char *name)
1869 char *full = NULL;
1870 struct hostent *hp = gethostbyname(name);
1872 if (!hp || !hp->h_name || !*hp->h_name) {
1873 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1874 fstrcpy(fqdn, name);
1875 return false;
1878 /* Find out if the fqdn is returned as an alias
1879 * to cope with /etc/hosts files where the first
1880 * name is not the fqdn but the short name */
1881 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1882 int i;
1883 for (i = 0; hp->h_aliases[i]; i++) {
1884 if (strchr_m(hp->h_aliases[i], '.')) {
1885 full = hp->h_aliases[i];
1886 break;
1890 if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1891 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1892 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1893 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1894 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1895 full = hp->h_name;
1897 if (!full) {
1898 full = hp->h_name;
1901 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1902 fstrcpy(fqdn, full);
1903 return true;
1906 /**********************************************************************
1907 Append a DATA_BLOB to a talloc'ed object
1908 ***********************************************************************/
1910 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1912 size_t old_size = 0;
1913 char *result;
1915 if (blob.length == 0) {
1916 return buf;
1919 if (buf != NULL) {
1920 old_size = talloc_get_size(buf);
1923 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1924 if (result == NULL) {
1925 return NULL;
1928 memcpy(result + old_size, blob.data, blob.length);
1929 return result;
1932 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1934 switch (share_access & ~FILE_SHARE_DELETE) {
1935 case FILE_SHARE_NONE:
1936 return DENY_ALL;
1937 case FILE_SHARE_READ:
1938 return DENY_WRITE;
1939 case FILE_SHARE_WRITE:
1940 return DENY_READ;
1941 case FILE_SHARE_READ|FILE_SHARE_WRITE:
1942 return DENY_NONE;
1944 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
1945 return DENY_DOS;
1946 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
1947 return DENY_FCB;
1950 return (uint32)-1;
1953 pid_t procid_to_pid(const struct server_id *proc)
1955 return proc->pid;
1958 static uint32 my_vnn = NONCLUSTER_VNN;
1960 void set_my_vnn(uint32 vnn)
1962 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
1963 my_vnn = vnn;
1966 uint32 get_my_vnn(void)
1968 return my_vnn;
1971 static uint64_t my_unique_id = 0;
1973 void set_my_unique_id(uint64_t unique_id)
1975 my_unique_id = unique_id;
1978 struct server_id pid_to_procid(pid_t pid)
1980 struct server_id result;
1981 result.pid = pid;
1982 result.task_id = 0;
1983 result.unique_id = my_unique_id;
1984 result.vnn = my_vnn;
1985 return result;
1988 struct server_id procid_self(void)
1990 return pid_to_procid(sys_getpid());
1993 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
1995 if (p1->pid != p2->pid)
1996 return False;
1997 if (p1->task_id != p2->task_id)
1998 return False;
1999 if (p1->vnn != p2->vnn)
2000 return False;
2001 return True;
2004 bool cluster_id_equal(const struct server_id *id1,
2005 const struct server_id *id2)
2007 return procid_equal(id1, id2);
2010 bool procid_is_me(const struct server_id *pid)
2012 if (pid->pid != sys_getpid())
2013 return False;
2014 if (pid->task_id != 0)
2015 return False;
2016 if (pid->vnn != my_vnn)
2017 return False;
2018 return True;
2021 struct server_id interpret_pid(const char *pid_string)
2023 struct server_id result;
2024 unsigned long long pid;
2025 unsigned int vnn, task_id = 0;
2027 ZERO_STRUCT(result);
2029 /* We accept various forms with 1, 2 or 3 component forms
2030 * because the server_id_str() can print different forms, and
2031 * we want backwards compatibility for scripts that may call
2032 * smbclient. */
2033 if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
2034 result.vnn = vnn;
2035 result.pid = pid;
2036 result.task_id = task_id;
2037 } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
2038 result.vnn = vnn;
2039 result.pid = pid;
2040 result.task_id = 0;
2041 } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
2042 result.vnn = get_my_vnn();
2043 result.pid = pid;
2044 result.task_id = task_id;
2045 } else if (sscanf(pid_string, "%llu", &pid) == 1) {
2046 result.vnn = get_my_vnn();
2047 result.pid = pid;
2048 } else {
2049 result.vnn = NONCLUSTER_VNN;
2050 result.pid = (uint64_t)-1;
2052 return result;
2055 char *procid_str_static(const struct server_id *pid)
2057 return server_id_str(talloc_tos(), pid);
2060 bool procid_valid(const struct server_id *pid)
2062 return (pid->pid != (uint64_t)-1);
2065 bool procid_is_local(const struct server_id *pid)
2067 return pid->vnn == my_vnn;
2070 /****************************************************************
2071 Check if an offset into a buffer is safe.
2072 If this returns True it's safe to indirect into the byte at
2073 pointer ptr+off.
2074 ****************************************************************/
2076 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2078 const char *end_base = buf_base + buf_len;
2079 char *end_ptr = ptr + off;
2081 if (!buf_base || !ptr) {
2082 return False;
2085 if (end_base < buf_base || end_ptr < ptr) {
2086 return False; /* wrap. */
2089 if (end_ptr < end_base) {
2090 return True;
2092 return False;
2095 /****************************************************************
2096 Return a safe pointer into a buffer, or NULL.
2097 ****************************************************************/
2099 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2101 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2102 ptr + off : NULL;
2105 /****************************************************************
2106 Return a safe pointer into a string within a buffer, or NULL.
2107 ****************************************************************/
2109 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2111 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2112 return NULL;
2114 /* Check if a valid string exists at this offset. */
2115 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2116 return NULL;
2118 return ptr + off;
2121 /****************************************************************
2122 Return an SVAL at a pointer, or failval if beyond the end.
2123 ****************************************************************/
2125 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2128 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2129 * NOT ptr[2].
2131 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2132 return failval;
2134 return SVAL(ptr,off);
2137 /****************************************************************
2138 Return an IVAL at a pointer, or failval if beyond the end.
2139 ****************************************************************/
2141 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2144 * Note we use off+3 here, not off+4 as IVAL accesses
2145 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2147 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2148 return failval;
2150 return IVAL(ptr,off);
2153 /****************************************************************
2154 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2155 call (they take care of winbind separator and other winbind specific settings).
2156 ****************************************************************/
2158 void split_domain_user(TALLOC_CTX *mem_ctx,
2159 const char *full_name,
2160 char **domain,
2161 char **user)
2163 const char *p = NULL;
2165 p = strchr_m(full_name, '\\');
2167 if (p != NULL) {
2168 *domain = talloc_strndup(mem_ctx, full_name,
2169 PTR_DIFF(p, full_name));
2170 *user = talloc_strdup(mem_ctx, p+1);
2171 } else {
2172 *domain = talloc_strdup(mem_ctx, "");
2173 *user = talloc_strdup(mem_ctx, full_name);
2177 /****************************************************************
2178 strip off leading '\\' from a hostname
2179 ****************************************************************/
2181 const char *strip_hostname(const char *s)
2183 if (!s) {
2184 return NULL;
2187 if (strlen_m(s) < 3) {
2188 return s;
2191 if (s[0] == '\\') s++;
2192 if (s[0] == '\\') s++;
2194 return s;
2197 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2198 struct tevent_context *ev,
2199 NTSTATUS *status)
2201 bool ret = tevent_req_poll(req, ev);
2202 if (!ret) {
2203 *status = map_nt_error_from_unix(errno);
2205 return ret;
2208 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2210 if (!NT_STATUS_IS_OK(err1)) {
2211 *result = err1;
2212 return true;
2214 if (!NT_STATUS_IS_OK(err2)) {
2215 *result = err2;
2216 return true;
2218 return false;
2221 int timeval_to_msec(struct timeval t)
2223 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2226 /*******************************************************************
2227 Check a given DOS pathname is valid for a share.
2228 ********************************************************************/
2230 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2232 char *ptr = NULL;
2234 if (!dos_pathname) {
2235 return NULL;
2238 ptr = talloc_strdup(ctx, dos_pathname);
2239 if (!ptr) {
2240 return NULL;
2242 /* Convert any '\' paths to '/' */
2243 unix_format(ptr);
2244 ptr = unix_clean_name(ctx, ptr);
2245 if (!ptr) {
2246 return NULL;
2249 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2250 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2251 ptr += 2;
2253 /* Only absolute paths allowed. */
2254 if (*ptr != '/')
2255 return NULL;
2257 return ptr;
2260 /*******************************************************************
2261 Return True if the filename is one of the special executable types.
2262 ********************************************************************/
2264 bool is_executable(const char *fname)
2266 if ((fname = strrchr_m(fname,'.'))) {
2267 if (strequal(fname,".com") ||
2268 strequal(fname,".dll") ||
2269 strequal(fname,".exe") ||
2270 strequal(fname,".sym")) {
2271 return True;
2274 return False;
2277 /****************************************************************************
2278 Open a file with a share mode - old openX method - map into NTCreate.
2279 ****************************************************************************/
2281 bool map_open_params_to_ntcreate(const char *smb_base_fname,
2282 int deny_mode, int open_func,
2283 uint32 *paccess_mask,
2284 uint32 *pshare_mode,
2285 uint32 *pcreate_disposition,
2286 uint32 *pcreate_options,
2287 uint32_t *pprivate_flags)
2289 uint32 access_mask;
2290 uint32 share_mode;
2291 uint32 create_disposition;
2292 uint32 create_options = FILE_NON_DIRECTORY_FILE;
2293 uint32_t private_flags = 0;
2295 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2296 "open_func = 0x%x\n",
2297 smb_base_fname, (unsigned int)deny_mode,
2298 (unsigned int)open_func ));
2300 /* Create the NT compatible access_mask. */
2301 switch (GET_OPENX_MODE(deny_mode)) {
2302 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
2303 case DOS_OPEN_RDONLY:
2304 access_mask = FILE_GENERIC_READ;
2305 break;
2306 case DOS_OPEN_WRONLY:
2307 access_mask = FILE_GENERIC_WRITE;
2308 break;
2309 case DOS_OPEN_RDWR:
2310 case DOS_OPEN_FCB:
2311 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
2312 break;
2313 default:
2314 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2315 (unsigned int)GET_OPENX_MODE(deny_mode)));
2316 return False;
2319 /* Create the NT compatible create_disposition. */
2320 switch (open_func) {
2321 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
2322 create_disposition = FILE_CREATE;
2323 break;
2325 case OPENX_FILE_EXISTS_OPEN:
2326 create_disposition = FILE_OPEN;
2327 break;
2329 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
2330 create_disposition = FILE_OPEN_IF;
2331 break;
2333 case OPENX_FILE_EXISTS_TRUNCATE:
2334 create_disposition = FILE_OVERWRITE;
2335 break;
2337 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
2338 create_disposition = FILE_OVERWRITE_IF;
2339 break;
2341 default:
2342 /* From samba4 - to be confirmed. */
2343 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
2344 create_disposition = FILE_CREATE;
2345 break;
2347 DEBUG(10,("map_open_params_to_ntcreate: bad "
2348 "open_func 0x%x\n", (unsigned int)open_func));
2349 return False;
2352 /* Create the NT compatible share modes. */
2353 switch (GET_DENY_MODE(deny_mode)) {
2354 case DENY_ALL:
2355 share_mode = FILE_SHARE_NONE;
2356 break;
2358 case DENY_WRITE:
2359 share_mode = FILE_SHARE_READ;
2360 break;
2362 case DENY_READ:
2363 share_mode = FILE_SHARE_WRITE;
2364 break;
2366 case DENY_NONE:
2367 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2368 break;
2370 case DENY_DOS:
2371 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
2372 if (is_executable(smb_base_fname)) {
2373 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2374 } else {
2375 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
2376 share_mode = FILE_SHARE_READ;
2377 } else {
2378 share_mode = FILE_SHARE_NONE;
2381 break;
2383 case DENY_FCB:
2384 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
2385 share_mode = FILE_SHARE_NONE;
2386 break;
2388 default:
2389 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2390 (unsigned int)GET_DENY_MODE(deny_mode) ));
2391 return False;
2394 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2395 "share_mode = 0x%x, create_disposition = 0x%x, "
2396 "create_options = 0x%x private_flags = 0x%x\n",
2397 smb_base_fname,
2398 (unsigned int)access_mask,
2399 (unsigned int)share_mode,
2400 (unsigned int)create_disposition,
2401 (unsigned int)create_options,
2402 (unsigned int)private_flags));
2404 if (paccess_mask) {
2405 *paccess_mask = access_mask;
2407 if (pshare_mode) {
2408 *pshare_mode = share_mode;
2410 if (pcreate_disposition) {
2411 *pcreate_disposition = create_disposition;
2413 if (pcreate_options) {
2414 *pcreate_options = create_options;
2416 if (pprivate_flags) {
2417 *pprivate_flags = private_flags;
2420 return True;
2425 void init_modules(void)
2427 /* FIXME: This can cause undefined symbol errors :
2428 * smb_register_vfs() isn't available in nmbd, for example */
2429 if(lp_preload_modules())
2430 smb_load_modules(lp_preload_modules());