s3:smbd/server: create smbd_parent_context earlier
[Samba/id10ts.git] / source3 / lib / util.c
blob2e432ab18eb861af824b9050e63adcaf4ce69810
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 bool parent_longlived)
377 NTSTATUS status = NT_STATUS_OK;
379 /* Reset the state of the random
380 * number generation system, so
381 * children do not get the same random
382 * numbers as each other */
383 set_need_random_reseed();
385 /* tdb needs special fork handling */
386 if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
387 DEBUG(0,("tdb_reopen_all failed.\n"));
388 status = NT_STATUS_OPEN_FAILED;
389 goto done;
392 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
393 smb_panic(__location__ ": Failed to re-initialise event context");
396 if (msg_ctx) {
398 * For clustering, we need to re-init our ctdbd connection after the
399 * fork
401 status = messaging_reinit(msg_ctx);
402 if (!NT_STATUS_IS_OK(status)) {
403 DEBUG(0,("messaging_reinit() failed: %s\n",
404 nt_errstr(status)));
407 done:
408 return status;
411 /****************************************************************************
412 (Hopefully) efficient array append.
413 ****************************************************************************/
415 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
416 void *element, void *_array, uint32 *num_elements,
417 ssize_t *array_size)
419 void **array = (void **)_array;
421 if (*array_size < 0) {
422 return;
425 if (*array == NULL) {
426 if (*array_size == 0) {
427 *array_size = 128;
430 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
431 goto error;
434 *array = TALLOC(mem_ctx, element_size * (*array_size));
435 if (*array == NULL) {
436 goto error;
440 if (*num_elements == *array_size) {
441 *array_size *= 2;
443 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
444 goto error;
447 *array = TALLOC_REALLOC(mem_ctx, *array,
448 element_size * (*array_size));
450 if (*array == NULL) {
451 goto error;
455 memcpy((char *)(*array) + element_size*(*num_elements),
456 element, element_size);
457 *num_elements += 1;
459 return;
461 error:
462 *num_elements = 0;
463 *array_size = -1;
466 /****************************************************************************
467 Get my own domain name, or "" if we have none.
468 ****************************************************************************/
470 char *get_mydnsdomname(TALLOC_CTX *ctx)
472 const char *domname;
473 char *p;
475 domname = get_mydnsfullname();
476 if (!domname) {
477 return NULL;
480 p = strchr_m(domname, '.');
481 if (p) {
482 p++;
483 return talloc_strdup(ctx, p);
484 } else {
485 return talloc_strdup(ctx, "");
489 /****************************************************************************
490 Interpret a protocol description string, with a default.
491 ****************************************************************************/
493 int interpret_protocol(const char *str,int def)
495 if (strequal(str,"NT1"))
496 return(PROTOCOL_NT1);
497 if (strequal(str,"LANMAN2"))
498 return(PROTOCOL_LANMAN2);
499 if (strequal(str,"LANMAN1"))
500 return(PROTOCOL_LANMAN1);
501 if (strequal(str,"CORE"))
502 return(PROTOCOL_CORE);
503 if (strequal(str,"COREPLUS"))
504 return(PROTOCOL_COREPLUS);
505 if (strequal(str,"CORE+"))
506 return(PROTOCOL_COREPLUS);
508 DEBUG(0,("Unrecognised protocol level %s\n",str));
510 return(def);
514 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
515 /******************************************************************
516 Remove any mount options such as -rsize=2048,wsize=2048 etc.
517 Based on a fix from <Thomas.Hepper@icem.de>.
518 Returns a malloc'ed string.
519 *******************************************************************/
521 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
523 if (*str == '-') {
524 const char *p = str;
525 while(*p && !isspace(*p))
526 p++;
527 while(*p && isspace(*p))
528 p++;
529 if(*p) {
530 return talloc_strdup(ctx, p);
533 return NULL;
536 /*******************************************************************
537 Patch from jkf@soton.ac.uk
538 Split Luke's automount_server into YP lookup and string splitter
539 so can easily implement automount_path().
540 Returns a malloc'ed string.
541 *******************************************************************/
543 #ifdef WITH_NISPLUS_HOME
544 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
546 char *value = NULL;
548 char *nis_map = (char *)lp_nis_home_map_name();
550 char buffer[NIS_MAXATTRVAL + 1];
551 nis_result *result;
552 nis_object *object;
553 entry_obj *entry;
555 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
556 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
558 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
559 if (result->status != NIS_SUCCESS) {
560 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
561 } else {
562 object = result->objects.objects_val;
563 if (object->zo_data.zo_type == ENTRY_OBJ) {
564 entry = &object->zo_data.objdata_u.en_data;
565 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
566 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
568 value = talloc_strdup(ctx,
569 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
570 if (!value) {
571 nis_freeresult(result);
572 return NULL;
574 value = talloc_string_sub(ctx,
575 value,
576 "&",
577 user_name);
581 nis_freeresult(result);
583 if (value) {
584 value = strip_mount_options(ctx, value);
585 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
586 user_name, value));
588 return value;
590 #else /* WITH_NISPLUS_HOME */
592 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
594 char *value = NULL;
596 int nis_error; /* returned by yp all functions */
597 char *nis_result; /* yp_match inits this */
598 int nis_result_len; /* and set this */
599 char *nis_domain; /* yp_get_default_domain inits this */
600 char *nis_map = (char *)lp_nis_home_map_name();
602 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
603 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
604 return NULL;
607 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
609 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
610 strlen(user_name), &nis_result,
611 &nis_result_len)) == 0) {
612 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
613 nis_result[nis_result_len] = '\0';
615 value = talloc_strdup(ctx, nis_result);
616 if (!value) {
617 return NULL;
619 value = strip_mount_options(ctx, value);
620 } else if(nis_error == YPERR_KEY) {
621 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
622 user_name, nis_map));
623 DEBUG(3, ("using defaults for server and home directory\n"));
624 } else {
625 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
626 yperr_string(nis_error), user_name, nis_map));
629 if (value) {
630 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
632 return value;
634 #endif /* WITH_NISPLUS_HOME */
635 #endif
637 /****************************************************************************
638 Check if a process exists. Does this work on all unixes?
639 ****************************************************************************/
641 bool process_exists(const struct server_id pid)
643 if (procid_is_me(&pid)) {
644 return True;
647 if (procid_is_local(&pid)) {
648 return (kill(pid.pid,0) == 0 || errno != ESRCH);
651 #ifdef CLUSTER_SUPPORT
652 return ctdbd_process_exists(messaging_ctdbd_connection(),
653 pid.vnn, pid.pid);
654 #else
655 return False;
656 #endif
659 bool processes_exist(const struct server_id *pids, int num_pids,
660 bool *results)
662 struct server_id *remote_pids = NULL;
663 int *remote_idx = NULL;
664 bool *remote_results = NULL;
665 int i, num_remote_pids;
666 bool result = false;
668 remote_pids = talloc_array(talloc_tos(), struct server_id, num_pids);
669 if (remote_pids == NULL) {
670 goto fail;
672 remote_idx = talloc_array(talloc_tos(), int, num_pids);
673 if (remote_idx == NULL) {
674 goto fail;
676 remote_results = talloc_array(talloc_tos(), bool, num_pids);
677 if (remote_results == NULL) {
678 goto fail;
681 num_remote_pids = 0;
683 for (i=0; i<num_pids; i++) {
684 if (procid_is_me(&pids[i])) {
685 results[i] = true;
686 continue;
688 if (procid_is_local(&pids[i])) {
689 results[i] = ((kill(pids[i].pid,0) == 0) ||
690 (errno != ESRCH));
691 continue;
694 remote_pids[num_remote_pids] = pids[i];
695 remote_idx[num_remote_pids] = i;
696 num_remote_pids += 1;
699 if (num_remote_pids != 0) {
700 #ifdef CLUSTER_SUPPORT
701 if (!ctdb_processes_exist(messaging_ctdbd_connection(),
702 remote_pids, num_remote_pids,
703 remote_results)) {
704 goto fail;
706 #else
707 for (i=0; i<num_remote_pids; i++) {
708 remote_results[i] = false;
710 #endif
712 for (i=0; i<num_remote_pids; i++) {
713 results[remote_idx[i]] = remote_results[i];
717 result = true;
718 fail:
719 TALLOC_FREE(remote_results);
720 TALLOC_FREE(remote_idx);
721 TALLOC_FREE(remote_pids);
722 return result;
725 /*******************************************************************
726 Convert a uid into a user name.
727 ********************************************************************/
729 const char *uidtoname(uid_t uid)
731 TALLOC_CTX *ctx = talloc_tos();
732 char *name = NULL;
733 struct passwd *pass = NULL;
735 pass = getpwuid_alloc(ctx,uid);
736 if (pass) {
737 name = talloc_strdup(ctx,pass->pw_name);
738 TALLOC_FREE(pass);
739 } else {
740 name = talloc_asprintf(ctx,
741 "%ld",
742 (long int)uid);
744 return name;
747 /*******************************************************************
748 Convert a gid into a group name.
749 ********************************************************************/
751 char *gidtoname(gid_t gid)
753 struct group *grp;
755 grp = getgrgid(gid);
756 if (grp) {
757 return talloc_strdup(talloc_tos(), grp->gr_name);
759 else {
760 return talloc_asprintf(talloc_tos(),
761 "%d",
762 (int)gid);
766 /*******************************************************************
767 Convert a user name into a uid.
768 ********************************************************************/
770 uid_t nametouid(const char *name)
772 struct passwd *pass;
773 char *p;
774 uid_t u;
776 pass = Get_Pwnam_alloc(talloc_tos(), name);
777 if (pass) {
778 u = pass->pw_uid;
779 TALLOC_FREE(pass);
780 return u;
783 u = (uid_t)strtol(name, &p, 0);
784 if ((p != name) && (*p == '\0'))
785 return u;
787 return (uid_t)-1;
790 /*******************************************************************
791 Convert a name to a gid_t if possible. Return -1 if not a group.
792 ********************************************************************/
794 gid_t nametogid(const char *name)
796 struct group *grp;
797 char *p;
798 gid_t g;
800 g = (gid_t)strtol(name, &p, 0);
801 if ((p != name) && (*p == '\0'))
802 return g;
804 grp = sys_getgrnam(name);
805 if (grp)
806 return(grp->gr_gid);
807 return (gid_t)-1;
810 /*******************************************************************
811 Something really nasty happened - panic !
812 ********************************************************************/
814 void smb_panic_s3(const char *why)
816 char *cmd;
817 int result;
819 DEBUG(0,("PANIC (pid %llu): %s\n",
820 (unsigned long long)sys_getpid(), why));
821 log_stack_trace();
823 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
825 * Make sure all children can attach a debugger.
827 prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
828 #endif
830 cmd = lp_panic_action();
831 if (cmd && *cmd) {
832 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
833 result = system(cmd);
835 if (result == -1)
836 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
837 strerror(errno)));
838 else
839 DEBUG(0, ("smb_panic(): action returned status %d\n",
840 WEXITSTATUS(result)));
843 dump_core();
846 /*******************************************************************
847 Print a backtrace of the stack to the debug log. This function
848 DELIBERATELY LEAKS MEMORY. The expectation is that you should
849 exit shortly after calling it.
850 ********************************************************************/
852 #ifdef HAVE_LIBUNWIND_H
853 #include <libunwind.h>
854 #endif
856 #ifdef HAVE_EXECINFO_H
857 #include <execinfo.h>
858 #endif
860 #ifdef HAVE_LIBEXC_H
861 #include <libexc.h>
862 #endif
864 void log_stack_trace(void)
866 #ifdef HAVE_LIBUNWIND
867 /* Try to use libunwind before any other technique since on ia64
868 * libunwind correctly walks the stack in more circumstances than
869 * backtrace.
871 unw_cursor_t cursor;
872 unw_context_t uc;
873 unsigned i = 0;
875 char procname[256];
876 unw_word_t ip, sp, off;
878 procname[sizeof(procname) - 1] = '\0';
880 if (unw_getcontext(&uc) != 0) {
881 goto libunwind_failed;
884 if (unw_init_local(&cursor, &uc) != 0) {
885 goto libunwind_failed;
888 DEBUG(0, ("BACKTRACE:\n"));
890 do {
891 ip = sp = 0;
892 unw_get_reg(&cursor, UNW_REG_IP, &ip);
893 unw_get_reg(&cursor, UNW_REG_SP, &sp);
895 switch (unw_get_proc_name(&cursor,
896 procname, sizeof(procname) - 1, &off) ) {
897 case 0:
898 /* Name found. */
899 case -UNW_ENOMEM:
900 /* Name truncated. */
901 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
902 i, procname, (long long)off,
903 (long long)ip, (long long) sp));
904 break;
905 default:
906 /* case -UNW_ENOINFO: */
907 /* case -UNW_EUNSPEC: */
908 /* No symbol name found. */
909 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
910 i, "<unknown symbol>",
911 (long long)ip, (long long) sp));
913 ++i;
914 } while (unw_step(&cursor) > 0);
916 return;
918 libunwind_failed:
919 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
921 #elif HAVE_BACKTRACE_SYMBOLS
922 void *backtrace_stack[BACKTRACE_STACK_SIZE];
923 size_t backtrace_size;
924 char **backtrace_strings;
926 /* get the backtrace (stack frames) */
927 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
928 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
930 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
931 (unsigned long)backtrace_size));
933 if (backtrace_strings) {
934 int i;
936 for (i = 0; i < backtrace_size; i++)
937 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
939 /* Leak the backtrace_strings, rather than risk what free() might do */
942 #elif HAVE_LIBEXC
944 /* The IRIX libexc library provides an API for unwinding the stack. See
945 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
946 * since we are about to abort anyway, it hardly matters.
949 #define NAMESIZE 32 /* Arbitrary */
951 __uint64_t addrs[BACKTRACE_STACK_SIZE];
952 char * names[BACKTRACE_STACK_SIZE];
953 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
955 int i;
956 int levels;
958 ZERO_ARRAY(addrs);
959 ZERO_ARRAY(names);
960 ZERO_ARRAY(namebuf);
962 /* We need to be root so we can open our /proc entry to walk
963 * our stack. It also helps when we want to dump core.
965 become_root();
967 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
968 names[i] = namebuf + (i * NAMESIZE);
971 levels = trace_back_stack(0, addrs, names,
972 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
974 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
975 for (i = 0; i < levels; i++) {
976 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
978 #undef NAMESIZE
980 #else
981 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
982 #endif
985 /*******************************************************************
986 A readdir wrapper which just returns the file name.
987 ********************************************************************/
989 const char *readdirname(SMB_STRUCT_DIR *p)
991 SMB_STRUCT_DIRENT *ptr;
992 char *dname;
994 if (!p)
995 return(NULL);
997 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
998 if (!ptr)
999 return(NULL);
1001 dname = ptr->d_name;
1003 #ifdef NEXT2
1004 if (telldir(p) < 0)
1005 return(NULL);
1006 #endif
1008 #ifdef HAVE_BROKEN_READDIR_NAME
1009 /* using /usr/ucb/cc is BAD */
1010 dname = dname - 2;
1011 #endif
1013 return talloc_strdup(talloc_tos(), dname);
1016 /*******************************************************************
1017 Utility function used to decide if the last component
1018 of a path matches a (possibly wildcarded) entry in a namelist.
1019 ********************************************************************/
1021 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1023 const char *last_component;
1025 /* if we have no list it's obviously not in the path */
1026 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1027 return False;
1030 DEBUG(8, ("is_in_path: %s\n", name));
1032 /* Get the last component of the unix name. */
1033 last_component = strrchr_m(name, '/');
1034 if (!last_component) {
1035 last_component = name;
1036 } else {
1037 last_component++; /* Go past '/' */
1040 for(; namelist->name != NULL; namelist++) {
1041 if(namelist->is_wild) {
1042 if (mask_match(last_component, namelist->name, case_sensitive)) {
1043 DEBUG(8,("is_in_path: mask match succeeded\n"));
1044 return True;
1046 } else {
1047 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1048 (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
1049 DEBUG(8,("is_in_path: match succeeded\n"));
1050 return True;
1054 DEBUG(8,("is_in_path: match not found\n"));
1055 return False;
1058 /*******************************************************************
1059 Strip a '/' separated list into an array of
1060 name_compare_enties structures suitable for
1061 passing to is_in_path(). We do this for
1062 speed so we can pre-parse all the names in the list
1063 and don't do it for each call to is_in_path().
1064 We also check if the entry contains a wildcard to
1065 remove a potentially expensive call to mask_match
1066 if possible.
1067 ********************************************************************/
1069 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1071 char *name_end;
1072 char *namelist;
1073 char *nameptr;
1074 int num_entries = 0;
1075 int i;
1077 (*ppname_array) = NULL;
1079 if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0')))
1080 return;
1082 namelist = talloc_strdup(talloc_tos(), namelist_in);
1083 if (namelist == NULL) {
1084 DEBUG(0,("set_namearray: talloc fail\n"));
1085 return;
1087 nameptr = namelist;
1089 /* We need to make two passes over the string. The
1090 first to count the number of elements, the second
1091 to split it.
1094 while(*nameptr) {
1095 if ( *nameptr == '/' ) {
1096 /* cope with multiple (useless) /s) */
1097 nameptr++;
1098 continue;
1100 /* anything left? */
1101 if ( *nameptr == '\0' )
1102 break;
1104 /* find the next '/' or consume remaining */
1105 name_end = strchr_m(nameptr, '/');
1106 if (name_end == NULL)
1107 name_end = (char *)nameptr + strlen(nameptr);
1109 /* next segment please */
1110 nameptr = name_end + 1;
1111 num_entries++;
1114 if(num_entries == 0) {
1115 talloc_free(namelist);
1116 return;
1119 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1120 DEBUG(0,("set_namearray: malloc fail\n"));
1121 talloc_free(namelist);
1122 return;
1125 /* Now copy out the names */
1126 nameptr = namelist;
1127 i = 0;
1128 while(*nameptr) {
1129 if ( *nameptr == '/' ) {
1130 /* cope with multiple (useless) /s) */
1131 nameptr++;
1132 continue;
1134 /* anything left? */
1135 if ( *nameptr == '\0' )
1136 break;
1138 /* find the next '/' or consume remaining */
1139 name_end = strchr_m(nameptr, '/');
1140 if (name_end)
1141 *name_end = '\0';
1142 else
1143 name_end = nameptr + strlen(nameptr);
1145 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1146 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1147 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1148 talloc_free(namelist);
1149 return;
1152 /* next segment please */
1153 nameptr = name_end + 1;
1154 i++;
1157 (*ppname_array)[i].name = NULL;
1159 talloc_free(namelist);
1160 return;
1163 #undef DBGC_CLASS
1164 #define DBGC_CLASS DBGC_LOCKING
1166 /****************************************************************************
1167 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1168 is dealt with in posix.c
1169 Returns True if we have information regarding this lock region (and returns
1170 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1171 ****************************************************************************/
1173 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1175 SMB_STRUCT_FLOCK lock;
1176 int ret;
1178 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1179 fd,(double)*poffset,(double)*pcount,*ptype));
1181 lock.l_type = *ptype;
1182 lock.l_whence = SEEK_SET;
1183 lock.l_start = *poffset;
1184 lock.l_len = *pcount;
1185 lock.l_pid = 0;
1187 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1189 if (ret == -1) {
1190 int sav = errno;
1191 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1192 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1193 errno = sav;
1194 return False;
1197 *ptype = lock.l_type;
1198 *poffset = lock.l_start;
1199 *pcount = lock.l_len;
1200 *ppid = lock.l_pid;
1202 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1203 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1204 return True;
1207 #undef DBGC_CLASS
1208 #define DBGC_CLASS DBGC_ALL
1210 /*******************************************************************
1211 Is the name specified one of my netbios names.
1212 Returns true if it is equal, false otherwise.
1213 ********************************************************************/
1215 bool is_myname(const char *s)
1217 int n;
1218 bool ret = False;
1220 for (n=0; my_netbios_names(n); n++) {
1221 if (strequal(my_netbios_names(n), s)) {
1222 ret=True;
1223 break;
1226 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1227 return(ret);
1230 /*******************************************************************
1231 Is the name specified our workgroup/domain.
1232 Returns true if it is equal, false otherwise.
1233 ********************************************************************/
1235 bool is_myworkgroup(const char *s)
1237 bool ret = False;
1239 if (strequal(s, lp_workgroup())) {
1240 ret=True;
1243 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1244 return(ret);
1247 /*******************************************************************
1248 we distinguish between 2K and XP by the "Native Lan Manager" string
1249 WinXP => "Windows 2002 5.1"
1250 WinXP 64bit => "Windows XP 5.2"
1251 Win2k => "Windows 2000 5.0"
1252 NT4 => "Windows NT 4.0"
1253 Win9x => "Windows 4.0"
1254 Windows 2003 doesn't set the native lan manager string but
1255 they do set the domain to "Windows 2003 5.2" (probably a bug).
1256 ********************************************************************/
1258 void ra_lanman_string( const char *native_lanman )
1260 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1261 set_remote_arch( RA_WINXP );
1262 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1263 set_remote_arch( RA_WINXP64 );
1264 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1265 set_remote_arch( RA_WIN2K3 );
1268 static const char *remote_arch_str;
1270 const char *get_remote_arch_str(void)
1272 if (!remote_arch_str) {
1273 return "UNKNOWN";
1275 return remote_arch_str;
1278 /*******************************************************************
1279 Set the horrid remote_arch string based on an enum.
1280 ********************************************************************/
1282 void set_remote_arch(enum remote_arch_types type)
1284 ra_type = type;
1285 switch( type ) {
1286 case RA_WFWG:
1287 remote_arch_str = "WfWg";
1288 break;
1289 case RA_OS2:
1290 remote_arch_str = "OS2";
1291 break;
1292 case RA_WIN95:
1293 remote_arch_str = "Win95";
1294 break;
1295 case RA_WINNT:
1296 remote_arch_str = "WinNT";
1297 break;
1298 case RA_WIN2K:
1299 remote_arch_str = "Win2K";
1300 break;
1301 case RA_WINXP:
1302 remote_arch_str = "WinXP";
1303 break;
1304 case RA_WINXP64:
1305 remote_arch_str = "WinXP64";
1306 break;
1307 case RA_WIN2K3:
1308 remote_arch_str = "Win2K3";
1309 break;
1310 case RA_VISTA:
1311 remote_arch_str = "Vista";
1312 break;
1313 case RA_SAMBA:
1314 remote_arch_str = "Samba";
1315 break;
1316 case RA_CIFSFS:
1317 remote_arch_str = "CIFSFS";
1318 break;
1319 case RA_OSX:
1320 remote_arch_str = "OSX";
1321 break;
1322 default:
1323 ra_type = RA_UNKNOWN;
1324 remote_arch_str = "UNKNOWN";
1325 break;
1328 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1329 remote_arch_str));
1332 /*******************************************************************
1333 Get the remote_arch type.
1334 ********************************************************************/
1336 enum remote_arch_types get_remote_arch(void)
1338 return ra_type;
1341 const char *tab_depth(int level, int depth)
1343 if( CHECK_DEBUGLVL(level) ) {
1344 dbgtext("%*s", depth*4, "");
1346 return "";
1349 /*****************************************************************************
1350 Provide a checksum on a string
1352 Input: s - the null-terminated character string for which the checksum
1353 will be calculated.
1355 Output: The checksum value calculated for s.
1356 *****************************************************************************/
1358 int str_checksum(const char *s)
1360 if (s == NULL)
1361 return 0;
1362 return hash(s, strlen(s), 0);
1365 /*****************************************************************
1366 Zero a memory area then free it. Used to catch bugs faster.
1367 *****************************************************************/
1369 void zero_free(void *p, size_t size)
1371 memset(p, 0, size);
1372 SAFE_FREE(p);
1375 /*****************************************************************
1376 Set our open file limit to a requested max and return the limit.
1377 *****************************************************************/
1379 int set_maxfiles(int requested_max)
1381 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1382 struct rlimit rlp;
1383 int saved_current_limit;
1385 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1386 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1387 strerror(errno) ));
1388 /* just guess... */
1389 return requested_max;
1393 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1394 * account for the extra fd we need
1395 * as well as the log files and standard
1396 * handles etc. Save the limit we want to set in case
1397 * we are running on an OS that doesn't support this limit (AIX)
1398 * which always returns RLIM_INFINITY for rlp.rlim_max.
1401 /* Try raising the hard (max) limit to the requested amount. */
1403 #if defined(RLIM_INFINITY)
1404 if (rlp.rlim_max != RLIM_INFINITY) {
1405 int orig_max = rlp.rlim_max;
1407 if ( rlp.rlim_max < requested_max )
1408 rlp.rlim_max = requested_max;
1410 /* This failing is not an error - many systems (Linux) don't
1411 support our default request of 10,000 open files. JRA. */
1413 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1414 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1415 (int)rlp.rlim_max, strerror(errno) ));
1417 /* Set failed - restore original value from get. */
1418 rlp.rlim_max = orig_max;
1421 #endif
1423 /* Now try setting the soft (current) limit. */
1425 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1427 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1428 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1429 (int)rlp.rlim_cur, strerror(errno) ));
1430 /* just guess... */
1431 return saved_current_limit;
1434 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1435 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1436 strerror(errno) ));
1437 /* just guess... */
1438 return saved_current_limit;
1441 #if defined(RLIM_INFINITY)
1442 if(rlp.rlim_cur == RLIM_INFINITY)
1443 return saved_current_limit;
1444 #endif
1446 if((int)rlp.rlim_cur > saved_current_limit)
1447 return saved_current_limit;
1449 return rlp.rlim_cur;
1450 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1452 * No way to know - just guess...
1454 return requested_max;
1455 #endif
1458 /*****************************************************************
1459 malloc that aborts with smb_panic on fail or zero size.
1460 *****************************************************************/
1462 void *smb_xmalloc_array(size_t size, unsigned int count)
1464 void *p;
1465 if (size == 0) {
1466 smb_panic("smb_xmalloc_array: called with zero size");
1468 if (count >= MAX_ALLOC_SIZE/size) {
1469 smb_panic("smb_xmalloc_array: alloc size too large");
1471 if ((p = SMB_MALLOC(size*count)) == NULL) {
1472 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1473 (unsigned long)size, (unsigned long)count));
1474 smb_panic("smb_xmalloc_array: malloc failed");
1476 return p;
1480 vasprintf that aborts on malloc fail
1483 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1485 int n;
1486 va_list ap2;
1488 va_copy(ap2, ap);
1490 n = vasprintf(ptr, format, ap2);
1491 va_end(ap2);
1492 if (n == -1 || ! *ptr) {
1493 smb_panic("smb_xvasprintf: out of memory");
1495 return n;
1498 /*****************************************************************
1499 Get local hostname and cache result.
1500 *****************************************************************/
1502 char *myhostname(void)
1504 static char *ret;
1505 if (ret == NULL) {
1506 ret = get_myname(NULL);
1508 return ret;
1511 /*****************************************************************
1512 Get local hostname and cache result.
1513 *****************************************************************/
1515 char *myhostname_upper(void)
1517 char *name;
1518 static char *ret;
1519 if (ret == NULL) {
1520 name = get_myname(talloc_tos());
1521 ret = strupper_talloc(NULL, name);
1522 talloc_free(name);
1524 return ret;
1528 * @brief Returns an absolute path to a file concatenating the provided
1529 * @a rootpath and @a basename
1531 * @param name Filename, relative to @a rootpath
1533 * @retval Pointer to a string containing the full path.
1536 static char *xx_path(const char *name, const char *rootpath)
1538 char *fname = NULL;
1540 fname = talloc_strdup(talloc_tos(), rootpath);
1541 if (!fname) {
1542 return NULL;
1544 trim_string(fname,"","/");
1546 if (!directory_exist(fname)) {
1547 if (!mkdir(fname,0755))
1548 DEBUG(1, ("Unable to create directory %s for file %s. "
1549 "Error was %s\n", fname, name, strerror(errno)));
1552 return talloc_asprintf(talloc_tos(),
1553 "%s/%s",
1554 fname,
1555 name);
1559 * @brief Returns an absolute path to a file in the Samba lock directory.
1561 * @param name File to find, relative to LOCKDIR.
1563 * @retval Pointer to a talloc'ed string containing the full path.
1566 char *lock_path(const char *name)
1568 return xx_path(name, lp_lockdir());
1572 * @brief Returns an absolute path to a file in the Samba pid directory.
1574 * @param name File to find, relative to PIDDIR.
1576 * @retval Pointer to a talloc'ed string containing the full path.
1579 char *pid_path(const char *name)
1581 return xx_path(name, lp_piddir());
1585 * @brief Returns an absolute path to a file in the Samba state directory.
1587 * @param name File to find, relative to STATEDIR.
1589 * @retval Pointer to a talloc'ed string containing the full path.
1592 char *state_path(const char *name)
1594 return xx_path(name, lp_statedir());
1598 * @brief Returns an absolute path to a file in the Samba cache directory.
1600 * @param name File to find, relative to CACHEDIR.
1602 * @retval Pointer to a talloc'ed string containing the full path.
1605 char *cache_path(const char *name)
1607 return xx_path(name, lp_cachedir());
1610 /*******************************************************************
1611 Given a filename - get its directory name
1612 ********************************************************************/
1614 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1615 const char **name)
1617 char *p;
1618 ptrdiff_t len;
1620 p = strrchr_m(dir, '/'); /* Find final '/', if any */
1622 if (p == NULL) {
1623 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1624 return False;
1626 if (name) {
1627 *name = dir;
1629 return True;
1632 len = p-dir;
1634 if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
1635 return False;
1637 (*parent)[len] = '\0';
1639 if (name) {
1640 *name = p+1;
1642 return True;
1645 /*******************************************************************
1646 Determine if a pattern contains any Microsoft wildcard characters.
1647 *******************************************************************/
1649 bool ms_has_wild(const char *s)
1651 char c;
1653 if (lp_posix_pathnames()) {
1654 /* With posix pathnames no characters are wild. */
1655 return False;
1658 while ((c = *s++)) {
1659 switch (c) {
1660 case '*':
1661 case '?':
1662 case '<':
1663 case '>':
1664 case '"':
1665 return True;
1668 return False;
1671 bool ms_has_wild_w(const smb_ucs2_t *s)
1673 smb_ucs2_t c;
1674 if (!s) return False;
1675 while ((c = *s++)) {
1676 switch (c) {
1677 case UCS2_CHAR('*'):
1678 case UCS2_CHAR('?'):
1679 case UCS2_CHAR('<'):
1680 case UCS2_CHAR('>'):
1681 case UCS2_CHAR('"'):
1682 return True;
1685 return False;
1688 /*******************************************************************
1689 A wrapper that handles case sensitivity and the special handling
1690 of the ".." name.
1691 *******************************************************************/
1693 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1695 if (ISDOTDOT(string))
1696 string = ".";
1697 if (ISDOT(pattern))
1698 return False;
1700 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
1703 /*******************************************************************
1704 A wrapper that handles case sensitivity and the special handling
1705 of the ".." name. Varient that is only called by old search code which requires
1706 pattern translation.
1707 *******************************************************************/
1709 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
1711 if (ISDOTDOT(string))
1712 string = ".";
1713 if (ISDOT(pattern))
1714 return False;
1716 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
1719 /*******************************************************************
1720 A wrapper that handles a list of patters and calls mask_match()
1721 on each. Returns True if any of the patterns match.
1722 *******************************************************************/
1724 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
1726 while (listLen-- > 0) {
1727 if (mask_match(string, *list++, is_case_sensitive))
1728 return True;
1730 return False;
1733 /*********************************************************
1734 Recursive routine that is called by unix_wild_match.
1735 *********************************************************/
1737 static bool unix_do_match(const char *regexp, const char *str)
1739 const char *p;
1741 for( p = regexp; *p && *str; ) {
1743 switch(*p) {
1744 case '?':
1745 str++;
1746 p++;
1747 break;
1749 case '*':
1752 * Look for a character matching
1753 * the one after the '*'.
1755 p++;
1756 if(!*p)
1757 return true; /* Automatic match */
1758 while(*str) {
1760 while(*str && (*p != *str))
1761 str++;
1764 * Patch from weidel@multichart.de. In the case of the regexp
1765 * '*XX*' we want to ensure there are at least 2 'X' characters
1766 * in the string after the '*' for a match to be made.
1770 int matchcount=0;
1773 * Eat all the characters that match, but count how many there were.
1776 while(*str && (*p == *str)) {
1777 str++;
1778 matchcount++;
1782 * Now check that if the regexp had n identical characters that
1783 * matchcount had at least that many matches.
1786 while ( *(p+1) && (*(p+1) == *p)) {
1787 p++;
1788 matchcount--;
1791 if ( matchcount <= 0 )
1792 return false;
1795 str--; /* We've eaten the match char after the '*' */
1797 if(unix_do_match(p, str))
1798 return true;
1800 if(!*str)
1801 return false;
1802 else
1803 str++;
1805 return false;
1807 default:
1808 if(*str != *p)
1809 return false;
1810 str++;
1811 p++;
1812 break;
1816 if(!*p && !*str)
1817 return true;
1819 if (!*p && str[0] == '.' && str[1] == 0)
1820 return true;
1822 if (!*str && *p == '?') {
1823 while (*p == '?')
1824 p++;
1825 return(!*p);
1828 if(!*str && (*p == '*' && p[1] == '\0'))
1829 return true;
1831 return false;
1834 /*******************************************************************
1835 Simple case insensitive interface to a UNIX wildcard matcher.
1836 Returns True if match, False if not.
1837 *******************************************************************/
1839 bool unix_wild_match(const char *pattern, const char *string)
1841 TALLOC_CTX *ctx = talloc_stackframe();
1842 char *p2;
1843 char *s2;
1844 char *p;
1845 bool ret = false;
1847 p2 = talloc_strdup(ctx,pattern);
1848 s2 = talloc_strdup(ctx,string);
1849 if (!p2 || !s2) {
1850 TALLOC_FREE(ctx);
1851 return false;
1853 strlower_m(p2);
1854 strlower_m(s2);
1856 /* Remove any *? and ** from the pattern as they are meaningless */
1857 for(p = p2; *p; p++) {
1858 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1859 memmove(&p[1], &p[2], strlen(&p[2])+1);
1863 if (strequal(p2,"*")) {
1864 TALLOC_FREE(ctx);
1865 return true;
1868 ret = unix_do_match(p2, s2);
1869 TALLOC_FREE(ctx);
1870 return ret;
1873 /**********************************************************************
1874 Converts a name to a fully qualified domain name.
1875 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1876 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1877 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1878 ***********************************************************************/
1880 bool name_to_fqdn(fstring fqdn, const char *name)
1882 char *full = NULL;
1883 struct hostent *hp = gethostbyname(name);
1885 if (!hp || !hp->h_name || !*hp->h_name) {
1886 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1887 fstrcpy(fqdn, name);
1888 return false;
1891 /* Find out if the fqdn is returned as an alias
1892 * to cope with /etc/hosts files where the first
1893 * name is not the fqdn but the short name */
1894 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1895 int i;
1896 for (i = 0; hp->h_aliases[i]; i++) {
1897 if (strchr_m(hp->h_aliases[i], '.')) {
1898 full = hp->h_aliases[i];
1899 break;
1903 if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1904 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1905 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1906 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1907 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1908 full = hp->h_name;
1910 if (!full) {
1911 full = hp->h_name;
1914 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1915 fstrcpy(fqdn, full);
1916 return true;
1919 /**********************************************************************
1920 Append a DATA_BLOB to a talloc'ed object
1921 ***********************************************************************/
1923 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1925 size_t old_size = 0;
1926 char *result;
1928 if (blob.length == 0) {
1929 return buf;
1932 if (buf != NULL) {
1933 old_size = talloc_get_size(buf);
1936 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1937 if (result == NULL) {
1938 return NULL;
1941 memcpy(result + old_size, blob.data, blob.length);
1942 return result;
1945 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1947 switch (share_access & ~FILE_SHARE_DELETE) {
1948 case FILE_SHARE_NONE:
1949 return DENY_ALL;
1950 case FILE_SHARE_READ:
1951 return DENY_WRITE;
1952 case FILE_SHARE_WRITE:
1953 return DENY_READ;
1954 case FILE_SHARE_READ|FILE_SHARE_WRITE:
1955 return DENY_NONE;
1957 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
1958 return DENY_DOS;
1959 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
1960 return DENY_FCB;
1963 return (uint32)-1;
1966 pid_t procid_to_pid(const struct server_id *proc)
1968 return proc->pid;
1971 static uint32 my_vnn = NONCLUSTER_VNN;
1973 void set_my_vnn(uint32 vnn)
1975 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
1976 my_vnn = vnn;
1979 uint32 get_my_vnn(void)
1981 return my_vnn;
1984 static uint64_t my_unique_id = 0;
1986 void set_my_unique_id(uint64_t unique_id)
1988 my_unique_id = unique_id;
1991 struct server_id pid_to_procid(pid_t pid)
1993 struct server_id result;
1994 result.pid = pid;
1995 result.task_id = 0;
1996 result.unique_id = my_unique_id;
1997 result.vnn = my_vnn;
1998 return result;
2001 struct server_id procid_self(void)
2003 return pid_to_procid(sys_getpid());
2006 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
2008 if (p1->pid != p2->pid)
2009 return False;
2010 if (p1->task_id != p2->task_id)
2011 return False;
2012 if (p1->vnn != p2->vnn)
2013 return False;
2014 return True;
2017 bool cluster_id_equal(const struct server_id *id1,
2018 const struct server_id *id2)
2020 return procid_equal(id1, id2);
2023 bool procid_is_me(const struct server_id *pid)
2025 if (pid->pid != sys_getpid())
2026 return False;
2027 if (pid->task_id != 0)
2028 return False;
2029 if (pid->vnn != my_vnn)
2030 return False;
2031 return True;
2034 struct server_id interpret_pid(const char *pid_string)
2036 struct server_id result;
2037 unsigned long long pid;
2038 unsigned int vnn, task_id = 0;
2040 ZERO_STRUCT(result);
2042 /* We accept various forms with 1, 2 or 3 component forms
2043 * because the server_id_str() can print different forms, and
2044 * we want backwards compatibility for scripts that may call
2045 * smbclient. */
2046 if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
2047 result.vnn = vnn;
2048 result.pid = pid;
2049 result.task_id = task_id;
2050 } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
2051 result.vnn = vnn;
2052 result.pid = pid;
2053 result.task_id = 0;
2054 } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
2055 result.vnn = get_my_vnn();
2056 result.pid = pid;
2057 result.task_id = task_id;
2058 } else if (sscanf(pid_string, "%llu", &pid) == 1) {
2059 result.vnn = get_my_vnn();
2060 result.pid = pid;
2061 } else {
2062 result.vnn = NONCLUSTER_VNN;
2063 result.pid = (uint64_t)-1;
2065 return result;
2068 char *procid_str_static(const struct server_id *pid)
2070 return server_id_str(talloc_tos(), pid);
2073 bool procid_valid(const struct server_id *pid)
2075 return (pid->pid != (uint64_t)-1);
2078 bool procid_is_local(const struct server_id *pid)
2080 return pid->vnn == my_vnn;
2083 /****************************************************************
2084 Check if an offset into a buffer is safe.
2085 If this returns True it's safe to indirect into the byte at
2086 pointer ptr+off.
2087 ****************************************************************/
2089 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2091 const char *end_base = buf_base + buf_len;
2092 char *end_ptr = ptr + off;
2094 if (!buf_base || !ptr) {
2095 return False;
2098 if (end_base < buf_base || end_ptr < ptr) {
2099 return False; /* wrap. */
2102 if (end_ptr < end_base) {
2103 return True;
2105 return False;
2108 /****************************************************************
2109 Return a safe pointer into a buffer, or NULL.
2110 ****************************************************************/
2112 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2114 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2115 ptr + off : NULL;
2118 /****************************************************************
2119 Return a safe pointer into a string within a buffer, or NULL.
2120 ****************************************************************/
2122 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2124 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2125 return NULL;
2127 /* Check if a valid string exists at this offset. */
2128 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2129 return NULL;
2131 return ptr + off;
2134 /****************************************************************
2135 Return an SVAL at a pointer, or failval if beyond the end.
2136 ****************************************************************/
2138 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2141 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2142 * NOT ptr[2].
2144 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2145 return failval;
2147 return SVAL(ptr,off);
2150 /****************************************************************
2151 Return an IVAL at a pointer, or failval if beyond the end.
2152 ****************************************************************/
2154 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2157 * Note we use off+3 here, not off+4 as IVAL accesses
2158 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2160 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2161 return failval;
2163 return IVAL(ptr,off);
2166 /****************************************************************
2167 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2168 call (they take care of winbind separator and other winbind specific settings).
2169 ****************************************************************/
2171 void split_domain_user(TALLOC_CTX *mem_ctx,
2172 const char *full_name,
2173 char **domain,
2174 char **user)
2176 const char *p = NULL;
2178 p = strchr_m(full_name, '\\');
2180 if (p != NULL) {
2181 *domain = talloc_strndup(mem_ctx, full_name,
2182 PTR_DIFF(p, full_name));
2183 *user = talloc_strdup(mem_ctx, p+1);
2184 } else {
2185 *domain = talloc_strdup(mem_ctx, "");
2186 *user = talloc_strdup(mem_ctx, full_name);
2190 /****************************************************************
2191 strip off leading '\\' from a hostname
2192 ****************************************************************/
2194 const char *strip_hostname(const char *s)
2196 if (!s) {
2197 return NULL;
2200 if (strlen_m(s) < 3) {
2201 return s;
2204 if (s[0] == '\\') s++;
2205 if (s[0] == '\\') s++;
2207 return s;
2210 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2211 struct tevent_context *ev,
2212 NTSTATUS *status)
2214 bool ret = tevent_req_poll(req, ev);
2215 if (!ret) {
2216 *status = map_nt_error_from_unix(errno);
2218 return ret;
2221 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2223 if (!NT_STATUS_IS_OK(err1)) {
2224 *result = err1;
2225 return true;
2227 if (!NT_STATUS_IS_OK(err2)) {
2228 *result = err2;
2229 return true;
2231 return false;
2234 int timeval_to_msec(struct timeval t)
2236 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2239 /*******************************************************************
2240 Check a given DOS pathname is valid for a share.
2241 ********************************************************************/
2243 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2245 char *ptr = NULL;
2247 if (!dos_pathname) {
2248 return NULL;
2251 ptr = talloc_strdup(ctx, dos_pathname);
2252 if (!ptr) {
2253 return NULL;
2255 /* Convert any '\' paths to '/' */
2256 unix_format(ptr);
2257 ptr = unix_clean_name(ctx, ptr);
2258 if (!ptr) {
2259 return NULL;
2262 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2263 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2264 ptr += 2;
2266 /* Only absolute paths allowed. */
2267 if (*ptr != '/')
2268 return NULL;
2270 return ptr;
2273 /*******************************************************************
2274 Return True if the filename is one of the special executable types.
2275 ********************************************************************/
2277 bool is_executable(const char *fname)
2279 if ((fname = strrchr_m(fname,'.'))) {
2280 if (strequal(fname,".com") ||
2281 strequal(fname,".dll") ||
2282 strequal(fname,".exe") ||
2283 strequal(fname,".sym")) {
2284 return True;
2287 return False;
2290 /****************************************************************************
2291 Open a file with a share mode - old openX method - map into NTCreate.
2292 ****************************************************************************/
2294 bool map_open_params_to_ntcreate(const char *smb_base_fname,
2295 int deny_mode, int open_func,
2296 uint32 *paccess_mask,
2297 uint32 *pshare_mode,
2298 uint32 *pcreate_disposition,
2299 uint32 *pcreate_options,
2300 uint32_t *pprivate_flags)
2302 uint32 access_mask;
2303 uint32 share_mode;
2304 uint32 create_disposition;
2305 uint32 create_options = FILE_NON_DIRECTORY_FILE;
2306 uint32_t private_flags = 0;
2308 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2309 "open_func = 0x%x\n",
2310 smb_base_fname, (unsigned int)deny_mode,
2311 (unsigned int)open_func ));
2313 /* Create the NT compatible access_mask. */
2314 switch (GET_OPENX_MODE(deny_mode)) {
2315 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
2316 case DOS_OPEN_RDONLY:
2317 access_mask = FILE_GENERIC_READ;
2318 break;
2319 case DOS_OPEN_WRONLY:
2320 access_mask = FILE_GENERIC_WRITE;
2321 break;
2322 case DOS_OPEN_RDWR:
2323 case DOS_OPEN_FCB:
2324 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
2325 break;
2326 default:
2327 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2328 (unsigned int)GET_OPENX_MODE(deny_mode)));
2329 return False;
2332 /* Create the NT compatible create_disposition. */
2333 switch (open_func) {
2334 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
2335 create_disposition = FILE_CREATE;
2336 break;
2338 case OPENX_FILE_EXISTS_OPEN:
2339 create_disposition = FILE_OPEN;
2340 break;
2342 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
2343 create_disposition = FILE_OPEN_IF;
2344 break;
2346 case OPENX_FILE_EXISTS_TRUNCATE:
2347 create_disposition = FILE_OVERWRITE;
2348 break;
2350 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
2351 create_disposition = FILE_OVERWRITE_IF;
2352 break;
2354 default:
2355 /* From samba4 - to be confirmed. */
2356 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
2357 create_disposition = FILE_CREATE;
2358 break;
2360 DEBUG(10,("map_open_params_to_ntcreate: bad "
2361 "open_func 0x%x\n", (unsigned int)open_func));
2362 return False;
2365 /* Create the NT compatible share modes. */
2366 switch (GET_DENY_MODE(deny_mode)) {
2367 case DENY_ALL:
2368 share_mode = FILE_SHARE_NONE;
2369 break;
2371 case DENY_WRITE:
2372 share_mode = FILE_SHARE_READ;
2373 break;
2375 case DENY_READ:
2376 share_mode = FILE_SHARE_WRITE;
2377 break;
2379 case DENY_NONE:
2380 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2381 break;
2383 case DENY_DOS:
2384 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
2385 if (is_executable(smb_base_fname)) {
2386 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2387 } else {
2388 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
2389 share_mode = FILE_SHARE_READ;
2390 } else {
2391 share_mode = FILE_SHARE_NONE;
2394 break;
2396 case DENY_FCB:
2397 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
2398 share_mode = FILE_SHARE_NONE;
2399 break;
2401 default:
2402 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2403 (unsigned int)GET_DENY_MODE(deny_mode) ));
2404 return False;
2407 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2408 "share_mode = 0x%x, create_disposition = 0x%x, "
2409 "create_options = 0x%x private_flags = 0x%x\n",
2410 smb_base_fname,
2411 (unsigned int)access_mask,
2412 (unsigned int)share_mode,
2413 (unsigned int)create_disposition,
2414 (unsigned int)create_options,
2415 (unsigned int)private_flags));
2417 if (paccess_mask) {
2418 *paccess_mask = access_mask;
2420 if (pshare_mode) {
2421 *pshare_mode = share_mode;
2423 if (pcreate_disposition) {
2424 *pcreate_disposition = create_disposition;
2426 if (pcreate_options) {
2427 *pcreate_options = create_options;
2429 if (pprivate_flags) {
2430 *pprivate_flags = private_flags;
2433 return True;
2438 void init_modules(void)
2440 /* FIXME: This can cause undefined symbol errors :
2441 * smb_register_vfs() isn't available in nmbd, for example */
2442 if(lp_preload_modules())
2443 smb_load_modules(lp_preload_modules());